Studying Java......

统计

留言簿(1)

积分与排名

JavaServerFaces

Mail Link

Open Source

友情链接

收藏的链接

阅读排行榜

评论排行榜

2005年11月24日 #

不刷新页面,切换表格的编辑状态

      前段时间做了一个简单的维护界面,包括添加,变更与删除的功能.变更界面是在页面中显示一个TABLE(第一列为RadioButton),选中一行后该行变成可编辑状态,切换到其它行后再恢复成文本显示.最初做的时候是点击单选项按钮后提交到后台刷新页面来实现的,后来要求改成在客户端切换编辑状态.


1.首先需要解决的是由文本显示状态与TEXT框转换的问题.由文本显示到编辑框这个可以通过修改对应对象的innerHTML来解决,由编辑框切换到文本显示开始用的是outerHTML来修改的(后来发现有问题).


2.行切换的问题:当选择的行做了变换时,如果数据做了更改且未提交的话仍显示未修改前的值.这个在页面中加入了一个隐藏域,保存选中行的数据.这部分数据只是用来临时保存数据的,不需要提交到后台,未包含在FORM中,只是给了一个ID进行区分;


3.选中的行并不是所有字段都更改为可编辑状态,只有部分字段需要更改.这里在修改innerHTML的时候进行了判断;


4.如何与FORM中的属性匹配的问题:可以在修改innerHTML的时候指定name就可以了;


5.后来在接下来的测试中,如果字段中存在HTML字符,通过outerHTML来赋值,浏览器会对它进行解析,并不是想要显示的信息.开始查JS函数的时候发现了escape与 unescape,以为会进行自动转换的,后来发现并非如此.在经过几番修改之后,发现修改outerText属性则不会对赋的值进行解析.


6.由于一些验证是定义在后台的,只有提交到服务器后才会进行校验.如果检验不通过还返回当前页面,要保留提交前的状态;这里是给RadioButton一个ID(后台数据表中的主键值).找到对应的行,再把把它置成选中状态,同时相应的列改为编辑框;


7.应该说到这里基本已经完成了,但在提交到服务器校验出错后,返回的页面中显示的仍然是编辑前的值,由于页面做了刷新,隐藏域的值已经被重置.如果再切换到其它行,显示的仍然是用户修改后的数据,这部分数据并未成功更新到后台,应该显示成修改前的数据.这里通过Request传回到页面中,在触发对应的RadioButton后再把值赋到隐藏域中.

部分代码如下:

<script language="JavaScript" type="text/javascript">
//Get parent node.
window.SearchByTagName = function(e, TAG) {
    while(e!=null && e.tagName){
     if(e.tagName==TAG.toUpperCase()) {
      return(e);
     } 
     e = e.parentNode;
    }
    return null;
}

var selectedRow = -1; //global

function selectChanged(e) {
    var td = SearchByTagName(e, "TD");
    var tr = td.parentNode;
    var tab = SearchByTagName(tr, "TABLE");
    var cellValue = "";
    //Reset the cell's value.
    if(selectedRow>=0) {
     for(var i=td.cellIndex+1; i<tab.rows[selectedRow].cells.length; i++) {
            var a = tab.rows[selectedRow].cells[i].getElementsByTagName("INPUT");
            for(var k=0; k<a.length; k++) {
                if(a[k].type=="text") {
                 //Valid only in IE.
                 a[k].outerText = document.getElementById(a[k].name).value;
                }
            }
        }
    } 
  
    selectedRow = tr.rowIndex;
 
 //Change the cell into text,and save the value into hidden field.
    var hyoujijunCell = document.getElementById("hyoujijun" + selectedRow);
    var ryakusyouCell = document.getElementById("ryakusyou" + selectedRow);
    var nameCell = document.getElementById("name" + selectedRow);
    
    document.getElementById("hyoujijun").value=rtrim(hyoujijunCell.innerText);
    document.getElementById("hyoujijun" + selectedRow).innerHTML =
     "<input type='text' name='hyoujijun' maxlength='3' style='width:80px' value='" +
      rtrim(hyoujijunCell.innerHTML) +"'>";
    
     document.getElementById("ryakusyou").value=rtrim(ryakusyouCell.innerText);
     document.getElementById("ryakusyou" + selectedRow).innerHTML =
      "<input type='text' name='ryakusyou' maxlength='4' style='width:60px' value='" +
      rtrim(ryakusyouCell.innerHTML) +"'>";
   
    document.getElementById("name").value= rtrim(nameCell.innerText);
    document.getElementById("name" + selectedRow).innerHTML =
     "<input name='name' maxlength='100' style='width:300px' value='" +
     rtrim(nameCell.innerHTML) +"'>";
}

