Here I got 2 views, first view is a form which let user to register. Then save information to DB in controller and refer to the other view.
I write a checkbox list in first view.
<?= $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']); ?>
Then I tried to get the value from it in controller and save to DB.
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
//save to DB
$model = new EntryForm();
$tableMember=new Members;
$tableMember->select=$model-> items ;
$tableMember->save();
return $this->render('entry-confirm', ['model' => $model]);
}
to show in entry-confirm.php
<li><label>Selected</label>: <?php echo Html::encode($model->items['a']) ?></li>
but it's empty.
I used NetBeans debugger, it shows:
$_POST = [
'_csrf' => 'OTFHYUpIaVJNSxAJPBEDGV8DcTYjAhojAFofVx0HJmULVCwoAiRENA==',
'EntryForm' => [
'username' => 'df',
'email' => '2#c.c',
'password' => '123',
'items' => [
'a',
'b',
],
'country' => '',
],
];
It seems that items did get attributes. Is there the other way to create checkboxes? Or how can I get the values from a checkbox list?
try this way :
<?php
echo $form->checkBoxList($model,'items',
array('a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C'),
);
?>
this checkbox list should be part of Form Widget, and Items should be your databse field or Variable in your class.First try to check your model fields are coming on your view or not.
Try this one
$tableMember->select = implode(",", $model-> items);
$model->items returns array of checked checkbox.
well, I always have issues getting back arrays with something like
$model->items
(as in values from e.g. checkboxlist), I find it easier to get the values with e.g. $_POST['EntryForm']['items'], like this:
$model->items=implode(',',$_POST['EntryForm']['items']);
(done in the controller, before $model->save())
as an example:
(we split the post and save action)
if ($model->load(Yii::$app->request->post())) {
$model->items=implode(',',$_POST['EntryForm']['items']); //change items into string to be saved
if($model->save()){
return $this->redirect(['view', 'id' => $model->id]);
}
} else {
$model->items=explode(',',$model->items); //string to array to fill the checkboxlist
return $this->render('create', [
'model' => $model,
]);
}
the main issue for $model->items not to work is that probably it is not considered "safe", meaning that it has not been declared in the models under rules (public function rules(), e.g. adding
[['items'], 'string', 'max' => 250],
or
[['items'], 'safe'],
should do the trick....
see also: Yii2 - Models - Safe Attributes
HTH
Related
Im have ActiveRecord model and view for update form of this model. Also I have getter and setter in model class that looks like this
public function setTopvisorGoogleRegion($value)
{
$this->myvalue = $value;
return(true);
}
public function getTopvisorGoogleRegion()
{
return([1 => '123']); //I return this array for show you essence of the problem
}
Following logic in this code $model->topvisorgoogleregion must return [1 => '123']
In view I have next code
<?php echo($form->field($model, topvisorgoogleregion)->textInput());?>
<?php echo $form->field($model, 'topvisorgoogleregion')->widget(Select2::classname(), [
'data' => [1 => '123', 2 => '456'],
'options' => [
'id'=>'projectCtrl',
'placeholder' => 'Select option',
'multiple' => true
],
'pluginOptions' => [
'allowClear' => true,
'tags' => true,
],
]);
?>
When I open form I want to see option 1 => '123' already selected in Select2. Its logically because when already existing record is updating, ActiveRecord get data that already stored in model (in this case using getter) and fill fields in view with this data (In first field that using textInput I see text 'Array' because getter in model returns array). But Select2 is empty when I open update page. Whats going wrong?
If I delete first field (textInput) nothing changes
I find the solution - in getter I need provide ActiveQuery object, not array. I dont know why and how it works, but it works
I am using unclead / yii2-multiple-input widget.
I want to generate different number of rows with values from my database.
How can i do this?
I can design my columns in view and edit data manualy after page generated. But miss how to program the number of rows and its values in the view.
My code in view:
<?= $form->field($User, 'User')->widget(MultipleInput::className(), [
'min' => 0,
'max' => 4,
'columns' => [
[
'name' => 'name',
'title' => 'Name',
'type' => 'textInput',
'options' => [
'onchange' => $onchange,
],
],
[
'name' => 'birth',
'type' => \kartik\date\DatePicker::className(),
'title' => 'Birth',
'value' => function($data) {
return $data['day'];
},
'options' => [
'pluginOptions' => [
'format' => 'dd.mm.yyyy',
'todayHighlight' => true
]
]
],
]
])->label(false);
How can I make (for example) 8 rows with different values, and also have the ability to edit/remove/update some of them?
You need to look into the documentation as it says that you need to assign a separate field into the model which will store all the schedule in form of JSON and then provide it back to the field when editing/updating the model.
You have not added the appropriate model to verify how are you creating the field User in your given case above. so, i will try to create a simple example which will help you implement it in your scenario.
For Example.
You have to store a user in the database along with his favorite books.
User
id, name, email
Books
id, name
Create a field/column in you User table with the name schedule of type text, you can write a migration or add manually.
Add it to the rules in the User model as safe.
like below
public function rules() {
return [
....//other rules
[ [ 'schedule'] , 'safe' ]
];
}
Add the widget to the newly created column in ActiveForm
see below code
echo $form->field($model,'schedule')->widget(MultipleInput::class,[
'max' => 4,
'columns' => [
[
'name' => 'book_id',
'type' => 'dropDownList',
'title' => 'Book',
'items' => ArrayHelper::map( Books::find()->asArray()->all (),'id','name'),
],
]
]);
When saving the User model convert the array to JSON string.
like below
if( Yii::$app->request->isPost && $model->load(Yii::$app->request->post()) ){
$model->schedule = \yii\helpers\Json::encode($model->schedule);
$model->save();
}
Override the afterFind() of the User model to covert the json back to the array before loading the form.
like below
public function afterFind() {
parent::afterFind();
$this->schedule = \yii\helpers\Json::decode($this->schedule);
}
Now when saved the schedule field against the current user will have the JSON for the selected rows for the books, as many selected, for example, if I saved three books having ids(1,2,3) then it will have json like below
{
"0": {
"book_id": "1"
},
"2": {
"book_id": "2"
},
"3": {
"book_id": "3"
}
}
The above JSON will be converted to an array in the afterFind() so that the widget loads the saved schedule when you EDIT the record.
Now go to your update page or edit the newly saved model you will see the books loaded automatically.
So I am new to laravel. I am trying to use a view but it keeps referencing its self with links.
See below what I mean
So I have a route "customers"
Route::get('customers/{cid?}', [
'uses' => 'customers#getCustomerView'
])->name('customers');
In this route as you can see I reference a controller getCustomerView. With an optional CID as someone might just want to see a list of customers. Then choose their customer. So here is the controller function
public function getCustomerView($cid = null){
$activeCustomer = array();
if(!empty($cid)){
// do middleware to get customer active detail
$activeCustomer = array(
'company' => 'Company '.$cid,
'fname' => 'Test',
'lname' => 'test'
);
}
return view('customers.view', [
'title' => 'Customer List',
'cid' => $cid,
'activeCustomer' => $activeCustomer,
'clist' => [
['company'=>'Company 1', 'fname' => 'Bob', 'lname' => 'Smith'],
['company'=>'Company 2', 'fname' => 'Julie', 'lname' => 'Reid'],
['company'=>'Company 3', 'fname' => 'Tony', 'lname' => 'Tima']
]
]);
}
When I load http://domain/customers - Everything works fine.
In my customers.view I have the following that loops and put's the array into a table. Later I will be using some middle ware or self function to get data from database. For now I am just using a harden array.
#foreach($clist as $key=>$customer)
<tr>
<td>{{$key+1}}</td>
<td>{{$customer['company']}}</td>
<td>{{$customer['fname']}}</td>
<td>{{$customer['lname']}}</td>
</tr>
#endforeach
The problem lies. Once I click on a customer. Page loads fine. http://domain/customers/1 - But if I go to click on another customer it does this
http://domain/customers/1/customers/2 - obviously this would cause an error. So why is it doing this?
How can I prevent it?
use this :
<td>{{$customer['company']}}</td>
it will generate a full url like http://domain/customers/1
but you can simply do that :
<td>{{$customer['company']}}</td>
I am new to yii2 and trying to get around. I have a dropdownlist whose values in the database are enum. So when the crud was created the dropdownlist had the enum values.
But I want to keep one value selected as default in the drop down list.
My form code is below:
<?= $form->field($model, 'priotiy_level')->dropDownList([ 'low' => 'Low', 'medium' => 'Medium', 'high' => 'High', ], ['prompt' => 'Select Priority Level']) ?>
Instead of the prompt, I want to have medium as a selected value. Can someone please help me with this?
Thank you.
After initialization of the $model instance in your controller set the attribute and then pass $model to view.
$model->priority_level = 'medium';
As #Bizley said, you need to set the value of the attribute in your Controller. In Yii2, you can do that with in one line:
public function actionSomething {
$model = new MyClass(['priotiy_level' => 'medium']);
// code
return $this->render('something', [
'model' => $model
]);
}
Additionally to previous answers you can also use default validator:
class SomeActiveRecord extends ActiveRecord {
// ...
function rules(){
return [
['priotiy_level', 'default', 'value' => 'medium']
// set "username" and "email" as null if they are empty
[['username', 'email'], 'default'],
// set "level" to be 1 if it is empty
['level', 'default', 'value' => 1],
];
}
}
More details see here: Handling Empty Inputs.
This code sets default value for the all actions/forms. If you need different default values on different forms, can be used also scenarios of validation.
Give class to your dropdownList :
Ex.
<?= $form->field($model, 'priotiy_level')->dropDownList([ 'low' => 'Low', 'medium' => 'Medium', 'high' => 'High', ], ['class' => 'priority_list','prompt' => 'Select Priority Level']) ?>
Give Default value using Java Script or Jquery
Ex.
<script>
$(".priority_list").val('medium'); // assing value using jquery
</script>
You can also use ID:
Ex.
<script>
var temp=document.getElementById('project-industry_id');
temp.value='medium';
</script>
Using Yii2, I'm trying to create a detailView. I want to hide empty rows, and therefore I use the kartik-v detailview. However, I also want to hide attributes if they conform to a certain condition. So I stumbled across this SO question, which captures the intention of my question. It does not, however, answer it satisfactory. (This question asks roughly the same thing). An example
<?= DetailView::widget([
'hideIfEmpty' => true, //available in kartik's detailview
'model' => $model,
'attributes' => [
'id',
'name', //cant be null, always shown
'description:ntext', //can be null, so hidden thanks to kartiks detailview
isAdmin() ? "password" :"", //an example, of course
"hypotheticalOtherField",
isAdmin() ? [
'attribute'=>'client',
'format'=>'raw',
'value'=>function($object) {
return Html::button("MyButton".$object->client);
}
] : ""
]
]) ?>
As you can see, I want to show some fields based on (in this example) whether or not the user is admin. Sadly, inserting emtpy strings, empty arrays, or null values into the attributes array if the condition isn't met, produces an error (IE The attribute must be specified in the format of "attribute", "attribute:format" or "attribute:format:label" when inserting empty strings)
I suppose I could create the attributes array like this:
$attrs = ['id','name','description:ntext'];
if (isAdmin()) array_push($attrs, "password");
array_push($attrs, "hypotheticalOtherField");
if (isAdmin()) array_push($attrs, [
'attribute'=>'client',
'format'=>'raw',
'value'=>function($object) {
return Html::button("MyButton".$object->client);
}
]);
echo DetailView::widget([
'hideIfEmpty' => true, //available in kartik's detailview
'model' => $model,
'attributes' => $attrs
]);
but then the overview with the standard Yii2 code layout is severely undermined.
So is there some way to conditionally insert values into an array, so I can keep coding Yii-style: estetic, organized, and uncluttered? Or maybe a values from which Yii2 knows it should be skipped when creating the View
You can use visible to DetailView
<?= DetailView::widget([
'hideIfEmpty' => true, //available in kartik's detailview
'model' => $model,
'attributes' => [
'id',
'name', //cant be null, always shown
'description:ntext', //can be null, so hidden thanks to kartiks detailview
[
'visible' => (isAdmin() ? true : false),
'value' => $model->password,
'label' => 'test'
],
]) ?>
Add whatever condition you want to add!!! in visible
If you try with an array append shorthand and the look of the code is more yii2 stylish
The attribute based on array is a correct (good) practice.
$attrs[] = ['id','name','description:ntext'];
if (isAdmin()) {
$attrs[] = ['password'];
}
$attrs[] = ['hypotheticalOtherField']
if (isAdmin()) {
$attrs[] = [
'attribute'=>'client',
'format'=>'raw',
'value'=>function($object) {
return Html::button("MyButton".$object->client);
}
}
echo DetailView::widget([
'hideIfEmpty' => true, //available in kartik's detailview
'model' => $model,
'attributes' => $attrs
]);