Applying form errors manually - validation

I have a situation where I'm editing a snippet of data within a larger context. The user submits this data to a specialized action for handling and redirects back to the parent page. Because it's a redirection, validation errors aren't getting automagically set, so I'm trying to work around that.
In the event of an error, I'm writing a validation_errors key to the session with a value of $model->validationErrors. In the form, though, I'd like to tell Cake to set each error so I can leverage my existing styles and not have to make a lot of changes to my $this->Form->input() methods.
Is something like this possible? Essentially, I'm looking to manually achieve the same result you'd get if a regular form was submitted and allowed to drop through with validation errors. I was hoping I could loop over each validation error and set the field error, but that's not making any change at all.
Thanks.

This can be achieved in the controller by
$this->Model->invalidate('fieldName', __('ErrorMessage', true));
If the values are available, you can also call
$this->Model->validates();
to validate all values with the validators defined in the model.

Save the data to the session and revalidate it.
function childAction() {
if(isset($this->data)) {
$this->Session->delete('invalid_data');
if($this->Test->save($this->data)) {
// ...
} else {
$this->Session->write('invalid_data', $this->data);
}
$this->redirect(array('action'=>'parentAction'));
}
}
function parentAction() {
if($this->Session->check('invalid_data')) {
// This will cause $this->Test->validationErrors to be populated
// Assuming your parent page has the form set up properly, the
// errors will be automagically filled. ie: $form->input('Test.field1')
$this->Test->set($this->Session->read('invalid_data'));
$this->Test->validates();
}
}

If you want to do the same with CakePHP 3, use the method "errors".

Related

Returning a variable from a filter. Laravel 4

