How to ajaxify Zend_Form validation - ajax

I have a Zend_Form subclass. Some elements are set to belong to arrays.
class My_Form extends Zend_Form {
public function __construct() {
$elem = $this->createElement('text','PROJECT_NAME',
array(
'required' => true
));
$elem->setBelongsTo('project');
$this->addElement($elem);
$elem = $this->createElement(
'text','PLANNED_END_DATE',
array(
'required' => true
)
);
$elem->setBelongsTo('project');
$elem->addValidator(new Zend_Validate_Date(array('format'=>'yyyy-MM-dd')));
$this->addElement($elem);
//and so on
}
}
I have a universal validation controller which does create the form and checks for errors, and returns them in json format:
class ValidateController extends Zend_Controller_Action
{
public function formAction()
{
$params = $this->_getAllParams();
if (isset($params['_frm'])) {
$formName = detect_the_form_class($params['_frm']);
if (class_exists($formName)) {
$form = new $formName();
if ($form instanceof Zend_Form) {
$result = $form->isValidPartial($params);
$messages = $form->getMessages();
$this->getResponse()
->setHeader('Content-Type', 'application/json')
->setBody(json_encode(array(
'result' => $result,
'messages' => $messages
)));
} else {
$this->getResponse()->setHttpResponseCode(500);
}
}
}
}
}
This controller works great for non-array forms, but the form I now need to validate hase arrays, eg elements with name 'project[PROJECT_NAME]'.
But the $form->getMessages() returns messages indexed with base name of elements, without array prefix.
The actual result is:
{ result: false,
messages: {
PROJECT_NAME: {isEmpty: "Value is required"},
PROJECT_END_DATE: {isEmpty: "Value is required"}
}
}
The result I need is:
{ result: false,
messages: {
"project[PROJECT_NAME]": {isEmpty: "Value is required"},
"project[PROJECT_END_DATE]": {isEmpty: "Value is required"}
}
}
or something similar, so I can find the element the validation message is for.
Any ideas?

For subforms use Zend_Form_Subform class:
class My_Form extends Zend_Form
{
public function init()
{
$subForm = new Zend_Form_SubForm();
$elem = $this->createElement('text', 'PROJECT_NAME', array(
'required' => true
));
$subForm->addElement($elem);
$elem = $this->createElement('text', 'PLANNED_END_DATE', array(
'required' => true
));
$subForm->addElement($elem);
$this->addSubForm($subForm, 'project');
}
}
Response:
{
"project":{
"PROJECT_NAME":{"isEmpty":"Value is required and can't be empty"},
"PLANNED_END_DATE":{"isEmpty":"Value is required and can't be empty"}
}
}
For form config it is recommended to use init() method.
For json response you can use build-in action helper:
$this->_helper->json($form->getMessages());

Related

Create flash message in class request laravel

i have a problem in my project. How to create a flash session in class request / validation ? I haven't found a way.
This my Request class code
class UserRequest extends FormRequest {
public function authorize()
{
return TRUE;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
"user_fullname" => "required|alpha_spaces",
"user_email" => "required|email|unique,list_user,user_email",
"user_phone" => "nullable|numeric",
"access_id" => "required|alpha_num_spaces",
"user_password" => "required|min:6|regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9]).*$/|confirmed",
"warehouse_id" => "alpha_num_spaces|nullable",
];
if ($this->method() == "POST") {
$rules["province_id"] = "alpha_num_spaces|nullable";
$rules["district_id"] = "alpha_num_spaces|nullable";
$rules["subdistrict_id"] = "alpha_num_spaces|nullable";
$rules["kode_pos"] = "alpha_num_spaces|nullable";
$rules["user_address"] = "alpha_num_spaces|nullable";
}
return $rules;
}
public function messages()
{
return [
"user_password.regex" => "Password wajib terdiri dari huruf & angka!"
];
}
}
This my controller
public function process_user_add(UserRequest $user_request)
{
$user_request->validated();
$request = \request();
$input = (object) \request()->all();
$check = User::add_user_from_owner($input);
if ($check->success) {
return \redirect()->to("administrator/user/" . \encrypt_url($check->id))->with("message", "<script>sweet('success', 'Success!', '$check->message')</script>");
} else {
return \redirect()->back()->with("message", "<script>sweet(\"error\", \"Failed!\", \"$check->message\")</script>")->withInput($request->all());
}
}
How to i check if validation failed, i create a flash message? To my knowledge, class request is auto redirect goback url if validation error
You can use die Validator Facade. Validator::make() After then you can rescieve the fails with the fails() Method. Take a look in the code below:
$rules = array(
"user_fullname" => "required|alpha_spaces",
"user_email" => "required|email|unique,list_user,user_email",
"user_phone" => "nullable|numeric",
"access_id" => "required|alpha_num_spaces",
"user_password" => "required|min:6|regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9]).*$/|confirmed",
"warehouse_id" => "alpha_num_spaces|nullable",
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails())
{
return Redirect::to('/your_url')->withInput()->withErrors($validator);
}
This section from the documentation will point you to the right direction

