使用原型ajax.updater更新多个选择选项

时间:2014-04-18 10:16:38

标签: javascript php ajax prototypejs

我查看了Ajax.Updater()的文档,其中构造函数的第一个参数是

  

container (String | Element) - DOM元素,其内容将作为Ajax请求的结果进行更新。可以是DOM节点或标识节点ID的字符串。

但我想使用Ajax.Updater()更新两个选择框。我应该在第一个参数中传递什么?可能吗?

供参考,html外观如下:

<select id="options_one">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
</select>
<!-- some other html code -->
<select id="options_two">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
</select>

两个<select>都包含相同的值,应在Ajax success之后更新。

2 个答案:

答案 0 :(得分:1)

搞定了。这是代码:

new Ajax.Request('/request/url', {
    method: 'post',
    parameters: {cid: '12', mid: '45'},
    onSuccess: function(transport) {
        var response = transport.responseText;
        $('options_one').update(response);
        $('options_two').update(response);
    },
    onFailure: function(transport) {
        alert('failed ' + transport.responseText);
    }
});

<强>更新

  

insertion (String):默认情况下,使用 Element.update ,这意味着响应的内容将替换容器的整个内容。您可以而不是插入响应文本而不会中断现有内容。 插入选项中的四个字符串之一 - 顶部底部之前之后 strong> - 和Element#insert描述的方式插入响应内容。

所以在我的情况下,使用Ajax.Updater不是一个好的选择。

答案 1 :(得分:0)

首先,您可能根本不想更新这样的选择元素。也许您打算稍后以交互方式使用它们,对吧?您可能想要选择一个选项并在浏览器中执行某些操作?如果您只是将一些选项填入选择的正文中,您将无法获得该效果,而在某些浏览器中,您也不会有任何工作选项。

动态更改选项选项的正确方法是操纵select元素的options集合,如下所示:

var new_options = {4: "Four", 5: "Five", 6: "Six"}; // or from your Ajax callback
var options_two = $('options_two'); // reference the select element
options_two.options.length = 0; // remove existing options
for(var i in new_options){
  // use the constructor new Option() to create a new option for each new value/label pair
  options_two.options[options_two.options.length] = new Option(new_options[i], i);
};

以这种方式完成,您附加到选择的任何观察者仍然可以在以后工作,并且浏览器不会丢失关于您在形式上做什么的线索。

其次,Ajax.Updater是Ajax.Request()和Element.update()的便利包装器。你可以这样想:

new Ajax.Request('your/endpoint', {
  onComplete: function(transport){
    $('your_element').update(transport.responseText);
  }
});

因此,要回答您的问题,在代码中使用Ajax.Updater的方式是将两个select标记包装在一个公共父级中,并让服务器响应返回两个完全组合的select标签。如上所述,其缺点是页面中已有的任何回调将不再具有对原始选择标记的引用 - 它们已经消失,并且替换必须附加新的侦听器。保持此页面打开的时间足够长,并且每次更换拣配器时都会出现内存泄漏。

采取这两个概念并将它们结合起来,这是我在最近的项目中如何做到这一点:

document.on('click', 'input.team', function(evt, elm){
  if($('project_project_template_id')){
    var picker = $('project_project_template_id').enable();
    var team = $$('input.team:checked').first();
    new Ajax.Request('/teams/' + $F(team) + '/project_templates.json', {
      onSuccess: function(xhr){
        var opts = xhr.responseJSON;
        // var none = picker.options[0];
        picker.options.length = 0;
        // picker.options[0] = none;
        opts.each(function(o){
          picker.options[picker.options.length] = new Option(o['name'], o['id']);
        });
      }
    });
  }
});

这是在一个Rails应用程序中,所以这里有一些惯例不在我之前的例子中,但你应该能够从中得到一些东西。如果你有多个选择器要更新,你只需要将它们嵌套在你的JSON响应中,所以你有这样的东西来自服务器:

{"options_one": {4: "Four", 5: "Five"}, "options_two": {6: "Six", 7: "Seven"}}

然后你可以用一个Ajax请求更新两个选择器。