Split ActiveForm fields into different tabs with Tabs widget - yii2

I'm creating a form view and I want to organize the form fields with tabs structure, using the official Tabs widget.
Is it possible init the Tabs widget with the id (or class) of the div elements that contains the active form fields?

One example of how you can manage it is doing like this:
First, divide your contact-form into one view-file for each tab.
Place the ActiveForm::begin() and ActiveForm::end() around the Tabs::widget()
Render the contact-form pages into content, with parameters $model and $form
Example code:
views/site/contact.php
<?php
/* #var $this yii\web\View */
$this->title = 'Contact';
use yii\bootstrap\Tabs;
use yii\bootstrap\ActiveForm;
?>
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
<?= Tabs::widget([
'items' => [
[
'label' => 'One',
'content' => $this->render('contact_form1', ['model' => $model, 'form' => $form]),
'active' => true
],
[
'label' => 'Two',
'content' => $this->render('contact_form2', ['model' => $model, 'form' => $form]),
],
]]);
?>
<?php ActiveForm::end(); ?>
views/site/contact_form1.php
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'subject') ?>
views/site/contact_form2.php
<?php
use yii\helpers\Html;
use yii\captcha\Captcha;
?>
<?= $form->field($model, 'body')->textArea(['rows' => 6]) ?>
<?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
]) ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
</div>
Hope this helps!

Just add at the top of your contact.php global $form; and all works fine.

I have another solution:
When we call $form->field($model, 'name')->textInput(), it will return the model of class yii\widgets\ActiveField, so just continue calling a method of this class as $form->field($model, 'name')->textInput()->render(). It will return a string then you can use it for the tab's content.
I have an example code in my application for translating multi languages as the following code:
<?php
$items = [];
foreach ($translateModels as $translateModel) {
$tabContent = $form->field($translateModel, "[{$translateModel->code}]name")->textInput()->render();
$items[] = [
'label' => $translateModel->language->name,
'content' => $tabContent,
];
}
?>
<?= Tabs::widget([
'options' => [
'class' => 'nav-tabs',
'style' => 'margin-bottom: 15px',
],
'items' => $items,
]) ?>
Maybe it's help.

Related

Kartik datepicker extention not working on array input form

