Hi all, I am trying make it possible for some model attributes to be edited in a normal view without requiring a reload or redirect to a form.
My problem is that everything seems to be working properly except that the ajaxSubmitButton doesn’t properly send anything through POST. If I have my form have validateOnChange=>true, then it does send POST properly for that. But all I get when submitting the form is an empty POST array. When I look at the generated HTML the form seems to be in order as if it should show normal behavior. Does anyone have an idea as to why this is occurring?
To do this, I’ve constructed a small widget for which the run() is:
public function run()
{
// Too many boolean flags
if( $this->bForeignKey && $this->bLookup )
{
echo 'Error: Value marked as both foreign key and lookup value.';
return;
}
$sHtml = '';
$sAttr = $this->sAttrName;
$arModel = $this->arModel;
$sHtml .= CHtml::openTag( 'div', array( 'class'=>'ajaxUpdater' ) );
$sHtml .= CHtml::openTag( 'span', array( 'class'=>'ajaxUpdaterAttr', 'id'=>'ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttr.'_content', ) );
// Attribute display / first span content
...
// The code I replaced with '...' basically just looks what kind of attribute
// I'm working with and formats/displays it properly; not really relevant to
// my problem.
$sHtml .= CHtml::closeTag( 'span' );
$sHtml .= CHtml::openTag( 'span', array( 'class'=>'ajaxUpdaterLink' ) );
// Link display / second span content
$sHtml .= CHtml::ajaxLink( 'Edit',
CController::createUrl( '/ajaxUpdater/edit',
array(
'iId' => $arModel->id,
'sClassName' => get_class( $arModel ),
'sAttrName' => $sAttr,
'sAttrType' => $this->sAttrType,
'bLookup' => $this->bLookup,
'sLookupType' => $this->sLookupType,
'iFieldType' => $this->iFieldType,
'bForeignKey' => $this->bForeignKey,
'sForeignClass' => $this->sForeignClass,
'sForeignAttrName' => $this->sForeignAttrName,
)
),
array(
'onclick' => '$("#ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttr.'").dialog("open"); return false;',
'update' => '#ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttr,
),
array(
'id' => 'ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttr.'_link'
)
);
$sHtml .= CHtml::closeTag( 'span' );
$sHtml .= CHtml::openTag( 'div', array( 'id'=>'ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttr, 'style'=>'display: none;' ) );
$sHtml .= CHtml::closeTag( 'div' );
$sHtml .= CHtml::closeTag( 'div' );
echo $sHtml;
}
The ajaxLink works to call up the ajaxUpdater/edit action:
public function actionEdit()
{
if( isset( $_POST['iId'] ) && isset( $_POST['sClassName'] ) )
{
$arModel = $this->loadModel( $_POST['iId'], $_POST['sClassName'] );
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation( $arModel );
if( isset( $_POST[ $_POST['sClassName'] ] ) )
{
$arModel->attributes = $_POST[ $_POST['sClassName'] ];
if( $arModel->save(false) )
{
echo $this->sFormatModelAttr(); // Format and display the attribute appropriately
}
}
}
elseif( isset( $_GET['sAttrName'] ) )
{
$arModel = $this->loadModel();
$this->renderPartial( '_edit_dialog', array(
'arModel' => $arModel,
'sAttrName' => $_GET['sAttrName'],
'sAttrType' => $_GET['sAttrType'],
'bLookup' => $_GET['bLookup'],
'sLookupType' => $_GET['sLookupType'],
'iFieldType' => $_GET['iFieldType'],
'bForeignKey' => $_GET['bForeignKey'],
'sForeignClass' => $_GET['sForeignClass'],
'sForeignAttrName' => $_GET['sForeignAttrName'],
), false, true );
}
else
{
print_r($_POST);
print_r($_GET);
//echo 'fail';
}
}
and to display the views of/inside the CJuiDialog:
<?php
/**
* View rendered by EAjaxUpdater to form a modal popup
*
* Variables passed in by the controller:
* @var string sAttrName
* @var string sAttrType
* @var boolean bLookup
* @var string sLookupType
* @var int iFieldType
* @var boolean bForeignKey
* @var string sForeignClass
* @var string sForeignAttrName
*/
$this->beginWidget('zii.widgets.jui.CJuiDialog',array(
'id'=>'ajaxupdate_dialog',
'options'=>array(
'title'=>'Edit',
'autoOpen'=>true,
'modal'=>'true',
'width'=>'350',
'height'=>'350',
),
));
// render the form
$this->renderPartial('_dialog_form', array(
'arModel' => $arModel,
'sAttrName' => $sAttrName,
'sAttrType' => $sAttrType,
'bLookup' => $bLookup,
'sLookupType' => $sLookupType,
'iFieldType' => $iFieldType,
'bForeignKey' => $bForeignKey,
'sForeignClass' => $sForeignClass,
'sForeignAttrName' => $sForeignAttrName,
), false, true );
$this->endWidget();
?>
_dialog_form.php
<?php
/**
* View rendered by EAjaxUpdater inside of a modal popup
*
* Variables passed in by the controller:
* @var string sAttrName
* @var string sAttrType
* @var boolean bLookup
* @var string sLookupType
* @var int iFieldType
* @var boolean bForeignKey
* @var string sForeignClass
* @var string sForeignAttrName
*/
//Yii::app()->clientScript->scriptMap=array(
// //scripts that you don't need inside this view
// 'jquery.js'=>false,
// 'jquery.yiiactiveform.js'=>false,
// 'jquery-ui.min.js'=>false,
//);
?>
<div class="miniHeading"><h3>Edit</h3></div>
<div class="form">
<?php
$wForm = $this->beginWidget('CActiveForm', array(
'id'=>'ajaxupdate-form',
'enableAjaxValidation' => true,
'method'=>'post',
'action'=> CController::createUrl('ajaxupdater/edit'),
'clientOptions'=>array(
'validateOnSubmit'=>true,
'validateOnChange'=>false,
),
));
?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $wForm->errorSummary($arModel); ?>
<?php
$sFormHtml = CHtml::tag( 'div', array( 'class'=>'row', ) );
$sFormHtml .= $wForm->labelEx( $arModel, $sAttrName );
switch( $iFieldType )
{
case EAjaxUpdater::FIELDTYPE_TEXTFIELD:
$sFormHtml .= $wForm->textField( $arModel, $sAttrName );
break;
case EAjaxUpdater::FIELDTYPE_DROPDOWN:
if( $bLookup )
{
$aLookupItems = CHtml::listData( Lookup::model()->findAll(array(
'condition' => 'type=:type',
'params' => array(':type' => $sLookupType ),
'order' => 'position',
)), 'code', 'name' );
$sFormHtml .= $wForm->dropDownList( $arModel, $sAttrName, $aLookupItems );
}
elseif( $bForeignKey )
{
$aForeignItems = CHtml::listData( eval( $sForeignClass."::model()->findAll(array(
'condition' => '',
'params' => array(),
'order' => '".$sForeignAttrName."',
)), 'id', '".$sForeignAttrName."' );" ));
$sFormHtml .= $wForm->dropDownList( $arModel, $sAttrName, $aForeignItems );
}
break;
case EAjaxUpdater::FIELDTYPE_CHECKBOX:
$sFormHtml .= $wForm->checkBox( $arModel, $sAttrName );
break;
case EAjaxUpdater::FIELDTYPE_MULTISELECT:
if( $bLookup )
{
$aLookupItems = CHtml::listData( Lookup::model()->findAll(array(
'condition' => 'type=:type',
'params' => array(':type' => $sLookupType ),
'order' => 'position',
)), 'code', 'name' );
$sFormHtml .= $wForm->listBox( $arModel, $sAttrName, $aLookupItems );
}
elseif( $bForeignKey )
{
$aForeignItems = CHtml::listData( eval( $sForeignClass."::model()->findAll(array(
'condition' => '',
'params' => array(),
'order' => '".$sForeignAttrName."',
)), 'id', '".$sForeignAttrName."' );" ));
$sFormHtml .= $wForm->listBox( $arModel, $sAttrName, $aForeignItems );
}
break;
case EAjaxUpdater::FIELDTYPE_TEXTAREA:
$sFormHtml .= $wForm->textArea( $arModel, $sAttrName );
break;
case EAjaxUpdater::FIELDTYPE_CHECKBOXLIST:
if( $bLookup )
{
$aLookupItems = CHtml::listData( Lookup::model()->findAll(array(
'condition' => 'type=:type',
'params' => array(':type' => $sLookupType ),
'order' => 'position',
)), 'code', 'name' );
$sFormHtml .= $wForm->checkBoxList( $arModel, $sAttrName, $aLookupItems );
}
elseif( $bForeignKey )
{
$aForeignItems = CHtml::listData( eval( $sForeignClass."::model()->findAll(array(
'condition' => '',
'params' => array(),
'order' => '".$sForeignAttrName."',
)), 'id', '".$sForeignAttrName."' );" ));
$sFormHtml .= $wForm->checkBoxList( $arModel, $sAttrName, $aForeignItems );
}
break;
default:
$sFormHtml .= '<br />Error: Bad field type given to EAjaxUpdater.<br />';
break;
}
$sFormHtml .= $wForm->error( $arModel, $sAttrName );
// Hidden vars
$sFormHtml .= CHtml::hiddenField( 'iId', $arModel->id );
$sFormHtml .= CHtml::hiddenField( 'sClassName', get_class($arModel) );
$sFormHtml .= CHtml::hiddenField( 'sAttrName', $sAttrName );
$sFormHtml .= CHtml::hiddenField( 'sAttrType', $sAttrType );
$sFormHtml .= CHtml::hiddenField( 'bLookup', $bLookup );
$sFormHtml .= CHtml::hiddenField( 'sLookupType', $sLookupType );
$sFormHtml .= CHtml::hiddenField( 'iFieldType', $iFieldType );
$sFormHtml .= CHtml::hiddenField( 'bForeignKey', $bForeignKey );
$sFormHtml .= CHtml::hiddenField( 'sForeignClass', $sForeignClass );
$sFormHtml .= CHtml::hiddenField( 'sForeignAttrName', $sForeignAttrName );
$sFormHtml .= CHtml::closeTag( 'div' );
echo $sFormHtml;
?>
<div class="row buttons">
<?php
echo CHtml::ajaxSubmitButton( 'Save', CHtml::normalizeUrl( array( 'ajaxupdater/edit',
//'iId'=>$arModel->id,
//'sAttrName' => $sAttrName,
//'sAttrType' => $sAttrType,
//'bLookup' => $bLookup,
//'sLookupType' => $sLookupType,
//'iFieldType' => $iFieldType,
//'bForeignKey' => $bForeignKey,
//'sForeignClass' => $sForeignClass,
//'sForeignAttrName' => $sForeignAttrName,
//'render'=>false
)),
array(
//'type'=>'POST',
'dataType'=>'html',
//'update'=>'#ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttrName.'_content',
'success'=>'function(html) {
$("#ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttrName.'_content").append(html);
$("#ajaxupdate_dialog").dialog("close");
$("#ajaxupdate-form").remove();
$(".ui-dialog").remove();
$("#ajaxupdate_dialog").remove();
}',
),
array('id'=>'closeItemDialog_'.rand(0,10000))
);
// echo CHtml::ajaxButton( "Save", CController::createUrl('ajaxupdater/edit'), $ajaxOptions = array(
// 'type' => 'POST',
// 'dataType' => 'text',
// 'success' =>
// 'function(html) {
// $("#ajaxupdate-form").remove();
// $(".ui-dialog").remove();
// $("#ajaxupdate_dialog").dialog("close");
// $("#ajaxupdate_dialog").remove();
// $("#ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttrName.'_content").append(html);
// }',
// ) );
?>
<?php /* echo CHtml::ajaxSubmitButton( 'Cancel', CHtml::normalizeUrl(array('#','render'=>false)),array(
//'update'=>'#content',
'success'=>'js: function(data) {
$("#ajaxupdate-form").remove();
$(".ui-dialog").remove();
$("#ajaxupdate_dialog").remove();
$("#ajaxupdate_dialog").dialog("close");
}'),array('id'=>'closeItemDialog_'.rand(0,10000))); */ ?>
<?php
// echo CHtml::submitButton( 'Save', array(
// 'submit' => CController::createUrl( 'ajaxupdater/edit' ),
// 'ajax' => array(
// 'dataType' => 'html',
// 'success' => 'function(html)
// {
// $("#ajaxupdate_dialog").dialog("close");
// $("#ajaxupdate-form").remove();
// $(".ui-dialog").remove();
// $("#ajaxupdate_dialog").remove();
// $("#ajaxupdate_'.get_class($arModel).'-'.$arModel->id.'-'.$sAttrName.'_content").append(html);
// }',
// ),
// ));
?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->