Rails에서 jquery-ui 자동 완성을 설정하는 방법
Rails 앱에서 jquery-ui 자동 완성 을 구현하는 방법에 대한 도움이 필요 합니다.
사용자가 고객 이름을 입력 할 수있는 텍스트 필드에 자동 완성 기능을 추가하고 싶습니다. 수백 명의 고객이있을 수 있으므로 표에서와 같이 제안 된 자동 완성 값을 '원격'으로 가져와야합니다 (적어도 이것이 제가 이해하는 것입니다).
내가 이해하지 못하는 요점은 자동 완성 텍스트 상자에 제안 된 값을 제공하는 방법입니다. 나는 jquery-ui 문서를 읽었지만이 문제에 대해 약간 조밀 한 것 같습니다.
그래서 제가 정말로 추구하는 것은 Rails 앱에서 어떻게 작동하도록 할 수 있는지에 대한 예입니다. 자바 스크립트가 어떻게 구축되었는지에 대한 전체 설명이 아닐 수도 있습니다 (이게 jquery-ui 팀이 저를 위해 해준 일입니다 =)).
예를 들어 자동 완성을위한 데이터를 준비하는 방법과 자동 완성 기능을 텍스트 상자에 연결하는 방법이 있습니다.
위의 질문에 대한 답을 얻지 못했기 때문에 결국 스스로 알아 내야했습니다. 같은 일을 궁금해하는 다른 사람이있을 경우를 대비하여 내가 생각 해낸 해결책을 게시해야한다고 생각했습니다.
가장 먼저 알아야 할 것은 이것이 자바 스크립트에 대한 첫 경험이며 Rails의 요령을 얻고 있다는 것입니다. 그러니 꼭 내가 잘못되었다고 생각하는 곳이면 어디든 자유롭게 편집하고 댓글을 달 수 있습니다. 옳고 그름 적어도 나는 그것이 내가 원하는 방식으로 작동한다는 것을 알고 있습니다.
이를 보여주는 가장 좋은 방법은 예를들 수 있습니다. 그래서 다음은 내 앱에서 자동 완성 위젯을 사용하는 방법입니다. 무슨 일이 일어나고 있는지 이해하지 못하더라도 앱에 다음 코드를 입력하면 각 부분이 어떻게 작동하는지 예제로 살펴볼 수 있습니다. 그 후에는 사용을 위해 수정하거나 굴절시키는 방법을 이해해야합니다.
RAILS 앱에 JQUERY UI를 포함하세요.
의 사본을 다운로드 jQuery를 UI 및 장소 JQuery와-UI-1.8.2.custom.min.js을 당신의 내부 / 공공 / 자바 스크립트 디렉토리. 또한 jQuery 자체의 복사본이 있고이 복사본도 동일한 폴더에 있는지 확인하십시오.
이와 같이 application.html.erb 파일 에 jQuery UI 파일과 jQuery 파일을 포함합니다 .
(파일이 일치하는 한 원하는대로 이름을 지정할 수 있습니다)
<%= javascript_include_tag 'jquery.min', 'jquery-ui-1.8.2.custom.min.js' %>
jQuery UI를 다운로드하면 모든 CSS 데이터가 포함 된 폴더가 있습니다. 이름은 선택한 테마에 따라 달라집니다. 예를 들어 ' 쿠퍼 티노 '라는 테마를 선택했습니다 . CSS 데이터가 포함 된 전체 폴더를 ' / public / stylesheets / '에 배치합니다. 그런 다음 이와 같이 application.html.erb에 CSS 파일을 포함하십시오.
<%= stylesheet_link_tag 'cupertino/jquery-ui-1.8.2.custom' %>
AUTOCOMPLETE JAVASCRIPT 예시
이제 다음 코드 덩어리를 ' 새 '뷰 중 하나에 배치합니다 . 어떤 뷰에서나 사용할 수 있지만 말 그대로 'links_controller'라는 컨트롤러에 속한 기존 뷰에서 가져 왔으며 'people_controller'에서 데이터를 가져오고 있다는 것을 알고 있습니다. Rails에 대해 충분히 알고 있으므로 변경해야 할 사항을 파악할 수 있기를 바랍니다.
-큰 코드 덩어리 시작-
<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이지만 익숙하지 않더라도 걱정하지 마십시오. 나도 마찬가지입니다. 그것은 당신의 / 다른 응용 프로그램의 다른 부분이 그것을 사용할 수 있도록 텍스트 서식을 지정하는 방법이라는 것을 아는 것으로 충분합니다.
자동 완성을 위해 텍스트 필드에 필요한 데이터는 ' source : '옵션에 지정됩니다 . 자동 완성에 사람들의 이름과 ID 목록을 보내려고하기 때문에 다음을 소스로 넣을 것입니다.
source: '<%= people_path(:json) %>'
위의 레일 도우미는 " /people.json " 문자열로 번역됩니다 . " /people.json "에 페이지를 만들 필요가 없습니다 . 해야 할 일은 people_controller에게 .json 형식의 / people에 대한 요청을받을 때 수행 할 작업을 알려주는 것입니다. 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
이제 @people의 모든 사람들이 자동 완성 텍스트 필드로 전송됩니다. 이것은 바로 다음 요점을 제시합니다.
입력을 기반으로 자동 완성 제안에 사용되는 필터 데이터
자동 완성 텍스트 필드는 입력 한 내용에 따라 결과를 필터링하는 방법을 어떻게 알 수 있습니까?
텍스트 필드에 할당 된 자동 완성 위젯은 텍스트 필드에 입력하는 모든 내용을 소스에 대한 매개 변수로 보냅니다. 전송되는 매개 변수는 " term "입니다. 따라서 텍스트 필드에 "Joe"를 입력하면 다음을 수행합니다.
/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
이제 자동 완성 텍스트 필드에 입력 된 내용을 기반으로 @people에 할당되는 레코드 수를 제한 했으므로 이제 자동 완성 제안을위한 JSON 형식으로 변환 할 수 있습니다.
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @people.to_json }
end
이제 "Big Chunk of Code"내부의 주석을 검토하면 나머지 부분이 어떻게 연결되는지 설명해야합니다.
마지막에는 페이지에 자동 완성 역할을하는 텍스트 필드와 매개 변수의 ID를 컨트롤러에 보내는 숨겨진 필드가 있어야합니다.
나만의 자동 완성을 사용자 지정
위의 내용을 이해하고 사용을 위해 수정하려면 컨트롤러에서 반환 된 JSON 형식이 다음과 같은지 알아야합니다.
[{"person":{"id":1,"given_name":"joe","middle_name":"smith","family_name":"jones","nationality":"australian"}}]
이 경우 자바 스크립트의 JSON 문자열에서 다른 값에 액세스하는 방법은 다음과 같습니다.
ui.item.person.name_of_some_attribute_such_as_given_name
예쁘고 간단합니다. Rails에서 ActiveRecord 속성에 액세스하는 것과 비슷합니다.
마지막 메모입니다. 이 함수가 jquery 위젯에 내장되어야한다고 생각했기 때문에 숨겨진 값을 제공하는 다른 방법을 찾기 위해 많은 시간을 보냈습니다. 그러나 이것은 사실이 아닙니다. 공식 jQuery 예제에서 매개 변수로 선택된 다른 값을 보내는 방법은 숨겨진 필드를 사용하는 것임을 분명히 알 수 있습니다.
누군가에게 도움이되기를 바랍니다.
골짜기
jQuery 1.9 / 1.10은 키 자동 완성을 제거하고 uiAutocomplete를 추가했습니다.
.data("uiAutocomplete") instead of .data("autocomplete")
After modifying to above,it worked for me.
Dale's Answer is quite the tutorial. One thing to note is that using your first query, the datasource will only return matches beginning with the string you type. If you want search anywhere in the word, you need to change:
@people = Person.find(:all,:conditions =>
['given_name LIKE ?', "#{params[:term]}%"])
to
@people = Person.find(:all,:conditions =>
['given_name LIKE ?', "%#{params[:term]}%"])
(added an extra %
to the query)
I basically followed Dale's advice below but my controller and js files were slightly diff- his version was giving me issues for some reason (maybe bc of jquery updates)
Context: I'm trying to autocomplete names of DJs typed in by users - also a newb
DJs Controller
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 file
<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>
This is a great help.
In addition to it in case if you need to fetch url of image of user, it might not be possible with to_json
. For that add the following code in model.
def avatar_url
avatar.url(:thumb)
end
And then in controller instead of to_json
use as_json
respond_to do |format|
format.json {render :json => @users.as_json(:only => [:id,:name,:username], :methods => [:avatar_url]) }
end
It's important to note that if your 'source' is relatively small, for example 50 elements, the implementation should be different (and a lot simpler). It is mentioned in the fourth paragraph of the official doc:
https://api.jqueryui.com/autocomplete/
When using local data all you need to do is obtain the data and pass it to the autocomplete method, and it will do the filtering for you. You don't need to go back and forth to the server every time a term es entered.
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();
}
}
});
});
ReferenceURL : https://stackoverflow.com/questions/3188157/how-to-set-up-jquery-ui-autocomplete-in-rails
'programing' 카테고리의 다른 글
Java 열거를 스트림으로 어떻게 전환합니까? (0) | 2021.01.16 |
---|---|
Jmap은 덤프를 만들기 위해 연결할 수 없습니다. (0) | 2021.01.16 |
IntegrityError 중복 키 값이 고유 제약 조건을 위반 함-django / postgres (0) | 2021.01.16 |
bash 스크립트를 데몬으로 실행 (0) | 2021.01.16 |
mysql-한 테이블에서 다른 테이블로 행 이동 (0) | 2021.01.16 |