21

Re: Multiple Select Helper plugin

ryanb wrote:

Yeah, that should work. What error are you getting? I'm guessing "favourite_fruit" is nil, make sure it is set before calling that:

<%= person.favourite_fruit.name unless person.favourite_fruit.nil? %>

Thanks. I think it's working and there is a problem elsewhere.

22

Re: Multiple Select Helper plugin

With regards to selecting a favourite fruit I have the following in my form:

<tr>
  <td><label for="person_fruits">Fruits</label></td>
  <td><%= collection_multiple_select( 'person[fruits_ids]',
                                      Fruit.find(:all, :order => "name ASC"),
                                      :id,
                                      :name,
                                      :selected_items => @fruits,
                                      :outer_class => 'multiple_select',
                                      :inner_class => 'multiple_select_checkbox',
                                      :alternate => true,
                                      :alternate_class => 'alt' )%></td>
</tr>

<tr>
  <td><label for="person_favourite_fruit_id">Favourite fruit</label></td>
  <td>
    <%= collection_select :person, :favourite_fruit_id, @fruits, :id, :name %>
  </td>
</tr>


and in the controller @fruits has been declared as follows:

@fruits = @person.fruits.map &:id

I'm getting the following error:

Showing app/views/persons/_form.rhtml where line #68 raised:

