I have 3 views. The create and update view are the same. In the _form.php view file. I have this:
<?php
use yii\bootstrap\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'adr_country_id') ->dropDownList($cities) ?>
<?php ActiveForm::end()?>
In the create and update view:
<?= $this->render('_form', ['model' => $model, cities' => $cities ]); ?>
. I can create new record but cant update it. I got the error in the title. This is my controller for update. What might be the problem here? Thanks in advance
public function actionUpdate($id) {
$model = ArrayHelper::map(AdrCountry::find()->all(),'id','name');
$cities = AdrCity::findOne($id);
if ($cities->load(Yii::$app->request->post()) && $cities->validate())
{
$cities->save();
Yii::$app->session->setFlash('success', ' updated');
return $this->redirect(['index']);
}
return $this->render('update',[
'cities' => $cities,
'model' => $model
]); }
Update you controller's action
public function actionUpdate($id) {
$cities = ArrayHelper::map(AdrCountry::find()->all(),'id','name');
$model = AdrCity::findOne($id);
if ($model->load(Yii::$app->request->post()) && $model->validate())
{
$model->save();
Yii::$app->session->setFlash('success', ' updated');
return $this->redirect(['index']);
}
return $this->render('update',[
'cities' => $cities,
'model' => $model
]); }
Related
I'm getting error from yii\web\Response when I use ajax validation.
Object of class yii\web\Response could not be converted to string
widget:
public function run()
{
$model = new Participants();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
$list = implode( ", ",$model->sections);
$model->sections = $list;
$model->save();
Yii::$app->session->setFlash(Alert::TYPE_SUCCESS, [
[
'title' => 'Congratulations!',
'text' => 'You are registered on the forum. Check out your email to get news about forum.',
'confirmButtonText' => 'Done!',
]
]);
return Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
}
return $this->render('header', [
'model' => $model,
]);
}
view of widget:
<?php $form = ActiveForm::begin();?>
...
<?= $form->field($model, 'email', ['enableAjaxValidation' => true])->textInput(['placeholder' => 'Email']); ?>
how I can solve this error? P.S. yii version - 2.0.17-dev
\yii\base\Widget::run() must return a string (all widgets basically)
All you should do within method run() is output or render content and you're attempting to return a Response object by way of return ActiveForm::validate($model); and return Yii::$app->controller->redirect(..)
i suggest you move all the code that supposed to handle form submission to it's own action
SiteController extends controller {
public function actionRegisterParticipant {
$model = new Participants();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
$list = implode(", ", $model->sections);
$model->sections = $list;
$model->save();
Yii::$app->session->setFlash(Alert::TYPE_SUCCESS, [
[
'title' => 'Congratulations!',
'text' => 'You are registered on the forum. Check out your email to get news about forum.',
'confirmButtonText' => 'Done!',
]
]);
return Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
}
// ...
}
and the form in the widget view should always point to this action:
<?php $form = ActiveForm::begin(['action' => 'site/register-participant']);?>
...
<?= $form->field($model, 'email', ['enableAjaxValidation' => true])->textInput(['placeholder' => 'Email']); ?>
Widget should return string as a result, but return Yii::$app->controller->redirect() returns Response object with configured redirection. If you want to redirect inside of widget you should use something like that:
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->controller->asJson(ActiveForm::validate($model));
Yii::$app->end();
}
// ...
Yii::$app->session->setFlash(/* ... */);
Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
Yii::$app->end();
But this smells like a bad design - widget should not be responsible for controlling application flow. It is better to handle user input in regular action/controller.
I have one form that form have below fields
i)Book
ii)Amount
Controller action:
public function actionBook()
{
$model = new Book();
if ($model->load(Yii::$app->request->post()) && $model->validate()){
print_r($model);exit;
return $this->redirect('/Book');
}
$model->getBook();
return $this->render('BookForm', ['model' => $model]);
}
Whenever this page will load i will call one model function by default, the function is getBook()
Model:
public book;
public amount;
public showAmountField;
public function rules()
{
return [
[['book'], 'required'],
['amount', 'required', 'when' => function($model) {
return $model->showAmountField == true;
}],
];
}
public function getBook()
{
if(some condition here){
$this->showAmountField = true;
}
}
so whenever the showAmountField is true at the time the amount field is required, otherwise it will not required, here all are working fine and the client side validation also working fine, but when i change amount field id using console(f12) at the time the server side validation not working and form is simply submit with the amount field is empty, so what is wrong here. Please explain anyone.
UPDATE
View
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
$this->params['breadcrumb'] = $model->breadCrumbs;
?>
<?php $form = ActiveForm::begin([
'id' => 'book-form',
'options' => ['class' => 'form-horizontal'],
]);
?>
<?= $form->field($model, 'book')->textInput()->label("Book"); ?>
<?php if($model->showAmountField): ?>
<?= $form->field($model, 'amount')->textInput()->label("Amount"); ?>
<?php endif; ?>
<?= $form->errorSummary($model, ['header' => '']); ?>
<?php ActiveForm::end(); ?>
Validation occurs on the field ID, if you change it through the console, the model does not understand that it needs to validate
$model = new Book();
if ($model->load(Yii::$app->request->post()) && $model->validate()){
print_r($model);exit;
return $this->redirect('/Book');
}
$model->getBook();
here you are initialising the $model->getBook(); after the if block so the model gets overridden in post request with new instance and hence server side validations fails for when condition.
$model = new Book();
$model->getBook();
if ($model->load(Yii::$app->request->post()) && $model->validate()){
print_r($model);exit;
return $this->redirect('/Book');
}
it should be before post load
i am using yii2 RESTapi for my module .my problem the validation is working fne and the error msg also display in console as a json format but it's not set in form field .see the image for more info..please help me anyone ...
This is model
public function rules()
{
return [
[['username'], 'required'],
[['username'],'unique'],
}
view:
<?php $form = ActiveForm::begin([
'id' => 'cab-form',
'enableAjaxValidation' => true,
])
; ?>
<?= $form->field($model, 'username')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton( 'Create', ['class' => 'btn btn-success','id'=>'submit-btn']) ?>
</div>
<?php ActiveForm::end(); ?>
controller:
public function actionCreate(){
$model = new Cab;
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$post_data = Yii::$app->request->post();
$model->load($post_data);
$model->save();
return $model;
}
Thanks...
Unique require AjaxValidation to work. You need verify in your controller if an ajax request exist and return the validation encoded with JSON. See the example below:
if ($model->load(Yii::$app->request->post()) {
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
}
I have two tables with foreign key relation . How to store company name in employee table.
in my view i have like this
<?= $form->field($model, 'Company_company_id')->dropDownList(ArrayHelper::map(
Company::find()->orderBy('Company_name')->all(),'Company_id','Company_name'),
['prompt'=>'Select Company','id' =>'cname','name'=>'cname'])
?>
controller
public function actionCreate()
{
$model = new Employee();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->save();
return $this->redirect(['index']);
}else {
return $this->render('create', [
'model' => $model,]);
}
}
Try this
<?= $form->field($model, 'company_id')->dropDownList(
ArrayHelper::map(Company::find()->
where(['id'=>company_id])->all(), 'id', 'companyname'),
[ 'prompt' => 'Please Select Company']
)
?>
I am using yii2 basic for my application. When I login to my application by typing wrong username or password, it does not set any message like incorrect username or password. The browser simply refreshes the page.
This is my site/login.php file:
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
/* #var $this yii\web\View */
/* #var $form yii\bootstrap\ActiveForm */
/* #var $model app\models\LoginForm */
$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-login">
<h1><?= Html::encode($this->title) ?></h1>
<p>Please fill out the following fields to login:</p>
<?php $form = ActiveForm::begin([
'id' => 'login-form',
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => [
'template' => "{label}\n<div class=\"col-lg-3\">{input}</div>\n<div class=\"col-lg-8\">{error}</div>",
'labelOptions' => ['class' => 'col-lg-1 control-label'],
],
]); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'rememberMe')->checkbox([
'template' => "<div class=\"col-lg-offset-1 col-lg-3\">{input} {label}</div>\n<div class=\"col-lg-8\">{error}</div>",
]) ?>
<div class="form-group">
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
<!-- <div class="col-lg-offset-1" style="color:#999;">
You may login with <strong>admin/admin</strong> or <strong>demo/demo</strong>.<br>
To modify the username/password, please check out the code <code>app\models\User::$users</code>.
</div> -->
</div>
And here is my action for login:
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post())) {
$model->password = md5($model->password);
$model->login();
return $this->redirect(['site/index']);
}
return $this->render('login', [
'model' => $model,
]);
}
Any help would be greatly appreciated.
You can add a custom message error in your rules.
public function rules()
{
return [
['username', 'required', 'message' => 'Please choose a username.'],
];
}
It creates a JavaScript vaidation and shows the error in message if validation was wrong.
See Validating Input and Customizing Error Messages section.
EDIT:
If you are using the basic app, make sure that your LoginForm.php has the login form calls validate. Something like this:
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
} else {
return false;
}
}
This is from the advanced template but is similar.
The if ($model->load())-statement does no validation at all. It simply determines if the form in question was POSTed and that the POST data was loaded into the form instance. I'm assuming that the login() function returns a bool so you'll have to check its return result as well:
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post())) {
$model->password = md5($model->password);
if ($model->login()) {
return $this->redirect(['site/index']);
}
}
return $this->render('login', [
'model' => $model,
]);
}
If the login function correctly uses the model::addError() function it should then also display errors.
The login-function of the basic application does run the validation, as #Sageth pointed out, so the change I proposed will work as expected.