Yii2 rule array validation - validation

I have 2 models A and B where A has many B.
Now i want to create multiple B at the same time(page).
Here is my codes.
B.php
...
public function rules()
{
return [
[['username', 'xx', 'yy'], 'required'],
[['xx', 'yy'], 'string'],
[['username'], 'string', 'max' => 255]
];
}
...
_form.php
<div class="b-form">
<?php $form = ActiveForm::begin(); ?>
<?php for ($i=0; $i < 3; $i++) {
?>
<h3>B #<?=$i+1?></h3>
<hr />
<?= $form->field($model, 'xx[]')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'yy[]')->textInput(['maxlength' => true]) ?>
<?php
}
?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
I want to make those 6(3x2) text inputs responds individually and at least need 2 pairs of xx and yy to pass validation.
Now how do i build good rules to cover my needs?

There is dedicated section about it in official docs - Collecting Tabular Input.
Example of controller:
<?php
namespace app\controllers;
use Yii;
use yii\base\Model;
use yii\web\Controller;
use app\models\Setting;
class SettingsController extends Controller
{
// ...
public function actionUpdate()
{
$settings = Setting::find()->indexBy('id')->all();
if (Model::loadMultiple($settings, Yii::$app->request->post()) && Model::validateMultiple($settings)) {
foreach ($settings as $setting) {
$setting->save(false);
}
return $this->redirect('index');
}
return $this->render('update', ['settings' => $settings]);
}
}
Used methods:
Model::loadMultiple() - load post data into an array of models.
Model::validateMultiple() - validates an array of models.
There is more info, for example how to create a dynamic set of new records, use it if you need it.
Also, take a look to some extensions for easing work with multiple inputs, for example unclead/yii2-multiple-input or wbraganca/yii2-dynamicform.
I want to make those 6(3x2) text inputs responds individually and at
least need 2 pairs of xx and yy to pass validation.
This sounds weird, you should never trust and always validate ALL data coming from user.

Related

Yii2 client validation does not work

I have clean yii2-advanced template installed. I created a table in DB with id and test fields. In my Model I wrote rule:
public function rules()
{
return [
[['test'], 'required'],
];
}
Also I specified an unique id for my form.
But validation does not work. After typing smth to control and focus out I have an error in console: Uncaught TypeError: Cannot read property 'required' of undefined. What can be a reason of this?
EDIT:
Model:
<?php
namespace backend\models;
use Yii;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public function rules()
{
return [
[['name'], 'required'],
];
}
}
View:
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
?>
<div class="site-contact">
<div class="row">
<div class="col-lg-6">
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
<?= $form->field($model, 'name')->textInput() ?>
<?= Html::submitButton('Submit', ['class' => 'btn btn-success']) ?>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
Controller action:
use backend\models\ContactForm;
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post())) {
return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}
When you use Rules(), you must type the attribute (or array of attributes) first, and then the type of rule (that can be also a custom function by the way):
[['name'], 'required'] // setting the attribute "name" as required
you can read more about validation and rules here
if you have applied unique id for your form field, try removing it, Yii2 generates id by itself and applies validation message accordingly.

Yii2 - ActiveForm ajax submit

