Dejsa Cocan
Dejsa Cocan

Reputation: 1569

SilverStripe - Retrieve checked values from admin model based on form field selection

I have a form with a dropdown field that contains a list of services. These services are displayed in the drodpown based on what has been entered into the Admin Model "Service."

The dropdown:

<select id="ServiceReq">
    <option value="">Service Requested*</option>
    <% if getServiceList %>
        <% loop getServiceList %>
            <option value="$Name">$Name</option>
        <% end_loop %>
    <% end_if %>
</select>

The code for the Service admin model:

<?php
class Service extends DataObject {

    private static $db = array(
        'Name' => 'varchar',
    );

    private static $belongs_many_many = array(
        'Locations' => 'Location'
    );

    public static $summary_fields = array(
        'Name' => 'Title',
    );

    private static $field_labels = array(
        'Name'
    );

    public function getCMSFields() {

        $fields = parent::getCMSFields();

        if ($this->ID) {
            $fields->addFieldToTab('Root.Locations', CheckboxSetField::create(
                'Locations',
                'Locations',
                Location::get()->filter(array(
                    'AcceptingAppointments' => '1'
                ))->map()
            ));
        }

        return $fields;
    }
}

What I want to do is, when a service is selected from the ServiceReq dropdown, I want to retrieve all the selected locations from the checkbox field set located in the Service admin model's Locations tab. These locations will then be used to populate the Locations dropdown in the form:

 <select id="Location">
     <option value="">Location/Hospital</option>
 </select>

I know I need to use the currently selected Service's ID, but I'm not sure how I can setup of the function to do this, but I am lost as to how to setup the functionality in the server side to be passed to the form.

Upvotes: 1

Views: 703

Answers (2)

3dgoo
3dgoo

Reputation: 15794

The Dependent dropdown field module helps do this nicely and easily.

Here is an example form using the dependent dropdown field that has a Service dropdown field and a Location dropdown field that is populated with the locations related to that service.

public function ServiceForm() {

    $locationSource = function($serviceID) {
        $service = Service::get()->byID($serviceID);
        return  $service->Locations()
                    ->filter('AcceptingAppointments', true)
                    ->map('ID', 'Name')->toArray();
    };

    $servicesField = DropdownField::create(
        'Service',
        'Service',
        Service::get()->map('ID', 'Name')->toArray()
    )->setEmptyString('');

    $locationsField = DependentDropdownField::create(
        'Location',
        'Location',
        $locationSource
    )->setDepends($servicesField);

    $form = Form::create($this, 'ServiceForm',
        FieldList::create(
            $servicesField,
            $locationsField
        ),
        FieldList::create(
            FormAction::create('processServiceForm', 'Submit')
        ),
        RequiredFields::create(
            'Service', 
            'Location'
        )
    );

    return $form;
}

First we have a normal dropdown field to select a service:

$servicesField = DropdownField::create(
    'Service',
    'Service',
    Service::get()->map('ID', 'Name')->toArray()
)->setEmptyString('');

Next we add a dependent dropdown field to select the service:

$locationsField = DependentDropdownField::create(
    'Location',
    'Location',
    $locationSource
)->setDepends($servicesField);

The setDepends function defines which field to link this field to, in this case the services field. The $locationSource is a function that will retrieve the locations and return an array for the field to use.

$locationSource = function($serviceID) {
    $service = Service::get()->byID($serviceID);
    return  $service->Locations()
                ->filter('AcceptingAppointments', true)
                ->map('ID', 'Name')->toArray();
};

Upvotes: 1

muskie9
muskie9

Reputation: 476

If you are trying to get the Locations related to the current Service, it would be $this->Locations() and you can still apply your filter you have, $this->Locations()->filter(array('AcceptingAppointments' => '1'))->map().

If it's more of a live updating type of thing, you may want to look into entwine. There is a good blog post for getting started with entwine here

Upvotes: 1

Related Questions