I'm trying to use Select2 and depdrop within a dynamic form. For the first row it's working only. But on the next row I'm getting following error.
When I'm using select2 without depfrop it works fine.
Code of form (of select2 and depdrop field)
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($modelsProductsales, "[{$i}]productname")->label(false)->widget(Select2::classname(), [
'data' => ArrayHelper::map(Productbatch::find()->orderBy('productname')->all(),'productname','productname'),
'language' => 'en',
'options' => ['placeholder' => 'Select Product','id' => 'prodname'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, 'batchno')->label(false)->widget(DepDrop::classname(), [
//'options'=>['id'=>'subcat-id'],
'pluginOptions'=>[
'depends'=>['prodname'],
'placeholder'=>'Batch No',
'url'=>Url::to(['/invoice/bills/subcat'])
]
]); ?>
Code of subcat action
public function actionSubcat() {
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
$out = Productbatch::getBatchNo($cat_id);
echo Json::encode($out);
// the getSubCatList function will query the database based on the
// cat_id and return an array like below:
// [
// ['id'=>'<sub-cat-id-1>', 'name'=>'<sub-cat-name1>'],
// ['id'=>'<sub-cat_id_2>', 'name'=>'<sub-cat-name2>']
// ]
//echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
Please let me know if anymore input from my end is required.
check your codes to find JavaScript codes for the first element that works correctly.you should be add JavaScript codes for all same elements that produces by insert button.
I suggest you to extended another dynamic form from \wbraganca\dynamicform\DynamicFormWidget for your own.Then override registerAssets function and add JavaScripts for other insert handler.
It has problem is yii2-dynamic-form.js file of dynamic form. Same solution work for Select2 and DepDrop both.
solution on following link works for me.
https://github.com/wbraganca/yii2-dynamicform/issues/76#top[Updated Code][1]
Related
This is my actionIndex() in my controller.
public function actionIndex()
{
$featured= new ActiveDataProvider([
'query'=>News::find()
->where(['not', ['featuredOrder' => null]])
->orderBy('featuredOrder'),
]);
$checkList=Featured::find()
->joinWith('news')
->where(['news.featuredOrder'=>null])
->orderBy('featuredOrder')
->all();
return $this->render('index', [
'dataProvider' => $featured,
'checkList'=>$checkList,
]);
I have a listview in my index view which is rendered by this controller. If an item of the listview is clicked, it will display the detailView of each item, along with the update button to update the item's data which will generate a form to update. I need to pass the $checklist to this form. Later I'll use this $checklist to populate a drop-down list. I wonder how to pass the parameter. I could just move this part to the form view, but I think it's not a good practice to have this inside a view.
$checkList=Featured::find()
->joinWith('news')
->where(['news.featuredOrder'=>null])
->orderBy('featuredOrder')
->all();
This is my index :
<?php echo \yii\widgets\ListView::widget([
'dataProvider' => $featured,
'itemView'=>'_post',
'options'=>['class'=>'row'],
'itemOptions'=>['class'=>'col-md-4'],
'summary'=>'',
'viewParams'=>['cekList'=>'cekList'],
'pager' => [
'options'=>['class'=>'pagination justify-content-center'],
'linkContainerOptions'=>['class'=>'page-item'],
'linkOptions'=>['class'=>'page-link'],
_post view
div class = "panel panel-default">
<div class = "panel-body">
<h2 class="truncate text-center"><?=Html::a($model->title, ['view', 'id' => $model->id] ) ?> </h2>
<hr>
</div>
<!-- another block of code, but unrelated, so I won't include it -->
This is the view.php file,being rendered if an item's title in the _post above is clicked.
<div class="row justify-content-between">
<div class="col-xs-6">
<?= Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'id' => $model->id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Do you want to delete this post?',
'method' => 'post',
],
]) ?>
If an update button is clicked, it will render a form. I want to pass the param to this form.
My Answer is Based On this Query :
$checkList=Featured::find()
->joinWith('news')
->where(['news.featuredOrder'=>null])
->orderBy('featuredOrder')
->all();
If you want to use only above query for drop down there is a two way to do that :
1. Create A method in controller and use array helper method for drop down list add select statement in query
public function checklistDropdown(){
$items = Featured::find()
->joinWith('news')
->where(['news.featuredOrder'=>null])
->orderBy('featuredOrder')
->all();
$items = ArrayHelper::map($items, 'id', 'name');
}
In your index action call this method pass just like you passed model and dataprovider
2. second option is more feasible i think
Create a component helper for generic drop down list add above method in that component and use that component to call the method in you view , you can define that method as STATIC . It will be reusable.
I want form data updated after ajax save. Cause if item was new (id - empty), it tries to create new one each time. Also there are back-end generated fields which are appears after save.
<?php $form = ActiveForm::begin([
'method' => 'post',
'action' => ['category/save', 'id' => $category ? $category->id : ''],
'enableClientValidation' => true,
// 'enableAjaxValidation' => false,
'validateOnChange' => false,
'validateOnBlur' => false,
'validateOnSubmit' => true,
'options' => [
'id' => 'customer-update',
'class' => 'ajax-submit',
],
'fieldConfig' => [
'template' => '<div class="row-content-col1">{label}</div><div class="row-content-col2">{input}{error}</div>'
]
]); ?>
.......
<?php echo $form->field($category, 'url')->textInput(['class' => 'ip', 'readonly' => true]); ?>
......
<?php $form->end(); ?>
Form field produce such html:
<div class="row-content-col1"><label class="control-label" for="category-url">Url</label></div><div class="row-content-col2"><input type="text" id="category-url" class="ip" name="Category[url]" readonly><div class="help-block"></div></div>
</div>
And than on controller i return this (tried different variations):
{"error":false,"message":"Category 'asdfzsdf sdf' saved","data":{"name":"asdfzsdf sdf","url":"asdfzsdf-sdf","project_id":1,"id":21}}
What is valid response for ajax form? Or is there other way to handle this all ?
Pjax is really useful for your challenge, Just add your form inside of Pjax widget. add form action to new path(such: site/control-data).
In your action method do what you want, but send response like that :
return $this->renderAjax('form path',$model);
It's the general of what you must do.
But maybe you have problem with jquery or pjax or need some more data, but all questions have an answer,
See Pjax for ActiveForm
I have not worked with the listview widget before so I cant find a solution for this, as I output a list with items I wanted to do 2 things, 1. auto increment and unique ID/number to each list item, 2. add a block(custom piece of code) after each 3rd list item.
I could not find any documentation about this so not sure if this is possible.
echo ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider
]);
<div id="listofitems">
<div class="list_item_wrapper">
// my items which are in a seperate file
<div class="list_item_wrapper">
// when using the $index to check for a certain number the code will be build here.
</div>
</div>
// the needed solution
if($index == 12 || $index == 12){
echo 'some div here';
}
</div>
You can use the itemView option for the ListView widget where you can either provide
Specify as a callback function ($model , $key , $index , $widget) { and add your custom HTML inside and do your custom operations like check every third item,or use the actual id by calling $model->id and appending it with the html tag attribute, it provides you
$model: mixed, the data model
$key: mixed, the key value associated with the data item
$index: integer, the zero-based index of the data item in the items array returned by $dataProvider.
$widget: ListView, this widget instance
For example
echo ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider,
'itemView'=>function ($model , $key , $index , $widget) {
//Do your Thing with Html you want to draw
//return '<div></div>';
}
]);
Or provide the view file path to the option, you can still use the above given params in the view file
For Example
echo ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider,
'itemView'=>'_view-name'
]);
Your view can look like
<?php
use yii\helpers\Html;
?>
<div class="card">
<div class="header">
<h3 class="title"><?= Html::encode ( $model->title ) ?></h3>
</div>
<div class="body"><img src="<?= Html::encode ( $model->name ) ?>"><?= Html::encode ( $model->id ) ?></div>
<div class="footer"></div>
</div>
UPDATE
If your requirements are to draw or add an element after every item or any number of items you can use the afterItem option which takes an anonymous function that is called once AFTER rendering each data model, it passes same set of parameters as beforeItem
$model: the current data model being rendered
$key: the key value associated with the current data model
$index: the zero-based index of the data model in the model array returned by $dataProvider
$widget: the ListView object
UPDATE2
The below should work in your case with the given HTML
<div id="listofitems">
<?php
echo ListView::widget ( [
'id' => 'listofitems' ,
'dataProvider' => $dataProvider ,
'afterItem=' > function($model , $key , $index , $widget) {
// the needed solution
if ( $index == 12 || $index == 12 ) {
return 'some div here';
}
} ,
'itemView' => function ($model , $key , $index , $widget) {
//Do your Thing with Html you want to draw
return '<div class="list_item_wrapper">
// my items which are in a seperate file
<div class="list_item_wrapper">
// when using the $index to check for a certain number the code will be build here.
</div>
</div>
';
}
] );
?>
</div>
There is such an index by default in the widget. Configure the 'itemView' attribute of the ListView widget, that means you can use a custom view which will be rendered for each item. Like this:
<?= ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider,
'itemView' => '/site/item',
?>
in your view file /site/item.php, you can access the index of the current item:
<?php
var_dump($index);
?>
More info about the itemView property here.
I have 5 tabs on one page. All the tabs have different content, but on one of them i need to have pagination. When click on pagination the page is refreshing and the current opened tab is closed and show by default first tab ... I want when click on pagination, the current tab to be open and the refresh only part with data information.
here is my code:
<?php
Pjax::begin([
'id' => 'w0',
'enablePushState' => true, // I would like the browser to change link
'timeout' => 10000 // Timeout needed
]);
$spec = Specifications::find()->where('active = 1')->orderBy(['sort' => SORT_ASC]);
$count = $spec->count();
$pagination = new Pagination(['totalCount' => $count, 'defaultPageSize' => 20]);
$models = $spec->offset($pagination->offset)
->limit($pagination->limit)
->all();
echo LinkPager::widget([
'pagination' => $pagination,
'hideOnSinglePage' => true,
'prevPageLabel' => 'Предишна',
'nextPageLabel' => 'Следваща'
]);
if ($spec) { ?>
<div class="form-group">
<label>Спецификации</label></br>
<?php
foreach ($models as $singleSpec) {
echo $singleSpec->id." ".$singleSpec->title;
}
?>
</div>
<?php } ?>
<?php Pjax::end() ?>
remove 'id'=>'w0' from Pjax, it is refreshing your page
I have developed form to allow owner to create team. code is:
<?php $form = ActiveForm::begin(['id' => 'team-create-form', 'action' => ['site/create-team-form'], 'options' => array('role' => 'form')]);
<div class="col-lg-10 form-group" id="createTeamForm" style="margin-top: 15px;">
<div class="col-lg-4">
<?= $form->field($model, 'team_name',['template' => "{label}\t{input}\n{error}"])->textInput(array('placeholder'=>'Enter team name....')); ?>
</div>
<div class="col-lg-4">
<?= $form->field($model, 'team_description',['template' => "{label}\t{input}\n{error}"])->textInput(array('placeholder'=>'Enter team Description....')); ?>
</div>
<div class="col-lg-2">
<?= Html::submitButton('Submit', ['class' => 'btn btn-danger', 'id' => 'tsubmit', 'style' => 'margin-top: 22.5px; margin-right: 15px;']) ?>
</div>
</div>
I have tried loading the page with the above code but it is showing me error "$model not defined". How to resolve that. Am i need to add something in the main-local.php???
public function actionLogin()
{
$model = new LoginForm();
$session = Yii::$app->session;
if ($model->load(Yii::$app->request->post()) && $model->login()) {
$collection1 = Yii::$app->mongodb->getCollection('users');
$teamid = $collection1->findOne(array('username' => $model->email_address));
$session->set('id', $teamid['_id']);
$session->set('name', $teamid['name']);
$session->set('username', $model->email_address);
$collection2 = Yii::$app->mongodb->getCollection('teamdashboard');
$teams = $collection2->find(array('admin' => $model->email_address));
$model1 = new TeamCreateForm();
return $this->render('dashboard', ['model'=>$model1, 'teams'=> $teams]);
} elseif($session->isActive){
$username = $session->get('username');
$collection = Yii::$app->mongodb->getCollection('users');
$teams = $collection->findOne(array('username' => $username));
return $this->render('dashboard', ['teams'=>$teams]);
}else{
$this->layout = 'index';
return $this->render('login', ['model' => $model]);
}
}
I have renamed the productpage as dashboard for better understanding.
Now when i run this & logs in, The address bar url shows url:..../web/index.php?r=site/login whereas it should show me url:..../web/index.php?r=site/dashboard & shows me the view of dashboard.
When i refresh the page, i brings me back to the login...
Did you use $model in dashboard view? If you do - you need to pass it (the same way as the login).
You have to send the $model to the view. The view only knows variables if you send it to it.
I have no idea what you mean with the address bar. The address bar has nothing to do with what you send to the view.
EDIT
Your entire way of thinking is strange. Why would u show different views depending if the person is registered or not?
return $this->render('dashboard', ['teams'=>$teams]);
return $this->render('login', ['model' => $model]);
User redirect with parameters to move the customer to another page. Having an URL like /login that actually shows a dashboard is not logical.