Yii RenderPartial not working - php

I am using renderParial() function to render views->subscriber->_form from views->layouts->main.php
Problem i am getting is I am failed to insert data using this. Gii generated CRUD is working perfectly but when i render _form and want to insert data in database it's not working.
Here is my code.
main.php
<div class="col-lg-6" style="text-align:right;">
<span>Subscribe Newsletter</span>
<div style="float:right;margin-left:10px;">
<?php
$model=new Subscription();
$this->renderPartial("/subscription/_form",array('model'=>$model));?>
</div>
and _form.php
<?php
/* #var $this SubscriptionController */
/* #var $model Subscription */
/* #var $form CActiveForm */
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'subscription-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,
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->textField($model,'email',array('size'=>30,'maxlength'=>30,'placeholder'=>'Email Address')); ?>
<?php echo $form->error($model,'email'); ?>
<?php echo CHtml::submitButton($model->isNewRecord ? 'Subscribe' : 'Save',array('class'=>'btn btn-xs btn-success subscribeBtn')); ?>
</div>
<?php $this->endWidget(); ?>
</div>

As adamS and Michiel have commented, if you want to put a form or data in your main.php layout file, you should use a widget.
To create a widget, you need to do the following:
1: Create a php file in your /protected/components/ dir, something like SubscriptionWidget.php
2: Create a dir views in your components dir
3: Create your view .php file in your /protected/components/views/, something like subscriptionWidget.php
4: Put the following code in your SubscriptionWidget.php file:
<?php
class SubscriptionWidget extends CWidget
{
public function init()
{
}
public function run()
{
$model = new SubscriptionForm;
if(isset($_POST['SubscriptionForm']))
{
// proces the data
}
$this->render('subscriptionWidget', array('model'=>$model));
}
}
?>
Your widget is done. All you need to do now is call it in your main.php layout file, like so:
<!doctype html>
<html lang="en">
...
<?php $this->widget('SubscriptionWidget'); ?>
...
</html>
Also, don't forget to put the form in your newly created view file.
Hope this helps.

Try adding one more slash
$this->renderPartial("//subscription/_form",array('model'=>$model));

Related

Yii: from a view, how do I found out where a variable came from?

In a Yii project passed to me, there's a function that creates (or shows?) a textbox when the button/link Comment is clicked. From there, the user can create Comments, which will be displayed in a row.
I'm trying to see if I can create an edit comment function, so I thought I could go about this by copying the Comment function - it'll show a textbox, and the user can input the new text in there. And instead of adding a new comment, it will edit the existing one.
But I hit a snag, as apparently the view.php makes use of a variable that I couldn't for the life of me figure out how to use in _comments.php - the file responsible for displaying the individual comments, afaik.
Here's the code for view.php:
</script>
<?php
$this->breadcrumbs=array('Forums'=>array('index'),$model->title,);
?>
<?php
if(Yii::app()->user->hasFlash('message')):
echo '<script>alert("'.Yii::app()->user->getFlash('message').'");</script>';
endif;
?>
<?php $starter = Persons::model()->findByAttributes(array('party_id'=>$model->party_id));?>
<div id="forum_main_box">
<div class="comment-icon-textbox">
<?php echo CHtml::ajaxLink('Comment',array('forum/callcommentform'),
array(
'update' => '#render_div'.$model->id,
'data'=>array('id'=>$model->id),
)); ?>
</div>
<?php endif; ?>
<div id="forum_comment_headerbox">
</div>
<div>
<?php
$this->widget('zii.widgets.CListView',
array(
'dataProvider'=>$dataProvider,
'itemView'=>'_comments',
'summaryText'=>'',
));
?>
<div id="render_div<?=$model->id?>" class="comment-form">
</div>
</div>
</div>
Of that code, below is the Comment link I spoke of:
<?php echo CHtml::ajaxLink('Comment',array('forum/callcommentform'),
array(
'update' => '#render_div'.$model->id,
'data'=>array('id'=>$model->id),
)); ?>
<?php } ?>
This block displays the list of comments, and what (I assume to be) the space where the textbox will pop up when the above Comment is clicked:
<?php
$this->widget('zii.widgets.CListView',
array(
'dataProvider'=>$dataProvider,
'itemView'=>'_comments',
'summaryText'=>'',
));
?>
<div id="render_div<?=$model->id?>" class="comment-form">
</div>
Notice that both makes use of $model. It first appeared in the code as $model->title.
And here's a shortened version of the _comments.php, which is used for the comment rows and the comment box.
<?php $comment = $data; ?>
<div class="other-member-comment-box">
<?php $person=Persons::model()->findByAttributes(array('party_id'=>$comment->party_id)); ?>
<?php
$country=Lookup_codes::model()->findByAttributes(array('id'=>$person->country));
$location = empty($country) ? '' : ' - '.$country->name;
// $model->title;
?>
<?php if (Yii::app()->user->id == $person->party_id || Yii::app()->partyroles->isAdmin()) {
?>
<p class="admin-commands">
<?php echo CHtml::link(CHtml::encode('Edit'),array('forum/editcomment','reply'=>$data->id,'topic'=>$data->content_id)); ?>
<?php echo CHtml::ajaxLink('EditTestComment',array('forum/callcommentform'),array('update' => '#render_div'.$model->id,'data'=>array('id'=>$model->content_id),)); ?>
<?php echo CHtml::link(CHtml::encode('Delete'),array('forum/delete','reply'=>$data->id,'topic'=>$data->content_id),array('confirm'=>'Are you sure you want to delete this item?')); ?>
<div id="render_div<?=$model->id?>" class="comment-form">
</div>
</p>
<?php } ?>
</div>
Under <p class="admin-commands">, there's a EditTestComment link which is a straight up copy of the Comment code from the view.php. This doesn't work, of course, because of this:
2016/04/07 10:24:03 [error] [php] Undefined variable: model
Where'd $model come from in view.php? Because putting in the same line ($model->title) anywhere in _comments.php just breaks it further.
EDIT: Here's the CallComment part of the controller:
public function actionCallCommentForm($id='')
{
$topic=Forum::model()->findByPk($id);
$this->renderPartial('_commentform', array(
'forum'=>$topic,
'model'=>new Comment,
//'view'=>array('view','id'=>$id),
'view'=>'view',
));
}
$model variable is coming from your controller initially. It is an instance of a Comment class which gets passed to the view via $this->render('view', array('model'=>$whatever)). This line will make $whatever available in the forum/view.php file under the name of $model. Now since you are dealing with partial views you have to track it because it is possible that the same $model variable will be passed to another partial view with $this->renderPartial('_comment', array('whatever'=>$model)) and now this will be accessible in partial view as $whatever.

