سؤال

أحتاج إلى بعض المساعدة حول كيفية تنفيذ ملف jquery-ui الإكمال التلقائي في تطبيق Rails الخاص بي.

أرغب في إضافة الإكمال التلقائي إلى حقل نص حيث يمكن للمستخدم إدخال اسم العميل. نظرًا لأنه يمكن أن يكون هناك مئات من العملاء ، سأحتاج إلى سحب قيم الإكمال التلقائي المقترح "عن بعد" ، كما في ، من جدول (على الأقل هذا ما أفهمه).

النقطة الرئيسية التي فشلت في فهمها هي كيفية توفير القيم المقترحة إلى مربع النص الإكمال التلقائي. لقد قرأت مستندات JQuery-UI ، لكن يبدو أنني كثيفة بعض الشيء في هذا الشأن.

لذا فإن ما أنا عليه حقًا هو مثال على كيفية جعل هذا العمل في تطبيق Rails ، وليس بالضرورة وصفًا كاملاً لكيفية بناء JavaScript (هذا ما فعله فريق JQuery-Ui من أجلي =)).

على سبيل المثال ، كيف أقوم بإعداد بيانات الإكمال التلقائي ، وكيف يمكنني إرفاق وظيفة الإكمال التلقائي إلى مربع نص.

هل كانت مفيدة؟

المحلول

حسنًا ، لم أحصل على إجابة على سؤالي أعلاه ، لذا انتهى بي الأمر إلى اكتشاف ذلك بنفسي. اعتقدت أنه يجب عليّ نشر الحل الذي توصلت إليه في حالة وجود أي شباب آخرين يتساءلون عن نفس الشيء.

أول شيء يجب أن تعرفه هو أن هذه هي تجربتي الأولى مع JavaScript ، وأنا فقط أحصل على تعليق القضبان. لذلك بكل الوسائل ، لا تتردد في التحرير ، والتعليق في أي مكان تشعر أنه أخطأ في هذا. صواب أو خطأ على الأقل أعرف أنه يعمل بالطريقة التي أردت بها.

أعتقد أن أفضل طريقة لإظهار هذا هو على سبيل المثال. لذا فإن ما يلي هو كيف حصلت على أداة الإكمال التلقائي للعمل في تطبيقي. يمكنك المضي قدمًا ووضع الرمز التالي في تطبيقك حتى لو لم تفهم ما يحدث ، فيمكننا أن نتجاوز كيف يعمل كل جزء بالمثال. بعد ذلك ، يجب أن يكون لديك فهم لكيفية تعديله لاستخدامك أو عكسته.


قم بتضمين jQuery UI في تطبيق Rails الخاص بك.

قم بتنزيل نسخة من jquery ui ومكان jquery-ui-1.8.2.custom.min.js داخل الخاص بك /عام/جافا سكريبت الدليل. تأكد أيضًا من أن لديك نسخة من jQuery نفسها وأن هذا هو أيضًا في نفس المجلد.

قم بتضمين ملف jQuery UI وملف jQuery في الخاص بك application.html.erb ملف مثل هذا.
(يمكنك تسمية الملفات كما يحلو لك طالما أنها تتطابق)

<%= javascript_include_tag 'jquery.min', 'jquery-ui-1.8.2.custom.min.js' %>

في تنزيل jQuery UI ، سيكون لديك مجلد يحتوي على جميع بيانات CSS الخاصة بك. سيختلف الاسم بناءً على السمة التي اخترتها ، على سبيل المثال اخترت السمة "كوبرتينو'. ضع المجلد بأكمله يحتوي على بيانات CSS الخاصة بك إلى '/أوراق أنماط/أنماط/'. ثم قم بتضمين ملف CSS في application.html.erb مثل هذا.

<%= stylesheet_link_tag 'cupertino/jquery-ui-1.8.2.custom' %>


مثال على الإكمال التلقائي javaScript

الآن خذ الجزء التالي من التعليمات البرمجية ووضعه في أحدك "الجديد' الآراء. يمكنك استخدام هذا في أي عرض ، لكن أدرك أنني قد أخذته حرفيًا من وجهة نظر موجودة تنتمي إلى وحدة تحكم تسمى "Links_Controller" ، وهي تقوم بسحب البيانات من "People_Controller". نأمل أن تعرف ما يكفي عن القضبان لتعرف على ما تحتاج إلى تغييره بحيث يناسبك هذا.

