selected data in multiple checkbox not recognized - cakephp-3.0

I am getting frusted because the edit.ctp is not recognizing the stored data within a multible value checkbox. This is my code:
Controller:
public function edit($id = null) {
$this->set('userfunc', $this->Auth->user('userfunction_id'));
$user = $this->Users->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
**$selection = explode('#',$user->member);**
$userfunctions = $this->Users->Userfunctions->find('list', ['limit' => 200]);
$userappartments = $this->Users->Userappartments->find('list', ['limit' => 200]);
$userparkings = $this->Users->Userparkings->find('list', ['limit' => 200]);
$this->set(compact('user', 'userfunctions', 'userappartments', 'userparkings', 'selection'));
$this->set('_serialize', ['user']);
}
edit.ctp:
<?php
echo $this->Form->label('User.status', 'Status');
$options = $statusList;
echo $this->Form->radio('status', $statusList);
echo $this->Form->label('User.member', 'Mitglied');
echo $this->Form->input('member', ['options' => $memberList, 'multiple' => 'checkbox', 'label' => false, 'selected' => $selection]);
echo $this->Form->input('userappartment_id', ['options' => $userappartments, 'label' => 'Wohnung']);
echo $this->Form->input('userparking_id', ['options' => $userparkings, 'label' => 'Parkplatz']);
echo $this->Form->input('contact', ['label' => 'Kontakt']);
?>
================
print_r is displaying an array that looks fine:
enter image description here
but the field in the form is emty:
enter image description here

Related

Yii2 Dynamic form update fail on kartik-Select2

