I am doing a yii web application
i have a drop down list that should be dependent on another , i use ajax however it doesnt work.
ive seen the yii tutorial for dependent drop downs and searched everywhere.
http://www.yiiframework.com/wiki/24
this is my main drop down list:
<div class="row">
<?php echo $form->labelEx($model, 'sourceID'); ?>
<?php
echo $form->dropDownList($model, 'sourceID', CHtml::listData(Sources::model()->findAll(), 'sourceID', 'name'), array('empty' => 'select source'), array(
'ajax' => array(
'type' => 'POST',
'url' => CController::createUrl('reservations/atest'),
'update' => '#meal'
)
)
);
?>
<?php echo $form->error($model, 'sourceID'); ?>
</div>
this is the dependent drop down list :
<div class="row">
<?php echo $form->labelEx($model, 'meal'); ?>
<?php echo $form->dropDownList($model, 'meal', array()); ?>
<?php echo $form->error($model, 'meal'); ?>
</div>
this is my controller action:
public function actionAtest() {
$data = Sources::model()->findAll();
$data = CHtml::listData($data, 'sourceID', 'name');
foreach ($data as $value => $name) {
echo CHtml::tag('option', array('value' => $value), CHtml::encode($name),true);
} }
also, i added the action to the access rules.
any help is appreciated ,
thank you in advance.
You placed the ajax option after the htmlOptions. Here is the modified code
<div class="row">
<?php echo $form->labelEx($model, 'sourceID'); ?>
<?php
echo $form->dropDownList($model, 'sourceID', CHtml::listData(Sources::model()->findAll(), 'sourceID', 'name'), array('empty' => 'select source','ajax' => array(
'type' => 'POST',
'url' => CController::createUrl('reservations/atest'),
'update' => '#meal'
)
)
);
?>
<?php echo $form->error($model, 'sourceID'); ?>
</div>
And instead of using forms dropdownlist use CHtml::dropDownList for the dependent drop-down.
echo CHtml::dropDownList('meal','', array());
You can also use CActiveForm::dropDownList but in that case you have to use CHtml::resolveNameId in the update option of ajax
Related
Hello I have dropdownlist dependant textfield. The value of the textfield should be updated via ajax request when dropdownlist is selected (I'm using Yii's CHTML textfield).
Here is my code :
view _form.php
<div class="row">
<?php echo $form->labelEx($model,'kode_rincian'); ?>
<?php
echo $form->dropDownList($model, 'kode_rincian', array(), array(
'empty'=>'--Pilih--',
'ajax' => array(
'type'=>'POST',
'url'=>CController::createUrl('OPS/calculateRealisasi'),
//'update'=>'#OPS_contrealisasi',
'dataType'=>'json',
'data'=>array(
'kode_program' => 'js:$(\'#OPS_kode_program option:selected\').val()',
'kode_kegiatan' => 'js:$(\'#OPS_kode_kegiatan option:selected\').val()',
'kode_output' => 'js:$(\'#OPS_kode_output option:selected\').val()',
'kode_komponen' => 'js:$(\'#OPS_kode_komponen option:selected\').val()',
'kode_akun' => 'js:$(\'#OPS_kode_akun option:selected\').val()',
'kode_rincian'=>'js:this.value',
),
'success'=>"function(data)
{
$('#OPS_realisasi_at').html(data.sumrealisasi);
$('#OPS_sisa_at').html(data.sumsisa);
} ",
)
));
?>
<?php echo $form->error($model,'kode_rincian'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'realisasi_at'); ?>
<?php
echo $form->textField($model,'realisasi_at');
?>
<?php echo $form->error($model,'realisasi_at'); ?>
</div class="row">
<?php echo $form->labelEx($model,'sisa_at'); ?>
<?php echo $form->textField($model,'sisa_at'); ?>
<?php echo $form->error($model,'sisa_at'); ?>
</div>
And controller OPSController.php:
public function actionCalculateRealisasi(){
$kode_rincian = $_POST["kode_rincian"];
$kode_program = $_POST["kode_program"];
$kode_kegiatan = $_POST["kode_kegiatan"];
$kode_komponen = $_POST["kode_komponen"];
$kode_akun = $_POST["kode_akun"];
$kode_output = $_POST["kode_output"];
$modelkode= KodePOK::model()->findByAttributes(array(
'kode_program'=>$kode_program,
'kode_komponen'=>$kode_komponen,
'kode_kegiatan'=>$kode_kegiatan,
'kode_akun'=>$kode_akun,
'kode_output'=>$kode_output,
'kode_rincian'=>$kode_rincian,
));
if($modelkode!=NULL){
$idpok=$modelkode->id_pok;
}
else{
$idpok=0;
}
$criteria = new CDbCriteria;
$criteria->select='SUM(jumlah_pengajuan) as realisasi';
$criteria->condition="id_pok='".$idpok."'";
$sum = OPS::model()->find($criteria);
$sumrealisasi=$sum->realisasi;
$sumrealisasi=(int)$sumrealisasi;
$calcsisa=POK::model()->findByPk($idpok);
$getjumlah=$calcsisa->jumlah_pagu;
$sumsisa=$getjumlah-$sumrealisasi;
echo CJSON::encode(array(
'sumrealisasi'=>$sumrealisasi,
'sumsisa'=>$sumsisa,
));
Yii::app()->end();
}
The code didn't show any error but the textfield wasn't updated. Please help me. Here is the result when I tried to inspect the page element :
I've solved the problem.
I changed
'success'=>"function(data)
{ $('#OPS_realisasi_at').html(data.sumrealisasi);
$('#OPS_sisa_at').html(data.sumsisa);
} ",
to :
'success'=>"function(data)
{ $('#OPS_realisasi_at').val(data.sumrealisasi);
$('#OPS_sisa_at').val(data.sumsisa);
} ",
I try load form via ajax in CJuiDialog. The form was success loaded but when I submitted form or write text, form not validate and not submit.I tried set "true" fourth parameter in renderPartialbut after then dialog window didn't open. In console, I got error
$(...).dialog is not a function
In view I have this:
Yii::app()->clientScript->registerScript(
"test",
"jQuery.ajax({
type: 'POST',
url: '".$this->createUrl("/Site/ShowForm")."',
success: function(html){
$('#form-test').html(html);
});
",
CClientScript::POS_READY); ?>
<div id="form-test"></div>
<?php $this->endWidget('zii.widgets.jui.CJuiDialog');
My actions in controller:
public function actionShowForm()
{
$model = new RegistrationForm;
if(Yii::app()->request->isAjaxRequest )
return $this->renderPartial('register', array('model' => $model),false,false);
}
public function actionRegister()
{
$model = new RegistrationForm;
$this->ajaxValidate($model);
$model->attributes =$_POST['RegistrationForm'];
if($model->validate())
{
$user = new User;
$user->attributes = $model->attributes;
if($user->save())
echo 1;
}
}
and my form (register.php)
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'register-form',
//'enableClientValidation'=>true,
'enableAjaxValidation' => true,
'clientOptions' => array(
//'validateOnSubmit' => true,
'validateOnChange' => true
),
'action' => array('site/Register'),
));
?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model, 'first_name'); ?>
<?php echo $form->textField($model, 'first_name'); ?>
<?php echo $form->error($model, 'first_name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model, 'last_name'); ?>
<?php echo $form->textField($model, 'last_name'); ?>
<?php echo $form->error($model, 'last_name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model, 'email'); ?>
<?php echo $form->emailField($model, 'email'); ?>
<?php echo $form->error($model, 'email'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model, 'password'); ?>
<?php echo $form->textField($model, 'password'); ?>
<?php echo $form->error($model, 'password'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model, 'Repeat password'); ?>
<?php echo $form->textField($model, 'repeat_password'); ?>
<?php echo $form->error($model, 'repeat_password'); ?>
</div>
<div>
<?php echo $form->textField($model, 'verifyCode'); ?>
<?php $this->widget('CCaptcha'); ?>
<?php echo $form->error($model, 'verifyCode'); ?>
</div>
<div class="row buttons">
<?php
echo CHtml::ajaxSubmitButton('Register', $this->createUrl("/Site/Register"), array(
'type' => 'POST',
'dataType' => 'json',
'success' => 'js:function(data){
if(data == 1){
window.location ="' . $this->createUrl('site/index') . '"
}
}',
));
?>
</div>
<?php $this->endWidget(); ?>
How Can I fix this problem?
In your controller, where you check if the request is Ajax, you should be doing the Ajax validation in there.
I found solution! I added
Yii::app()->clientScript->scriptMap = array(
'jquery.js' => false,
'jquery.ui.js' => false,
'jquery.yiiactiveform.js' => false,
);
in my actionShowForm.
I'm not sure how to describe my question. First I added a button at my CCGridview:
array(
'class'=>'CButtonColumn',
'template' => '{view}{update}{delete}{upload_image}',
'buttons' => array(
'upload_image' => array(
'label' => 'upload foto',
'url' => 'Yii::app()->createUrl("/image/create",
array("product_id" => $data->product_id))',
),
),
),
when I clicked it will bring me to the /image/create view which has a product_id value. For example on that gridview I clicked record number 7, so the url would be:
(webApp)/index.php/image/create?product_id=7
Since it rendering a partial _form so the form has the attribute according to the image table which has this attributes: id, title, filename, product_id.
So the view will be something like:
<div class="row">
<?php echo $form->labelEx($model,'title'); ?>
<?php echo $form->textField($model,'title',array('size'=>45,'maxlength'=>45)); ?>
<?php echo $form->error($model,'title'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'filename'); ?>
<?php echo $form->fileField($model,'filename',array('size'=>45,'maxlength'=>45)); ?>
<?php echo $form->error($model,'filename'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'product_id'); ?>
<?php echo $form->textField($model,'product_id'); ?>
<?php echo $form->error($model,'product_id'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
My question is, how do we use the value from the url which I mentioned before is 7 (../create?product_id=7) into the product_id attribute without have to type it at provided textField?
In other word I will remove this from the view:
<div class="row">
<?php echo $form->labelEx($model,'product_id'); ?>
<?php echo $form->textField($model,'product_id'); ?>
<?php echo $form->error($model,'product_id'); ?>
</div>
But when i submitted, the form the value (7) should have been passed/saved at product_id field.
Added:
My controller actionCreate is
//...
public function actionCreate()
{
$dir = Yii::app()->basePath . '/../productimages/';
$uploaded = false;
$model=new Image();
if(isset($_POST['Image']))
{
$model->attributes=$_POST['Image'];
$tempSave=CUploadedFile::getInstance($model,'filename');
if($model->validate())
{
$uploaded = $tempSave->saveAs($dir.'/'.$tempSave->getName());
$this->redirect(array('/products/index'));
}
}
$this->render('index', array(
'model' => $model,
'uploaded' => $uploaded,
'dir' => $dir,
));
}
That's it. Many thanks..
modify your controller this way:
if(isset($_POST['Image']))
{
$model->attributes=$_POST['Image'];
$tempSave=CUploadedFile::getInstance($model,'filename');
if($model->validate())
{
$uploaded = $tempSave->saveAs($dir.'/'.$tempSave->getName());
$this->redirect(array('/products/index'));
}
} else {
//initialize defaults
$model->product_id=intval($_GET['product_id']);
}
i am trying this sample about Creating a dependent dropdown i created form in provinceCity/_form and copy actionDynamiccities to ProvinceCityController.php but when i change dropDown list i have not any change ?
i think i must to enable ajax but i do not how i do it?
<?php echo CHtml::dropDownList('country_id','', array(1=>'USA',2=>'France',3=>'Japan'),
array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('ProvinceController/dynamiccities'), //url to call.
//Style: CController::createUrl('ProvinceCity/methodToCall')
'update'=>'#city_id', //selector to update
//'data'=>'js:javascript statement'
//leave out the data key to pass all form values through
)));
//empty since it will be filled by the other dropdown
echo CHtml::dropDownList('city_id','', array()); ?>
Here is what you will do in _form
<?php echo CHtml::dropDownList('country_id','', array(1=>'USA',2=>'France',3=>'Japan'),
array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('ProvinceController/dynamiccities'), //url to call.
'update'=>'#city_name', //selector to update
'data'=>array('country_id' => 'js:this.value'),
)));
?>
</div>
<div id=city_name>
<?php echo $form->dropDownList($model, 'city_id', array()); ?>
</div>
Hopefully, it would help you.
It should be,
<?php
$countryAry=array(1=>'USA',2=>'France',3=>'Japan');
echo CHtml::dropDownList('country_id','', $countryAry,
array
(
'ajax' => array
(
'type'=>'POST',
'url'=>CController::createUrl('Controller/action'),
'dataType'=>'JSON',
'success'=>'js:function(data)'
. '{'
. ' var opt="<option value=>-----Select city-----</option>";'
. ' $.each(data,function(i,obj)'
. ' {'
. ' opt+="<option value=\'"+obj.id+"\'>"+obj.name+"</option>";'
. ' });'
. ' $("#city_id").html(opt);'
. '}'
)
));
echo CHtml::dropDownList('city_id','', array());
?>
But, I suggest you to implement this task as showing bellow.
<?php
$countryAry=array(1=>'USA',2=>'France',3=>'Japan');
echo CHtml::dropDownList('country_id','', $countryAry,array('onchange'=>'js:getCities()'));
echo CHtml::dropDownList('city_id','', array());
?>
<script type="text/javascript">
function getCities()
{
$.ajax
({
type:'POST',
url:'Controller/action',
dataType:'JSON',
success:function(data)
{
var opt="<option value=>-----Select city-----</option>";
$.each(data,function(i,obj)
{
opt+="<option value='"+obj.id+"'>"+obj.name+"</option>";
});
$("#city_id").html(opt);
}
});
}
</script>
I found the solution here Dependent dropdown list in yii
<?php
$model=new ModelClass; // initilize it in controller
$form=$this->beginWidget('CActiveForm', array(
'id'=>'dependent-form',
'enableClientValidation'=>true,
'htmlOptions' => array('enctype' => 'multipart/form-data','autocomplete'=>'off'),
'clientOptions'=>array(
'validateOnSubmit'=>true,
)
));
?>
<div class="row">
<?php
echo $form->dropDownList($model,'country_id',
CHtml::listData(Countries::model()->findAll(), 'id', 'title'),
array(
'prompt'=>'Select Country',
'ajax' => array(
'type'=>'POST',
'url'=>Yii::app()->createUrl('YourController/loadstates'), // get states list
'update'=>'#ModelClass_state_id', // add the state dropdown id
'data'=>array('country_id'=>'js:this.value'),
)));
?>
</div>
<div class="row">
<?php
echo $form->dropDownList($model,'state_id',
array(),
array(
'prompt'=>'Select State',
'ajax' => array(
'type'=>'POST',
'url'=>Yii::app()->createUrl('YourController/loadcities'), // get states list
'update'=>'#ModelClass_city_id', // add the state dropdown id
'data'=>array('state_id'=>'js:this.value'),
)));
?>
</div>
<div class="row">
<?php
echo $form->dropDownList($model,'city_id',array(),array('empty'=>'-choose city-'));
?>
</div>
<?php echo CHtml::submitButton($model->isNewRecord ? 'Add' : 'Update',array('class'=>'btn btn-primary')); ?>
<?php $this->endWidget(); ?>
I have 2 templates,
- /view/opinions/add.ctp - add form
- /view/opinions/list.ctp - displays opinions
and I want them diplay in /views/opinions/index.ctp is it possible?
Is the only way to do it by $this -> element() ? if so, can I include templates from /view/opinions instead of /view/elements ?
#edit
OpinionsController.php
class OpinionsController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session');
var $name = 'Opinions';
function index() {
$opinions = $this->Opinion->find('all');
if(isset($this->params['requested'])) {
return $opinions;
}
$this->set('opinions', $opinions);
}
public function add() {
if ($this->request->is('post')) {
$this->Opinion->create();
if ($this->Opinion->save($this->request->data)) {
$this->Session->setFlash(__('saved.'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('Unable to add.'));
}
}
}
}
index.ctp
$this->extend('/Opinions/view');
$this->extend('/Opinions/add');
add.ctp
echo $this->Form->create('Opinion', array('type' => 'file'));
echo $this->Form->input('author_name', array('label' => 'Imię'));
echo $this->Form->input('author_signature', array('label' => 'Podpis'));
echo $this->Form->input('text', array('rows' => '5', 'cols' => '30', 'label' => 'Opinia'));
echo $this->Form->input('author_pic', array('type' => 'file', 'label' => 'Zdjęcie'));
echo $this->Form->input('author_pic_dir', array('type' => 'hidden'));
echo $this->Form->end('Dodaj opinię');
view.ctp
`
<?php foreach ($opinions as $opinion): ?>
<div class="opinion">
<div class="author">
<div class="pic"><?php echo $this->Html->image("defaultAvatar.jpg", array('alt' => $opinion['Opinion']['author_name'])); ?></div>
<div class="signature"><b><?= $opinion['Opinion']['author_name']?></b><br><i><?= $opinion['Opinion']['author_signature']?></i></div>
</div>
<div class="text">
<blockquote><p><?= $opinion['Opinion']['text']?></p></blockquote>
</div>
<div class="clear"><!-- . --></div>
</div>
<div class="clear"><!-- . --></div>
<?php endforeach; ?>
<?php unset($post); ?>
`
In web frameworks like CakePHP, we want to keep our code DRY. In order to do what you want, I think the better approach is to create elements to list your opinions and another with the form to add a new one.
Then in index.ctp you would put these two elements. And in add.ctp you put only the element with the form and in view.ctp you should put the element that list the opinions.