How can i use ActiveForm with these requirements?
Submit form with ajax.
Before submitting with ajax: Check if error exits.
After submitting: Display error of field under field's input if the server responses unsuccess saving result.
This is your form in view. I prefer use different actions for validation and saving. You can join them into single method.
<?php $form = \yii\widgets\ActiveForm::begin([
'id' => 'my-form-id',
'action' => 'save-url',
'enableAjaxValidation' => true,
'validationUrl' => 'validation-rul',
]); ?>
<?= $form->field($model, 'email')->textInput(); ?>
<?= Html::submitButton('Submit'); ?>
<?php $form->end(); ?>
In validation action you should write. It validates your form and returns list of errrs to client. :
public function actionValidate()
{
$model = new MyModel();
$request = \Yii::$app->getRequest();
if ($request->isPost && $model->load($request->post())) {
\Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
}
And this is save action. In validate input data for security:
public function actionSave()
{
$model = new MyModel();
$request = \Yii::$app->getRequest();
if ($request->isPost && $model->load($request->post())) {
\Yii::$app->response->format = Response::FORMAT_JSON;
return ['success' => $model->save()];
}
return $this->renderAjax('registration', [
'model' => $model,
]);
}
This code will validate your form in actionValidate() and. For submitting your form via AJAX use beforeSubmit event. In your javascript file write:
$(document).on("beforeSubmit", "#my-form-id", function () {
// send data to actionSave by ajax request.
return false; // Cancel form submitting.
});
That's all.
Submit form with ajax.
Before submitting with ajax: Check if error exits. yii display error if any by default....... :)
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\widgets\Pjax;
/* #var $this yii\web\View */
/* #var $model backend\models\search\JobSearch */
/* #var $form yii\bootstrap\ActiveForm */
?>
<div class="job-search">
<?php $form = ActiveForm::begin([
'action' => ['index'],
//'method' => 'get',
'options' => ['id' => 'dynamic-form111']
]); ?>
<?php echo $form->field($searchModel, 'id') ?>
<?php echo $form->field($searchModel, 'user_id') ?>
<?php echo $form->field($searchModel, 'com_id') ?>
<?php echo $form->field($searchModel, 'job_no') ?>
<?php echo $form->field($searchModel, 'court_id') ?>
<?php // echo $form->field($model, 'case_no') ?>
<?php // echo $form->field($model, 'plainttiff') ?>
<?php // echo $form->field($model, 'defendant') ?>
<?php // echo $form->field($model, 'date_fill') ?>
<?php // echo $form->field($model, 'court_date') ?>
<?php // echo $form->field($model, 'status_id') ?>
<?php // echo $form->field($model, 'created_at') ?>
<?php // echo $form->field($model, 'updated_at') ?>
<div class="form-group">
<?php echo Html::submitButton('Search', ['class' => 'btn btn-primary','id'=>'submit_id']) ?>
<?php echo Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('body').on('beforeSubmit', 'form#dynamic-form111', function () {
var form = $(this);
// return false if form still have some validation errors
if (form.find('.has-error').length)
{
return false;
}
// submit form
$.ajax({
url : form.attr('action'),
type : 'get',
data : form.serialize(),
success: function (response)
{
var getupdatedata = $(response).find('#filter_id_test');
// $.pjax.reload('#note_update_id'); for pjax update
$('#yiiikap').html(getupdatedata);
//console.log(getupdatedata);
},
error : function ()
{
console.log('internal server error');
}
});
return false;
});
});
</script>

How to load database into helper and display in view with specific column

footer_helper
<?php
function get_gadget_footer() {
//the database functions can not be called from within the helper
//so we have to explicitly load the functions we need in to an object
//that I will call ci. then we use that to access the regular stuff.
$ci=& get_instance();
$ci->load->database();
//select the required fields from the database
//$ci->db->select('name, type, setting');
//tell the db class the criteria
$ci->db->where('display', 'Footer');
//supply the table name and get the data
$query = $ci->db->get('gadgets');
foreach($query->result() as $row):
$type['name'] = $row->name;
$type['type'] = $row->type;
var_dump($type);
endforeach;
return $type;
}
hi this is my helper page. var_dump($type) is returning me required result in form of array as:
var_dump($type)
array (size=2)
'name' => string 'Quick Links' (length=11)
'type' => string '<a href='www.facebook.com'>Facebook</a><br>
<a href='#'>Twitter</a><br>
<a href='#'>Salyani</a><br>
<a href='#'>B&W</a><br>' (length=123)
array (size=2)
'name' => string 'Social Network' (length=14)
'type' => string '<a href='#'>Facebook</a><br>
<a href='#'>Facebook</a><br>
<a href='#'>Facebook</a><br>
<a href='#'>Facebook</a><br>' (length=115)
Now in my view page. I want display specific record in div. Like record of name
record of type .
Since now i had done following:
view
<?php
$this->load->helper('footer_helper');
$name = get_gadget_footer();
?>
<div id="footer">
<div id="footer_gadget_collection">
<?php
foreach ($name as $dat){
?>
<?php
?>
<div id="footer_subgadget">
<div id='title'><?php echo $dat['name']; ?></div>
<div id='description'><?php $dat['type']; ?> </div>
</div>
<?php
}
?>
But, its giving me error. Please help me.
In your helper you are restting the name/type of the array, not building it.
It should be something like;
<?php
//supply the table name and get the data
$query = $ci->db->get('gadgets');
$type = array();
foreach ($query->result() as $row) {
$type[] = array('name' => $row->name, 'type' => $row->type);
}
return $type;

Form is not getting submitted when render partial in Yii

