I am trying to use Yii2's conditional validator within DynamicModel clas, but the validator when is not working:
Controller
private function createFormModel(){
$model = new DynamicModel([
'indicador',
'departamento',
'mes'
]);
$model->addRule(['indicador'],'required',['message' => 'Este campo es obligatorio']);
$model->addRule(['departamento'], 'required', ['when' => function ($model) {
return $model->indicador == 'Semana';
}]);
return $model;
}
public function actionCuatrimestre()
{
$model = $this->createFormModel();
return $this->render('cuatrimestre',[
'model' => $model,
]);
}
Whether I select or not the "indicador" field which is a select field, the "departamento" field alwasys returns as required. I have algo try this way but with no results:
$model->addRule(['departamento'], 'required', ['when' => function ($model) {
return $model->indicador == 'Semana';
}], ['whenClient' => "function (attribute, value) {
return $('#indicador').val() == 'Semana';
}"]);
What I am missing here?
EDIT
My view code cuatrimestre.php
<?php $form = ActiveForm::begin(); ?>
<div class="form-group">
<?= $form->field($model, 'indicador')->widget(Select2::class, [
'options' => ['id'=>'indicador'],
'data' => ['Semana','Día','Resumen'],
]); ?>
</div>
<div class="form-group">
<?= $form->field($model, 'departamento')->widget(Select2::class, [
'options' => ['id'=>'departamento'],
'data' => Departamentos::getDepartamentosByUser(),
]); ?>
</div>
<div class="form-group">
<?= $form->field($model, 'curso')->widget(DepDrop::class, [
'type' => DepDrop::TYPE_SELECT2,
'options' => ['id' => 'curso-id'],
'select2Options' => ['pluginOptions' => ['allowClear' => true]],
'pluginOptions' => [
'depends' => ['departamento-id'],
'placeholder'=>'Seleccionar curso',
'url' => Url::to(['/campus-actividad/subcursos']),
'loadingText' => 'Cargando ...',
'initialize' => true,
]
]);?>
</div>
<div>
<?= Html::submitButton('Aplicar filtros', ['class' => 'btn btn-block btn-default']) ?>
<?php ActiveForm::end(); ?>
</div>
Related
I have a form and I want to change my DynamicModel rule validations depedending on the value chosen in a specific select input. I've read this doc but I don't understand why my code doesn't work. I've tried the following with no results:
MyController
private function createFormModel(){
$model = new DynamicModel([
'indicador',
'mes'
]);
$model->addRule(['indicador'], 'required',['message' => 'This field is required']);
$model->addRule(['mes'], 'string');
$model->addRule(
'mes',
function ($attribute, $params, $validator) use ($model) {
if ($model->indicador == 'semana') {
$model->addError('mes', 'This field is required');
}
}
);
return $model;
}
MyView
<?php $form = ActiveForm::begin(); ?>
<!-- indicador -->
<div class="form-group">
<?= $form->field($model, 'indicador')->widget(Select2::class, [
'options' => ['id'=>'indicador'],
'data' => [
'dia' => 'Actividad por Día',
'semana' => 'Actividad por Semana',
'resumen' => 'Resumen de actividad'
],
'pluginOptions' => [
'placeholder'=>'Seleccionar indicador',
'allowClear' => true
],
]); ?>
</div>
<!-- /.indicador -->
<!-- mes -->
<div id = "semana" class="form-group hidden">
<?= $form->field($model, 'mes')->widget(DepDrop::class, [
'type' => DepDrop::TYPE_SELECT2,
'options' => ['id' => 'mes'],
'select2Options' => ['pluginOptions' => ['allowClear' => true]],
'pluginOptions' => [
'depends' => ['indicador'],
'placeholder'=>'Seleccionar mes',
'url' => Url::to(['/campus/subindicador']),
'loadingText' => 'Cargando ...',
'initialize' => true,
]
]);?>
</div>
<!-- /.mes -->
<?= Html::submitButton('Aplicar filtros', ['class' => 'btn btn-block btn-default']) ?>
<?php ActiveForm::end(); ?>
You need to use when with required validator.
$model = new DynamicModel(['indicador', 'mes']);
$model->addRule(['indicador'], 'required', ['message' => 'This field is required']);
$model->addRule(['mes'], 'string');
$model->addRule(['mes'], 'required', ['when' => function ($dModel) {
return $dModel->indicador == 'semana';
}, 'message' => 'This field is required']);
The model is Booking.php. I need to get data from another model called ServiceCategory.php and add a filter to it in Gridview on my index.php. I created filter on view/index.php as below.
['label' => 'Service Category', 'attribute' => 'category.name', 'filter' => ArrayHelper::map(app\models\Servicecategory::find()->where(['status' => true])->asArray()->all(), 'id', 'name')],
This is my index.php
<?php
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use yii\grid\GridView;
use app\models\Servicecategory;
/* #var $this yii\web\View */
/* #var $searchModel app\models\BookingSerach */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Bookings';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="list-booking">
<h1 class=""><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p class="form-inline text-right">
<label>Client:</label>
<?= Html::dropDownList('client', null, ArrayHelper::map($clients, 'id', 'fullname'), ['prompt' => 'Please Select', 'class' => 'form-control']) ?>
<?= Html::a('+ New Booking', ['booking/create/'], ['class' => 'btn btn-primary client-create']) ?>
</p>
<?=
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
['label' => 'Client', 'value' => 'user.client.view', 'format' => 'raw'],
'postCode',
'start',
'end',
['label' => 'Service Category', 'attribute' => 'category.name', 'filter' => ArrayHelper::map(Servicecategory::find()->where(['status' => true])->asArray()->all(), 'id', 'name')],
//'numberOfDays',
//'date',
//'followUpEmail:email',
// 'followUpEmailSent:ckeckbox',
//'Status',
['attribute' => 'status', 'value' => 'Status', 'filter' => array_filter(\app\models\Booking::$statuses)],
['class' => 'yii\grid\CheckboxColumn',
'header' => 'follow Up',
'checkboxOptions' => function($model, $key, $index) {
$url = \yii\helpers\Url::to(['booking/followup/' . $model->id]);
return ['onclick' => 'js:followUp(this, "' . $url . '")', 'checked' => false, 'id' => 'followup'];
}
],
['class' => 'yii\grid\ActionColumn',
'headerOptions' => ['style' => 'width:15%'],
'template' => '{view} {approval} {update} {delete} ',
'buttons' => [
'view' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', ['/booking/review/' . $model->id], [
'title' => Yii::t('app', 'Review'),
]);
},
'approval' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-ok"></span>', ['/booking/approval/' . $model->id], [
'title' => Yii::t('app', 'Additional Details'),
'class' => 'error',
]);
},
],
],
],
]);
?>
</div>
<?php
$script = <<< JS
$('.client-create').on('click', function () {
select = $(this).prev();
if(select.val()){
location.href = $(this).attr('href')+"/"+select.val();
} else {
$(this).parent().addClass('has-error');
}
return false;
});
JS;
$this->registerJs($script);
$this->registerJs("
function followUp(e, url){
$('#modal').modal('show').find('#modalContent').load(url);
}", yii\web\View::POS_END);
?>
I can get the data to the column on gridview but the filter is not working. Can anyone help me with this?
I solved it myself. For your information I post it here. I changed the attribute as the model contains and added the value as category.name
['attribute' => 'categoryID', 'value' => 'category.name','filter' => ArrayHelper::map(Servicecategory::find()->where(['status' => true])->asArray()->all(), 'id', 'name')],
If I try to update records,I get following error without any ideas, what's about or what this error could have been caused by.
Furthermore, it's strange, that this error only will be bred by records having been imported by a dump. There will be no error, if I will update a record having been created using saveasnew option. Unfortunately, I can't delete this record in order to recreate it,'cause it would expel against referential integrity.
Here is error:
Invalid Configuration – yii\base\InvalidConfigException
Unable to locate message source for category 'mtrelt'.
throw new InvalidConfigException("Unable to locate message source for category '$category'.")
2. in ...\vendor\yiisoft\yii2\i18n\I18N.php at line 88 – yii\i18n\I18N::getMessageSource('mtrelt')
3. in ...\vendor\yiisoft\yii2\BaseYii.php at line 509 – yii\i18n\I18N::translate('mtrelt', 'Data can't be deleted because it...', [], 'de-DE')
4. in ...\vendor\mootensai\yii2-relation-trait\RelationTrait.php at line 312 – yii\BaseYii::t('mtrelt', 'Data can't be deleted because it...')
Here is model:
<?php
namespace common\modules\lookup\models\base;
use Yii;
use mootensai\behaviors\UUIDBehavior;
class LPersonArt extends \yii\db\ActiveRecord
{
use \mootensai\relation\RelationTrait;
public function relationNames()
{
return [
'eAppEinstellungArts',
'lKontaktVerwendungszwecks',
'people'
];
}
public function rules()
{
return [
[['person_art'], 'string', 'max' => 50],
[['zieltabelle'], 'string', 'max' => 100],
[['bemerkung'], 'string', 'max' => 255]
];
}
public static function tableName()
{
return 'l_person_art';
}
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'person_art' => Yii::t('app', 'Personengruppen'),
'zieltabelle' => Yii::t('app', 'Zieltabelle'),
'bemerkung' => Yii::t('app', 'Bemerkung'),
];
}
public function getEAppEinstellungArts()
{
return $this->hasMany(\common\modules\erweiterung\models\EAppEinstellungArt::className(), ['id_person_art' => 'id']);
}
public function getLKontaktVerwendungszwecks()
{
return $this->hasMany(\common\modules\lookup\models\LKontaktVerwendungszweck::className(), ['id_person_art' => 'id']);
}
public function getPeople()
{
return $this->hasMany(\common\modules\basis\models\Person::className(), ['id_person_art' => 'id']);
}
public function behaviors()
{
return [
'uuid' => [
'class' => UUIDBehavior::className(),
'column' => 'id',
],
];
}
public static function find()
{
return new \common\modules\lookup\models\LPersonArtQuery(get_called_class());
}
}
Here is Controller:
public function actionUpdate($id)
{
$model = new LPersonArt();
if (!Yii::$app->request->post('_asnew') == '1'){
$model = $this->findModel($id);
}
if ($model->load(Yii::$app->request->post()) && $model->saveAll()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
Here is view:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="lperson-art-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->errorSummary($model); ?>
<?= $form->field($model, 'id', ['template' => '{input}'])->textInput(['style' => 'display:none']); ?>
<?=
$form->field($model, 'person_art')->widget(\jlorente\remainingcharacters\RemainingCharacters::classname(), [
'type' => \jlorente\remainingcharacters\RemainingCharacters::INPUT_TEXTAREA,
'text' => Yii::t('app', '{n} characters remaining'),
'options' => [
'rows' => '3',
'class' => 'col-md-12',
'maxlength' => 50,
'placeholder' => Yii::t('app', 'Write something')
]
])
?>
<?=
$form->field($model, 'bemerkung')->widget(\jlorente\remainingcharacters\RemainingCharacters::classname(), [
'type' => \jlorente\remainingcharacters\RemainingCharacters::INPUT_TEXTAREA,
'text' => Yii::t('app', '{n} characters remaining'),
'options' => [
'rows' => '3',
'class' => 'col-md-12',
'maxlength' => 255,
'placeholder' => Yii::t('app', 'Write something')
]
])
?>
<div class="form-group">
<?php if (Yii::$app->controller->action->id != 'save-as-new'): ?>
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?php endif; ?>
<?php if (Yii::$app->controller->action->id != 'create'): ?>
<?= Html::submitButton(Yii::t('app', 'Save As New'), ['class' => 'btn btn-info', 'value' => '1', 'name' => '_asnew']) ?>
<?php endif; ?>
<?= Html::a(Yii::t('app', 'Cancel'), Yii::$app->request->referrer, ['class' => 'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Problem will be solved adding following code into components of
common/config/main-local.php
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#backend/messages', // if advanced application, set #frontend/messages
'sourceLanguage' => 'de',
],
],
],
I was having a similar problem, but the Yii2 error message was
Unable to locate message source for category ''
I was running Gii from console:
php yii gii/crud --controllerClass="app\controllers\StcDocumentTypeController" --messageCategory="stc_document_type" --enableI18N=1 --enablePjax=1 --interactive=0 --modelClass="app\models\StcDocumentType" --searchModelClass="app\models\StcDocumentTypeSearch" --overwrite=1
The solution was to add the i18n configuration on the console.php config file:
'components' => [
...
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
'sourceLanguage' => 'en-US',
],
]
],
...
]
If you're running from web check also that config in web.php
Recently I installed the multiSelect check box extension.
my _form.php looks like this:
<? = $ Form-> field ($ model_detail, 'product_id') ->
widget (MultiSelect :: className (),
['id' => "multiXX",
"options" => ['multiple' => "multiple"],
'data' => $ rows,
'attribute' => 'product_id',
'model' => $ models ,
"clientOptions" =>
[
"includeSelectAllOption" => true, 'numberDisplayed' => 2,
],
]);
How can I extract the data chosen by the user in actionCreate of anther model?
how can I get the options that the user selected?
(I tried the $_post[] and it didn't worked.)
this is the whole form:
div class="customer-order2-form">
<?php $form = ActiveForm::begin(['action' => ['create']]); ?>
<?= $form->field($model, 'customer_name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'customer_phone')->widget(\yii\widgets\MaskedInput::className(),
[
'mask' => '999-9999999',
'clientOptions' => ['alias' => '972']
]) ?>
<?php /* $form->field($model, 'customer_phone')->textInput(['maxlength' => 255]) **/?>
<?= $form->field($model, 'order_date')->widget(
DatePicker::className(), [
'inline' => false,
// 'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-m-d'
]
]);?>
<?php $model_detail = new OrderDetails2(); /* -------- כאן הוספתי נתונים ממודל
$rows=ArrayHelper::map(ProductFamily::find()->all(), 'id', 'name'); //--- אין צורך בשאילתא, עכשיו גם מציג את מה שנבחר למעלה
?>
<?= $form->field($model_detail, 'product_id')->widget(
MultiSelect::className(), [
'id'=>"multiXX",
"options" => ['multiple'=>"multiple"], // for the actual multiselect
'name' =>'multicheck',
'data' =>$rows,
'attribute' => 'product_id', // if preselected
'model' => $models,
"clientOptions" =>
[
"includeSelectAllOption" => true,
'numberDisplayed' => 2,
],
]);
?>
<?php
echo $form->field($model, 'description')->textarea(['rows' => 6]);
echo /*$form->field($model, 'totalprice')->textInput();*/
$form->field($model, 'totalprice')->widget(MaskMoney::classname(), [
'pluginOptions' => [
'prefix' => '₪ ',
'allowNegative' => false
]
]);
echo $form->field($model, 'status_id')->dropDownList(ArrayHelper::map(Status::find()->select('*')->all(), 'id', 'name'));
?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'יצירה' : 'עדכון', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
what i tried is saving to different table in DB with a default Array,
and it worked.
it looks like this:
public function actionCreate()
{
$model = new CustomerOrder2();
$model_details= new OrderDetails2();
if ($model->load(Yii::$app->request->post()) && $model->save())
{
if (isset($_POST['product_id'])){
$model_details->attributes = $_POST['product_id'];
$model_details->attributes=array();
echo
$model_details->attributes;
}
echo $_POST['description'];
$values = Array('1'=>'1','2'=>'2');
$model_details->attributes = $_POST['product_id'];
$array=$model_details->attributes;
//$data=OrderDetails2::->request->post();
//$values= Array(Yii::$app->request->post()['multiXX']);
//$values=Array($model_details->attributes);
foreach($values as $value)
{
$command = Yii::$app->db->createCommand();
$command->insert('order_details',array('Order_id'=>$model->id,
'product_id'=> $value,
'quantityOrdered'=> '1',
));
$command->execute();
}
return $this->redirect(['view', 'id' => $model->id]);
}
else {
return $this->render('create', [
'model' => $model,
]);
}
}
So I have created a simple search form, and created the query within my controller (I am aware this isn't the best way to do it and should be done in my model/search model however for the time being it will do).
I was wondering how can I add an option to my form within the two dropdown with the label All which if passed will mean that that part of the query isn't applied.
Below is my view
<?php $form = ActiveForm::begin(['id' => 'home-search','method' => 'post', 'action' => Url::to(['productitem/search'])]); ?>
<?= $form->field($productitem, 'name')->textInput(array('placeholder' => 'What are you looking for?'))->label(false) ?>
<?= $form->field($productitem, 'brand_id')->dropDownList(
ArrayHelper::map(ProductBrand::find()->all(),'id','name'),
['prompt'=>'Select Brand']
)->label(false) ?>
<?= $form->field($productitem, 'category_id')->dropDownList(
ArrayHelper::map(ProductCategory::find()->all(),'id','name'),
['prompt'=>'Select Department']
)->label(false) ?>
<div class="form-group search-button">
<button type="submit" class="btn btn-primary" name="login-button">Search <i class="fa fa-lg fa-arrow-circle-o-right"></i></button>
</div>
<?php ActiveForm::end(); ?>
Below is my controller/query
public function actionSearch()
{
$query = ProductItem::find()
->andFilterWhere(['like', 'name', $_POST['ProductItem']['name']])
->andFilterWhere(['in', 'brand_id', $_POST['ProductItem']['brand_id']])
->andFilterWhere(['in', 'category_id', $_POST['ProductItem']['category_id']]);
$dataProvider = new ActiveDataProvider([
'query' => $query
]);
return $this->render('search', [
'dataProvider' => $dataProvider,
]);
}
hope this will offer some reference.
<?= $form->field($model, 'categoryid1')->widget(Select2::className(), [
'id' => 'categoryid1',
'name' => 'categoryid1',
'data' => ArrayHelper::map(Category::getCategoryByPid(0), 'id', 'name'),
'options' => [
'placeholder' => 'choose first',
],
'pluginOptions' => [
'allowClear' => true
],
])->label('first') ?>
<?= $form->field($model, 'categoryid2')->widget(DepDrop::className(), [
'type' => DepDrop::TYPE_SELECT2,
'id' => 'categoryid2',
'name' => 'categoryid2',
'data' => $model->categoryid1 ? ArrayHelper::map(Category::getCategoryByPid($model->categoryid1), 'id', 'name') : [],
'pluginOptions' => [
'depends' => ['product-categoryid1'],
'placeholder' => 'choose second',
'url' => Url::to(['/category/second'])
]
])->label('second'); ?>
<?= $form->field($model, 'categoryid')->widget(DepDrop::className(), [
'type' => DepDrop::TYPE_SELECT2,
'data' => $model->categoryid2 ? ArrayHelper::map(Category::getCategoryByPid($model->categoryid2), 'id', 'name') : [],
'pluginOptions' => [
'depends' => ['product-categoryid1', 'product-categoryid2'],
'placeholder' => 'third',
'url' => Url::to(['/category/third'])
]
])->label('third'); ?>