i want add a new action in my controller in yii2 project :
i have error for add any new action !
new action have this error : Not Found (#404)
<?php
namespace soft\controllers;
use Yii;
use soft\models\Reserve;
use soft\models\ReserveSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use \yii\web\Response;
use yii\helpers\Html;
/**
* ReserveController implements the CRUD actions for Reserve model.
*/
class ReserveController extends Controller {
/**
* #inheritdoc
*/
public function behaviors() {
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
'bulk-delete' => ['post'],
],
],
];
}
/**
* Lists all Reserve models.
* #return mixed
*/
public function actionIndex() {
$searchModel = new ReserveSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
public function actionJson() {
die;
}
/**
* Displays a single Reserve model.
* #param string $id
* #return mixed
*/
public function actionView($id) {
$request = Yii::$app->request;
if ($request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
return [
'title' => "Reserve #" . $id,
'content' => $this->renderAjax('view', [
'model' => $this->findModel($id),
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::a('Edit', ['update', 'id' => $id], ['class' => 'btn btn-primary', 'role' => 'modal-remote'])
];
} else {
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
}
/**
* Creates a new Reserve model.
* For ajax request will return json object
* and for non-ajax request if creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate() {
$request = Yii::$app->request;
$model = new Reserve();
if ($request->isAjax) {
/*
* Process for ajax request
*/
Yii::$app->response->format = Response::FORMAT_JSON;
if ($request->isGet) {
return [
'title' => "Create new Reserve",
'content' => $this->renderAjax('create', [
'model' => $model,
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])
];
} else if ($model->load($request->post()) && $model->save()) {
return [
'forceReload' => '#crud-datatable-pjax',
'title' => "Create new Reserve",
'content' => '<span class="text-success">Create Reserve success</span>',
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::a('Create More', ['create'], ['class' => 'btn btn-primary', 'role' => 'modal-remote'])
];
} else {
return [
'title' => "Create new Reserve",
'content' => $this->renderAjax('create', [
'model' => $model,
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])
];
}
} else {
/*
* Process for non-ajax request
*/
if ($model->load($request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
}
/**
* Updates an existing Reserve model.
* For ajax request will return json object
* and for non-ajax request if update is successful, the browser will be redirected to the 'view' page.
* #param string $id
* #return mixed
*/
public function actionUpdate($id) {
$request = Yii::$app->request;
$model = $this->findModel($id);
if ($request->isAjax) {
/*
* Process for ajax request
*/
Yii::$app->response->format = Response::FORMAT_JSON;
if ($request->isGet) {
return [
'title' => "Update Reserve #" . $id,
'content' => $this->renderAjax('update', [
'model' => $model,
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])
];
} else if ($model->load($request->post()) && $model->save()) {
return [
'forceReload' => '#crud-datatable-pjax',
'title' => "Reserve #" . $id,
'content' => $this->renderAjax('view', [
'model' => $model,
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::a('Edit', ['update', 'id' => $id], ['class' => 'btn btn-primary', 'role' => 'modal-remote'])
];
} else {
return [
'title' => "Update Reserve #" . $id,
'content' => $this->renderAjax('update', [
'model' => $model,
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])
];
}
} else {
/*
* Process for non-ajax request
*/
if ($model->load($request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
}
/**
* Delete an existing Reserve model.
* For ajax request will return json object
* and for non-ajax request if deletion is successful, the browser will be redirected to the 'index' page.
* #param string $id
* #return mixed
*/
public function actionDelete($id) {
$request = Yii::$app->request;
$this->findModel($id)->delete();
if ($request->isAjax) {
/*
* Process for ajax request
*/
Yii::$app->response->format = Response::FORMAT_JSON;
return ['forceClose' => true, 'forceReload' => '#crud-datatable-pjax'];
} else {
/*
* Process for non-ajax request
*/
return $this->redirect(['index']);
}
}
/**
* Delete multiple existing Reserve model.
* For ajax request will return json object
* and for non-ajax request if deletion is successful, the browser will be redirected to the 'index' page.
* #param string $id
* #return mixed
*/
public function actionBulkDelete() {
$request = Yii::$app->request;
$pks = explode(',', $request->post('pks')); // Array or selected records primary keys
foreach ($pks as $pk) {
$model = $this->findModel($pk);
$model->delete();
}
if ($request->isAjax) {
/*
* Process for ajax request
*/
Yii::$app->response->format = Response::FORMAT_JSON;
return ['forceClose' => true, 'forceReload' => '#crud-datatable-pjax'];
} else {
/*
* Process for non-ajax request
*/
return $this->redirect(['index']);
}
}
/**
* Finds the Reserve model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param string $id
* #return Reserve the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id) {
if (($model = Reserve::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
why action json is
not found but action create is Available ؟!
this is working :admin2.localhost/en/reserve/create
but this is not working : admin2.localhost/en/reserve/json
this is my main.php :
<?php
$params = array_merge(
require (__DIR__ . '/../../common/config/params.php'),
require (__DIR__ . '/params.php')
);
$config = [
'id' => 'app-soft',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'soft\controllers',
'bootstrap' => ['log'],
'modules' => [],
'components' => [
'user' => [
'identityClass' => 'main\models\custom\SoftUser',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'aaaaaaaaaaaaaaa',
],
'runtime'=>[
'class'=>'soft\config\Runtime',
],
'urlManager' => [
'rules' => [
'package' => 'site/package',
],
],
],
'params' => $params,
];
return $config;
Thank you for your guidance.
my params.php have problem and fixed :
'urlRules' => [
'' => 'site/index',
'login/' => 'site/login',
'signup/' => 'site/signup',
'<controller:[\w-]+>/<action:\w+>' => '<controller>/<action>',
'<controller:[\w-]+>/<id:\d+>' => '<controller>/view',
'<controller:[\w-]+>/create' => '<controller>/create',
'<controller:[\w-]+>/update/<id:\d+>' => '<controller>/update',
'<controller:[\w-]+>/delete/<id:\d+>' => '<controller>/delete',
'<controller:[\w-]+>/bulk-delete' => '<controller>/bulk-delete',
]
Related
I have this error message when I submit form.
Notice: Undefined index: title in
C:\xampp\htdocs\ameyaw\module\BusinessGhana\src\Service\AutosManager.php
on line 38
Notice: Undefined index: description in
C:\xampp\htdocs\ameyaw\module\BusinessGhana\src\Service\AutosManager.php
on line 39
Notice: Undefined index: featured in
C:\xampp\htdocs\ameyaw\module\BusinessGhana\src\Service\AutosManager.php
on line 58
Message:
An exception occurred while executing 'INSERT INTO auto (title,
description, featured, date_created) VALUES (?, ?, ?, ?)' with params
[null, null, null, "2017-06-15 05:04:44"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'title'
cannot be null
this is my form and fieldset
use Zend\Form\Fieldset;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use BusinessGhana\Entity\Autos;
class AddFieldset extends Fieldset
{
protected $objectManager;
public function init()
{
$this->add([
'type' => 'text',
'name' => 'title',
'attributes' => [
'id' => 'autoTitle'
],
'options' => [
'label' => 'Title',
'display_empty_item' => true,
'empty_item_label' => 'Maximum of 60 characters',
],
]);
$this->add([
'type' => 'textarea',
'name' => 'description',
'attributes' => [
'id' => 'autoDescription'
],
'options' => [
'label' => 'Description',
'display_empty_item' => true,
'empty_item_label' => 'description',
],
]);
$this->add([
'type' => 'radio',
'name' => 'featured',
'attributes' => [
'id' => 'autoFeatured'
],
'options' => array(
'label' => 'Featured',
'value_options' => array(
array('value' => '0',
'label' => 'No',
'selected' => true,
'label_attributes' => array(
'class' => 'col-sm-2 btn btn-default',
),
),
array(
'value' => '1',
'label' => 'Yes',
'label_attributes' => array(
'class' => 'col-sm-2 btn btn-danger',
),
),
),
'column-size' => 'sm-12',
'label_attributes' => array(
'class' => 'col-sm-2',
),
),
]);
}
}
use Zend\Form\Form;
//use Zend\InputFilter\InputFilter;
class AddForm extends Form
{
public function init()
{
$this->add([
'name' => 'dependentForm',
'type' => AddFieldset::class,
]);
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Submit',
],
]);
}
}
This is my controller action
public function addAction()
{
// Create the form.
$form = new PostForm();
if ($this->getRequest()->isPost()) {
// Get POST data.
$data = $this->params()->fromPost();
// Fill form with data.
$form->setData($data);
if ($form->isValid()) {
// Get validated form data.
$data = $form->getData();
$this->AutosManager->addNewAutos($data);
return $this->redirect()->toRoute('retrieve');
}
}
return new ViewModel([
'form' => $form
]);
}
I know hydration can solve this problem but I don't know how to use it yet.
thanks for any help.
this is my autosManager
class AutosManager
{
/**
* Entity manager.
* #var Doctrine\ORM\EntityManager;
*/
private $entityManager;
/**
* Constructor.
*/
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
public function addNewAutos($data)
{
$autos = new Autos();
$autos->setTitle($data['title']);
$autos->setDescription($data['description']);
$autos->setFeatured($data['featured']);
$currentDate = date('Y-m-d H:i:s');
$autos->setDateCreated($currentDate);
$this->entityManager->persist($autos);
$this->entityManager->flush();
}
}
i can retrieve data from database.
This is where i render my forms:
$form = $this->form;
$fieldset = $form->get('dependentForm');
$title = $fieldset->get('title');
$title->setAttribute('class', 'form-control');
$title->setAttribute('placeholder', 'Maximum of 60 characters');
$title->setAttribute('id', 'autoTitle');
$description = $fieldset->get('description');
$description->setAttribute('class', 'form-control');
$description->setAttribute('placeholder', 'Description here...');
$description->setAttribute('id', 'autoDescription');
$featured = $fieldset->get('featured');
$featured->setAttribute('id', 'autoRadio');
$form->get('submit')->setAttributes(['class'=>'btn btn-primary']);
$form->prepare();
echo $this->form()->openTag($form);
?>
<fieldset>
<div class="form-group">
<?= $this->formLabel($title) ?>
<?= $this->formElement($title) ?>
<?= $this->formElementErrors()->render($title,['class'=>'help-block'])?>
</div>
<div class="form-group">
<?= $this->formLabel($description) ?>
<?= $this->formElement($description) ?>
<?=$this->formElementErrors()->render($description,
['class'=>'help-block'])?>
</div>
<div class="form-group">
<?= $this->formLabel($featured) ?>
<?= $this->formElement($featured) ?>
<?= $this->formElementErrors()->render($featured,
['class' =>'help-block']) ?>
</div>
</div></div><div class="row">
<div class="col-md-4">
</fieldset>
<?= $this->formElement($form->get('submit')); ?>
In your function addNewAutos($data) : your $data variable don't have title, description and featured fields. So php consider these as null, and your $this->entityManager->flush() will try to write null values in database, but you have a constraint that at least title must not be null.
So check your $data array contains the title, description and featured fields before to initiate your Auto object...
My problem is validating the records if already exists in database. So i created a Officials Form using Gii Generator in yii2. It contains name_id,position,fname,mname,lname. If the admin wants to create a new data, and that data is already exists it will show a pop-up message "This data already exists".
How can i achieve that? Any ideas?
This is my model:
class Name extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'name';
}
public function rules()
{
return [
[['position', 'fname', 'lname'], 'required'],
[['position', 'fname', 'mname', 'lname'], 'string', 'max' => 50],
];
}
public function attributeLabels()
{
return [
'name_id' => 'Name ID',
'position' => 'Position',
'fname' => 'First Name',
'mname' => 'Middle Name',
'lname' => 'Last Name',
];
}
}
This is my controller:
public function actionCreate()
{
$model = new Name();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['report/create', 'id' => $model->name_id]);
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
And this is my _form:
<div class="name-form">
<?php yii\widgets\Pjax::begin(['id' => 'sign-up']) ?>
<?php $form = ActiveForm::begin(['id' => 'form-signup', 'options' => ['data-pjax' => true]]); ?>
<?= $form->field($model, 'position')->textInput(['maxlength' => true,'style'=>'width:500px','placeholder' => 'Enter a Position....']) ?>
<?= $form->field($model, 'fname')->textInput(['maxlength' => true,'style'=>'width:500px','placeholder' => 'Enter a First Name....']) ?>
<?= $form->field($model, 'mname')->textInput(['maxlength' => true,'style'=>'width:500px','placeholder' => 'Enter a Middle Name....']) ?>
<?= $form->field($model, 'lname')->textInput(['maxlength' => true,'style'=>'width:500px','placeholder' => 'Enter a Last Name....' ]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-success','style' => 'padding:10px 60px; width:100%;']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php yii\widgets\Pjax::end() ?>
So i assume you want a unique validator, you can try this in your model :
public function rules()
{
return [
[['position', 'fname', 'lname'], 'required'],
[['position', 'fname', 'mname', 'lname'], 'string', 'max' => 50],
[['fname','lname'], 'unique', 'targetAttribute' => ['fname', 'lname'], 'message' => 'This data already exists']
];
}
The above rules will make the combination of fname and lname attributes to be unique, you can modify what attribute or combination of attributes you want to be unique by adding or removing the field name / attributes to the validation rules.
You can create your custom validation , Take any attribute name and define rule :
public function rules()
{
return [
[['position', 'fname', 'lname'], 'required'],
[['position', 'fname', 'mname', 'lname'], 'string', 'max' => 50],
[['position', 'fname', 'lname'], 'checkUniq'], //add this line
];
}
-> custom function in model :
public function checkUniq($attribute, $params)
{
$user = self::find()->where(['fname'=>$this->fname,'lname'=>$this->lname,'position'=>$this->position])->one();
if (isset($user) && $user!=null)
$this->addError($attribute, 'User already added.');
}
I am building a drupal form with multiple ajax enabled form elements.
I have one select list that does an ajax callback after change. The problem is that it adds a new select list to the page, which is also ajax enabled. This does not seem to work, which seems logical to me because the ajax is actually bundled an added to the page so it is lost in the replacecommand.
Is there anyone experienced with this, and does anyone have a solution ?
This is my code
/**
* {#inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state)
{
$form['city'] = [
'#type' => 'select',
'#title' => $this->t('Station'),
'#description' => $this->t('City'),
'#options' => array(
'Aalst' => $this->t('Aalst'),
'Brussel' => $this->t('Brussel'),
'Hasselt' => $this->t('Hasselt'),
'Leuven' => $this->t('Leuven'),
),
'#ajax' => [
'callback' => array($this, 'extendFormAjax'),
'event' => 'change',
'progress' => array(
'type' => 'throbber',
'message' => t('Choose City'),
),
],
'#suffix' => '<div id="extended-form"></div>',
];
$form['submit'] = [
'#type' => 'submit',
'#value' => t('Submit'),
];
return $form;
}
/**
* Ajax callback to validate the email field.
*/
public function extendFormAjax(array &$form, FormStateInterface $form_state)
{
$parking = [
'#type' => 'select',
'#title' => $this->t('Parking'),
'#description' => $this->t('Parking'),
'#options' => [
'P1' => $this->t('P1'),
'P2' => $this->t('P2'),
],
'#ajax' => [
'callback' => array($this, 'extendFormAjax'),
'event' => 'change',
'progress' => array(
'type' => 'throbber',
'message' => t('Choose parking'),
),
],
];
$response = new AjaxResponse();
$response->addCommand(new InsertCommand('#extended-form', $parking));
return $response;
}
I had a similar issue and i resolved it by adding the element in buildForm and adding a wrapper for it and sending the form element via HtmlCommand
/**
* {#inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state)
{
$form['city'] = [
'#type' => 'select',
'#title' => $this->t('Station'),
'#description' => $this->t('City'),
'#options' => array(
'Aalst' => $this->t('Aalst'),
'Brussel' => $this->t('Brussel'),
'Hasselt' => $this->t('Hasselt'),
'Leuven' => $this->t('Leuven'),
),
'#ajax' => [
'callback' => array($this, 'extendFormAjax'),
'event' => 'change',
'progress' => array(
'type' => 'throbber',
'message' => t('Choose City'),
),
],
];
$form['parking'] = [
'#prefix' => '<div id="extended-form">',
'#suffix' => '</div>',
'#type' => 'select',
'#title' => $this->t('Parking'),
'#description' => $this->t('Parking'),
'#options' => [
'P1' => $this->t('P1'),
'P2' => $this->t('P2'),
],
'#ajax' => [
'callback' => array($this, 'extendFormAjax'),
'event' => 'change',
'progress' => array(
'type' => 'throbber',
'message' => t('Choose parking'),
),
],
];
$form['submit'] = [
'#type' => 'submit',
'#value' => t('Submit'),
];
return $form;
}
/**
* Ajax callback to validate the email field.
*/
public function extendFormAjax(array &$form, FormStateInterface $form_state)
{
$parking = [
'#type' => 'select',
'#title' => $this->t('Parking'),
'#description' => $this->t('Parking'),
'#options' => [
'P1' => $this->t('P1'),
'P2' => $this->t('P2'),
],
'#ajax' => [
'callback' => array($this, 'extendFormAjax'),
'event' => 'change',
'progress' => array(
'type' => 'throbber',
'message' => t('Choose parking'),
),
],
];
$response = new AjaxResponse();
$response->addCommand(new HtmlCommand('#extended-form', $parking));
return $response;
}
Try it like this. I have not tested the code.
Try call somewhere in JS Drupal.attachBehaviors();
I experienced this issue and resolved it by this way :
For each element which were populated by Ajax, I add the property "#validated" => true and in the callback, the returned field must have the same attributes (id, name) that the original field :
$form['example_field'] = array(
'#type' => 'select',
'#required' => FALSE,
'#options' => getDynamicOptions(),
'#prefix' => '<div id="etablissement-type-wrapper">',
'#suffix' => '</div>',
'#attributes' => [
'data-drupal-selector' => "edit-example",
'id' => "edit-example",
'name' => "example",
],
'#validated' => TRUE,
);
You need add ajax elements in buildForm methods and rebuild form. Something like this:
/**
* {#inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $no_js_use = FALSE) {
// We want to deal with hierarchical form values.
$form['#tree'] = TRUE;
$form['step'] = [
'#type' => 'value',
'#value' => !empty($form_state->getValue('step')) ? $form_state->getValue('step') : 1,
];
switch ($form['step']['#value']) {
case 1:
$limit_validation_errors = [['step']];
$form['step1'] = [
'#type' => 'fieldset',
'#title' => $this->t('Step 1: Personal details'),
];
$form['step1']['name'] = [
'#type' => 'textfield',
'#title' => $this->t('Your name'),
'#default_value' => $form_state->hasValue(['step1', 'name']) ? $form_state->getValue(['step1', 'name']) : '',
'#required' => TRUE,
];
break;
case 2:
$limit_validation_errors = [['step'], ['step1']];
$form['step1'] = [
'#type' => 'value',
'#value' => $form_state->getValue('step1'),
];
$form['step2'] = [
'#type' => 'fieldset',
'#title' => t('Step 2: Street address info'),
];
$form['step2']['address'] = [
'#type' => 'textfield',
'#title' => $this->t('Your street address'),
'#default_value' => $form_state->hasValue(['step2', 'address']) ? $form_state->getValue(['step2', 'address']) : '',
'#required' => TRUE,
];
break;
case 3:
$limit_validation_errors = [['step'], ['step1'], ['step2']];
$form['step1'] = [
'#type' => 'value',
'#value' => $form_state->getValue('step1'),
];
$form['step2'] = [
'#type' => 'value',
'#value' => $form_state->getValue('step2'),
];
$form['step3'] = [
'#type' => 'fieldset',
'#title' => $this->t('Step 3: City info'),
];
$form['step3']['city'] = [
'#type' => 'textfield',
'#title' => $this->t('Your city'),
'#default_value' => $form_state->hasValue(['step3', 'city']) ? $form_state->getValue(['step3', 'city']) : '',
'#required' => TRUE,
];
break;
}
$form['actions'] = ['#type' => 'actions'];
if ($form['step']['#value'] > 1) {
$form['actions']['prev'] = [
'#type' => 'submit',
'#value' => $this->t('Previous step'),
'#limit_validation_errors' => $limit_validation_errors,
'#submit' => ['::prevSubmit'],
'#ajax' => [
'wrapper' => 'ajax-example-wizard-wrapper',
'callback' => '::prompt',
],
];
}
if ($form['step']['#value'] != 3) {
$form['actions']['next'] = [
'#type' => 'submit',
'#value' => $this->t('Next step'),
'#submit' => ['::nextSubmit'],
'#ajax' => [
'wrapper' => 'ajax-example-wizard-wrapper',
'callback' => '::prompt',
],
];
}
if ($form['step']['#value'] == 3) {
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t("Submit your information"),
];
}
$form['#prefix'] = '<div id="ajax-example-wizard-wrapper">';
$form['#suffix'] = '</div>';
return $form;
}
public function prompt(array $form, FormStateInterface $form_state) {
return $form;
}
public function nextSubmit(array $form, FormStateInterface $form_state) {
$form_state->setValue('step', $form_state->getValue('step') + 1);
$form_state->setRebuild();
return $form;
}
public function prevSubmit(array $form, FormStateInterface $form_state) {
$form_state->setValue('step', $form_state->getValue('step') - 1);
$form_state->setRebuild();
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$messenger = \Drupal::messenger();
$messenger->addMessage($this->t('Your information has been submitted:'));
}
How can I do: I have 2 multi-select fields Select2, the first field for Branches, second for Workers.
When I choose branches, in second field I need to show Workers, who work in this branches.
View file
<label><?= $model->getAttributeLabel('branch') ?></label>
<?php echo Select2::widget([
'name' => 'branch',
'id' => 'branches',
'theme' =>Select2::THEME_BOOTSTRAP,
'value' => '',
'data' => $branchList,
'options' => [
'placeholder' => Yii::t('app', 'Choose branch'),
'multiple' => true,
],
'pluginOptions' => [
'tags' => true,
'allowClear' => true,
],]);?>
<label><?= $model->getAttributeLabel('Workers') ?></label>
<?php echo Select2::widget([
'name' => 'worker',
'id' => 'workers',
'theme' =>Select2::THEME_BOOTSTRAP,
'value' => '',
'data' => [],
'options' => [
'placeholder' => Yii::t('app', 'Choose workers'),
'multiple' => true,
],
'pluginOptions' => [
'tags' => true,
'allowClear' => true,
],]);
?>
JS
$("#branches").change(function(){
change();
});
function change() {
var selectValue = $("#branches").val();
$("#workers").empty();
$.post( "'.Yii::$app->urlManager->createUrl('constructor/lists?id=').'"+selectValue,
function(data){
$("#workers").html(data);
}
);
};
ConstructorController
public function actionLists($id)
{
if ($id != null) {
$ids = explode(",", $id);
foreach ($ids as $id_branch) {
$workers = Report::getWorkers($id_branch);
if (count($workers) > 0) {
foreach ($workers as $worker) {
echo "<option value='" . $worker . "'>" . $worker . "</option>";
}
} else {
echo "'<option>-</option>'";
}
}
}
}
I am working in CakePHP 3.2. I have users table and register action in UsersController.
I'm trying to add a new record but default validation is not working.
This is my 'UsersTable.php`
<?php
namespace App\Model\Table;
use App\Model\Entity\User;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Auth\DefaultPasswordHasher;
use Cake\Validation\Validator;
class UsersTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('UserAddresses', [
'foreignKey' => 'user_id'
]);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->uuid('id')
->allowEmpty('id', 'create');
$validator
->notEmpty('name');
$validator
->email('email')
->notEmpty('email');
$validator
->add('mobile', [
'minLength' => [
'rule' => ['minLength', 10],
'message' => 'Mobile number must be of 10 characters long',
],
'maxLength' => [
'rule' => ['maxLength', 10],
'message' => 'Mobile number must be of 10 characters long',
]
])
->numeric('mobile')
->notEmpty('mobile');
$validator
->notEmpty('password');
$validator
->add('newPassword', [
'compare' => [
'rule' => ['compareWith', 'confirmNewPassword'],
]
])
->notEmpty('newPassword');
$validator
->add('confirmNewPassword', [
'compare' => [
'rule' => ['compareWith', 'newPassword'],
'message' => 'Password does not match'
]
])
->notEmpty('confirmNewPassword');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* #param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* #return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['email']));
return $rules;
}
public function validationPassword(Validator $validator)
{
$validator
->add('old_password', 'custom', [
'rule' => function($value, $context){
$user = $this->get($context['data']['id']);
if ($user) {
if((new DefaultPasswordHasher)->check($value, $user->password)) {
return true;
}
}
return false;
},
'message' => 'The old password does not match the current password!',
])
->notEmpty('old_password');
$validator
->add('password1', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'The Password have to be at least 6 characters!',
]
])
->add('password1', [
'match' => [
'rule' => ['compareWith', 'password2'],
'message' => 'The passwords does not match!',
]
])
->notEmpty('password1');
$validator
->add('password2', [
'length' => [
'rule' => ['minLength', 6],
'message' => 'The Password have to be at least 6 characters!',
]
])
->add('password2', [
'match' => [
'rule' => ['compareWith', 'password1'],
'message' => 'The passwords does not match!',
]
])
->notEmpty('password2');
return $validator;
}
}
register() method
public function register()
{
// if already logged in, redirect to referer action to prevent new registration
if (!empty($this->Auth->user('id'))) {
return $this->redirect($this->referer());
}
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
// check user exists or not
$userExists = $this->Users->find('all', [
'conditions' => [
'OR' => [
'email' => $this->request->data['email'],
'mobile' => $this->request->data['mobile'],
]
]
]);
if ($userExists->count() > 0) {
$userExists = $userExists->first();
$this->Flash->success(__('It seems you are already registered. Please login using your email or mobile and passowrd'));
return $this->redirect(['controller' => 'Users', 'action' => 'login']);
}
$hash = hash('sha256',date('YmdHis').time());
$user->tmp_hash = $hash;
$user->verified = 0;
$user = $this->Users->patchEntity($user, $this->request->data);
if ($u = $this->Users->save($user)) {
// send verification email
if ($this->sendEmail($user->id, $user->email, $hash, 'register')) {
$this->Flash->registerSuccess(__('Thank you. You need to verify email. Not received verification email ?'), [
'params' => [
'userId' => $user->id
],
['escape' => false]
]);
return $this->redirect(['action' => 'login']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
return $this->redirect(['action' => 'login']);
}
}
}
$this->set(compact('user'));
$this->set('_serialize', ['user']);
}
register.ctp view
<?= $this->Form->create(null, ['url' => ['controller' => 'Users', 'action' => 'register'], 'class' => 'regForm']) ?>
<div class="form-group">
<label>Name <?= $this->Form->error('name') ?></label>
<?= $this->Form->input('name', ['class' => 'form-control', 'label' => false, 'placeholder' => 'Enter Your Name', 'title' => 'Please Enter your full name']) ?>
</div>
<div class="form-group">
<label>Email address</label>
<?= $this->Form->input('email', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Enter Email', 'title' => 'Please enter valid email']) ?>
</div>
<div class="form-group">
<label>Mobile</label>
<?= $this->Form->input('mobile', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Mobile Number', 'title' => 'Please enter valid mobile no to receive notifications']) ?>
</div>
<div class="form-group">
<label>Password</label>
<?= $this->Form->input('password', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Password', 'title' => 'Please enter password']) ?>
</div>
<?= $this->Form->button('<i class="fa fa-user"></i> Create and account', ['type' => 'submit', 'class' => 'btn btn-primary', 'escape' => false]) ?>
<?= $this->Form->end() ?>
</div>
When I try to submit form without filling anything, it simply refreshes the form without showing validation error.
In your register.ctp file
$this->Form->create(null, ['url' => ['controller' => 'Users', 'action' => 'register'], 'class' => 'regForm']);
Replace it with
$this->Form->create($user, ['url' => ['controller' => 'Users', 'action' => 'register'], 'class' => 'regForm']);
As per concept of CakePHP v3 you have to pass entity in Form Creation method so it will display form validation error in view.