function validReturn() {
 if ( <%=selectedMasterID%> > 0) {
  //Get the selected row,and select it.
  var radioSn = document.getElementById("masterid<%=selectedMasterID%>");
  radioSn.click( );
  //Save original value.If changed other row,restore data as before modified.
  document.getElementById("hyoujijun").value = "<%=hyoujijunReturn%>";
  document.getElementById("name").value = "<%=nameReturn%>";
  document.getElementById("ryakusyou").value = "<%=ryakusyouReturn%>";
 }
}

//Clear the last blank.
function rtrim(cellValue) {
 if (cellValue.lastIndexOf(" ") >= 0) {
  cellValue = cellValue.substr(0,cellValue.lastIndexOf(" "));
 }
 
 return cellValue; 
}
</script>


<body class="gyomu" onload="validReturn()">
<table>
  <logic:present name="masterList">
   <logic:iterate id="element" indexId="index" name="masterList">
    <tr>
     <td class="meisai" style="width: 50px">
      <logic:notEqual name="element" property="sakujyo" value="DELETE">
       <input type="radio" name="masterid"
        value="<bean:write name='element' property='masterid'/>"
        onclick="selectChanged(this)" id="masterid<bean:write name='element' property='masterid'/>" />
       <%rowCount++;%>  
      </logic:notEqual>
     </td>
     <td class="meisai" style="width: 80px" id="hyoujijun<%=index%>">
      <bean:write name="element" property="hyoujijun" />
     </td>
     <td class="meisai" style="width: 60px" id="cd<%=index%>">
      <bean:write name="element" property="cd" />
     </td>
     <td class="meisai" style="width: 300px" id="name<%=index%>">
      <bean:write name="element" property="name" />
     </td>
     <logic:equal name="needShortName" value="true">
      <td class="meisai" style="width: 60px" id="ryakusyou<%=index%>">
       <bean:write name="element" property="ryakusyou" />
      </td>
     </logic:equal>
     <td class="meisai" style="width: 70px" id="sakujyo<%=index%>">
      <bean:write name="element" property="sakujyo" />
     </td>
    </tr>
   </logic:iterate>
  </logic:present>
 </table>
</body>

posted @ 2005-12-08 11:46 Terence 阅读(2337) | 评论 (2)编辑 收藏

利用函数computeURL( )实现同一FORM的多动作提交

       在实际处理的页面中,往往在一个页面中有多个触发的动作,而Struts的ActionForm中只能指定一个Action,是一种粗粒度的实现(JSF中有更好的解决方案),computeURL( )可以提供一种变通的解决方法.
       computeURL( )是在org.apache.struts.util.RequestUtils(Struts Ver1.1)与org.apache.struts.taglib.TagUtils(Struts Ver1.2)类中的一个函数,用来解析基于Forward,Action,链接,页面参数的URL可以用来动态改变页面中Form对应的Action.Ver1.1中有以下两种:
