动态添加其他文本输入字段后,jQuery自动完成失败

时间:2014-07-13 03:53:29

标签: javascript jquery ruby-on-rails-3 jquery-ui autocomplete

**更新**我将HTML ID改为了类。并将建议纳入当前的最佳答案。自动填充功能现在可以使用,但自动填充选项列表无法成功显示动态加法文本输入字段。它适用于原版。

我在下面添加了更新的代码。

我刚刚在我的Rails应用程序中将jQuery UI自动完成添加到表单中。该功能正常工作但是当我动态添加具有相同类的另一个输入字段时它不起作用吗?

<a href="#" class="addNewIngredient">Add ingredient</a>

动态添加其他字段后,原始字段的自动填充功能可以继续正常运行,但新添加的字段的自动完成功能不起作用。

如果输入字段共享相同的ID,为什么动态添加字段的自动完成功能会失败?

的application.js

$(document).ready(function(){
$(".addNewIngredient").on('click', function(e){
  e.preventDefault();
$(".ingredientField").append($("#new_ingredients_form").html());
$(".select_ingredient").autocomplete({
        minLength: 2,
        source: '/ingredients',
        focus: function(event, ui) {
            $('.select_ingredient').val(ui.item.name);
            return false;
        },
        select: function(event, ui) {
            $('.select_ingredient').val(ui.item.name);
    $('.link_ingredient_id').val(ui.item.id);
            return false;
        }
    })
    .data( "ui-autocomplete" )._renderItem = function( ul, item ) {
        return $( "<li></li>" )
            .data( "ui-autocomplete-item", item )
            .append( "<a>" + item.name + "</a>" )
            .appendTo( ul );
    };
});

$(".removeIngredient").on('click', function(e){
  e.preventDefault();
$(".ingredientField #new_ingredients_form").empty();
});
});

new.html.erb

<h1>Create Meal</h1>
<%= form_for(@meal) do |f| %>

  <%= f.label :name %>
  <%= f.text_field :name %><br/>

  <div class="ingredientField">
    <%= render "ingredient_form" %>
  </div>
  <a href="#" class="addNewIngredient">Add ingredient</a>
  <a href="#" class="removeIngredient">Remove ingredient</a>

  <%= f.label :clean_up %>
  <%= f.select :clean_up, options_for_select([["", ""],["Low", "low"], ["Med", "med"], ["High", "high"]]) %><br/>

  <%= f.label :homemade %>
  <%= f.select :homemade, options_for_select([["Yes", true],["No", false]])  %><br/>

  <%= f.submit "Save" %>
<% end %>

_ingredient_form.html.erb

    <script type="text/javascript">
    $(function() {
 // Below is the name of the textfield that will be autocomplete
    $('.select_ingredient').autocomplete({
 // This shows the min length of charcters that must be typed before the autocomplete looks for a match.
            minLength: 2,
 // This is the source of the auocomplete suggestions. In this case a list of names from the people controller, in JSON format.
            source: '<%= ingredients_path(:json) %>',
  // This updates the textfield when you move the updown the suggestions list, with your keyboard. In our case it will reflect the same value that you see in the suggestions which is the person.given_name.
            focus: function(event, ui) {
                $('.select_ingredient').val(ui.item.name);
                return false;
            },
 // Once a value in the drop down list is selected, do the following:
            select: function(event, ui) {
 // place the person.given_name value into the textfield called 'select_origin'...
                $('.select_ingredient').val(ui.item.name);
 // and place the person.id into the hidden textfield called 'link_origin_id'.
        $('.link_ingredient_id').val(ui.item.id);
                return false;
            }
        })
 // The below code is straight from the jQuery example. It formats what data is displayed in the dropdown box, and can be customized.
        .data( "ui-autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
 // For now which just want to show the person.name in the list.
                .append( "<a>" + item.name + "</a>" )
                .appendTo( ul );
        };
    });
    </script>


<div class="ingredientsForm" id="new_ingredients_form">
  <%= label_tag "ingredients" %>
  <input class="select_ingredient"/>
  <input class="link_ingredient_id" name="link[ingredient_id]" type="hidden"/>
  <%= label_tag "servings" %>
  <%= text_field_tag "servings[]" %>
</div>

ingredients_controller.rb

class IngredientsController < ApplicationController
  before_filter :authenticate_user!

  def index
    if params[:term]
      @ingredients = Ingredient.find(:all,:conditions => ['name LIKE ?', "#{params[:term]}%"])
    else
      @ingredients = Ingredient.all
    end

    respond_to do |format|
      format.html
      format.json { render :json => @ingredients.to_json }
    end
  end
end

3 个答案:

答案 0 :(得分:3)

使用$(document).on("keydown.autocomplete",".select_ingredient",function(e){}

修复了此问题

完全修订的功能:

<script type="text/javascript">
$(function() {
$(document).on("keydown.autocomplete",".select_ingredient",function(e){
$(this).autocomplete({
         minLength: 2,
        source: '<%= ingredients_path(:json) %>',
        focus: function(event, ui) {
            $(this).val(ui.item.name);
            return false;
        },
         select: function(event, ui) {
             $(this).val(ui.item.name);
     $('.link_ingredient_id').val(ui.item.id);
            return false;
        }
    })
     .data( "ui-autocomplete" )._renderItem = function( ul, item ) {
        return $( "<li></li>" )
            .data( "item.autocomplete", item )
             .append( "<a>" + item.name + "</a>" )
            .appendTo( ul );
    };
  });
});
</script>

答案 1 :(得分:2)

尝试使用:

$(document).ready(function(){
$("#addNewIngredient").on('click', function(){
  e.preventDefault();
$("#ingredientField").append($("#new_ingredients_form").html());
});

$("#removeIngredient").on('click', function(){
  e.preventDefault();
$("#ingredientField #new_ingredients_form").empty();
});
});

请参阅第一个答案here.

您可以做的其他事情是:在函数中编写jquery代码(比如applyJquery())并写入 href="#" onclick="applyJquery();href="javascript:applyJquery();

Jquery通常不能像动态创建的元素那样使用静态元素。

使用.on(),请参阅示例here

编辑:写:$(文件).on(&#34;事件&#34;,&#34; .class&#34;,函数(e){$(this).autocomplete({//写点东西});

答案 2 :(得分:1)

应该是

$('form').on('click', '#addNewIngredient', function() {...

但重复的ID是无效的html,所以你应该使用classname而不是id属性,例如。

<a href="javascript:;" class="addNewIngredient">Add ingredient</a>

$('form').on('click', '.addNewIngredient', function() {...
相关问题