buffalo-bind.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Buffalo Web Remoting, An amowa infrastructure facility, a web remoting library.
  3. *
  4. * Author: Michael Chen (mechiland AT gmail DoT com, http://michael.nona.name)
  5. *
  6. * Version: 1.0
  7. *
  8. */
  9. /**
  10. * @fileoverview buffalo-bind.js is the bind library for binding the remote call
  11. * reply to the html elements.
  12. *
  13. * @author Michael Chen mechiland@gmail.com http://michael.nona.name
  14. * @version 1.0
  15. */
  16. /**
  17. * Invoke the remote service directly, and bind the reply to
  18. * the specified element.
  19. *
  20. * @param {String} service the remote service, such as serviceName.methodName
  21. * @param {Array} params The parameters. if none, use <code>[]</code> and don't use <code>null</code>
  22. * @param {String} bindElemId The element id in the page.
  23. */
  24. Buffalo.prototype.bindReply = function(service, params, bindElemId) {
  25. this.remoteCall(service, params, function(reply) {
  26. Buffalo.bind(bindElemId, reply.getResult());
  27. });
  28. }
  29. /**
  30. * Bind the value to the specified elementId.
  31. *
  32. * @param {String} elementId The element id
  33. * @param {varient} bindValue The binded value.
  34. */
  35. Buffalo.bind = function(elementId, bindValue) {
  36. var elem = Buffalo.getElementById(elementId);
  37. switch(elem.tagName) {
  38. case "INPUT":
  39. switch (elem.type.toLowerCase()) {
  40. case "text": ;
  41. case "hidden": ;
  42. case "password": BindFactory.bindText(elem, bindValue); break;
  43. case "checkbox": ;
  44. case "radio": BindFactory.bindRadioOrCheckbox(elem, bindValue); break;
  45. }
  46. break;
  47. case "TEXTAREA":
  48. BindFactory.bindText(elem, bindValue);
  49. break;
  50. case "TABLE":
  51. BindFactory.bindTable(elem, bindValue);
  52. break;
  53. case "SELECT":
  54. BindFactory.bindSelect(elem, bindValue);
  55. break;
  56. case "DIV":
  57. case "SPAN":
  58. alert(bindValue);
  59. elem.innerHTML = bindValue;
  60. break;
  61. //TODO: add more bindings here for
  62. }
  63. }
  64. /**
  65. * Factory method. Do not call it directly.
  66. */
  67. function BindFactory(){}
  68. /**
  69. * Report the error.
  70. * @param {HTMLDOMElement} elem the html element
  71. * @param {varient} the value to be binded
  72. * @param {String} msg the error message
  73. */
  74. BindFactory.reportError = function(elem, value, msg) {
  75. throw "Data bind failed: "+msg;
  76. }
  77. /**
  78. * Bind value to the text-like element, such as input, textarea
  79. * @param {HTMLDOMElement} elem the html element
  80. * @param {varient} value the value to bind
  81. */
  82. BindFactory.bindText = function(elem, value) {
  83. elem.value = value;
  84. }
  85. /**
  86. * Bind value to the radiobox oo checkbox.
  87. * @param {HTMLDOMElement} elem the html element
  88. * @param {varient} value the value to bind
  89. */
  90. BindFactory.bindRadioOrCheckbox = function(elem, value) {
  91. var ret = false;
  92. switch (typeof(value)) {
  93. case 'boolean': ret = value; break;
  94. case 'string': ret = (value == "1" || value == "true" || value == "yes"); break;
  95. case 'number': ret = (parseInt(value) == 1); break;
  96. default: ret = false;
  97. }
  98. elem.checked = ret;
  99. }
  100. /**
  101. * Bind value to select/list element.
  102. *
  103. * @param {HTMLDOMElement} elem the html element
  104. * @param {varient} value the value to bind
  105. */
  106. BindFactory.bindSelect = function(elem, value) {
  107. //TODO: Check the data type
  108. if (typeof(value) != "object" || value.constructor != Array) {
  109. BindFactory.reportError(elem,value,"绑定到Select控件需要数组类型数据!");
  110. }
  111. // delete all the nodes.
  112. while (elem.childNodes.length > 0) {
  113. elem.removeChild(elem.childNodes[0]);
  114. }
  115. // bind data
  116. for (var i = 0; i < value.length; i++) {
  117. var option = document.createElement("OPTION");
  118. var data = value[i];
  119. if (data == null || typeof(data) == "undefined") {
  120. option.value = "";
  121. option.text = "";
  122. }
  123. if (typeof(data) != 'object') {
  124. option.value = data;
  125. option.text = data;
  126. } else {
  127. option.value = data[elem.getAttribute("jvalue")];
  128. option.text = data[elem.getAttribute("jtext")];
  129. }
  130. elem.options.add(option);
  131. }
  132. }
  133. /**
  134. * Bind value to a html table.
  135. * @param {HTMLDOMElement} elem the html element
  136. * @param {varient} value the value to bind
  137. */
  138. BindFactory.bindTable = function(elem, value) {
  139. var jHeight = parseInt(elem.getAttribute("jheight"));
  140. var dataHeader = [];
  141. var tBody = elem.getElementsByTagName("TBODY")[0];
  142. // clear the generated rows
  143. if (elem.getElementsByTagName("TBODY").length > 0) {
  144. while (tBody.rows.length > jHeight) {
  145. tBody.deleteRow(jHeight);
  146. }
  147. }
  148. if (jHeight == 0) { // if table is null, push the data to the tables.
  149. for (x in value[0] ) {
  150. dataHeader[dataHeader.length] = x;
  151. }
  152. var hTr = elem.insertRow(elem.rows.length);
  153. for (var i = 0; i < dataHeader.length; i++) {
  154. var td = hTr.insertCell(hTr.cells.length);
  155. td.innerHTML = dataHeader[i];
  156. }
  157. for (var i = 0; i < value.length; i++) {
  158. var tr = elem.insertRow(elem.rows.length);
  159. var data = value[i];
  160. for (x in data ) {
  161. var td = tr.insertCell(tr.cells.length);
  162. td.innerHTML = data[x];
  163. }
  164. }
  165. }
  166. if (jHeight == 1) { // 只有一行,那么第一行为header(其中每一个td指定jtext属性)
  167. var headerTR = tBody.rows[0];
  168. for (var i = 0; i < headerTR.cells.length ; i++ ) {
  169. dataHeader[dataHeader.length] = headerTR.cells[i].getAttribute("jtext");
  170. }
  171. for (var i = 0; i < value.length; i++) {
  172. var tr = tBody.insertRow(tBody.rows.length);
  173. var data = value[i];
  174. for (var j = 0; j < dataHeader.length; j++ ) {
  175. var td = tr.insertCell(tr.cells.length);
  176. td.innerHTML = data[dataHeader[j]];
  177. }
  178. }
  179. }
  180. if (jHeight == 2) { // 两行,第一行为header, 第二行为后面循环的样式
  181. var headerTR = tBody.rows[0];
  182. for (var i = 0; i < headerTR.cells.length ; i++ ) {
  183. dataHeader[dataHeader.length] = headerTR.cells[i].getAttribute("jtext");
  184. }
  185. for (var i = 0; i < value.length; i++) {
  186. var tr;
  187. if (i == 0) { // 如果是第一行,那么直接使用
  188. tr = elem.rows[1];
  189. } else { // 否则,复制第一行
  190. tr = elem.rows[1].cloneNode(true);
  191. }
  192. if (i > 0) {
  193. tBody.appendChild(tr);
  194. }
  195. var data = value[i];
  196. for (var j = 0; j < tr.cells.length; j++ ) {
  197. var td = tr.cells[j];
  198. td.innerHTML = data[dataHeader[j]];
  199. }
  200. }
  201. }
  202. if (jHeight >= 3) { // 三行及以上,第一行为header, 二、三行为交换样式,后面的行将会被忽略。
  203. var headerTR = tBody.rows[0];
  204. for (var i = 0; i < headerTR.cells.length ; i++ ) {
  205. dataHeader[dataHeader.length] = headerTR.cells[i].getAttribute("jtext");
  206. }
  207. for (var i = 0; i < value.length; i++) {
  208. var tr;
  209. if (i == 0) { // 如果是第一行,那么直接使用
  210. tr = tBody.rows[1];
  211. } else if (i == 1) { // 第二行,也直接使用
  212. tr = tBody.rows[2];
  213. } else if ( i % 2 == 0) { // 取第一个行
  214. tr = tBody.rows[1].cloneNode(true);
  215. } else if (i % 2 == 1) { // 取第二个行
  216. tr = tBody.rows[2].cloneNode(true);
  217. }
  218. if (i > 1) {
  219. tBody.appendChild(tr);
  220. }
  221. var data = value[i];
  222. for (var j = 0; j < tr.cells.length; j++ ) {
  223. var td = tr.cells[j];
  224. td.innerHTML = data[dataHeader[j]];
  225. }
  226. }
  227. }
  228. }
  229. /**
  230. * Bind value to a repeater(under considering.)
  231. * @param {HTMLDOMElement} elem the html element
  232. * @param {varient} value the value to bind
  233. */
  234. BindFactory.bindRepeater = function(elem, value) {
  235. //TODO: implementation will be added.
  236. }