Rails (3.2.9) autocomplete work like jQuery combobox? - ajax

I have an autocomplete field on my form that is working however I need to force the user to select one of the values from the list (with autocomplete, the user is not restricted to an item from the list -- it's a textfield and they can enter whatever they want). The jQuery combobox adds the additional functionality that I require. Can anyone help me add that additional functionality to my form -- is there a tutorial or exmample I can follow?
Here's what I have so far (and it is working - Thank you Ryan Bates )
view - new.html.erb
<%= f.input :widget_name, input_html: { data: { autocomplete_widget_source: widgets_list_path } } %>
controller
def list
#widgets = Widget.order(:name).where("name like ?", "%#{params[:term]}%")
render json: #widgets.map(&:name)
end
JQuery
jQuery ->
$('#model_widget_name').autocomplete
source: $('#model_widget_name').data('autocomplete-widget-source')
I tried using a simple collection_select, but the document is too large (10,000 items) because of the size of the select list.
<%= collection_select :model, :widget_id, Widget.all, :id, :name, selected: #model.widget_id -->
Thanks in advance.

I think I finally found the answers I was looking for.
I added the following
jQuery ->
$('#model_widget_name').bind 'autocompletechange', (event, ui) ->
if (!ui.item)
$(this).val('');
Does this make sense? Do I need more?
THANK YOU TO THE FOLLOWING:
mechianicalfish on stackoverflow
Mark Berry at MCB
Systems

Related

ASP.Net MVC 3 - DropDownListFor fails to select the value form the model if HtmlFieldPrefix is set on the partial view

when using
<%= Html.DropDownListFor(model => model.FeeTypeId, Model.GetFeeTypes(), new { })%>
in this case the right option is selected according to Model.FeeTypeId when the select is rendered.
BUT
if you render the form using a partial view, passing it a specific HtmlFieldPrefix (you will need it if,for example, you want to render two identical views and want different ids the elements)
<% Html.RenderPartial("path-to-partial-view", Model, new ViewDataDictionary() { TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = "myPrefix" } }); %>
then the value will not be selected.
looks similar to the problem at DropDownListFor in EditorTemplate not selecting value but from different cause.
looked in the MVC 3 source and seems like the problem is at the SelectInternal method
it uses the htmlHelper.ViewData.Eval(fullName);
which fails to get the value by the full name when it contains the prefix,
TextBoxFor doesn't fail as it passes the value of the expression to InputHelper so it doesn't get to use the ViewData.Eval
just to be sure tested it at the partial view:
in the partial view the following will print "myPrefix.FeeTypeId"
<%= Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName("FeeTypeId") %>
and the following will print "by property name: [value] by full name: [empty string]"
<%="by property name: " + Html.ViewData.Eval("FeeTypeId")%><br />
<%= "by full name: " + Html.ViewData.Eval(Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName("FeeTypeId"))%>
The only solution i found is to generate a List at Model.GetFeeTypes() and mark the option i want as selected:
<%= Html.DropDownListFor(model => model.FeeTypeId, Model.GetFeeTypes(Model.FeeTypeId), new { })%>
don't really like this solution + i know i can create the List in the partial view which is also ugly,
is there another solution to this?
I have discovered that this is a bug in MVC. It's not fixed, though there is a work around.
See my question answered by myself (I had the same problem before finding your post).
MVC4 binding drop down list in a list (bug)
Regards
Craig

Update a Rails 3 partial using AJAX (not a form)

I found a number of questions and answers regarding updating a partial using Ajax after submitting a form. But my question is ?simpler?, I just want to reload a partial every few seconds and load in the new data. This really can't be hard at all, and I remember doing something similar in Rails 2.3 but I can't find the answer anywhere.
Basically, I have a show.html.erb rendering a partial like so:
<div id="latest_post">
<%= render :partial=>'info/latest', :object=>#user, :as=>:user %>
</div>
The partial file located at app/views/info/_latest
<% post = user.posts.last %>
<h1>Last Post</h1>
<p><%= post.content %></p>
I just want the latest_post div to be updated every 30 seconds. Please help!
Well it turns out the answer is a little complicated:
Step 1: Use Javascript's setInterval function along with jQuery's $.get() function to load a page, say /users/1/posts/latest.
setInterval(function(){
$.get("/users/1/posts/latest.js", function(data){
$("latest_post").html(data);
},
"html")
}, 30000);
Step 2: Create a latest.js.erb and put it in your app/views/posts folder.
Contents of latest.js.erb:
<%= render partial: 'posts/latest', object: #user.posts.last, as: :post %>
Step 3: Create the above partial with whatever you'd like (if you don't need a partial, you can just write the entire contents of the div in the latest.js.erb file.)
Step 4: Add a latest method to your PostsController, that defines #user, etc. for the latest.js.erb to use.
Step 5: Add get '/latest' to your routes.rb

Rails 3.1 - Ajax Radio Buttons