Yii Submit Form in View page

I just started working with yii and I stumbled upon a problem.
I have a table called "users" and a table called "messages".
I basically want to have a page where I can view a user's details but also send him a message that would be saved in the message table.
I have a view called "user/view.php" which consists of:
<h1>View User #<?php echo $model->id; ?></h1>
<?php $this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'username',
'first_name',
'last_name',
),
)); ?>
<?php $message=new Message;
echo $this->renderPartial('_messagesend', array('model'=>$message)); ?>
the _messagesend form (created using gii) looks like:
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'message-_messagesend-form',
'enableAjaxValidation'=>false,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
//for the sake of simplicity lets just insert the id's manually for now
<div class="row">
<?php echo $form->labelEx($model,'idFrom'); ?>
<?php echo $form->textField($model,'idFrom'); ?>
<?php echo $form->error($model,'idFrom'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'idTo'); ?>
<?php echo $form->textField($model,'idTo'); ?>
<?php echo $form->error($model,'idTo'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'msg'); ?>
<?php echo $form->textField($model,'msg'); ?>
<?php echo $form->error($model,'msg'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Send'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
I have a simple view in my UserController to display the details info:
public function actionView($id)
{
$this->render('view',array(
'model'=>$this->loadModel($id)
));
}
And now I want to figure out how i can add the controller to save the message. After gii creation I get a code which I tried to use and modify a little bit:
public function actionMessagesend()
{
$model=new Message;
if(isset($_POST['Message']))
{
$model->attributes=$_POST['Message'];
if($model->save()){
$this->redirect(array('admin'));
}
}
$this->render('_messagesend',array('model'=>$model));
}
I tried to add this controller function in the UserController.php but it doesn't seem to work, I tried to add the same function to MessageController.php but it also doesn't seem to work. I tried to remove all the code and only add a redirect to show if the controllercode actually hits but it doesn't redirect (i tried it both in usercontroller and messagecontroller). So I have a feeling my code isn't reached. You guys have any idea what I'm missing here?
Maybe a little extra question: Is there a better suggestion to do what I want to do?
Thanks a lot!
Best regards,
WtFudgE
Your message sending action isn't reached because by default the CActiveForm submits to the current page, so you will have to add the message processing to the view action, or you will need to set the action property for your CActiveForm.
Here is the link to the property documentation: http://www.yiiframework.com/doc/api/1.1/CActiveForm#action-detail
So the form widget in the view should be something like:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'message-_messagesend-form',
'enableAjaxValidation'=>false,
'action' => array( '/message/messageSend' ), // change depending on your project
)); ?>
You can also achieve this by editing the submit button in the view page like this:
<?php echo CHtml::button('Send', array('submit' => array('message/messageSend')));?>

Using a controller plugin to extend the existing layout in zend framework