I am using wbraganca dynamic form widget. It works fine for the Create action.
Let me thanks for those guys making great tutorial video on youtube!!!
I am working on the Update action now. I work it on a purchase order function.
the controller of update action :
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelsItem = $model->purchaseitems;
if ($model->load(Yii::$app->request->post()) ) {
$oldIDs = ArrayHelper::map($modelsItem, 'purchaseitem_id', 'purchaseitem_id');
$modelsItem = Model::createMultiple(Purchaseitem::classname(), $modelsItem);
Model::loadMultiple($modelsItem, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsItem, 'purchaseitem_id', 'purchaseitem_id')));
$valid = $model->validate();
$valid = Model::validateMultiple($modelsItem) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs)) {
Purchaseitem::deleteAll(['purchaseitem_id' => $deletedIDs]);
}
foreach ($modelsItem as $modelItem) {
$modelItem->purchaseitem_purchaseorder_id = $model->purchaseorder_id;
$modelItem->purchaseitem_description = Inventory::findOne($modelItem->purchaseitem_inventory_id)->inventory_partno;
if (! ($flag = $modelItem->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->purchaseorder_id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
//return $this->redirect(['view', 'id' => $model->purchaseorder_id]);
} else {
return $this->render('update', [
'model' => $model,
'modelsItem' => (empty($modelsItem)) ? [new Purchaseitem] : $modelsItem
]);
}
}
But I think the problem may happen on the view file, as the Select2 field can show the value, which is the 'id' of the product rather than the product code.
view:
<div class="panel panel-default">
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper',
'widgetBody' => '.container-items',
'widgetItem' => '.item',
'limit' => 50,
'min' => 1,
'insertButton' => '.add-item',
'deleteButton' => '.remove-item',
'model' => $modelsItem[0],
'formId' => 'dynamic-form',
'formFields' => [
'purchaseitem_inventory_id',
'purchaseitem_qty',
'purchaseitem_cost_usd',
'purchaseitem_deliverydate',
],
]); ?>
<?php foreach ($modelsItem as $i => $modelItem): ?>
<div class="item">
<?php
// necessary for update action.
if (! $modelItem->isNewRecord) {
echo Html::activeHiddenInput($modelItem, "[{$i}]purchaseitem_id");
}
?>
<div class="row">
<?= $form->field($modelItem, "[{$i}]purchaseitem_inventory_id")->widget(
Select2::classname(), [
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 2,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Error on finding results...'; }"),
],
'ajax' => [
'url' => Url::toRoute('inventory/inventorylist'),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
'templateSelection' => new JsExpression('function (purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
],
])->label(false) ?>
<?= $form->field($modelItem, "[{$i}]purchaseitem_qty")->textInput(['maxlength' => true])->label(false) ?>
<?= $form->field($modelItem, "[{$i}]purchaseitem_cost_usd")->textInput(['maxlength' => true])->label(false) ?>
<?= $form->field($modelItem, "[{$i}]purchaseitem_deliverydate")->widget(
DatePicker::className(), [
'options' => [
['placeholder' => 'Please enter delivery date'],
],
'removeButton' => false,
'pluginOptions' => [
'autoclose'=>true,
'format' => 'yyyy-mm-dd',
'todayHighlight' => true,
]
]
)->label(false) ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
I have a thought that the problem maybe related to that few lines of JsExpression function.
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
'templateSelection' => new JsExpression('function (purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
For the Select2 query URL method is here:
public function actionInventorylist($q = null, $id = null) {
Yii::$app->response->format = yii\web\Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) {
$query = new Query;
$query->select('inventory_id AS id, inventory_partno AS text')
->from('inventory')
->where(['like', 'inventory_partno', $q])
->limit(10);
$command = $query->createCommand();
$data = $command->queryAll();
$out['results'] = array_values($data);
}
elseif ($id > 0) {
$out['results'] = ['id' => $id, 'text' => Inventory::find($id)->inventory_partno];
}
return $out;
}
I can load the record, when I click in the update view. Most of the data are feed in right place of the form, except the 'partno' field. I use Select2 to let user select partno by text and store the 'id' in table. It works on the Create view.
but in the update view, it only show the 'id' instead of the 'partno'.
if I make input to the field, I can select 'other' partno only, let me explain here:
if there are 2 code, "ABC" with 'id' is 1, "XYZ" with 'id' 2.
the record original is "ABC", the field show "1".
If I input "XYZ", it will show "XYZ" as normal effect of widget. But, if I change back to "ABC", it will show "1" instead of "ABC".
And the form also cannot submit for update. the button click with no effect.
I am new to Yii2 framework, and quite stuck on this issue, does anyone knows how can I solve this?
THANKS!!!!
I just solve the problem, a few issue happened actually.
To solve the Select2 widget cannot display the partno instead of the ID, I find the partno by the ID and feed it with initValueText in Select2. For my case:
$partno = empty($modelItem->purchaseitem_inventory_id) ? '':Inventory::findOne($modelItem->purchaseitem_inventory_id)->inventory_partno;
$form->field($modelItem, "[{$i}]purchaseitem_inventory_id")->widget(Select2::classname(), ['initValueText' => $partno, ...
About the update POST fail issue, I got error of Getting unknown property: backend\models\Purchaseitem::id, and I found it happened on the Dynamic-form widgets Model.php line 25. That lines is $keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
If I change the 'id' to my ID field name, i.e 'purchaseitem_id', it will work, but this model will only work for this Id field name afterward. So I get the model's primaryKey and make it work for my other model.
add this line $primaryKey = $model->tableSchema->primaryKey; and modify above line $keys = array_keys(ArrayHelper::map($multipleModels, $primaryKey, $primaryKey));

Two gridview from two model search by single field in yii2

I have one search form with a field and a button. On the button click I want to search 2 searchmodel - sellitembtdtSearch and puritembtdtSearch. The result will be shown in one view. I can display the view without any problem. The problem is when I'm searching only one searchmodel is getting searched. Please let me know how can I search both the searchModel at the sametime.
First I land on index2.php page where the form is.
'action' => ['/stock/sellitem/printproductledger3',],
'method' => 'get',
<?= $form->field($model, 'productname')->textInput(['maxlength' => true,]) ?>
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
actionIndex2.php
public function actionIndex2()
{
$searchModel1 = new SellitemsbdtSearch();
$dataProvider1 = $searchModel1->search(Yii::$app->request->queryParams);
$searchModel2 = new PuritemsbdtSearch();
$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);
return $this->render('_formbtdt', [
'model' => $searchModel2,
//'searchModel1' => $searchModel2,
]);
}
public function actionPrintproductledger3() {
$searchModel1 = new SellitemsbdtSearch();
$dataProvider1 = $searchModel1->search(Yii::$app->request->get());
$searchModel2 = new PuritemsbdtSearch();
$dataProvider2 = $searchModel2->search(Yii::$app->request->get());
//$productname = yii::$app->request->get('productname');
//$prodesc = yii::$app->request->get('prodesc');
$content = $this->renderPartial('_printproductledgerbtdt', [
//'productname' => $productname,
'searchModel1' => $searchModel1,
'dataProvider1' => $dataProvider1,
'searchModel2' => $searchModel2,
'dataProvider2' => $dataProvider2,
//'prodesc' => $prodesc,
]);
return $this->render('_printproductledgerbtdt', [
'dataProvider1' => $dataProvider1,
'searchModel1' => $searchModel1,
'searchModel2' => $searchModel2,
'dataProvider2' => $dataProvider2,
]);
This code only searchs puritemdtdtSearch. I want to search puritembtdtSearch and sellitembtdtSearch at the same time. Thanks.
The issue is you are using searchModel2 in your form so you are just getting the result of searchModel2. And not getting the result of searchModel1.
What you can do is send searchModel1 to your _search file.
<?php echo $this->render('_search', ['model1' => $searchModel1, 'model2' => $searchModel2]); ?>
Now in your form use a hidden input.
<?php echo $form->field($model1, 'productName')->textInput(['id' => 'model1']); ?>
<?php echo $form->field($model2, 'prodcutName')->hiddenInput(array('id' => 'model2')); ?>
Now its that we have two model fields we need to populate the hidden field, this can be done using jquery.
<?php $this->registerJs('
//add the .search class name for your search button
jQuery("body").on("click", ".search", function() {
alert("Hello");
var a = $("#model1").val();
$("#model2").attr("value", a);
});
');?>
Try this..tested completely and works fine!!

Set enablePushState = false on specific urls inside Pjax container (Yii2)

I need pjax to work on change status click and it's working fine but don't want it to change the URL as well. Below is the code:
<?php Pjax::begin(['id'=>'pjax-container-agency-index', 'timeout' => 10000, 'enablePushState' => true]); ?>
<?= GridView::widget([...,
[
'label' => 'Status',
'format' => 'raw',
'value' => function ($data) {
if ($data->deactive == 0) {
return Html::a(FA::i('circle'), ['agency/change-status', 'id' => $data->member_id, 'set' => 1], ['onclick' => "return confirm('Deactive this state/site?');", 'class' => 'status-inactive']);
} else {
return Html::a(FA::i('circle'), ['agency/change-status', 'id' => $data->member_id, 'set' => 0], ['onclick' => "return confirm('Active this state/site?');", 'class' => 'status-active']);
}
},
],
]);
<?php Pjax::end(); ?>
actionChangeStatus() is as below:
public function actionChangeStatus($id, $set) {
if (!empty($id) && isset($set)) {
$localGovt = $this->findModel($id);
$localGovt->deactive = $set;
if ($localGovt->save()) {
Yii::$app->getSession()->setFlash('success-status', 'State Status Changed');
} else {
Yii::$app->getSession()->setFlash('error-status', 'There is some error. Please consult with Admin.');
}
$searchModel = new AgencySearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider
]);
}
}
Note: I need 'enablePushState' => true for other events, so I can't change it to false inside Pjax::begin
I believe it's
'enableReplaceState' => true
Pass this attribute to Pjax:
Pjax::begin(['enablePushState' => false]);
This worked for me.

Selected Value is not showing in Kartik Select2 multiple select

This is my view file:
<?php
$data = array();
echo '<label class="control-label">Attribute Group Name</label>';
echo Select2::widget([
'name' => 'attribute_grp_name',
'data' => $attribute_group_name, // initial value
'options' => ['placeholder' => 'Please Enter Attribute Group Name', 'multiple' => true],
'pluginOptions' => [
'attribute_grp_name' => true,
'maximumInputLength' => 100,
],
]);
?>
In my view here selected data is not showing.
This is my controller for create and update function:
public function actionCreate()
{
$model = new AttributeSet();
$attribute_group = AttributeGroupLang::find()->select('*')->all();
$attribute_group_name = ArrayHelper::map($attribute_group, 'id_attribute_group', 'name');
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$post_array = Yii::$app->request->post();
foreach ($post_array['attribute_grp_name'] as $key => $value) {
$attribute_set_group_combination = new AttributeSetGroupCombination();
$attribute_set_group_combination->id_attribute_set = $model->id_attribute_set;
$attribute_set_group_combination->id_attribute_group = $value;
$attribute_set_group_combination->save(false);
}
return $this->redirect(['view', 'id' => $model->id_attribute_set]);
} else {
return $this->render('create', [
'model' => $model,
'attribute_group_name' => $attribute_group_name,
]);
}
}
This is update function:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$attribute_set_group_combination = AttributeSetGroupCombination::find()->where(['id_attribute_set' => $id])->all();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$post_array = Yii::$app->request->post();
if(!empty($post_array['attribute_grp_name'])){
AttributeSetGroupCombination::deleteAll('id_attribute_set = '.$id);
foreach ($post_array['attribute_grp_name'] as $key => $value) {
$attribute_set_group_combination = new AttributeSetGroupCombination();
$attribute_set_group_combination->id_attribute_set = $model->id_attribute_set;
$attribute_set_group_combination->id_attribute_group = $value;
$attribute_set_group_combination->save(false);
}
}
return $this->redirect(['view', 'id' => $model->id_attribute_set]);
} else {
return $this->render('update', [
'model' => $model,
'attribute_set_group_combination' => $attribute_set_group_combination,
'attribute_group_name' => $this->getExistAttrSet($id),
]);
}
}
public function getExistAttrSet($id){
$query = new Query;
$query->select(['attribute_group_lang.name AS attribute_group_name','attribute_group_lang.id_attribute_group'])
->from('attribute_set_group_combination')
->join('LEFT OUTER JOIN', 'attribute_set', 'attribute_set.id_attribute_set =attribute_set_group_combination.id_attribute_set')
->join('LEFT OUTER JOIN', 'attribute_group_lang', 'attribute_group_lang.id_attribute_group =attribute_set_group_combination.id_attribute_group')
->where('attribute_set.id_attribute_set='.$id)
->all();
$command = $query->createCommand();
$model = $command->queryAll();
$data = array();
foreach ($model as $attrsetlist[]) {
$data = ArrayHelper::map($attrsetlist, 'id_attribute_group', 'attribute_group_name');
}
return $data;
}
Can anyone help me that how can i show the selected value in the multiple select field.
You just need to pass in model value:
<?php
echo kartik\select2\Select2::widget([
'name' => 'some_field_name',
// ----------------------
'value' => 'a',
//'value' => ['a', 'b'],
//'value' => $model->some_value,
// ----------------------
'data' => ['a'=>'a', 'b'=>'b', 'c'=>'c'],
'options' => ['placeholder' => 'Select menu items ...', ],
]);
?>

How to check current password in cakephp 3.x from model?

How to check current password is correct from cakephp model. I've searched a lot but not found any details information.
The solution in this post worked for me. Just don't forget to add the use Cake\Auth\DefaultPasswordHasher; at the top of your UsersTabel model.
I found something very useful for checking the current password on http://base-syst.com/password-validation-when-changing-password-in-cakephp-3/ .
Insert this in your template(change_password.ctp):
<div class="users form large-9 medium-9 columns">
<?= $this->Form->create() ?>
<fieldset>
<?= $this->Form->input('current_password', ['type' => 'password', 'label'=>'Current Password', 'value' => ''])?>
<?= $this->Form->input('password', ['type'=>'password' ,'label'=>'Password', 'value' => '']) ?>
<?= $this->Form->input('confirm_password', ['type' => 'password' , 'label'=>'Repeat password', 'value' => ''])?>
</fieldset>
<?= $this->Form->button(__('Save')) ?>
<?= $this->Form->end() ?>
Insert this in your (Users)Table, for validation:
use Cake\Auth\DefaultPasswordHasher;
use Cake\Validation\Validator;
public function validationDefault(Validator $validator )
{
$validator
->add('current_password','custom',[
'rule'=> function($value, $context){
$user = $this->get($context['data']['id']);
if ($user) {
if ((new DefaultPasswordHasher)->check($value, $user->password)) {
return true;
}
}
return false;
},
'message'=>'The old password does not match the current password!',
])
->notEmpty('current_password');
$validator
->add('password', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'The password have to be at least 6 characters!',
]
])
->add('password',[
'match'=>[
'rule'=> ['compareWith','confirm_password'],
'message'=>'The passwords does not match!',
]
])
->notEmpty('password');
$validator
->add('confirm_password', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'The password have to be at least 6 characters!',
]
])
->add('confirm_password',[
'match'=>[
'rule'=> ['compareWith','password'],
'message'=>'The passwords does not match!',
]
])
->notEmpty('confirm_password');
return $validator;
}
Insert this in your (Users)Controller:
public function change_password() {
$user = $this->Users->get($this->Auth->user('id'));
if ($this->request->is(['patch', 'post', 'put'])) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$this->set(compact('user'));
$this->set('_serialize', ['user']);
}