Pass array as attribute from form - yii

In my model I have attribute - specifications:
class Category extends CActiveRecord
{
private $_specifications = array();
public function getSpecifications()
{
return $this->_specifications;
}
public function setSpecifications($specifications)
{
$this->_specifications = implode(', ', $specifications);
}
So I want specifications to be an array.
My view file:
<div id="specifications" class="row">
<?php echo $form->labelEx($model,'specifications'); ?>
<?php echo $form->textField($model,'specifications',array('rows'=>6, 'cols'=>50, 'name'=>'Category[specifications][0]', 'class' => 'clonedInput')); ?>
<?php echo $form->textField($model,'specifications',array('rows'=>6, 'cols'=>50, 'name'=>'Category[specifications][1]', 'class' => 'clonedInput')); ?>
<?php echo $form->error($model,'specifications'); ?>
</div>
When I send form I get an error:
htmlspecialchars() expects parameter 1 to be string, array given
...
public static function encode($text)
84 {
85 return htmlspecialchars($text,ENT_QUOTES,Yii::app()->charset);
86 }
I've tried to disable encoding:
<?php echo $form->textField($model,'specifications',array('encode'=>false, 'rows'=>6, 'cols'=>50, 'name'=>'Category[specifications][0]', 'class' => 'clonedInput')); ?>
<?php echo $form->textField($model,'specifications',array('encode'=>false, 'rows'=>6, 'cols'=>50, 'name'=>'Category[specifications][1]', 'class' => 'clonedInput')); ?>
But in that case it's another error:
Array to string conversion
...
2216 $html .= ' ' . $name . '="' . ($raw ? $value : self::encode($value)) . '"';
Can anybody give an advice, what should I do to pass an array from form? Thanks.

How can you pass an array to a single textfield? What should it display?
You can can create a virtual attribute for that.
In the model:
private $_specifications = array();
public function getSpecifications()
{
return implode(', ', $this->_specifications);
}
The view can remain untouched.
Edit:
Of course you need a setter too, if you want to be able to write to the attribute.
public function setSpecifications($specifications)
{
$this->_specifications = explode(', ', $specifications);
}
Please refer to http://www.yiiframework.com/wiki/167/understanding-virtual-attributes-and-get-set-methods/

Since your specifications attribute is an array, you should simply make a loop to display corresponding inputs, e.g. :
foreach ($model->specifications as $s)
{
echo Chtml::textField('Category[specifications][]', $s, array('rows'=>6, 'cols'=>50, 'class' => 'clonedInput'));
}

<?php echo $form->textField($model,'specifications',array('encode'=>false, 'rows'=>6, 'cols'=>50, 'name'=>'Category[specifications][0]', 'class' => 'clonedInput')); ?>
<?php echo $form->textField($model,'specifications',array('encode'=>false, 'rows'=>6, 'cols'=>50, 'name'=>'Category[specifications][1]', 'class' => 'clonedInput')); ?>
I think the specifications will be displayed twice.

Related

sending a text data between template to controller in cakephp 3

Definition :
I want to send text data from the template (ctp file) to the controller but it is not working.
What I DO Until now :
I have this controller courses and it has function called search as following :
/src/Controller/CoursesController :
public function search()
{
$search = $this->request->getData('keyword');
debug($search);die;
...
The /src/Template/search:
<?= $this->Form->create(null, ['url' => ['controller'=>'courses','action' => 'search']]) ?>
<?= $this->Form->control('keyword', ['label' => false, 'type'=>'text','class'=>'form-control', 'placeholder' => __('Search for...')]); ?>
<?= $this->Form->button(__('Go'), ['class' => 'btn btn-default', 'type' => 'submit']) ?>
<?= $this->Form->end() ?>
Despite my attempts to get the text data from the form and print it using debug but unfortunately I've got empty array
try this:
public function search()
{
$data = $this->request->data;
if($this->request->is(['patch', 'post', 'put', 'get']))
{
$search = $this->request->data('keyword');
debug($search);
}
}

registration form post field as empty

i'm using Yii-user, and have made some modification to the user/views/user/registration.php file.
for some reason even when i fill in firstname and lastname, it still says i left those fields empty. any idea why?
$form=$this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'id'=>'registration-form',
'type'=>'vertical',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
));
<?php echo $form->textField($model,'email', array('class' => 'input-block-level', 'placeholder' => $model->getAttributeLabel('email'))); ?>
<?php echo $form->passwordField($model,'password', array('class' => 'input-block-level', 'placeholder' => $model->getAttributeLabel('password'))); ?>
<?php echo $form->passwordField($model,'verifyPassword', array('class' => 'input-block-level', 'placeholder' => $model->getAttributeLabel('verifyPassword'))); ?>
<p class="text-seperator"> about you </p>
<?php echo $form->textField($profile,'firstname', array('class' => 'input-block-level', 'placeholder' => $model->getAttributeLabel('firstname'), 'maxlength'=> 255)); ?>
<?php echo $form->textField($profile,'lastname', array('class' => 'input-block-level', 'placeholder' => $model->getAttributeLabel('lastname'), 'maxlength'=> 255)); ?>
and in my user/models/registrationform.php i have this
class RegistrationForm extends User {
public $firstname; //added
public $lastname; //added
public $verifyPassword;
public $verifyCode;
public function rules() {
$rules = array(
array('firstname, lastname, password, verifyPassword, email', 'required'),
array('firstname', 'length', 'max'=>225, 'min' => 3,'message' => UserModule::t("Incorrect First Name (length between 3 and 225 characters).")),
array('lastname', 'length', 'max'=>225, 'min' => 3,'message' => UserModule::t("Incorrect Last Name (length between 3 and 225 characters).")),
.........
}
}
to fill up firstname and last name using the original code they used this...
$profileFields=Profile::getFields();
if ($profileFields) {
foreach($profileFields as $field) {
?>
<!--div class="row"-->
<?php echo $form->labelEx($profile,$field->varname); ?>
<?php
if ($widgetEdit = $field->widgetEdit($profile)) {
echo $widgetEdit;
} elseif ($field->range) {
echo $form->dropDownList($profile,$field->varname,Profile::range($field->range));
} elseif ($field->field_type=="TEXT") {
echo$form->textArea($profile,$field->varname,array('rows'=>6, 'cols'=>50));
} else {
echo $field->varname.'<br />';
echo $form->textField($profile,$field->varname,array('size'=>60,'maxlength'=>(($field->field_size)?$field->field_size:255)));
}
?>
<?php echo $form->error($profile,$field->varname); ?>
<!--/div-->
<?php
}
}
I think you need to change this,
you have passed $model in here:
<?php echo $form->textField($model,'email', array('class' => 'input-block-level', 'placeholder' => $model->getAttributeLabel('email'))); ?>
but you have given $profile here:
<?php echo $form->textField($profile,'firstname', array('class' => 'input-block-level', 'placeholder' => $model->getAttributeLabel('firstname'), 'maxlength'=> 255)); ?>
if you check out the generated html, you will notice that the generated input has different name!
i'm not sure why this works (would be great is someone could explain in detail)
but the issue was here..
public function rules() {
$rules = array(
array('firstname, lastname, password, verifyPassword, email', 'required'),
array('firstname', 'length', 'max'=>225, 'min' => 3,'message' => UserModule::t("Incorrect First Name (length between 3 and 225 characters).")),
array('lastname', 'length', 'max'=>225, 'min' => 3,'message' => UserModule::t("Incorrect Last Name (length between 3 and 225 characters).")),
.........
}
}
firstname, lastname when this is removed it works. and it still is set as required.

change placeholder text from array

I'm using the yii-user extension and i'm trying the add proper label to the 'placeholder' attribute. really new to Yii so still trying to get the grasp of things.
I've added the attributeLabels() method in the class in the models folder.
class RegistrationForm extends User {
/**
* Declares attribute labels.
*/
public function attributeLabels()
{
return array(
'email'=>'Email Address',
'firstname'=>'First Name',
'lastname' => 'Last Name',
'verifyPassword' = 'Retype Password'
);
}
}
Here is my code in my /views/ folder
$form=$this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'id'=>'registration-form',
'type'=>'vertical',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
));
<?php echo $form->textField($model,'email', array('class' => 'input-block-level', 'placeholder' => 'email')); ?>
<?php echo $form->passwordField($model,'password', array('class' => 'input-block-level', 'placeholder' => 'password')); ?>
<?php echo $form->passwordField($model,'verifyPassword', array('class' => 'input-block-level', 'placeholder' => 'verifyPassword')); ?>
<?php
$profileFields=Profile::getFields();
if ($profileFields) {
foreach($profileFields as $field) {
if ($widgetEdit = $field->widgetEdit($profile)) {
//echo $widgetEdit;
} elseif ($field->range) {
echo $form->dropDownList($profile,$field->varname,Profile::range($field->range),array('class' => 'input-block-level'));
} elseif ($field->field_type=="TEXT") {
echo $form->textArea($profile,$field->varname,array('rows'=>6, 'cols'=>50));
} else {
//echo $field->varname;
if ($field->varname == 'firstname')
{
$placeholder = 'First Name';
}
else if ($field->varname == 'lastname')
{
$placeholder = 'Last Name';
}
else
{
$placeholder = $field->varname;
}
echo $form->textField($profile,$field->varname,array('size'=>60,'maxlength'=>(($field->field_size)?$field->field_size:255),'class' => 'input-block-level', 'placeholder' => $placeholder));
}
echo $form->error($profile,$field->varname);
}
}
?>
how would i make attributeLabels() work on my echo $form->textField($profile,$field->varname,array('size'=>60,'maxlength'=>(($field->field_size)?$field->field_size:255),'class' => 'input-block-level', 'placeholder' => $placeholder)); ?
You can get the text label for the specified attribute with getAttributeLabel() like:
$model->getAttributeLabel('verifyPassword');
E.x:
<?php echo $form->passwordField($model,'verifyPassword',
array('class' => 'input-block-level',
'placeholder' => $model->getAttributeLabel('verifyPassword')));
?>
you don't have to edit class RegistrationForm extends User
open protected/modules/user/model/User.php
add add/edit your custom labels in the attributeLabels() method
public function attributeLabels()
{
return array(
'id' => UserModule::t("Id"),
'username'=>UserModule::t("username"),
'password'=>UserModule::t("Password"),
'verifyPassword'=>UserModule::t("Retype Password"),
'firstname'=>UserModule::t("First Name"), //ADDED
'lastname'=>UserModule::t("Last Name"), // ADDED
'email'=>UserModule::t("Email Address"), //EDITED
'verifyCode'=>UserModule::t("Verification Code"),
'activkey' => UserModule::t("Activation Key"),
'createtime' => UserModule::t("Registration Date"),
'create_at' => UserModule::t("Registration Date"),
'lastvisit_at' => UserModule::t("Last Visit"),
'superuser' => UserModule::t("Superuser"),
'status' => UserModule::t("Status"),
);
}
and to get the label to show in your view file. use this
<?php echo $form->passwordField($model,'verifyPassword',
array('class' => 'input-block-level',
'placeholder' => $model->getAttributeLabel('email')));
?>

Custom validation rule is not working for CFormModel

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
}
}

Undefined Variable: model

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]) ?>