Fatch value in Dependent dropdown in Yii2 - drop-down-menu

I created a Dependent drop-down now i want to fetch these values on update page. How can i do ?
I created 2 drop-down - 1st Client and 2nd Staff
on update page i got the value of client but i did not get the value of staff (Because it is dependent drop-down)
Form
<?php
//First drop-down
echo $form->field($model, 'client')->dropDownList($Client,
['prompt'=>'-Select Client-',
'onchange'=>'
$.post
(
"'.urldecode(
Yii::$app->urlManager->createUrl
('leads/lists&id=')).'"+$(this).val(), function( data )
{
$( "select#staff_id" ).html( data );
});
']); ?>
// depend dropdown
<?php echo $form->field($model, 'staff')
->dropDownList
(
['prompt'=>'-Choose a Sub Category-'],
['id'=>'staff_id','value'=>$Staff]
);
?>
Controller
public function actionLists($id)
{
$sql = "select * from staff where client='$id' ";
//exit;
$models = Staff::findBySql($sql)->asArray()->all();
//echo "<pre>";print_r($model);exit;
if(sizeof($models) >0){
echo "<option>-Choose a Sub Category-</option>";
foreach($models as $model){
echo "<option value='".$model['id']."'>".$model['fname']."</option>";
}
}
else{
echo "<option>-Choose a Sub Category-</option><option></option>";
}
}

first add $modelsStaff variable to your create and update actions like below:
<?
public function actionCreate()
{
$modelsStaff=null;
$model = new model();
if ($model->load(Yii::$app->request->post()) && $model->save())
{
return $this->redirect(['view', 'id' => $model->id]);
}
else
{
return $this->render('create', [ 'model' => $model,'modelsStaff'=>$modelsStaff]);
}
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save())
{
return $this->redirect(['view', 'id' => $model->id]);
}
else
{
$sql = "select * from staff where client='$model->client'";
$modelsStaff = Staff::findBySql($sql)->asArray()->all();
return $this->render('update', [ 'model' => $model,'modelsStaff'=>$modelsStaff]);
}
}
?>
In your update action find all staff using $model->client and get all staff under this client and update your view like this
<?php
//First drop-down
echo $form->field($model, 'client')->dropDownList($Client,
['prompt'=>'-Select Client-',
'onchange'=>'
$.post
(
"'.urldecode(
Yii::$app->urlManager->createUrl
('leads/lists?id=')).'"+$(this).val(), function( data ) //<---
{
$( "select#staff_id" ).html( data );
});
']); ?>
// depend dropdown
<?php echo $form->field($model, 'staff')->dropDownList
($modelsStaff,
['prompt'=>'-Choose a Sub Category-'],
['id'=>'staff_id','value'=>$Staff]
);
?>

You have to create separate function in your controller (like an example):
public function actionLists($id)
{
$posts = \common\models\Post::find()
->where(['category_id' => $id])
->orderBy('id DESC')
->all();
if (!empty($posts)) {
$option = '<option>-Select Option-</option>';
foreach($posts as $post) {
$options .= "<option value='".$post->id."'>".$post->title."</option>";
}
return $options;
} else {
return "<option>-</option>";
}
}
and in view file (example):
use yii\helpers\ArrayHelper;
$dataCategory=ArrayHelper::map(\common\models\Category::find()->asArray()->all(), 'id', 'name');
echo $form->field($model, 'category_id')->dropDownList($dataCategory,
['prompt'=>'-Choose a Category-',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('post/lists?id=').'"+$(this).val(), function( data ) {
$( "select#title" ).html( data );
});
']);
$dataPost=ArrayHelper::map(\common\models\Post::find()->asArray()->all(), 'id', 'title');
echo $form->field($model, 'title')
->dropDownList(
$dataPost,
['id'=>'title']
);
This is from Yii docs: https://www.yiiframework.com/wiki/723/creating-a-dependent-dropdown-from-scratch-in-yii2

Related

Yii2 Dependant drop down not working when we open update page

Yii2 Dependant drop down not working when we open update page.My depend drop down value came from database. When I create entry It works Very well with the condition. but I when go for Update then Pre selectect value does not show. i.e. Which I save while creating. This is my _form.php
$arrCountry = \yii\helpers\ArrayHelper::map($modelCountry, 'country_id', 'country');
echo $form->field($model, 'country_id')->dropDownList($arrCountry,
['prompt'=>'-Choose a country-',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('country/lists?id=').'"+$(this).val(), function( data ) {
$( "select#city_name" ).html( data );
});
']);
$dataPost=\yii\helpers\ArrayHelper::map(City::find()->asArray()->all(), 'city_id', 'city_name');
// print_r($dataPost);die;
echo $form->field($model, 'city_id')
->dropDownList(
$dataPost,
['id'=>'city_name']
);
2.Controller
public function actionLists($id)
{
$countCity =City::find()
->where(['city_id' => $id,'status'=>'not assign'])
->count();
$arrCity = City::find()
->where(['city_id' => $id,'status'=>'not assign'])
->orderBy('city_id DESC')
->all();
if($countCity>0){
foreach($arrCity as $arrCity){
echo "<option value='".$arrCity->city_id."'>".$arrCity->city_name."</option>";
}
}
else{
echo "<option>-</option>";
}
}

CakePHP 3.1 : My validation for translate behaviour fields, need some help in review/comment

I have worked on a hook for validate my translated fields, based on this thread : https://stackoverflow.com/a/33070156/4617689. That i've done do the trick, but i'm looking for you guys to help me to improve my code, so feel free to comment and modify
class ContentbuildersTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Tree');
$this->addBehavior('Timestamp');
$this->addBehavior('Translate', [
'fields' => [
'slug'
]
]);
}
public function validationDefault(Validator $validator)
{
$data = null; // Contain our first $context validator
$validator
->requirePresence('label')
->notEmpty('label', null, function($context) use (&$data) {
$data = $context; // Update the $data with current $context
return true;
})
->requirePresence('type_id')
->notEmpty('type_id')
->requirePresence('is_activated')
->notEmpty('is_activated');
$translationValidator = new Validator();
$translationValidator
->requirePresence('slug')
->notEmpty('slug', null, function($context) use (&$data) {
if (isset($data['data']['type_id']) && !empty($data['data']['type_id'])) {
if ($data['data']['type_id'] != Type::TYPE_HOMEPAGE) {
return true;
}
return false;
}
return true;
});
$validator
->addNestedMany('translations', $translationValidator);
return $validator;
}
}
I'm not proud of my trick with the $data, but i've not found a method to get the data of the validator into my nestedValidator...
Important part here is to note that i only rule of my nestedValidator on 'translations', this is very important !
class Contentbuilder extends Entity
{
use TranslateTrait;
}
Here basic for I18ns to work
class BetterFormHelper extends Helper\FormHelper
{
public function input($fieldName, array $options = [])
{
$context = $this->_getContext();
$explodedFieldName = explode('.', $fieldName);
$errors = $context->entity()->errors($explodedFieldName[0]);
if (is_array($errors) && !empty($errors) && empty($this->error($fieldName))) {
if (isset($errors[$explodedFieldName[1]][$explodedFieldName[2]])) {
$error = array_values($errors[$explodedFieldName[1]][$explodedFieldName[2]])[0];
$options['templates']['inputContainer'] = '<div class="input {{type}} required error">{{content}} <div class="error-message">' . $error . '</div></div>';
}
}
return parent::input($fieldName, $options);
}
}
With that formHelper we gonna get the errors of nestedValidation and inject them into the input, i'm not confortable with the templates, so that's why it's very ugly.
<?= $this->Form->create($entity, ['novalidate', 'data-load-in' => '#right-container']) ?>
<div class="tabs">
<?= $this->Form->input('label') ?>
<?= $this->Form->input('type_id', ['empty' => '---']) ?>
<?= $this->Form->input('is_activated', ['required' => true]) ?>
<?= $this->Form->input('translations.fr_FR.slug') ?>
<?= $this->Form->input('_translations.en_US.slug') ?>
</div>
<?php
echo $this->Form->submit(__("Save"));
echo $this->Form->end();
?>
Here my fr_FR.slug is required when type_id is not set to Type::TYPE_HOMEPAGE, yeah my homepage has not slug, note that the en_US.slug is not required at all, because i only required 'translations.xx_XX.xxxx' and not '_translations.xx_XX.xxxx'.
And the last part of the code, the controller
$entity = $this->Contentbuilders->patchEntity($entity, $this->request->data);
// We get the locales
$I18ns = TableRegistry::get('I18ns');
$langs = $I18ns->find('list', [
'keyField' => 'id',
'valueField' => 'locale'
])->toArray();
// Merging translations
if (isset($entity->translations)) {
$entity->_translations = array_merge($entity->_translations, $entity->translations);
unset($entity->translations);
}
foreach ($entity->_translations as $lang => $data) {
if (in_array($lang, $langs)) {
$entity->translation($lang)->set($data, ['guard' => false]);
}
}
Here a .gif of the final result om my side : http://i.giphy.com/3o85xyrLOTd7q0YVck.gif