Yii2 - dynamically switch rules set in model

I want to dynamically substitute rules in model according to switch value on form.
In view:
<?php
$form = ActiveForm::begin([
'enableAjaxValidation' => true,
'validationUrl' => Url::toRoute('anounce/validation')
]);
?>
In controller:
public function actionValidation()
{
$model = new Anounce();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->
request->post())) {
Yii::$app->response->format = 'json';
return ActiveForm::validate($model);
}
}
Excerpts from model:
class Anounce extends \yii\db\ActiveRecord
{
private $currentRuleSet; // Current validation set
// Here are arrays of rules with assignment
private $fullRuleSet; // = [...];
private $shortRuleSet; // = [...];
private $minRuleSet; // = [...];
public function init()
{
parent::init();
$this->currentRuleSet = $this->fullRuleSet;
}
public function rules()
{
return $this->currentRuleSet;
}
public function beforeValidate()
{
if ($this->idanounce_type === self::FULL) {
$this->currentRuleSet = $this->fullRuleSet;
} else if ($this->idanounce_type === self::SHORTER) {
$this->currentRuleSet = $this->shortRuleSet;
} else if ($this->idanounce_type === self::MINIMAL) {
$this->currentRuleSet = $this->minRuleSet;
}
return parent::beforeValidate();
}
}
Variable idanounce_type is a switch between rules.
Unfortunately, validation made according to full rules set (or rules set used in init), despite on which *RuleSet value assigned to currentRuleSet.
How to write dynamic switching of rules?
What you want here is to change validation according to the user's input. You can do this by defining scenarios in your model.
So firstly set scenarios where you put in it the fields that are to be validated. Example if you have username, password, and email fields, and you defined two scenarios, in SCENARIO_FIRST only username and password will get validated.
public function scenarios()
{
return [
self::SCENARIO_FIRST => ['username', 'password'],
self::SCENARIO_SECOND => ['username', 'email', 'password'],
];
}
Then in your controller, set the scenario according to the input:
public function actionValidation()
{
$model = new Anounce();
//example
if($condition == true)
{
$model->scenario = Anounce::SCENARIO_FIRST;
}
if (Yii::$app->request->isAjax && $model->load(Yii::$app->
request->post())) {
Yii::$app->response->format = 'json';
return ActiveForm::validate($model);
}
}
Read more about scenarios here and how to use them with validation here:
http://www.yiiframework.com/doc-2.0/guide-structure-models.html#scenarios

Phalcon: HMVC view not working

