User information in modal before submitting form in Yii - php

I have a form and after user submits the form and validation goes OK, I want to ask him for his email and nickname in modal window. If user fills and submit an email and nickname, I want to validate it and save it as new record or get id of existing one (in case email was already used in past). If validation is not successful, user should be able to correct values in the same modal. If everything is OK, I want to save the form including create user id.
I already have form saving and user create/find process done. I just do not know, how to put this together, to work in scenario I described above. Could anyone explain, how this should be done in Yii? I am using Yii 1.1.15 and Yii Booster. Thank you.

In Yii the _form.php view file is used both in update.php and create.php views by default.
So, you might need to do smth. similar: insert form with modal in both update.php and create.php views.
Actions and different for these, so you keep logic separate; this is the MVC basic advantage.
public function actionCreate() {
$model = new Users;
if (isset($_POST['Users'])) {
$model->attributes = $_POST['Users'];
if ($model->save()) { // here in the save() method the valadation is included
// ONLY after we validate and successfully saved we go to update action
$this->redirect(array('update', 'id' => $model->id));
}
}
$this->render('create', array(
'model' => $model,
));
}
The main thing is that when you try to save save() method the validation happend automatically.
So if validation is not successful the logic brings back to the same action (create for example) with fields populated in view since model is already having data passed into it: $model->attributes = $_POST['Users'].
If validation is successful we redirect further. Not nessesary ajax form submit, even casual submit fits here.
public function actionUpdate($id) {
$model = $this->loadModel($id);
if (isset($_POST['Users'])) {
$model->attributes = $_POST['Users'];
if ($model->save()) { // after saving EXISTING record we redirect to 'admin' action
$this->redirect(array('admin'));
}
}
$this->render('update', array(
'model' => $model,
));
}
Forms in views(update/create) you keep as originally designed.
Validation for uniqueness is simple in model rules():
array('username, email', 'unique'),
Email valadation for email syntax is seems like this:
array('email', 'email'),

Related

automatically redirects to index page instead of desired page

I have a taskController controller in my laravel application.Inside my resource folder i have have three pages under resource/views/taksController/
1.index.blade
2.store.blade
3.create.blade..
in my create.blade i have a form which on submit will go through a validation and if succeeded i want it to be redirected to store.blade ,otherwise it will redirect to create.blade again to fill up the form again.But here in my program ,on success it doesn't redirect me to store.blade file, rather it redirect me to index.blade.Why is this happening?How i can solve this?
i am using laravel 5.2
In my route.php i added the controller like
Route::resource('taskController','taskController');
in taskController the validation logic inside controller is like the following:
public function index()
{
//
return View::make('taskController.index');
}
public function create()
{
//
return View::make('taskController.create');
}
public function store(Request $request)
{
$rules = array(
'email' => 'required|email', // required and must be unique in the ducks table
'comment' => 'required',
'agree' => 'required|accepted' // required and has to match the password field
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
echo 'bal';
// redirect our user back to the form with the errors from the validator
return Redirect::route('taskController.create');
}else{
return Redirect::route('taskController.store');
}
}
The URL used for the index route and the store route are the same. The difference is the HTTP verb that is used on that URL. GET requests to the URL will take you to the index, whereas POST requests to the URL will take you to the store.
In your store() method, when you return Redirect::route('taskController.store');, the route() method converts the parameter to the URL, and then makes a GET request to it. This is why you are redirected to index.
Generally, your store, update, and destroy routes don't have views associated with them. They are meant to perform an action and then redirect to the route that contains the view.
For example, the general workflow for creating a new resource is:
create route shows create view which has the form,
form POSTs to store route,
store route attempts to create new resource,
if validation fails, store route redirects back to create route with errors,
if resource is created successfully, store route redirects to the show route, with the id of the newly created resource.
The workflow for editing a resource is similar:
edit route shows edit view which has the form,
form PUTs to update route,
update route attempts to edit the resource,
if validation fails, update route redirects back to edit route with errors,
if resource is modified successfully, update route redirects to the show route, with the id of the modified resource.
i think you should have this:
public function index(){
return view('taksController.index');
}
public function create(){
return view('taksController.create');
}
public function store(Request $request)
{
//
$rules = array(
'email' => 'required|email', // required and must be unique in the ducks table
'comment' => 'required',
'agree' => 'required|accepted' // required and has to match the password field
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
//echo 'bal';
// redirect our user back to the form with the errors from the validator
return Redirect::route('taskController.create');
}else{
return view('taksController.store');// redirects me to index.blade instead of store.blade
}
}

Yii : Rules Checking On Different Scenario

