Creating and editing my element instead of using `new` - ruby-on-rails

So, basically my 'index' action is a long list of elements output as a table with Rails, each one has a checkbox next to it. These elements are items in a catalog that will be line-items in a quote.
A user can select as many checkboxes as they like, then click a button that says "Create a new Quote" it'll take the items they checked and clone them into a new table so they can edit them as apart of the quote.
The issue I'm having is that when the list is really long, say 6000 records it’s a n awfully long list to load, so I want pagination, BUT! then my checkboxes won’t work, because they will go away if the user changes pages.
Additionally the user has no way of going back to this page to "add" more items to the quote.
My first thought was to create a new element right when they browse to this "index page and essentially have the user editing the quote from the get go"
Any ideas on this implementation? I'm a little stuck on how to get started implementing this.

This is a classic shopping cart type problem. You might want to read up on implementing those in Rails with sessions. Simple example is to use the user's session. You can either create a class to encapsulate the logic, or just use a hash or array to hold the ids that are checked. So when the user clicks on "Start New Quote" you can set a var in their session to blank like:
session[:new_quote_items] = []
Then when they check off items you can have a link to add them to the quote. You can then place those ids into the array. On page display of the possible quote items you can show the user which ones are check and have then add/remove IDs from this list. Then when the user is done they can click on a finish link which will take the ids from the session and create the quote as you have now.

This question is similar to yours and covers your first problem. Pagination.
In addition to that, clever use of accepts_nested_attributes_for on the join model will allow you to simplify addition of elements to either existing or new quotes.
Sorry I've got no code for you right now, but here is the general idea:
Generate a list of QuoteItems that is is the union of the set of existing quote items for this quote, and quote items built for the current quote from items not part of the current quote.
Give that list to fields_for and set up each field_for region so that it passes the item_id as a hidden value and contain a checkboxes, such that they modify the :_delete field, with default value evaluating true, and checked value equating to false.

Related

How to disable caching of select2 search results?

I have two select2 containers, which work together side-by-side. Both are ajax based selects, and the selected value of one of them, determines the results in the other.
My problem is the following: when I select the first of the two select boxes, and open up the second one, it is prepopulated with the correct search results. Yet, when I change the first select, and then reopen the second one, for a split-second, while the ajax request is sent for the new data from the second select option, the results that were shown previously are still visible and selectable.
For a concrete example, imagine the following two select boxes: one is for occupation, and the other contains names of persons. The intended use case would be, is to select an occupation in the first one, and then the second one will only list the persons with that occupation. If I select, for example doctor as the occupation, and then list the second one with all the doctors I get the correct result. But if I then reselect the first one, and change it to engineer, and re-open the second one, I will get the list of doctors for a split-second, before the ajax manages the load my engineers. I can even select a doctor, as an engineer, if I am quick enough.
Is there a way to disable this behaviour? IE: whenever I click on an ajax related select2, show me an empty list, or the "Searching" string, while the request to the server is made, and an answer is returned?
Select2 "caches" options retrieved by ajax inside the options of the original tag. To disable cache as you say, remove all those options just before the new option gets selected.
In practice, removing options before or after does not make a difference in your problem, but if you were to have this same problem in a single select (not combining two as you mention), you should do this with the event 'select2:selecting', instead of 'select2:select' event (Select2 events)
$('#select-occupation').select2({
...,
ajax: {
...
}
})
.on('select2:selecting', function(event){
console.log('actual value: ' + $(event.target).val());
$('#select-people').find('option').remove();
});

Select or input

In my app I have a form for creating new trip. Model Trip has field finish_address. For setup the finish_address in I use select in simple form to select address from user's addressbook. But I want to make a better form: if there isn't necessary address, user can add it using input field.
So I need to make form with to types of setup finish_address. How can I make it?
You have 2 basic options.
You can use autocomplete on a text input, populating a dynamic crop-down with know values.
There are several gems available to get you started in this direction, like https://github.com/crowdint/rails3-jquery-autocomplete.
Alternatively, you can add an "other" option to a select input, populated with your known values. When the "other" item is selected, display a previously hidden text input with the same name below the select input. The "lowest" element will take precedence, for what gets sent to the controller.
In the controller, just do a find_or_create_by, using your provided value.
These options both require javascript, but you can eliminate the need for javascript if you make your select a non-db-backed attribute, and manipulate your params accordingly, as they come in to the model. This might help with validations, as well.

Rails AJAX filtering has me totally stumped

