Sorry. I was shorten my question because i was consider that, those users who work on yii can easily understand my question but now i am modifying so you can easily understand.
I want to update two different table at a time through single controller/view.
_form.php (update form)
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'verse-form',
'enableAjaxValidation'=>true,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'topic_id'); ?>
<?php echo $form->textField($model,'topic_id', $model->topic_id); ?>
<?php echo $form->error($model,'topic_id'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'sorah_id'); ?>
<?php echo $form->textField($model,'sorah_id', $model->topic_id); ?>
<?php echo $form->error($model,'sorah_id'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'verse_text'); ?>
<?php echo $form->textArea($model,'verse_text',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model,'verse_text'); ?>
</div>
<?php
$trans = array();
foreach($model->verseTranslations as $p)
{
$trans[$p->id] = $p->translation_text;
}
?>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
I have an array in my _form.php file.
<?php
$trans = array();
foreach($model->verseTranslations as $p)
{
$trans[$p->id] = $p->translation_text;
}
?>
if i write print_r($trans); Its output like this.
Array ( [3] => In the name of ALLAH, most Gracious, most Compassionate. [4] => شروع الله کا نام لے کر جو بڑا مہربان نہایت رحم والا ہے [5] => En el nombre de Alá, el Compasivo, el Misericordioso )
Now I want to assign this variable i.e. $trans to $model in _form.php file of yii framework, so that i easily access it on controller and then easily submit it to the separate table.
I also want to use it in textArea.
Hope you understand my question.
Any help will be appreciated.
Thanks.
instead of performing this task in view file , you should do it in the controller like
public function actionCreate()
{
$model=new MODELNAME;
// your rest of code
$trans = array();
foreach($model->verseTranslations as $p)
{
$trans[$p->id] = $p->translation_text;
}
// and then you can send this variable to the view by rendering the view file
$this->render('create',array('model'=>$model,'trans'=>$trans));
}
You can not send an array from view to controller, but there is a way (No Professional Way) to send:
put it in a session in your view (_form):
<?php $_SESSION["t"]=$trans;?>
and catch it in controller and then destroy session.
$trans=$_SESSION["t"];
it is better to do such operations in controller itself, instead of doing it in view and pass it to controller!
Add new property on your model like this.
class YOUR_MODEL_WITH_TRANS extends ParentModel
{
public $trans;
---
}
Go to your view file and assign it easily like this.
$model->trans=$trans;
Related
I am developing this website that requires me to combine two models in one view where they have one to many relationship between them. The models name is Home and Image meaning Home has many Images but Image only has one Home.
I have manged to combine The view together but the problem that i encountering is to get all of the images. For example i have 6 images i want to display them or if i have 5 images i want to display them.
Home Controller UpdateMethod
public function actionUpdate($id)
{
$home=$this->loadModel($id);
$image=Image::model()->findByAttributes(array('homeId'=>$home->id));
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Home'],$_POST['Image'])){
$home->attributes=$_POST['Home'];
$image->attributes=$_POST['Image'];
$valid=$home->validate();
$valid=$image->validate() && $valid;
if($valid){
if($home->save()){
$image->save();
}
}
}
$this->render('update',array(
'home'=>$home,
'image'=>$image,
));
}
My _form.php to join them together
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'home-form',
// Please note: When you enable ajax validation, make sure the corresponding
// controller action is handling ajax validation correctly.
// There is a call to performAjaxValidation() commented in generated controller code.
// See class documentation of CActiveForm for details on this.
'enableAjaxValidation'=>false,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($home); ?>
<div class="row">
<?php echo $form->labelEx($image,'imageUrl'); ?>
<?php echo $form->textField($image,'imageUrl',array('size'=>60,'maxlength'=>100)); ?>
<?php echo $form->error($image,'imageUrl'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($home,'recentEvents'); ?>
<?php echo $form->textField($home,'recentEvents',array('size'=>60,'maxlength'=>100)); ?>
<?php echo $form->error($home,'recentEvents'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($home,'introduction'); ?>
<?php echo $form->textArea($home,'introduction',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($home,'introduction'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($home->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
Update I had FindByattribues instead of FindAllByAttribues in the model so now it is returning an array. Now how to process that array in the view?
Okay i figured it out by myself posting this to maybe help someone who needs it. I the view i did the following.
<?php
foreach($image as $image){
?>
<div class="row">
<?php echo $form->labelEx($image,'imageUrl'); ?>
<?php echo $form->textField($image,'imageUrl',array('size'=>60,'maxlength'=>100)); ?>
<?php echo $form->error($image,'imageUrl'); ?>
</div>
<?php
}
?>
i am creating yii application first time, i have used following code to create dropdownlist in my view
echo $form->dropDownList($model,'CodeLookupId',Forms::model()->findAll());
it show me error
include(Forms.php): failed to open stream: No such file or directory
C:\wamp\www\LearningYii\protected\views\codelookup_form.php(35):
<?php echo $form->textField($model,'ShortDesc',array('size'=>50,'maxlength'=>50)); ?>
<?php echo $form->error($model,'ShortDesc'); ?>
</div>
<div class="row">
<?php echo $form->dropDownList($model,'CodeLookupId',Forms::model()->findAll()); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
$opts = CHtml::listData(Codelookup::model()->findAll(),'CodeLookupId','CodeDesc');
echo $form->dropDownList($model,'ParentCodeLookupId',$opts,array('empty'=>''));
This code is working
use CHtml::listData to convert the db object to list data:
Here ID , NAME is your table values which should be used in option value and option text.
<?php
$opts = CHtml::listData(Forms::model()->findAll(),'CodeLookupId','CodeLookupId');
//to check list
print_r($opts);
echo $form->dropDownList($model,'CodeLookupId',$opts);
?>
try hope this will help..
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php
$records = loaddataform::model()->findAll();
$list = CHtml::listData($records, 'id', 'username');
echo CHtml::dropDownList('loaddataform', $model,
CHtml::listData($records,
'a_id', 'a_name'),
array('empty' => '(Select a name)'));
?>
</div>
and in controller
public function actionloaddata()
{
$model = new loaddataform;
$models = loaddataform::model()->findAll(array('order' => 'a_name'));
$list = CHtml::listData($models, 'a_id', 'a_name');
$this->render('loaddata',array('model'=>$model));
}
This works correctly..it retrives name from database.
I know that usually you would just use the integrated CRUD delete button that is in admin however for my purposes I am requiring an actual page for delete that just has the id in a field and a submit button but so far it just produces the error view so any assistance is appreciated. I have tried to create it the same as my create and update pages are set up, please see the code below:
The link to the delete page:
<?php echo CHtml::link('Delete Article', array('delete', 'id'=>$pageid)); ?>
The link it produces:
http://local/..../Yii/news/index.php/delete?id=3
The controller:
public function actionDelete($id)
{
$model=$this->loadModel($id);
if(isset($_POST['news_model']))
{
$model->attributes=$_POST['news_model'];
if($model->save())
$this->redirect('index');
}
$this->render(array('delete', array(
'model'=>$model,
));
}
Delete.php:
<h2>Delete a news item</h2>
<?php echo $this->renderPartial('_form2', array('model'=>$model)); ?>
_form2.php
<?php echo $form->errorSummary($model); ?>
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'news-model-form',
'enableAjaxValidation'=>false,
)); ?>
<div class="form">
<div class="row">
<?php echo $form->labelEx($model,'id'); ?><br>
<?php echo $form->textField($model,'id',array('size'=>50,'maxlength'=>128)); ?>
<?php echo $form->error($model,'id'); ?>
</div><br>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Delete a news item'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
Thanks in advance for any help given.
You got an error in your php synax in _form2.php
<?php echo CHtml::submitButton($model->isNewRecord ? 'Delete a news item'); ?>
more like
<?php echo CHtml::submitButton($model->isNewRecord ? 'Delete a news item':'Delete an old item'); ?>
See the Ternary Operator in PHP: Comparison Operators
... yet I don't se the point in that sentence, to me it would seem a little bit more like:
<?php if (!$model->isNewRecord) echo CHtml::submitButton("Delete Record"); ?>
... but the record is guaranteed to not be new when it is loaded by $model=$this->loadModel($id);
Also, In Delete.php
<?php echo $this->renderPartial('_form2', array('model'=>$model)); ?>
would be more like
<?php echo $this->renderPartial('_form2', array('model'=>$model), true); ?>
or
<?php $this->renderPartial('_form2', array('model'=>$model)); ?>
Seel the documentation renderPartial(), specially pay attention to its return value its third argument. Turns out that you're actually echoing NULL. which explains why there is no display.
I am doing a small application in Yii Framework for that my database is something like this
=== Invoices ===
id (PK)
customer_id
invoice_title
order_no
invoice_issue_date
due_date
description
=== Customers ===
id (PK)
email_address
customer_name
address
city
state
postal_code
description
I have rendered the Customer model in Invoice model so that I can enter all the values for both models in a single Invoice form.But there is one problem,let us assume that I have a customer name xyz which I had saved before.Now when I am going to again fill the Customer name with xyz,it should show all the fields of both models like invoice_title,order_no,invoice_issue_date,due_date,description,email_address,customer_name,address etc. in that input fields of the form so that I don't have to re-enter all the fields again.So how this can be achive in Yii framework.Any help and suggestions will be highly appreciable.More clarification on codes that I have done can be shared if needed.
Please help me out.I am totally stuck here.
To do this as everyone has already mentioned you need ajax, and some javascript. The logic is something like this:
When a value is selected in the dropdown for customer name, trigger an ajax call to retrieve the information about that user. This can be easily done with the ajax option, which is available as an additional htmlOption for some html element helpers in CHtml, as part of clientChange.
echo $form->dropDownList($model,'customer_name',CHtml::listData(Customers::model()->findAll(),'id','customer_name'),
array(// htmlOptions
'ajax'=>array(// special htmlOption through clientChange, for ajax
'type'=>'GET',
'url'=>$this->createUrl('controllername/customerdetails'),// action that will generate the data
'data'=>'js:"id="+$(this).val()',// this is the data that we are sending to the action in the controller
'dataType'=>'json',// type of data we expect back from the server
'success'=>'js:updateFields'// a javascript function that will execute when the request completes successfully
)
)
);
The documentation for the above options for ajax can be seen in jquery's ajax documentation.
Then in the server side find the particular customer, and send a response to the browser. Example:
// in the controllername code an action that will return the values as json
public function actionCustomerdetails($id){
$var=Customers::model()->findByPk($id);
echo CJSON::encode($var);
}
When you receive the server response populate the respective fields. This can be done in the success function callback for ajax, in the above code it was updateFields:
Yii::app()->clientScript->registerScript('update','
function updateFields(data, textStatus, jqXHR){
// select each input field by id, and update its value
$("#Customers_postal_code").val(data.postal_code);
$("#Customers_city").val(data.city);
$("#Customers_address").val(data.address);
// similarly update the fields for the other inputs
}
');
Notes:
Your customer can have many invoices, so the question will be which invoice to select given a customer name. That's something you'll have to handle, i think my answer has enough code to get you going.
To know the input field ids, you can simply check the generated html.
You could do this in two stages, so that:
When the view is initially displayed, the customer is asked for their email address or customer_name.
The Controller Action that the form is submitted to then retrieves data from the Customer model for the submitted email address or customer_name (I'll use email_address in my example below). Once retrieved, you can display your Single Invoice Form View with the data pre-populated for the customer if available.
This concept could then be implemented as follows:
<?php
// file: controllers/InvoiceController.php
class InvoiceController extends CController
{
// ... other controller functions
public function actionCreate($step = null)
{
$invoice = new Invoice;
$customer = new Customer;
# Form has been submitted:
if ( isset($_POST['Customer']) )
{
# The submitted form was Step 1:
if ( $step == 1 )
{
# make sure the submitted email address is valid
$customer->setAttributes($_POST['Customer']);
if ( $customer->validate(array('email_address')) )
{
# retrieve the customer by email_address
$customer = Customer::model()->findByAttributes(array('email_address' => $_POST['Customer']['email_address']));
}
$this->render('createstep2', array('invoice' => $invoice, 'customer' => $customer));
}
# The submitted form was Step 2:
elseif ( $step == 2 )
{
$income->setAttributes($_POST['Invoice']);
$customer->setAttributes($_POST['Customer']);
# save the data
if ( $customer->save() )
{
$invoice->customer_id = $customer->id;
if ( $invoice->save() )
{
$this->redirect(array('view', 'id' => $invoice->id));
}
}
# display any errors
$this->render('createstep2', array('invoice' => $invoice, 'customer' => $customer));
}
}
$this->render('createstep1', array('invoice' => $invoice, 'customer' => $customer));
}
// ... other controller functions
}
?>
You could split that to two separate Controller Actions if you wish.
For Step 1 View, you could then have the following:
<!-- file: views/invoice/createstep1.php -->
<h1>Create Invoice: Step 1</h1>
<div class="form">
<?php
$form = $this->beginWidget('CActiveForm', array(
'id'=>'invoice-form',
'enableAjaxValidation'=>false,
'action'=>array('invoice/create','step' => 1)
));
?>
<?php echo $form->errorSummary($customer); ?>
<div class="row">
<?php echo $form->labelEx($customer,'email_address'); ?>
<?php echo $form->textField($customer,'email_address', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'email_address'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Next'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
Step 2 view, you could then look like what you already have. Maybe something like:
<!-- file: views/invoice/createstep2.php -->
<h1>Create Invoice: Step 2</h1>
<div class="form">
<?php
$form = $this->beginWidget('CActiveForm', array(
'id'=>'invoice-form',
'enableAjaxValidation'=>false,
'action'=>array('invoice/create','step' => 2)
));
?>
<?php echo $form->errorSummary($invoce); ?>
<?php echo $form->errorSummary($customer); ?>
<h2>Customer Details</h2>
<div class="row">
<?php echo $form->labelEx($customer,'email_address'); ?>
<?php echo $form->textField($customer,'email_address', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'email_address'); ?>
</div>
<!-- If the customer already exists, these field should be pre-populated: -->
<div class="row">
<?php echo $form->labelEx($customer,'customer_name'); ?>
<?php echo $form->textField($customer,'customer_name', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'customer_name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($customer,'address'); ?>
<?php echo $form->textField($customer,'address', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'address'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($customer,'city'); ?>
<?php echo $form->textField($customer,'city', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'city'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($customer,'state'); ?>
<?php echo $form->textField($customer,'state', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'state'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($customer,'postal_code'); ?>
<?php echo $form->textField($customer,'postal_code', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'postal_code'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($customer,'description'); ?>
<?php echo $form->textField($customer,'description', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($customer,'description'); ?>
</div>
<h2>Order Details</h2>
<div class="row">
<?php echo $form->labelEx($invoice,'invoice_title'); ?>
<?php echo $form->textField($invoice,'invoice_title', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($invoice,'invoice_title'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($invoice,'order_no'); ?>
<?php echo $form->textField($invoice,'order_no', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($invoice,'order_no'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($invoice,'invoice_issue_date'); ?>
<?php $form->widget('zii.widgets.jui.CJuiDatePicker', array(
'model' => $invoice,
'attribute' => 'invoice_issue_date',
'value' => $invoice->invoice_issue_date,
'options' => array(
'showButtonPanel' => false,
'changeYear' => true,
'dateFormat' => 'yy-mm-dd',
),
)); ?>
<?php echo $form->error($invoice,'invoice_issue_date'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($invoice,'due_date'); ?>
<?php $form->widget('zii.widgets.jui.CJuiDatePicker', array(
'model' => $invoice,
'attribute' => 'due_date',
'value' => $invoice->due_date,
'options' => array(
'showButtonPanel' => false,
'changeYear' => true,
'dateFormat' => 'yy-mm-dd',
),
)); ?>
<?php echo $form->error($invoice,'due_date'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($invoice,'description'); ?>
<?php echo $form->textField($invoice,'description', array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($invoice,'description'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Create'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
Have you checked the Yii Autocomplete widget? And you wouldn't have to worry about AJAX implementation. It does it for you.
Yii Framework: CJui AutoComplete
A more customized autocomplete solution in this link.
Yii Framework: custom-autocomplete-display-and-value-submission
I tried to bring the comment form in the post view list where user can put a comment .
my code which I am write for the above problem ...
<h5>Add your Comment</h5>
<?php if(Yii::app()->user->hasFlash('commentSubmitted')): ?>
<div class="flash-success">
<?php echo Yii::app()->user->getFlash('commentSubmitted'); ?>
</div>
<?php else: ?>
<?php $this->renderPartial('/comment/_form',array(
'model'=>$comment
)); ?>
<?php endif; ?>
"The _form contain....."
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'comment-form',
'enableAjaxValidation'=>true,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'content'); ?>
<?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model,'content'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'author'); ?>
<?php echo $form->textField($model,'author',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,'author'); ?>
</div>
It gives the error "Undefined variable: comment "
You need to define $comment. You are trying to pass a model to the form. This is usually a model of a database table. It looks like you are using active form. That means you are using the Active Record model in Yii. You should have a model that covers your comment table. If you need to know how to create a model you can find out how to use Gii here.
If you already have a comment model then you just need to define the model. Something like:
$comment = new Comment();
$this->renderPartial('/comment/_form',array('model'=>$comment));
It looks like this is a view that sometimes calls another view. You could define the $comment variable in the controller that calls the original view. You would just have to pass the comment variable into the original view as well as the second one.
Without knowing exactly where the error occurs, it seems to me that the most logical location is in this snippet:
<?php $this->renderPartial('/comment/_form',array(
'model'=>$comment
)); ?>
The solution would then probably be to replace $comment by 'Comment' (or something similar, I'm not really familiar with Yii).