i want to check different validation in one controller.
i have problem is,
when user is registering first time at that time i want to do following validation
array('name, email, password, location, confirm_password', 'required','on'=>'create'),
array('confirm_password', 'compare', 'compareAttribute' => 'password','on'=>'create,fbuser'),
array('email','unique','on'=>'create'),
and if user is already registered with FB and trying to register at that time i want to do following validation (i don't want to validate email address in this case)
array('name, password, location, confirm_password', 'required','on'=>'fbuser'),
array('confirm_password', 'compare', 'compareAttribute' => 'password','on'=>'create,fbuser'),
this is my controller method...
public function actionCreate()
{
$model=new AppUser('create');
if(!Yii::app()->user->isGuest)
$this->redirect('/');
if(Yii::app()->request->isPostRequest)
{
if($model->isFbUser($_POST['email'])){
$model->scenario = 'fbuser';
if($model->validate())
$this->redirect(array('/Appuser/fbauth','email'=> $_POST['email']));
}
else
$model->scenario = 'create';
$model->attributes=$_POST;
if($model->save())
$this->redirect('/login');
}
$this->render('create',array(
'model'=>$model,
));
}
but its not validating properly.
can anyone help me to solve it?
Thanks in advance
I think the problem might be, that in the if (isFbUser) clause you do not assign the post data to the model before validating.
Your use of scenarios looks good to me.

How to connect a form into another phtml view in Zend 2 framework

I am new at Zend2:
I have a form, and in the first stage I create a new ViewModel and return it:
return new ViewModel(array('form' => $form, 'messages' => $messages));
In the post stage when the data comes back from the browser, how can I connect this same form to a new View (which has the same elements maybe less, maybe more) or create another form and rassign it the old form's data and relate it to a new view to show?
Any help would be appreciated.
EDIT:
I tried to do the following:
$form->setAttribute('action', $this->url('auth/index/login-post.phtml'));
But still shows the old one.
When I do this:
return $this->redirect()->toRoute('auth/default', array('controller' => 'index', 'action' => 'login-post'));
I get error page: The requested controller was unable to dispatch the request.
When I get the post of the request I need to load another view, I mean how do I specify which view is connected to which form?
The forms do not themselves have any knowledge of the view. If you wish to change the view after completing the form submission; where this new view provides perhaps a different form, this is something that should be done within the controller.
A (non-working) example with a few options on how a different view could be returned.
class FooController extends AbstractActionController
{
public function getFooForm()
{
return $this->getServiceLocator()->get('Form\Foo');
}
public function getBarForm()
{
return $this->getServiceLocator()->get('Form\Bar')
}
public function fooAction()
{
$request = $this->getRequest();
$form = $this->getFooForm();
if ($request->isPost()) {
$form->setData($request->getPost());
// Is the posted form vaild
if ($form->isValid()) {
// Forms validated data
$data = $form->getData();
// Now there are a few options
// 1. Return a new view with the data
$view = new ViewModel($data);
$view->setTemplate('path/to/file');
return $view;
// OR Option 2 - Redirect
return $this->redirect()->toRoute('bar', $someRouteParams);
// Option 3 - Dispatch a new controller action
// and then return it's view model/response
// We can also pass on the posted data so the controller
// action that is dispathed will already have our POSTed data in the
// request
$request->setPost(new \Zend\Stdlib\Parameters($data));
return $this->forward()->dispatch('App\Controller\Foo', array('action' => 'bar'));
}
}
// Render default foo.phtml or use $view->setTemplate('path/to/view')
// and render the form, which will post back to itself (fooAction)
return new ViewModel(array('form' => $form));
}
public function barAction()
{
$request = $this->getRequest();
$form = $this->getBarForm();
if ($request->isPost()) {
$form->setData($request->getPost());
// ....
}
// Renders the bar.phtml view
return $this->viewModel(array('form' => $form));
}
}
From what I understand form your question, you would need to be using option 3 as the new view should populate a second form with it's already validated data.
If you are referring to something like an edit view then you just need to bind your object to the form.
$form->bind($yourObject);
http://zf2.readthedocs.org/en/latest/modules/zend.form.quick-start.html#binding-an-object
Otherwise you can make the form post to any controller action using by setting it:
$form->setAttribute('action', $this->url('contact/process'));
Maybe post what code you have and more specifics and I'm sure you will get some more detailed answers

Symfony2 form submitting on page refresh

I have a form in Symfony2 framework. On successful submission of the page it renders another twig template file and returns the values by passing the parameters in an array. But after submission, if I refresh the page, again it is submitting the form and the table entry is created. Here is the code that is executed after submission in the controller,
$this->get('session')->setFlash('info', $this->get('translator')->trans('flash.marca'));
return $this->render('NewBundle:Backend:marca.html.twig', array(
'active' => 1,
'marca' => $marca,
'data' => $dataCamp,
'dataMarca' => $this->getMarcas($admin->getId()),
'admin' => $admin,
));
I want the form to be redirected to the twig files mentioned there with the parameters and the alert message mentioned above. But I don't want the form to be submitted on page refresh.
Thanks
This worked for me:
return $this->redirectToRoute("route_name");
You should save submitted data in session and redirect user. Then you will be able to refresh page as much as you want without additional submission.
Example code - your action algorithm should be similar:
...
/**
* #Route("/add" , name="acme_app_entity_add")
*/
public function addAction()
{
$entity = new Entity();
$form = $this->createForm(new EntityType(), $entity);
$session = $this->get('session');
// Check if data already was submitted and validated
if ($session->has('submittedData')) {
$submittedData = $session->get('submittedData');
// There you can remove saved data from session or not and leave it for addition request like save entity in DB
// $session->remove('submittedData');
// There your second template
return $this->render('AcmeAppBundle:Entity:preview.html.twig', array(
'submittedData' => $submittedData
// other data which you need in this template
));
}
if ($request->isMethod('POST')) {
$form->bindRequest($request);
if ($form->isValid()) {
$this->get('session')->setFlash('success', 'Provided data is valid.');
// Data is valid so save it in session for another request
$session->set('submittedData', $form->getData()); // in this point may be you need serialize saved data, depends of your requirements
// Redirect user to this action again
return $this->redirect($this->generateUrl('acme_app_entity_add'));
} else {
// provide form errors in session storage
$this->get('session')->setFlash('error', $form->getErrorsAsString());
}
}
return $this->render('AcmeAppBundle:Entity:add.html.twig', array(
'form' => $form->createView()
));
}
Redirect to same page is preventing additional data submission. So lean of this example modify your action and you will be fine.
Also instead save data in session you can pass it through redirect request. But I think this approach is more difficult.
Save your data (session/db/wherever you want it saved)
redirect to a new action, retreiving the new data in that action, and rendering the template
this way, refreshing the new action, will only refresh the template, as the saving of your data happened in the previous action
understand ?
so basically replace your
return $this->render....
by
return $this->redirect($this->generateUrl('ROUTE_TO_NEW_ACTION')));
and in this new action, you put your
return $this->render....

