17

我正在尝试通过 Harves (http://harvesthq.github.com/chosen/) 使用“Chosen”插件,它适用于我传递的静态选项集。但是,我想要的是,每当有人键入不在预填充选项中的内容时,它应该将其作为新选项发送到服务器并在成功响应时,我不仅想将其添加到有效列表中选项,还要让它选择它。

重新加载选项非常简单:

// In ajax response
var newOption = new Option("Text", __value__);
$("#tagSelection").append(newOption);
$("#tagSelection").trigger("liszt:updated");

但是,我不知道如何让“Chosen”插件选择这个作为值。我很想做类似的事情

$("#tagSelection").trigger("liszt:select:__value__"); 

或类似的东西。

有什么建议么?

(ps:我正在尝试构建一个基于选择的“标记”插件。因此,如果输入的标记不存在,它会将其添加到服务器,然后立即选择它。)

4

8 回答 8

10

这些是我为解决这个问题而对所选插件(jquery 版本)所做的完整更改

Chosen.prototype.choice_build = function(item) {
  this.new_term_to_be_added = null; 
  // ....
};

Chosen.prototype.no_results = function(terms) {
  // ....
  no_results_html.find("span").first().html(terms);
  this.new_term_to_be_added = terms;
  return this.search_results.append(no_results_html);
};


Chosen.prototype.keydown_checker = function(evt) {
       // ...
        case 13:
          if(this.new_term_to_be_added != null &&  this.options.addNewElementCallback != null) {
              var newElement = this.options.addNewElementCallback(this.new_term_to_be_added);


              if(newElement!=null && newElement.length == 1) {
                  // KEY TO SOLVING THIS PROBLEM
                  this.result_highlight = newElement;
                  // This will automatically trigger the change/select events also. 
                  // Nothing more required.
                  this.result_select(evt);
              }
              this.new_term_to_be_added = null;
          }
          evt.preventDefault();
          break;
          // ...
};

this.new_term_to_be_added 维护当前键入的字符串,该字符串不在预定义选项中。

options.addNewElementCallback 是调用函数的回调,以允许他们处理它(将其发送到服务器等),并且它必须是同步的。下面是骨架:

var addTagCallback = function(tagText) {
    var newElement = null;
    $.ajax({url : that.actionUrl, 
        async : false, 
        dataType: "json",
        data : { // ....},
        success : function(response) {
        if(response) {
                            $('#tagSelection').append(
                                $('<option></option>')
                                      .val(data.Item.Id)
                                      .html(data.Item.Value)
                                      .attr("selected", "selected"));
            $("#tagSelection").trigger("liszt:updated");
            // Get the element - will necessarily be the last element - so the following selector will work
            newElement = $("#tagSelection_chzn li#tagSelection_chzn_o_" + ($("#tagSelection option").length - 1));
        } else {
            // Handle Error
        }
    }});
    return newElement;
};

newElement 是一个 jquery 元素 - 选项列表中最新添加的 li 对象。

通过这样做。result_highlight = newElement; 和 this.result_select(evt); 我告诉 Chosen 插件选择这个。无论是单选还是多选,这都有效。Rifky 的解决方案仅适用于单选。

于 2012-03-14T09:08:03.423 回答
10

我一直在做这个。我不喜欢 Shreeni 的设置选择线(无冒犯),所以我选择了

$('#tagSelection').append(
    $('<option></option>')
        .val(data.Item.Id)
        .html(data.Item.Value)
        .attr("selected", "selected"));
$("#tagSelection").trigger("liszt:updated");

我个人认为它更干净(用多选框测试,效果很好)

于 2012-04-16T18:36:08.987 回答
6

已在此处创建了包含您想要的功能的分叉。这个叉子被称为 koenpunt 叉子。

您可以在harveshq github 站点上继续讨论此功能

我对发生的事情的总结:

  1. 很多人想要这个功能
  2. 一些人使用提议的解决方案创建了拉取请求
  3. 最好的解决方案是pull-request 166
  4. “选择”的作者决定不包含该功能
  5. koenpunt(pull-request 166 的作者)创建了一个 'chosen' 的分支
  6. 人们已经开始放弃“chosen”的harveshq版本,转而使用koenpunt fork
于 2013-07-02T15:39:16.187 回答
4

从 1.0 版开始,上面的一些建议不再相关。这是所有需要的:

--- /home/lauri/Downloads/chosen_v1.0.0 (original)/chosen.jquery.js
+++ /home/lauri/Downloads/chosen_v1.0.0 (modified)/chosen.jquery.js
@@ -408,8 +408,18 @@
           break;
         case 13:
           evt.preventDefault();
-          if (this.results_showing) {
+          if (this.results_showing && this.result_highlight) {
             return this.result_select(evt);
+          }
+          var new_term_to_be_added = this.search_field.val();
+          if(new_term_to_be_added && this.options.add_term_callback != null) {
+              var newTermID = this.options.add_term_callback(new_term_to_be_added);
+              if(newTermID) {
+                this.form_field_jq.append(
+                  $('<option></option>').val(newTermID).html(new_term_to_be_added).attr("selected", "selected")
+                );
+                this.form_field_jq.trigger("chosen:updated");
+              }
           }
           break;
         case 27:

选项如下:

{add_term_callback: addTagCallback, no_results_text:'Press Enter to add:'}

这意味着如果“Orange”不在水果列表中,它只会提示:

按 Enter 键添加:“橙色”

回调应通过任何必要的方式注册新术语,并返回新选项的 ID(或底层选择元素上下文中的值)。

var addTagCallback = function(tagText) {
  // do some synchronous AJAX 
  return tagID;
};
于 2013-08-08T13:27:45.373 回答
1

我这样做很简单,而且效果很好:

// this variable can be filled by an AJAX call or so
var optionsArray = [ 
    {"id": 1, "name": "foo"}, 
    {"id": 2, "name": "bar"}
];

var myOptions = "<option value></option>";
for(var i=0; i<optionsArray.length; i++){
    myOptions +=  '<option value="'+optionsArray[i].id+'">'+optionsArray[i].name+'</option>';
}

// uses new "chosen" names instead of "liszt"
$(".chosen-select").html(myOptions).chosen().trigger("chosen:updated");
于 2013-08-21T14:33:58.743 回答
0

在您的 ajax 响应中,尝试

var newOption = new Option("Text", __value__);  
$("#tagSelection").append(newOption);  
**/*  add this line */  
$("#tagSelection").val(__value__);**  
$("#tagSelection").trigger("liszt:updated");  
于 2012-03-14T05:08:18.087 回答
0

我认为这不是最佳做法,但这段代码对我有用。数据返回有一个html标签<option>

$.post("url.php",{data:data},function(data){
$('.choosen').empty().append(data);
$(".choosen").trigger("liszt:updated");
});
于 2013-05-03T07:14:41.877 回答
0

你不需要太大的压力,保持简单。您需要在选择框 html 中添加您的 ajax 响应,然后更新选择。

这看起来像..

代码:

var baseURL='Your Url';

 $.ajax({

           type: "POST",

           url: baseURL+"Your function", //enter path for ajax

           data: "id="+id,   //pass any details

           success: function(response){   //get response in json_encode()formate
                  
                 var json_data = JSON.parse(response);

                  var i=0; var append='';

                  if((json_data['catss_data'].length > 0)){

                      for(i=0;i < json_data['response_data'].length; i++){

                          append+="<option value='"+json_data['response_data'][i].category_name+"'>"+json_data['response_data'][i].category_name+"</option>";
                                   // make response formate in option 

                        }

                    $('#(selectbox-id)').html(append);   // enter select box id and append data in it

                     }

                 }

           $("#(selectbox-id)").trigger("chosen:updated");  // enter select box id and update chosen

   });   
于 2017-01-10T07:09:34.290 回答