It's not often that I find myself completely baffled as to how to go about solving a problem, but for this one, I honestly haven't a clue.
I'm building a site that has many projects, and on the homepage, I'd like people to be able to browse these projects by turning on and off filters. One of the filter types, for example, is GENRE. The user sees a list of genres which, when clicked, filter out all projects that match that genre. Furthermore, if you click on two different genres, you'll see only the projects that match BOTH of those genres.
The problem is, this all needs to be done via AJAX, and that's when things start to get confusing for me. How can I make an ajax call that not only sets up a new filter, but remembers the filters that are currently in place? When the page is loaded, I could do something like
First Genre
Second Genre
But the problem is that when I click two at a time, I end up only filtering by a single genre. I could, perhaps, update all the links to contain an array of already-selected genres using JS each time one is clicked, but this seems incredibly sloppy. Each and every link would then have something like:
First Genre
Another thought I had was to maybe store all current filters in a cookie and then when a link is clicked, add that new filter to the list of filters in the cookie, but again, this seems sloppy.
Point is, I have no idea what the proper way to do this is, and I'm feeling a bit lost. To anyone out there who's had success doing something like this before, help!!
Ajax filters always create two issues from user point of view. one is user can't bookmark filter urls and can't use back button.
For example, user click on filter 1, then click filter 2. if user click on back button or reload page, user will lose all filter data.
Here is one method to manage all
You can use this method Jquery BBQ http://benalman.com/projects/jquery-bbq-plugin/
on click of genre filter, you can append filter values into hash of url by using above plugin and whenever user reload page or use back button, you have all selected genres into hash.

How to update certain parts of a form

I'm looking to create a report with similar that has a checkbox next to each row. Each row has some fields that are editable (such as comments). What I'd like is to give the user the ability to check off which rows he/she would like to update by selecting the checkbox next to that row. Then I'd have a save button at the bottom of the form that only updates the rows that have a check box active next to it.
I'm pretty new to rails and web programming in general so any advice/direction you might be able to give me should prove helpful.
A popular way to achieve this is to :
1- All your checkboxes should share the same name.
2- All your checkboxes' values should be the ID of the row/object
3- When you POST the form, only the checked checkboxes are in the POST data. Retrieve those IDS and only update these objects.
For example, your checkbox should be something like :
<%= check_box_tag "row_ids[]", row.id, false, :id => "row_#{row.id}" %>
Then, in your controller :
Row.find(params[:row_ids]).each do |row|
# do whatever you want
end
Well you can do this, but it adds more work for the user: they have to check off multiple checkboxes before hitting Update. It be nicer if they just hit Update and it worked.
The basic idea is you want the user to just click Update and your code only updates records that changed.
What you can do is store (in a hidden field tag) the ID of each row's record. Then when you update, you loop through all rows and you grab (based on the ID stored in the hidden field) the record from the database. Let's say only Comments were editable. Then you can check to see if the comments have actually been changed (like with a simple string comparison) and if they have, update it. If more things are editable, then you can check them too before deciding if you need to update or not.
That is a high level description, but let me know if you want some more implementation details.

Rails - storing search query/result

I have a search page which finds candidates.
From this page you can click view to find more information about the candidate.
When on the candidate view you can click edit or do a number of other actions which would return you too the candidates view.
My problem is from the candidates view I need to add a button to go back to the search results.
I originally thought of using a JS button with history -1 but because the user can do other action from inside the view this won't work.
I am still quite new to rails so not sure of my options... I am thinking some sort of caching of the results and then maybe a hidden field to keep track of the location of the cache(don't think this is the best solution as keeping track of the hidden value could get abit messy!)
Thanks, Alex
I would probably use a session variable to store this information.
First, make sure your form that posts to the search page is a GET operation, this way the search details are in your query string. Then in your search action, you can grab the request URL and store it in the session:
session[:search_results] = request.url
Now in your view for the results, you can do your "Back to search results" like this:
link_to "Back to search results", session[:search_results]
You have a couple of options:
Cache the results, as you've suggested. The potential downsides to this are that it takes memory, and if new valid records get added, you won't see them. You could store the cache in Session, or in the database (though in the latter case, you don't gain much).
I'd suggest just remembering the last search term, either in session or using hidden fields. You end up re-running the query when you go to the search results page, but in a properly indexed DB, that shouldn't be a big deal.
Good luck!
You can include the parameters for the query on the subpage. Eg.: /foo/search?q=stuff displays search result. Each result then has a link like /foo/:id?q=stuff. And on the subpage, you will have the parameter available to link back to the main page.
This solution doesn't use any server side state, which is generally accepted as the better way to build web applications. Not only does it mean that you browser will behave as expected, with respect to bookmarks, multiple tabs etc., but it also ensures that proper caching can be employed. Further, it lowers the complexity of your application, making it easier to debug and extend.
You could put the search results in a "search_results" table keyed by the user id. Then when the user hits the page, always load from a query on that table.
If anybody does come across this page and you need a button that goes back to the previous page and still display those search results (just like the google chrome button), just use :back.....
<%= link_to(image_tag("back.svg"), :back, :class => 'back_btn') %>

Resources