【问题标题】:jQuery Autocomplete rendertem__ Cant Return Value Within If StatementjQuery Autocomplete rendertem__ 不能在 If 语句中返回值
【发布时间】:2021-10-26 23:40:24
【问题描述】:

尝试使用 jQuery Autocomplete 呈现搜索列表,但是我的目标是,一旦将列表项附加到页面(用户选择一个项目,并且用户可以选择多个项目),用户就无法搜索相同的项目。

HTML 代码

                 <div id='feature-searchbar'>
                        <label for='feature-search'>Search for applicable features...</label>
                        <input id="feature-search-input" type="text" name="featureSearch-input" placeholder="Search for applicable features..." class="feature__search-input ui-autocomplete-input" autocomplete="off">
                    
                    <div id='feature-results'>
                
                //Selected items go here
                    </div>
                </div>

现在尝试通过将一个类添加到已呈现的项目中来解决它,如果它已经存在于附加页面中。使用 jQuery,如果用户选择一个并以数据类型为目标,我将目标定位在项目将出现的页面上。告诉我的 jQuery '如果数据类型已经存在,添加一个类' 但是我似乎无法在 if 语句之外返回值。

jQuery

                      jQuery("#feature-search-input").autocomplete({
                                appendTo: "#feature-searchbar",
                                source: function (req, res) {
                                    jQuery.ajax({
                                        url: myAPI
                                        data: {
                                            term: jQuery("#feature-search-input").val(),
                                            
                                        },
                                        type: "GET",
                                        datatype: 'json',
                                        crossOrigin: true,
                                        success: function (data) {

                                        // set results to top 6 only
                                        data.length = Math.min(data.length, 5);

                                        
                                        var items = data;

                                        var search_term = jQuery("#feature-search-input").val();

                                        items.push({

                                            label: `<?php _e('More search results for'); ?> "${ search_term }"`,
                                            value: search_term,
                                            more_results: true

                                        });
                                        res(items);
                                        
                                        }
                                    });
                                },
                                select: function(event, ui) {

                                

                                    var featureListItem = `<div class="feature-list-item" data-id="${ui.item.id}">
                                                                <input type='hidden' name='content-feature-ids[]' value='${ui.item.id}'>
                                                                <p>${ ui.item.short_desc }</p> 
                                                                <a class='content-feature-remove'>Remove<a/>
                                                            </div>`;

                                    
                                //append to page
                                jQuery('#feature-results').append(featureListItem);

                                    
                                //removal 
                                    jQuery(".content-feature-remove").click(function (e) {
                                        jQuery(this).parent().remove(); 

                                    });


                                    jQuery("#feature-search-input").val('');


                                }
                            }).data("ui-autocomplete")._renderItem = function( ul, item ) {

                                //TODO: check if item exists within feature-results, do not render it

                                //if item is rendered onto feature-results { add: class which tells user it has already been selected}
                                var item_label = '';

                                //need to validate items somehow so they do not get selected twice
                                
                                

                                if (item.id && item.short_desc) {

                                    item_label = `
                                                    <div class='rendered-feature-item' data-id="${item.id}">
                                                        <p>${ item.short_desc }</p>     
                                                    </div>  
                                                    `;          
                                } else { 
                                    item_label = `<strong>No Results</strong>`;
                                }

//need to validate items somehow so they do not get selected twice
//target the html and check if data-type is same as item.id

                                var existing_feature = jQuery(`#feature-results .feature-list-item[data-id="${item.id}"]`)
                                var existing_feature_id = 0;
                                var variable = '';
                                if (existing_feature !== undefined && existing_feature !== null) { 
                                    existing_feature_id = existing_feature.data('id');
                                    if (existing_feature_id !== undefined && existing_feature_id !== null) {
                                        console.log(existing_feature_id);

                                        var potential_existing = jQuery('.rendered-feature-item[data-id="'+existing_feature_id+'"]');
                                        var potential_existing_id = potential_existing;
                                        return existing_feature_id;
                                    }
                                    return existing_feature_id;
                                }   

//here is where I get errors, code does not recognize existing_feature_id
                                        
                                   var potential_existing_id = existing_feature_id
var potential_existing_item = jQuery('.rendered-feature-item[data-id="'+potential_existing_id+'"]')


                                    potential_existing_item.css('color', 'red');

                                            

                                return jQuery( '<li>' )
                                .attr( "data-value", item.id )
                                .append( item_label )
                                .appendTo( ul );
                            };

                        
                        });

