質問

I'm trying to add some functionality to jQuery plugin tag-it based on auto-complete :

a) I try to filtering my JSON data to display only name of tag.

A JSON sample returned by /repo/json :

[{id:1, name:"0.8-alpha-1", category:"version"}, {id:2, name:"0.8-alpha-2", category:"version"}, {id:3, name:"0.8-alpha-3", category:"version"}, {id:4, name:"0.8-alpha-4", category:"version"}, {id:5, name:"0.8-alpha-1", category:"version"}, {id:6, name:"0.8-alpha-2", category:"version"}, {id:7, name:"0.8-alpha-3", category:"version"}, {id:8, name:"0.8-alpha-4", category:"version"}]

b) I want to submit the id of the tag when user submits data, and not the name.

c) I try to add some constraint to my tag-it input field : user cannot validate a tag which is not in the JSON returned by my /repo/json call.

I don't want to fork tag-it repository, and it seems possible to to test intersection between user array and search with beforeTagAdded option.

I try without success at this time, because I don't know where I can find the list of tags to realize intersection.

My js code :

 $(function(){
    $("#singleFieldTags").tagit({
      tagSource: function(search, showChoices) {
        $.ajax({
          url: "/repo/json",
          dataType:   "json",
          data: {q: search.term},
          success: function(choices) {
            showChoices(choices);
          }
        })},
           beforeTagAdded: function(event, ui) {
           //if ($.inArray(ui.tagLabel, search) == -1) {
           //   $("#singleFieldTags").tagit("removeTagByLabel", ui.tagLabel);
           // }
            console.log(ui.tag);
           }});

    });

The html form :

<form name="data" action="/repo/uploadMole" method="POST" enctype="multipart/form-data">
    <input name="tags" id="singleFieldTags" ><br/>
    <input type="Submit">
</form>
役に立ちましたか?

解決

You ask you want to submit, something different. Then lets take that single point of entry:

$('#data').submit(function() {
    // Change the value we are submitting
    var tagids = [];
    $.each($('#singleFieldTags').val().split(','),
           function(idx, taglabel){
               tagids.push(lookup_tagid_for_label(taglabel));
           }
    )
    $('#singleFieldTags').val(tagids.join(','));          
    return true; // Let the event go on.
});

That should change the labels with the ids before submit.

lookup_tagid_for_label, could either do the ajax call again, but it may be cheaper to cache it on the field at first lookup:

$("#singleFieldTags").tagit({
     autocomplete: {
        source: function(search, showChoices) {
                    $.getJSON("/repo/json", {q: search.term},
                        function (data) {
                            var choices = [];
                            $.each(data, function (idx, tag) {
                                choices.push(tag.name);
                                $("#singleFieldTags").data(tag.name, tag.id);
                            });
                            showChoices(choices);
                    });
                }
});

Then you can replace lookup_tagid_for_label(taglabel) with $("#singleFieldTags").data(taglabel).

In contrary to my other answer, that expected tag-it to follow the autocomplete-api, this works now.

他のヒント

Changing the tags when they are added breaks removal and possibly other things as well. You could try the mitigate that by writing a beforeTagRemoved handler and possibly other handlers in the future. (a pain to maintain).

As I commented you should use the autocomplete api. The doc points further to jquery-ui. The data can be in this form:

... An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ]

So I suspect this could be enough:

 $("#singleFieldTags").tagit({
     autocomplete: {
        source: function(search, showChoices) {
                    $.getJSON("/repo/json", {q: search.term},
                              function(data) {
                                  var choices = [];
                                  $.each(data, function(idx, tag){
                                      choices.push({label: tag.name,
                                                    value: tag.id})
                                      });
                                  showChoices(choices);
                              });
                }
         }
     })

Sadly this doesn't work as expected as tag-it, currently drops the label and uses just the id, when creating the tag. I think tag-it should be cleaned up and support the complete autocomplete api.

Update

The maintainer agrees with this. So this answer may become the canonical answer in the future.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top