My front end is Php Yii. I am trying to create a custom validation rule which checks to see if the username already exists in the database.
I don't have direct access to the database. I have to use the RestClient to communicate with the Database. My issue is that custom validation rule is not working with my CFormModel.
Here is my code:
public function rules()
{
return array(
array('name', 'length', 'max' => 255),
array('nickname','match','pattern'=> '/^([a-zA-Z0-9_-])+$/' )
array('nickname','alreadyexists'),
);
}
public function alreadyexists($attribute, $params)
{
$result = ProviderUtil::CheckProviderByNickName($this->nickname);
if($result==-1)
{
$this->addError($attribute,
'This Provider handler already exists. Please try with a different one.');
}
This doesn't seem to work at all, I also tried this:
public function alreadyexists($attribute, $params)
{
$this->addError($attribute,
'This Provider handler already exists. Please try with a different one.');
}
Even then, it doesn't seem to work. What am I doing wrong here?
The problem with your code is that it doesn't return true or false.
Here is one of my rules to help you:
<?php
....
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('title, link', 'required'),
array('title, link', 'length', 'max' => 45),
array('description', 'length', 'max' => 200),
array('sections','atleast_three'),
);
}
public function atleast_three()
{
if(count($this->sections) < 3)
{
$this->addError('sections','chose 3 at least.');
return false;
}
return true;
}
...
?>
I met the same issue and finally got it solved. Hopefully, the solution could be useful for resolving your problem.
The reasons why the customised validation function is not called are:
this is a server side rather than client side validation
when you click the "submit" button, the controller function takes over the process first
the customised function won't be involved if you didn't call "$model->validate()"
Therefore, the solution is actually simple:
Add "$model->validate()" in the controller function. Here is my code:
"valid.php":
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'alloc-form',
'enableClientValidation'=>true,
'clientOptions'=>array('validateOnSubmit'=>true,),
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'valid_field'); ?>
<?php echo $form->textField($model,'valid_field'); ?>
<?php echo $form->error($model,'valid_field'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
"ValidForm.php":
class ValidForm extends CFormModel
{
public $valid_field;
public function rules()
{
return array(
array('valid_field', 'customValidation'),
);
}
public function customValidation($attribute,$params)
{
$this->addError($attribute,'bla');
}
}
"SiteController.php"
public function actionValid()
{
$model = new ValidForm;
if(isset($_POST['AllocationForm']))
{
// "customValidation" function won't be called unless this part is added
if($model->validate())
{
// do something
}
// do something
}
}
Related
i try to save multilanguaged content
My About model
...
public function rules() {
return [
[['status', 'date_update', 'date_create'], 'integer'],
[['date_update', 'date_create'], 'required'],
];
}
...
public function getContent($lang_id = null) {
$lang_id = ($lang_id === null) ? Lang::getCurrent()->id : $lang_id;
return $this->hasOne(AboutLang::className(), ['post_id' => 'id'])->where('lang_id = :lang_id', [':lang_id' => $lang_id]);
}
My AboutLang model
public function rules()
{
return [
[['post_id', 'lang_id', 'title', 'content'], 'required'],
[['post_id', 'lang_id'], 'integer'],
[['title', 'content'], 'string'],
];
}
My About controller
public function actionCreate()
{
$model = new About();
$aboutLang = new AboutLang();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,'aboutLang'=>$aboutLang]);
}
}
and my view (create form)
...
<?= $form->field($model, 'status')->textInput() ?>
<?= $form->field($aboutLang, 'title')->textInput() ?>
<?= $form->field($aboutLang, 'content')->textInput() ?>
enter code here
And when i put $aboutLang in create form i get an error "Call to a member function formName() on a non-object"
It looks like the views you are using were generated by Gii. In that case, Gii generates a partial view for the form (_form.php) and two views both for create and update actions (create.php and update.php). These two views perform a rendering of the partial view.
The problem you might have is that you are not passing the variable $aboutLang from create.php to _form.php, that must be done in create.php, when you call renderPartial():
$this->renderPartial("_form", array(
"model" => $model,
"aboutLang" => $aboutLang, //Add this line
));
Hope it helps.
Check your $aboutLang type.
It looks like it is null.
if ($aboutLang) {
echo $form->field($aboutLang, 'title')->textInput();
echo $form->field($aboutLang, 'content')->textInput();
}
I get an error 200. Form never gets posted, all fields return blank. I also checked if the columns are required, i set everything to null. I have another form that looks like this and it works fine. Any ideas?
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'thisForm',
)); ?>
//form
<?php
echo CHtml::ajaxSubmitButton('Add',
Yii::app()->createUrl("url/controller"),
array(
'type'=>'POST',
'dataType'=>'text json',
'data'=>'js:$("#thisForm").serialize()',
'success'=>'js:function(data) {
if(data.status=="success")
$.fn.yiiGridView.update("osb123");
}',
'error'=>'function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}'
));
?>
public function actionController()
{
$model=new Model;
if($_POST['Model'])
{
$model->attributes=$_POST['Model'];
$model->temporary_id = Yii::app()->user->user_id;
$model->cost = floatval($_POST['Model']['cost']);
$model->active = "Y";
if($model->validate()){
echo CJSON::encode(array('status'=> 'success',
'data'=>var_dump($_POST['Model'])
));
}
else{
$error = CActiveForm::validate($model);
echo CJSON::encode(array('status'=> 'error', 'error'=>var_dump($_POST['Model'])));
}
}else echo CJSON::encode(array('status'=>'error','error'=>'Not Set'));
}
In the ajax button for url you set: Yii::app()->createUrl("url/controller") while usually the right syntax is Yii::app()->createUrl("controller/action") Could you with debugging tool (Ctrl+Shift+I or F12) check the POST-request and see the actual url that has been generated by yii?
You have beginWidget, do you also have endWidget ?
I will appreciate if somebody could help me to find how to solve out one problem, I have a checkbox in my create form. If i pushed the create button I want to have a popup window if the checkbox is checked and do nothing if the checkbox is unchecked.
my codes in _form
<?php echo $form->checkBoxRow($model, 'default'); ?>
<div class="form-actions">
<?php $this->widget('bootstrap.widgets.TbButton', array(
'buttonType'=>'submit',
'type'=>'primary',
'label'=>$model->isNewRecord ? 'Create' : 'Save',
)); ?>
</div>
in my create controller
public function actionCreate()
{
$model=new EmpSched;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['EmpSched']))
{
$model->attributes=$_POST['EmpSched'];
if($model->save())
$this->redirect(array('view','id'=>$model->id_empsched));
}
$this->render('create',array(
'model'=>$model,
'emp'=> new CActiveDataProvider('schedule'),
));
}
in my create.php
<?php
$this->breadcrumbs=array(
'Emp Scheds'=>array('index'),
'Create',
);
$this->menu=array(
array('label'=>'List EmpSched','url'=>array('index')),
array('label'=>'Manage EmpSched','url'=>array('admin')),
);
?>
<h1>Create EmpSched</h1>
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
<?php $this->widget('bootstrap.widgets.TbGridView',array(
'id'=>'schedule-grid',
'dataProvider'=>$emp,
'columns'=>array(
'id_sched',
'sched_name',
array(
'name'=>'mon',
'value'=>'$data->fkidday->monday->name'
),
array(
'name'=>'tues',
'value'=>'$data->fkidday->tuesday->name'
),
array(
'name'=>'wed',
'value'=>'$data->fkidday->wednesday->name'
),
array(
'name'=>'thurs',
'value'=>'$data->fkidday->thursday->name'
),
array(
'name'=>'fri',
'value'=>'$data->fkidday->friday->name'
),
/*'sat',
'sun',
*/
),
));
?>
<script>
$(function() {
// when row is clicked
$('#schedule-grid tbody:first').on('click', 'tr', function() {
// get the ID
var id = $(this).find('td:first').text();
// select the same option in dropdown list with same value
$('#EmpSched_fk_id_sched')
.find("option[value="+ id +"]")
.prop("selected", "selected");
});
});
</script>
Add custom javascript (supposing the create button will submit the form)
$('#form-id').submit(function() {
if $(this).find('#check-box-id').is(':checked') {
// open popup here
}
return false;
});
I am new to Yii and learning it now. Here i am trying to get the listing of the user from the users table of the database.
Following is my Users Controller function for view:
class UsersController extends Controller
{
public function actionIndex()
{
$this->render('index');
}
public function actionView()
{
$model = new Users;
$this->render('view',array(
'model'=>$model,
));
}
}
Following is my Users Model:
class Users extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return '{{users}}';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('fname, lname, email', 'required'),
array('fname, lname', 'length', 'max'=>50),
array('email', 'length', 'max'=>100),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, fname, lname, email', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'fname' => 'First Name',
'lname' => 'Last Name',
'email' => 'Email',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('fname',$this->fname,true);
$criteria->compare('lname',$this->lname,true);
$criteria->compare('email',$this->email,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
Following is my View:
<h1>Users</h1>
<p>
Below is the list of users, here you may add user.
</p>
<?php $this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'fname',
'lname',
'email',
),
)); ?>
<div class="view">
<b><?php echo CHtml::encode($data->getAttributeLabel('id')); ?>:</b>
<?php echo CHtml::link(CHtml::encode($data->id), array('view', 'id'=>$data->id)); ? >
<br />
<b><?php echo CHtml::encode($data->getAttributeLabel('fname')); ?>:</b>
<?php echo CHtml::encode($data->fname); ?>
<br />
<b><?php echo CHtml::encode($data->getAttributeLabel('lname')); ?>:</b>
<?php echo CHtml::encode($data->lname); ?>
<br />
<b><?php echo CHtml::encode($data->getAttributeLabel('email')); ?>:</b>
<?php echo CHtml::encode($data->email); ?>
<br />
</div>
I am getting a PHP notice saying that undefined variable: model, please help thanks in advance.
It looks like you were pasting _view.php.
Make sure you hand your $model variable from view.php to _view.php, since in actionView() you are only handing it to 'view'.
field($model, 'VideoTitle')->textInput(['autofocus' => true, 'required' => true]) ?>
field($model, 'Description')->textInput(['autofocus' => true, 'required' => true]) ?>
I just created this a renderPartial():
renderPartial('/users/_form', array('model'=>new Users), true, true); ?>
the problem that the data entered doesn't validated.
Did I miss something ?
it's not clear from your question exactly WHEN you want to validate.
If on client side you need something like this:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'your-form',
'enableAjaxValidation'=>true,
'clientOptions' => array(
'validateOnSubmit'=>true,
),
)); ?>
Plus this in your controller in the post action:
$this->performAjaxValidation($model);
Along with a controller method like:
/**
* Performs the AJAX validation.
* #param CModel the model to be validated
*/
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='saferides-registered-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
If you only want to validate on post, something like this as part of your controller action that handles the post:
if ( $model->validate() && $model-save() )
{
..redirect to your view
}
Also consult the docs