使用dojo.xhrGet更新表单字段会导致dijit.checkbox只读

时间:2011-02-16 20:03:51

标签: dojo readonly checkbox

我有一个表格,其中包含两个输入框,一个选择框和一些复选框。所有表单字段都使用dojoType =“dijit.form。{theFieldType}”。

当用户单击添加按钮时,将从jsp文件加载具有相同字段的新表。这是我的ajax功能:

    <script language="javascript">
    dojo.addOnLoad(passNumber);

    function passNumber() {
        var count = 0;
        dojo.query('#add').onclick(function() {
            var dNode = dojo.byId('more');
            count++;
            dojo.xhrGet({url: 'add.html', 
                         handleAs: "text", 
                         preventCache: true,
                         content:{fieldId:count} ,
                    load: function(data) {
                        dNode.innerHTML += data;
                        dojo.parser.parse(dNode);
                    },
                    error: function(error) {
                        dNode.innerHTML += "AJAX error: " + error;
                    }
            });
        });
    }

</script>

单击“添加”按钮时,一切都会正常运行。

多次单击“添加”按钮时出现问题。多次单击时,表中的字段会正确添加到表单中,但所有dojoType字段现在都是只读的(除了最新添加的表)。

今天早上我搜索了几个小时,找不到正确的解决办法。我看到一些人发布了关于破坏对象的文章,而其他人则谈到只解析最新的字段。我尝试了几种技术,无法让它发挥作用。

我有一个简单的解决方法,可以帮助处于相同位置的人。

<script language="javascript">
    dojo.addOnLoad(passNumber);

    function passNumber() {
        var count = 0;
        dojo.query('#add').onclick(function() {
            var dNode = dojo.byId('more'+count);
            count++;
            dojo.xhrGet({url: 'add.html', 
                         handleAs: "text", 
                         preventCache: true,
                         content:{fieldId:count} ,
                    load: function(data) {
                        dNode.innerHTML = data;
                        dojo.parser.parse(dNode);
                    },
                    error: function(error) {
                        dNode.innerHTML += "AJAX error: " + error;
                    }
            });
        });
    }

</script>

主要的区别是dNode中的+ =。内部HTML现在只是一个=。另外我只解析最新的div元素。在我的jsp上,我添加了一个名为'more'的空div容器+传递的数字。

我是dojo的新手,所以可能有一个简单的解释或修复我原来的问题。但我想分享我遇到同样问题的人的修复。

由于

2 个答案:

答案 0 :(得分:2)

你至少有一个问题,可能还有两个问题。

首先,您应该使用dojo.place将HTML片段放在页面中,而不是innerHTML

其次(你可能不会这样做)你不应该在解析器已经运行的DOM的一部分上运行解析器。如果你这样做,你最终会得到错误'尝试用if'foo'注册一个小部件但该id已经注册'。

基本上,就像DOM节点的ID必须是唯一的一样,它们对于小部件也必须是唯一的。

您有几个选择:

  1. 不要从JSP返回文档片段/ HTML文本。相反,使用JSON或类似方法,并在load()回调中以编程方式构造新的表单元素。

  2. 执行您正在执行的操作(但请确保您拥有唯一ID),而不是使用innerHTML使用dojo.place()。然后跟踪您正在创建的新表节点,并仅解析该节点。

  3. 例如:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html dir="ltr">
    
        <head>
            <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/claro/claro.css">
        </head>
    
        <body class="claro ">
            <div id="container">
                <table id="original">
                    <tr>
                        <td>
                            <input type="text" name="first" id="first" value="testing testing" dojoType="dijit.form.TextBox" trim="true" propercase="true">
                        </td><td>
                            <input type="text" name="second" id="second" value="testing testing" dojoType="dijit.form.TextBox" trim="true" propercase="true">
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2">
                            <select dojoType="dijit.form.FilteringSelect" id="third" name="third">
                                <option value="AP">
                                    Apples
                                </option>
                                <option value="OR" selected>
                                    Oranges
                                </option>
                                <option value="PE">
                                    Pears
                                </option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <input id="fourth" name="fourth" dojoType="dijit.form.CheckBox" value="agreed" checked>
                            <label for="mycheck">
                                I agree
                            </label>
                        </td>
                    </tr>
                </table>
            </div>
            <div>
              <button dojoType="dijit.form.Button" type="button">
                  Add new fields using HTML
                  <script type="dojo/method" event="onClick" args="evt">
                      dojo.xhrGet({
                          url: '_data/mockBackendForXhrBuildDomExample.php',
                          handleAs: 'text',
                          preventCache: true,
                          load: function(data) {
                              // This is a little contrived, but hopefully you get the idea
                              console.log(data);
                              var container = dojo.byId('container');
                              var newTable = dojo.place(data, container, 'last');
                              dojo.parser.parse(newTable);                          
                          },
                          error: function(error) {
                              console.error(error);
                          }
                      });
                  </script>
              </button>
            </div>
        </body>
    
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js"
        djConfig="parseOnLoad: true">
        </script>
        <script type="text/javascript">
            dojo.require("dijit.form.FilteringSelect");
            dojo.require("dijit.form.TextBox");
            dojo.require("dijit.form.CheckBox");
            dojo.require("dijit.form.Button");
            dojo.addOnLoad(function() {
    
    
            });
        </script>
    
    </html>
    

    我在http://telliott.net/dojoExamples/dojo-xhrBuildDomExample.html添加了一个这样的例子。 AJAX调用返回的HTML可以在http://telliott.net/dojoExamples/_data/mockBackendForXhrBuildDomExample.php找到(它使用PHP time()函数,所以不要每秒多次点击按钮!)。

    HTH,

    汤姆

答案 1 :(得分:0)

非常感谢Tom的建议。我是道场新手,不知道地方功能。我改变了我的代码,我可以使用它并在同一个div中放置新的表单字段。我正在使用一个使用以下spring标签的jsp片段:

<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>

&lt;%@ taglib uri =“http://www.springframework.org/tags/form”prefix =“form”%&gt;

当这些位于片段的最顶端时,我会收到ajax错误,指出类型不匹配。我尝试完全删除它们,但随后将放置字段但没有值。我最终将它们放在开始标记内,现在一切正常。

感谢您的帮助。