我必须运行 if 语句的原因是 id 变量作为 id 返回,但同时也作为“未定义” 目前收到一个错误,指出 未捕获的 TypeError:this._renderItem(...).data 不是函数

【问题讨论】:

标签: javascript jquery jquery-ui jquery-ui-autocomplete


【解决方案1】:

考虑以下示例。这与https://jqueryui.com/autocomplete/#multiple 松散相关

jQuery(function($) {
  var availableFeatures = [{
      label: "ActionScript",
      value: "ActionScript",
      id: "1"
    },
    {
      label: "AppleScript",
      value: "AppleScript",
      id: "2"
    },
    {
      label: "Asp",
      value: "Asp",
      id: "3"
    },
    {
      label: "BASIC",
      value: "BASIC",
      id: "4"
    },
    {
      label: "C",
      value: "C",
      id: "5"
    }
  ];

  function getFeatures(apiUrl, searchTerm) {
    var results;
    $.ajax({
      url: apiUrl,
      data: {
        term: searchTerm,
      },
      type: "GET",
      datatype: 'json',
      crossOrigin: true,
      success: function(data) {
        results = data;
      }
    });
    return results;
  }

  function filterResults(fArr, results) {
    $.each(fArr, function(i, el) {
      var index = results.map(function(e) {
        return e.label;
      }).indexOf(el);
      if (index > -1) {
        results.splice(index, 1);
      }
    });
    return results;
  }

  function getCurrentFeatures(target) {
    var features = [];
    $(".feature-list-item", target).each(function(i, el) {
      features.push($("p", el).text().trim());
    });
    return features;
  }

  function addFeature(item) {
    var featureItem = $("<div>", {
      class: "feature-list-item"
    }).data("feature-id", item.id);
    $("<p>").html(item.label).appendTo(featureItem);
    $("<a>", {
      class: "content-feature-remove",
      title: "Remove Feature"
    }).html("X").appendTo(featureItem);
    $("#feature-results").append(featureItem);
    if ($("#selectedFeatures").val() == "") {
      $("#selectedFeatures").val(item.id);
    } else {
      var selected = $("#selectedFeatures").val().split(",");
      selected.push(item.id);
      $("#selectedFeatures").val(selected.join(","));
    }
  }

  function removeFeature(item) {
    var thisId = $(item).closest(".feature-list-item").data("feature-id");
    console.log("Remove Feature", thisId);
    $(item).parent().remove();
    var selected = $("#selectedFeatures").val().split(",");
    var index = selected.indexOf(thisId);
    console.log(selected, index);
    if (index > -1) {
      selected.splice(index, 1);
    }
    $("#selectedFeatures").val(selected.join(","));
  }

  $("#feature-search-input").autocomplete({
    source: function(request, response) {
      // Example og getting data
      // var myData = getFeatures("/results", request.term);

      var myData = availableFeatures;
      myData = filterResults(getCurrentFeatures("#feature-results"), myData);
      myData = $.ui.autocomplete.filter(myData, request.term);
      response(myData);
    },
    focus: function() {
      return false;
    },
    select: function(e, ui) {
      addFeature(ui.item);
      $(this).val("").autocomplete("search", "");
      return false;
    }
  });

  $("#feature-results").on("click", ".content-feature-remove", function(event) {
    event.preventDefault();
    removeFeature(this);
  });

  /*$("#feature-search-input").autocomplete({
    appendTo: "#feature-searchbar",
    source: function(req, res) {
      $.ajax({
        url: myAPI
        data: {
          term: $("#feature-search-input").val(),
        },
        type: "GET",
        datatype: 'json',
        crossOrigin: true,
        success: function(data) {
          var items = [];
          items.push({
            label: data.label,
            value: data.value
          });
          res(items);
        }
      });
    },
    select: function(event, ui) {
      var featureListItem = `<div class="feature-list-item" data-id="${ui.item.id}"><input type='hidden' name='content-feature-ids[]' value='${ui.item.id}'><p>${ ui.item.short_desc }</p><a class='content-feature-remove'>Remove<a/></div>`;
      $('#feature-results').append(featureListItem);
      $(".content-feature-remove").click(function(e) {
        $(this).parent().remove();
      });
      $("#feature-search-input").val('');
    }
  }).data("ui-autocomplete")._renderItem = function(ul, item) {
    var item_label = '';
    if (item.id && item.short_desc) {
      item_label = `<div class='rendered-feature-item' data-id="${item.id}"><p>${ item.short_desc }</p></div>`;
    } else {
      item_label = `<strong>No Results</strong>`;
    }
    var existing_feature = $(`#feature-results .feature-list-item[data-id="${item.id}"]`);
    var existing_feature_id = 0;
    var variable = '';
    if (existing_feature !== undefined && existing_feature !== null) {
      existing_feature_id = existing_feature.data('id');
      if (existing_feature_id !== undefined && existing_feature_id !== null) {
        console.log(existing_feature_id);
        var potential_existing = jQuery('.rendered-feature-item[data-id="' + existing_feature_id + '"]');
        var potential_existing_id = potential_existing;
        return existing_feature_id;
      }
      return existing_feature_id;
    }
    var potential_existing_id = existing_feature_id
    var potential_existing_item = jQuery('.rendered-feature-item[data-id="' + potential_existing_id + '"]')
    potential_existing_item.css('color', 'red');
    return jQuery('<li>')
      .attr("data-value", item.id)
      .append(item_label)
      .appendTo(ul);
  };
  */
});
.feature-list-item {
  border: 1px solid #9f9f9f;
  border-radius: 6px;
  display: inline-block;
  padding: 3px 6px;
  margin-right: 3px;
}

