Multiple dependent dynamic select boxes in form

2.3k Views Asked by At

There is a model A that has_many B and a form where one can create a new A and add/remove Bs. I.e. there is a link Add new B that runs some Javascript to insert another partial where one fills in values for B. All works fine.

The problem

Specifying a B is done through selecting the values using a couple of select boxes. The problem is that depending on a value selected in one, the collections used in the other selects should be scoped to only show relevant options. It's the classic case with dynamic select boxes (think country - state select boxes), only with more select boxes and I'd like all the select boxes to appear initially, so the user can start from anywhere (select state first and country select box narrows down its collection to the ones that can be chosen for that state).

Current approach

The Bs are rendered in a table, one B per row and I was thinking that I could use AJAX to replace the table row (content) after fetching the new collections from the server. This obviously needs a couple of things in place.

  • tr tag must have a unique id attribute, so replace_html can be used.
  • need to have a trigger on change for each select box
  • need to pass all select boxes' values (for that row) to the server

I'm stuck here, because of the following:

  • adding a B needs to have something unique to identify the tr tag as well as all the selects on that row. I can use Time.now.to_i but that won't work for the Javascript run by the link to add a new B because that will hardcode the value and all use the same.
  • not sure if I should go with observe_field or a remote call in the select form field helper.
  • how to pick up the values of all selects in one row and pass that remotely to the server when triggered?

The project I'm working on is Rails 1.2.3 and uses Prototype. Please feel free to post "newer" solutions too, because I'm curious to see different solutions.

Any help on this is highly appreciated. Thanks in advance!

2

There are 2 best solutions below

0
On

This doesn't answer your entire question but it might get you started. I handle it like this... this is for playlist entry, where the user can add new forms in a div #playlist-entry, and each form is .new_song_form with a hidden field .form_num (which I use in the create.js.erb file to tell it which form to hide/warn of validation errors, which isn't really relevant for you I guess).

var form_counter = 1;

function addSongFields() {
    playlistEntry = $('#playlist-entry');
    playlistEntry.append("<%= escape_javascript(render :partial => 'playlist_entry_form', :locals => { :schedule_event => @schedule_event, :playlist_entry => PlaylistEntry.new }) %>");
    playlistEntry.find('.new_song_form:last').attr('id', 'new_song_form_'+form_counter);
    playlistEntry.find('.form_num:last').val('new_song_form_'+form_counter);
}

$(document).ready(function() {  
    $('#add-song-link').click(function(event) {
        event.preventDefault();
        addSongFields();
        form_counter++;
    });
});

This form is a little different because there's no one "major" form to submit, it's a bunch of forms all on one page, but this basic idea might help you. It's not perfect programming - for example I should be passing form_counter as an argument to the function... but it works perfectly.

0
On

Dynamic Dependent Select Boxes How to create dependent drop down list in php? I have searched a lot then implemented this one. This is created using HTML, JS, PHP simple dependent drop down boxes.

I knew it was possible to create a dynamic dependent drop down form using PHP, MySQL, and JavaScript,

but I had never had an excuse to use one before I need to teach to my students.

<?php

$region = $country = $state = $city = null; //declare vars

$conn = mysql_connect('localhost', 'username', 'password');
$db = mysql_select_db('selects',$conn);

if(isset($_GET["region"]) && is_numeric($_GET["region"]))
{
    $region = $_GET["region"];
}

if(isset($_GET["country"]) && is_numeric($_GET["country"]))
{
    $country = $_GET["country"];
}

if(isset($_GET["state"]) && is_numeric($_GET["state"]))
{
    $state = $_GET["state"];
}

if(isset($_GET["city"]) && is_numeric($_GET["city"]))
{
    $city = $_GET["city"];
}

?>

<script language="JavaScript">

function autoSubmit()
{
    var formObject = document.forms['theForm'];
    formObject.submit();
}

</script>

<form name="theForm" method="get">

    <!-- REGION SELECTION -->

    <select name="region" onChange="autoSubmit();">
        <option value="null"></option>
        <option VALUE="1" <?php if($region == 1) echo " selected"; ?>>East</option>
        <option VALUE="2" <?php if($region == 2) echo " selected"; ?>>West</option>
    </select>

    <br><br>

    <!-- COUNTRY SELECTION BASED ON REGION VALUE -->

    <?php

    if($region != null && is_numeric($region))
    {

    ?>

    <select name="country" onChange="autoSubmit();">
        <option VALUE="null"></option>

        <?php

        //POPULATE DROP DOWN MENU WITH COUNTRIES FROM A GIVEN REGION

        $sql = "SELECT COUN_ID, COUN_NAME FROM COUNTRY WHERE RE_ID = $region";
        $countries = mysql_query($sql,$conn);

        while($row = mysql_fetch_array($countries))
        {
            echo ("<option VALUE=\"$row[COUN_ID]\" " . ($country == $row["COUN_ID"] ? " selected" : "") . ">$row[COUN_NAME]</option>");
        }

        ?>

    </select>

    <?php

    }

    ?>

    <br><br>

    <?php

    if($country != null && is_numeric($country) && $region != null)
    {

    ?>

    <select name="state" onChange="autoSubmit();">
        <option VALUE="null"></option>

        <?php

        //POPULATE DROP DOWN MENU WITH STATES FROM A GIVEN REGION, COUNTRY

        $sql = "SELECT STAT_ID, STAT_NAME FROM states WHERE COUN_ID = $country ";
        $states = mysql_query($sql,$conn);

        while($row = mysql_fetch_array($states))
        {
            echo ("<option VALUE=\"$row[STAT_ID]\" " . ($state == $row["STAT_ID"] ? " selected" : "") . ">$row[STAT_NAME]</option>");
        }

        ?>    

    </select>

    <?php

    }

    ?>

    <br><br>

    <?php

    if($state != null && is_numeric($state) && $region != null && $country != null)
    {

    ?>

    <select name="city" onChange="autoSubmit();">
        <option VALUE="null"></option>

        <?php

        //POPULATE DROP DOWN MENU WITH CITIES FROM A GIVEN REGION, COUNTRY, STATE

        $sql = "SELECT CIT_ID, CITY_NAME FROM CITY WHERE STAT_ID = $state ";
        $cities = mysql_query($sql,$conn);

        while($row = mysql_fetch_array($cities))
        {
            echo ("<option VALUE=\"$row[CIT_ID]\" " . ($city == $row["CIT_ID"] ? " selected" : "") . ">$row[CITY_NAME]</option>");
        }

        ?>    

    </select>

    <?php

    }

    ?>

</form>