Yii2 uploadfile image from model method beforeSave - yii2

i try to upload 4 or less images, the ajax validation do not return any error, but on submit i get the follow:
"errors": {
"imageFiles": [
"Please upload a file."
]
}
attr:
/**
* #var UploadedFile[]
*/
public $imageFiles;
Rules:
return [
[['imageFiles'], 'required', 'on' => self::REPORT_STEP1],
[['imageFiles'], 'file', 'skipOnEmpty' => false, 'maxFiles' => 4],
];
BeforeSave:
public function beforeSave($insert)
{
$files_urls = [];
$this->imageFiles = UploadedFile::getInstances($this, 'imageFiles');
foreach ($this->imageFiles as $file) {
$path = Url::to(['/uploads/reports/'], true) . Yii::$app->security->generateRandomString() . '.' . $file->extension;
$file->saveAs($path);
$files_urls[] = $file->name;
}
$this->img_url = json_encode($files_urls);
return parent::beforeSave($insert); // TODO: Change the autogenerated stub
}
Form:
<?php $form = ActiveForm::begin([
'enableAjaxValidation' => true,
'options' => [
'enctype' => 'multipart/form-data'
]
]) ?>
<?= $form->field($model, 'imageFiles[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<div class="form-group">
<?= Html::submitButton('Siguiente', ['class' => 'btn btn-standard']) ?>
</div>
<?php ActiveForm::end() ?>

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];
}

Yii2 log in form works only when ajaxvalidation is false