I'm trying to add a HighCharts chart to my Rails app, the content of which will be determined by the selection of radio buttons. My code for the radio buttons is fairly standard and is as follows:
<%= radio_button_tag(:interface, "wlan") %>
<%= label_tag(:interface_wlan, "WLAN") %>
<%= radio_button_tag(:interface, "3g") %>
<%= label_tag(:interface_3g, "3G") %>
I see Rails 3.1 has the "remote => :true" option to make Ajax much simpler. My question is where exactly do I put this option for a series of radio buttons? I tried adding it at the end of the radio_button_tag parameters, but it didn't generate the appropriate HTML.
Alternatively, if there is a simpler way of doing what I want to do I'd be open to that as well.
You can do this using jquery. In my opinion is far easier to do this way.
You put the code in your your_model.js file, create the ajax function like the code below.
Create a custom route and do whatever you want.
$("#wlan").click(function() {
$.ajax({
type: "TYPE_OF_REQUEST",
url: "/your_url",
success: function(data) {
... Your success behavior here ...
},
error: function(data) {
... Your error behavior here ...
}
});
});

mvc 3 html attributes

i have been playing around with MVC. I am currently stumped on with html helper methods. One thing i have noticed is that I cant really cant apply the ASP.NET Web Form logic into MVC. To explain further, in ASP.NET I could create a Label control and assign it some text data and then read the text data.
However, in MVC, I cant seem to do the same with #Html.LabelFor/#Html.Label, I have realised that once you do a POST from your form, the value from the Label is not bound back into my view model. However, if I use an EditorFor or TextBoxFor, I can get values bound to my viewmodel upon POST.
My question what html hlper method should I use to display text as readonly but yet be able to bind back to my viewmodel upon post ? I have tried TextBoxFor with its html attributes set to disabled and readonly but no luck.
Appreciate any pointers.
thanks
You should be able to bind the readonly attribute to the TextBox by passing in htmlAttributes as the 2nd parameter of the TextBoxFor method:
<%=Html.TextBoxFor(m => m.SomeProperty, new { #readonly = "readonly" }) %>
On MSDN: InputExtensions.TextBoxFor Method (HtmlHelper, Expression>, Object)
If you're trying to maintain the Label value you can use a combination of the LabelFor and HiddenFor methods.
I don't know why you would need to do this though, since you should be able to get the DisplayText attribute or the Property Name from the property.
<%=Html.LabelFor(m => m.SomeProperty) %>
<%=Html.HiddenFor(m => m.SomeProperty) %>
but this doesn't make a lot of sense since the usual syntax would be:
<%=Html.LabelFor(m => m.SomeProperty) %>
<%=Html.TextBoxFor(m => m.SomeProperty) %>
Note that if you use the disabled attribute the input will not be posted when the form is submitted
This is expected behaviour, only values form elements are added to your Model on POST so your label will be ignored. To get around this duplicate your label value in a hidden field
Html.HiddenFor(model => model.FieldName)
or
Html.Hidden("FieldName", model.FieldName)

Using AJAX in Rails: How do I change a button as soon as it's clicked?

Hey! I'm teaching myself Ruby, and have been stuck on this for a couple days:
I'm currently using MooTools-1.3-compat and Rails 3.
I'd like to replace one button (called "Follow") with another (called "Unfollow") as soon as someone clicks on it. I'm using :remote => true and have a file ending in .js.erb that's being called...I just need help figuring out what goes in this .js file
The "Follow" button is in a div with id="follow_form", but there are many buttons on the page, and they all have an id = "follow_form"...i.e. $("follow_form").set(...) replaces the first element and that's not correct. I need help replacing the button that made the call.
I looked at this tutorial, but the line below doesn't work for me. Could it be because I'm using MooTools instead of Prototype?
$("follow_form").update("<%= escape_javascript(render('users/unfollow')) %>")
ps. This is what I have so far, and this works:
in app/views/shared:
<%= form_for current_user.subscriptions.build(:event => #event), :remote => true do |f| %>
<div><%= f.hidden_field :event %></div>
<div class="actions"><%= f.submit "Follow" %></div>
<% end %>
in app/views/events/create.js.erb
alert("follow!"); //Temporary...this is what I'm trying to replace
*in app/controllers/subscriptions_controller.rb*
def create
#subscription = current_user.subscriptions.build(params[:subscription])
#subscription.save
respond_to do |format|
format.html { redirect_to(..) }
format.js {render :layout}
end
Any help would be greatly, greatly appreciated!
The ID selector should be used if there is only one of those elements on the page, as the Id selector us for unique IDs. A Class selector is what your looking for. Classes are used for multiple elements that have the same styles or same javascript events.
The code to replace Follow with Unfollow would be as follows in Mootools. I am not totally understanding your question, but you will need to assign a ID to the button.
document.addEvent('domready',function(){
$$('follow_form').addEvent('click',function(e){
//Ajax Here
this.set('value','Unfollow');
});
});
Mootools has a different set of functions than Prototype, so most (if not all) code designed for prototype will not work in Mootools. If you want to see the functions in Mootools, I recommend the Docs (its a good read): http://mootools.net/docs/
This code would work as well for you, if you do not/can not add unique IDs to each form element:
$$('input').addEvent('click',function(){
if(this.value == 'Follow') {
//Ajax Here
this.set('value','Unfollow');
}
});

Resources