Background
In my Rails 7 with Turbo and Bootstrap app I've got a table with few headers but only 3 of the 6 headers can be used as sorting. Data for that table comes from external API so to sort that data I need to pass the sort and direction params into the API client. Everything works well, passing params, retrieve data etc.
Current implementation
To make sorting happen I'm using link_to where I redirect users to the same path but passing extra params of column and direction. Example for status header below.
view
<%= link_to 'Status', column: 'status', direction: 'desc' %>
controller
def sort_params
{
sort_by: params[:column],
direction: params[:direction],
}.compact_blank!
end
Issue
Everything works well but the styling of link_to is ugly. Columns that are used for sorting have typical link_to styling with this ugly underlying:
How to get rid of that underlying and have the same styling as e.g. it is in Order Id or Payment Method headers?
Related
I've got a view that renders a contact form. This contact form is rendered through javascript. There is also a javascript filter that the user can set viewing options in. (Depending on the settings, different markers are shown on a google map. The user can then click on the markers and in the viewbox click on a view button that renders some info and the contact form below the map)
If I were to make a normal form and use the post method with a #contact and contact routes, I would have to rerender the entire page after the #contact#create method was called. Which would mean all of the current users filter options would be unset. I could obviously save the settings, but feel like this is a hassle.
What I would like is for the contact form to call a method upon submit without actually changing paths, but I have no idea if this is even possible. (i'm using simple form so an answer for that would be preferable)
Since your question is quite broad, I'll have to answer as such:
if this is even possible
Yes it's possible.
You'll have to use ajax to send an asynchronous request to your server.
Ajax (Asynchronous Javascript And Xml) sends requests out of scope of typical HTTP; you can send/receive "hidden" data without reloading (this is what you want):
Don't worry - ajax is really simple once you understand it.
There's a great Railscast about it here:
Implementation
For you, you will just have to get your form to submit over ajax (javascript). There are two ways to do this:
Standard JS (JQuery)
Rails UJS (unobtrusive Javascript)
Basically, javascript acts as a mini browser, opening a url on your server, handling the returned data & doing what you tell it on the path:
<% form_tag contact_path, remote: true %>
<%= text_field_tag "name %>
<%= email_field_tag "email" %>
<%= submit_tag %>
<% end %>
You'll then be able to back this up with the corresponding controller action on your server:
#app/controllers/contact_forms_controller.rb
class ContactFormsController < ApplicationController
def create
... #-> your own logic here
respond_to do |format|
format.js #-> when receiving a pure xml request, this will fire
format.html
end
end
end
#app/views/contact_forms/create.js.erb
$("body").append("<%=j #variable %>");
Without going into too much detail, this is the most efficient way to achieve what you want. I can elaborate if required.
How do I create some simple ajax rating like there is on this page http://watir.com/documentation/ ? Every visitor should be able to rate, I dont need to set permissions. I want to store the ratings in a column. So the user can sort by ratings.
Please make an detailled example. I am not a javascript expert.
I have found an example to create ratings from scratch. But it authorizes a user.
Can someone show me a guidance to create ratings without a Rater (user)? It should not only store the values but also count the votes.
http://eighty-b.tumblr.com/post/1569674815/creating-an-ajaxified-star-rating-system-in-rails-3
What I did recently to add a simple rating mechanism to an existing project was the following:
I added two fields to an existing table (which contained the items to be rated). Those were:
rating_score => The current score
ratings => The number of ratings which led to the score
For example, if five users would've voted "5" for the current item, rating_score would be 25, and ratings would be 5. The current rating would be computed as rating_score / ratings.
Then I added a new method to the controller of the items to be rated, called "rate", which looked something like:
def rate
#item = Item.find(params[:id])
#container = "item"+#item.id.to_s
#item.rating_score += params[:rating].to_i
#item.ratings += 1
#item.save
respond_to do |format|
format.js
end
end
My view for that method, called rate.js.erb, would look something like
$('#<%= #container %>').html('<%= escape_javascript(render(partial: 'rating', locals: { item: #item })) %>');
This code works only if you've got jQuery installed, but it should be easily translatable to Prototype or whatever JS framework you may be using.
And the partial for the rating, called _rating.html.erb, was something like:
<%= form_tag url_for(controller: 'items', action: 'rate', id: item.id), remote: true %>
<%= rating_stars(item.rating_score, item.ratings) %>
<%= item.ratings %> Votes
</form>
In this partial, the rating_stars() helper method generated some kind of star-like representation for the rating, but you can do that however you like.
By setting "remote: true" in the form_tag helper, your Rails installation should automatically transmit the request via the installed Javascript framework. This magic is part of the whole unobtrusive javascript thing going on in Rails lately, which is actually pretty cool.
Hope this gives you an idea of how to realize a very simple rating system with no IP lock feature whatsoever in Rails.
Looks like the Watir documentation rating system is set up through polldaddy.
For this particular case, it appears they include the polldaddy javascript which populates the rating div container with their star rating widget. Looks like there's a corresponding javascript object which you can inspect:
console.log( PDRTJS_101132_page_2.avg_rating ); //=> 4
If you had numerous rating widgets like these on a page, and you were able to make a collection of the javascript objects paired with their divs, presumably you could sort them based on that average rating property.
I have a form around a list of items. I would like to check a radio button on the list and then, after clicking 'Submit', go to the 'Edit' page of the selected item.
The problem is that if I am writing something like
<%= form_tag edit_item_path %>
but Rails complains that I didn't provided a proper id, which in turn is being set on my radio buttons as the following:
<%= radio_button 'item', 'id', item.id %>
So - how would I send a form with a selected id to a given action?
Doing it the way you describe would not work, since edit_item_path by default RESTful path definitions is a GET request. You are trying to make it a POST request. If you would like to stick to the RESTful way of doing things I would recommend simply looping through your items and provide links to edit, since you are planning to edit them one at a time anyways. Otherwise, you would have to define a new route if you would prefer doing things within the form with radio buttons. If you are, than you would add something like this to your config/routes.rb: (assuming you are using rails 2.3.x)
map.resources :items, :member =>{:edit_radio_form => :post}
Than your form would look like this:
<%= form_tag edit_radio_form_item_path do |form| %>
And it should work, but it not the right way of doing things for several reasons, the most anoying one of which is that you won't get a full URL on your edit page because you got there with a POST request, so if you refresh the page, your item id param will be gone and will produce an error.
I'm using periodically_call_remote to update a portion of a page that contains a list of objects. I send along with the url a param containing the created_at date for the most recent object in the database. The action that is called then get all the objects that have been created since then and renders a partial which displays them at the top of the list.
The problem is that I can't seem to figure out how to make it so that the next time periodically_call_remote triggers it sends along the created_at date for the new most recent object (if there is one). I tried putting the periodically_call_remote inside the partial that is being rendered but that caused all sorts of problems (This explains why you shouldn't do that).
Is there some way I can make periodically_call_remote send along a new param each time it's called? As it stands right now it just sends the same one over and over which means that new objects get rendered more than once.
Hackery you say? :)
Store the parameter in a hidden div. You can access the contents of that div via Javascript, which periodically_call_remote will accept as part of the :with option.
When the parameter changes, simply update the contents of the hidden div as part of your controller action.
So, for example..
<div id="date_to_check_from" style="display:none;"><%= #initial_created_at %></div>
<%= periodically_call_remote :url => path_to_controller(#normal_params), :with => "'date_to_check_from=' + $('#date_to_check_from').html()", :method => :get, :frequency => 10 %>
That will get you params[:date_to_check_from] in your controller. Then update however you want, e.g.,
render :update do |page|
page << "$('#date_to_check_from').html('#{#new_date_to_check_from}');
end
It's possible to do some hackery, but I recommend that you start looking into writing your own JavaScript code to perform AJAX requests. Rails' helpers like periodically_call_remote aren't meant to be used in such complex situations.
Is there a way to capture the querystring and send that along as part of a form post? I'm using Rails 2.3.5 and my user is on a page that has multiple querystring parameters. On this page, they are going to submit a form. Inside the action that receives the post, I want to know what those querystring parameters were. Obviously, they are not sent as part of the post. So I need the actual form values, plus the querystring params that were on the page when the user submitted the form.
I'm sure I could write some nasty javascript that would shove the querystring params into hidden fields on the form so they would be available, but that seems ugly. My Googling hasn't turned up much, which makes me wonder if I'm just going about this all wrong. To make matters worse, I'm a Rails newbie.
Appreciate any pointers or ideas to get me going in the right direction.
A friend of mine showed me what I believe is an easier way:
<% form_tag params.merge(:action=>"someAction") do %>
Merging params into the hash necessary for making the form_tag did the trick perfectly.
The preferred way would be to use hidden fields. I haven't tried it, but I think you can specify additional query string parameters within the *_path or *_url helpers. Something like:
<% form_for(#post,
:url => post_path(#post, :foo => 'foo', :bar => 'bar')) do |f| %>
...
<% end %>
<% form_tag params.merge(:action=>"someAction") do %>
- No route matches [POST]
Use hidden_field_tag if you're using a GET request.
In our case we were using a simple form with a select for setting the Per Page values for pagination. We found that any existing GET params were cleared when submitting this form. To fix this we used hidden_field_tags in our form.
Inside of your form, just set hidden_field_tags for the existing GET params, like so:
form_content = request.query_parameters.collect do |key, value|
hidden_field_tag key, value
end
This will ensure that your existing params persist.