I have a form field "dob[]" with array input like
<?php $form = ActiveForm::begin();
for($i=0;$i<= 3;$i++):
echo $form->field($model, 'dob[]')->widget(DatePicker::classname(), [
'options' => ['placeholder' => 'Date Of Birth'],
'type' => DatePicker::TYPE_INPUT,
'pluginOptions' => [
'format' => 'mm/dd/yyyy',
'autoclose' => true,
]
]);
endfor; ?>
<div class="form-group">
<?= Html::button('Submit', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
Datepicker working only on first "dob" field but rest of the field having only button format of datepicker but calendar not working.
This is because the javascript cannot determine the correct input fields, after the first one. Take a look in your source code. All widgets have properly the same id and/or name. You have to setup a unique ID for each of the generated widgets.
By the way, it is always a good approach to name form data accordingly.
That is documented at the demo page.
The following should work:
<?php
$form = ActiveForm::begin();
for ($i=0; $i < 3; $i++) {
echo $form->field($model, 'date_end')->widget(DatePicker::classname(), [
'options' => [
'placeholder' => 'Date Of Birth',
'name' => 'DOB' .$i,
'id' => 'DOB-ID' . $i,
],
'type' => DatePicker::TYPE_INPUT,
'pluginOptions' => [
'format' => 'mm/dd/yyyy',
'autoclose' => true,
],
]);
}
?>
<div class="form-group">
<?= Html::button('Submit', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>

Yii2=>ActiveForm=> add "has-error" (or "has-access") by default on page open

I have a simple form:
<?php $form = ActiveForm::begin([
'id' => 'answer-form',
'action' => Yii::$app->getUrlManager()->createUrl('test'),
'enableClientValidation' => false,
]); ?>
<?= $form->field($user_answer, 'user_text')->textInput(['value' => $text])->label('Text') ?>
<?php ActiveForm::end(); ?>
I want to show input with red color (div with class "has-error" by default)- like somebody added wrong data to the input. How can i do it?
Try this
<?= $form->field($user_answer, 'user_text', [ 'options' => [ 'class' => 'has-error'])->textInput(['value' => $text])->label('Text') ?>

ActiveForm without model yii2

I want to create ActiveForm without model for just in case something. I did try with dynamicModel but i got some error :
use yii\base\DynamicModel;
$model = DynamicModel::validateData(compact('KOMENTAR'), [
[['KOMENTAR'], 'string', 'max' => 128],
]);
This is the form i want to create
<br>
<?php $form = ActiveForm::begin([
'method' => 'post',
]); ?>
<?= $form->field($model, 'KOMENTAR')->textarea(['rows' => 6])->label(false) ?>
<div class="form-group">
<?= Html::submitButton('POST', ['class' => 'btn btn-primary']) ?>
</div>
This is the error
Getting unknown property: yii\base\DynamicModel::KOMENTAR
Normally ActiveItems are used to work with a model, but Yii2 have a helper class called Html to use the same items like classic HTML.
Use beginForm() method from Html. And try something like that:
use yii\helpers\Html;
<?= Html::beginForm(['/controller/view', 'id' => $model->id], 'POST'); ?>
<?= Html::textarea('KOMENTAR', '', ['rows' => 6])->label(false); ?>
<div class="form-group">
<?= Html::submitButton('POST', ['class' => 'btn btn-primary']); ?>
</div>
<?= Html::endForm(); ?>
You can read more about this helper in the documentation.
Since you are using compact('KOMENTAR'), you should have a $KOMENTAR variable.
Read more about compact : http://php.net/manual/fr/function.compact.php
Or you should simply create your model like this :
$model = new \yii\base\DynamicModel(['KOMENTAR']);
$model->addRule(['KOMENTAR'], 'string', ['max' => 128]);
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// do what you want
}

yii.validation is not defined error in yii2

I am opening a ActiveForm in modal window in yii2.
This error comes when I am opening a ActiveForm in Modal window . my index.php is
<?php
use yii\helpers\Html;
use yii\bootstrap\Modal;
$this->title = 'Roles';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="role-index">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Create Role', '#', [
'class' => 'btn btn-success',
'id' => 'create-role-model',
'data-toggle' => 'modal',
'data-target' => '#activity-create-modal',
]) ?>
</p>
</div>
<?php
Modal::begin([
'id' => 'activity-create-modal',
'header' => '<h2>Hello world</h2>',
'footer' => Html::button('Close', ['class' => 'btn btn-default', 'data-dismiss' => 'modal'])
. PHP_EOL . Html::button('Add', ['class' => 'btn btn-primary btn-modal-save']),
]);
$model= new \frontend\models\Role();
echo $this->renderAjax('_form',['model' => $model]);
Modal::end();
?>
and my _form.php is
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
/* #var $this yii\web\View */
/* #var $model frontend\models\Role */
/* #var $form yii\widgets\ActiveForm */
?>
<?php $form = ActiveForm::begin([
'id' => 'create-ro',
'enableClientValidation' => true,
]); ?>
<?= $form->field($model, 'id')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'created_on')->textInput() ?>
<?= $form->field($model, 'updated_on')->textInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
However when I place ActiveForm without render in index.php Yii Validation is working.Am I doing it an wrong manner . What have to be done so that modal validation start
It's echo $this->render('_form',['model' => $model]); you need, not $this->renderAjax().
The latter actually terminates the entire page and returns it without a layout around it (so including any javascript includes and so on).
Since you are still in another view that is definitely not what you need. So just use render(). It's a bit confusing because Controller::render() actually does close the page (and also adds javascripts), but in case of the View (Which $this is in that context) it does what renderPartial does for the controller.

Render Form inside Yii2 Gui Tab

My application have to have multiple language, so I decided to separate each language by using tab (Yii2 gui), but how can I render the form in side the 'content' key?
<?php
$language_tab=[];
$increment=0;
$content="I love you";
foreach($language as $obj){
$language_tab[$increment] = array('label' => $obj->name ,'content' => $content);
$increment++;
}
echo Tabs::widget([
'items' => $language_tab,
'options' => ['tag' => 'div'],
'itemOptions' => ['tag' => 'div'],
'headerOptions' => ['class' => 'my-class'],
'clientOptions' => ['collapsible' => false],
]);
?>
<div class="status-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'date_created')->textInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
I just wanna change from $content to the form below.
Please help!!!
You may create separate view for the form and render it:
...
'content' => $this->render('_language_form', ['language' => $obj, 'model' => $model]),
...