I am implementing a dependent drop-down and want to save their IDs in the table CANDIDATE.
I have a table named as CENTER which has two columns ID, NAME.
My other table is DISTRICT which has three columns ID, NAME and CENTER_ID.
By selecting the CENTER , I am populating the DISTRICT drop-down but the district_id is not being saved in the table CANDIDATE .
_form
<div class="row">
<?php echo $form->labelEx($model, 'district_id'); ?>
<?php
$dist = CHtml::listData(Center::model()->findAll(array('order' => 'id')), 'id', 'name');
echo $form->dropDownList($model, 'center_id', $dist, array(
'prompt' => '–select district–',
'ajax' => array('type' => 'POST',
'url' => CController::createUrl('candidate/districts'),
'update' => '#center_id',
)
));
?>
<?php
echo CHtml::dropDownList('center_id','', array());
?>
</div>
CandidateController
public function actionDistricts() {
$centers = District::model()->findAll('center_id =:id', array(':id' => (int) $_POST['Candidate']['center_id']));
$return = CHtml::listData($centers, 'id', 'name');
foreach ($return as $centerId => $centerName) {
echo CHtml::tag('option', array('value' => $centerId), CHtml::encode($centerName), true);
}
}
1) It seems like your url is not properly created:
'url' => CController::createUrl('districts')
Try:
'url' => CController::createUrl('candidate/districts')
2) The form you post:
$form->dropDownList($model, 'district_id', $dist...
It posts district_id to CandidateController/actionDistricts(), where you do following:
$centers = Center::model()->findAll('id=:id', array(':id' => (int) $_POST['Candidate']['center_id']));
I can't see any input containing center_id, moreover, firing Center::model()->findAll('id:id'..) doesn't make sense, if you search by primary key (id), do Center::model()->findByPk($id);
Anyways, back to the problem, your firebug log sais it all, it can't read center_id form $_POST variable, so to finish it up, try rewriting actionDistricts().
I can't guess what kind of relation (one district, several centers per 1?) your db has, so i wont be able to fully fix the problem here. But you should rewrite
$centers = Center::model()->findAll('id=:id', array(':id' => (int) $_POST['Candidate']['center_id']));
to something that expects $_POST['Candidate']['district_id'].
Replace
'url' => CController::createUrl('districts'),
By
'url' => $this::createUrl('candidate/districts'),
Related
I have translates table with example data:
So, this table holds records, which will represent custom translation texts.
Now i want to build a form to edit all of those rows in one page / form.
This is controlle code:
public function translate() {
$this->loadModel('Translate');
$data = $this->Translate->find('all');
$this->set('data', $data);
pr ($this->request->data);
if ($this->request->is('post','put')) {
if ($this->Translate->save($this->request->data)) {
$this->Session->setFlash('Recipe Saved!');
return $this->redirect($this->referer());
}
}
}
And view - please note, that i have used loop for creating inputs, not sure if cakephp has better way to do this.
<?php echo $this->Form->create('Translate'); ?>
<?php
foreach ($data as $d) {
echo $this->Form->input('text', array('label' => 'Link strony', 'type' => 'text','value'=>$d['Translate']['text']));
echo $this->Form->input('id', array('type' => 'hidden', 'value' => $d['Translate']['id']));
}
?>
<?php echo $this->Form->end(array('class' => 'btn btn-success floatRight', 'label' => 'Zapisz')); ?>
For now, this code works, but not as i expect. $this->request->data shows only last input, ignoring other ones. Attached, you see debug of $this->request->data. Only last item is edited. All i want is to have ability to edit selected input and save. Thanks for help.
Looks like you're saving multiple rows in a single form. In that case,
you need to change your approach a bit.
Use proper indices in the Form helper.
Use saveAll() instead of save() to save multiple data.
Changes to the View file:
<?php
foreach ($data as $k => $d) {
echo $this->Form->input('Translate.'.$k.'.text', array(
'label' => 'Link strony',
'type' => 'text',
'value' =>$d['Translate']['text']
));
echo $this->Form->input('Translate.'.$k.'.id', array(
'type' => 'hidden',
'value' => $d['Translate']['id']
));
}
?>
And then, in your controller:
if ($this->request->is('post','put')) {
$this->Translate->saveAll($this->request->data['Translate']);
/* Other code */
}
Try to specify the name as array (translate[]) :
echo $this->Form->input('text', array('label' => 'Link strony', 'type' => 'text','value'=>$d['Translate']['text'],'name'=>'translate[]'));
I am using cakephp 3.3
I have in the controller
$employee = TableRegistry::get('employees');
$allNames = $employee->find('list', array('employee_name' => array('employee_name') ) );
$allNames = $allNames->toArray();
$this->set('name', $allNames);
and in my template
<?= $this->Form->input('employee', array('type'=>'select','label' => false,
'options' => $name,'value'=>$name));?>
The only thing being retrieved and displayed is the number of entries i have in the database, $name only contains an array(1,2,3,4) when it should be actual people names.
Did you read the documentation about how find('list') works?'
$allNames = $employee->find('list', [
'keyField' => 'employee_name'
'valueField' => 'employee_name'
]);
$this->set('name', $allNames);
<?= $this->Form->input('employee', ['type'=>'select','label' => false,
'options' => $name]);?>
You can map id and value by keyField and valueField in list query
in your controller
$employee = TableRegistry::get('employees');
$allNames = $employee->find('list', array('valueField' =>employee_name','keyField'=>'employee_id' )); // correct employee_id with your table id field.
$this->set('name', $allNames);
In your View
<?= $this->Form->input('employee', array('type'=>'select','label' => false,
'options' => $name));?>
How can i get categories names to the select list not their ID's !! , I'm using CakePHP
the 'categories' table has only two columns (id, name)
the view part :
echo $this->Form->input('category',array(
'type' => 'select',
'options' => $categories,
'empty' => 'select category'
));
the association :
class Job extends AppModel{
public $name = 'Job';
public $belongsTo = array('Category');
}
and the controller :
$categories= $this->Job->Category->find('list');
$this->set('categories',$categories);
the result is a select list with 1,2,3,4,5,6 values
You needs to edit your controller code as following :
$categories= $this->Job->Category->find('list',array('fields'=>array('Category.id','Category.name')));
you need to use virtual field in cakephp.
http://book.cakephp.org/2.0/en/models/virtual-fields.html
also Line main in ctp file
foreach($times as $key => $value ){ $timesList[$value] = $value; } $times = $timesList
use as per your model-controller. for mor info. plz follow this link .here i face same problem and i got solution.
virtual field are not working in cakephp
In cakephp 3.X
// Common Usage:
$users = [
['id' => 1, 'name' => 'mark'],
['id' => 2, 'name' => 'jane'],
['id' => 3, 'name' => 'sally'],
['id' => 4, 'name' => 'jose'],
];
$results = Hash::extract($users, '{n}.id');
// $results equals:
// [1,2,3,4];
https://book.cakephp.org/3.0/en/core-libraries/hash.html
I have a CakePHP controller like this:
$this->loadModel('Project');
$list2 = $this->Project->find( 'list', array(
'fields' => array('Project.project'),
'conditions' => array('Project.user_id' => $userId)
));
$this->set($list2, 'list2');
$this->loadModel('Distance');
if(!empty($this->request->data)){
$this->Distance->create();
if ($this->Distance->save($this->request->data)) {
$this->Session->setFlash('Saved.');
// $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('FAILED');
}
}else{
// $this->Session->setFlash('test');
}
and a view like this:
echo $this->Form->input('Distance.project', array('options' => $list2, 'label' => false, 'empty' => '(choose one)' ;
But I get inserted to the database the id of the project instead of the project name.
I never have such problems working with the fields - just with a list of data.
Any idea why it happens?
It's normal ... The $list2 it's and array ... and the values of the options are the indexes from that array.
If you want to insert only the project name you need to change $list2 with $list2['project_name']. You need to remove or replace the indexes of $list2.
LE: take iexiak example. He change also the code for you.
$list2 = $this->Project->find( 'list', array(
'fields' => array('Project.project'),
'conditions' => array('Project.user_id' => $userId)
)
);
This is because $list2 automatically creates a list of ID => project; and when you use that as input for your form it automatically creates the drop down to reflect this. This is generally the best practice, to link to ID's instead of to descriptions, as ID's do not change as often. The below should get you exactly what you want though:
$list2 = $this->Project->find( 'list', array(
'fields' => array('Project.project','Project.project'),
'conditions' => array('Project.user_id' => $userId)
)
);
So we have a variety of search pages each with different search criteria, so I decided to write a component which will get parameters passed to it from the controller, collect the neccesary data and return an array which I could then set to be used within my view file to populate drop down boxes to filter the criteria.
I have managed to get everything write up to where I must use the cakePHP helper to build a dynamical select box. I am convinced that I am doing something wrong and if there is an easier way to do this and still keep it somewhat dynamic please assist where you can:
// COMPONENT METHOD:
public function filterQueries($parameters) {
// Get defaults from the user:
$criteria = $parameters["custom"];
$defaults = $parameters["defaults"];
// Validate the defaults the user may want and assign them to the return array:
if($defaults != "false") {
foreach($defaults as $key => $value) {
if(array_key_exists($value, $this->defaults)) {
$this->returnArray["defaults"][$value] = $this->defaults[$value];
}
}
}
// Get all data for the custom requested form fields:
if($criteria != false) {
foreach($criteria as $model => $arguments) {
$fields = $arguments["fields"];
$conditions = $arguments["conditions"];
$recursive = $arguments["recursive"];
if(!in_array($model,$this->uses)) {
$useModel = ClassRegistry::init($model);
} else {
$useModel = $this->$$model;
}
$array = $useModel->find("all",array("conditions" => $conditions, "fields" => $fields, "recursive" => $recursive));
$this->returnArray["custom"][$model] = $array;
}
}
return $this->returnArray;
}
The above function will get an array which breaks down either custom searches or defaults (not included above but it all works, it returns the array exactly as I would have expected it.
// The code within my action to get the content from above:
// Load the Filters component to search data:
$search = $this->Components->load("Filter");
// Tell search what you want:
$searchBoxes = array(
"defaults" => array("statuses", "survey_type"),
"custom" => array(
"User" => array(
"fields" => array("User.id","User.first_name", "User.last_name"),
"conditions" => array("User.user_group_id" => "4f847c63-1840-446e-88be-3e4d29566cf0"),
"recursive" => -1
)
)
);
$filterResults = $search->filterQueries($searchBoxes);
$this->set("filters",$filterResults);
So now I get this multi-associative array within my view file (all still fine), but I want to now build example a drop down list of the users based on the array created above, but the outcome is nothing like what I expected:
echo $this->Form->input('user_id',
array(
"type" => "select",
"options" => $filters["custom"]["User"]
)
);
The HTML output is broken and displays it like this:
<option value="last_name">Doe</option>
<option value="first_name">Jihn</option>
<optgroup label="User"> </optgroup>
<optgroup label="1"> </optgroup>
<option value="last_name">Marilyn</option>
<option value="first_name">Monroe</option>
I acknowledge that I do not have a lot of cake experience but cannot understand how to just get the results to :
<option value='USERID'>NAME</option> // Yes I know the names and surnames must be concatinated still
Any advise help or guidance on how to do it, and do it the right way, would greatly be appreciated :)
VARDUMP ON $filters['custom']['users']
array
0 =>
array
'User' =>
array
'id' => string '4f84840e-cda8-4704-8fdf-210729566cf0' (length=36)
'first_name' => string 'Name' (length=4)
'last_name' => string 'Surname' (length=11)
1 =>
array
'User' =>
array
'id' => string '4f8488cb-53e0-4f72-af73-3de229566cf0' (length=36)
'first_name' => string 'Name' (length=6)
'last_name' => string 'Surname' (length=6)
You can enhance your output by doing as follows:
1) for combining two fields of a table, you can use "virtualfields" in the model, as follows: For example if you have the user model, you can define as follows:
public $virtualFields = array(
'full_name' => 'CONCAT(first_name, " ",last_name)'
);
So now the "full_name" field will be got whenever you call the find method of the User model.
2) For getting the data from the table for a select box, you can use the find('list') method. For example for the User model if you need the id,full_name (last and first name combined using the virtual fields) of the table,it can be done as follows :
$this->User->find('list',array('fields'=>array('id','full_name'),'conditions'=>$conditions))
I hope this helps..
Well I guess what you want to do is actually create another array with formatted options.
foreach ($filters["custom"]["User"] as $arr)
{
$options[$arr['id']] = $arr['first_name'] . ' ' . $arr['last_name'];
}
then
echo $this->Form->select('user_id', $options);
I think you need something like this:
$result = Set::combine($filters["custom"]["User"],
'{n}.User.id', // this is the value of select box
array(
'{0} {1}',
'{n}.User.first_name',
'{n}.User.last_name'
) // this is the text of select box
);
pr($result);
$this->form->input('inputname', array('label' => false, 'options' => array('Select optionstype','a','b'), 'class'=>array('form-a', 'b'), 'id' => 'bacid', 'style' => 'width:280px;','value'=>$abc['model']['array_attribute']));
On cakePHP 3, I can't use "virtualFields" yet, but I can use as follows:
//In PostsController
$users = $this->Posts->Users->find('list',
['keyField' => 'id',
'valueField' => 'full_name', //Don't forget to call concatened field here
'conditions' => $conditions,
'order' => $orderBy
]);
//here the magic happens
$concat = $users->func()->concat(
['Users.first_name' => 'identifier',
' ',
'Users.last_name' => 'identifier'
]);
//selecting fields
$users->select(['id', 'full_name' => $concat]);
//sending to view
$this->set('users', $users->toArray());
I hope this helps CakePHP 3 developers