How to use observer_field in RoR? - ruby-on-rails

I have a single select_tag with categories gathered from array in controller. When the user selects a category I want the application to redirect to the selected category. I have the following code in my view which. (I've tried both using :method => :get and :post, only change is in development.log)
<%=select_tag "cat_selected", options_for_select(#cats_for_mt)%><br>
<%=observe_field 'cat_selected',
:url => {:action => :viewflokkur},
:with => 'cat',
:method => :get %>
When I select one of the options the following gets logged to development.log.
Processing CategoriesController#viewflokkur (for 127.0.0.1 at 2010-06-12 12:33:26) [GET]
Parameters: {"cat"=>"Taugasjúkraþjálfun", "authenticity_token"=> "B2u5ULNr7IJ/ta0+hiAMBjmjEtTtc/yMAQQvSxFn2d0="}
Rendering template within layouts/main
Rendering categories/viewflokkur
Completed in 20ms (View: 18, DB: 0) | 200 OK [http://localhost/categories/viewflokkur?cat=Taugasj%C3%BAkra%C3%BEj%C3%A1lfun&authenticity_token=B2u5ULNr7IJ%2Fta0%2BhiAMBjmjEtTtc%2FyMAQQvSxFn2d0%3D]
According to this I should now be in "viewflokkur", but nothing changes in the browser window. Is there anything else I need to do, maybe in the controller?
BR,
Sindri

here is an example of Observe field :
<label for="search">Search term:</label>
<%= text_field_tag :search %>
<%= observe_field(:search,
:frequency => 0.5,
:update => :results,
:url => { :action => :search }) %>
<div id="results"></div>
Found here.

Related

kaminari pagination ajax call renders to wrong controller

First we start off with conversations/index.html.haml to create a message
#new_message_conversation
.panel.panel-info
.panel-heading
%h4 Send a Bark!
.panel-footer(style="padding-top: 20px")
= simple_form_for :message, url: :messages, :remote => true do |f|
.form-group
= f.input :master_name, placeholder: 'Choose master...', label: false, :url => autocomplete_master_name_conversations_path, :as => :autocomplete, id_element: "#master_name_id", input_html: {class: "form-control"}
= f.input :recipient_id, as: "hidden", input_html: {id: "master_name_id"}
= f.input :body, label: false, as: "text", placeholder: 'Write message...', :input_html => { :rows => 5 }
= f.button :submit, 'Send', :class => "btn btn-lg btn-primary", :disable_with => "Sending..."
which then goes to the messages#create action which has
...
respond_to do |format|
format.js { render "create", locals: { conversation: #conversation, conversations: #conversations, receipts: #receipts }}
end
...
which sends the work to the conversations/create.js.erb file
$('#new_message_conversation').prop('disabled', true).html("<%= raw escape_javascript(render(:partial => 'conversations/show', locals: { conversation: conversation, receipts: receipts })) %>").hide().fadeIn('fast');
which adds the conversations/show partial, _show.html.haml which has
...
%ul.pager.pull-left(style= "padding-left: 10px")
%li#paginator_3= link_to_previous_page #receipts, "Newer", :remote => true, :param_name => 'page_2'
%li#paginator_4= link_to_next_page #receipts, "Older", :remote => true, :param_name => 'page_2'
...
everything works excepts now the pagination buttons don't work. and when I click a pagination button the server says
Rendered messages/index.js.erb
Why does a partial that's in views/conversations that has a remote ajax call render to a different controller (messages)? It should be rendering conversations/show.js.erb because the partial is conversations/_show.html.haml right?
here are my routes also
...
resources :conversations do
get :autocomplete_master_name, :on => :collection
end
resources :messages
...
Even though you're rendering views and partials from the conversations path, you never even touched the ConversationController.
You can render whatever views you want for the action you're executing. The only thing connecting the ConversationController with the views/conversation/file.html.erb and similar view files is a loose naming convention. When rendering say render 'index' from an action of the ConversationController, it just assumes by that convention you meant the views/conversation/index.html.erb file.
Your view or partial alone cannot reference the controller it would belong to (when going by the naming convention) because it is just used as a template by the render command in your action. The view doesn't care whether the controller behind it is the appropriate one. In this case, the render was originally executed in the MessagesController, so the view also just has a reference to that one.
To still have the links point to the correct controller, you need to specify the controller to be used for the url. Otherwise, it is assumed that you want to use the very same controller you used to render the page.
The culprit is probably somewhere in the link_to_previous_page and link_to_next_page helpers by kaminari. When using the full paginate helper, you can set the controller and action you want to use like this:
<%= paginate #users, :params => {:controller => 'foo', :action => 'bar'} %>
The documentation (here: https://github.com/amatsuda/kaminari) doesn't say whether this param is also possible with the other helpers, but the helper uses a simple link_to (see here: https://github.com/amatsuda/kaminari/blob/master/lib/kaminari/helpers/action_view_extension.rb), so you should be able to do something like this:
link_to_previous_page #receipts, "Newer", {:controller => 'foo', :action => 'bar', :remote => true, :param_name => 'page_2'}

How can I update the content of certain column without any page loading?

User has_one UserProfile.
Then UserProfile has wanted_message column as string.
Here, I'm showing input box to update wanted_message
I want it to be updated if certain user inputs any message then press "Update" button.
How can I? now, It's taking me to the url "/users/12" if I press "Update"
I don't want that:( I want it to be updated without any page loading(Ajax Request).
Then I want to have Action called update_message in User contoroller
How can I?
<%= form_for(current_user, :url => {:controller => "user", :action => "update_message" }, :remote => true, :class => 'form-search') do |f| %>
<%= f.fields_for :user_profile do |profile_form| %>
<div class="input-append">
<%= profile_form.text_field :wanted_message, :class => 'span6' %>
<button type="submit" class="btn">Update</button>
</div>
<% end %>
<% end %>
You have to set remote => true in your form and also set :method => put Put lets you update columns in your database and remote true will configure the form to send an ajax request. You'll also have to configure the update_message action in your controller to handle ajax requests. Finally, make sure your routes are configured correctly. You'll have to define that route in routes.rb and probably do an :as => 'update_message' to have access to that route helper method
This may help you with ajax in rails forms http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html
Here's a sample form, it's in haml though:
= link_to "Start", polls_toggle_live_path(poll.id), :method => :put, :remote => true, :class=> 'btn btn-success btn-small start-poll', :id => poll.id
Which links to this controller action
def toggle_live
#poll = Poll.find(params[:poll_id])
#poll.toggle_live
#poll.save!
end
Calls this method in the associated polls model to switch the db column value
def toggle_live
self.is_live = !self.is_live
end
Finally its configured in routes.rb this way to pass along the correct updates
match '/polls/toggle_live/:poll_id' => 'polls#toggle_live', :via => :put, :as => 'polls_toggle_live'

Routing issue. Url becomes parameter

I have a url with path /user_management/edit_official/:id
its corresponding output from rake routes is
user_management_update_official POST /user_management/edit_official/:id(.:format) {:controller=>"user_management/employees", :action=>"update_official"}
When I try to access url via form, url is not reached, because the url /user_management/edit_official/:id becomes a parameter.
Following is the log file entry?
Started POST "/user_management/edit_official/31" for 127.0.0.1 at
2012-01-02 11:05:21 +0530 Processing by ErrorsController#index as
HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"DED4E/9w/GDUQdjZ27mrUWrYBgipgHnNvS8mOjdaNXU=",
"employee"=>{"empl_id"=>"", "confirmation_date"=>"",
"designation_id"=>"", "rep_head1_id"=>"", "payment_mode"=>"",
"pf_number"=>"", "bank_name"=>"", "pt_applicable"=>"false",
"reg_date"=>"", "employee_type_id"=>"", "joining_date"=>"",
"rep_head2_id"=>"", "pf_applicable"=>"false",
"bank_account_number"=>"", "empl_email_id"=>"false",
"last_working_date"=>""}, "designation_level"=>"L-5b",
"user"=>{"username"=>"dsaf.adsfas", "password"=>"[FILTERED]"},
"commit"=>"Next", "a"=>"user_management/edit_official/31"}
Is there any reason for this. Thanks.
EDIT: Form included
<% url = user_management_update_official_path(#employee) %>
<%= form_for(#employee, :url => url, :html => { :enctype => 'multipart/form-data'} ) do |f| %>
<div id="employee_details" class="employee_form_steps">
<%= render :partial => 'user_management/employees/official_information',
:locals => { :f => f} %>
</div>
<div class="btn_row">
<%= content_tag(:button, '< Back', :id => 'official_information_back', :class => 'grey') %>
<%= f.submit 'Next', :class => 'green', :style => 'margin:0px;padding:4px;width:50px;' %>
<%= content_tag(:button, 'Cancel', :class => 'cancel grey') %>
</div>
<% end %>
The error must lie in your routes.rb
The rule in this file is: first match, first served.
Try to take the line corresponding to "errors#index" and put it under the one describing /user_management/edit_official/:id
The actual problem was the http method used for form. The form_for used put method while, in routes I specified POST. Changing POST to PUT, made everything work.

Rails: How to change this link into a button?

Right now I can call a method using ajax (:remote=> 'true') at awisprotect_path by simply clicking on the "x" in this link
<%= link_to "x",
awisprotect_path,
:remote => true,
:method => :post,
%>
The controller action renders jquery so the response is included into the html in the view
<div class="awishanswer">
</div>
That's all working fine. However, instead of having an "x" to click, I wanted the user to click a button and get the same result. So I essentially just wanted to put the link info
<%= link_to "x",
awisprotect_path,
:remote => true,
:method => :post,
%>
into this button
<button class="btn small primary" >
check
</button>
So I created this form and put it in a partial
<%= form_tag(:controller => "sessions", :action => "awisprotect", :remote => true, :method => "post") do %>
<button type="submit" class="btn small secondary">check awis</button>
<% end %>
but the problem is that the controller action that renders js is not putting the result of the action into the html div. Instead, it's redirecting to a blank page and then printing the jquery method with the result that I was checking for with the controller action. the blank page just shows this...
$('div.awishanswer').html(' html to be inserted in div');
Can anyone explain?
In the url it says
http://localhost:3000/awisprotect?method=post&remote=true
in the view file
<div class="awishanswer" id="awishanswer">
<% form_remote_tag :url => {:controller => "sessions", :action => "awisprotect"},
:html => {:method => "post"}, :update => "awishanswer" do %>
<input type="submit" class="btn small primary" value="check" />
<% end %>
</div>
in the action
def awisprotect
#flag = params[:flag] // suppose sending parameter flag from form
// do something
render :partial => 'partial file containing html to send to view'
end
The form will be submitted when the submit button is clicked.
the action will send the html contained in partial file.
the form will update the div with id provided in form with the html code send back from action.
EDIT:partial file
<%if #flag%>
// include some html
<%else%>
// include some other html
<%end%>
The reason your getting a problem is probably because of your usage of the form_tag helper uses the :remote and :method values inside the url generation instead of being handled be the form. The correct usage would probably be like this:
<%= form_tag({:controller => "sessions", :action => "awisprotect"},
:remote => true,
:method => "post")
However, Rails already has a helper method to create a button to submit data called button_to. It basically takes the exact same arguments as the link_to helper so I would probably use it like this in your case:
<%= button_to "x", awisprotect_path, :remote => true, :method => :post %>
The :method argument could possibly even be left out because I think the button_to helper defaults to the POST protocol.
You can disguise a link as a button, using some CSS. Here's a nice article.
This might be better than all these experiments with partials and forms. :-)
I'm thinking you didn't wrap the options for form_tag properly. Try something like this:
form_tag( { :controller => :sessions, :action => :awisprotect, :method => post }, { :remote => true } ) do ....
It may or may not also help to use button_tag.

Rails route for button

I'm a rails newbie and a question on routes is confusing me.
On one of my pages, I have a form. In that form I allow the user to fill in some needed information and press a "submit" button.
I get:
No route matches {:action=>"inventory_test", :controller=>"test_types"}
I do have an action in the test_type controller for "inventory_test".
My confusion is that routes seem to be defined according to the REST model, such as /Users/edit/1. That's fine, but how does one create routes for things like buttons?
I may be naive, but it seems like if I tried to setup a route in the form:
match 'some/url' => 'controller#action'
then I'm essentially defining the action for the entire page. How do I define actions for elements on the page?
When this button is clicked, I want the action in the controller called. I'm looking for:
match "submit_button" => 'test_types#inventory_test'
I realize I'm likely misunderstanding the paradigm, so any education is greatly appreciated.
Code:
(Note that I haven't tested the form code yet, but hopefully you get the idea)
index.html.haml
%div
%table
%caption
Inventory Tests
%form
Inventory Run: %input {:type => 'text', :name=>'inventory_run'}
Inventory Class: %input {:type => 'text', :name=>'inventory_class'}
=button_to "Run Inventory Test", :action => 'inventory_test';
If you are submitting a normal form then this should help
The route match '/url' => "test_types#inventory_test" should work fine.
<%= form_for(#user, :url => "/url") do |f| %>
"Put your form code here"
<%= f.submit "Submit" %>
<% end %>
Revert back if any queries .
Edited as per code posted
%form{ :action => "inventory_test", :method => "post"}
%label{:for => "inventory_run"} Inventory Run:
%input{:type => "text", :name => "inventory_run"}
%label{:for => "inventory_class"} Inventory Class:
%input{:type => "text", :name => "inventory_class"}
%input{:type => "submit", :value => "Submit"}
Just check, it should work for you but i have not tried with it

Resources