save image with cakephp3

I want to save the image path through a form, but the path of the image is not saved.
i've tried with this but i don't know where to put the code
MultimediaController:
public function add()
{
$multimedia = $this->Multimedia->newEntity();
if ($this->request->is('post')) {
$multimedia = $this->Multimedia->patchEntity($multimedia, $this->request->data);
$file = $_FILES['url'];
$path = 'files/' .$_FILES['url']['name'];
move_uploaded_file($this->data['url']['tmp_name'], $path);
if ($this->Multimedia->save($multimedia)) {
$this->Flash->success('The multimedia has been saved.');
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error('The multimedia could not be saved. Please, try again.');
}
}
$categories = $this->Multimedia->Categories->find('list', ['limit' => 200]);
$this->set(compact('multimedia', 'categories'));
$this->set('_serialize', ['multimedia']);
}
add.ctp
<?= $this->Form->create($multimedia, array('enctype' => 'multipart/form-data')); ?>
<fieldset>
<legend><?= __('Add Multimedia') ?></legend>
<?php
echo $this->Form->input('title');
echo $this->Form->input('description');
echo $this->Form->input('mime_type');
echo $this->Form->input('filename');
echo $this->Form->input('url', array('type' => 'file'));
echo $this->Form->input('category_id', ['options' => $categories]);
echo $this->Form->input('created_by');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
I'm new to cakephp 3 and am a bit lost. Please help.
Update:
already achieved to save the image:
$file = $_FILES['url'];
$path = "webroot\\files\\" .$_FILES['url']['name'];
print_r($file);
move_uploaded_file($_FILES['url']['tmp_name'], $path);
if ($this->Multimedia->save($multimedia)) {
$this->Flash->success('The multimedia has been saved.');
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error('The multimedia could not be saved. Please, try again.');
}
But now the "url" is not saved in the database
I hope this help you, the script here has some improvements like using the short deceleration for arrays:
The Controller code:
//don't forget to import the Folder class
use Cake\Filesystem\Folder;
public function add()
{
$multimedia = $this->Multimedia->newEntity();
if ($this->request->is('post')) {
$multimedia = $this->Multimedia->patchEntity($multimedia, $this->request->data);
//upload script start here
$mm_dir = new Folder(WWW_ROOT . 'upload_dir', true, 0755);
$target_path = $mm_dir->pwd() . DS . $this->request->data('url.name');
move_uploaded_file($this->request->data('url.tmp_name'), $target_path);
//save the file name in the field 'url'
$multimedia->url= $this->request->data('url.name');
//the script ends here
if ($this->Multimedia->save($multimedia)) {
// ............
} else {
// .........
}
}
// ..........
}
add.ctp // improvement
<?= $this->Form->create($multimedia, ['type' => 'file']); ?>
echo $this->Form->input('url', ['type' => 'file']);

