Getting unknown property: frontend\modules\printinvoice\models\Prodfin::productcode - yii2

I'm trying to print an invoice in yii2. There are two tables which I'm touching two tables. One is prodfin - where the totalamount is stored and prodsummary where the products and quantities are stored. Now I want to pass these to my view and print to pdf using mpdf. I am using prodfin as primary model and get prodsummary data attached to it. My main obstacle now is to pass prodsummary details i.e. - productcode, productname, quantity,rate, amount in place row by row. I'm attaching a sample with this.
What I'm trying to achieve -
My Controller Action
public function actionPrintinvoice($id) {
$model = $this->findModel($id);
$searchModel = new ProdfinSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$data = Prodfin::findOne($id);
$dataProvider = new ActiveDataProvider([
'query' => Prodsummary::find()->select(['productcode','productname','qty','rate','amount'])->where(['prfinid' => $id]),
'pagination' => [
'pageSize' => 20,
],
]);
$posts = $dataProvider->getModels();
$content = $this->renderPartial('_printInvoice', [
'model' => $model,
'dataProvider' => $dataProvider,
'searchModel' => $searchModel,
'data'=> $data,
]);
$pdf = new Pdf([
'mode'=> Pdf::MODE_UTF8,
'format'=> Pdf::FORMAT_A4,
'destination'=> Pdf::DEST_BROWSER,
//'destination' => Pdf::DEST_DOWNLOAD,
'cssFile' => '#vendor/kartik-v/yii2-mpdf/assets/kv-mpdf-bootstrap.min.css',
// any css to be embedded if required
'cssInline' => '.kv-heading-1{font-size:18px}',
// set mPDF properties on the fly
'options' => ['title' => 'Print Invoice'],
// call mPDF methods on the fly
'methods' => [
'SetHeader'=>['Private and Confidential'],
'SetFooter'=>['This Payslip is computer generated.'],
],
'content' => $content,
]);
return $pdf->render();
//return $this->render('_printSalarystatement', ['s_period' => $s_period]);
}
My view.php (partialview)
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
/* #var $this yii\web\View */
/* #var $model frontend\modules\printinvoice\models\Prodfin */
$this->title = $model->prfinslno;
$this->params['breadcrumbs'][] = ['label' => 'Prodfins', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="ps-details">
<div style="width:38%; float:left;border:1px solid black;">
<h3 style="margin-bottom:0;margin-bottom:0;margin-top:2;margin-left:2;"><strong><p class="text-left">M/S. My Company</p></strong></h3>
<h5 style="margin-bottom:0;margin-top:0;margin-left:2;"><p class="text-left">My details</p></h5>
<h5 style="margin-bottom:0;margin-top:0;margin-left:2;"><p class="text-left">My Address</p></h5>
</div>
<div style="width:61.25%; float:right;border:1px solid black;">
<table style="width:100%">
<tr>
<td>PAN No.</td>
<td>AGZPD/2365A</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>Invoice No.</td>
<td><?php echo $model['invoiceno'];?></td>
<td>Date : </td>
<td><?php echo $model['date'];?></td>
</tr>
<tr>
<td>Challan No.</td>
<td><?php echo $model['challanno'];?></td>
<td>Date : </td>
<td><?php echo $model['date'];?></td>
</tr>
<tr>
<td>Order No.</td>
<td><?php echo $model['orderno'];?></td>
<td>Date : </td>
<td><?php echo $model['date'];?></td>
</tr>
</table>
</div>
</div>
<div class="orient-details">
<div style="width:100%; float:center;border:1px solid black;">
<h3 style="margin-bottom:0;margin-top:2;margin-left:2;"><strong><p class="text-center">My Company</p></strong></h3>
<h5 style="margin-bottom:0;margin-top:0;margin-left:2;"><p class="text-center">A Division of My Company</p></h5>
<h5 style="margin-bottom:0;margin-top:0;margin-left:2;"><p class="text-center">My Address</p></h5>
</div>
</div>
<div class="product-details">
<?= DetailView::widget([
'model' => $model,
'attributes' => [
//'id',
'productcode',
'productname',
'qty',
'rate',
'amount:ntext'
//'ativo',
],
]) ?>
</div>
<div class="prodfin-view">
<!-- <h1><?= Html::encode($this->title) ?></h1> -->
<!-- <strong>Using display: inline-block; </strong><br>
<table style="border:1px solid black;border-collapse:collapse;width:100%" class="inlineTable">
<tr>
<td style="border-right: 1px solid";><font face="Calibri";size="72">M/S P.S. Enterprise</font></td>
<td>This One will contain the Invoice details</td>
</tr>
</table> -->
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'prfinslno',
'invoiceno',
'challanno',
'orderno',
'amount',
'date',
],
]) ?>
</div>
Please let me know how to set the gridview with the details in the middle in picture.
Model Prodfin -
<?php
namespace frontend\modules\printinvoice\models;
use Yii;
/**
* This is the model class for table "prodfin".
*
* #property string $prfinslno
* #property string $invoiceno
* #property string $challanno
* #property string $orderno
* #property string $amount
* #property string $date
*/
class Prodfin extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'prodfin';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['date'], 'safe'],
[['invoiceno', 'challanno', 'orderno', 'amount'], 'string', 'max' => 40],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'prfinslno' => 'Prfinslno',
'invoiceno' => 'Invoiceno',
'challanno' => 'Challanno',
'orderno' => 'Orderno',
'amount' => 'Amount',
'date' => 'Date',
];
}
}
Model Prodsummary
<?php
namespace frontend\modules\printinvoice\models;
use Yii;
/**
* This is the model class for table "prodsummary".
*
* #property string $prid
* #property string $productiondate
* #property string $invoiceno
* #property string $challanno
* #property string $orderno
* #property string $productcode
* #property string $productname
* #property string $unit
* #property string $qty
* #property string $rate
* #property string $amount
*/
class Prodsummary extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'prodsummary';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['productiondate'], 'safe'],
[['invoiceno', 'challanno', 'orderno'], 'string', 'max' => 40],
[['productcode', 'amount'], 'string', 'max' => 15],
[['productname'], 'string', 'max' => 80],
[['unit', 'qty', 'rate'], 'string', 'max' => 10],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'prid' => 'Prid',
'productiondate' => 'Productiondate',
'invoiceno' => 'Invoiceno',
'challanno' => 'Challanno',
'orderno' => 'Orderno',
'productcode' => 'Productcode',
'productname' => 'Productname',
'unit' => 'Unit',
'qty' => 'Qty',
'rate' => 'Rate',
'amount' => 'Amount',
];
}
}