I got a problem rendering nested view, here is what I'm trying to do
I changed your 'request' of HMVC (HMVC-GitHub or/and HMVC-Pattern) function into an Elements module
namespace Modules\Main\Libraries;
/**
* Elements
*
* Helps to build UI elements for the application
*/
class Elements extends \Phalcon\Mvc\User\Component
{
public function loadModule($path = '', $data = array()) {
$di = clone $this->getDI();
$dispatcher = $di->get('dispatcher');
$paths = explode('/', $path);
$data = is_array($data) ? $data : array($data);
// get controller name
if (isset($paths[0])) {
$controller = $paths[0];
}
// get action name
if (isset($paths[1])) {
$action = $paths[1];
}
// get params
if (isset($paths[2])) {
array_splice($paths, 0, 2);
$params = array_merge($paths, $data);
} else {
$params = $data;
}
if (!empty($controller)) {
$dispatcher->setControllerName($controller);
} else {
$dispatcher->setControllerName('index');
}
if (!empty($action)) {
$dispatcher->setActionName($action);
} else {
$dispatcher->setActionName('index');
}
if (!empty($params)) {
if(is_array($params)) {
$dispatcher->setParams($params);
} else {
$dispatcher->setParams((array) $params);
}
} else {
$dispatcher->setParams(array());
}
$dispatcher->dispatch();
$response = $dispatcher->getReturnedValue();
if ($response instanceof ResponseInterface) {
return $response->getContent();
}
return $response;
}
}
and I have 2 controllers:
namespace Modules\Main\Controllers;
class IndexController extends ControllerBase
{
public function indexAction()
{
$secondContent = $this->elements->loadModule('test/hello/json');
$this->view->setVar('secondContent', $secondContent);
}
}
and
namespace Modules\Main\Controllers;
use \Phalcon\Http\Response;
class TestController extends ControllerBase
{
public function indexAction()
{
}
public function helloAction($format='html', $param = 'empty')
{
$this->view->setVar('content', 'Hello this is test value "'.$param.'"');
$content = $this->view->getContent();
return (string)$content;
// return 'Hello this is test value "'.$param.'"';
}
}
my DI
$di['elements'] = function() {
return new \Modules\Main\Libraries\Elements();
};
Views files
IndexController::Index
<h1>Congratulations!</h1>
<p>You're now flying with Phalcon. Great things are about to happen!</p>
<p>Second content: {{ secondContent}}</p>
<p>HMVC: {{ elements.loadModule('test/hello/json', 'test') }}</p>
and HelloController::test
This is :: {{ content }}
expecting to get
Congratulations!
You're now flying with Phalcon. Great things are about to happen!
Second content: This is :: Hello this is test value "empty"
HMVC: This is :: Hello this is test value "test"
but it only rendering the HelloController (First call from IndexController::indexAction):
This is :: Hello this is test value "empty"
if I change IndexController::indexAction to
public function indexAction()
{
$secondContent = '';
$this->view->setVar('secondContent', $secondContent);
}
and TestController::helloAction to
public function helloAction($format='html', $param = 'empty')
{
$this->view->setVar('content', 'Hello this is test value "'.$param.'"');
$content = $this->view->getContent();
//return (string) $content;
return 'Hello this is test value "'.$param.'"';
}
the result that i get is (Second content is empty):
Congratulations!
You're now flying with Phalcon. Great things are about to happen!
Second content:
HMVC: Hello this is test value "test"
Any solution to solve this ?
Thanks,
Helman
Phalcon have built-it modules feature, you dont have to built your own module loader, you just need create module bootstrap that extend ModuleDefinitionInterface.
Just take a look this sample from phalcon multi module
https://github.com/phalcon/mvc/tree/master/multiple
this example below is taken from link above, This contain module bootstrap code.
<?php
namespace Multiple\Frontend;
class Module
{
public function registerAutoloaders()
{
$loader = new \Phalcon\Loader();
$loader->registerNamespaces(array(
'Multiple\Frontend\Controllers' => '../apps/frontend/controllers/',
'Multiple\Frontend\Models' => '../apps/frontend/models/',
));
$loader->register();
}
/**
* Register the services here to make them general or register in the ModuleDefinition to make them module-specific
*/
public function registerServices($di)
{
//Registering a dispatcher
$di->set('dispatcher', function () {
$dispatcher = new \Phalcon\Mvc\Dispatcher();
//Attach a event listener to the dispatcher
$eventManager = new \Phalcon\Events\Manager();
$eventManager->attach('dispatch', new \Acl('frontend'));
$dispatcher->setEventsManager($eventManager);
$dispatcher->setDefaultNamespace("Multiple\Frontend\Controllers\\");
return $dispatcher;
});
//Registering the view component
$di->set('view', function () {
$view = new \Phalcon\Mvc\View();
$view->setViewsDir('../apps/frontend/views/');
return $view;
});
$di->set('db', function () {
return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo"
));
});
}
}
you can load module using this code below
$app = new \Phalcon\Mvc\Application();
$app->registerModules(array(
'frontend' => array(
'className' => 'Multiple\Frontend\Module',
'path' => '../apps/frontend/Module.php'
),
'backend' => array(
'className' => 'Multiple\Backend\Module',
'path' => '../apps/backend/Module.php'
)
));