undefined method `name' for 2:Fixnum

If I replace

<%= collection_select :person, :favourite_fruit_id, @fruits, :id, :name %>

with

    <%= collection_select :person, :favourite_fruit_id, Fruit.find(:all, :order => "name ASC"), :id, :name %>

then I get a list of all fruits but I need a list of those which have been previously selected. Where am I going wrong?

Last edited by mip (2006-10-31 06:35:53)

23

Re: Multiple Select Helper plugin

So

@fruits = @person.fruits.map &:id

get me a collection of ids.

Then in the view I can do

Fruit.find(@fruits, :order => "name ASC")

there must be a better way to do this?

Re: Multiple Select Helper plugin

Try:

<%= collection_select :person, :favourite_fruit_id, @person.fruits, :id, :name %>

If you want the fruits to be in alphabetical order, you can set this in the model:

class Person < ActiveRecord::Base
  has_many :fruits, :order => 'name' # :through => ...
end

Railscasts - Free Ruby on Rails Screencasts

25

Re: Multiple Select Helper plugin

I dont suppose anyone knows how I can use JavaScript to add entries selected in the multiple select list to a drop down list on the same page?

Re: Multiple Select Helper plugin

This article discusses transferring options from one select box to another. The javascript will show you how to add and remove items from a select box, so it will get you halfway there. Every time a checkbox is checked, you need to add it to the select box, etc. Sorry I can't go into any further detail.

Railscasts - Free Ruby on Rails Screencasts

27

Re: Multiple Select Helper plugin

ryanb wrote:

This article discusses transferring options from one select box to another. The javascript will show you how to add and remove items from a select box, so it will get you halfway there. Every time a checkbox is checked, you need to add it to the select box, etc. Sorry I can't go into any further detail.

Thanks for the link.

28

Re: Multiple Select Helper plugin

I have :

<tr>
  <th><label for="person_favourite_fruit_id">Favourite fruit</label></th>
  <td>
    <%= collection_select :person, :favourite_fruit_id, Fruits.find(@fruits, :order => "name ASC"), :id, :name %>
  </td>
</tr>

<tr>
  <th><label for="person_fruits">Fruits</label></th>
  <td><%= collection_multiple_select( person[fruits_ids]',
                                      Fruits.find(:all, :order => "name ASC"),
                                      :id,
                                      :name,
                                      :selected_items => @fruits,
                                      :outer_class => 'multiple_select',
                                      :inner_class => 'multiple_select_checkbox',
                                      :alternate => true,
                                      :alternate_class => 'alt' )%></td>
</tr>

<script type="text/javascript">
  var elementList = document.getElementsByClassName("multiple_select_checkbox");   
  for (i in elementList) {
    Event.observe(elementList, 'click', myFunction(elementList[i].getElementsByTagName('input')));
  }   
</script>


I'm trying to access each input tag in the multiple select list when is is clicked and dynamically add it to the "Favourite fruit" drop down list.

I have a function in my [i]application.js called myFunction() which will add the value to the drop down list but how do I pass it the values?

Re: Multiple Select Helper plugin

You need to specify the onchange HTML attribute in the collection_multiple_select method. I don't have experience with this method, so I'm not sure how to do that. But anyway, you would need to pass a parameter that would look something like this:

:onchange => 'myFunction(this)'

What you want is an onchange HTML attribute in the select tag. It would then call the method every time an item is selected/deselected. You can use the passed parameter to reference what items are select. Sorry I can't offer anymore details. I haven't really done this before.

Railscasts - Free Ruby on Rails Screencasts

30

Re: Multiple Select Helper plugin

ryanb wrote:

You need to specify the onchange HTML attribute in the collection_multiple_select method. I don't have experience with this method, so I'm not sure how to do that. But anyway, you would need to pass a parameter that would look something like this:

:onchange => 'myFunction(this)'

What you want is an onchange HTML attribute in the select tag. It would then call the method every time an item is selected/deselected. You can use the passed parameter to reference what items are select. Sorry I can't offer anymore details. I haven't really done this before.

As far as I can see collection_multiple_select doesnt have a way of my specifying a onchange HTML attribute.

Re: Multiple Select Helper plugin

You'll have to generate the select tag manually then. hmm

Railscasts - Free Ruby on Rails Screencasts

32

Re: Multiple Select Helper plugin

I have:

<%= collection_multiple_select( 'person[fruit_ids]', 
                                      Fruit.find(:all, :order => "name ASC"),
                                      :id,
                                      :name,
                                      :selected_items => @fruits,
                                      :outer_class => 'multiple_select',
                                      :inner_class => 'multiple_select_checkbox',
                                      :alternate => true,
                                      :alternate_class => 'alt' )%>
</tr>

<script type="text/javascript">
  var elementList = document.getElementsByClassName('multiple_select_checkbox');   
  for (i in elementList) {
    Event.observe(elementList[i], 'click', function(e){ alert('Alert!')) }); 
  }   
</script>


I can do an alert every time I click the check box. But how do I access the values?

Re: Multiple Select Helper plugin

Aha, using observe field. Smart!

The link I gave above shows roughly how to access the selected values. Try this:

for (i=0; i < $('the_dom_id_of_the_select_box').options.length; i++) {
  current = $('the_dom_id_of_the_select_box').options[i]
  if (current.selected) {
    alert('Selected: ' + current.value)
  }
}

I think that's how you would do it anyway. This is completely untested.

Last edited by ryanb (2006-11-06 13:29:50)

Railscasts - Free Ruby on Rails Screencasts

34

Re: Multiple Select Helper plugin

ryanb wrote:

Aha, using observe field. Smart!

It was suggested to be my the plugin's developer smile

Here's the email he sent me:

It's not easy, but maybe you can. I'll try to explain myself.

You can configure the multiple_select to have an inner_class in each
of the items. This class is applied not to the checkbox but to a
parent box (an li element, by default). Inside this container there is
the checkbox and the label... so using Prototype you can install
handlers after creating the elements... so:

- add prototype javascript in the header
- use multiple_select in the rhtml
- just below your multiple_select add a javascript tag which:
- search for all inner_class elements
(Document.getElementByClassName), search inside each one the input
(getElementsByTagName)
- install using Event.observe your handler to the checkbox.

If you use several multiple select helpers in one page and you want
different behaviour for each one you must use different inner classes,
of course.

I hope it helps, and I sorry that it isn't easier to do it.

ryanb wrote:

The link I gave above shows roughly how to access the selected values. Try this:

for (i=0; i < $('the_dom_id_of_the_select_box').options.length; i++) {
  current = $('the_dom_id_of_the_select_box').options
  if (current.selected) {
    alert('Selected: ' + current.value)
  }
}

I think that's how you would do it anyway. This is completely untested.

Should I use [i]getElementsByTagName here?

Re: Multiple Select Helper plugin

I don't think you need to use getElementsByTagName for this. That is for grabbing all of a specific tag on one page (such as all select boxes, or all option tags). The $('...') selector will work I think.

Last edited by ryanb (2006-11-06 14:24:18)

Railscasts - Free Ruby on Rails Screencasts

36

Re: Multiple Select Helper plugin

ryanb wrote:

Aha, using observe field. Smart!

The link I gave above shows roughly how to access the selected values. Try this:

for (i=0; i < $('the_dom_id_of_the_select_box').options.length; i++) {
  current = $('the_dom_id_of_the_select_box').options
  if (current.selected) {
    alert('Selected: ' + current.value)
  }
}

I think that's how you would do it anyway. This is completely untested.

Think I understand this. It occurs every time a the [i]Event.observe triggers and event?

Re: Multiple Select Helper plugin

mip wrote:

It occurs every time a the Event.observe triggers and event?

Yeah, if you call the function with Event.observe with that code in it.

Railscasts - Free Ruby on Rails Screencasts

Re: Multiple Select Helper plugin

Hi mip,

My approach will be this (a bit changed from the mail I sent you and a bit easier):

<div id="my-id">
<%= multiple_select 'my-name', [1, 2, 3, 4, 5, 6] %>
</div>
<%= javascript_tag %q{
function myOnClickFunction(event) {
  var element = Event.element(event);
  alert(element.value + ' clicked!');
}

var list = $('my-id');
var checkboxes = list.getElementsByTagName('input');
for (var i = 0; i < checkboxes.length; i++) {
  Event.observe(checkboxes[i], 'click', myOnClickFunction);
}
} %>


I use a wrapper div with an unique id to get to the inputs (the div should wrap only the list, so no other input is modified). Then I get the list of all input tags inside the div (the checkboxes) and I iterate them adding my function to the 'click' event. The function attached to events get automagically a parameter with information about the event, one of the members of this structure is the element that fired the event. If you have the element you have its value and you can do anything you want with it.

I hope it helps.

PD: You obviously need to include prototype in the header.

Last edited by yonosoytu (2006-11-06 16:52:29)

39

Re: Multiple Select Helper plugin

Thanks yonosoytu that works. Is it possible to get the value of the label associated with the check box too?

Can I pass more parameters to myOnClickFunction?

Should something like this be possible:

<div id="my-id">
<%= multiple_select 'my-name', [1, 2, 3, 4, 5, 6] %>
</div>
<%= javascript_tag %q{
  function myFunction(event, label) {
    var element = Event.element(event);
    alert(label.value + ' clicked!');
  }
  var list = $('my-id');
  var checkboxes = list.getElementsByTagName('input');
  var labels = list.getElementsByTagName('label');
  for (var i = 0; i < checkboxes.length; i++) {
    Event.observe(checkboxes[i], 'click', myFunction(event, labels[i]));
  }
}
%>

Last edited by mip (2006-11-07 10:46:47)

Re: Multiple Select Helper plugin

Don't know if you can pass another arguments, but you can use DOM to get the label...

function myOnClickFunction(event) {
  var checkbox = Event.element(event);
  var label = checkbox.parentNode.getElementsByTagName('label')[0];
  // ... here your code ...
}

It's a bit tricky, but I don't know how to get the label assigned to a form element easily with Javascript.