jQuery select2:正在重新创建重复标签

jQuery select2: duplicate tag getting recreated

我今天早些时候问了一个问题 ()。但是,我正在尝试修复它并这样做,现在我遇到了一些奇怪的问题。我不确定为什么会这样。

下面是 JavaScript 代码。

<div class="form-group">
   <label class="col-sm-4 control-label">Product Name</label>
   <div class="col-sm-6">       
      <input type="hidden" id="tags" style="width: 300px"/>
   </div>
</div>

<script type="text/javascript">
var lastResults = [];

$("#tags").select2({
    multiple: true,
    placeholder: "Please enter tags",
    tokenSeparators: [","],
    initSelection : function (element, callback) {
        var data = [];
        $(element.val().split(",")).each(function () {
            data.push({id: this, text: this});
        });
        callback(data);
    },
    ajax: {
        multiple: true,
        url: "fetch.php",
        dataType: "json",
        type: "POST",
      data: function(term) {
                        return {q: term};
                    },
                    results: function(data) {
                        return {results: data};
                    }, 

    },
    createSearchChoice: function (term) {
        var text = term + (lastResults.some(function(r) { return r.text == term }) ? "" : " (new)");
        return { id: term, text: text };
    },
});

$('#tags').on("change", function(e){
    if (e.added) {
        if (/ \(new\)$/.test(e.added.text)) {
           var response = confirm("Do you want to add the new tag "+e.added.id+"?");
           if (response == true) {
              alert("Will now send new tag to server: " + e.added.id);
              /*
               $.ajax({
                   type: "POST",
                   url: '/someurl&action=addTag',
                   data: {id: e.added.id, action: add},    
                   error: function () {
                      alert("error");
                   }
                });
               */
           } else {
                console.log("Removing the tag");
                var selectedTags = $("#tags").select2("val");
                var index = selectedTags.indexOf(e.added.id);
                selectedTags.splice(index,1);
                if (selectedTags.length == 0) {
                    $("#tags").select2("val","");
                } else {
                    $("#tags").select2("val",selectedTags);
                }
           }
        }
    }
});
</script>

这里是 php 代码 (fetch.php)

<?php 
// connect to database 
require('db.php');

// strip tags may not be the best method for your project to apply extra layer of security but fits needs for this tutorial 
$search = strip_tags(trim($_GET['q'])); 
//$search='te';
// Do Prepared Query 
$query = $mysqli->prepare("SELECT tid,tag FROM tag WHERE tag LIKE :search LIMIT 4");

// Add a wildcard search to the search variable
$query->execute(array(':search'=>"%".$search."%"));

// Do a quick fetchall on the results
$list = $query->fetchall(PDO::FETCH_ASSOC);

// Make sure we have a result
if(count($list) > 0){
   foreach ($list as $key => $value) {
    $data[] = array('id' => $value['tid'], 'text' => $value['tag']);                
   } 
} else {
   $data[] = array('id' => '0', 'text' => 'No Products Found');
}

// return the result in json
echo json_encode($data);

?>

select2版本为3.5

以上代码可以通过fetch.php从数据库send/receive请求。

问题是在我的数据库中有两条记录 test & temp 当我标记其中任何一条时它会创建新标记。

它应该像这样工作:如果数据库有值,那么它不会创建同名的新标签。

更新

标签需要一个 ID 和一个文本。您遇到的问题是您的文本与 ID 不匹配。

因此,即使您编写相同的文本,Select2 也会认为新文本是一个新选项,因为 id 不匹配。

要解决您的问题,您需要将 id 设置为与文本相同的值。将 fetch.php 的 foreach 更改为以下内容:

foreach ($list as $key => $value) {
    $data[] = array('id' => $value['tag'], 'text' => $value['tag']);                
} 