I have a log in form which works only when i turn of my ajaxValidation. If i enable itenableAjaxValidation = true` it dies. What is the problem? Is it something with the model rules? On the previous projects i used the same form and all was fine. Can't realize. Can you guys give an advice and quick explanation. Thank you in advance!
<div class="row">
<div class="col-xs-12">
<h3 class="contact-page-title"><?= Yii::t('app', 'app.Login') ?></h3>
<?php if (Yii::$app->user->isGuest): ?>
<?php $form = ActiveForm::begin([
'id' => 'login-widget-form',
'action' => Url::to(['/user/security/login']),
/*'enableAjaxValidation' => true,*/
'enableClientValidation' => false,
'validateOnBlur' => false,
'validateOnType' => false,
'validateOnChange' => false,
]) ?>
<?= $form->field($model, 'login')->textInput() ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'rememberMe')->checkbox() ?>
<input type="hidden" name="checkoutLogin" value="1">
<?= Html::submitButton(Yii::t('user', Yii::t('app','app.Login')) , ['class' => 'btn-1 shadow-0 full-width']) ?>
<?php ActiveForm::end(); ?>
<?php else: ?>
<?= Html::a(Yii::t('user', 'Logout'), ['/user/security/logout'], [
'class' => 'btn btn-danger btn-block',
'data-method' => 'post'
]) ?>
<?php endif ?>
</div>
</div>
And these are the rules:
public function rules()
{
$rules = [
'loginTrim' => ['login', 'trim'],
'requiredFields' => [['login'], 'required'],
'confirmationValidate' => [
'login',
function ($attribute) {
if ($this->user !== null) {
$confirmationRequired = $this->module->enableConfirmation
&& !$this->module->enableUnconfirmedLogin;
if ($confirmationRequired && !$this->user->getIsConfirmed()) {
$this->addError($attribute, Yii::t('user', 'You need to confirm your email address'));
}
if ($this->user->getIsBlocked()) {
$this->addError($attribute, Yii::t('user', 'Your account has been blocked'));
}
}
}
],
'rememberMe' => ['rememberMe', 'boolean'],
];
if (!$this->module->debug) {
$rules = array_merge($rules, [
'requiredFields' => [['login', 'password'], 'required'],
'passwordValidate' => [
'password',
function ($attribute) {
if ($this->user === null || !Password::validate($this->password, $this->user->password_hash)) {
$this->addError($attribute, Yii::t('user', 'Invalid login or password'));
}
}
]
]);
}
return $rules;
}
EDIT Action:
public function actionLogin() {
if (!Yii::$app->user->isGuest) {
$this->goHome();
}
$register = new RegistrationForm();
if(Yii::$app->request->isAjax){
return 1;
}
/** #var LoginForm $model */
$model = Yii::createObject(LoginForm::className());
$event = $this->getFormEvent($model);
$this->performAjaxValidation($model);
$this->trigger(self::EVENT_BEFORE_LOGIN, $event);
if ($model->load(Yii::$app->getRequest()->post()) && $model->login()) {
$this->trigger(self::EVENT_AFTER_LOGIN, $event);
//return $this->goBack();
if (Yii::$app->request->baseUrl == "" and !isset($_POST["checkoutLogin"])) {
$session = Yii::$app->session;
return $this->redirect('/');
} elseif(isset($_POST["checkoutLogin"]) and $_POST["checkoutLogin"] == 1) {
$lang = \frontend\models\Lang::getCurrent();
$checkout = Page::findOne(91);
if($checkout){
return $this->redirect('/'.$lang->url.'/'.$checkout->url);
}else{
return $this->goBack();
}
} else {
return $this->goBack();
}
}
return $this->render('login', [
'model' => $model,
'module' => $this->module,
'register' => $register
]);
}
Try with the code of performAjaxValidation() moved to the action:
// instead of $this->performAjaxValidation($model);
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}

Get data from selected checkboxes in yii2

I have a form rawmaterial and in that I've a Gridview with checkboxcolumn and some form fields. I want to get all the fields of the selected rows as array.
I've tried to solve as mentioned here - http://www.yiiframework.com/forum/index.php/topic/53777-gridview-get-selected-colum/. But getting Not Found error.
Code of index.php
<?php
use yii\helpers\Html;
use kartik\grid\GridView;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use frontend\models\Rmtemplate;
use kartik\form\ActiveForm;
/* #var $this yii\web\View */
/* #var $searchModel frontend\modules\rmprod\models\RmtemplateSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Templates';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="rmtemplate-index">
<?php $form = ActiveForm::begin([
'id' => 'rmtemplate-index',
'action' => ['/rmprod/Rmtemplate/processSelected',],
'method' => 'get',
'enableClientScript' => false,
]); ?>
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'id'=>'mytable',
'columns' => [
['class' => 'kartik\grid\CheckboxColumn'],
//'id',
//'productname',
[
'attribute'=>'productname',
'filterType'=>GridView::FILTER_SELECT2,
'filter'=>ArrayHelper::map(Rmtemplate::find()->orderBy(['productname' => SORT_ASC])->asArray()->all(), 'productname', 'productname'),
'filterWidgetOptions'=>[
'pluginOptions'=>['allowClear'=>true],
],
'filterInputOptions'=>['placeholder'=>'Charge Name'],
],
'rmname',
'qty',
// [
// 'attribute' => 'unitcost',
// 'value' => 'unitcost.unitcost',
// ],
'cost',
//['class' => 'kartik\grid\ActionColumn'],
],
]); ?>
<div class="form-group pull-right">
<?= Html::submitButton('Next', ['class' => 'btn btn-primary search','id'=>'tabbutton',]) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
<?php
/* start getting the data */
$script = <<<EOD
$('tabbutton').one('click',function() {
var keys = $('#w0').yiiGridView('getSelectedRows'); // returns an array of pkeys, and #grid is your grid element id
$.post({
url: '/rmtemplate/processSelected', // your controller action
dataType: 'json',
data: {keylist: keys},
success: function(data) {
if (data.status === 'success') {
alert('I did it! Processed checked rows.');
}
},
});
});
EOD;
$this->registerJs($script);
/*end getting the data */
?>
Controller Action
public function actionProcessSelected() {
if (isset($_POST['keylist'])) {
$keys = \yii\helpers\Json::decode($_POST['keylist']);
// you will have the array of pk ids to process in $keys
// perform batch action on these keys and return status
// back to ajax call above
}
}
Console
Output
Give an id to the GridView like:
<?= GridView::widget([
'id'=>'mytable',
...
And in your js code, call this:
var rows = $('#mytable').yiiGridView('getSelectedRows');
There are two possible(Temporary) soutions you can try:
Solution 1::
In Index.php=>
//define action ::
$productupdate = '/rmprod/Rmtemplate/processSelected';
In column add this........
[
'class' => 'kartik\grid\CheckboxColumn'
'checkboxOptions' => function ($data) {
return ['value' => $data['product_primary_key'], 'class' => 'class_checkbox']; //primary_key=>product_primary_key
},
],
Add Jquery code(To post data) ::::
$('.class_checkbox').change(function()
{
var action_url = '<?= $productupdate; ?>';
if (this.checked) {
var product_data = $(this).attr('value'); //get product_primary_key
$.ajax({
method: "post",
url: action_url,
data: {product_data:product_data,_csrf: csrfToken}
}).done(function(data)
{
$('#LoadingMSG').hide();
console.log(data);
});
}
else
{
//you can apply another ajax to post data when checkbox unselect
}
});
In Controller=>
public function processSelected()
{
$getdata = Yii::$app->request->post(); //get posted data
//apply query to play with database by $getdata (primary_key)
}
Solution 2
In Index.php.............
[
'class' => 'kartik\grid\CheckboxColumn'
'checkboxOptions' => function ($data) {
return ['value' => $value1.'+'.$value2.'+'.$value3.'+'.$value4, 'class' => 'class_checkbox'];
},
],
Add Jquery code(To post data) ::::
$('.class_checkbox').change(function()
{
var action_url = '<?= $productupdate; ?>';
if (this.checked) {
var all_flds_data = $(this).attr('value');
$.ajax({
method: "post",
url: action_url,
data: {all_flds_data:all_flds_data,_csrf: csrfToken}
}).done(function(data)
{
$('#LoadingMSG').hide();
console.log(data);
});
}
else
{
//you can apply another ajax to post data when checkbox unselect
}
});
In Controller=>
public function processSelected()
{
$getdata = Yii::$app->request->post(); //get posted data
//after json_deocode you will get all posted data from ajax
}

Yii2 upload image from modal issue

I'm using yii2 bootstrap modal for uploading images, the issue is I need to double click on Create button then form submit works otherwise it don't work on single click.
On double click image is uploading and form data also saved to database.
Is this issue with my code?
Here is code:
//Form
<?php Pjax::begin(['id' => 'banner-form']) ?>
<?php $form = ActiveForm::begin([
'id' => 'banner-form',
'options' => [
'data-pjax' => true,
'enctype' => 'multipart/form-data'
]
]);
?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'banner')
->fileInput([
"accept"=>"image/*"
])
?>
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
<?php Pjax::end(); ?>
//Model
[['banner'], 'file', 'skipOnEmpty' => false,
'extensions' => ['jpg', 'jpeg', 'png', 'gif']
]
//index.php
<p>
<?= Html::a(Yii::t('app', 'Create Banner'), null, ['class' => 'btn btn-success', 'id'=>'createBannerButton',
'value'=>Url::to(['/banner/create'])]) ?>
</p>
<?php Pjax::begin(['id' => 'banner-index']) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
....
]); ?>
<?php Pjax::end(); ?>
//Controller
use yii\web\UploadedFile;
class BannerController extends Controller
{
...
public function actionCreate()
{
$model = new Banner();
if ($model->load(Yii::$app->request->post())){
$file = UploadedFile::getInstance($model, 'banner');
if (!empty($file))
$model->banner = $file;
if($model->save()){
if (!empty($file))
$file->saveAs( Yii::getAlias('#root') .'/uploads/' . $file);
return $this->redirect(['view', 'id' => $model->id]);
}
}
else if (Yii::$app->request->isAjax) {
return $this->renderAjax('create', [
'model' => $model,
]);
}
else {
return $this->render('create', [
'model' => $model,
]);
}
}
...
}
//layouts/main.php
<?php
Modal::begin([
'header' => '',
'id' => 'modal',
'size' => 'modal-medium', //medium
'clientOptions' => ['backdrop' => 'static', 'keyboard' => false]
]);
echo "<div id='modalContentBackend'>
<div class='col-lg'>
<img src='/images/loading.gif' width='280' height='210' alt='loading...'>
</div>
</di>";
Modal::end();
?>
<?php $this->endBody() ?>
//backend/web/js/custom.js
$(function(){
$("#createBannerButton").click(function(){
$("#modal").modal('show')
.find('#modalContentBackend')
.load($(this).attr('value'));
});
});
//backend/assets/AppAsset
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/site.css',
];
public $js = [
'js/custom.js'
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
I got the issue, I'm including Pjax::begin() in index.php and _form.php, I have removed Pjax::begin() from _form.php and now it is working fine.

PHP - Yii 2.0 Multiple images are save in folder but not saved in database

I have used use kartik\file\FileInput; (extension) for saving multiple images from single form submit.
The images are save locally but are not saving in the database.
Here is my Model Code media.php
namespace app\models;
use yii\web\UploadedFile;
class Media extends \yii\db\ActiveRecord
{
public function rules(){
return [
[['title'], 'file', 'skipOnEmpty' => false, 'extensions' => ['gif', 'jpg', 'png', 'jpeg', 'JPG', 'JPEG', 'PNG', 'GIF'], 'checkExtensionByMimeType' => false ,'maxFiles' => 4, 'maxSize' => 1024 * 1024 * 1024],
[['extension'], 'string', 'max' => 6],
];
}
Controller code:
if ($mediamodel->load ( Yii::$app->request->post () )) {
$title = UploadedFile::getInstances ( $mediamodel, 'title' );
foreach ($title as $key => $file) {
$file->saveAs(Yii::$app->basePath . '/web/images/hotel/'. $file->baseName . '.' . $file->extension);}
foreach ($title as $key => $file){
echo $mediamodel->title."*********";
$mediamodel->title = $file->baseName . '.' . $file->extension;
echo " \Title: ".$mediamodel->title;
$mediamodel->save ();
}
}
My view code:
use kartik\file\FileInput;
$form = ActiveForm::begin([ 'layout' => 'horizontal', {label}\n{beginWrapper}\n{input}\n{hint}\n{error}\n{endWrapper}",
'fieldConfig' => ['horizontalCssClasses' => ['label' => 'col-md-3','offset' => 'col-md-offset-2','wrapper' => 'col-md-4', 'error' => '','hint' => '',],],'
options' => [ 'class' => 'form-horizontal', 'enctype' => 'multipart/form-data', ], ]);?>
<?php echo $form->field($mediamodel, 'title[]')->widget(FileInput::classname(), ['options'=>['multiple' => true]]);
Html::submitButton($model->isNewRecord ? 'Add' : 'Update');
use
$mediamodel->save (false);
instead of
$mediamodel->save ();
// You should handle errors like this.
if(!$mediamodel->save()){
// handle the errors of model.
var_dump($mediamodel->getErrors());
}