After an ajax request i got one array from my controller as response, how can I use this array values in my dropdown list?
Answer
in my view I have
echo CHtml::dropDownList('client_id', '',CHtml::listData($model,'client_id','client_name'), array(
'ajax'=> array(
'type'=>'POST',
'url'=>Yii::app()->baseUrl.'/index.php?r=page/dynamicDropdownList',
'update'=>'#program_id',
'empty'=>'-Select a Client-')));
// I need to populate the response array in this dropdownlist
echo CHtml::dropDownList('program_id','', CHtml::listData($result,'program_id', 'program_name'));
in my controller
public function actionDynamicDropdownList()
{
if($_POST['client_id'] > '0') {
$result = Yii::app()->db->createCommand()->select('program_id, program_name')->from('program')->where('client_id='.$_POST['client_id'].'')->order('program_name')->queryAll();
$this->render('admin', array(
'result' => $result,
));
}
}
Another Problem
Now I got everything working except the second drop downlist is also showing the values of 1st dropdown list with the result.
solution:- I have parse the response and show it in the dropdownlist
This is how your controller should look like:
public function actionIndex() {
$model = new SearchForm();
if ($_GET['SearchForm']) {
$model->attributes = $_GET['SearchForm'];
}
//here is where you put your criteria or query commands
if ($_GET['ajax']) {
$this->renderPartial('index', array(
'model' => $model,
));
} else {
$this->render('index', array(
'model' => $model,
));
}
}
You catch the data from ajax or GET and you do something with it, then you pas the data to the view;
And this should be what the vies contains:
<? echo $form->dropDownList($model, 'position_type', CHtml::listData(PositionType::model()->findAll(array('condition' => 'status=1')), 'id', 'name'), array('class' => 'postdropdown2', 'empty' => array(-1 => 'All'), 'onchange' => 'showDiv(this.value,1);')); ?>
You have to work with data received using ajax in the controller, as it is not visible in the view, if it was not passed using render or renderpartial
Related
New to yii2 and PHP, ran into a break here.
Based on this and this post, I tried recreating the AJAX call.
Right now, using the Kartik SwitchInput widget, I'm at least trying to get the value into the controller and then return it to another place on the index page.
Here's what's in the view
...
<?= GridView::widget([
'dataProvider' => $customers,
'columns' => [
...
[
'label' => 'Status',
'format' => 'raw',
'attribute' => 'status',
'value' => function($models){
return SwitchInput::widget([
'name' => $models->id,
'value' => $models->status,
'pluginEvents' => [
'switchChange.bootstrapSwitch' => 'function(e) {
$.ajax({
method: "POST",
url: "'.Url::to(['update-status']).'",
data: { "status": e.currentTarget.checked, "id": e.currentTarget.name },
error:function(res){
console.log(res.responseText);
}
})
console.log(`${e.currentTarget.checked} ${e.currentTarget.name}`);
}'
]
...
Here's the controller:
class CustomerController extends Controller{
public function actionIndex(){
$customers = new ActiveDataProvider([
'query' => Customer::find()
]);
$models = $customers->getModels();
return $this->render('index', [
'customers' => $customers,
'models' => $models
]);
}
public function actionUpdateStatus(){
$status = Yii::$app->request->post('status');
$id = Yii::$app->request->post('id');
return $this->renderPartial('index', [
'status' => $status,
'id' => $id
]);
}
}
Whenever I flip the switch, it returns a 500 Internal error. Console.logging it revealed: $customers is undefined.
From what I realised, whenever I make an actionUpdateStatus call, Yii re-renders the view completely anyway, and tries to find the $customers, which isn't in the UpdateStatus.
How do I return the switch data, separately, back into the same view, then?
I posted one of the answers you mentioned, and i havent specified one thing there which is reloading of the gridview which wasnt the requirement there, but can be done using $.pjax.
A few things you need to look at
You dont need any view for the updateStatus action as per your requirement.
You just need to return some status code to the ajax call that you are using inside the gridView for the switch input, and refresh your gridview to load the new updated status.
In ajax success callback function check if that status code is ok then you should refresh the gridview rather than using render partial.
And you are not updating anything in the updateStatus? you need to switch the status
So change your action to the following
public function actionUpdateStatus()
{
try {
$status = Yii::$app->request->post('status');
$id = Yii::$app->request->post('id');
$model = Customer::findOne($id);
$model->status=$status;
if(!$model->save()){
throw new Exception(implode("\n",\yii\helpers\ArrayHelper::getColumn($model->errors,'0'));
}
return $this->asJson(['success' => true]);
} catch (Exception $e) {
return $this->asJson(['success' => false, 'message' => $e->getMessage()]);
}
}
Make sure you have wrapped the GridView inside Pjax start and end and add an id to the Pjax widget
<?php
Pjax::begin(['id'=>'pjax-container']);
echo GridView::widget([
'dataProvider' => $customers,
'columns' => [
.......
]);
Pjax::end();
?>
And your ajax call to the following
'switchChange.bootstrapSwitch' => 'function(e) {
$.ajax({
method: "POST",
url: "'.Url::to(['update-status']).'",
dataType:'json',
data: { "status": e.currentTarget.checked, "id": e.currentTarget.name },
success:function(data){
if(data.success){
$.pjax({container: "#pjax-container"});
}else{
console.log(data.message);
}
},
error:function(res){
console.log(res.responseText);
}
});
}'
I have created a yii2 kartik select2 widget to select multiple car models like below
<?= Select2::widget([
'name' => 'drp-make',
'data' => Car::getCarMakesEnglish(),
'value' => explode(",",$model->drp_make),
'options' => [
'id'=>'drp-make',
'placeholder' => 'All Makes',
'multiple' => true
]
]); ?>
And the function to get data for the select2 like
public static function getCarMakesEnglish(){
$out=array();
$makes=CarMakes::find()->select(['id','make_eng'])->all();
foreach ($makes as $make) {
array_push($out,array($make['id'] => $make['make_eng']));
}
return $out;
}
Its working perfect.But a issue is there.please see the below picture
Its showing values too not only the names.I want to show only the make names.How to do that
Because you are pushing an array to every index of the $out
array_push($out,array($make['id'] => $make['make_eng']))
you should use yii\helpers\ArrayHelper::map() instead that do this for you. Change your function getCarMakesEnglish() to the following
public static function getCarMakesEnglish()
{
$makes = CarMakes::find()->select(['id', 'make_eng'])->all();
return \yii\helpers\ArrayHelper::map($makes,'id','make_eng');
}
In addition to #MuhammadOmerAslam answer, you can avoid ArrayHelper::map() for simple scenario by using column()
public static function getCarMakesEnglish()
{
return CarMakes::find()->select('make_eng')->indexBy('id')->column();
}
Wanting to add a custom Model to be rendered in a custom Magento admin form. Just cant seem to get the source model to render any of the options. Couldn't really find anything on google as it was mostly to do with system/config source model examples. See code below
Model File (My/Module/Model/MyModel.php)
<?php
class My_Module_Model_MyModel extends Mage_Core_Model_Abstract
{
static public function getOptionArray()
{
$allow = array(
array('value' => '1', 'label' => 'Enable'),
array('value' => '0', 'label' => 'Disable'),
);
return $allow;
}
}
and my form tab file - Tab shows up with multiselect field, but its blank (My/Module/Block/Adminhtml/Module/Edit/Tab/Data.php)
<?php
class My_Module_Block_Adminhtml_Module_Edit_Tab_Data extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm(){
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('module_form', array('legend'=>Mage::helper('module')->__('Module Information')));
$object = Mage::getModel('module/module')->load( $this->getRequest()->getParam('module_id') );
echo $object;
$fieldset->addField('module_enabled', 'multiselect', array(
'label' => Mage::helper('module')->__('Allowed Module'),
'class' => 'required-entry',
'required' => true,
'name' => 'module_enabled',
'source_model' => 'My_Module_Model_MyModel',
'after_element_html' => '<small>Select Enable to Allow</small>',
'tabindex' => 1
));
if ( Mage::getSingleton('adminhtml/session')->getModuleData() )
{
$form->setValues(Mage::getSingleton('adminhtml/session')->getModuleData());
Mage::getSingleton('adminhtml/session')->setModuleData(null);
} elseif ( Mage::registry('module_data') ) {
$form->setValues(Mage::registry('module_data')->getData());
}
return parent::_prepareForm();
}
}
So I have other fields, tabs that all save the data etc but just cant get the values to render using a custom model inside the multiselect field.
Looks like method name in the source model is incorrect. Also, you probably don't need to extend Mage_Core_Model_Abstract in source models.
Try this:
<?php
class My_Module_Model_MyModel
{
public function toOptionArray()
{
return array(
array('value' => '1', 'label' => Mage::helper('module')->__('Enable')),
array('value' => '0', 'label' => Mage::helper('module')->__('Disable')),
);
}
}
OP's solution migrated from the question to an answer:
updated the MyModel.php to get a foreach in a collection (CMS Pages
for example)
<?php
class My_Module_Model_MyModel
{
public function toOptionArray($withEmpty = false)
{
$options = array();
$cms_pages = Mage::getModel('cms/page')->getCollection();
foreach ($cms_pages as $value) {
$data = $value->getData();
$options[] = array(
'label' => ''.$data['title'].'('.$data['identifier'].')',
'value' => ''.$data['identifier'].''
);
}
if ($withEmpty) {
array_unshift($options, array('value'=>'', 'label'=>Mage::helper('module')->__('-- Please Select --')));
}
return $options;
}
and within My/Module/Block/Adminhtml/Module/Edit/Tab/Data.php I just
removed "source_model" and replaced it with
'values' => Mage::getModel('module/mymodel')->toOptionArray(),
Just to add, also had the issue of multiselect values not
saving/updating the multiselect field on refresh/save on the edit
page. To get this working, I edited the admin controller under the
saveAction (or the action name to save the form data). See below my
saveAction in the controller for the admin/backend located in
My/Module/controllers/Adminhtml/ModuleController.php
public function saveAction() {
$model = Mage::getModel('module/module');
if ($data = $this->getRequest()->getPost()) {
$model = Mage::getModel('module/module');
$model->setData($data)
->setModuleId($this->getRequest()->getParam('module_id'));
try {
if ($model->getCreatedTime() == NULL || $model->getUpdateTime() == NULL) {
$model->setCreatedTime(now())->setUpdateTime(now());
} else {
$model->setUpdateTime(now());
}
$ModuleEnabled = $this->getRequest()->getParam('module_enabled');
if (is_array($ModuleEnabled))
{
$ModuleEnabledSave = implode(',',$this->getRequest()->getParam('module_enabled'));
}
$model->setModuleEnabled($ModuleEnabledSave);
//save form data/values per field
$model->save();
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('module')->__('Item
was successfully saved'));
Mage::getSingleton('adminhtml/session')->setFormData(false);
if ($this->getRequest()->getParam('back')) {
$this->_redirect('*/*/edit', array('module_id' => $model->getModuleId()));
return;
}
$this->_redirect('*/*/');
return;
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
Mage::getSingleton('adminhtml/session')->setFormData($data);
$this->_redirect('*/*/edit', array('module_id' => $this->getRequest()->getParam('module_id')));
return;
}
}
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('module')->__('Unable
to find item to save'));
$this->_redirect('*/*/');
}
This saves an imploded array (ie 2, 3 ,6, 23, 28,) into the database
value and renders the selected multiselect fields on the corresponding
tab on refresh/update/save
how can I save value as ivar from dropDownlist in yii? here my code, which doesn't work :/
declaration of ivar:
public $blaaa;
and my dropdownlist code:
echo CHtml::dropDownList(
'categoryDropDownList',
'',
CHtml::listData(Category::model()->findAll(), 'id', 'name'),
array(
'empty' => 'Select Category',
'onchange'=>function () {
$this->blaaa = 'js:this.value';
}
));
I tried also with ajax, but it also doesnt work:
'ajax' => array(
'type' => 'POST',
'url' => CController::createUrl('category/actionBla'),
'data' => array('id' => 'js:this.value')
where
public function bla()
{
if (isset($_POST['id'])) {
$this->blaaa = $_POST['id'];
}
thanks in advance for help!
In ajax section, change url as below
'url' => CController::createUrl('category/bla'),
In controller, your function name should be
public function actionBla()
I solved my problem with echo'ing CHtml::dropDownList in form:
echo CHtml::form();
echo CHtml::dropDownList(
'categoryDropDownList',
'',
CHtml::listData(Category::model()->findAll(), 'id', 'name'),
array(
'empty' => 'Select Category'
));
echo CHtml::endForm();
and now activeForm bother about sending parameters via POST
I have two models "Ficha" and "Perigo":
class Ficha extends AppModel {
var $primaryKey = 'id_ficha';
public $validate = array(
'nome_produto' => array(
'rule' => 'notEmpty'
),
'versao' => array(
'rule' => 'notEmpty'
),
'data_ficha' => array(
'rule' => 'notEmpty'
)
);
}
class Perigo extends AppModel {
var $belongsTo = array(
'Ficha' => array(
'className' => 'Ficha',
'foreignKey' => 'id_fichas'
)
);
}
As you can see they are "linked". Now, in the code i have a form for Ficha that the method "add()" of FichasController redirects to my Perigo Model:
add() (of FichaController)
public function add() {
//pr($this->request->data); // to get the data from the form
if ($this->request->is('post')) {
$this->Ficha->create();
if ($this->Ficha->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
//$last_id=$this->Ficha->getLastInsertID();
//$this->redirect(array('action' => 'preencher_ficha'),$last_id);
$this->redirect(array('controller'=>'perigos', 'action' => 'add'),$last_id);
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}
The redirection is made to a form that exists in PerigosController.
add.ctp (of Perigo)
echo $this->Form->create('Perigo');
echo $this->Form->input('class_subst', array('label' => 'Classificação da substância ou mistura:'));
echo $this->Form->input('simbolos_perigo', array('label' => 'Símbolos de Perigo:'));
echo $this->Form->input('frases_r', array('label' => 'Frases R:'));
echo $this->Form->end('Avançar');
add() (of PerigoController)
public function add() {
if ($this->request->is('post')) {
$this->Perigo->create();
if ($this->Perigo->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('controller'=>'perigos', 'action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}
but there's something i don't know how to do it. Since the models are relational, and the same happens with the two tables on the database (the table perigos has a foreignkey that is the primary key of the table "fichas", how can i insert the data on table perigos in database? I mean, how can i get the key of the Ficha inserted in the first form and insert her in the foreign key of "perigos" when i submit this second form?
As #mark says, your redirection is bad, it should include the id in the URL array:
$this->redirect(array('controller'=>'perigos', 'action' => 'add', $last_id));
Like this you are passing the parameter by URL.
In the add action of your PerigosController you should have an $idFicha param at the method:
//PerigosController.php
public function add($idFicha){
//here you can use $idFicha
...
//when submiting the Perigos form, we add the foreign key.
if($this->request->is('post')){
//adding the foreign key to the Perigo's array to add in the DB.
$this->request->data['Perigo']['ficha_id'] = $idFicha;
if ($this->Ticket->save($this->request->data)) {
//...
}
}
}
Data submitted by POST method in a form will be always contained in an array of this type: $this->request->data['Model_name']. In your case:
$this->request->data['Perigo']
Another way to do this, is using sessions if you prefer to hide the id value:
http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#sessions