Phalcon validation scenario

I used to use Yii framework. I would like to make project using Phalcon. I could not find validation scenario on Phalcon. What is the best way to correctly implement it on Phalcon?
Thanks in advance.
Any data validation:
<?php
use Phalcon\Validation\Validator\PresenceOf,
Phalcon\Validation\Validator\Email;
$validation = new Phalcon\Validation();
$validation->add('name', new PresenceOf(array(
'message' => 'The name is required'
)));
$validation->add('email', new PresenceOf(array(
'message' => 'The e-mail is required'
)));
$validation->add('email', new Email(array(
'message' => 'The e-mail is not valid'
)));
$messages = $validation->validate($_POST);
if (count($messages)) {
foreach ($messages as $message) {
echo $message, '<br>';
}
}
http://docs.phalconphp.com/en/1.2.6/reference/validation.html
If you are working with models:
<?php
use Phalcon\Mvc\Model\Validator\InclusionIn,
Phalcon\Mvc\Model\Validator\Uniqueness;
class Robots extends \Phalcon\Mvc\Model
{
public function validation()
{
$this->validate(new InclusionIn(
array(
"field" => "type",
"domain" => array("Mechanical", "Virtual")
)
));
$this->validate(new Uniqueness(
array(
"field" => "name",
"message" => "The robot name must be unique"
)
));
return $this->validationHasFailed() != true;
}
}
http://docs.phalconphp.com/en/1.2.6/reference/models.html#validating-data-integrity
models also have events, so you can add any logic you need in these functions:
http://docs.phalconphp.com/en/1.2.6/reference/models.html#events-and-events-manager
I would like to use forms for CRUD as they are very dynamic and reusable.
You can achieve that in forms using options.
You can pass additional options to form and act like a scenario.
You can check Form constructor here
https://docs.phalconphp.com/en/latest/api/Phalcon_Forms_Form.html
In your controller you can pass $options
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function insertAction()
{
$options = array();
$options['scenario'] = 'insert';
$myForm = new MyForm(null, $options);
if($this->request->hasPost('insert')) {
// this will be our model
$profile = new Profile();
// we will bind model to form to copy all valid data and check validations of forms
if($myForm->isValid($_POST, $profile)) {
$profile->save();
}
else {
echo "<pre/>";print_r($myForm->getMessages());exit();
}
}
}
public function updateAction()
{
$options = array();
$options['scenario'] = 'update';
$myForm = new MyForm(null, $options);
}
}
And your form should look like something this
<?php
// elements
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
// validators
use Phalcon\Validation\Validator\PresenceOf;
class MyForm extends Form {
public function initialize($entity = null, $options = null) {
$name = new Text('first_name');
$this->add($name);
if($options['scenario'] == 'insert') {
// at the insertion time name is required
$name->addValidator(new PresenceOf(array('message' => 'Name is required.')));
}
else {
// at the update time name is not required
// as well you can add more additional validations
}
}
}
now you can add multiple scenarios and act based on scenarios.

cakephp validation response returning data to controller

Hi i have made a custom validation in the model. How can i access the result($visitor) from this in the controller?
model:
<?php
class Visitors extends AppModel
{
var $name = 'Visitors';
var $validate = array(
'xxx' => array(
'rule' => array('checkxxx'),
'message' => 'yyy.'
)
);
function checkIxxx($check){
$visitor = $this->find('first', array('conditions' => $check));
return $visitor;
}
}
?>
in my controller i want this:
function start() {
$this->Visitors->set($this->data);
if($this->Visitors->validates())
{
if($this->Visitors->xxx->type == 'value') //this is a value from the $visitor array in the model**
{
//do something
}
}
is this possible?
Updated to be a relevant answer, apologies.
//Model
var myField = 'invalid';
function myValidation($var){
if($var === true){
// Passed your validation test
$this->myField = 'valid';
}else{
$this->myField = 'invalid';
}
}
// Controller
$this->Model->set($this->data);
$this->Model->validates($this->data);
if($this->Model->myfield == 'valid'){
// Field has passed validation
}
You will want to use
$this->Model->invalidFields()
PS: You dont follow cake conventions
the model should be "Visitor" (singular)

Resources