I have a layout file as follows:
<?php echo $this->doctype(); ?>
<html>
<head>
<?php echo $this->headTitle(); ?>
<?php echo $this->headLink(); ?>
</head>
<body>
<?php echo $this->layout()->content; ?>
</body>
</html>
I have a menu system which is written in another template
<p>
<div>
menu code goes here
</div>
<p>
<?php echo $this->actionContent; ?>
</p>
</p>
I wanted the action method's output should be placed in $this->actionContent and all of that should go to the layout.
Then I wrote a Controller plugin as follows:
class ZFExt_Controller_Plugin_Addmenu extends Zend_Controller_Plugin_Abstract
{
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$view = Zend_Controller_Front::getInstance()
->getParam('bootstrap')
->getResource('view');
if (false !== $request->getParam('menu'))
{
$response = $this->getResponse();
$content = $response->getBody(true);
$view->menuContent = $content['default'];
$updatedContent = $view->render('menu.phtml');
$response->setBody($updatedContent);
}
}
}
In the controller class
class IndexController extends Zend_Controller_Action {
public function indexAction() {
}
public function viewAction()
{
$this->getRequest()->setParam('menu', false);
}
}
So whichever action does not want the menu there we can pass a parameter 'menu' with value 'false'.
My question is: Is this the right way to do ?
First, I probably wouldn't render the menu from an action. I tend to think of actions as corresponding to HTTP requests, building full pages/responses, rather than just page fragments, for the waiting client. I would either have a separate class/component handle menu creation or just use Zend_Navigation.
Beyond that, if I understand correctly, you simply want each action to be able to enable/disable the menu portion of the layout, right?
So, how about simply setting a switch in the view that enables/disables the menu in the layout.
The layout looks like:
<?php echo $this->doctype(); ?>
<html>
<head>
<?php echo $this->headTitle(); ?>
<?php echo $this->headLink(); ?>
</head>
<body>
<?php if ($this->renderMenu): ?>
// render menu here
<?php endif; ?>
<?php echo $this->layout()->content; ?>
</body>
</html>
Then in your action, if you want to disable the menu rendering, you can set:
$this->view->renderMenu = false;
Probably also worthwhile to set a default value for the $view->renderMenu flag at some point in the request dispatch cycle - perhaps at bootstrap, or in a controller plugin, or in controller init().

Display two views at once and change url on change

I have a main view with a menu which helps me display another view. It's similar to this:
<div id="page">
<div id="menu">
Page1
Page2
</div>
<div id="content">
<!-- Page1 or Page2 are displayed here -->
</div>
</div>
I'm using php's Yii framework. Which makes me not to use <?php include("menuview.php"); ?>. So I'm looking for a different solution. I can do this with Ajax, but I would also like the link to change to mypage/controller/Page2. With Ajax I can only get it to this: mypage/controller/index#Page2
in main view, instead of include do
<?php echo $this->renderPartial('_page1', array('model'=>$model)); ?>
UPDATE:
protected/views/controller/page1.php and protected/views/controller/page2.php content at your liking
protected/views/layouts/custom.php:
<?php $this->beginContent('//layouts/main'); ?>
<div id="page">
<div id="menu">
<?php echo CHtml::ajaxLink('Page1', array('controller/page1'), array('update' => '#content')); ?>
<?php echo CHtml::ajaxLink('Page2', array('controller/page2'), array('update' => '#content')); ?>
</div>
<div id="content">
<?php echo $content; ?>
</div>
</div>
<?php $this->endContent(); ?>
protected/controllers/ControllerController.php:
class ControllerController extends Controller {
/**
* #var string the default layout for the views.
*/
public $layout = '//layouts/custom';
public function actionPage1() {
if (Yii::app()->request->isAjaxRequest)
$this->renderPartial('page1');
else
$this->render('page1');
}
public function actionPage2() {
if (Yii::app()->request->isAjaxRequest)
$this->renderPartial('page2');
else
$this->render('page2');
}
}
UPDATE2:
If you need the link in address bar to change too then your only option is to use regular link and not ajax <?php echo CHtml::link('Page1', array('controller/page1')); ?>
using ajax the preferred way is using hash like you mentioned.

Yii display and validation of fields not present in table

I am a newbie in Yii. I have created a page where user can change their password.
So in my changePassword view I have :
<div class="row">
<?php echo $form->labelEx($model,'oldpwd'); ?>
<?php echo $form->textField($model,'oldpwd'); ?>
<?php echo $form->error($model,'oldpwd'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'pwd'); ?>
<?php echo $form->textField($model,'pwd'); ?>
<?php echo $form->error($model,'pwd'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'pwd_repeat'); ?>
<?php echo $form->passwordField($model,'pwd_repeat'); ?>
<?php echo $form->error($model,'pwd_repeat'); ?>
</div>
Now obviously I am getting an error as only the field 'pwd' is in the table and thereby in the model. I am new to MVC frameworks and can use some help here. Thanks
Declare them in your model as property of model First..
public $old_pwd;
public $pwd;
public $pwd_repeat;
As you are asking model Labels of these attributes..define them in your attributeLabels function in model..
public function attributeLabels()
{
return array(
'old_pwd'=>'Old Passw....',
'.....same way for all those who are not already there..'
);
}
Declare them safe in rules if required...
add the following line to your model
public $old_pwd;
public $pwd_repeat;
we instruct Yii to use this field as virtual field instead of searching in database field

Categories