I am partially rendering a form in a view in which user can add subaccounts(profiles). The view in which the form is called is another form where all subaccounts are listed as radiolist.
Below is my view.
<div class="inputs">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'selectUser-form',
'enableAjaxValidation' => false,
)); ?>
<?php echo CHtml::activeRadioButtonList($model,'id', $model->getSubAccounts(),array('prompt'=>'Please Select'));?>
<?php echo CHtml::submitButton($model->isNewRecord ? 'Book Now' : 'Save'); ?>
<?php echo CHtml::Button('Cancel',array('submit'=>array('cancel','id'=>$model->a_id)));?>
<?php $this->endWidget(); ?>
<div id="data"></div>
<?php echo CHtml::ajaxButton ("Add Users",
CController::createUrl('/user/user/addSubAccount'),
array('update' => '#data'));
?>
Below is my addSubAccount action.
public function actionAddSubAccount()
{
$profile=new YumProfile;
if (isset($_POST['YumProfile']))
{
$profile->attributes = $_POST['YumProfile'];
$profile->user_id=Yii::app()->user->id;
if($profile->save())
$this->redirect(array('/home/create'));}
if(!Yii::app()->request->isAjaxRequest){
$this->render('subaccount_form', array('profile'=>$profile));}
else{
$this->renderPartial('subaccount_form', array('profile'=>$profile));
}
}
Below is subaccount_form.
<?php $this->title = Yum::t('SubAccounts');?>
<div class="wide form">
<?php $activeform = $this->beginWidget('CActiveForm', array(
'id'=>'subaccount-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions' => array(
'validateOnChange' => true,
'validateOnSubmit' => true,
),
));
?>
<div class="row"> <?php
echo $activeform->labelEx($profile,'Firstname');
echo $activeform->textField($profile,'firstname');
echo $activeform->error($profile,'firstname');
?> </div>
<div class="row"> <?php
echo $activeform->labelEx($profile,'Lastname');
echo $activeform->textField($profile,'lastname');
echo $activeform->error($profile,'lastname');
?> </div>
<div class="row"> <?php
echo $activeform->labelEx($profile,'Age');
echo $activeform->textField($profile,'age');
echo $activeform->error($profile,'age');
?> </div>
<div class="row submit">
<?php echo CHtml::submitButton(Yum::t('Add')); ?>
</div>
<?php $this->endWidget(); ?>
My form is rendering. But it's not getting submitted.What am i doing wrong?
After submitting,I need the view to be refreshed and to display the newly added user as an option in the radio list.
EDIT:
I tried like adding the following in the CActiveForm Widget array:
'action' => array( '/user/user/addsubAccount' ),
But still no result.Instead it is saving my data two times when i go through my direct way,meaning render method. :-(
It is because
'enableAjaxValidation'=>true,
Ajax validation is set to true in your form. Set its value to false
'enableAjaxValidation'=>FALSE, and then your form will submit :)
and if you want it to be true only then you should uncomment
$this->performAjaxValidation($model);
in your controller's action
Update 1
if(!Yii::app()->request->isAjaxRequest){
$this->render('subaccount_form', array('profile'=>$profile));}
else{
//change this line
$this->renderPartial('subaccount_form', array('profile'=>$profile),FALSE,TRUE);
}
This link might help you
on renderPartial the action attribute of the form is set to the current page instead of being set to the actual update or create url
My Solution
$form=$this->beginWidget('CActiveForm', array(
'id'=>'country-form',
'action' => Yii::app()->createUrl(is_null(Yii::app()->request->getParam('id'))?'/country/create':'/country/update/'.Yii::app()->request->getParam('id')),

Codeigniter: Not inserting data in table

Update: It is solved ..
For some reason, the data is not getting inserted into the table. It is however being posted from the form as I could see with var dump, but further than that, won't do. So, here are the 3 modules. It is a very simple test scheme: Just a form with two fields, you press Submit and should be inserted. (I can do all that in ordinary PHP with one page, but, the MVC frameworks are a nightmare in this regard, you write about 30 times more code than you would need in procedural.
<?php
class Inserting_controller extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('Inserting_model');
}
public function index ()
{
$this->load->view('inserting_view');
}
// Controller
public function insert()
{
$data = array(
'username' => $this->input->post('username', TRUE),
'password' => sha1($this->input->post('password', TRUE)
));
var_dump($data); // We do get the data posted
exit;
$this->Inserting_model->insertdata($data); // this should forward them to the Model
}
}
?>
==============
MODEL
<?php
class Inserting_model extends CI_Model{
function __construct()
{
// Call the Model constructor
parent::__construct();
$this->load->database();
}
public function insertdata($data)
{
$this->db->insert('users', $data);
}
}
?>
========
VIEW
<div id="inserting_form">
<?php echo form_open('index.php/Inserting_controller/insert/'); ?>
<ul>
<li>
<label>Username</label>
<div><?php echo form_input(array('id' => 'username', 'name' => 'username')); ?></div>
</li>
<li>
<label>Password</label>
<div><?php echo form_password(array('id' => 'password', 'name' => 'password')); ?></div>
</li>
<li><?php echo validation_errors();?></li>
<li><?php echo form_submit(array('name' =>'submit'),'Insert');?> </li>
</ul>
<?php echo form_close(); ?>
</div>
Blushing :/
On writing the debugging code, I forgot to delete the exit; thus, the program exited right after that ....

Resources