Cakephp Form with Selection of other Model - php

In Cakephp I have a model called Category and I have another model called Page. Now I connected the Page with $belongsTo to the Category model.
Now I have a form where I can create a new Page:
<?php echo $this->Form->create('Page', array('action' => 'create')); ?>
<?php echo $this->Form->input('title'); ?>
<?php echo $this->Form->input('text'); ?>
<?php echo $this->Form->end('Create new Page'); ?>
Now I want to add the possibility to select the category in the form. I think the solution is simple but I didn't found anything helpful so far...

in your form add this code
echo $this->Form->input('category_id');
now go to your Page controller, inside the appropriate action method, you add this code
$categories = $this->Page->Category->find('list');
$this->set(compact('categories'));

Related

How to send the request through POST and how to access attributes of the model?

I am a bit new to the Yii Framework. I am making a product selling website, which has 3 basic models
1. Users model containing the primary key id
2. Products model containing the primary key id
3. Orders model which is basically a mapping between the products and orders. It contains the fields product_id and user_id as foreign keys.
I have made a page where all the products are populated and the logged in user can click on a button on product box to order a particular product.
the code of the link is like this
<?php echo CHtml::link('Order Now',array('order',
'product_id'=>$model->id,
'user_id'=>Yii::app()->user->id)); ?>
(Q1) This is sending a GET request but I want to sent the details as post request. How to do this?
My default controller is the site controller. I have made an actionOrder method in this controller.
The code is:
if(Yii::app()->user->isGuest){
$this->redirect('login');
}else{
$model=new Orders;
if(isset($_POST['products_id']))
{
$model->attributes->products_id=$_POST['product_id'];
$model->attributes->users_id=Yii::app()->user->id;
if($model->save())
$this->redirect(array('index'));
}
$this->render('index');
}
But this code is showing bunch of errors. Also, (Q2) how can I put both products_id and users_id in a single array Orders so that I just have to write $_POST['orders']
Also, (Q3) how can I display a flash message after the save is successful?
Kindly help me to solve my 3 problems and sorry if you feel that the questions are too stupid.
Q1: If you want to use POST request, you're going to have to use a form of sorts, in this case the CActiveForm.
Controller:
public function actionOrder()
{
if(Yii::app()->user->isGuest)
$this->redirect('login');
else
{
$model=new Orders;
if(isset($_POST['Orders']))
{
$model->product_id=$_POST['Orders']['products_id'];
$model->users_id = Yii::app()->user->id;
if($model->save())
{
// Q3: set the flashmessage
Yii::app()->user->setFlash('ordered','The product has been ordered!');
$this->redirect(array('index'));
}
}
$this->render('index', array('model'=>$model)); //send the orders model to the view
}
}
View:
<!-- Q3: show the flash message if it's set -->
<?php if (Yii::app()->user->hasFlash('ordered')): ?>
<?php echo Yii::app()->user->getFlash('ordered'); ?>
<?php endif ?>
...
<?php $form=$this->beginWidget('CActiveForm', array('id'=>'order-form')); ?>
<?php echo $form->hiddenField($model,'products_id',array('value'=>$product->id)); ?> // please note the change of variable name
<?php echo CHtml::submitButton('Order Now'); ?>
<?php $this->endWidget(); ?>
Please note that I have changed the name of the product model variable $model to $product, because we will be using $model for the Orders model for the form.
Q2: In this case I set the users_id value in the controller, so $_POST['Orders'] only contains the value for products_id. In yii you can also mass assign your attributes with:
$model->attributes = $_POST['Orders']
Which basicly means $_POST['Orders'] is already an associative array containing the attribute names and values that are in your form.
Q3: The code shows you how to set and show a flash message after an order is succesfull.
First you have to declare forms send method, if you're using bootsrap it'll be like mine:
<?php $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'action' => Yii::app()->createUrl($this->route),
'method' => 'post',
'id' => 'activity_timeRpt',
));
?>
Second if you want to send custom inputs, you have to specify, otherwise it'll be like
i'll be back to finish this
For your questions 1 and 2 I'd recomend you to use a CActiveForm class. For example
<?php $form = $this->beginWidget('CActiveForm', array(
'action' => 'you_action_here'
'method'=>'post' // this is optinal parameter, as 'post' is default value
)); ?>
<?php echo $form->textField($model,'product_id'); ?>
<?php echo $form->hiddenField($model,'user_id', array('value'=>Yii::app()->user->id)); ?>
<?php $this->endWidget(); ?>
where $model is instance of Orders class, passed by variables thru controller, or set in view file. After that you can use it in way you wanted $model->attributes = $_POST['orders'] in your action method.
For flash message you can use Yii->app()->user->setFlash('orderStatus', 'Successful'), before redirect( or render ) in your actionOrder. To show it:
<?php if(Yii::app()->user->hasFlash('orderStatus')):?>
<div class="info">
<?php echo Yii::app()->user->getFlash('orderStatus'); ?>
</div>
<?php endif; ?>

Cakephp none add action forms

