I want to edit a record from a database with a Zend Form (Zend Framework 2).
In ZF1 I did in my controller:
$values = $table->getValues();
$form = new MyForm();
$form->populate($values);
$this->view->form = $form;
and in the viewscript:
<?php echo $this->form ?>
In ZF2 I tried in my controller:
$values = $table->getValues();
$form = new MyForm();
$form->populateValues($values); // form->setData($values) does not work either
return array('form' => $form);
and in my viewscript:
<?php echo $this->form()->openTag($form) ?>
<?php echo $this->formCollection($form) ?>
<?php echo $this->form()->closeTag($form) ?>
but that renders the form, without data however.
what is the correct way to do this?
You need to call prepare() on your form before you open it in your view script. For example:
<?php $form->prepare(); ?>
<?php echo $this->form()->openTag($form) ?>
<?php echo $this->formCollection($form) ?>
<?php echo $this->form()->closeTag($form) ?>
See the reference guide here
Note the following point:
the prepare() method. You must call it prior to rendering anything in
the view (this function is only meant to be called in views, not in
controllers).
The issue was that $table->getValues() in my code returns an arrayObject whereas populateValues() expects an array.
Related
I am building a Yii application and I followed a tutorial to enable the Advanced search in the index file of a table like this:
<?php
/* #var $this TakeController */
/* #var $dataProvider CActiveDataProvider */
$this->breadcrumbs=array(
'Takes',
);
$this->menu=array(
array('label'=>'Create Take', 'url'=>array('create')),
array('label'=>'Manage Take', 'url'=>array('admin')),
);
Yii::app()->clientScript->registerScript('search', "
$('.search-button').click(function(){
$('.search-form').toggle();
return false;
});
$('.search-form form').submit(function(){
$.fn.yiiListView.update('takelistview', {
data: $(this).serialize()
});
return false;
});
");
?>
<h1>Takes</h1>
<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); ?>
</div>
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'id'=>'takelistview',
'sortableAttributes'=>array('id', 'data'')
)); ?>
I would like to know if there is a way to process the output of the advanced search. I know that with $dataprovider I can access all the records for this table, but I want to access only the filtered ones. In particular, I want to get the attribute "data" for each record in order to enable the download for all filtered records. I took a look at $.fn.yiiListView and CListView but I don't understand what to do. Can you help me? Thanks!
the $dataProvider variable belongs to the CDataProvider class, you can access the data using the getdata Function as below.
$data = $dataProvider->getData($refresh);
Set the $refresh flag to true if you want to reload the data from data source
Refer to full data provider documentation for more dataProvider methods
I Need Help in Yii, i get problem in my form, the problem is if i put id in textfield then client validation not showing for that field but another field no problem. This is my code in form
<div class="row">
<?php echo $form->labelEx($model,'latar_belakang'); ?>
<?php echo $form->textField($model,'latar_belakang',array('id' => 'latarbelakang','class' => 'input-block-level')); ?>
<?php echo $form->error($model,'latar_belakang'); ?>
<?php echo $form->labelEx($model,'rumusan_masalah'); ?>
<?php echo $form->textField($model,'rumusan_masalah',array('id' => 'rumusanmasalah','class' => 'input-block-level')); ?>
<?php echo $form->error($model,'rumusan_masalah'); ?>
</div>
for your knows i use id in textfield for calculaten field with jquery which i put in form . this is my jquery code in form
Yii::app()->clientScript->registerCoreScript('jquery');
Yii::app()->clientScript->registerScript('totalValues',"
function totalValues()
{
var lb = $('#latarbelakang').val() ;
var rm = $('#rumusanmasalah').val();
var tot = parseInt(lb) + parseInt(rm);
$('#nilaiakhir').val( tot );
}
", CClientScript::POS_HEAD);
Yii::app()->clientScript->registerScript('changeTotals', "
$('#latarbelakang').change( function(){ totalValues(); } );
$('#rumusanmasalah').change( function(){ totalValues();} );
", CClientScript::POS_END);
What i must do ? for solving this problem ?.
Thanks B4..
By default Yii generates ids of fields dynamically using model name and field name.
For example for 'password' field of 'User' model the id would be 'User_password'
You can inspect a field(to which you have not given your custom id) with firebug and see the auto generated id. also yii maps error messages with those auto generated ids in response. that is why your error messages are not showing.
what you can do is to try to call that js function with yii generated id.
i have a stupid question... why if i pass e variable to view the browser return me
Undefined variable: ? I just clone my first method (for the ads, the same procedure). But with ads work, and with category not work, this is so stupid, why?
i show my little application
my controller:
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Ads extends Controller_Template {
public $template = 'template';
// function indes Ads
public function action_index()
{
$ads = ORM::factory('ads')->find_all(); // load all object inside ads table
$view = new View('ads/index'); // load the view/ads/index.php
$view->set('ads', $ads); // set 'ads' object to view
$this->template->set('content', $view);
}
// view single ads
public function action_single()
{
$id = $this->request->param('id');
$record = ORM::factory('ads')
->where('id_ads', '=', $id)
->find();
$view = new View('ads/single');
$view->set('ads', $record);
$this->template->set('content', $view);
}
public function action_category()
{
$category = ORM::factory('category')->find_all();
$view = new View('ads/index');
$view->set('category', $category);
$this->template->set('content', $view);
}
} // End Ads
my interest view (ads/index.php)
<?php foreach ($ads as $obj) : ?>
<h3><?php echo HTML::anchor('/ads/single/'.$obj->id_ads, $obj->title_ads); ?></h3>
<p><?php echo $obj->description_ads; ?></p>
<p>Autore: <?php echo $obj->author_ads; ?> || creato il <?php echo $obj->date_ads; ?> || categoria: <?php echo HTML::anchor('#', $obj->category->category_name); ?></p>
<?php endforeach; ?>
<?php foreach ($category as $obj) : ?>
<?php echo $obj->id; ?>
<?php endforeach; ?>
the error in the browser
ErrorException [ Notice ]: Undefined variable: category
why only for category ?? and not for ads?
Only one of action functions gets run,
This means in action_index() the $ads variable is being set but not $category.
And in action_category() the $category variable is being set but not $ads.
If you only expect to use of those variables, you should make another ads/category.php view and use that in the action_category() function, and remove the references to $ads in that view.
Also it seem that you are expecting the action_category() function to be running, based on the error you are seeing, it is actually running action_index(). Check your routes to find out why.
I need to have comments/hints for some fields in my Form. My idea is to describe it in model, just like attributeLabels. How can I do it?
And then it would be ideal, if the Gii Model (and Crud) generator would take it directly from mysql column's comment
So I see two questions here:
Describe hints in the model and display on the form.
Get hints from mysql comment
Displaying Hints from Model
Here's a slightly modified version of the default login.php file generated by Yiic
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
<p class="hint">
Hint: You may login with <kbd>demo</kbd>/<kbd>demo</kbd> or <kbd>admin</kbd>/<kbd>admin</kbd>.
</p>
</div>
<div class="row rememberMe">
<?php echo $form->checkBox($model,'rememberMe'); ?>
<?php echo $form->label($model,'rememberMe'); ?>
<?php echo $form->error($model,'rememberMe'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Login'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
Let's move that password hint into the model by adding a attributeHints() method and a getHint() method to the LoginForm.php model.
/**
* Declares attribute hints.
*/
public function attributeHints()
{
return array(
'password'=>'Hint: You may login with <kbd>demo</kbd>/<kbd>demo</kbd> or <kbd>admin</kbd>/<kbd>admin</kbd>.',
);
}
/**
* Return a hint
*/
public function getHint( $attribute )
{
$hints = $this->attributeHints();
return $hints[$attribute];
}
As you can see, we;ve moved the hint text from the view into the model and added a way to access it.
Now, back in login.php, let's add the hint tag based on data from the model.
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
<?php echo CHtml::tag('p', array('class'=>'hint'), $model->getHint('password')); ?>
</div>
So now we've changed the hardcoded hint into a generated element populated with data from the model.
Now, moving on to the second question.
Getting hints from mySQL comments
Unforunately, I am not fammiliar enough with Gii to know how to automatically generate the hints from mySQL comments. However, getting the mySQL comment data into the model is fairly easy.
To do this we can use the following mySQL query
SHOW FULL COLUMNS FROM `tbl_user`
So let's add the comment to the password field
ALTER TABLE `tbl_user`
CHANGE `password` `password` VARCHAR( 256 )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL
COMMENT 'Hint: You may login with <kbd>demo</kbd>/<kbd>demo</kbd> or <kbd>admin</kbd>/<kbd>admin</kbd>.';
And let's add the code to fetch it into our attributeHints() method.
/**
* Declares attribute hints.
*/
public function attributeHints()
{
$columns= Yii::app()->db->createCommand('SHOW FULL COLUMNS FROM `tbl_user`')->queryAll();
$comments=array();
foreach($columns as $column){
if( isset( $column['Comment'] ) )
{
$comments[ $column['Field'] ] = $column['Comment'];
}
}
//Add any hardcoded hints here
$hints = array(
'username'=>'Enter username above',
);
//Return merged array
return array_merge( $comments, $hints );
}
We now have two ways to set comments, through mySQL comments or through hard coded statements.
Let's update our login.php file quick to include hints of both types.
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
<?php echo CHtml::tag('p', array('class'=>'hint'), $model->getHint('username')); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
<?php echo CHtml::tag('p', array('class'=>'hint'), $model->getHint('password')); ?>
</div>
And that's it!
Now our login page will look like this, with a username hint from the model and a password hint from the mySQL comment.
As of Yii-1.1.13, a new attribute, comment, has been added to CMysqlColumnSchema which is defined in parent CDbColumnSchema:
comment of this column. Default value is empty string which means that no comment has been set for the column. Null value means that RDBMS does not support column comments at all (SQLite) or comment retrieval for the active RDBMS is not yet supported by the framework.
So we can use it to access the comment. Somewhat like this:
$modelObject->tableSchema->columns['column_name']->comment
// or if you are doing this within your model use
$this->tableSchema->columns['column_name']->comment
Note that the tableSchema is already set when any CActiveRecord model is constructed or even if the static model is used, so there are no new queries executed when we access the property.
A sample implementation within your model:
class MyModel extends CActiveRecord {
// hints array will store the hints
public $hints=array();
public function init() {
parent::init();
$this->hints=self::initHints($this);
}
public static function initHints($model) {
$comments=array();
foreach ($model->tableSchema->columns as $aColumn){
if(!empty($aColumn->comment))
$comments["$aColumn->name"]=$aColumn->comment;
}
return $comments;
}
public static function model($className=__CLASS__) {
$model=parent::model($className);
$model->hints=self::initHints($model);
return $model;
}
}
Now you can access hints as:
$model = new MyModel;
$single_column_hint=$model->hints['column_name'];
$model = MyModel::model();
$single_column_hint=$model->hints['column_name'];
For doing this through gii templates, you just need to copy the above code to your custom model code template, read the guide to see how this can be done.
I would recommend having the code in a custom base class, from which you can derive your active records.
I am trying to include form on product page using renderPartial but it gives error
Fatal error: Call to a member function getErrors() on a non-object in /Applications/MAMP/htdocs/yii/framework/web/helpers/CHtml.php on line 1605
i am using below code...
in product page
// product detail goes here, use below form to make an inquiry about this product
<?php $this->renderPartial('inquiry'); ?>
and in inquiry page page
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'query-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,'name'); ?>
<?php echo $form->error($model,'name'); ?>
</div>
There is a variable called $model in your view, but in your controller's renderPartial() call, you are not passing $model into your view. So the view is looking for a variable called $model, but it does not exist.
You need to generate a new model in your controller, then pass it into the view, as follows:
$model = new Product(); //use whatever class you created for the model in place of 'Product' here
$this->renderPartial('inquiry', array('model'=>$model));
The 'model'=>$model tells Yii to pass the variable $model into the view, and the 'model' represents the name you use to access that variable from within the view. So if you write something like:
$this->renderPartial('inquiry', array('product'=>$model));
Then in the view, you would access the variable by typing $product instead of $model.