I Have my model with 2 fields Product.php:
[['ID_PRODUCT'], 'integer'],
[['NAME_PRODUCT'], 'string'],
my Controller ProductController.php:
public function actionCreate()
{
$model = new Product();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->ID_PRODUCT]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
And i want insert many times the same table with ActiveForm:
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'ID_PRODUCT')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'NAME_PRODUCT')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'ID_PRODUCT')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'NAME_PRODUCT')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
But when i save the information the fields are overwritten and only the last record is inserted
What you are trying to do is collect, validate and save tabular data. The reason it doesn't work is that in the form, Yii generates a name tag based on the field name and model, e.g. name="[Product]["ID_PRODUCT"]. When the form is sent to the server, the first fields get overwritten by the last ones, as they have the same name. The correct way to collect tabular input in a form is to add brackets at the end of the name, like this; name="[1][Product]["ID_PRODUCT"].Using this method, Yii gives ways of loading and validating multiple models.
Modify your controller code to use multiple models;
<?php
namespace app\controllers;
use Yii;
use yii\base\Model;
use yii\web\Controller;
use app\models\Product;
class ProductController extends Controller
{
public function actionCreate(){
//Find out how many products have been submitted by the form
$count = count(Yii::$app->request->post('Product', []));
//Send at least one model to the form
$products = [new Product()];
//Create an array of the products submitted
for($i = 1; $i < $count; $i++) {
$products[] = new Product();
}
//Load and validate the multiple models
if (Model::loadMultiple($products, Yii::$app->request->post()) && Model::validateMultiple($products)) {
foreach ($products as $product) {
//Try to save the models. Validation is not needed as it's already been done.
$product->save(false);
}
return $this->redirect('view');
}
return $this->render('create', ['products' => $products]);
}
}
Now you have all the data you need to populate the form, including any error messages generated for individual instances of you product model. The view file for the form needs to be altered like this, to use the multiple models;
foreach ($products as $index => $product) {
echo $form->field($product, "[$index]ID_PRODUCT")->label($product->ID_PRODUCT);
echo $form->field($product, "[$index]NAME_PRODUCT")->label($product->NAME_PRODUCT);
}
All of this is covered in the Yii2 documentation
Related
I created a table named (users) it has two columns: name and pass.
In view I created form like this:
<?php
$form = ActiveForm::begin() ?>
<div class="form-group">
<?= $form->field($model, 'user') ?>
<?= $form->field($model, 'password') ?>
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end() ?>
So I need to pass this two attributes to controller to insert into data base.
In YourController.php
assuing you have an Create action for manage your insert in db
and a create view for manage the user input (a view for only display the correct result )
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\EntryForm;
class YourController extends Controller
{
// ...existing code...
public function actionCreate()
{
$model = new User();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// valid data received in $model
//
if( $model->save()){
return $this->render('create', ['model' => $model]);
} else {
// this is just for debug
var_dump('not inserted');
die();
}
} else {
// either the page is initially displayed or there is some validation error
return $this->render('view', ['model' => $model]);
}
// render the initial page per allow to the user input
return $this->render('create', ['model' => $model]);
}
....
}
In your controller you can get your post form in this way:
Yii::$app->request->post()
And this way you can load the value into your model
$model->load(Yii::$app->request->post())
Here you can find a starting point
I am coding a form to get user input and then pass that information to a controller and execute a function based on that, at this point I can not pass the data to the controller using POST method, I get empty vars.
So the Controller function display the view form correctly, I can type on the textboxes, after press submit button I get a setFlash custom message that the parameters are empty. I am using a model class with just two parameters.
a) This is the model:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class SendmailForm extends Model
{
public $template;
public $emtransport;
/**
* #return array the validation rules.
*/
public function rules()
{
return [
[['template', 'emtransport'], 'required'],
];
}
}
b) This is the view:
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\captcha\Captcha;
$this->title = 'Send Mail';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-contact">
<h1><?= Html::encode($this->title) ?></h1>
<?php if (Yii::$app->session->hasFlash('sminfo')): ?>
<div class="alert alert-success">
<?= Yii::$app->session->getFlash('sminfo');?>
</div>
<?php else: ?>
<p>
SendMail Exercise. Please choose needed options bellow:
</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'sendmail-form']); ?>
<?= $form->field($model, 'template')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'emtransport') ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'value'=>'one', 'name'=>'sendbtn']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php endif; ?>
</div>
And this is the controller's function:
public function actionSendmail(){
$model = new SendmailForm();
if ($model->load(Yii::$app->request->post())) {
$template = Yii::$app->request->post('template');
$emailTransport = Yii::$app->request->post("emtransport");
if($emailTransport=="local"){
for($i=0;$i<=2;$i++){
$xclient = 'client' . $i;
\app\models\User::findByUsername($xclient)->sendMail($template, 'Welcome To XYZ Services', ['accountInfo' => 'www.mysite.com']);
}//end of for loop
Yii::$app->session->setFlash("sminfo", "Emails sent successfully to the Clients");
return $this->refresh();
}//end of second if loop
else{
Yii::$app->session->setFlash("sminfo", "Params could not be verified!. Contact Tech Support");
return $this->refresh();
}
}//end of post if loop
return $this->render('sendmail', [
'model' => $model,
]);
}
The idea is to get the values from the view, at this moment I am getting empty values-
Two parts below:
$template = Yii::$app->request->post('template');
$emailTransport = Yii::$app->request->post("emtransport");
Change the following:
$template = $model->template;
$emailTransport = $model->emtransport;
After editing
public function actionSendmail(){
$model = new SendmailForm();
if ($model->load(Yii::$app->request->post())) {
$template = $model->template;
$emailTransport = $model->emtransport;
if($emailTransport=="local"){
for($i=0;$i<=2;$i++){
$xclient = 'client' . $i;
\app\models\User::findByUsername($xclient)->sendMail($template, 'Welcome To XYZ Services', ['accountInfo' => 'www.mysite.com']);
}//end of for loop
Yii::$app->session->setFlash("sminfo", "Emails sent successfully to the Clients");
return $this->refresh();
}//end of second if loop
else{
Yii::$app->session->setFlash("sminfo", "Params could not be verified!. Contact Tech Support");
return $this->refresh();
}
}//end of post if loop
return $this->render('sendmail', [
'model' => $model,
]);
}
I did some changes to the Controller and now it works, those are them:
//at the beginning of the Controller:
use app\models\SendmailForm;
//two lines changed in the function:
$model->template = $_POST['SendmailForm']['template'];
$model->emtransport = $_POST['SendmailForm']['emtransport'];
That's all I needed. Best regards
I have a user model and an attachment model.
User:
id name email password_hash
--------------------------------------
1 Reza reza#web.af xxxxxxx
Attachment:
user_id type(enum) name
--------------------------------------
1 resume fk4k34kdfmkg3.pdf
1 photo 59rg3kerfn3ju.jpg
1 nid 34kf2wkefclh0.jpg
I need to create the activeform for it and I am wondering what is the appropriate (best) way to create model fields for them. each time a new user is registered three rows of attachments will be inserted to the attachments table too. Of course the following activeform is not doing what i want. please help.
<?php $form = ActiveForm::begin(); ?>
<?=$form->field($user, 'name')->textInput(['maxlength' => true]) ?>
<?=$form->field($user, 'email')->textInput(['maxlength' => true]) ?>
<?=$form->field($user, 'password_hash')->passwordInput(['maxlength' => true]) ?>
<?= $form->field($attachment, 'type')->fileInput()->label('photo') ?>
<?= $form->field($attachment, 'type')->fileInput()->label('resume') ?>
<?= $form->field($attachment, 'type')->fileInput()->label('nid') ?>
..
..
In your model define three public variable like
public $typePhoto;
public $typeResume;
public $typeNid;
then define rules like
public function rules()
{
return [
[['typePhoto', 'typeResume', 'typeNid'], 'required'],
];
}
and then create ActiveForm like this
<?php $form = ActiveForm::begin(); ?>
<?=$form->field($user, 'name')->textInput(['maxlength' => true]) ?>
<?=$form->field($user, 'email')->textInput(['maxlength' => true]) ?>
<?=$form->field($user, 'password_hash')->passwordInput(['maxlength' => true]) ?>
<?= $form->field($attachment, 'typePhoto')->fileInput()->label('photo') ?>
<?= $form->field($attachment, 'typeResume')->fileInput()->label('resume') ?>
<?= $form->field($attachment, 'typeNid')->fileInput()->label('nid') ?>
..
..
Refer Creating Forms
I think for that purpose you should use yii model form extended from yii\base\Model. It can provide columns different from database ones.
Here is the simplified example of form model that you need:
class LoginForm extends \yii\base\Model
{
public $name;
public $email;
public $password_hash;
public $type_resume;
public $type_photo;
public $type_nid;
public function rules()
{
return [
// define validation rules here
];
}
public function saveData()
{
$userModel = new User();
$userModel->name = $this->name;
//and so on, save all user properties
$userModel->save();
$attachModel = new Attachment();
$attachModel->type = 'resume'; //it better to use constant
$attachModel->user_id = $userModel->id;
$attachModel->name = ' '; //set the necessary value
$attachModel->save();
//and so on, save your attachment models for all types
}
}
So your ActiveForm should be something like this:
<?php $form = ActiveForm::begin(); ?>
<?=$form->field($loginForm, 'name')->textInput(['maxlength' => true]) ?>
<?=$form->field($loginForm, 'email')->textInput(['maxlength' => true]) ?>
<?=$form->field($loginForm, 'password_hash')->passwordInput(['maxlength' => true]) ?>
<?= $form->field($loginForm, 'type_photo')->fileInput()->label('photo') ?>
<?= $form->field($loginForm, 'type_resume')->fileInput()->label('resume') ?>
<?= $form->field($loginForm, 'type_nid')->fileInput()->label('nid') ?>
..
In code above the $loginForm is object of LoginForm class. Use saveData method of LoginForm to save the data properly.
For more information about yii form models visit http://www.yiiframework.com/doc-2.0/guide-input-forms.html
I am newbie to yii2. I am trying to create my simple form in yii2 to retrieve password. Here is class code:
<?php
namespace app\models;
use yii\base\Model;
class RetrievePasswordForm extends Model
{
public $email;
public function rules()
{
return [
['email', 'required'],
['email', 'email'],
];
}
}
Here is action code:
$model = new RetrievePasswordForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()){
return $this->render('retrievepassword-confirm', ['model' => $model]);
} else {
return $this->render('retrievepassword', ['model' => $model]);
}
My form looks like this:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$this->title = 'Retrieve password';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?= Html::encode($this->title) ?></h1>
<p>We will send link to retrieve your password to the following email:</p>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'email')->textInput(['style'=>'width:200px'])?>
<div class="form-group">
<?= Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
The problem is that $model->load(Yii::$app->request->post()) always returns false, so when I am clicking "submit" button, page just reloads.
I am currently working without database. I am just creating form and trying to go to another form, when valid data received in model. Thanks for help.
Try explicitally assign the method and the action to the active Form
Then Assuming that your target action is named actionRetrivePassword
<?php $form = ActiveForm::begin([
'method' => 'post',
'action' => Url::to(['/site/retrivepassword']
); ?>
I'll go with I feel it's wrong, if this doesn't help, please give more information.
It's a registration form, so I assume you need email and password for that (since you have those columns in database). But you also declared public member $email in your model. This removes any value associated to $email from database. Therefore, remove this line:
public $email;
I have 3 tables:
Order
Ordered_number
Number
Ordered_number connects the other two - it has order_id and number_id columns.
In my Index Action, I want to render view named "call", where I have a form with choosing one order. When I submit which order I want, I want to go to actionCall and send there numbers connected with this order. Something isn't correct and I think I may be doing something wrong.
public function actionIndex()
{
$model = new \common\models\Order();
if ($model->load(Yii::$app->request->post())){
$numery = \common\models\Number::find()
->joinWith('ordered_number')
->where(['ordered_number.order_id' => $model->id]);
return $this->redirect(['/call', 'numery' => $numery]);
} else {
$this->render('call', ['model' => $model]);
}
}
When I open my actionIndex it displays a blank page instead of rendering a view that I want.
My "call" view:
<?php
use common\models\Customer;
use common\models\Order;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\web\View;
use yii\widgets\ActiveForm;
/* #var $this View */
/* #var $form ActiveForm */
/* #var $model Order */
var_dump($this);
die();
echo "<h1>Dodaj numery do przedzwonienia</h1>";
echo "Wybierz zamówienie, którego numery chcesz przedzwonić: ";
$form = ActiveForm::begin();
$form->field($model, 'id')->dropDownList(ArrayHelper::map(Customer::find()->all(), 'id', 'id'));
Html::submitButton("Przedzwoń", ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']);
ActiveForm::end();
I added var_dump in my view, and it displays it, but without var_dump and die() command, there is simply blank page without text I want to be next.
Missing return statement in else
return $this->render('call', ['model' => $model]);