views:

39

answers:

2

Hi,

Got a rails application that has a form (new action) with a select with an options value range from 1 to 5. When the users selects one of the options I need to use ruby "build" to build a number of objects depending on what the select value is.

So when the user selects 2 in the select box the following code needs to run:

@rooms = 2.times { @travel.rooms.build }

Also when the users changes this value from 2 to 1 the code needs to be replaced with

@rooms = 1.times { @travel.rooms.build }

Basically I'm having trouble finding a way to setting the value in jQuery and then updating it in the html. Getting the value is no problem, it's how to dynamically change it in the html that's the issue.

Any tips on how to proceed with this?

Thanks, Amund

Edit - Clarification

I need this to happen before the form is submitted.

@rooms = 2.times { @travel.rooms.build }

So any changes to the above needs to happen while the user is on the form page.

A: 

I am not sure if you need Ruby help or jQuery help? Well, here's some Ruby, anyway. I includes the input validation just for good measure:

count = (params[:number_of_rooms] || 1).to_i
count = [1, [5, count].min].max
@rooms = (0...count).collect { @travel.rooms.build }

I'm not inclined to write a solution in JS, but in general, you add an observer to the select field and then add the fields by creating HTML dom elements. Assuming you already have one of the forms built on the page, you can probably do some tricks to clone the fields to create the additional fields. Another way is to always have 5 sets of fields and just show/hide the sets of fields you need. Good luck!

wuputah
Thanks for the reply, it's really more of a jQuery question. Unfortunately you don't have access to params before the form is submitted. I've clarified this in the question above.
Amund
Sorry I am still lost. Maybe someone more familiar with what you're trying to do (and working in jQuery) will be able to help.
wuputah
I see you have working knowledge of Rails, so let me paraphrase in a more Rails-way. I have a nested form, travel has many rooms. Instead of the user clicking "add room" to have a new room object appear in the form I want the number of rooms that appear in the form to be determined by what the user selects in the select_tag.
Amund
I'm not inclined to write a solution in JS, but in general, you add an observer to the select field and then add the fields by creating HTML dom elements. Assuming you already have one of the forms built on the page, you can probably do some tricks to clone the fields to create the additional fields. Another way is to always have 5 sets of fields and just show/hide the sets of fields you need. Good luck!
wuputah
A: 

I've found a way that works, although it's not pretty nor does it work if the user doesn't have JS (In my case if the user don't have JS they can gtfo).

Below is the code needed for it to work. (Keep in mind this works, but I've done nothing to make it more concise or better). ps. It looks like hell.

$('#room_details .fields').hide();
$('#room_details .fields:eq(0)').show();
$('.fields:eq(0)').find('.is_wanted').val("true");
$('#number_of_rooms').change(function() {
$('#room_details .fields').hide();
$('.is_wanted').val("");
if($(this).val() == '1') {
  $(".fields:eq(0)").each(function() {
    $(this).show();
    $(this).find('.is_wanted').val("true");
  });
}
else if ($(this).val() == '2'){
  $(".fields:eq(0), .fields:eq(1)").each(function() {
    $(this).show();
    $(this).find('.is_wanted').val("true");
  });
}
else if ($(this).val() == '3'){
  $(".fields:eq(0), .fields:eq(1), .fields:eq(2)").each(function() {
    $(this).show();
    $(this).find('.is_wanted').val("true");
  });
}
else if ($(this).val() == '4'){
  $(".fields:eq(0), .fields:eq(1), .fields:eq(2), .fields:eq(3)").each(function() {
    $(this).show();
    $(this).find('.is_wanted').val("true");
  });
}
else if ($(this).val() == '5'){
  $(".fields:eq(0), .fields:eq(1), .fields:eq(2), .fields:eq(3), .fields:eq(4)").each(function() {
    $(this).show();
    $(this).find('.is_wanted').val("true");
  });
}
});

Then in the model we do:

accepts_nested_attributes_for :rooms, :allow_destroy => true, :reject_if => proc { |attrs| attrs['is_wanted'].blank? }

Where is_wanted is a hidden field in the form for each room. I'm sure there are prettier ways, but at least it works.

Any thoughts?

Amund
I might add, that in my use case there will always be a limit of 5 rooms, of the limit is variable then this wont work. Also if you have more than 5 rooms this will function will get really long quickly.
Amund