-ابدأ جزءًا كبيرًا من التعليمات البرمجية-

    <script type="text/javascript">
    $(function() {

 // Below is the name of the textfield that will be autocomplete    
    $('#select_origin').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: '<%= people_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_origin').val(ui.item.person.given_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_origin').val(ui.item.person.given_name);
 // and place the person.id into the hidden textfield called 'link_origin_id'. 
        $('#link_origin_id').val(ui.item.person.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( "autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
 // For now which just want to show the person.given_name in the list.
                .append( "<a>" + item.person.given_name + "</a>" )
                .appendTo( ul );
        };
    });
    </script>



<h1>New link</h1>

<% form_for(@link) do |f| %>
  <%= f.error_messages %>

<!-- Place the following text fields in your form, the names are not important. What is important is that they match the names in your javascript above -->
  <p>
        Select which person you want to link:<br /> 
<!-- This is the textfield that will autocomplete. What is displayed here is for the user to see but the data will not go anywhere -->
        <input id="select_origin"/>
<!-- This is the hidden textfield that will be given the Persons ID based on who is selected. This value will be sent as a parameter -->
      <input id="link_origin_id" name="link[origin_id]" type="hidden"/>
  </p>
<!-- end of notes -->
  <p>
    <%= f.label :rcvd_id %><br />
    <%= f.text_field :rcvd_id %>
  </p>
  <p>
    <%= f.label :link_type %><br />
    <%= f.text_field :link_type %>
  </p>
  <p>
    <%= f.label :summary %><br />
    <%= f.text_area :summary %>
  </p>
  <p>
    <%= f.label :active %><br />
    <%= f.check_box :active %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

-إنهاء جزء كبير من التعليمات البرمجية-

حسنًا الآن لتوصيل النقاط.


توفير بيانات لإكمال تلقائي لاستخدامها كاقتراحات

دعنا نبدأ بتوصيل بعض البيانات التي يمكن لحقل النص الإكمال التلقائي عرضها في الاقتراحات المنسدلة. التنسيق الذي سنستخدمه هو JSON ، ولكن لا تقلق إذا لم تكن على دراية به ... لا أنا =). من الجيد بما يكفي أن نعرف أنها طريقة لتنسيق النص بحيث يمكن لأجزاء أخرى من التطبيقات الخاصة بك/التطبيقات الأخرى استخدامه.

يتم تحديد البيانات التي سيحتاجها Textfield إلى الإكمال التلقائي في ''مصدر:' اختيار. لأننا نريد إرسال قائمة بأسماء الشعوب ومعرفها إلى الإكمال التلقائي ، سنضع ما يلي كمصدر.

source: '<%= people_path(:json) %>'  

سوف يترجم المساعد القضبان أعلاه إلى سلسلة "/people.json". لا تحتاج إلى إنشاء صفحة في"/people.json". ما عليك القيام به هو إخبار الأشخاص الخاص بك _controller عما يجب فعله عندما يتلقى طلبًا /أشخاصًا مع تنسيق .json. ضع ما يلي في people_controller:

def index  
# I will explain this part in a moment.
  if params[:term]
    @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"])
  else
    @people = Person.all
  end

  respond_to do |format|  
    format.html # index.html.erb  
# Here is where you can specify how to handle the request for "/people.json"
    format.json { render :json => @people.to_json }
    end
end

الآن لدينا جميع الأشخاص في الأشخاص الذين يتم إرسالهم إلى TextField الإكمال التلقائي. هذا يظهر النقطة التالية للغاية.


بيانات التصفية المستخدمة لاقتراح الإكمال التلقائي ، استنادًا إلى الإدخال

كيف يعرف حقل النص الإكمال التلقائي كيفية تصفية النتائج بناءً على ما تكتبه؟

سيرسل عنصر واجهة التحكم التلقائية المعينة إلى Textfield أي شيء تكتبه في حقل Text كمعلمة إلى المصدر الخاص بك :. المعلمة التي يتم إرسالها هي "مصطلح". لذلك إذا كنت تريد كتابة" جو "في حقل النص ، فسنفعل ما يلي:

/people.json?term=joe

هذا هو السبب في أن لدينا ما يلي في وحدة التحكم:

# If the autocomplete is used, it will send a parameter 'term', so we catch that here
    if params[:term]
# Then we limit the number of records assigned to @people, by using the term value as a filter.
      @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"])
# In my example, I still need to access all records when I first render the page, so for normal use I assign all. This has nothing to do with the autocomplete, just showing you how I used it in my situation.
    else
      @people = Person.all
    end

الآن وبعد أن حصرنا عدد السجلات المخصصة للشروط استنادًا إلى ما يتم كتابته في حقل النص الإكمال التلقائي ، يمكننا الآن تحويل ذلك إلى تنسيق JSON للاقتراحات الإكمال التلقائي.

respond_to do |format|  
      format.html # index.html.erb  
      format.json { render :json => @people.to_json }
    end 

الآن ، ما عليك سوى مراجعة التعليقات الموجودة داخل "جزء كبير من التعليمات البرمجية" التي يجب أن تفسر بقية كيفية ارتباط هذا معًا.

في النهاية ، يجب أن يكون لديك حقل نص على صفحتك يعمل كإكمال تلقائي وحقل مخفي يرسل المعرف في معلمة إلى وحدة التحكم الخاصة بك.


تخصيص الإكمال التلقائي الخاص بك