Cake PHP Validation not happening

Im new to cakePHP.I just learning the way to validate the data before storing into the database.I just did the following validation to check the birth date given by the user.
class User extends AppModel {
public $name = "Users";
public $validate = array (
'birth_dt' => array ( 'rule' => 'date',
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date' ));
}
I expected a error message when I give wrong data in the birth_dt field.But there is no errors in case of wrong data ,bug the data is not getting store in the database.If I give the valid data also the data is not getting stored.If I remove the validation part then data getting stored in the database.
It not only happen for date ,it happen for other fields like alphaNumeric ,email which I used in my form.Any one please tell what I did wrong.
This is my controller code,
<?php
class UsersController extends AppController{
var $name = 'Users';
var $uses = array('User','Dob');
var $helpers = array('Form');
function index() {
if ($this->request->is('post')) {
if ($this->request->data) {
$this->User->save ( $this->request->data );
$this->Session->setFlash("User Added!");
$this->redirect('/users');
}
}
}
There can be multiple possible issue.Try following.
Before saving user Create new record like this->User->create();
You don't have else part. Write like following in else & check,
else {
$this->Session->setFlash(__('User could not be saved',true));
}
You can check why save() failed by examining the validationErrors array in the User model. From the UsersController it can be access via $this->User->validationErrors.
Furthermore, your controller logic isn't quite right. A was mentioned in some of the comments, you don't check if save() was successful and you always state that a user was added, even when it's not true.
Try something like this:
if($this->request->is('post') && !empty($this->data)) {
if($this->User->save($this->data)) {
$this->Session->setFlash('User added!', 'flash_good');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Could not add player.', 'flash_bad');
}
}
This way, when save() fails for some reason, the user will remain in that action and the form will still be populated with the data the user entered. Furthermore, if you use $this->Form->input(...) to create you form elements the validation errors will be added to the form automagically.
I think your public $validate is wrongly written
Try this
class User extends AppModel {
public $name = "Users";
//For more strict validation you should have more than one parameter
//submitted to the rule array for date which requires the user to enter
// exactly what you need. for example 01/01/12 instead of 01/01/2012
//Please check the following address
//http://book.cakephp.org/2.0/en/models/data-validation.html#Validation::date
//However, this should work fine.
public $validate = array (
'birth_dt' => array (
'rule' => array('date'),
'required' => true,
'allowEmpty' => false,
'message' => 'Please Give valid date'
)
);
}
I think best way for validation is to integrate server side and client side validation.
form fields should be validated on focus out/blur with ajax call to server side validation rules via your controllers. This will ensure consistency in server side and client side validation.
bla..bla :)
I think validate error message not show
because you use $this->redirect('/users');
when redirect cakephp will be render view that clear message error :)
You can comment line //$this->redirect('/users'); and then try again :)

Categories