Dependent Combos in CakePHP 3.5

0

I am using ajax to be able to recharge a second combo dependent on the first and I can not get it to work. I enclose my code to see if you can help me.

The view loads a script and it executes a controller action. Everything works correctly and the controller returns the following: {"data": {"states": ["Curitiva", "Florianopolis", "San Pablo"]}} which is correct, but when receiving it in the view it seems that I can not visualize the result because the second combo / select is blank.

src / Controller / DropdownController.php

<?php
namespace App\Controller;

use App\Controller\AppController;

class DropdownController extends AppController 
{
    public function index()
    {
        $countries = $this->getCountry();
        $states = $this->getState();

        $this->set(compact(['countries', 'states']));
        $this->set('_serialize', ['countries', 'states']);
    }

    private function getCountry()
    {
        //$this->loadModel('Country');
        //return $this->Countries->find('list');
        return ['Argentina', 'Brasil', 'Chile'];
    }

    private function getState($country_id = null)
    {
        switch ($country_id) 
        {
            case 0:
                $states = ['Buenos Aires', 'Córdoba', 'Tucumán'];
                break;
            case 1:
                $states = ['Curitiva', 'Florianópolis', 'San Pablo'];
                break;
            case 2:
                $states = ['Iquique', 'Santiago de Chile', 'Valparaiso'];
                break;
            default:
                $states = [];
        }
        return $states;
    }

    public function ajaxStateByCountry()
    {
        if ($this->request->is(['ajax', 'post'])) 
        {
            $id = $this->request->query('id');
            $data = ['data' => ['states' => $this->getState($id)]];
            return $this->json($data);
        }
    }
}

src / Template / Dropdown / index.ctp

<?= $this->Html->script('dropdown.js'); ?>

<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
        <li><?= $this->Html->link('Home', ['controller' => 'pages']) ?></li>
    </ul>
</nav>

<div class="form large-9 medium-8 columns content">
    <?= $this->Form->create() ?>
    <fieldset>
        <legend>Prueba con AJAX</legend>
        <?php
            //echo $this->Form->control('País', ['id' => 'countryField', 'options' => $countries]);
            $request = $this->Url->build(['action' => 'ajaxStateByCountry', 'ext' => 'json']);
            echo $this->Form->control('País', ['id' => 'countryField', 
                                               'rel' => $request,
                                               'options' => $countries]);
            echo $this->Form->control('Ciudad', ['id' => 'stateField','options' => $states]);
        ?>
    </fieldset>
    <?= $this->Form->button('Enviar') ?>
    <?= $this->Form->end() ?>
</div>

webroot / js / dropdown.js

$(function() 
{
    $('#countryField').change(function() 
    {
        var targeturl = $(this).attr('rel');
        var country_id = $(this).val();

        $.ajax({
            type: 'get',
            url: targeturl + '&id=' + country_id,
            beforeSend: function(xhr) 
            {
                xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
            },
            success: function(response) 
            {
                if (response.data) 
                {
                    $('#stateField').html(response.data.states);
                }
            },
            error: function(e) 
            {
                alert("An error occurred: " + e.responseText.message);
                console.log(e);
            }
        });
    });
});
    
asked by Vaquero 24.10.2017 в 14:57
source

1 answer

0

I forgot to inform you that if I do the following, it works, but I do not know if it is the correct way:

private function getState($country_id = null)
{
    switch ($country_id) 
    {
        case 0:
            //$states = ['Buenos Aires', 'Córdoba', 'Tucumán'];
            $states = [
                '<option value="1">Buenos Aires</option>',
                '<option value="2">Córdoba</option>',
                '<option value="3">Tucumán</option>',
            ];
            break;

        case 1:
            //$states = ['Curitiva', 'Florianópolis', 'San Pablo'];
            $states = [
                '<option value="4">Curitiva</option>',
                '<option value="5">Florianópolis</option>',
                '<option value="6">San Pablo</option>',
            ];
            break;

        case 2:
            //$states = ['Iquique', 'Santiago de Chile', 'Valparaiso'];
            $states = [
                '<option value="7">Iquique</option>',
                '<option value="8">Santiago de Chile</option>',
                '<option value="9">Valparaiso</option>',
            ];
            break;

        default:
            $states = [];
    }
    return $states;
}
    
answered by 24.10.2017 в 15:18