I am working on a project in yii2. I need to place an input field on the index page. This field should be similar to the form field. i.e. the type of the field that is used in the form while creating a record. For this, I have done the following
public function actionIndex()
{
$model = MdcmetercustRel::className();// this is the class whose data field I want to get
$searchModel = new MdcmetersdataSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
My index
<?=
$form = ActiveForm::begin();
$relModel=$model->getModels()[0]; print_r($relModel['cust_id']);
$form->field($relModel, 'cust_id')->textInput()
?>
When I refresh my page I am getting
Object of class yii\widgets\ActiveForm could not be converted to string
How can I achieve this?
Any help would be highly appreciated
Your mistake is <?=which is trying to output the whole script and you cant echo $form or ActiveForm::begin()
change it to
<?php
$form = ActiveForm::begin();
$relModel=$model->getModels()[0]; print_r($relModel['cust_id']);
echo $form->field($relModel, 'cust_id')->textInput()
?>
Also you need to change the
$model = MdcmetercustRel::className();
to
$model = new MdcmetercustRel();
otherwise there wont be an object in $model but a string i.e class namespace.
Related
In a projects/create active form I have a field "related company account" as a dropdown (select2 by kartik). Behind this field I'd like to place a plus sign or something else to add new accounts to the dropdown with the following behavior:
gather all input done so far (like $input = compact(array_keys(get_defined_vars())); but probably needed on client side)
jump to accounts/create and pass $input
after submiting the new account jump back to projects/create (e.g. return $this->redirect(Yii::$app->request->referrer);) and fill the previously entered data (extract($input, EXTR_PREFIX_SAME, "arr");)
I'm struggling now with several issues:
Is this process according to best practice or should I change something fundamentally?
How is the button like? Submit button, link or some form of javascript?
Problem with Submit button is that not all required fields may be filled. So saving and resuming/updating the project model might not be possible.
Problem with link is that it is constructed before data was entered
Problem with javascript is that I have no glue
Any hints are welcome. Thank you in advance.
One alternative i would suggest is using Session.
As for the "Add Accounts" button, i would use Submit button, and give different name to actual Submit button (two submit button in form, as answered in here). So, the projects/create view will look like this :
<?php $form = ActiveForm::begin(); ?>
...
...
...
<?= $form->field($model, 'account_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Account::find()->all(), "id", "name"),
'options' => ['placeholder' => 'Select a related company account ...'],
'pluginOptions' => [
'allowClear' => true
],
]) ?>
<?= Html::submitButton('Add Account ;)', ['class' => 'btn btn-success', 'name' => 'add_account_submit']) ?>
...
...
...
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
And then check in ProjectsController, which submit button pressed by user. If add account was pressed, then save the inputed field (i would put this function in model for clearance), else, save the model or anything. And, before all that, check if session about project is set, if yes then pre-load it to model (again, in model). Okay, like they say, one code is worth a thousand words, so, this is ProjectsController will look like :
class ProjectsController extends Controller
{
...
...
...
public function actionCreate($category)
{
$model = new Projects();
if (Projects::isSavedInSession()) {
$model->loadFromSession();
}
if (Yii::$app->request->post('add_account_submit')) { // if add_account_submit is clicked
$model->saveTosession(Yii::$app->request->post('Projects')); // I assume your model named Projects, if not, change this value to your model name
return $this->redirect(['accounts/create']);
}
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$model->clearSession(); // we dont need the session anymore
return $this->redirect(['index');
}
return $this->render('create', [
'model' => $model,
]);
}
...
...
...
}
And Projects model will look like :
class Projects extends \yii\db\ActiveRecord
{
...
...
...
public static function isSavedInSession() { // why this is static is beyond this question context
if (Yii::$app->session->get('projects')) return true;
return false;
}
public function loadFromSession() {
if (Yii::$app->session->get('projects_name')) $this->name = if (Yii::$app->session->get('projects_name'));
if (Yii::$app->session->get('projects_account_id')) $this->account_id = if (Yii::$app->session->get('projects_account_id'));
...
... // insert all model's field here
...
}
public function saveToSession($fields) {
Yii::$app->session->set('projects', 1);
foreach ($fields as $field=>$value) {
Yii::$app->session->set('projects_' . $field, $value);
}
}
public function clearSession() {
Yii::$app->session->remove('projects'));
Yii::$app->session->remove('projects_name'));
Yii::$app->session->remove('projects_account_id'));
...
... // insert all model's field here
...
}
...
...
...
}
And in the AccountsController, just tell the program to jump back to projects/create if projects session is set, like so :
class AccountsController extends Controller
{
...
...
...
public function actionCreate($category)
{
$model = new Accounts();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if (Projects::isSavedInSession()) {
return $this->redirect(['projects/create');
}
return $this->redirect(['index');
}
return $this->render('create', [
'model' => $model,
]);
}
...
...
...
}
Well, it's looks bit lengthy, but yeah, it's worth trying. Anyway, you could use this approach for another purpose, save current form state for example.
Oh, one more thing, i haven't tested this in real code, so if any error exposed on my code, hit me up in comment.
Happy coding. :)
I want to get value of field in controller.
could you please help me?
here is my form code:
<?php
$form = ActiveForm::begin([
'id' => 'request-form',
'action' => 'site/request_page',
'method' => 'post',
'fieldConfig' => ['autoPlaceholder' => false]
]);
?>
<?= $form->field($model, 'workroom_id')->label(FALSE) ?>
and this is my controller code:
public function actionRequest_page() {
echo Yii::$app->request->post('workroom_id');
die();
}
But I got nothing in result.
write workroom_id in safe rule like this-
public function rules()
{
return [
[['workroom_id'],'safe']
];
}
Use bellow code -
echo Yii::$app->request->post('MODEL_NAME')['workroom_id'];
You should expand your action form-attribute. By using Url::to() for instance. As in echo \yii\helpers\Url::to(['site/request_page']);
And access your post data differently. Try var_dump(Yii::$app->request->post()); to see what your form data looks like. The other answer shows how to access it correctly.
The docs have an excellent starting place for working with forms.
I have created a DynamicModel to build a search form which contains a checkboxList with the items being populated by the records of a model. The form works fine, however the form appears on the results page and all fields are populated with the previously selected values apart from the checkboxList.
Controller:
$model = DynamicModel::validateData(
['date_from',
'date_to',
'client_site',
'report_types',
]);
$model->addRule(['client_site'], 'integer');
$model->addRule(['client_site', 'report_types'], 'required');
$model->addRule(['date_from','date_to'], 'string');
$model->load(Yii::$app->request->post()) && $model->validate();
$reportTypes = ArrayHelper::map(ReportType::find()->asArray()->all, 'id', 'name');
return $this->render('print-report-form', [
'report_types' => $reportTypes,
'model' => $model,
]);
View:
<?= $form->field($model, 'report_types[]')
->inline(false)
->checkboxList($reportTypes);
?>
Do I need to tie the $reportTypes in within the model another way? Any ideas on why the selected checkboxes are not being pre-populated on the form submission?
First of all, there is a mistake in view form field, variable name is wrong, it should be
<?= $form->field($model, 'report_types[]')
->inline(false)
->checkboxList($report_types);
?>
then in controller
$model = DynamicModel::validateData(
['date_from',
'date_to',
'client_site',
'report_types',
]);
$model->addRule(['client_site'], 'integer');
$model->addRule(['client_site', 'report_types'], 'required');
$model->addRule(['date_from','date_to'], 'string');
$posted_model = clone $model;
$reportTypes = ArrayHelper::map(ReportType::find()->asArray()->all, 'id', 'name');
if($posted_model->load(Yii::$app->request->post()) && $posted_model->validate())
{
// save data or do as per your requirement with $posted_model
// if nothing to be done, and just rendering back to form then
return $this->render('print-report-form', [
'report_types' => $reportTypes,
'model' => $model, // line X
]);
}
else
{
return $this->render('print-report-form', [
'report_types' => $reportTypes,
'model' => $model, // line X
]);
}
This was happening because when the view was rendering the very first time, all checkbox are empty, but when submit the form the model gets filled up with POSTed data ie all its attribute are set and then always you were rendering POSTed model ie the model filled with data.
Now with the above situation you are not rendering POSTed model, you are always rendering empty new model.
This was the situation where you need empty checkbox.
Second Situation:
If you need checkbox to be prepopulated then
remove [] in form field
<?= $form->field($model, 'report_types')
->inline(false)
->checkboxList($report_types);
?>
and replace line X by
'model' => $posted_model,
Here you will get filled checkboxes
I want to show selected value in Yii2 dropdown,
$_GET Value:
$id = $_GET["cid"];
Drop down code
$form->field($model, 'userid')
->dropDownList(
[User::getUser()],
//[ArrayHelper::map(User::findAll(['active' => '1']), 'id', 'name')],
['prompt'=>'Select a user','id'=>'user_dropdown'],
['options' =>
[
$id => ['selected' => true]
]
]
)->label('');
but this method is not working!
Try this.
$model->userid=$id;
$form->field($model, 'userid')
->dropDownList(...)
->label('');
Basically, you affect the options (your <option> elements) by using the value attribute's actual value as the array key in the dropDownList options array.
So in this case I have an array of states and the value attributes have the state abbreviation, for example value="FL". I'm getting my selected state from the Address table, which stores the abbreviation, so all I have to do is use that as my array key in the options array:
echo $form->field($model, 'state')->dropDownList($listData, ['prompt'=>'Select...', 'options'=>[$address->state=>["Selected"=>true]]]);
The documentation spells it out: http://www.yiiframework.com/doc-2.0/yii-helpers-basehtml.html#dropDownList()-detail
i hope this will help you
$form->field($model, 'userid')
->dropDownList(
[User::getUser()],
//[ArrayHelper::map(User::find()->where('id' => $id)->all(), 'id', 'name')],
['prompt'=>'Select a user','id'=>'user_dropdown'],
['options' =>
[
$id => ['selected' => true]
]
]
)->label('');
$model->userid = $_GET['cid'];
$form->field($model, 'userid')
->dropDownList(
$items, //Flat array('id'=>'val')
['prompt'=>''] //options
)->label('');
<?php
$selectValue = $_GET['tid']
echo $form->field($model, 'tag_id')
->dropdownList(
ArrayHelper::map(Tag::find()->where(['visibility'=>'1'])->orderBy('value ASC')->all(), 'tag_id', 'value'),
['options' => [$selectValue => ['Selected'=>'selected']]],
['prompt' => '-- Select Tag --'])
->label(false);
?>
This code will Auto Select the selected value received as input.
Where $selectValue will be numeric value received from GET method.
Final output : <option value="14" selected="selected">NONE</option>
Ok, if you are using ActiveForm then value of your model field will be used as the selected value. With Html helper dropDownList function accepts another parameter selection doc. Example:
$id = $_GET["cid"];
\yii\helpers\Html::dropDownList('userid', $id, [ArrayHelper::map(User::findAll(['active' => '1']), 'id', 'name'), [......])
This is my S.O.L.I.D approach.
Controller
$model = new User();
$model->userid = $id; #this line does the magick. Make sure the $id has a value, so do the if else here.
return $this->return('view', compact('model'))
But, if you prefer the setter method. Do this...
# Model
class User extends ActiveRecord
{
public function setUserId(int $userId): void
{
$this->userid = $userId;
}
}
# Controller
$model = new User();
$model->setUserId($userId);
View (view is as-is)
$form->field($model, 'userid')
->dropDownList(...)
->label('');
Use this code below:
$category = \backend\models\ProductCategory::find()->WHERE(['deleted'=>'N'])->all();
$listData = ArrayHelper::map($category,'product_category_id','category_name');
echo $form->field($model, 'product_category_id')->dropDownList($listData,['prompt'=>'Select']);
All of the options I've added are unrequired.
What is written in the 'value' index is what dropdown item will be selected as default.
Prompt just displays a first option that doesn't have a value associated with it.
echo $form->field($model, 'model_attribute_name')
->dropDownList($associativeArrayValueToText,
[
'value'=> $valueIWantSelected,
'prompt' => 'What I want as a placeholder for first option',
'class' => 'classname'
]);
You'll find the function that assigns this in the following file:
vendor/yiisoft/yii2/helpers/BaseHtml.php
public static function renderSelectOptions($selection, $items, &$tagOptions = [])
Also from the function you can see that you can add an optgroup to your dropdown, you just need to supply a multidimensional array in where I've put $associativeArrayValueToText. This just means that you can split your options by introducing group headings to the dropdown.
I have created datetime field in mysql. I want to store it in the db when i pick the date by using datepicker.
This is my part of code in controller
public function actionCreate()
{
$model=new EmpDetails;
$model->created = date("Y-m-d H:i");
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST['EmpDetails']))
{
$model->attributes=$_POST['EmpDetails'];
if($model->save())
$this->redirect(array('view ','id'=>$model->emp_id));
}
$this->render('create',array(
'model'=>$model,
));
}
The part of my form.php is:
<div class="row">
<?php echo $form->labelEx($model,'dateof_leave'); ?>
<?php $model->created=new CDbExpression('NOW()');
$sqldate = date('Y-m-d H:i:s',strtotime($textFieldValue));?>
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'model' => $model,
'attribute' => 'dateof_leave',
'htmlOptions' => array(
'size' => '10', // textField size
'maxlength' => '10', // textField maxlength
),
));
?>
<?php // echo $form->textField($model,'dateof_leave'); ?>
<?php echo $form->error($model,'dateof_leave'); ?>
</div>
am facing the error Property "EmpLeave.created" is not defined.
Please clarify my doubts and explain me how can i overcome this issue?
Replace
$model->created=new CDbExpression('NOW()');
On
$model->created=date("Y-m-d H:i:s");
Because CJuiDatePicker needs string on input.
In yout Controller you add line
$model->created = date("Y-m-d H:i");
In your _form.php you add input form for dateof_leave. So when posting form the $model->created is EMPTY. If i am understand right In controller u must add
$var= $_POST['EmpDetails']['dateof_leave'];
$model->created = date("Y-m-d H:i", $var);