/* * Buffalo Web Remoting, An amowa infrastructure facility, a web remoting library. * * Author: Michael Chen (mechiland AT gmail DoT com, http://michael.nona.name) * * Version: 1.0 * */ /** * @fileoverview buffalo-bind.js is the bind library for binding the remote call * reply to the html elements. * * @author Michael Chen mechiland@gmail.com http://michael.nona.name * @version 1.0 */ /** * Invoke the remote service directly, and bind the reply to * the specified element. * * @param {String} service the remote service, such as serviceName.methodName * @param {Array} params The parameters. if none, use [] and don't use null * @param {String} bindElemId The element id in the page. */ Buffalo.prototype.bindReply = function(service, params, bindElemId) { this.remoteCall(service, params, function(reply) { Buffalo.bind(bindElemId, reply.getResult()); }); } /** * Bind the value to the specified elementId. * * @param {String} elementId The element id * @param {varient} bindValue The binded value. */ Buffalo.bind = function(elementId, bindValue) { var elem = Buffalo.getElementById(elementId); switch(elem.tagName) { case "INPUT": switch (elem.type.toLowerCase()) { case "text": ; case "hidden": ; case "password": BindFactory.bindText(elem, bindValue); break; case "checkbox": ; case "radio": BindFactory.bindRadioOrCheckbox(elem, bindValue); break; } break; case "TEXTAREA": BindFactory.bindText(elem, bindValue); break; case "TABLE": BindFactory.bindTable(elem, bindValue); break; case "SELECT": BindFactory.bindSelect(elem, bindValue); break; case "DIV": case "SPAN": alert(bindValue); elem.innerHTML = bindValue; break; //TODO: add more bindings here for } } /** * Factory method. Do not call it directly. */ function BindFactory(){} /** * Report the error. * @param {HTMLDOMElement} elem the html element * @param {varient} the value to be binded * @param {String} msg the error message */ BindFactory.reportError = function(elem, value, msg) { throw "Data bind failed: "+msg; } /** * Bind value to the text-like element, such as input, textarea * @param {HTMLDOMElement} elem the html element * @param {varient} value the value to bind */ BindFactory.bindText = function(elem, value) { elem.value = value; } /** * Bind value to the radiobox oo checkbox. * @param {HTMLDOMElement} elem the html element * @param {varient} value the value to bind */ BindFactory.bindRadioOrCheckbox = function(elem, value) { var ret = false; switch (typeof(value)) { case 'boolean': ret = value; break; case 'string': ret = (value == "1" || value == "true" || value == "yes"); break; case 'number': ret = (parseInt(value) == 1); break; default: ret = false; } elem.checked = ret; } /** * Bind value to select/list element. * * @param {HTMLDOMElement} elem the html element * @param {varient} value the value to bind */ BindFactory.bindSelect = function(elem, value) { //TODO: Check the data type if (typeof(value) != "object" || value.constructor != Array) { BindFactory.reportError(elem,value,"绑定到Select控件需要数组类型数据!"); } // delete all the nodes. while (elem.childNodes.length > 0) { elem.removeChild(elem.childNodes[0]); } // bind data for (var i = 0; i < value.length; i++) { var option = document.createElement("OPTION"); var data = value[i]; if (data == null || typeof(data) == "undefined") { option.value = ""; option.text = ""; } if (typeof(data) != 'object') { option.value = data; option.text = data; } else { option.value = data[elem.getAttribute("jvalue")]; option.text = data[elem.getAttribute("jtext")]; } elem.options.add(option); } } /** * Bind value to a html table. * @param {HTMLDOMElement} elem the html element * @param {varient} value the value to bind */ BindFactory.bindTable = function(elem, value) { var jHeight = parseInt(elem.getAttribute("jheight")); var dataHeader = []; var tBody = elem.getElementsByTagName("TBODY")[0]; // clear the generated rows if (elem.getElementsByTagName("TBODY").length > 0) { while (tBody.rows.length > jHeight) { tBody.deleteRow(jHeight); } } if (jHeight == 0) { // if table is null, push the data to the tables. for (x in value[0] ) { dataHeader[dataHeader.length] = x; } var hTr = elem.insertRow(elem.rows.length); for (var i = 0; i < dataHeader.length; i++) { var td = hTr.insertCell(hTr.cells.length); td.innerHTML = dataHeader[i]; } for (var i = 0; i < value.length; i++) { var tr = elem.insertRow(elem.rows.length); var data = value[i]; for (x in data ) { var td = tr.insertCell(tr.cells.length); td.innerHTML = data[x]; } } } if (jHeight == 1) { // 只有一行,那么第一行为header(其中每一个td指定jtext属性) var headerTR = tBody.rows[0]; for (var i = 0; i < headerTR.cells.length ; i++ ) { dataHeader[dataHeader.length] = headerTR.cells[i].getAttribute("jtext"); } for (var i = 0; i < value.length; i++) { var tr = tBody.insertRow(tBody.rows.length); var data = value[i]; for (var j = 0; j < dataHeader.length; j++ ) { var td = tr.insertCell(tr.cells.length); td.innerHTML = data[dataHeader[j]]; } } } if (jHeight == 2) { // 两行,第一行为header, 第二行为后面循环的样式 var headerTR = tBody.rows[0]; for (var i = 0; i < headerTR.cells.length ; i++ ) { dataHeader[dataHeader.length] = headerTR.cells[i].getAttribute("jtext"); } for (var i = 0; i < value.length; i++) { var tr; if (i == 0) { // 如果是第一行,那么直接使用 tr = elem.rows[1]; } else { // 否则,复制第一行 tr = elem.rows[1].cloneNode(true); } if (i > 0) { tBody.appendChild(tr); } var data = value[i]; for (var j = 0; j < tr.cells.length; j++ ) { var td = tr.cells[j]; td.innerHTML = data[dataHeader[j]]; } } } if (jHeight >= 3) { // 三行及以上,第一行为header, 二、三行为交换样式,后面的行将会被忽略。 var headerTR = tBody.rows[0]; for (var i = 0; i < headerTR.cells.length ; i++ ) { dataHeader[dataHeader.length] = headerTR.cells[i].getAttribute("jtext"); } for (var i = 0; i < value.length; i++) { var tr; if (i == 0) { // 如果是第一行,那么直接使用 tr = tBody.rows[1]; } else if (i == 1) { // 第二行,也直接使用 tr = tBody.rows[2]; } else if ( i % 2 == 0) { // 取第一个行 tr = tBody.rows[1].cloneNode(true); } else if (i % 2 == 1) { // 取第二个行 tr = tBody.rows[2].cloneNode(true); } if (i > 1) { tBody.appendChild(tr); } var data = value[i]; for (var j = 0; j < tr.cells.length; j++ ) { var td = tr.cells[j]; td.innerHTML = data[dataHeader[j]]; } } } } /** * Bind value to a repeater(under considering.) * @param {HTMLDOMElement} elem the html element * @param {varient} value the value to bind */ BindFactory.bindRepeater = function(elem, value) { //TODO: implementation will be added. }