بمجرد أن تفهم ما سبق وتريد تعديله لاستخدامك ، يجب أن تعلم أن التنسيق الذي تم إرجاعه من وحدة التحكم الخاصة بك يبدو مثل هذا:

[{"person":{"id":1,"given_name":"joe","middle_name":"smith","family_name":"jones","nationality":"australian"}}]

ستكون طريقة الوصول إلى القيم المختلفة من سلسلة JSON في JavaScript في هذه الحالة:

ui.item.person.name_of_some_attribute_such_as_given_name

جميلة ، بسيطة. يشبه إلى حد كبير الوصول إلى سمة ActivereCord في القضبان.

ملاحظة أخيرة. قضيت الكثير من الوقت في البحث عن طريقة مختلفة لتزويد القيمة المخفية ، حيث اعتقدت أن هذه الوظيفة كان ينبغي أن تكون مضمنة في عنصر واجهة المستخدم. ولكن هذا ليس هو الحال. يظهر بوضوح في مثال jQuery الرسمي أن طريقة إرسال قيمة مختلفة ثم تم تحديدها كمعلمة ، هي استخدام حقل مخفي.

حسنًا ، آمل أن يساعد شخص ما.

ديل

نصائح أخرى

jQuery 1.9/1.10 أزال الإكمال التلقائي الرئيسي وأضاف uiautocomplete

.data("uiAutocomplete") instead of .data("autocomplete")

بعد التعديل إلى أعلاه ، نجحت بالنسبة لي.

إجابة ديل هو تماما البرنامج التعليمي. شيء واحد يجب ملاحظته هو استخدام استفسارك الأول ، لن تُرجع مصدر البيانات إلا لمباريات بداية مع السلسلة التي تكتبها. إذا كنت تريد البحث في أي مكان في الكلمة ، فأنت بحاجة إلى التغيير:

@people = Person.find(:all,:conditions =>
    ['given_name LIKE ?', "#{params[:term]}%"])

إلى

@people = Person.find(:all,:conditions =>
    ['given_name LIKE ?', "%#{params[:term]}%"])

(أضاف إضافي % إلى الاستعلام)

لقد اتبعت بشكل أساسي نصيحة Dale أدناه ، لكن ملفات التحكم الخاصة بي وملفات JS كانت مختلفة قليلاً- كانت نسخته تعطيني مشكلات لسبب ما (ربما قبل الميلاد من تحديثات jQuery)

السياق: أحاول إكمال أسماء دي جي التي كتبها المستخدمون - أيضًا Newb

وحدة التحكم دي جي

 class DjsController < ApplicationController
    def index
     if params[:term]
       @djs = Dj.is_dj.where('lower(name) LIKE ?', "%#{params[:term].downcase}%")
       respond_to do |format|  
          format.html
          format.json { render :json => @djs.map(&:name) }
       end
     end    
   end
 end

ملف html.erb

  <script type="text/javascript">

$(function() {  
    $('#select_origin').autocomplete({
        source: '<%= djs_path(:json) %>'
      })

    $('.submit-comment').click(function(){
      var dj_name = $('#select_origin').val();
      $('#link_origin_id').val(dj_name);
    })

})

</script>

هذه مساعدة عظيمة.

بالإضافة إلى ذلك إذا كنت بحاجة إلى جلب عنوان URL الخاص بـ Viths of User ، فقد لا يكون ذلك ممكنًا to_json. لذلك أضف الكود التالي في النموذج.

def avatar_url
    avatar.url(:thumb)
end

ثم في وحدة التحكم بدلاً من to_json استعمال as_json

respond_to do |format|
    format.json {render :json => @users.as_json(:only => [:id,:name,:username], :methods => [:avatar_url]) }
end 

من المهم أن نلاحظ أنه إذا كان "المصدر" صغيرًا نسبيًا ، على سبيل المثال 50 عنصرًا ، يجب أن يكون التنفيذ مختلفًا (وأبسط كثيرًا). تم ذكره في الفقرة الرابعة من المستند الرسمي:

https://api.jqueryui.com/autocplete/

عند استخدام البيانات المحلية ، كل ما عليك القيام به هو الحصول على البيانات ونقلها إلى الطريقة الإكمال التلقائي ، وسوف يقوم بالتصفية لك. لا تحتاج إلى الذهاب ذهابًا وإيابًا إلى الخادم في كل مرة يتم فيها إدخال مصطلح ES.

function filterByTags(tags) {
  $("#stories-filter").autocomplete({
     source: tags,
     autoFocus: true
  });
}

$("#stories-filter").click(function() {
  $.ajax({
    dataType: 'json',
    method: 'GET',
    url: 'tags/index',
    data: $(this).data('project-id'),
    success: function (response) {
      if(response.success) {
        var tags = response.data.tags;
        filterByTags(tags);
      }
    },
    error: function (response) {
      if(response.status === 422) {
        var $errors = 'There are no tags in this project',
            $errorsContainer = $('.error-container');
        $errorsContainer.append($errors);
        $errorsContainer.show();
      }
    }
  });
});
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top