`
redhacker
  • 浏览: 489235 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Oracle ADF中实现输入框字数统计功能

阅读更多
需求:在我们的信息系统中,为了用户体验,通常会有如下图的字数统计功能:



在传统的jsp页面里实现这样的功能,相信各位同学都会轻车熟路,但是当我们使用了oracle adf框架后,实现这个功能,尽然花费了我一天的时间,原因是,企图使用oracle adf自己封装的js api实现,结果是徒劳。原因如下:

先来看一下源代码:
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
          xmlns:trh="http://myfaces.apache.org/trinidad/html">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1" title="不能正常工作的字数自动统计输入框实验">
      <trh:script id="showAutoNum">
        var leftLen = 300;
        function counterNum2(actionEvent) {
            var component = actionEvent.getSource();
            var markContent = component.findComponent("markContent");
            var content = markContent.getValue();
            var usedLen = content.length;
            var maxLen = markContent.getMaximumLength();
            leftLen = maxLen - usedLen;
            var showNum = AdfPage.PAGE.findComponent("showNum");
            showNum.setValue("可写 " + leftLen + " 字");
        }
      </trh:script>
      <af:panelSplitter id="ps1">
        <f:facet name="first">
          <af:panelGroupLayout layout="scroll"
                               xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
                               id="pgl1">
            <af:inputText label="备注" id="markContent" rows="10"
                          clientComponent="true" maximumLength="300">
              <af:clientListener type="keyUp" method="counterNum2"/>
            </af:inputText>
          </af:panelGroupLayout>
        </f:facet>
        <f:facet name="second">
          <af:outputText id="showNum" value="可写 300 字" clientComponent="true"/>
        </f:facet>
      </af:panelSplitter>
    </af:document>
  </f:view>
</jsp:root>



分析:

1、在这个页面中,我使用了oracle adf js api查找一个页面对象,设置其值,但af:clientListener这个标签的监听事件类型设为type="keyUp",根本不是想象的那样(当键盘键弹起时触发),只有当焦点移开af:inputText备注框时,才能触发。

2、oracle adf js api都是发送一些异步的ajax请求,上面的这个例子在备注输入框失去焦点的时候也能统计出结果,但是,似乎是由于ajax 异步请求后台处理的原因,统计很不流畅,甚至有很大的延迟,用户体验非常差。

基于上述两个原因,我继续寻求其他的解决办法,我在想,这样统计字数的功能,在使用jsp或html的时候,我们通常都是用前台的js技术解决,根本不需要与后台服务器交互,那么,在这里,我们能不能也这样处理呢?想到这里,我的思路豁然开朗,我借助firebug的强大功能,分析了上面代码在浏览器中解析后的结构,见如下图:



这样以来,我将上面的代码改为如下代码,最终达到了我们想要的效果:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
          xmlns:trh="http://myfaces.apache.org/trinidad/html">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1" title="desc:auto count textarea input demo by using oracle adf framework. author:beanor@gmail.com">
      <af:panelSplitter id="ps1" orientation="vertical" collapsed="false"
                        disabled="true" splitterPosition="200">
        <f:facet name="first">
          <af:inputText label="备注" id="markContent" rows="10"
                        clientComponent="true" maximumLength="300"></af:inputText>
        </f:facet>
        <f:facet name="second">
          <af:outputText id="showNum" value="可写 300 字" clientComponent="true"/>
        </f:facet>
      </af:panelSplitter>
      <trh:script id="autoCountInput">
        //获取输入框对象,markContent为af:inputText的id
        var markContentObj = document.getElementById('markContent::content');
            
        //获取显示字数对象,showNum为af:outputText的id
        var showNumObj = document.getElementById('showNum');
        
        //设置输入框背景
        markContentObj.style.backgroundColor = "White";
        
        //设置输入框监听函数
        markContentObj.onkeyup = function () {                   
            
            //获取输入框中的字符串
            var markContent = markContentObj.value;
            
            //获取输入框中的字符串的长度
            var usedLen = markContent.length;
            
            //无法直接获取输入框允许输入的最大数,请保持与af:inputText的maximumLength一致
            var maxLen = 300;
            
            //计算还剩余多少字可输入
            var leftLen = maxLen - usedLen;
            
            var showNum = showNumObj.innerText;
            
            //设置界面显示剩余的字数
            var showMsg = "可写 " + leftLen + " 字";
            if (typeof(showNum) == "undefined") {
                showNumObj.textContent = showMsg;
            } else {
                showNumObj.innerText = showMsg;
            }
        };
      </trh:script>
    </af:document>
  </f:view>
</jsp:root>


代码里都做了详细的注释,我这里就不在赘述。值得一提的是,在最后ie和firefox兼容性上遇到了点麻烦,对于html的span标记的操作,firefox不支持innerText属性,最后改为textContent,但对于对undefined的比较变量,要使用typeof进行转换,是我之前不知道的知识点,经过查找资料解决了兼容性问题。

总结:

从上面的例子可以看到,对于oracle adf的js api如果在使用时不是那么得心应手,我们通过上面的方法,同样可以回归到最基础的html、js方式进行处理,这样就突破的oracle adf框架的限制,实现许多我们自己想要的功能。

值得一提的是,如果我们确定要使用原生的js api来操作html dom树实现自己的功能,兼容性是个问题,这就要求我们借助httpwatch(ie下使用)和firebug(firefox下使用)这些工具进行相应的调试,这一定程度上对我们的开发带来了难度,因此,这就要求我们对基础知识有足够的掌握,才能利用好任何的开发框架,在提高效率的同时,又能利用基础知识解决框架不能解决的难题。
  • 大小: 20.6 KB
  • 大小: 61.7 KB
0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics