Dynamic forms rails 6 - ruby-on-rails

I'm stuck on something I didn't think would be so difficult. I'm making a fantasy football website for a client. I have a separate table for players and roster. Players being the global pool of available players to choose and the roster being the user's roster where they add available players to their team. For the new roster form, where a player is added to the user's roster, the form expects values such as (in order) position, player_id, name, teamname (user's teamname), user's team_id, user_id. I want a dynamic form where position is selected via a dropdown select_tag or form.select, that selection then populates the player selection drop down to show only players of that position. I cannot seem to get this function to work. Any suggestions?

Update: I finally solved the issue using a separate local form in the new player page and sending the select_tag value to the controller where it became the string for showing only the players at that position. By doing it before the form was rendered the onchange method didn't try to submit the form and everything populated as expected.
If anyone has a similar issue I'd be happy to advise you on it, the specific answer will be depending on your specific set up and requirements.

Related

Toggle categories in a table in Ruby on Rails

I am trying to create a page that shows a table that contains products and I would like for the user to be able to toggle the categories. For example, if there are categories jeans, shirts and jackets, I would like a set of checkboxes that would toggle between showing the three categories of products. The problem is that I am unsure of how to approach this problem. I am not sure how to allow the user to relay the information to the controller without changing every users toggled categories. I also don't know how to get around the fact that refreshing the page to refresh the table would simply reset all of the categories.
you can do it in this way,
based upon event click of checkbox fire up ajax request on get req/param_catagory
get and assign data and load it over data table
you can use jquery data table plugins for that
There are few easy jquery plugins for that example: jquery data table
Hope this will help.

How do I get Grails g:select with multiple-selection with all selections when returning from the controller

I have a page that is a report from a database and I'm working on modifying how the filtering works. The intention is to allow the user to select possible values form a list that will be used to filter the resulting report. There are too many values to do this with checkboxes. I'm defining a multiple selection list box with this:
<g:select name="country" from="${countryDataList.KOUNTRY}" value="${params.country}" multiple="true" />
countryDataList is a List<> of objects with a name and a value which I create in the controller. I'm able to get the selected counties and process them without an issue.
But when the page returns from the controller with the filtered report, only the first selection in the list is selected. It doesn't re-select all of the items that the user selected. I am passing the params.country object back from the controller as
country:params.country
I saw some posts about this not working, but they are all from several years ago. Am I missing a vital step?
Ahh sorry, I was reading it on the phone initially and missed the point.
So what you want is a way of sending a multiple select box to a confirmation page. If I understand correctly?
Anyways how many objects in the select are we talking massive or a dozen couple of dozen or so ?
What I did was use check boxes and did a confirmation which shows the selection ticked in check boxes.. So this is the confirmation page that loads in https://github.com/vahidhedayati/mailinglist/blob/master/grails-app/views/mailingListEmail/confirmcontact.gsp
this page which is where multiple attachments selected from the schedule re-appear...
https://github.com/vahidhedayati/mailinglist/blob/master/grails-app/views/mailingListAttachments/_mailerAttachmentsDisplay.gsp.
Please note advice below is all conceptual stuff and there may be easier ways than this
Other than that You could create a taglib call on the confirmation page https://github.com/vahidhedayati/ajaxdependancyselection/blob/master/grails-app/taglib/ajaxdependancyselection/AutoCompleteTagLib.groovy#L55 which takes in your arrayList you could probably convert it to JSON pass it into the javascript that you load in within the taglib (on mine further down it loads this page in)
https://github.com/vahidhedayati/ajaxdependancyselection/blob/master/grails-app/views/autoComplete/_selectJs1.gsp#L23
and look to reselect them using javascript... as I say I haven't tested the last bit, the first bit i.e. checkbox works it is/has been in use.
Years later from you I just had the same problem. What I figured out is: it happens when params.country is an array instead of a Collection (i.e. an ArrayList).
A workaround for this if you want to stick to the array type is at the value attribute of the tag doing this: params.country?.findAll().

Need to update HABTM checkboxes based on a select menu