.feature-list-item p {
  display: inline-block;
  font-size: 11px;
  font-family: sans-serif;
  padding: 0;
  margin: 0;
  padding-right: 3px;
  color: #2f2f2f;
}

.content-feature-remove {
  font-size: 10px;
  font-family: sans-serif;
  font-weight: bold;
  display: inline-block;
  color: #999;
  border: 1px solid #999;
  border-radius: 50%;
  width: 12px;
  height: 12px;
  text-align: center;
  cursor: pointer;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id='feature-searchbar'>
  <label for='feature-search'>Search for applicable features...</label>
  <input id="feature-search-input" type="text" name="featureSearch-input" placeholder="Search for applicable features..." class="feature__search-input ui-autocomplete-input" autocomplete="off">
  <div id='feature-results'></div>
  <input id="selectedFeatures" type="hidden" name="content-feature-ids" />
</div>

考虑到您的 AJAX 将返回一个对象数组,我设置了示例来处理这种情况。

当用户选择一个项目时,它会将它添加到一个列表中,并更新一个文本字段。随着更多项目的添加或删除,文本字段会更新为每个功能的 ID。

建议列表将过滤结果并排除已选择的任何结果。

sn-p 不能显示 AJAX。您将看到一个帮助从 PHP 获取数据的函数。像这样运行它:

var myFeatures = getFeatures("/features.php", "feature");

这将对搜索词提供的 URL 执行 GET 请求。你的 PHP 会想要返回一个对象数组:

[{
  label: "Feature 1",
  value: "Feature 1"
  id: "f001"
}];

如果你愿意,你可以有比 'id' 更多的参数,但你必须有 labelvalue 才能自动完成。

具有标签和值属性的对象数组:[ { label: "Choice1", value: "value1" }, ... ]

我的示例使用以下行:

myData = $.ui.autocomplete.filter(myData, request.term);

您可以在脚本中省略这一行,因为 PHP 应该为您过滤结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2010-11-17
    • 2018-04-18
    • 2020-12-15
    • 2016-02-12
    相关资源
    最近更新 更多