How to dynamically update options for a dropdown list?

How to dynamically update options for a dropdown list?

ptaylorptaylor Posts: 28Questions: 7Answers: 0

My dropdown list will have a little over 1000 items, and I'd like to only show the items that are not already associated with another record.

I now have code that generates the list of options, but this is only loaded at page-load time. If I select an existing record and hit edit, I want to update that list of options. In addition to all the items that aren't associated with any other record, this new list of options needs to also include the one item that IS associated with the individual record that is being edited.

So, I guess this is a two-part question... How can I grab the ID of the item being edited at the moment the user hits Edit? Once that is done, how can I update the list of options based on that record ID.

This question has an accepted answers - jump to answer

Answers

  • ptaylorptaylor Posts: 28Questions: 7Answers: 0
    edited May 2015

    Ok, making headway. Please excuse my primitive code.

    My project includes a sim table, an ip table, and a sim_ip link table. It also includes a vendor table, as different vendors have different ranges of static IP addresses available.

    The desired behavior is to only show IP addresses in the dropdown list that belong to the selected vendor and have not been assigned to any other sim when creating new records. When editing an existing record, I want the dropdown list to be the same as above, except it should also include the IP address that is assigned to the selected record.

    Here's my code:

        editor.on( 'initEdit', function ( e, node, data ) {
            console.log( data );
            $.ajax( {
                url: "/sim/update_ip_list.php",
                type: 'POST',
                data: {
                    data: data
                },
                dataType: 'JSON',
                success: function( json ) {
                    editor.field( 'sim_ip.ip_id' ).update( json );
                }
            } );
        } );
    
    $tempdata = $_POST["data"];
    $passed_vendor_id = $tempdata['sim']['vendor_id'];
    $passed_ip_id = $tempdata['sim_ip']['ip_id'];
    
        $ipList = $db
                    ->query( 'select' )
                    ->distinct( true )
                    ->table ( 'ip' )
                    ->get( 'ip.id as value' )
                    ->get( 'ip.name as label')
                    ->get( 'vendor_id')
                    ->join( 'sim_ip', 'ip.id = sim_ip.ip_id', 'LEFT')
                    ->where( 'vendor_id', $passed_vendor_id )
                    ->and_where( 'sim_ip.ip_id', null)
                    ->or_where( 'sim_ip.ip_id', $passed_ip_id )
                    ->order( 'value asc')
                    ->exec();
        $out[] = array('value' => '', 'label' => '');
        while ( $row = $ipList->fetch() ) {
            $out[] = array(
                "value" => $row['value'],
                "label" => $row['label']
             );
        }
        echo json_encode($out);
    

    When I hit the Edit button for a row, the Ajax posts the entire data variable to the PHP code. The PHP code grabs the two fields I need from the data that was passed. It generates the list, including the 'value' and 'label" for the passed IP id. It JSON encodes the result, sends it back to the client browser, who populates it appropriately.

    My dropdown list on the resulting edit page includes all the ip_ids that are not assigned to a sim, and it includes the ip_id that was passed via Ajax, however the one that is selected in the dropdown list is the top item, the blank record.

    Thinking perhaps it defaults to the top item, I tried altering my code so that the passed ip_id was the top item, but it doesn't matter. The one shown selected when first opening the edit screen is the blank item, for some strange reason. Why doesn't the right one show up as selected?

    I've almost go it... Any ideas what I'm doing wrong?

  • ptaylorptaylor Posts: 28Questions: 7Answers: 0
    edited May 2015

    This may be an issue with when the update happens... I've found that if I navigate to the page, select a record and hit Edit, the ip field is blank. But, if I close the form, then hit edit again on the same record, it opens back up with the proper item as selected in the dropdown list.

    Is the initEdit call too late for this to work as desired? What other method can I use to make this work as planned? Is there an event to call when a record is selected?

  • ptaylorptaylor Posts: 28Questions: 7Answers: 0
    edited May 2015

    Ok, finally got this down...

    It appears that before the form opens, I need to have all possible options in the dropdown. So, when the page loads, I'm not doing anything to restrict the options:

            Field::inst( 'lte_sim_ip.ip_id' )
                ->setFormatter( 'Format::nullEmpty' )
                ->options( 'lte_ip', 'id', 'name'),
    

    Using the initEdit event, I use Ajax to pull a list of options for the dropdown that include all the unused ip_id's and the one that the selected record uses.

    This works as designed, but I found that if you try to create a record after you edit one, the dropdown list will include the items set by initEdit. So, I started watching for initCreate and using Ajax to pull the list of all unused ip_id's, so I'm ready when someone does an Edit, then a create without reloading the page.

    The opposite workflow causes an issue too though. If you create a record, then edit another record, I'm back to the situation I was in originally with the Edit... The dropdown has everything I want in it, but that field starts out blank on the edit screen. So, to get this working again, I needed to be able to reset the list of options to that same as it was when the page is loaded (all possible options).

    Finally, I started watching for the Close form event. When I see it, I update ip_id's to be the full list of all possibilities. So, this updates the dropdown after every Create or Edit back to the same as the page loaded with.

    In this way, the dropdown list has only unused items when I'm doing a create, and has unused items along with the selected item when you do an edit, and everything displays properly no matter the order of creates / edits you do.

    Whew!

  • allanallan Posts: 63,680Questions: 1Answers: 10,498 Site admin
    Answer ✓

    Hi,

    Thanks for posting back with your findings - good to hear you got it working in the end!

    You may wish to have a look at the dependent() method if you look into this further, or need to do something similar again in future. It will hopefully take some of the pain away!

    Regards,
    Allan

  • ptaylorptaylor Posts: 28Questions: 7Answers: 0

    Thanks Allan - I don't think the dependent() method would help me here, since the dropdown value doesn't change depending on values put on this specific form, but I see where it could be potentially useful.

    Ultimately, I ended up using Select2, which didn't match the behavior listed above. Fortunately, they allow you to set things programatically in the javascript and taking advantages of that feature took care of my issues.

This discussion has been closed.