Codeigniter dropdown only retrieve last data from db

I use CI form with form_dropdown helper and tried to pull Mysql data into its options, from the below code, its only retrieve the last record from db into the option list?
please advise what is wrong with my code?
Model
public function getStates() {
$query = $this->db->get('states');
$return = array();
if($query->num_rows() > 0){
$return[''] = 'please select';
foreach($query->result_array() as $row){
$return[$row['state_id']] = $row['state_name'];
}
}
return $return;
}
Controller
$this->load->model('db_model');
$data['options'] = $this->db_model->getStates();
$this->load->view('create_new', $data);
View
$state = array(
'name' => 'state',
'id' => 'state',
//'value' => set_value('state', $state)
);
<?php echo form_label('State', $state['id']); ?>
<?php echo form_dropdown($state['name'], $options); ?>
<?php echo form_error($state['name']); ?>
<?php echo isset($errors[$state['name']])?$errors[$state['name']]:''; ?>
send full query result from the model to the view like this
Model
public function getStates() {
$query = $this->db->get('states');
return $query->result();
}
let the controller as it is and now you can populate states in dropdown like this:
View
<?php
foreach($options as $opt){
$options[$opt->state_id]=$opt->state_name;
}
echo form_dropdown($state['name'], $options);
?>
Try this:
function getStates() {
$return = array();
$query = $this->db->get('states')->result_array();
if( is_array( $query ) && count( $query ) > 0 ){
$return[''] = 'please select';
foreach($query as $row){
$return[$row['state_id']] = $row['state_name'];
}
}
return $return;
}