I am new to Laravel and I am trying to set up some basic routing logic. I have a route that will process a certain URL pattern. These URLs will usually be an ajax request (returning data for a popup window). However, search engines and users with javascript disabled will follow a normal link, so I want the data to be returned on a separate page. To do this, I need to determine if the request is ajax. I understand I can do this using:
if(Request::ajax()){
//
}
My plan was to do this as part of a 'before' filter attached to the route. If my thinking is correct, I would need to return a boolean ajax=true/false back from the filter. Maybe this is a very simple question, but I can't find anywhere that explains how you actually return a value like this from a filter? Everything I can find seems to assume that the default outcome of any filter logic must be a redirect.
Thanks
EDIT: I've come to the conclusion that I am simply not using the filtering method in the way it was intended, and simply placing the handler in my controller method. But I would still like to know if it is possible to return data from a filter.
In a controller:
if(Request::ajax()){
return Response::json(['message' => 'Hi. Your request was ajax!', 'status' => 1]);
}
The simple solution I found for that is to use Session::flash which populates data for the next request only and you can easily get the result anywhere. So for example :
Route::filter('something', function() {
if(false) {
View:make('error); // or whenever you want
} else {
return Session:flash('result_var', $my_result_var);
}
});

How to enforce Grails command objects have been validated?

We use the following general pattern with Grails controllers and command objects
SomeController {
def someAction() {
SomeCommandObject co = SomeCommandObject.valueOf(params)
if(!co.validate()) {
// return bad request
}
someService.doWork(co)
// return ok
}
SomeService {
def doWork(SomeCommandObject co) {
notTrue(!co.hasErrors(), 'cant have errors') // Commons validation
// do actual work
}
}
Apparently, if co.validate() has not been called, .hasErrors() will always return false. Is there a better way to enforce that .validate() has been called before a command object is passed between application layers? We don't want to pass around invalid command objects but we don't want to force every new method to re-validate the command object either.
Note: We aren't using the default controller/command object creation pattern because we need to do some custom parameter map checking, we use a static valueOf method instead to create the command object. Answers that change that practice are also welcome.
EDIT: A little more info on why we aren't using the 'default' controller/command object creation. Specifically why we aren't doing ..
def someAction(SomeCommandObject co) {
}
We have a requirement to disallow random query parameters, eg. endpoint/object?color=blue. To do that we need access to the parameter map in the command object to verify that it doesn't contain any 'unexpected' parameter keys. As I understand it, the default way would just create a member on the CO named color, and I don't see how to prevent arbitrary members using even custom validators. I'd happily entertain suggestions for doing so, thereby allowing us to use this default means.
Yes; what you can do is pass the command object as a parameter to the controller, and then the command will always be validated automatically.
Also, what you can do, is to make a filter or similar, so that you don't have to check for the hasErrors() each time, but handle all the cases in the same way (for example, by throwing an error, or returning with a specific response).
In an application we created, we had something like:
withValidCommand(cmd) {
// do work
}
Which worked pretty well. But maybe you can come up something even more elegant.
You should be doing this:
def someAction(SomeCommandObject co) {
if (!co.hasErrors()) {
someService.doWork(co)
}
}
By passing SomeCommandObject in as the argument grails will automatically populate it from params and validate. No need to do it manually.

submitting form values in php using ajax request

okay, so I am trying to load a user's information into form fields after the user has finished creating an account. This is sort of a "re-check your personal info" but here his previously entered values are already set. How should I do so using ajax. I want to use the prototype ajax to avoid obtrusive coding.
Again,these are the steps
1.User creates an account on signUp.php
2.He is redirected to edit.php where he checks his personal info which is set by default.
if I do this
function setFormData()
{
new Ajax.requestHTML("edit.php")
{ onSuccess:someFunction()
});
}
then how can I set the form values, like
function someFuncton(ajax)
{
$("firstname").value=??
$("lastname").value=??
$("country").value=??
}
you can in the edit.php output an xml, json or string with the values, parse it and use in your someFunction

Where to validate and test user input date, In the controller or the model?

Where to clean up/ validate/ verify the user input data? In the controller or the model?
In controller.
Look at it this way: Your form will post to a controller function with the form data in $_POST variable. You validate the data in that function of the controller and do some DB inserts or updates. Then you show the success message as a view or in case of error a fail message.
See the form validation tutorial in CodeIgniter's user guide here.
I'd go with the model so your validation can be reused. Models should handle the data and the controller should direct it to where it needs to go.
The code that make the validation must be in the model, but the call to this code must be in the controller.
Something like this:
class MyAwesomeUserModel {
public function isValid()
{
//some code to validate the user
}
}
class MyUserController {
public function myUserAction()
{
//some code to insert the input of the user in the model
if($userModel->isValid()){
//do nice things with the data and send some message/data to the view
} else {
//send 'nice' error messages to the view
}
}
}
This is just the way I use, may not be the best way, but it's the best fit in my application. And that's what matters, you should look for what best suits your application.

CakePHP validation error messages - how to pass them around?

Please note: I'm not trying to do this anymore, because I found an alternative, but it may be useful in the future to know the answer.
I have a form that is in a view (index.ctp) associated with the index() action on a controller. That form should post data to another action, contact(), in the same controller. This second action doesn't have a view, it's just to process the information and redirect the user according to the outcome. This action is doing the validation and redirecting the user to the referer (index in this case) in case of an error, and then the error should be displayed in index. Note that the model doesn't use a database table, but it's used only to define validation rules.
The validation is taking place correctly and reporting the expected errors. In order to retrieve the errors after the redirect, it writes the $this->ModelName->invalidFields() array to a session variable that is retrieved on the index() action after the redirection.
This array is passed on to the $errors variable to the view. Now comes the problem. The errors, although being passed correctly between redirects, aren't getting attached to the respective forms. How can I accomplish this? The form has all the conventional names, so it should be automatic, but it isn't.
Here's part of the relevant code:
Index view:
echo $this->Form->create('Contact', array('url' => '/contacts/contact'));
echo (rest of form) ...
echo $this->Form->end(__('send message', true));
Contacts controller:
function index() {
if ($this->Session->check('Contact.errors')) {
$this->set('errors', $this->Session->read('Contact.errors'));
}
}
function contact() {
if (!empty($this->data)) {
$this->Contact->set($this->data);
if ($this->Contact->validates()) {
(send the email)
}
else {
$this->Session->write('Contact.errors', $this->Contact->invalidFields());
$this->redirect($this->referer);
}
}
}
I don't think it's a good idea to write the validation errors in a session variable. I'm no CakePHP expert, but I don't think that's the way you are supposed to do it. All your forms should point to the same url you are on, so the data that the user has entered will not be lost.
Could you add some code to your question?

Resources