Thanks for reading this.
I have an index view in my rails app. it has an area where i display a list of records. i use an instance variable called #list to hold the array of records. i have a couple of buttons on the form that remotely renders the list in either a grid or a list format. everything works great - i have a grid_partial and a list_partial, and i use JS to render whichever view the user clicks on.
i recently added a feature that allows the user to select the ordering criteria for the list (order by price: ascending, delivery date: descending, etc.). when they click on an ordering scheme, i ajax a method in the controller that updates the value of #list. the update method then calls a js.erb file that renders the partial. it does this correctly as the #list records are now in the order the user requested. My issue occurs when i click one of the buttons to switch between list and grid view. when i do this, the list and grid partials use the original, un-updated version of #list, NOT the value i most recently received from the last AJAX communication to the server. Both of my partials reference the #list instance variable to get the array.
It was my intent to be able to update/overwrite the value of #list, so that subsequent rendering of partials that reference #list would use the new, updated value. Is this possible?
I have tried to replace the #list variable with a local variable that is passed into each partial, but that doesn't fix the problem. Thanks in advance for your consideration.
Based on the limited information available I am guessing the controller that renders the list/grid partial on clicking the button is not aware of the altered ordering scheme.
you may consider either passing that information from the client as a query parameter, or save it in session.
Related
(Rail 5 beta 3)
I have a table on an index page (action) of a view with around 15 columns. Some of them are for text and some of them are for integers only. Every entry of this list (table) will be filled out by a 'form_for' form (in new or edit action).
For editing or deleting there are links with each list entry in the index view leading to the corresponding show, edit or destroy actions. This all works well. Some of these entries are entered by a select with pulldown on the new or edit view. This works well, too.
But if one of these selects should be changed for more than one entry in the list it takes too much time to click on 'edit', change the select and click on submit at each list item. To make this a better user experience I would like to be able to change the selects in the list (table) directly. It would be good to have the select/pulldown in place. The change of the state or choosen entry should than be saved in place as well or with an extra button ("save changes") above/below the table.
To say it in short:
I want to update multiple entries in a table in an index view without editig each single entry via edit view. The dates will be changed by a select and the data should be saved by a submit button on this page
Has anybody an idea how I can solve this?
Try best_in_place gem. It can solve the problem you have quoted. here are some links to it
https://github.com/bernat/best_in_place
http://railscasts.com/episodes/302-in-place-editing?view=asciicast
Your original text wasn't that confusing to me...
You want what's called a bulk edit feature. Easiest way would be to set up a new target at the controller level specifically to handle this request. I'll give you the pseudocode and it should be easy enough to fill in the blanks, but essentially:
Create a "bulk edit" form (the drop down select menu above the table)
Create a controller method to handle the bulk edit (controller#bulk)
Update routes.rb to direct a URL to that new method
Handle the bulk update in the controller and redirect back to index upon completion (cheap way of updating the page after editing is done).
Note: I'm assuming your model name is "Resource" because you did not specify what it actually was
On your index page, you want HTML like:
<form method="POST" action="/resources/bulk">
<select name="bulk_value">...</select>
</form>
On change/form submit/whatever, submit that form.
If you're using resourceful routing, you can hook this into config.rb via:
resources :resources do
post :bulk, on: :collection
end
Otherwise, hook the route however you see fit.
Then, in your controller:
def bulk
value = params[:bulk_value]
Resource.update_all value: value
redirect_to {resources_path}
end
Now, you said index view, so I am assuming you want all. But if you just want a subset, you can pass the preferred IDs along with the form as a hidden field, then use a where clause to filter, i.e.
Resource.where(id: parmas[:id_array]).update_all(value: value)
Anyway, that should get you down the right path.
In my project, an Article has many Items within it. Since each Item has different length, so I would like to implement pagination manually, for example, by creating a PageBreakItem model, in order to allow users insert page breaks wherever they want. But I don't know how to use "page" parameter in controller to render views correctly.
Some gems like kaminari or will_paginate only allow me to configure the number of items per page. They don't have options for inserting page breaks manually.
Any suggestions are greatly appreciated.
You don't need a special model for this. You could do this with small adaptation of your Item model:
Add sort_order numeric field to denote order of items within the article and is_on_new_page boolean field to denote a page break occurring before that article.
I want to display a list of stocks when the user logs in (default parameters). This smells like an index action. However, I will also make a form for the user to select the market capitalization of the stocks (that is to refine the universe). The submission of the form will send parameters to some action (I am not sure if I should use the same index action) and then do an ajax update of the list. This ajax doesn't do anything to the database, it just updates the parameters for the database query.
The first time the user visits the site, they will see the default parameters for the query, but I also want them to be able to change the parameters later and renew the list according to their parameter through ajax.
Yep, a list of stocks sure sounds like an index action. Do you mean that you want to filter the list depending on some form input?
You can make the form send to the index action with a get method, and in your controller, just read the params, and query your #stocks however you want your filter to work.
This is the non-Ajax solution, so users without Javascript will be happy. When you get this working, you can easily AJAXify it.
Specifically, I have a number of pages in my Rails app that use the same partial. In the action handler for each page I create an array object (e.g. #list_elements) based on a database query. Each page uses a different query so that each page has different list elements in it. At the top of each page I have a form_remote_tag containing an edit field, allowing the user to add a new element in a dynamic, AJAXy fashion (think something like Twitter 'What's happening' box).
My problem is that when the AJAX command fires I need to reload the list to include the newly added item, but the contents of the list were determined by a database query. I need to remember which query applies to the current page (i.e. controller action) so that I can run it again. I thought about storing something in the rails session structure but it seems like overkill - it's like storing the current page all the time.
Anybody done anything like this and have a nice Railsy way to achieve it?
Ben
Couldn't you just re-render the partial in your rjs template?
page[:div_element].replace_html :partial => 'partial'
If you perform the query and define the array in the controller action, then an ajax call will refresh that array.
The best public example that I can think of off the top of my head would be the amazon shopping cart. Where you have a page that displays multiple distinct records that can have multiple distinct fields updated.
I can't put each one in a form tag because the user may modify more than one record and then submit.
I can't just update all the records that I get back because:
1. Performance
2. Auditing
3. If someone changed the record that the user 'didn't change' when they were viewing the page and then the user submits those changes would be overwritten.
So how to best handle getting the data back and then getting which records where changed out of that?
Is that clear?
Use binding! Don't be iterating the form collection in your actions.
Steve Sanderson wrote a blog post about how to do it. I wrote a blog post on how to do it with MvcContrib.FluentHtml. Both posts are very detailed and include downloadable code.
Generate your form in a repeater, and append an ID to the form elements that increments with each new form. Save the number of repeated form elements in a hidden field. Then in your controller, read the value of this hidden field - that'll be the number of forms to read. Then, in a loop, retrieve each form's fields by specifying the name of the field, plus the loop index appended to the name, as the key.
You can use some javascript logic to detect when a form's value changes, and update a hidden field in that form's section if that occurs; or you can hide the original values inside a hidden field with each form section (although I don't recommend this as too many fields / forms will bloat your page).
one (but not necessarily the best) approach is to store which items are changed in a js-variable or something on the client side as they are changed, and then only send the data that is actually different from what the user recieved.
and as Erik stated, you could use hidden form elements to make sure that it works without js as well.