codeigniter views with dynamic parameters

I have a edit view whose url is /group/edit/1 where 1 is the group id which is dynamic.
I am validating the form data in controller as :
if ($this->form_validation->run() == FALSE)
{
$this->load->view('group/edit', $data);
}
How do I pass the id parameter "1" to this view ?
Below option does not work since the url has to be group/edit/1
$this->load->view('edit', $data);
You're thinking about this wrong. You want to have a view called edit.php and pass the number 1 into it, or perhaps more to the point, you want to get the data for 1 from your model and pass the return value of your model into your view. Consider this:
controller
function edit($id)
{
$data['item_info'] = $this->whateverModel->getItem($id);
$this->load->view('edit', $data);
}
Then in your edit view, you can refer to the data like this:
view
echo $item_info['id'];
echo $item_info['name']; //or whatever you pass back from the model
Is this what you mean?
$this->load->view('group/edit/'.$parameter, $data);
That would make it load your 1, as you are simply defining the path of the VIEW document
Per CodeIgniters reference this is the format:
$this->load->view('folder_name/file_name');
http://codeigniter.com/user_guide/general/views.html
Not sure if you are confused by routing vs views, here is a quick difference:
If you want http://www.example/group/edit/10
then you need a route setup, not a view.
If you want http://www.example/ and to display the contents from page main.php (in your views folder) then you do $this->load->view('main'); inside your primary controller.
This is what I am doing. Is this acceptable ?
Controller action :
function edit($id)
{
$group_q = $this->db->query("SELECT * FROM groups WHERE id = ?", array($id));
$group_data = $group_q->row();
/* Form fields */
$data['name'] = array(
'name' => 'name',
'id' => 'name',
'value' => $group_data->name,
);
$options = array("A", "B", "C", "D");
$data['group_parent'] = $options;
$data['group_parent_status'] = $group_data->parent_id;
$data['group_id'] = $id;
/* Form validations */
$this->form_validation->set_rules('name', 'Name', 'trim|required|min_length[2]');
if ($this->form_validation->run() == FALSE)
{
if ($this->input->post('submit', TRUE))
{
$data['name']['value'] = $this->input->post('name', TRUE);
$data['group_parent_status'] = $this->input->post('group_parent', TRUE);
}
$this->load->view('group/edit', $data);
}
else
{
$data_name = $this->input->post('name', TRUE);
$data_parent_id = $this->input->post('group_parent', TRUE);
$data_id = $id;
if ( ! $this->db->query("UPDATE groups SET name = ?, parent_id = ? WHERE id = ?", array($data_name, $data_parent_id, $data_id)))
{
$this->session->set_flashdata('error', "Error");
$this->load->view('group/edit', $data);
} else {
$this->session->set_flashdata('message', "Success");
redirect('account');
}
}
return;
}
View file :
<?php
echo form_open('group/edit/' . $group_id); /***** NOTE THIS STEP *****/
echo "<p>";
echo form_label('Name', 'name');
echo "<br />";
echo form_input($name);
echo "</p>";
echo "<p>";
echo form_label('Parentp', 'group_parent');
echo "<br />";
echo form_dropdown('group_parent', $group_parent_active);
echo "</p>";
echo form_hidden('group_id', $group_id);
echo form_submit('submit', 'Submit');
echo form_close();
?>

Resources