I'm working in a Prestashop 1.6 module and I'm having problem with one field that seems not to be recognized. In the controller I'm using the renderForm() method to get the form and I define the field in the form like this:
array(
'type' => 'text',
'label' => $this->l('Message'),
'name' => 'message',
'required' => true,
'hint' => $this->l('Message to be shown when the customer exceeds the quota '),
),
And in the model class I define it like this:
'message' => array(
'type' => self::TYPE_STRING,
'validate' => 'isString',
'required' => true,
'size' => 4000,
'db_type' => 'varchar'
),
And then when I try to save the record I get this message: Property QuotaModel->message is empty
Am I missing a definition somewhere else? Can you see what I'm missing here?
Thanks for any help
Define the field as public property in your object model class.
class QuotaModel extends ObjectModel
{
...
public $message;
...
}
Related
Hi I have CRUD generated CGridView in yii. I need to add a new button to CGridView rows and hide it if appointment_status(one of CGridView column) value equals 0
This is my code of CGridView,
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'bookings-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'id',
'name',
'email',
'telephone',
'time',
'employee',
'appointment_status',
'client_ip',
'link' => array(
'header' => 'Confirmation',
'type' => 'raw',
'value' => 'CHtml::button("$data->appointment_status",array("onclick"=>"document.location.href=\'".Yii::app()->controller->createUrl("controller/action",array("id"=>$data->id))."\'"))',
'visible'=>$data->appointment_status==1,
),
array(
'class' => 'CButtonColumn',
),
),
));
But all I'm getting is error stating,
Undefined variable: data
It would be great help if someone can look into it.
you can use like this:
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'bookings-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'id',
'name',
'email',
'telephone',
'time',
'employee',
'appointment_status',
'client_ip',
'link' => array(
'header' => 'Confirmation',
'type' => 'raw',
'value' => function ($data) {
if ($data->appointment_status == 1) {
return CHtml::button("$data->appointment_status", array("onclick" => "document.location.href=\'" . Yii::app()->controller->createUrl("controller/action", array("id" => $data->id)) . "\'"));
} else {
return;
}
}
),
array(
'class' => 'CButtonColumn',
),
),
));
Your 'visible' handling the column visibility and not the button, you can use custom attribute on model to create and handle the button visibility.
add to your model:
public function getConfirmationButton()
{
if ($data->appointment_status == 1) {
return CHtml::button($this->appointment_status,array("onclick"=>"document.location.href=\'".Yii::app()->controller->createUrl("controller/action",array("id"=>$this->id))."\'"));
} else {
return '';
}
}
and call it in your view:
..........
'link' => array(
'header' => 'Confirmation',
'type' => 'raw',
'value' => '$data->confirmationButton',
),
...........
visible is a boolean or a PHP expression that will be evaluated to give a boolean. During the evaluation $data is assigned to the current item from the dataProvider used. $data doesn't exist outside of the evaluation function evaluateExpression(). As such the implementation should be:
`visible` => '$data->appointment_status == 1',
You need to quote value of visible key in link array. So instead of this:
'visible'=>$data->appointment_status==1
It should be:
'visible'=>'$data->appointment_status==1'
it should work now.
You will get undefined variable because visible not allow any callback.
Try this solution, it's yii2 code and i don't know much of Yii.
'delete' => function ($url, $model) {
return ($model->isVisible($model)) ?
Html::a('<span class="glyphicon glyphicon-trash"></span>',
$url,
['title' => Yii::t('app', 'Delete')]) : '';
public static function isVisible($data)
{
return ($data->appointment_status == 1) ? true : false;
}
I want first and last record id form $dataprovider which is passed to gridview which i need to pass to this link.
array(
'name' => 'msg',
'value' => 'CHtml::link(substr(strip_tags($data->msg),0,30)." .....",Yii::app()->createUrl("Mail/view",array("id"=>$data->primaryKey,"flag"=>"inbox","tab"=>'.$tab.',"category"=>'.$category.')))',
'type' => 'raw',
'header' => 'Message',
),
Declare two attributes in your controller.
public $first=null;
public $last=null;
Define a function in controller to render your link
public function renderMailViewLink($data,$row){
// you can return anything you want here. whether a link or whatever
// access $this->first->id , $this->last->id
return CHtml::link($data->anyAttribute,array('someRoute','id'=>$data->id,'first'=>$this->first->id))
}
CActiveDataProvider has a method getData(), which return array of all active records.
in actionIndex
$dataProvider = $model->search()
$data = $dataProvider->getData();
$this->first = reset($data );
$this->last = end($data);
And finally in your view
array(
'name' => 'msg',
'value' => array($this,'renderMailViewLink'),
'type' => 'raw',
'header' => 'Message',
),
Please note this code is not tested. But thats how it can be achieved
I'm trying to use Form Builder to build a simple file upload prompt. I want to specify the rule for the file to be similar to
array('formFile', 'file', 'allowEmpty' => false, 'types' => 'html'),
but something is wrong. The file upload element only appears if I explicitly mark the element as 'safe' (and remove the 'file' rule). What am I missing?
models/UploadForm.php
class UploadForm extends CFormModel
{
public $year;
public $formFile;
public function rules ()
{
return array(
array('year', 'required'),
array('year', 'date', 'format'=>'yyyy'),
// array('formFile', 'safe'),
array('formFile', 'file', 'allowEmpty' => false, 'types' => 'html'),
);
}
static public function getYearOptions () {...}
}
views/extranet/uploadForm.php
return array(
'title' => 'Select year',
'method' => 'post',
'enctype' => 'multipart/form-data',
'elements' => array(
'year' => array(
'type' => 'dropdownlist',
'items' => UploadForm::getYearOptions(),
),
'formFile' => array(
'type' => 'file',
'label' => 'form source file',
),
),
'buttons' => array(
'upload' => array(
'type' => 'submit',
'label' => 'upload',
),
),
);
controllers/ExtranetController.php
class ExtranetController extends CController
{
public function actionIndex ()
{
$form = new CForm('application.views.extranet.uploadForm', new UploadForm());
if ($form->submitted('upload') && $form->validate()) {...}
$this->render('index', array('form' => $form));
}
}
The reason for this is very simple.
The form builder only renders input elements which are considered safe (I.E. have a validation rule). What you have done is perfectly fine, except CFileValidator isn't "safe" by default, whereas other validators are safe.
The quickest way to solve this is the following:
// In your model::rules() function
return array(
array('formFile', 'file', 'allowEmpty' => false, 'types' => 'html', 'safe' => true),
);
Refer to these two links for more information: the CFileValidator#safe documentation, and the Github issue for a problem very similar to yours.
Until now I have been binding input filters to the form in the module, in other words I have been creating elements in the form, adding input filters to the elements on the module side.
For example check this example
Right now im creating text field elements dynamically depending upon the requirements, like this in my form
//Form
public function addNamesTextFieldElement($names)
{
foreach($names as $name)
{
$nameTextField = new Element\Text($name->getName());
$nameTextField->setAttribute('type', "text");
$nameTextField->setLabel($name->getName());
$this->add($nameTextField );
}
}
What would be best approach where to add/attach input filters to such dynamically generated elements.
I probably wouldn't use this approach, but something like this would work, providing you have already assigned an InputFilter to the form:
public function addNamesTextFieldElement($names)
{
$factory = new InputFactory();
foreach($names as $name)
{
$nameTextField = new Element\Text($name->getName());
$nameTextField->setAttribute('type', "text");
$nameTextField->setLabel($name->getName());
$this->add($nameTextField );
$this->getInputFilter()->add(
$factory->createInput(array(
'name' => $name->getName(),
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
))
);
}
}
I'm using Zend Framework 2 and I need a Dependent Dropdown. When user select an category (cat_id on my example) the system fills the subcategory (sca_id) with the correct elements.
I could do that by creating an application like this:
My form looks like:
$this->add(array(
'name' => 'cat_id',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => 'Categoria',
'value_options' => array(
'' => '',
),
),
));
$this->add(array(
'name' => 'sca_id',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => 'Sub Categoria',
'style' => 'display:none;', // Esse campo soh eh exibido qndo uma categoria for escolhida
'value_options' => array(
'' => '',
),
),
));
Note that I don't fill the value_options there, because I choose do that in my controller, where the Service Manager is avaliable:
$form = new ProdutoForm('frm');
$form->setAttribute('action', $this->url()->fromRoute('catalogo-admin', array( ... )));
// Alimenta as comboboxes...
$form->get('cat_id')->setValueOptions($this->getCategoriaService()->listarCategoriasSelect());
On the change event of cat_id I do an $.ajax to grab the elements from an Action and fill the sca_id.
That works fine!
The problem is on my validation:
$this->add(array(
'name' => 'cat_id',
'require' => true,
'filters' => array(
array('name' => 'Int'),
),
));
$this->add(array(
'name' => 'sca_id',
'require' => true,
'filters' => array(
array('name' => 'Int'),
),
));
When I submit my form it keeps saying : The input was not found in the haystack for both dropdowns...
What I'm doing wrong?
Extra questions : There's a better way to fill my dropdowns?
Ps.: I guess this question Disable notInArray Validator Zend Framework 2 asks something similar than me, but I wanted to detail more my problem.
Well, I realized that I should populate my select element before validate my form!
// SaveAction
$request = $this->getRequest();
if ($request->isPost())
{
$form = new ProdutoForm();
// Alimenta as comboboxes...
$form->get('cat_id')->setValueOptions($this->getCategoriaService()->listarCategoriasSelect());
$form->get('sca_id')->setValueOptions($this->getSubCategoriaService()->listarSubCategoriasSelect());
// If the form doesn't define an input filter by default, inject one.
$form->setInputFilter(new ProdutoFormFilter());
// Get the data.
$form->setData($request->getPost());
// Validate the form
if ($form->isValid())
{
// Valid!
}else{
// Invalid...
}
That code works nice. My form now validate perfectly!