You get the productcode using dataProvider based on Prodsummary
$dataProvider = new ActiveDataProvider([
'query' => Prodsummary::find()->select(['productcode','productname','qty','rate','amount'])->where(['prfinid' => $id]),
..
but you use the field productcode in a detailview using a $model .. the $model var don't contain the class Prodsummary but seems came from $model = $this->findModel($id);
<div class="product-details">
<?= DetailView::widget([
'model' => $model,
'attributes' => [
//'id',
'productcode',
'productname',
'qty',
'rate',
'amount:ntext'
//'ativo',
],
]) ?>
</div>
so you should pass the proper value for the detailview
You have passed the te view the $datProvider related to Prodsummary. A data provider return a collection of models but you want use these data in a widget that show only a single model.
So if you want show only the first model of dataProvider you shoudl use
<div class="product-details">
<?= DetailView::widget([
'model' => $dataProvider[0],
'attributes' => [
//'id',
'productcode',
'productname',
'qty',
'rate',
'amount:ntext'
//'ativo',
],
]) ?>
</div>
if you instead want show all the models in data provider then should use an iteration
foreach ($dataProvider as $key => $model ) {
echo DetailView::widget([
'model' => $model,
'attributes' => [
//'id',
'productcode',
'productname',
'qty',
'rate',
'amount:ntext'
//'ativo',
],
]) ;
}

Related

Can't delete selected image when update the form by using Yii kartik fileinput

I refer to this link https://github.com/jaradsee/faktharm/blob/master/controllers/PhotoLibraryController.php
to upload multiple images but when I try to delete the selected image in update form it showing me these error
(image1)
(image2)
For image 2, why the url link always give products%252Fdeletefile-ajax (give number 25)
Below is my code, please help me to check what's goes wrong, thank you!
Uploads.php
class Uploads extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'uploads';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['file_name'], 'required'],
[['upload_id'], 'integer'],
[['create_date'], 'safe'],
[['ref'], 'string', 'max' => 100],
[['file_name', 'real_filename'], 'string', 'max' => 150],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'upload_id' => 'Upload ID',
'ref' => 'Ref',
'file_name' => 'File Name',
'real_filename' => 'Real Filename',
'create_date' => 'Create Date',
];
}
}
Products.php
class Products extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
//public $file;
const UPLOAD_FOLDER='products';
public static function tableName()
{
return 'products';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['productName', 'productDescription', 'productPrice', 'categoryId', 'brandId', 'productStatus'], 'required'],
[['productDescription', 'productStatus'], 'string'],
[['productPrice'], 'number'],
[['categoryId', 'brandId'], 'integer'],
[['productName','ref'], 'string', 'max' => 100],
[['brandId'], 'exist', 'skipOnError' => true, 'targetClass' => Brands::className(), 'targetAttribute' => ['brandId' => 'brandId']],
[['categoryId'], 'exist', 'skipOnError' => true, 'targetClass' => Categorys::className(), 'targetAttribute' => ['categoryId' => 'categoryId']],
[['ref'],'unique']
// ['productImage', 'file','maxFiles'=>5],
//[['file'],'productImage']
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'productId' => 'Product ID',
'productName' => 'Product Name',
'productDescription' => 'Product Description',
'productPrice' => 'Product Price',
'ref' => 'Product Image',
'categoryId' => 'Category',
'brandId' => 'Brand',
'productStatus' => 'Product Status',
];
}
/**
* Gets query for [[Brand]].
*
* #return \yii\db\ActiveQuery
*/
public function getBrand()
{
return $this->hasOne(Brands::className(), ['brandId' => 'brandId']);
}
/**
* Gets query for [[Category]].
*
* #return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(Categorys::className(), ['categoryId' => 'categoryId']);
}
public function getImages()
{
return $this->hasMany(Images::className(), ['productId' => 'productId']);
}
public static function getUploadPath(){
return Yii::getAlias('#webroot').'/'.self::UPLOAD_FOLDER.'/';
}
public static function getUploadUrl(){
return Url::base(true).'/'.self::UPLOAD_FOLDER.'/';
}
public function getThumbnails($ref,$event_name){
$uploadFiles = Uploads::find()->where(['ref'=>$ref])->all();
$preview = [];
foreach ($uploadFiles as $file) {
$preview[] = [
'url'=>self::getUploadUrl(true).$ref.'/'.$file->real_filename,
'src'=>self::getUploadUrl(true).$ref.'/thumbnail/'.$file->real_filename,
'options' => ['title' => $event_name]
];
}
return $preview;
}
}
ProductsController.php
namespace backend\controllers;
use Yii;
use backend\models\Products;
use backend\models\Uploads;
use backend\models\ProductsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\helpers\Json;
use yii\widgets\ActiveForm;
use yii\web\UploadedFile;
use yii\helpers\Url;
use yii\helpers\html;
use yii\helpers\BaseFileHelper;
use yii\helpers\ArrayHelper;
/**
* ProductsController implements the CRUD actions for Products model.
*/
class ProductsController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
// 'access' => [
// 'class' => AccessControl::className(),
// 'rules' => [
// [
// 'actions' => ['view','update','_form','index','_search','create','uploadAjax','createDir'],
// 'allow' => true,
// 'roles' => ['admin'],
// ],
// ],
// ],
];
}
/**
* Lists all Products models.
* #return mixed
*/
public function actionIndex($pageSize = 10)
{
$searchModel = new ProductsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $pageSize);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'pageSize' => $pageSize,
]);
}
/**
* Displays a single Products model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Products model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
/*public function actionCreate()
{
$model = new Products();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$model->imageFiles = UploadedFile::getInstances($model, 'productImage');
return $this->redirect(['view', 'id' => $model->productId]);
}
return $this->render('create', [
'model' => $model,
]);
}*/
public function actionCreate()
{
$model = new Products();
if ($model->load(Yii::$app->request->post())) {
$this->Uploads(false);
if($model->save()){
return $this->redirect(['view', 'id' => $model->productId]);
}
}
else{
$model->ref = substr(Yii::$app->getSecurity()->generateRandomString(),10);
}
return $this->render('create', [
'model' => $model,
]);
}
/**
* Updates an existing Products model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
list($initialPreview,$initialPreviewConfig) = $this->getInitialPreview($model->ref);
if ($model->load(Yii::$app->request->post())) {
$this->Uploads(false);
if($model->save()){
return $this->redirect(['view', 'id' => $model->productId]);
}
}
return $this->render('update', [
'model' => $model,
'initialPreview'=>$initialPreview,
'initialPreviewConfig'=>$initialPreviewConfig
]);
}
/**
* Deletes an existing Products model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
//$model = new Products();
//$this->findModel($id)->delete();
$model->$this->findModel($id);
$this->removeUploadDir($model->ref);
Uploads::deleteAll(['ref'=>$model->ref]);
$model->delete();
return $this->redirect(['index']);
}
/**
* Finds the Products model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Products the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Products::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
/*|*********************************************************************************|
|================================ Upload Ajax ====================================|
|*********************************************************************************|*/
public function actionUploadAjax(){
$this->Uploads(true);
}
private function CreateDir($folderName){
if($folderName != NULL){
$basePath = Products::getUploadPath();
if(BaseFileHelper::createDirectory($basePath.$folderName,0777)){
BaseFileHelper::createDirectory($basePath.$folderName.'/thumbnail',0777);
}
}
return;
}
private function removeUploadDir($dir){
BaseFileHelper::removeDirectory(Products::getUploadPath().$dir);
}
private function Uploads($isAjax=false) {
if (Yii::$app->request->isPost) {
$images = UploadedFile::getInstancesByName('upload_ajax');
if ($images) {
if($isAjax===true){
$ref =Yii::$app->request->post('ref');
}else{
$Products = Yii::$app->request->post('Products');
$ref = $Products['ref'];
}
$this->CreateDir($ref);
foreach ($images as $file){
$fileName = $file->baseName . '.' . $file->extension;
$realFileName = md5($file->baseName.time()) . '.' . $file->extension;
$savePath = Products::UPLOAD_FOLDER.'/'.$ref.'/'. $realFileName;
if($file->saveAs($savePath)){
if($this->isImage(Url::base(true).'/'.$savePath)){
$this->createThumbnail($ref,$realFileName);
}
$model = new Uploads;
$model->ref = $ref;
$model->file_name = $fileName;
$model->real_filename = $realFileName;
$model->save();
if($isAjax===true){
echo json_encode(['success' => 'true']);
}
}else{
if($isAjax===true){
echo json_encode(['success'=>'false','eror'=>$file->error]);
}
}
}
}
}
}
private function getInitialPreview($ref) {
$datas = Uploads::find()->where(['ref'=>$ref])->all();
$initialPreview = [];
$initialPreviewConfig = [];
foreach ($datas as $key => $value) {
array_push($initialPreview, $this->getTemplatePreview($value));
array_push($initialPreviewConfig, [
'caption'=> $value->file_name,
'width' => '120px',
'url' => Url::to(['/products/deletefile-ajax']),
'key' => $value->upload_id
]);
}
return [$initialPreview,$initialPreviewConfig];
}
public function isImage($filePath){
return #is_array(getimagesize($filePath)) ? true : false;
}
private function getTemplatePreview(Uploads $model){
$filePath = Products::getUploadUrl().$model->ref.'/thumbnail/'.$model->real_filename;
$isImage = $this->isImage($filePath);
if($isImage){
$file = Html::img($filePath,['class'=>'file-preview-image', 'alt'=>$model->file_name, 'title'=>$model->file_name]);
}else{
$file = "<div class='file-preview-other'> " .
"<h2><i class='glyphicon glyphicon-file'></i></h2>" .
"</div>";
}
return $file;
}
private function createThumbnail($folderName,$fileName,$width=250){
$uploadPath = Products::getUploadPath().'/'.$folderName.'/';
$file = $uploadPath.$fileName;
$image = Yii::$app->image->load($file);
$image->resize($width);
$image->save($uploadPath.'thumbnail/'.$fileName);
return;
}
public function actionDeletefileAjax(){
$model = Uploads::findOne(Yii::$app->request->post('key'));
if($model!==NULL){
$filename = Products::getUploadPath().$model->ref.'/'.$model->real_filename;
$thumbnail = Products::getUploadPath().$model->ref.'/thumbnail/'.$model->real_filename;
if($model->delete()){
#unlink($filename);
#unlink($thumbnail);
echo json_encode(['success'=>true]);
}else{
echo json_encode(['success'=>false]);
}
}else{
echo json_encode(['success'=>false]);
}
}
}
_form.php
<?php
//use kartik\file\FileInput;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use backend\models\Brands;
use backend\models\Categorys;
use yii\helpers\Url;
use kartik\file\FileInput;
/* #var $this yii\web\View */
/* #var $model backend\models\Products */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="photo-library-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data']]); ?>
<?php $form->errorSummary($model) ?>
<?= $form->field($model, 'ref')->hiddenInput(['maxlength' => 100])->label(false); ?>
<?= $form->field($model, 'productName')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'productDescription')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'productPrice')->textInput() ?>
<?=
$form->field($model, 'brandId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Brands::find()->where(['brandStatus'=>'active'])->all(),'brandId','brandName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a brand ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?=
$form->field($model, 'categoryId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Categorys::find()->where(['categoryStatus'=>'active'])->all(),'categoryId','categoryName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a category ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?= $form->field($model, 'productStatus')->dropDownList([ 'active' => 'Active', 'inactive' => 'Inactive', ], ['prompt' => 'Status']) ?>
<div class="form-group field-upload_files">
<label class="control-label" for="upload_files[]"> Product Images </label>
<div>
<?=
FileInput::widget([
'name' => 'upload_ajax[]',
//'attribute'=>'productImage[]',
//'name'=>'productImage[]',
'options' => [
'multiple'=>true,
'accept' => 'image/*',
//'id'=>'imageId',
],
'pluginOptions' => [
'initialPreview'=> $initialPreview,
'initialPreviewConfig'=> $initialPreviewConfig,
'deleteUrl'=>Url::to(['/products/deletefile-ajax']),
'showPreview' => true,
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'uploadAsync' => true,
'uploadUrl'=>Url::to(['/products/upload-ajax']),
'maxFileCount' => 5,
'allowedFileExtensions' => ['jpg', 'png','jpeg'],
'previewFileType' => ['jpg', 'png','jpeg'],
'overwriteInitial'=>false,
'uploadExtraData' => [
'ref'=>$model->ref
],
'msgUploadBegin' => Yii::t('app', 'Please wait, system is uploading the files'),
'validateInitailCount'=>true,
'layoutTemplates'=>[
'actionZoom'=>'<button type="button" class="kv-file-zoom">{zoomIcon}</button>',
'actionUpload'=>'',
//'actionDelete'=>'<a>jj</a>',
//'footer' => '<div class="file-thumbnail-footer"><div class="file-caption-name" style="width:{width}">{caption}{size}</div>
//{progress}{actions}',
//'footer' => '<div class="file-thumbnail-footer"> <div class="file-caption-caption" title="{caption}"</div>'
//'actionDelete'=>'<button type="button" class="kv-file-remove"> {dataKey}{deleteUrl} {removeIcon}</button>',
],
],
'pluginEvents' => [
'filebatchselected' => 'function(event, files) {
$(this).fileinput("/products/upload-ajax");
}',
],
]);
?>
<br>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord? 'Save': 'Update', ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('app', 'Cancel'), ['index', 'id' => $model->productId], ['class'=>'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
I found the solution my bad
need to change all the Url::to() in controller and _form
to this format solution
The detail answer as below
_form.php
<?php
//use kartik\file\FileInput;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use backend\models\Brands;
use backend\models\Categorys;
use yii\helpers\Url;
use kartik\file\FileInput;
/* #var $this yii\web\View */
/* #var $model backend\models\Products */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="photo-library-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data']]); ?>
<?php $form->errorSummary($model) ?>
<?= $form->field($model, 'ref')->hiddenInput(['maxlength' => 100])->label(false); ?>
<?= $form->field($model, 'productName')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'productDescription')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'productPrice')->textInput() ?>
<?=
$form->field($model, 'brandId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Brands::find()->where(['brandStatus'=>'active'])->all(),'brandId','brandName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a brand ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?=
$form->field($model, 'categoryId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Categorys::find()->where(['categoryStatus'=>'active'])->all(),'categoryId','categoryName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a category ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?= $form->field($model, 'productStatus')->dropDownList([ 'active' => 'Active', 'inactive' => 'Inactive', ], ['prompt' => 'Status']) ?>
<label>Product Images</label>
<?=
FileInput::widget([
'name' => 'upload_ajax[]',
//'attribute'=>'productImage[]',
//'name'=>'productImage[]',
'options' => [
'multiple'=>true,
'accept' => 'image/*',
//'id'=>'imageId',
],
'pluginOptions' => [
'initialPreview'=> $initialPreview,
'initialPreviewConfig'=> $initialPreviewConfig,
'showPreview' => true,
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'uploadAsync' => false,
'uploadUrl'=>Url::to('index.php?r=products/upload-ajax'),
'deleteUrl'=>Url::to('index.php?r=products/deletefile-ajax'),
'maxFileCount' => 5,
'allowedFileExtensions' => ['jpg', 'png','jpeg'],
'previewFileType' => ['jpg', 'png','jpeg'],
'overwriteInitial'=>false,
'enableResumableUpload'=>true,
'uploadExtraData' => [
'ref'=>$model->ref
],
'validateInitialCount'=>true,
'initialPreviewShowDelete' => true,
'layoutTemplates'=>[
'actionZoom'=>'<button type="button" class="kv-file-zoom">{zoomIcon}</button>',
'actionUpload'=>'',
'actionDelete' => '<button type="button" class="kv-file-remove" title="{removeTitle}" {dataKey}{dataUrl}><i class="glyphicon glyphicon-trash"></i></button>'
],
],
'pluginEvents' => [
// 'filebatchselected' => 'function(files) {
// $(this).fileinput("index.php?r=products/upload-ajax");
// }',
'filepredelete'=>'function(jqXHR){
var abort = true;
if (confirm("Are you sure you want to delete this image?")) {
abort = false;
}
return abort;
}'
],
]);
?>
<br>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord? 'Save': 'Update', ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('app', 'Cancel'), ['index', 'id' => $model->productId], ['class'=>'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
ProductsController
private function getInitialPreview($ref) {
$datas = Uploads::find()->where(['ref'=>$ref])->all();
$initialPreview = [];
$initialPreviewConfig = [];
foreach ($datas as $key => $value) {
array_push($initialPreview, $this->getTemplatePreview($value));
array_push($initialPreviewConfig, [
'caption'=> $value->file_name,
'width' => '120px',
'url' => Url::to('index.php?r=products/deletefile-ajax'),
'key' => $value->upload_id
]);
}
return [$initialPreview,$initialPreviewConfig];
}

My search is not working in yii2 ,i have to try to find the solution but fails

I want to search my data but the search is not working. I can't understand what's going wrong? please help to fix it... here is the code
payable controller
<?php
namespace app\controllers;
use Yii;
use app\models\Payable;
use app\models\PayableSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* PayableController implements the CRUD actions for Payable model.
*/
class PayableController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Payable models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new PayableSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Payable model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Payable model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Payable();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
]);
}
/**
* Updates an existing Payable model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
]);
}
/**
* Deletes an existing Payable model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Payable model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Payable the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Payable::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}
PaybleSearch
<?php
namespace app\models;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Payable;
/**
* PayableSearch represents the model behind the search form of `app\models\Payable`.
*/
class PayableSearch extends Payable
{
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['id', 'consumer_id', 'total_months_conservancy', 'water_arrears', 'conservancy_amount', 'total_water_and_conservancy_amount', 'tinure', 'dues_amount', 'per_month_charges', 'no_of_months', 'total_amount_of_current_months', 'advanced_pay', 'arrears', 'arrears_period', 'total_bill', 'after_due_date_charges', 'total_after_due_date', 'balance_arears', 'water_charges_per_month', 'conservancy_charges_per_month', 'four_months_water_charges', 'four_months_conservancy_charges'], 'integer'],
[['water_remarks', 'remarks', 'billing_months', 'issue_date', 'due_date'], 'safe'],
];
}
/**
* {#inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = Bill::find()->where('status=0');
// echo"<pre>";
// print_r($query);
// exit();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'consumer_id' => $this->consumer_id,
'total_months_conservancy' => $this->total_months_conservancy,
'water_arrears' => $this->water_arrears,
'conservancy_amount' => $this->conservancy_amount,
'total_water_and_conservancy_amount' => $this->total_water_and_conservancy_amount,
'tinure' => $this->tinure,
'dues_amount' => $this->dues_amount,
'per_month_charges' => $this->per_month_charges,
'no_of_months' => $this->no_of_months,
'total_amount_of_current_months' => $this->total_amount_of_current_months,
'advanced_pay' => $this->advanced_pay,
'arrears' => $this->arrears,
'arrears_period' => $this->arrears_period,
'total_bill' => $this->total_bill,
'after_due_date_charges' => $this->after_due_date_charges,
'total_after_due_date' => $this->total_after_due_date,
'balance_arears' => $this->balance_arears,
'water_charges_per_month' => $this->water_charges_per_month,
'conservancy_charges_per_month' => $this->conservancy_charges_per_month,
'four_months_water_charges' => $this->four_months_water_charges,
'four_months_conservancy_charges' => $this->four_months_conservancy_charges,
'issue_date' => $this->issue_date,
'due_date' => $this->due_date,
]);
$query->andFilterWhere(['like', 'water_remarks', $this->water_remarks])
->andFilterWhere(['like', 'remarks', $this->remarks])
->andFilterWhere(['like', 'billing_months', $this->billing_months]);
return $dataProvider;
}
}
Payable Model
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "payable".
*
* #property int $id
* #property int $consumer_id
* #property int $total_months_conservancy
* #property int $water_arrears
* #property string $water_remarks
* #property int $conservancy_amount
* #property int $total_water_and_conservancy_amount
* #property int $tinure
* #property int $dues_amount
* #property int $per_month_charges
* #property int $no_of_months
* #property int $total_amount_of_current_months
* #property int $advanced_pay
* #property int $arrears
* #property int $arrears_period
* #property int $total_bill
* #property int $after_due_date_charges
* #property int $total_after_due_date
* #property int $balance_arears
* #property string $remarks
* #property int $water_charges_per_month
* #property int $conservancy_charges_per_month
* #property int $four_months_water_charges
* #property int $four_months_conservancy_charges
* #property string $billing_months
* #property string $issue_date
* #property string $due_date
*/
class Payable extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'payable';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['consumer_id', 'total_months_conservancy', 'water_arrears', 'water_remarks', 'conservancy_amount', 'total_water_and_conservancy_amount', 'tinure', 'dues_amount', 'per_month_charges', 'no_of_months', 'total_amount_of_current_months', 'advanced_pay', 'arrears', 'arrears_period', 'total_bill', 'after_due_date_charges', 'total_after_due_date', 'balance_arears', 'remarks', 'water_charges_per_month', 'conservancy_charges_per_month', 'four_months_water_charges', 'four_months_conservancy_charges', 'billing_months', 'issue_date', 'due_date'], 'required'],
[['consumer_id', 'total_months_conservancy', 'water_arrears', 'conservancy_amount', 'total_water_and_conservancy_amount', 'tinure', 'dues_amount', 'per_month_charges', 'no_of_months', 'total_amount_of_current_months', 'advanced_pay', 'arrears', 'arrears_period', 'total_bill', 'after_due_date_charges', 'total_after_due_date', 'balance_arears', 'water_charges_per_month', 'conservancy_charges_per_month', 'four_months_water_charges', 'four_months_conservancy_charges'], 'integer'],
[['issue_date', 'due_date'], 'safe'],
[['water_remarks'], 'string', 'max' => 250],
[['remarks'], 'string', 'max' => 350],
[['billing_months'], 'string', 'max' => 25],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'consumer_id' => 'Consumer ID',
'total_months_conservancy' => 'Total Months Conservancy',
'water_arrears' => 'Water Arrears',
'water_remarks' => 'Water Remarks',
'conservancy_amount' => 'Conservancy Amount',
'total_water_and_conservancy_amount' => 'Total Water And Conservancy Amount',
'tinure' => 'Tinure',
'dues_amount' => 'Dues Amount',
'per_month_charges' => 'Per Month Charges',
'no_of_months' => 'No Of Months',
'total_amount_of_current_months' => 'Total Amount Of Current Months',
'advanced_pay' => 'Advanced Pay',
'arrears' => 'Arrears',
'arrears_period' => 'Arrears Period',
'total_bill' => 'Total Bill',
'after_due_date_charges' => 'After Due Date Charges',
'total_after_due_date' => 'Total After Due Date',
'balance_arears' => 'Balance Arears',
'remarks' => 'Remarks',
'water_charges_per_month' => 'Water Charges Per Month',
'conservancy_charges_per_month' => 'Conservancy Charges Per Month',
'four_months_water_charges' => 'Four Months Water Charges',
'four_months_conservancy_charges' => 'Four Months Conservancy Charges',
'billing_months' => 'Billing Months',
'issue_date' => 'Issue Date',
'due_date' => 'Due Date',
];
}
public function getconsumerId()
{
return $this->hasOne(Plot::className(),['id' => 'consumer_id']);
}
}
View.php
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
/* #var $this yii\web\View */
/* #var $model app\models\Payable */
$this->title = $model->id;
$this->params['breadcrumbs'][] = ['label' => 'Payables', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
\yii\web\YiiAsset::register($this);
?>
<div class="payable-view">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'id' => $model->id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
</p>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'consumer_id',
'total_months_conservancy',
'water_arrears',
'water_remarks',
'conservancy_amount',
'total_water_and_conservancy_amount',
'tinure',
'dues_amount',
'per_month_charges',
'no_of_months',
'total_amount_of_current_months',
'advanced_pay',
'arrears',
'arrears_period',
'total_bill',
'after_due_date_charges',
'total_after_due_date',
'balance_arears',
'remarks',
'water_charges_per_month',
'conservancy_charges_per_month',
'four_months_water_charges',
'four_months_conservancy_charges',
'billing_months',
'issue_date',
'due_date',
],
]) ?>
</div>
Index.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel app\models\PayableSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Payables';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="payable-index">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Create Payable', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//
'id',
[ 'header'=> 'Consumer Name',
'attribute'=>'consumer_id',
'value'=>'consumerId.allottee_name',
],
// 'total_months_conservancy',
// 'water_arrears',
// 'water_remarks',
// 'conservancy_amount',
//'total_water_and_conservancy_amount',
//'tinure',
//'dues_amount',
//'per_month_charges',
//'no_of_months',
//'total_amount_of_current_months',
//'advanced_pay',
'arrears',
//'arrears_period',
'total_bill',
//'after_due_date_charges',
'total_after_due_date',
//'balance_arears',
//'remarks',
//'water_charges_per_month',
//'conservancy_charges_per_month',
//'four_months_water_charges',
//'four_months_conservancy_charges',
'billing_months',
//'issue_date',
'due_date',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
I want to make a search but the search is not working. I tried but fails. I could not found any error.please help me in finding the issue

