Related
I have made a Listbox depend on a dropDownList, when selecting an option from the dropDownList brings me a list of data that is added to the Listbox, it works to save a single option but the problem occurs when trying to save multiple selections, I cannot save more than 1 option, I have tried to add a foreach in my controller but it throws an error.
DropDownList
<?php echo $form->field($model, 'group_id')->widget(Select2::classname(), [
'data' => $seccion->lgrupo, //I get the group list
'size' => Select2::MEDIUM,
'theme' => Select2::THEME_BOOTSTRAP,
'options' => [
'placeholder' => '-- '.Yii::t('backend', 'Select').' --',
'onchange'=>'
$.post( "lists?id="+$(this).val(), function( data ) {//I get the list of people registered in the group and send it to the listbox
$( "select#assignment-user_id" ).html( data );
});',
],
'pluginOptions' => [
'allowClear' => true,
],
'addon' => [
'prepend' => [
'content' => Html::icon('building')
],
]
]); ?>
ListBox
<?php echo $form->field($model2, 'users_id')->listBox([] ,['multiple'=>true,'size'=>17]
); ?>
Groups Controller
public function actionCreate()
{
$model = new Groups();
$model2 = new Assignment();
$seccion = new Group();
if ($model->load(Yii::$app->request->post()) && $model2->load(Yii::$app->request->post())) {
if ($model->save(false)) {
foreach ($model2->users_id as $i => $as) {
$as->assign_group_id = $model->id_group_list;
if ($model2->save()) {
} else {
// error in saving model
}
}
return $this->redirect(['view', 'id' => $model->id_group]);
}
}
return $this->render('create', [
'model' => $model,
'model2' => $model2,
'seccion' => $seccion,
]);
}
Tables
I hope your can tell me what I'm doing wrong.
public function actionCreate()
{
$model = new Groups();
$model2 = new Assignment();
$seccion = new Group();
if ($model->load(Yii::$app->request->post()) && $model2->load(Yii::$app->request->post())) {
if ($model->save(false)) {
foreach ($model2->users_id as $user_id) {
$assignmentModel = new Assignment();
$assignmentModel->user_id= $user_id;
$assignmentModel->assign_group_id = $model->id_group_list;
//$assignmentModel->area= ''; //if you want to set some value to these fields
//$assignmentModel->assignment= '';
if ($assignmentModel->save()) {
} else {
// error in saving model
}
}
return $this->redirect(['view', 'id' => $model->id_group]);
}
}
return $this->render('create', [
'model' => $model,
'model2' => $model2,
'seccion' => $seccion,
]);
}
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);
}
This is the continuation of question Pass data from a form to a controller in yii2 and Get data from textbox and pass to Controller in yii2.
I'm trying to generate a report by controllerAction actionStockbetweendates. The parameters for this productname, startdate, enddate comes from index2 through a javascript function on clicking of a button. In console I'm getting the following error.
index2.php
<?php
use yii\helpers\Html;
//use yii\grid\GridView;
use kartik\grid\GridView;
use kartik\export\ExportMenu;
use frontend\modules\stock\models\Sellitem;
use dosamigos\datepicker\DatePicker;
use dosamigos\datepicker\DateRangePicker;
use kartik\form\ActiveForm;
use yii\helpers\Json;
use yii\db\Query;
use yii\db\Command;
use kartik\mpdf\Pdf;
/* #var $this yii\web\View */
/* #var $searchModel frontend\modules\stock\models\SellitemSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Stock';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="sellitem-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<div class="row">
<div class="form-group">
<div class="col-xs-4 col-sm-4 col-lg-4">
<label for="upc" class="control-label"><p class="text-info">Product Code <i class="icon-star"></i></p></label>
<input type="text" class="form-control" id="upc" class="span3">
</div>
<div class="col-xs-4 col-sm-4 col-lg-4">
<label for="upc" class="control-label"><p class="text-info">Start Date <i class="icon-star"></i></p></label>
<?= DatePicker::widget([
//'label' => 'Startdate',
'name' => 'startdate',
'id' => 'startdate',
//'value' => '02-16-2012',
'template' => '{addon}{input}',
'clientOptions' => [
'autoclose' => true,
'todayHighlight' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
<div class="col-xs-4 col-sm-4 col-lg-4">
<label for="upc" class="control-label"><p class="text-info">End Date <i class="icon-star"></i></p></label>
<?= DatePicker::widget([
//'label' => 'Startdate',
'name' => 'enddate',
'id' => 'enddate',
//'value' => '02-16-2012',
'template' => '{addon}{input}',
'clientOptions' => [
'autoclose' => true,
'todayHighlight' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
</div>
</div>
<p>
<div class="form-group pull-right">
<button id="yourButton" class="btn btn-primary" >Seach</button>
</div>
</p>
</div>
<?php
/* start getting the itemid */
$this->registerJs(
"$('#yourButton').on('click', function() {
var productname = $('#upc').val();
var startdate = $('#startdate').val();
var enddate = $('#enddate').val();
//alert(uPc);
$.get('index.php?r=stock/sellitem/stockbetweendates',{ productname : productname, startdate : startdate, enddate : enddate}, function(data){
var data = $.parseJSON(data);
});
});"
);
/* end getting the itemid */
?>
ControllerAction
public function actionStockbetweendates($productname, $startdate, $enddate) {
$modelProduction = Puritem::find()->where(['pi_upc' => $productname]);
$searchModel1 = new PuritemsbSearch();
$dataProvider1 = $searchModel1->search(Yii::$app->request->queryParams, $productname);
$modelSell = Sellitem::find()->where(['si_iupc' => $productname]);
$searchModel2 = new SellitemsbSearch();
$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams, $productname);
$content = $this->renderPartial('_printproductledgerbtdt', [
'modelProduction' => $modelProduction,
'dataProvider1' => $dataProvider1,
'searchModel1' => $searchModel1,
//'data'=> $data,
'modelSell' => $modelSell,
'searchModel2' => $searchModel2,
'dataProvider2' => $dataProvider2,
'productname' => $productname,
//'prodesc' => $prodesc,
]);
$footer = "<table name='footer' width=\"1000\">
<tr>
<td style='font-size: 18px; padding-bottom: 20px;' align=\"right\">Signature</td>
</tr>
</table>";
$pdf = new Pdf([
'mode'=> Pdf::MODE_UTF8,
'format'=> Pdf::FORMAT_A4,
'destination'=> Pdf::DEST_BROWSER,
'orientation'=> Pdf::ORIENT_LANDSCAPE,
//'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 Party Ledger'],
//'options' => ['defaultfooterline' => 0,],
'options' => ['defaultheaderline' => 0,],
// call mPDF methods on the fly
'methods' => [
'SetHeader'=>['Ledger'],
//'SetFooter'=>[$footer],
],
'content' => $content,
]);
return $pdf->render();
//return $this->render('_printSalarystatement', ['s_period' => $s_period]);
return $this->render('index2', [
'upc' => $upc,
'startdate' => $startdate,
'enddate' => $enddate,
]);
}
updated javascript
<?php
/* start getting the itemid */
$this->registerJs(
"$('#yourButton').on('click', function() {
var productname = $('#upc').val();
var startdate = $('#startdate').val();
var enddate = $('#enddate').val();
//alert(uPc);
$.get('index.php?r=stock/sellitem/stockbetweendates',{ productname : productname, startdate : startdate, enddate : enddate});
});"
);
/* end getting the itemid */
?>
Updated Controller Action
public function actionStockbetweendates($productname, $startdate, $enddate) {
$modelProduction = Puritem::find()->where(['pi_upc' => $productname]);
$searchModel1 = new PuritemsbSearch();
$dataProvider1 = $searchModel1->search(Yii::$app->request->queryParams, $productname);
$modelSell = Sellitem::find()->where(['si_iupc' => $productname]);
$searchModel2 = new SellitemsbSearch();
$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams, $productname);
$content = $this->renderPartial('_printproductledgerbtdt', [
'modelProduction' => $modelProduction,
'dataProvider1' => $dataProvider1,
'searchModel1' => $searchModel1,
//'data'=> $data,
'modelSell' => $modelSell,
'searchModel2' => $searchModel2,
'dataProvider2' => $dataProvider2,
'productname' => $productname,
//'prodesc' => $prodesc,
]);
$footer = "<table name='footer' width=\"1000\">
<tr>
<td style='font-size: 18px; padding-bottom: 20px;' align=\"right\">Signature</td>
</tr>
</table>";
$pdf = new Pdf([
'mode'=> Pdf::MODE_UTF8,
'format'=> Pdf::FORMAT_A4,
'destination'=> Pdf::DEST_BROWSER,
'orientation'=> Pdf::ORIENT_LANDSCAPE,
//'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 Party Ledger'],
//'options' => ['defaultfooterline' => 0,],
'options' => ['defaultheaderline' => 0,],
// call mPDF methods on the fly
'methods' => [
'SetHeader'=>['Ledger'],
//'SetFooter'=>[$footer],
],
'content' => $content,
]);
return $pdf->render();
}
Output
Earlier used button to call Controller action and passing parameter
[
'class' => 'kartik\grid\ActionColumn',
'template' => '{ledger}',
'buttons' => [
'ledger' => function ($url, $model) {
//var_dump($model);
//exit;
return Html::a(
'<span class="glyphicon glyphicon-eye-open"></span>',
['/stock/sellitem/printproductledger', 'productname' => $model['i_upc'],'prodesc'=>$model['i_desc']],
[
'title' => 'Ledger',
'data-pjax' => '0',
]
);
},
],
],
Updated Controller Action
public function actionPrintproductledger2($productname) {
$productname = yii::$app->request->get('productname');
$prodesc = yii::$app->request->get('prodesc');
$modelProduction = Puritem::find()->where(['pi_upc' => $productname]);
$searchModel1 = new PuritemsbSearch();
$dataProvider1 = $searchModel1->search(Yii::$app->request->queryParams, $productname);
$modelSell = Sellitem::find()->where(['si_iupc' => $productname]);
$searchModel2 = new SellitemsbSearch();
$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams, $productname);
Yii::$app->response->format = Response::FORMAT_JSON;
return $this->render('_printproductledgerbtdt', [
'modelProduction' => $modelProduction,
'modelSell' => $modelSell,
'dataProvider1' => $dataProvider1,
'searchModel1' => $searchModel1,
'searchModel2' => $searchModel2,
'dataProvider2' => $dataProvider2,
'productname' => $productname,
'prodesc' => $prodesc,
]);
}
updated javascript
<?php
/* start getting the itemid */
$this->registerJs(
"$('#yourButton').on('click', function() {
var productname = $('#upc').val();
var startdate = $('#startdate').val();
var enddate = $('#enddate').val();
var desc = $('#desc').val();
//alert(productname);
//$.get('index.php?r=stock/sellitem/printproductledger2',{ productname : productname, startdate : startdate, enddate : enddate,prodesc:desc});
$.ajax({
type: 'GET',
url: 'index.php?r=stock/sellitem/printproductledger2',
data: { productname:productname, startdate : startdate, enddate : enddate,prodesc:desc},
contentType: 'application/json; charset=utf-8',
//dataType: 'json',
success: function() { alert('Success'); }
});
});"
);
/* end getting the itemid */
?>
You code can't work for several reason
so this is not properly an answer but some main suggetions
1) you are using this call for obtain data
$.get('index.php?r=stock/sellitem/stockbetweendates',
{ productname : productname, startdate : startdate, enddate : enddate},
function(data){
var data = $.parseJSON(data);
});
the data obtain are not correctly JSON formatted ..
If you need correct data JSON format you should encode_JSON properly in you action and send this data to the caller using an echo.
2 ) In you actionStockbetweendates
you have two time the return statement
]);
return $pdf->render();
//return $this->render('_printSalarystatement', ['s_period' => $s_period]);
return $this->render('index2', [
'upc' => $upc,
'startdate' => $startdate,
'enddate' => $enddate,
]);
obviously only the firts work .. and (could be) render a pdf ..
but in this way yuo are not sending nothings to the ajax caller ($.get...)
My suggestion is that you split you code in separated function .. each of this specifically related to a single need .
And for pdf try using
'mode' => Pdf::MODE_BLANK,
instead of ( 'mode'=> Pdf::MODE_UTF8,)
I want to use dynamic form in yii2(http://wbraganca.com/yii2extensions) here is my code:
part of controller:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelsProductImage = $model->images;
if ($model->load(Yii::$app->request->post())) {
$oldIDs = ArrayHelper::map($modelsProductImage, 'id', 'id');
$modelsProductImage = Model::createMultiple(ProductImage::classname(), $modelsProductImage);
Model::loadMultiple($modelsProductImage, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsProductImage, 'id', 'id')));
foreach ($modelsProductImage as $index => $modelProductImage) {
$modelProductImage->sort_order = $index;
$modelProductImage->product_id = $model->id;
//echo $modelProductImage->file = UploadedFile::getInstance($modelProductImage, "[{$index}]file");
$file = UploadedFile::getInstanceByName($index);
print_r($file);
}
}
}
and this is my view file:
<?php $form = ActiveForm::begin([
'id' => 'dynamic-form',
'options' => [
'enctype' => 'multipart/form-data'
],
]); ?>
<?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' => $modelsProductImage[0],
'formId' => 'dynamic-form',
'formFields' => [
'id',
//'path',
'product_id',
],
]); ?>
<?php foreach ($modelsProductImage as $index => $modelProductImage): ?>
<div class="item panel panel-default col-md-3"><!-- widgetBody -->
<div class="panel-heading">
<span class="panel-title-address"><?= Yii::t('app','Image').':'. ($index + 1) ?></span>
<button type="button" class="pull-left remove-item btn btn-danger btn-xs"><i class="fa fa-minus"></i></button>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (!$modelProductImage->isNewRecord) {
echo Html::activeHiddenInput($modelProductImage, "[{$index}]id");
}
?>
<?php
$modelImage = $modelProductImage;
$initialPreview = [];
if ($modelImage) {
$pathImg = '/'.$modelImage->path;
$initialPreview[] = Html::img($pathImg, ['class' => 'file-preview-image']);
}
?>
<div class="">
<?= $form->field($modelProductImage, "[{$index}]file")->label(false)->widget(FileInput::classname(), [
'options' => [
'multiple' => false,
'accept' => 'image/*',
'class' => 'productImage-path',
'name' => $index
],
'pluginOptions' => [
'previewFileType' => 'image',
'showCaption' => false,
'showUpload' => false,
'browseClass' => 'btn btn-default btn-sm',
//'browseLabel' => Yii::t('app',' Pick Image'),
'browseIcon' => '<i class="glyphicon glyphicon-picture"></i>',
'removeClass' => 'btn btn-danger btn-sm',
//'removeLabel' => ' Delete',
'removeIcon' => '<i class="fa fa-trash"></i>',
'previewSettings' => [
'image' => ['width' => '138px', 'height' => 'auto']
],
'initialPreview' => $initialPreview,
'layoutTemplates' => ['footer' => '']
]
]) ?>
</div>
</div>
</div>
<?php endforeach; ?>
When i use getInstanceByName in controller it only return one file, and when i use getInstance it return NULL
and when i use getInstanceByname it save new file on old file(not as a new file)
Are you see example? docs
This is part of example from docs:
...
$modelsOptionValue = Model::createMultiple(OptionValue::classname());
Model::loadMultiple($modelsOptionValue, Yii::$app->request->post());
foreach ($modelsOptionValue as $index => $modelOptionValue) {
$modelOptionValue->sort_order = $index;
$modelOptionValue->img = \yii\web\UploadedFile::getInstance($modelOptionValue, "[{$index}]img");
}
...
Have you tried \yii\web\UploadedFile::getInstances()?
You can check the details here
It there any way to make 'data-confirm' => Please enter the number' not just confirm but some like JS prompt and get imputed values to sent it to controller?
<?php \yii\widgets\Pjax::begin(['id' => 'pjax-orders_table','clientOptions' => ['method' => 'POST'], 'enablePushState'=>false]) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'id'=>'orders_table',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
///some columns
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}{some}',
'buttons' => [
'some' => function ($url,$model,$key) {
if($model->status=='not confirm')
{
return Html::a('<span class="glyphicon glyphicon-trash"</span>',['my/some', 'id' => $model->id],[
'title' => Yii::t('yii', 'Delete'),
'data-confirm' => Please enter the number',
'data-method' => 'post',
]);
}
},
],
],
],
]); ?>
<?php \yii\widgets\Pjax::end() ?>
In controller
public actionSome()
{ $dataProvider = new ActiveDataProvider();
$dataProvider->query = Orders::find()->all();
return $this->render('some',['dataProvider'=>$dataProvider]);
}
instead of Html::a() use Html::button()where button id = some_item_id and then write this JS code
$('.buttons_class').click(function(){
var selection;
do{
selection = parseInt(window.prompt("Please enter a number from 1 to 100", ""), 10);
}
while(isNaN(selection));
if(!isNaN(selection))
{
$.post("some",{id:45,prompt_value:selection}, function(response)
{
console.log(response);
$.pjax.reload({container:'#pjax-orders_table'});
});
}
})