I have created a countries, cities and customers table and i'm trying to ensure that when I add a new customer from a drop down I can select a country and then a city related to that country. Currently I am able t select any city and country combination from the drop down. This is my database
CREATE TABLE IF NOT EXISTS `southpac_team`.`customers` (
`id` INT NOT NULL,
`name` VARCHAR(100) NULL,
`country_id` INT NULL,
`city_id` INT NULL,
`address` VARCHAR(255) NULL,
`postal_address` VARCHAR(255) NULL,
`phone` VARCHAR(45) NULL,
`email` VARCHAR(100) NULL,
`payment_terms_id` INT NULL,
`stop_credit` TINYINT(1) NULL,
`gst_percentage` INT NULL,
`currency` VARCHAR(45) NULL,
`account_closed` TINYINT(1) NULL,
`invoice_email` VARCHAR(100) NULL,
`customer_notes` VARCHAR(255) NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `southpac_team`.`countries` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `southpac_team`.`cities` (
`id` INT NOT NULL AUTO_INCREMENT,
`country_id` INT NOT NULL,
`name` VARCHAR(100) NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
I've used Cake Bake to create the relationships between the tables this is my customer controller.
<?php
namespace App\Controller;
use App\Controller\AppController;
/**
* Customers Controller
*
* @property \App\Model\Table\CustomersTable $Customers
*/
class CustomersController extends AppController
{
/**
* Index method
*
* @return \Cake\Network\Response|null
*/
public function index()
{
$this->paginate = [
'contain' => ['Countries', 'Cities', 'PaymentTerms']
];
$customers = $this->paginate($this->Customers);
$this->set(compact('customers'));
$this->set('_serialize', ['customers']);
}
/**
* View method
*
* @param string|null $id Customer id.
* @return \Cake\Network\Response|null
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$customer = $this->Customers->get($id, [
'contain' => ['Countries', 'Cities', 'PaymentTerms']
]);
$this->set('customer', $customer);
$this->set('_serialize', ['customer']);
}
/**
* Add method
*
* @return \Cake\Network\Response|null Redirects on successful add, renders view otherwise.
*/
public function add()
{
$customer = $this->Customers->newEntity();
if ($this->request->is('post')) {
$customer = $this->Customers->patchEntity($customer, $this->request->data);
if ($this->Customers->save($customer)) {
$this->Flash->success(__('The customer has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The customer could not be saved. Please, try again.'));
}
$countries = $this->Customers->Countries->find('list', ['limit' => 200]);
$cities = $this->Customers->Cities->find('list', ['limit' => 200]);
$paymentTerms = $this->Customers->PaymentTerms->find('list', ['limit' => 200]);
$this->set(compact('customer', 'countries', 'cities', 'paymentTerms'));
$this->set('_serialize', ['customer']);
}
/**
* Edit method
*
* @param string|null $id Customer id.
* @return \Cake\Network\Response|null Redirects on successful edit, renders view otherwise.
* @throws \Cake\Network\Exception\NotFoundException When record not found.
*/
public function edit($id = null)
{
$customer = $this->Customers->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$customer = $this->Customers->patchEntity($customer, $this->request->data);
if ($this->Customers->save($customer)) {
$this->Flash->success(__('The customer has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The customer could not be saved. Please, try again.'));
}
$countries = $this->Customers->Countries->find('list', ['limit' => 200]);
$cities = $this->Customers->Cities->find('list', ['limit' => 200]);
$paymentTerms = $this->Customers->PaymentTerms->find('list', ['limit' => 200]);
$this->set(compact('customer', 'countries', 'cities', 'paymentTerms'));
$this->set('_serialize', ['customer']);
}
/**
* Delete method
*
* @param string|null $id Customer id.
* @return \Cake\Network\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$customer = $this->Customers->get($id);
if ($this->Customers->delete($customer)) {
$this->Flash->success(__('The customer has been deleted.'));
} else {
$this->Flash->error(__('The customer could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
}
and this is my customer add.ctp
<?php
/**
* @var \App\View\AppView $this
*/
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('List Customers'), ['action' => 'index']) ?></li>
<li><?= $this->Html->link(__('List Countries'), ['controller' => 'Countries', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New Country'), ['controller' => 'Countries', 'action' => 'add']) ?></li>
<li><?= $this->Html->link(__('List Cities'), ['controller' => 'Cities', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New City'), ['controller' => 'Cities', 'action' => 'add']) ?></li>
<li><?= $this->Html->link(__('List Payment Terms'), ['controller' => 'PaymentTerms', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New Payment Term'), ['controller' => 'PaymentTerms', 'action' => 'add']) ?></li>
</ul>
</nav>
<div class="customers form large-9 medium-8 columns content">
<?= $this->Form->create($customer) ?>
<fieldset>
<legend><?= __('Add Customer') ?></legend>
<?php
echo $this->Form->input('name');
echo $this->Form->input('country_id', ['options' => $countries, 'empty' => true]);
echo $this->Form->input('city_id', ['options' => $cities, 'empty' => true]);
echo $this->Form->input('address');
echo $this->Form->input('postal_address');
echo $this->Form->input('phone');
echo $this->Form->input('email');
echo $this->Form->input('payment_terms_id', ['options' => $paymentTerms, 'empty' => true]);
echo $this->Form->input('stop_credit');
echo $this->Form->input('gst_percentage');
echo $this->Form->input('currency');
echo $this->Form->input('account_closed');
echo $this->Form->input('invoice_email');
echo $this->Form->input('customer_notes');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
I am able to create new customers and select countries and cites I just want restrict the drop boxes so that I can only select a city for the correct country. I've tried to research this but have just come across examples using jshelper which cakephp 3.0 doesn't include. Thanks.
You can try Chained Selects Plugin for jQuery Chained Selects Plugin for jQuery and Zepto
Required Source files:
ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
jquery.chained.min.js
Example:
$(document).ready(function() {
$("#cityId").chained("#countryId");
});
来源:https://stackoverflow.com/questions/42402533/dependent-dropdown-box-cakephp-3