1.computeURL(javax.servlet.jsp.PageContext pageContext, java.lang.String forward, java.lang.String href, java.lang.String page, java.util.Map params, java.lang.String anchor, boolean redirect)
2.computeURL(javax.servlet.jsp.PageContext pageContext, java.lang.String forward, java.lang.String href, java.lang.String page, java.lang.String action, java.util.Map params, java.lang.String anchor, boolean redirect)
其中第一个是  Deprecated.第二个在新版本中得以保留,另外还提供了另外一种重载:
computeURL(javax.servlet.jsp.PageContext pageContext, java.lang.String forward, java.lang.String href, java.lang.String page, java.lang.String action, java.lang.String module, java.util.Map params, java.lang.String anchor, boolean redirect, boolean encodeSeparator) 
参数说明如下:
Parameters:
pageContext - PageContext for the tag making this call
forward - Logical forward name for which to look up the context-relative URI (if specified)
href - URL to be utilized unmodified (if specified)
page - Module-relative page for which a URL should be created (if specified)
action - Logical action name for which to look up the context-relative URI (if specified)
params - Map of parameters to be dynamically included (if any)
anchor - Anchor to be dynamically included (if any)
redirect - Is this URL for a response.sendRedirect(

下面介绍一下详细的使用方法:
1.在JSP页面中导入对应的包:
<%@ page import= "org.apache.struts.util.RequestUtils"%>

<%@ page import= "org.apache.struts.taglib.TagUtils"%>
2.创建一个JAVASCRIPT函数:
<script language="JavaScript" type="text/javascript">
function search() {
 <%String searchUrl = RequestUtils.computeURL(
   pageContext,
   null,
   null,
   "/Search.do",
   null,
   null,
   null,
   false);
 %>
   
 document.form1.action = "<%=searchUrl%>";
 document.form1.submit();  
}
</script>
3.在JSP页面中给对应的表单指定ID以便上面的函数进行确定提交的是哪个FORM(如果一个页面在存在多个FORM的话):
<html:form styleId="form1" action="/aotherSearch">
.........
</html:form>
4.在需要触发提交动作的地方,调用2中的JAVASCRIPT函数:
<html:button property="searchInfo" value="检索" onclick="search()" style="width:100px" />

对应的ACTION与FORM在配置文件中定义.这样,就可以动态更改FORM的ACTION实现一个FORM对应多个ACTION了.

posted @ 2005-11-24 11:29 Terence 阅读(1611) | 评论 (2)编辑 收藏

终于贴出了第一篇文章

        说是贴的第一篇,其实并不完全准确,文章前几天就贴上了,但开始的时候放在了"文章"栏目下面而不是随笔下面,首页中显示不出来,反复修改"选项"的设置也没有搞定.在BLOGJAVA上面也没有找到相关的使用说明,郁闷了好一段时间.有点想到其它地方申请个BLOG的想法了.早上的时候看别人的BLOG,发现都是随笔,猜测可能是只有随笔才会在自己BLOG的首页中显示出来.于是把必到"文章"栏目中的一篇文章搬到了随笔下,果然显示在首页了!
       如果有遇到同样问题的朋友,请把文章转贴到"随笔"栏目中就可以了!

posted @ 2005-11-24 10:29 Terence 阅读(393) | 评论 (1)编辑 收藏

Struts中的下拉列表标签的使用

页面中经常用到下拉列表,下面是个人对于STRUTS中标签使用的一点总结:
STRUTS中的下拉选择列表标签必须嵌套在<html:form>标签中,包括:
1.<html:select>
2.<html:option>
3.<html:options>
4.<html:optionsCollection>

使用时嵌套如下:
<html:select property="ationForm.property">
    <html:option>或<html:options>或<html:optionsCollection>
</html:select>
其中property为ActionForm中对应的一个属性.

1.<html:option>
<html:option value="value">displayName</html:option>
其中value为实际使用的值(赋值到ActionForm对应的属性中) displayName页面中显示的信息.
例:<html:option value=""></html:option>显示一个空白选择,值为"".

2..<html:options>
<html:options collection="collection" labelProperty="displayName" property="value"/>
其中collection为一个集合,一般是个ArrayList,displayName为前台显示的名称,value为后台实际使用的值.
例:<html:options collection="arrayList" labelProperty="name" property="id" />

3..<html:optionsCollection>
<html:optionsCollection property="actionForm.property" label="displayName" value="value"/>
其中property为ActionForm中的一个属性,为一个集合.displayName为前台显示的名称,value为后台实际使用的值.
例:<html:optionsCollection property="listProperty" label="name" value="id" />

补充一点:如果要从 数据库去取数据,一般是在 action 里调用 DAO ,把结果存入一个ArrayList作为 request 的一个属性传到页面上; 这时一般用 <html:options .../> 标签.另外,如果数据不从数据库去取,而是代码固定的,则一般把这种放到 ActionForm 里,作为属性在页面上取,这时一般用 <html:optionsCollection ... /> .

posted @ 2005-11-24 10:21 Terence 阅读(2673) | 评论 (3)编辑 收藏