更新: 您还需要更新变量 lastResults 以避免重复使用相同文本的标签。绑定select2的时候需要把ajaxresults 属性改成这样(基于this answer:

ajax: {
    multiple: true,
    url: "fetch.php",
    dataType: "json",
    type: "POST",
    data: function(term) {
        return {q: term};
    },
    results: function(data) {
        lastResults = data.results;
        return {results: data};
    }, 
},

注意 lastResults = data.results;。没有这个,lastResults变量总是空的,当createSearchChoice函数被执行时,它总是return一个新标签。

终于可以使用了。我要感谢@alex 和@milz 的支持。 这是完整的 n 最终代码。现在不会创建重复标签。但是,我正在努力在数据库中添加标签。

php/html 文件

<div class="form-group">
   <label class="col-sm-4 control-label">Product Name</label>
   <div class="col-sm-6">
      <input type="hidden" id="tags" style="width: 300px"/>
   </div>
</div>

<script type="text/javascript">
var lastResults = [];

$("#tags").select2({
    multiple: true,
    tags: true,
    placeholder: "Please enter tags",
    tokenSeparators: [',', ' '],//[","],
    initSelection : function (element, callback) {
        var data = [];
        $(element.val().split(",")).each(function () {
            data.push({id: this, text: this});
        });
        callback(data);
    },
    ajax: {
        multiple: true,
        url: "fetch.php",
        dataType: 'json',
      //  type: "POST",
       data: function(term,page) {
                        return {
                            term: term
                           };
                    },
                    results: function(data,page) {
                         lastResults = data;                       
                          return {results: data};

                    }, 
    },
    maximumSelectionSize: 3,
    minimumInputLength: 3,
createSearchChoice: function(term) {
    console.log($(this).attr('data'));
    var text = term + (lastResults.some(function(r) {

     console.log(r.text);
      console.log(term);
      return r.text == term
    }) ? "" : " (new)");

    return {
      id: term,
      text: text
    };
  },
});

$('#tags').on("change", function(e){
    if (e.added) {
        if (/ \(new\)$/.test(e.added.text)) {

           var response = confirm("Do you want to add the new tag "+e.added.id+"?");
           if (response == true) {
              alert("Will now send new tag to server: " + e.added.id);
              /*
               $.ajax({
                   type: "POST",
                   url: '/someurl&action=addTag',
                   data: {id: e.added.id, action: add},    
                   error: function () {
                      alert("error");
                   }
                });
               */
           } else {
                console.log("Removing the tag");
                var selectedTags = $("#tags").select2("val");
                var index = selectedTags.indexOf(e.added.id);
                selectedTags.splice(index,1);
                if (selectedTags.length == 0) {
                    $("#tags").select2("val","");
                } else {
                    $("#tags").select2("val",selectedTags);
                }
           }
        }
    }
});
</script>

这里是 php 文件,用于从数据库中获取数据。 fetch.php

<?php 
// connect to database 
require('db.php');

// strip tags may not be the best method for your project to apply extra layer of security but fits needs for this tutorial 
//if(isset($_GET)){
$search = strip_tags(trim($_GET['term'])); 

// Do Prepared Query 
$query = $mysqli->prepare("SELECT tid,tag FROM tag WHERE tag LIKE :search LIMIT 4");

// Add a wildcard search to the search variable
$query->execute(array(':search'=>"%".$search."%"));

$list = $query->fetchall(PDO::FETCH_ASSOC);

if(count($list) > 0){
   foreach ($list as $key => $value) {
    $data[] = array('id' => $value['tag'], 'text' => $value['tag']);            
   } 
} else {
   $data[] = array('id' => 'No Products Found', 'text' => 'No Products Found');
}

echo json_encode($data);

?>

花了很多时间。将近3天。我希望它能节省一些人的精力。

应用下面 select2.min.js (v4.0.6-rc.1) 代码片段中的更改

第 1 部分

c.on("results:select", function() {
                    var a = e.getHighlightedResults();
                    if (0 !== a.length) {
                        var c = b.GetData(a[0], "data");
                        "true" == a.attr("aria-selected") ? e.trigger("close", {}) : e.trigger("select", {

                        //custom select2 tagging
                        if(a.attr("aria-selected")){
                            c.id = c.id + 1;
                        }
                        e.trigger("select", {
                            data: c
                        })

                        //"true" == a.attr("aria-selected") ? e.trigger("close", {}) : e.trigger("select", {
                        // e.trigger("select", {
                        //     data: c
                        // })

                    }
                })

第 2 部分

this.on("query", function(b) {
                    a.isOpen() || a.trigger("open", {}), this.dataAdapter.query(b, function(c) {
                        //custom select2 tagging
                        let searchInput = $(".select2-search__field").val();
                        searchInput = {results: [{id: searchInput, text: searchInput}]};
                        a.trigger("results:all", {
                            data: c,
                            data: searchInput,
                            query: b
                        })
                    })
                })