Yii2 Dynamic model and Ajax missing data issue - ajax

I get only partial data in controller. here is the situation
my action in controller that show the view with the form:
$model_sms = array();
$model_sms = new \yii\base\DynamicModel(['sms_code', 'iduser', 'mail_status', 'signup_control']);
$model_sms->addRule(['sms_code, iduser, mail_status, signup_control'], 'required');
$model_sms->addRule(['iduser, mail_status, signup_control'], 'integer');
$model_sms->addRule('sms_code', 'string', ['min' => 5, 'max' => 5]);
$model_sms->iduser = $user->id;
$model_sms->mail_status = $mail_status;
$model_sms->signup_control = 1;
return $this->renderAjax('_sms_confirmation', ['model_sms' => $model_sms]);
then the view code is here
<?php
use yii\helpers\Html;
use kartik\form\ActiveForm;
?>
<div class=" site-login">
<?php $form = ActiveForm::begin(['id' => 'frmsmsconfirm', 'action'=>'/index.php?r=site/confirmsms']); ?>
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-10">
<div class="formSeparator"><span>Enter SMS code</span></div>
<p class="logtxt">Please fill out the following fields to login:</p>
<?php
echo $form->field($model_sms, 'iduser')->hiddenInput()->label(false);
echo $form->field($model_sms, 'mail_status')->hiddenInput()->label(false);
echo $form->field($model_sms, 'signup_control')->hiddenInput()->label(false);
echo $form->field($model_sms, 'sms_code', [
'feedbackIcon' => [
'default' => 'phone',
'success' => 'ok',
'error' => 'exclamation-sign',
'defaultOptions' => ['class'=>'cw']
]
])->textInput(['placeholder'=>'Enter SMS code', 'class'=>'newxinput xinput'])->label('SMS code');
?>
</div>
<div class="col-md-1">
</div>
</div>
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-10">
<div class="scforget">
If you did not receive SMS <?= Html::a('send it again', ['site/smsresend']) ?>.
</div>
</div>
<div class="col-md-1">
</div>
</div>
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-10"><br><br>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'xsubbtn', 'name' => 'login-button']) ?>
</div><br><br>
</div>
<div class="col-md-1">
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<script>
$('#frmsmsconfirm').on('submit', function(e){
e.preventDefault();
e.stopImmediatePropagation();
var form = $(this);
alert('ajax start');
alert(form.serialize());
$.ajax({
url : form.attr('action'),
type : 'post',
data : form.serialize(),
success: function (response)
{
alert('radi a ne radi... hm');
$('#sc_content').html(response);
},
error: function ()
{
console.log('internal server error');
}
});
});
</script>
I get all correct data in alert(serialize.form), but when it is passed to another action in controller I only get sms_code, other 3 fields come blank... here is the code...
$model_sms = array();
$model_sms = new \yii\base\DynamicModel(['sms_code', 'iduser',
'mail_status', 'signup_control']);
$model_sms->addRule(['sms_code, iduser, mail_status,
signup_control'], 'required');
$model_sms->addRule(['iduser, mail_status, signup_control'],
'integer');
$model_sms->addRule('sms_code', 'string', ['min' => 5, 'max' =>
5]);
$model_sms->load(Yii::$app->request->post());
echo $model_sms->sms_code.'- xxx - <br>';
echo $model_sms->iduser.'- xxx - <br>';
echo $model_sms->mail_status.'- xxx - <br>';
echo $model_sms->signup_control.'- xxx - <br>';
exit;
Does anybod have any idea?
Thanks

You have an error at your 2 addRule() definitions:
$model_sms->addRule(['sms_code, iduser, mail_status, signup_control'], 'required');
$model_sms->addRule(['iduser, mail_status, signup_control'], 'integer');
should be:
$model_sms->addRule(['sms_code', 'iduser', 'mail_status', 'signup_control'], 'required');
$model_sms->addRule(['iduser', 'mail_status', 'signup_control'], 'integer');
The 1st parameter of addRule should be an array of attributes.

Related

How to use plugins in chartjs and laravel chart consoletvs/chartsjs

Need use chartjs plugin datalabels in laravel 5.8 and consoletvs/chartsjs ver 6.*
This line generate a error in laravel.
$chart->plugins(['datalabels'=>['color'=>'#223388']]);
$chart = new Chart;
$chart->labels($arrHora);
$chart->dataset('Propostas Por Hora','bar', $arrQtdHora)
->backgroundColor('#64b5f6');
$chart->options([
'responsive' => true,
//'aspectRatio' => 1,
'tooltips' => ['enabled'=>false],
'legend' => ['display' => false],
'scales' => [
'yAxes'=> [[
'display'=>false,
'ticks'=> ['beginAtZero'=> true],
'gridLines'=> ['display'=> false],
]],
'xAxes'=> [[
'categoryPercentage'=> 0.55,
//'barThickness' => 100,
'barPercentage' => 0.5,
'ticks' => ['beginAtZero' => true],
'gridLines' => ['display' => false],
]],
],
]);
$chart->plugins(['datalabels'=>['color'=>'#223388']]);
//dd($chart);
//->backgroundColor('#64b5f6');
return view('dashboard', ['chart' => $chart]);
Two things I have to clarify, after playing around with the library, I came up with the following results:
First: The function $chart->plugins is used to create inline plugins only, under chartjs/script.blade.php the file begins with:
So for each plugin array that you define it will load a view from the pluginsView array that have the same name, but I think this is not full developed yet, and since this is not what the question is about lets move on.
Second: You can perfectly a nested option use options -> plugin like I have suggested before, but there's one thing that you will have to be careful whit, is that 'plugins' can't be an array like the others, and here is why:
The function expects a string to be printed raw, so with that you can use something like:
$chart->options([
//...
'plugins' => '{datalabels: {color: \'red\'}}',
//...
]);
Which will work as expected:
I share here the complete solution of my code and if you have any comments or suggestions, you will be welcome.
/* Controller */
<?php
namespace App\Http\Controllers\dashboard;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use ConsoleTVs\Charts\Classes\Chartjs\Chart;
use DB;
class DashBoardController extends Controller
{
public function index() {
$result = DB::select('select
convert(varchar(10),data_da_solicitacao,121) data,
convert(varchar(2),data_da_solicitacao,114) hora,
COUNT(id_controle_proposta_pac) qtdHora
from contact_std_parceiros_propostas (nolock) p
where convert(varchar(10),data_da_solicitacao,121) between convert(varchar(10),getdate(),121) and convert(varchar(10),getdate(),121)
and not exists (select * from contact_std_parceiros_propostas_fora (nolock) f where f.id_controle_proposta_pac = p.id_controle_proposta_pac)
Group by convert(varchar(10),data_da_solicitacao,121), convert(varchar(2),data_da_solicitacao,114)
Order by 1');
$arrHora = array();
$arrQtdHora = array();
$i = 0;
foreach ( $result as $r )
{
$arrHora[$i] = $r->hora;
$arrQtdHora[$i] = $r->qtdHora;
$i++;
}
$chart = new Chart;
$chart->labels($arrHora);
$chart->dataset('Propostas Por Hora no dia de hoje','bar', $arrQtdHora)->backgroundColor('#64b5f6');
$chart->options([
'responsive' => true,
'legend' => ['display' => true],
'tooltips' => ['enabled'=>true],
//'aspectRatio' => 1,
'scales' => [
'yAxes'=> [[
'display'=>false,
'ticks'=> ['beginAtZero'=> true],
'gridLines'=> ['display'=> false],
]],
'xAxes'=> [[
'categoryPercentage'=> 0.8,
//'barThickness' => 100,
'barPercentage' => 1,
'ticks' => ['beginAtZero' => true],
'gridLines' => ['display' => false],
]],
],
'plugins' => '{datalabels: {color: \'red\'}}',
]);
return view('dashboard',compact('chart'));
}
}
/* view */
#extends('layout.main')
#section('titulo','Pac - DashBoard')
#section('conteudo')
<div class="row">
<div class="col s6 col m12 l12">
<div class="x_panel">
<div class="x_title">
<div class="col s6 m6 l6"><h2>Propostas do dia</h2></div>
<ul class="nav navbar-right panel_toolbox">
<li><a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
</li>
<li><a class="close-link"><i class="fa fa-close"></i></a></li>
</ul>
<div class="clearfix"></div>
</div>
<div class="x_content" style="display: block;">
<div class="row">
<div class="row top_tiles" id="card-0"></div>
<div class="row">
<div class="col s4 m7 l7">
<div id="graph-0" class="x_panel" style="height: 250px">
<!--<canvas id="bar-0" style="width: 70% !important;height: auto !important;">-->
{!! $chart->container() !!}
#foreach($chart->plugins as $plugins)
#include($chart->pluginsViews[$plugins])
#endforeach
<!--</canvas>-->
</div>
</div>
<div class="col s3 m5 l5">
<div id="graph-1" class="x_panel">
<canvas id="pie-1" style="width: 100% !important;height: auto !important;"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{!! $chart->script() !!}
#endsection

how can i show this $data value in the form input field?

how to show $data value in form input field?
<head>
<script>
$(function () {
$("#task_id").change(function () {
var task_id = $(this).val();
var url = "status/tasks/get_task_info/" + task_id;
$.ajax({
url: url,
beforeSend: function () {
$(".load-taskinfo").html('<img src="images/ajax/ajax-loader10.gif">');
},
success: function (response) {
$data = JSON.parse(response);
}
});
});
});
</script>
</head>
<body>
<div class="span3">
<div class="control-group <?php echo (form_error('progress_percent')) ? 'error' : ''; ?>">
<label class="control-label" for="progress_percent">Progress (In %) :</label>
<div class="controls">
<?php echo form_input(array(
'name' => 'progress_percent',
'id' => 'progress_percent',
'maxlength' => 160
)); ?>
<?php if (form_error('progress_percent')) : ?>
<span class="help-inline">
<?php echo form_error('progress_percent'); ?>
</span>
<?php endif; ?>
</div>
</div>
</div>
</body>
In your success callback, use jQuery selector to select the input by ID or by name, and fill its value.
success: function (response) {
var $data = JSON.parse(response);
$('#progress_percent').val($data);
}

Yii2 conditional validation on radio box

I'm trying to use conditional validation on a attribute account_no. It should be validate only when I select the value 'old' in the attribute account_version. But it is not working. The error I'm getting is validation is required for newalso. Should I use javascript instead to validate
My code in model
return [
['account_no', 'required', 'when' => function($model) {
return $model->account_version == 'Old';
}],
]
My code in form
<?php if ($model->isNewRecord) {?>
<div class="row">
<div class="col-md-2">
<label for="">Account Version</label>
</div>
<div class="col-md-2">
<?php echo $form->field($model, 'account_version')->radioList(['New'=>'New','Old'=>'Old'])->label(false); ?>
</div>
<div id="action_block" class="col-md-6">
<div class="col-md-3">
<label for="">Account No:</label>
</div>
<div class="col-md-3">
<?= $form->field($model, 'account_no')->textInput(['maxlength' => true])->label(false) ?>
</div>
</div>
</div>
<?php } ?>
Model
[['account_no'], 'required', 'when' => function ($model) { return $model->account_version == 'Old'; }, 'whenClient' => "function (attribute, value) { return $('#modelName[account_version]').val() == 'Old'; }"],
Form
<?php $form = ActiveForm::begin(['id' => 'account-form', 'enableAjaxValidation' => true]); ?>
Controller
if($model->load(Yii::$app->request->post())) {
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return yii\widgets\ActiveForm::validate($model);
}
}
<?php
return [
['account_no', 'required', 'when' => function ($model) {
return $model->account_no == 'Old';
}, 'whenClient' => "function (attribute, value) {
return $('#account_no').val() == 'Old';
}"]
]
?>
http://www.yiiframework.com/doc-2.0/guide-input-validation.html [reference links]

Input image in Yii2 Dynamic Form always null

I want to make dynamic input that save an image to my website.
I use yii2-dynamicform and Kartik input file extension. But, it always save it as null.
Thank you for your help
Ps : ... is other part of my code that not relevant with this question. :)
In controller :
<?php
namespace frontend\controllers;
use Yii;
use common\models\Election;
use common\models\ElectionSearch;
use common\models\Model;
use common\models\Kandidat;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\data\ActiveDataProvider;
use yii\web\Session;
use yii\web\UploadedFile;
use yii\helpers\ArrayHelper;
class ElectionController extends Controller
{
...
public function actionCreate()
{
$model = new Election();
$modelsKandidat = [new Kandidat];
if ($model->load(Yii::$app->request->post())){
$model->save();
$modelsKandidat = Model::createMultiple(Kandidat::classname());
Model::loadMultiple($modelsKandidat, Yii::$app->request->post());
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsKandidat) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
foreach ($modelsKandidat as $modelKandidat) {
$modelKandidat->id_election = $model->id_election;
if($modelKandidat->file = UploadedFile::getInstance($modelKandidat,'file'))
{
$imageName = date('dmyhis_').$modelKandidat->id_election;
$modelKandidat->file->saveAs('../../common/file/fotokandidat/'.$imageName.'.'.$modelKandidat->file->extension);
$modelKandidat->foto = $imageName.'.'.$modelKandidat->file->extension;
}
if (! ($flag = $modelKandidat->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id_election]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
} else {
return $this->render('create', [
'model' => $model,
'modelsKandidat' => $modelsKandidat,
]);
}
}
...
}
In _form :
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\file\FileInput;
use yii\helpers\ArrayHelper;
use dosamigos\datepicker\DatePicker;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<div class="election-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data', 'id' => 'dynamic-form']]); ?>
...
<!-- mulai input kandidat !-->
<div class="row">
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i>Vote</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' => $modelsKandidat[0],
'formId' => 'dynamic-form',
'formFields' => [
'nama',
'deskripsi',
'riwayat',
'file',
],
]); ?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($modelsKandidat as $i => $modelsKandidat): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<h3 class="panel-title pull-left">Kandidat</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 (! $modelsKandidat->isNewRecord) {
echo Html::activeHiddenInput($modelsKandidat, "[{$i}]id_kandidat");
}
?>
<div class="row">
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]nama")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]deskripsi")->textarea(['rows' => 6]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]riwayat")->textarea(['rows' => 6]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]file")->fileInput() ?>
</div>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
</div>
</div>
<!-- selesai input kandidat !-->
...
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
It's from #shoara/#zahraj answer :
I think you forgot to specify index for your file `
foreach ($modelsKandidat as $keyindex=>$modelKandidat)
{
$modelKandidat->id_election = $model->id_election;
if ($modelKandidat->file = UploadedFile::getInstance($modelKandidat, "[{$keyindex}]file")) {
.......
}
}
see demo controller and form part,imagine $modelCatalogOption in demo is your $model = new Election(); and $modelsOptionValue is your $modelsKandidat = [new Kandidat]; if you try and check your values in your controller I'm sure you can solve this problem easily. Pay attention to actionCreate

Rendering part of form in main view

Is there any way to render partial view using AJAX that is a part of form which other part starts ActiveForm->begin() in main view?
Controller:
public function actionCreate()
{
$model = new order();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
try {
if ($model->save()) {
Yii::$app->getSession()->setFlash('success', 'New record has been saved.');
return $this->redirect(['index']);
}
}
catch(yii\db\IntegrityException $e) {
Yii::$app->getSession()->setFlash('error', 'Cannot save new record. Please try again.');
return $this->redirect(['index']);
}
}
else {
return $this->render('create', ['model' => $model, ]);
}
}
public function actionSpecialdetform()
{
$model = new order();
return $this->renderAjax('_specialform');
}
public function actionDetform()
{
$model = new order();
return $this->renderAjax('_form');
}
View (main - create.php):
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $model app\models\order */
$this->title = 'Create';
$this->params['breadcrumbs'][] = ['label' => 'Orders', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="order-create">
<h1><?= Html::encode($this->title) ?></h1>
<?php $form = ActiveForm::begin(['enableAjaxValidation' => true,]); ?>
<div class="panel panel-default wizard" id="order-wizard">
<div class="wizard-steps clearfix" id="form-wizard">
<ul class="steps">
<li data-target="#step1" class="active"><span class="badge badge-info">1</span>Order</li>
<li data-target="#step2"><span class="badge">2</span>Details</li>
</ul>
</div>
<div class="step-content clearfix">
<div class="step-pane active" id="step1">
<?php echo $form->field($model, 'order_date')->input(); ?>
</div>
<div class="step-pane" id="step2">
<div id="order-details">
</div>
</div>
<div class="actions pull-left">
<button type="button" class="btn btn-default btn-sm btn-prev wizard-btn" disabled="disabled"><i class="fa fa-angle-double-left" style="margin-right:5px"></i> Previous step</button>
<button type="button" class="btn btn-default btn-sm btn-next wizard-btn" data-last="Save">Next step <i class="fa fa-angle-double-right" style="margin-left:5px"></i></button>
</div>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$js = '
$(document).ready(function() {
$("#order-wizard").on("change", function(e, data) {
if(data.step===1 && data.direction==="next")
{
var date = $("#order-order_date").val();
if(date==="")
{
e.preventDefault();
}
var form = null;
if(date === "2015-01-01")
{
form = "/order/specialdetform"
}
else
{
form = "order/detform"
}
$.ajax({
url: form,
dataType: "html",
success: function(data) {
$("#order-details").html(data);
}
});
}
});
});
';
$this->registerJs($js, \yii\web\View::POS_END);
?>
Partial View - (_specialform.php):
<?= $form->field($model, 'promo_code')->input(); ?>
<?= $form->field($model, 'Surname')->input(); ?>
Partial View - (_form.php):
<?= $form->field($model, 'Surname')->input(); ?>
I don't want to just create one partial view, because this is only one different field, but it's an example.

Resources