I am new in Yii. I need to create product module to save product data. In that i need to create two table products and product_image to save product data and multiple product images.
Product table
id, category_id, , title ,price, description
Product image table
id, product_id, image
I have created table as above and generated model and CRUD for product table. BUT when I goto add product page I am not getting image upload button. I am getting just product table field in add product page.
Should I created model for two table to get image upload button ?
How to insert data in multiple table in yii ?
thanks in advance.
UPDATES
ProductController :
public function actionCreate()
{
$model = new Products();
$productsImage = new ProductsImage();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'productsImage'=> $productsImage,
]);
}
}
My Add product form.php
<div class="products-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'category_id')->dropDownList(['0'=>'Select Parents Category']+
ArrayHelper::map(ProductCategory::find()->all(),'id','category_name')
) ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'price')->textInput() ?>
<?= $form->field($model, 'description')->textarea(['rows' => 6]) ?>
<?= $form->field($productsImage,'image')->fileInput() ?> //here i am getting error of undefined variable $productsImage
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
In Your products table there is no field for image so you are not getting upload image button. Here is many way you can do this. 1 ) You can create public variable for image button in you products model. suppose you have create public variable in products model like public $productImage and in view file in you can create upload button for image using this code.
`echo $form->fileField($model,'productImage',array('class' => 'btn'));`
2) Second option if you want create productImage model then you need to pass that object from create action of product. suppose in your products controller in create action you can create object of productImages model like below.
$productImages = new productImages;
and you need to pass this model variable in create view like this way
$this->render('create',array(
'model'=>$model,
'productImages'=> $productImages,
));
Here suppose $model is your products model object. and in view file you can create image button like below code.
echo $form->fileField($productImages,'product_image',array('class' => 'btn'));
here 'product_image' is your column name of your product_image table. in controller create action you will get in post object using product_images post after that save data how you want i hope you will get idea what you need to do now. hope it helps you
Yii2 provides a way to handle this situation:
in your product controller:
public function actionCreate()
{
$product = new app\models\Product();
$productImages = new app\models\ProductImage();
if($product->load(Yii::$app->request->post()) && $productImages->load(Yii::$app->request->post()) && Model::validateMultiple([$product, $productImages])) {
// your other file processing code
$product->save();
$productImages->save();
// return/redirection statement
}else {
return $this->render(['create', 'product' => $product, 'productImages' => $productImages]);
}
}
Related
Im new to Yii, and would appreciate any help.
I need to create a page with multiple choice poll. My models look like this:
PollQuestion:
id int
title varchar
PollAnswer
id char //one letter - answer option
title
question_id //FK pool_question(id)
PollResult
user_id int
question_id int //FK poll_question(id)
answers //will be stored like A,B,C
indicated_answer //alternaive answer specified by user
Sample question looks like:
What do you think about us?
(checkbox)A. Good
(checkbox)B.Bad
(checkbox)C.Other (indicate) (textbox goes here)
Im not sure if Im doing it right, my controller:
public function actionSurvey($user_id)
{
$model = [new PollResult];
foreach($model as $model_item){
$model_item->user_id= $user_id;
if ($model_item->load(Yii::$app->request->post())) {
//only one item received, why??
}
}
return $this->render('survey', ['model' => $model]);
}
View:
<?php $form = ActiveForm::begin(); ?>
<?php foreach(PollQuestion::find()->all() as $question) {?>
<?php foreach($model as $model_item) { ?>
<p><?=$question->title?></p>
<?= Html::activeHiddenInput($model_item , "user_id"); ?>
<?= $form->field($model_item, 'answers')->checkboxList(ArrayHelper::map($question->pollAnswers, 'id', 'title')?>
<?= $form->field($model_item, 'indicated_answer') ->textInput()?>
<?php } }?>
<div class="form-group">
<?= Html::submitButton(Yii::t('app', 'Send'), ['class' => 'btn btn-success' ]) ?> </div>
<?php ActiveForm::end(); ?>
The problem is that in controller i receive only one item in array. Im not sure what am I doing wrong.
My suggestion, you need an extra form model to do that.
You can see how to create form model on http://www.yiiframework.com/doc-2.0/guide-input-forms.html.
The form model you create at least has this attributes:
answers[]
indicated_answer[]
and you can save input from user to that attributes and save them into your ActiveRecord model.
It is correct that one model entry is returned. In your form, you are creating a single model and passing that to the form.
public function actionSurvey($user_id)
{
$model = [new PollResult];
// ...
return $this->render('survey', ['model' => $model]);
}
You can then expect a single model back.
Have a look at this related issue on how you can solve this.
Utilising Yii2.0 checkboxlist for Parent-child relation models
First of all i am working with yii2.0 framework.
Right, i have a gridview that pulls data from my database. It currently works and if i use any of the searches it will reload the page with the new data.
However i now have created some dropdownlist categories. Basically there are three tiers of categories , so a main category subcategory and child category. At the moment i have two ajax requests that will populate the sub and child category when the dropdownlist changes. (It populates the categories from my database).
Now i want the gridview to display the cases that are linked to the child categories. So when i choose my first category then choose my second and child category the gridview displays the content that relates to it.
At the moment my controller renders the searchModel + dataProvider for the grid view as seen below::
public function actionIndex()
{
$searchModel = new CaseSearch();
$allCategory = Category::find()->all();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'allCategory' => $allCategory
]);
}
and in my view it displays the data with this::
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
'case_id',
'name',
'judgement_date',
'year',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
How should i go about achieving this? should i create something _grid.php which i can then render from my view and send the ajax request there?
The simplest way to achieve this functionality is to wrap the GridView with built-in Pjax widget like so:
use yii\widgets\Pjax;
<?php Pjax::begin(); ?>
// Place GridView code here
<?php Pjax::end(); ?>
From the js you can trigger form submit like that:
$('.grid-view-selector').yiiGridView('applyFilter');
If pjax is attached, content will be replaced dynamically without page reload.
Official docs:
Pjax
I would probably will use GridView $filterSelector.
And add the selector for youre custom category dropDown.
After you will need add category attribute for youre SearchModel.
In final - wou will get the filter with youre custom field added to standart some
i've a little problem with yii 2. This is my case:
I manage two tables, Customer and Order, and any Order has a Customer. I've created the relational data and the normal view to create, update, view and delete data from DB. Now i would use the search model of customer in the Order's _form view (to create and update data) to select the customer and pull customer.id that i want to save in my order.id_customer.
With my solution i can see the gridview with customer search in the create view, but (with RadioColumn) it doesn't return customer.id and when i try to filter the data the form doesn't filter anything but it tries to submit my input in to the db.
The old "_form"'s code is on pastebin.
Any suggestion?
Thank you!
-----------------------UPDATE-----------------------------
After many hours of work i fixed my problem.
Now my gridview is out from activeform, where i copy the radio's returnament through a javascript function.
This is the code:
<script type="text/javascript">
var agente = document.getElementById('agente');
var radioSelAgente = document.getElementsByName('radioAgenteId');
function aggiungiAgente(){
for (var i = 0, length = radioSelAgente.length; i < length; i++) {
if (radioSelAgente[i].checked) {
document.getElementById('contrattoformativo-id_agente_iscritto').value=radioSelAgente[i].value;
alert(radioSelAgente[i].value);
break;
}
}
}
<form id="formAddAgente" onclick="aggiungiAgente()">
<?php
$agenteModel = new \backend\models\Agente();
$agenteSearchModel = new \backend\models\AgenteSearch();
$agenteDataProvider = $agenteSearchModel->search(Yii::$app->request->queryParams);
$agenteDataProvider->pagination->pageSize=5;
?>
<?php
echo \kartik\grid\GridView::widget([
'dataProvider' => $agenteDataProvider,
'filterModel' => $agenteSearchModel,
'id'=>'agente',
'columns' => [
[
'class' => '\kartik\grid\RadioColumn',
'width'=>'36px',
'name' => 'radioAgenteId',
'showClear' => false,
'radioOptions' => function($agenteModel, $key, $index, $column) {
return ['value' => $agenteModel->id];
},
],
'nome',
'cognome',
],
'export'=>false,
'pjax'=>true,
'pjaxSettings'=>[
'neverTimeout'=>true,
],
]);
?>
</form>
And in the active form i have:
<?= Html::activeHiddenInput($model, 'id_agente_iscritto') ;?>
Bye!
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; ?>
I am just newbie to the yii framework. Currently I have two tables
one for sales and other for stores
Sales table is looking like this
==============
sales
==============
id
store_id
store table is looking like this
==============
Stores
==============
id
store_name
store_location
Now in sales view form(_form.php) I have rendered both sales and stores.
In sales controller the code for action create is like this
public function actionCreate()
{
$model=new Sales;
$stores = new Stores;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Sales']$_POST['Stores']))
{
$model->attributes=$_POST['Sales'];
$stores->attributes = $_POST['Stores'];
$valid = $model->validate();
$valid = $stores->validate();
if($valid)
{
$stores->save(false);
$model->store_id = $stores->getPrimaryKey();
$model->save(false);
$this->redirect(array('view','id'=>$model->id));
}
}
$this->render('create',array(
'model'=>$model,
'stores' => $stores,
));
}
To get all the stores name in dropdown list I made my code like this
<div class="row">
<?php echo $form->labelEx($stores,'store_name'); ?>
<?php echo $form->dropDownList($stores,'store_name', CHtml::listData(Stores::model()->findAll(), 'store_name', 'store_name'), array('empty'=>'--Select--')) ?>
<?php echo $form->error($stores,'store_name'); ?>
</div>
But here I want the cjuiautocomplete field so that when someone will press any key then it will start to show the suggesions stores name. For that I just came through this link
and just like the docs I made the EAutoCompleteAction.php under protected/extension directory
Then I just made my controller code like this in sales controller
public function actions()
{
return array(
'aclist'=>array(
'class'=>'application.extensions.EAutoCompleteAction',
'model'=>'Stores', //My model's class name
'attribute'=>'store_name', //The attribute of the model i will search
),
);
}
and in view file of sales(_form.php) I made the code like this
<div class="row">
<?php echo $form->labelEx($stores,'store_name'); ?>
<?php
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'attribute'=>'store_name',
'model'=>$stores,
'sourceUrl'=>array('stores/store_name'),
'name'=>'store_name',
'options'=>array(
'minLength'=>'3',
),
'htmlOptions'=>array(
'size'=>45,
'maxlength'=>45,
),
)); ?>
After all when I am doing the search by keywords it is showing 404 error in console panel of firebug.
The requested search url in firebug was like this (ads was my search query in store name field)
http://localhost/WebApp/index.php?r=stores/store_name&term=ads
any one here for help?
You forgot to change action name from sample aclist into store_name:
public function actions()
{
return array(
'store_name'=>array( // << Array key is action name
'class'=>'application.extensions.EAutoCompleteAction',
'model'=>'Stores', //My model's class name
'attribute'=>'store_name', //The attribute of the model i will search
),
);
}