I have an index action in one of my controllers.
In this index action i wish to create a "search" form that calls another action within my controller with a post request.
All the documentation i could find on form creation in cakephp is about creating new elements (i.e insert data into a database ) and not actually sending data to another action / function.
here is an example:
<?php echo $this->Form->create('Product'); ?>
<fieldset>
<legend><?php echo __('Søg Produkt'); ?></legend>
<?php
echo $this->Form->input('Search field');
?>
</fieldset>
<?php echo $this->Form->end(__('Søg')); ?>
How would i send the value of my search field to another action? (so it redirects to that action and sends data to it)
Did you try to read the documentation?
$this->Form->create('Product', array('url' => array('action' => 'search');

Insert rows in other tables on creation in yii

For the following database:
TABLES:
user: [id,username]
project: [id,name]
project_user_assignment: [user_id,project_id,role]
When a new project is being created I'd like to show a dropdown with the available users to manage the project and when saving it insert into project_user_assignment the row
[user_id,project_id,'manager']
I'm starter with yii and don't know where (class,method) I must do the insert and how to return an error if in the moment of the insert the query fails
To display a drop down list in the you can use the foliowing code:
<?php echo CHtml::dropDownList(null,
'type',
CHtml::listData(
User::model()->findAll(),
'id',
'username',
),
array('empty' => 'Select a manager from the list ... ', 'id'=>'manager_list')
);?>
to update the corresponding field of the project_user_assignment model use the following:
<?php
<div class="row">
<?php echo $form->labelEx($model,'user_id'); ?> // Here I assume you have the $model variable set to Project_user_assignemenet ... if not (which probably is the case since you are creating a new project, set a new $model2 variable in the controller and use $model2 instead of $model)
<?php echo $form->textArea($model,'user_id'); ?>
<?php echo $form->error($model,'user_id'); ?>
</div>
?>
<script>
$('#manager_list').on('change', function(e) {
$('#Project_user_assignemenet_user_id').val($(this).val()); // Here id maybe wrong! Check them.
return true;
});
</script>
and finally in the controller you just save the model.

How to convert to use the Yii CDataProvider on view?

I am trying to learn Yii, and have looked at Yii documentation, but still do not really get it. I still have no idea how to use the CDataProvider on the Controller and View to display all the blog posts available on the view. Can anyone please advise or give an example based on the following:
The actionIndex in my PostController:
public function actionIndex()
{
$posts = Post::model()->findAll();
$this->render('index', array('posts' => $posts));
));
The View, Index.php:
<div>
<?php foreach ($post as $post): ?>
<h2><?php echo $post['title']; ?></h2>
<?php echo CHtml::decode($post['content']); ?>
<?php endforeach; ?>
</div>
Instead of doing the above, can anyone please advise how to use the CDataProvider to generate instead?
Many thanks.
The best that i can suggest is using a CListView in your view, and a CActiveDataProvider in your controller. So your code becomes somewhat like this :
Controller:
public function actionIndex()
{
$dataProvider = new CActiveDataProvider('Post');
$this->render('index', array('dataProvider' => $dataProvider));
}
index.php:
<?php
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_post', // refers to the partial view named '_post'
// 'enablePagination'=>true
)
);
?>
_post.php: this file will display each post, and is passed as an attribute of the widget CListView(namely 'itemView'=>'_post') in your index.php view.
<div class="post_title">
<?php
// echo CHtml::encode($data->getAttributeLabel('title'));
echo CHtml::encode($data->title);
?>
</div>
<br/><hr/>
<div class="post_content">
<?php
// echo CHtml::encode($data->getAttributeLabel('content'));
echo CHtml::encode($data->content);
?>
</div>
Explanation
Basically in the index action of the controller we are creating a new CActiveDataProvider, that provides data of the Post model for our use, and we pass this dataprovider to the index view.In the index view we use a Zii widget CListView, which uses the dataProvider we passed as data to generate a list. Each data item will be rendered as coded in the itemView file we pass as an attribute to the widget. This itemView file will have access to an object of the Post model, in the $data variable.
Suggested Reading: Agile Web Application Development with Yii 1.1 and PHP 5
A very good book for Yii beginners, is listed in the Yii homepage.
Edit:As asked without CListView
index.php
<?php
$dataArray = $dataProvider->getData();
foreach ($dataArray as $data){
echo CHtml::encode($data->title);
echo CHtml::encode($data->content);
}
?>

How do I import a Model from another Model in CakePHP

Desc Model belongsTo Prod Model. I want that all Prod.Name will appear as checkboxes when adding a new desc, so that user will just click a Prod.Name when adding a new description for it. Like:
<?php
echo $form->create('Desc');
echo $form->checkBox(Prod.Name); // assuming this is the correct code.
echo $form->textArea('Desc.content');
echo $form->end('Save');
?>
I'm still not familiar with this framework, still messing with it.
Thanks!
So far this is what I did:
<select name='data[Desc][prod_id]' id='DescriptionProdId'>
<?php echo $form->create('Desc'); ?>
<?php foreach($opps as $opp): ?>
<option value="<?php $opp["Prod"]["id"] ?>">
<?php echo $opp["Prod"]["name"]; ?>
</option>
<?php endforeach; ?>
</select>
Instead of creating the element manually, you should use the FormHelper.
In your view:
<?php
echo $form->input('prod_id', array('options' => $opps));
?>
Cakephp will make the select input, using the $opps records as the options. You can also set other options other than the 'options' option. Check out:
http://book.cakephp.org/view/189/Automagic-Form-Elements
If you specify the view variable as prods in your controller action, then you do not need to specify the options key of the $options array. In the controller action:
$this->set('prods', $this->find('all'));

Categories