Activeform data submit in database using Yii2, Not working

I m new in yii2 framework, when I submit my Activeform data to save in database in display error
Not Found (#404).
This Activeform mention in different model view. My form is on product page and I want just give review of customer regarding this product and save in DB.
view file: detail.php:
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $model app\models\Product */
$name = $result->name;
$price = $result->price;
$offerrate = 8;
$offer = ($price / 100) * $offerrate;
$offerprice = number_format($price - $offer, 2);
$text = $result->Description;
$list = explode(",", $text);
?>
<div id="page-content" class="home-page">
<div class="container">
<div class="row">
<div class="col-lg-5">
<center>
<?= Html::img(Yii::$app->urlManagerBackend->BaseUrl.'/'.$result->image, ['alt'=>'myImage','width'=>'300','height'=>'300', 'class' => 'img-responsive']) ?>
<br/>
<?= Html::button('ADD TO CART', ['class' => 'btn btn-success', 'id'=>'addcart']) ?>
<?= Html::button('BUY NOW', ['class' => 'btn btn-danger', 'id'=>'buynow']) ?>
</center>
</div>
<div class="col-lg-7">
<?php echo "<h5 style='color:#009933'>".$name."</h5>"?><br/>
<?php
echo "<ul>";
foreach ($list as $lists)
{
echo "<li class='liststyle'>".$lists."</li>";
}
echo "</ul>";
?><br/>
<?php echo "<h6 style='color:#009933'>MobileShop Offer Price Rs: ".$offerprice."</h6>" ?>
<?= Html::button('Rate and Review product', ['class' => 'btn btn-default', 'id'=>'review', 'data-toggle' => 'collapse', 'data-target' => '#demo']) ?>
<div id="demo" class="collapse">
<?php $form = ActiveForm::begin(['id' => 'reviewForm', 'action' => Yii::$app->urlManager->createUrl(['TblFeedback/create'])]); ?>
<?= $form->field($feedback, 'cust_name')->textInput() ?>
<?= $form->field($feedback, 'feedback')->textArea(['rows' => '2', 'cols' => '10'])?>
<?= $form->field($feedback, 'rating')->dropDownlist(['1' => '*', '2' => '* *', '3' => '* * *', '4' => '* * * *', '5' => '* * * * *']) ?>
<div class="form-group">
<?= Html::submitButton('Save', ['id' => 'savebtn', 'class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
</div>
Controller file: TblFeedbackController.php
<?php
namespace frontend\controllers;
use Yii;
use app\models\TblFeedback;
use frontend\models\Product;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
class TblFeedbackController extends \yii\web\Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
public function actionIndex()
{
return $this->render('index');
}
public function actionCreate()
{
$feedback = new TblFeedback();
if ($feedback->load(Yii::$app->request->post()) && $feedback->validate())
{
var_dump($feedback);
die();
$feedback->save();
Yii::$app->session->setFlash('success', '<h5>Thanks for review!</h5>');
return $this->redirect(['index']);
}
else {
return $this->render('index',
['feedback' => $feedback,
]);
Yii::$app->session->setFlash('error', 'Error Found!');
}
}
}
model file: TblFeedback.php
<?php
namespace frontend\models;
use Yii;
/**
* This is the model class for table "tbl_feedback".
*
* #property integer $id
* #property integer $product_id
* #property integer $cust_id
* #property string $cust_name
* #property integer $rating
* #property string $feedback
*
* #property Product $product
* #property User $cust
*/
class TblFeedback extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'tbl_feedback';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['product_id', 'cust_id', 'cust_name', 'rating', 'feedback'], 'required'],
[['product_id', 'cust_id', 'rating'], 'integer'],
[['rating'], 'integer', 'min' => 1, 'max' => 5],
[['cust_name'], 'string', 'max' => 200],
[['feedback'], 'string', 'max' => 1000],
[['product_id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::className(), 'targetAttribute' => ['product_id' => 'id']],
[['cust_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['cust_id' => 'id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'product_id' => 'Product ID',
'cust_id' => 'Cust ID',
'cust_name' => 'Enter Name:',
'rating' => 'Rating',
'feedback' => 'Description',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProduct()
{
return $this->hasOne(Product::className(), ['id' => 'product_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCust()
{
return $this->hasOne(User::className(), ['id' => 'cust_id']);
}
}
The naming convention for controller action are based on - separator when a part is uppercase so you should use
<?php $form = ActiveForm::begin(['id' => 'reviewForm',
'action' => Yii::$app->urlManager->createUrl(['Tbl-feedback/create'])]); ?>
the naming convention,for the controllers, it is to start with a lowercase character.
so you should use
class tblFeedbackController extends \yii\web\Controller
and
<?php $form = ActiveForm::begin(['id' => 'reviewForm',
'action' => Yii::$app->urlManager->createUrl(['tbl-feedback/create'])]); ?>
and last suggestion you could use urlHelper
use yii\helpers\Url;
<?php $form = ActiveForm::begin(['id' => 'reviewForm',
'action' => Url::to(['tbl-feedback/create'])]); ?>

Yii2 Select2 - selected value on update - junction table (many to many)

I am successfully inserting new rows in my junction table (userlocations) on action create and I successfully update them on action update but the problem is on ation update the location_id field is always empty. It should retrieve the location_id's from userlocations table and populate the field on update but it doesnt.
Database: http://i.stack.imgur.com/JFjdz.png
UserController:
<?php
namespace backend\controllers;
use Yii;
use backend\models\User;
use backend\models\UserSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\helpers\ArrayHelper;
use backend\models\Locations;
use backend\models\Userlocations;
class UserController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all User models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new UserSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single User model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new User model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new User();
$locations = ArrayHelper::map(Locations::find()->all(), 'id', 'name');
$userlocations = new Userlocations();
if ($model->load(Yii::$app->request->post()) ) {
$model->setPassword($model->password);
$model->generateAuthKey();
$userlocations->load(Yii::$app->request->post());
if ($model->save() && !empty($userlocations->location_id)){
foreach ($userlocations->location_id as $location_id) {
$userlocations = new Userlocations();
$userlocations->setAttributes([
'location_id' => $location_id,
'user_id' => $model->id,
]);
$userlocations->save();
}
}
return $this->redirect(['user/index']);
} else {
return $this->render('create', [
'model' => $model,
'locations' => $locations,
'userlocations' => $userlocations,
]);
}
}
/**
* Updates an existing User model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
$locations = ArrayHelper::map(Locations::find()->all(), 'id', 'name');
$userlocations = new Userlocations();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
Userlocations::deleteAll(['user_id' => $id]);
$userlocations->load(Yii::$app->request->post());
if (!empty($userlocations->location_id)){
foreach ($userlocations->location_id as $location_id) {
$userlocations = new Userlocations();
$userlocations->setAttributes([
'location_id' => $location_id,
'user_id' => $model->id,
]);
$userlocations->save();
}
}
return $this->redirect(['user/index']);
} else {
return $this->render('update', [
'model' => $model,
'locations' => $locations,
'userlocations' => $userlocations,
]);
}
}
/**
* Deletes an existing User model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the User model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return User the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = User::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
User model:
class User extends \common\models\User
{
public $password;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'User';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['username', 'password'], 'required'],
[['status', 'created_at', 'updated_at'], 'integer'],
[['username', 'password_hash', 'password_reset_token', 'email'], 'string', 'max' => 255],
[['auth_key'], 'string', 'max' => 32],
[['username'], 'unique', 'message' => 'Username already taken!'],
[['email'], 'unique'],
[['password_reset_token'], 'unique'],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'auth_key' => 'Auth Key',
'password_hash' => 'Password Hash',
'password_reset_token' => 'Password Reset Token',
'email' => 'Email',
'status' => 'Status',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
}
My form:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use kartik\select2\Select2;
use backend\models\Locations;
?>
<div class="user-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'username')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'password')->passwordInput(['maxlength' => true]) ?>
<?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>
<?= $form->field($userlocations, 'location_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Locations::find()->all(), 'id', 'name'),
'size' => Select2::MEDIUM,
'options' => ['placeholder' => 'Select a location ...', 'multiple' => true],
'pluginOptions' => [
'allowClear' => true,
],
]); ?>
<?= $form->field($model, 'status')->dropDownList(['10' => 'Active', '0' => 'Inactive']) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
For multiple location select, use the plugin code as given below.
<?= Select2::widget([
'name' => 'Userlocations[location_id]',
'value' => $location_ids, // initial value
'data' => ArrayHelper::map(Locations::find()->all(), 'id', 'name'),
'options' => ['placeholder' => 'Select your locations...', 'multiple' => true],
'pluginOptions' => [
'tags' => true,
'maximumInputLength' => 10
],
]); ?>
$location_ids will be the location array you have previously selected during creation time.Also remember when you are making changes for more than one table,make sure you do it in a transaction.

How to make validations from a query to a table? yii2

my problem is: I have a form where i have select2 and the user can select from a dropdown list which is populated from a table, so, basically what i want to happen is that when the user tries to select a driver a validation rule will take place which will check if the driver was already registered through the system that day.
I have one idea of how to do it, i have my archive form which registers people that enter in the archive table, it checks wether it exists or not in the drivers table and if not you have to register them, if they exists you proceed to fill out the form, each field in the this archive table has a datecreated column which is the date the field was entered, so basically the last time he came in.
How can i make a rule which calls for this column compares to current day and gives an error if he had already entered that day? The rule should be in drivers model.(My code is confusing that is why i'm clarifying, i'm new to Yii2)
My view (archive form):
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use wbraganca\dynamicform\DynamicFormWidget;
use app\models\Drivers;
use app\models\Vehicles;
use app\models\Invoices;
use dosamigos\datepicker\DatePicker;
use kartik\select2\Select2;
use yii\bootstrap\Modal;
use yii\helpers\Url;
/* #var $this yii\web\View */
/* #var $model app\models\Archive */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="archive-form">
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>
<?= $form->field($model, 'driver_identitynum')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Drivers::find()->all(),'driver_identitynum', 'fullname'),
'language' => 'en',
'options' => ['placeholder' => 'Ingrese el numero de cedula...'],
'pluginOptions' => [
'allowClear' => true],
]); ?>
<div align="right"><?= Html::a('Add driver', ['/drivers/create'],
['target'=>'_blank']); ?>
</div>
<?= $form->field($model, 'vehicle_lp')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Vehicles::find()->all(),'vehicle_lp', 'fulltruck'),
'language' => 'en',
'options' => ['placeholder' => 'Ingrese la placa del vehiculo...'],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
<div align="right"><?= Html::a('Add vehicle', ['/vehicles/create'],
['target'=>'_blank']); ?>
</div>
<div class="row"> <div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i>Facturas</h4></div>
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 4, // the maximum times, an element can be cloned (default 999)
'min' => 1, // 0 or 1 (default 1)
'insertButton' => '.add-item', // css class
'deleteButton' => '.remove-item', // css class
'model' => $modelsInvoices[0],
'formId' => 'dynamic-form',
'formFields' => [
'invoice_number',
'invoice_loadamount',
'invoice_date',
],
]); ?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($modelsInvoices as $i => $modelInvoices): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<h3 class="panel-title pull-left">Facturas</h3>
<div class="pull-right">
<button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (! $modelInvoices->isNewRecord) {
echo Html::activeHiddenInput($modelInvoices, "[{$i}]id");
}
?>
<div class="row">
<div class="col-sm-6">
<?= $form->field($modelInvoices, "[{$i}]invoice_number")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($modelInvoices, "[{$i}]invoice_loadamount")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($modelInvoices, "[{$i}]invoice_date", ['enableAjaxValidation' => true])->widget(DatePicker::className(), [
// inline too, not bad
'inline' => false,
// modify template for custom rendering
//'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'options' => ['class' => 'form-control picker'],
'clientOptions' => [
'autoclose' => true,
'format' => 'dd-mm-yyyy'
]
]);?>
</div>
</div><!-- .row -->
<div class="row">
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
</div>
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
My drivers model:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "drivers".
*
* #property integer $driver_id
* #property string $driver_name
* #property string $driver_lastname
* #property string $driver_identitynum
*/
class Drivers extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'drivers';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['driver_name', 'driver_lastname', 'driver_identitynum'], 'required'],
[['driver_name', 'driver_lastname', 'driver_identitynum'], 'string', 'max' => 100]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'driver_id' => 'Driver ID',
'driver_name' => 'Driver Name',
'driver_lastname' => 'Driver Lastname',
'driver_identitynum' => 'Driver Identitynum',
];
}
public function getfullName()
{
return $this->driver_identitynum.' - '.$this->driver_name.' '.$this->driver_lastname.' ';
}
/**
* #return \yii\db\ActiveQuery
*/
public function getArchives()
{
return $this->hasMany(Archive::className(), ['driver_identitynum' => 'driver_identitynum']);
}
}
My archive model:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "archive".
*
* #property integer $id
* #property string $driver_identitynum
* #property string $vehicle_lp
* #property string $DateCreated
*
* #property Invoices[] $invoices
*/
class Archive extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'archive';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['driver_identitynum', 'vehicle_lp'], 'required'],
[['DateCreated'], 'safe'],
[['driver_identitynum', 'vehicle_lp'], 'string', 'max' => 100]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'driver_identitynum' => 'Cedula del conductor:',
'vehicle_lp' => 'Placa del vehiculo:',
'DateCreated' => 'Date Created',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getInvoices()
{
return $this->hasMany(Invoices::className(), ['archive_id' => 'id']);
}
public function __toString()
{
return 'CI:'.$this->driver_identitynum.' Placa: '.$this->vehicle_lp;
}
public function didheloadtoday($attribute,$params)
{
$inputlp=($this->invoice_loadamount);
$row = (new \yii\db\Query())
->select('vehicle_lp')
->from('vehicles')
->where("vehicle_lp=$vehiclelp")
->all();
}
}
So, the rule is that only one driver_identitynum and DateCreated combination can exist in the archive table.
To validate the driver_identity field for this you can use the native unique validator and specify the attributes that need to be unique together.
The corresponding rule would be:
[['driver_identitynum'], 'unique',
'targetAttribute' => ['driver_identitynum', 'DateCreated'],
],
If this validation is called from another model, then it complicates matters a bit. In addition to the above:
specify the target class
declare a public date variable in the other model
store current date in this field
indicate the this date property should be used as value to check uniqueness of DateCreated
The adjusted rule would be:
[['driver_identitynum'], 'unique',
'targetAttribute' => ['driver_identitynum', 'date' => 'DateCreated'],
'targetClass' => '\app\models\Archive'
],