In my rails 3.1 app, I have a Timesheet model. A Timesheet belongs to a Track. A Track has many TimingEyes.
When I create a new Timesheet and select its Track (via a select menu), I need to dynamically display a group of checkboxes for choosing Timing Eyes that were activated that day. At the moment I can display all the timing eyes available in my database, however there are a dozen tracks each with several timing eyes. This is way too much information on the new Timesheet form.
Is there a way I can limit the group of Timing Eyes to the track_id chosen in my select menu? Would there be an advantage to making this a multistep form?
Multi step form wouldn't be a bad thing here and would remove complexity... if you want to stay with a single page form though, this sounds like a great time for some jquery.
Use .change to fire whenever the select box changes value.
When this fires use .get (ajax) to render your "checkbox" section html.
So a basic boilerplate would look something like this:
$("#trackselect").change(function () {
$.get('yoururl', function(data) {
$('#checkboxsection').html(data);
});
})
With this setup you need to define a url/page that outputs the checkboxes html for that particular track. Maybe something like (http://yourdomain.com/tracks/:id/checkboxes).
Hope this helps

Rails Nested Form with Ajax

I have an interesting problem involving an object creation step in my Rails 3 music application.
I have two models (not the actual models; but for simplicity):
Playlist
Song
Playlist has_many Songs; Song belongs_to Playlist.
Each Playlist object must have an exact number of Songs. Each Song must belong to a Playlist.
Given this, I want to create a process for creating a Playlist that also involves creating all of the necessary Songs at the same time.
Another thing is that to get Song data, the user enters a query (which I will not be saving in the Song model), which I then gather data from an API with. This is the data that should be used to make the Song object. Therefore, I can't (don't think?) use a traditional form_for.
Instead, I'm using a remote form_tag. This form asks for a query and then uses an Ajax request to fetch the data, which is put into a temporary Song object and then displayed inline on the Playlist creation page using a Song view. This form is reused for all the necessary Song objects for the Playlist.
So, the idea is that when the user has entered the required number of queries (i.e. added the required number of songs to the playlist), they are presented with a new button that enables them to submit the playlist info and continue in the process. The Playlist will then be created with all the Song objects that were created via Ajax as children.
In reality, I can't figure out a way for this to work in an elegant way. Although I create the Song objects via Ajax, they aren't saved anywhere and they aren't aware of which Playlist they're supposed to be added into (because the Playlist object doesn't exist in the database yet either.) Therefore, when I go to the next step, I'm left without all the Song data. I looked into using nested forms with accepts_nested_attributes_for, but I can't figure out a way to use it with my setup (a non-model-based form using Ajax.)
So, I'm stuck. If anyone can help, it would be very much appreciated.
I've run into problems similar to this before. For the record, I have never found the remote tags useful and never end up using them for something this complicated. You're right - nested forms with accepts_nested_attributes_for were made for this kind of thing, and there's certainly a way to get it work.
What you need to do is, after your Ajax query, generate your nested Song fields on the fly with JavaScript. For example, let's say you have:
<form...>
<input type="text" name="playlist[name]" />
<div class="songs">
</div>
</form>
You will want your Ajax callback to do something like (I'm assuming jQuery here):
<script type="text/javascript">
$(function() {
var songs = $('form .songs') // Store a reference to the DOM song container
// Insert Ajaxy goodness for song lookup here.
// When it's finished, it should call add_song and pass in any data it needs
})
function add_song(song_name, artist_name, artist_id) {
var num_songs = $(songs).size()
$(songs).append('<p>'+song_name+' by '+artist_name+
'<input type="hidden" name="playlist[songs_attributes]['+num_songs+'][name]" value="'+song_name+'" />' +
'<input type="hidden" name="playlist[songs_attributes]['+num_songs+'][artist_id]" value="'+artist_id+'" /></p>')
}
</script>
There are few things going on there:
The field name "playlist[songs_attributes]..." is what tells Rails that that field belongs to a nested attribute
The num_songs index after "playlist[songs_attributes]..." is extremely important. Rather, it's extremely important that it be unique for every song. Think of it like an array index. So basing it off of the size of the every-increasing list of songs is perfect. (This is the trickiest and least-obvious part of dynamically creating nested form fields, IMO.)
My code probably isn't perfect, and I'm sure I didn't get your field names right anyway. But it should be a good start. Also, looking at the submitted form data in your app's development log is quite helpful for debugging this stuff.
Here are a few things to consider:
What about your users who don't have JavaScript available? (I've been told those people exist.)
Why do you want to couple the playlist creation process to the song creation process? What's wrong with creating a playlist as its own process? This way a playlist can be saved. Then you can create songs (since it requires gathering data from a separate API), so the songs can be saved. Then you can associate songs to a playlist. Consider saving the user's input at each step, so that if s/he has to stop in the middle, s/he won't lose all the existing data.
If you implement a not-Ajax interface first, then it may be easier for you to pull together the pieces to create your final Ajax interface. This way you have your all your necessary resources in place. The Ajax just becomes a nice glue so that there aren't so many page refreshes.

What is the best way to handle repeating forms in MVC?

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.

Resources