I have added a button in the form and upon clicking it performs different set of action. The problem i am facing is that the default form is also submitted and i get the velidation messages like enter email etc.
Please advise.
You cannot hijack a form like that. When a form is submitted, all enabled validate handlers will be called, and if no error is found all submit handlers is called.
If you want to make a multi-purpose form, with different requirements, you need to either create the form yourself and handle the validate, or use an existing form, and replace the existing validation with your own.
Related
I have got a form in which I want to show html links. To avoid that a user looses form inputs in case clicking the link, I want to inform the user before he leaves the form.
To achieve that, I tried
public function registerAction(Registration $registration = null) {
$formHasBeenSubmitted = !is_null($registration);
$this->view->assign('formHasBeenSubmitted', $formHasBeenSubmitted);
}
But it is always false.
What is the correct way to find out if the form for a specific action has been submitted?
Update after undkos answer:
I would like to show the message in case the form has been submitted but validation errors have been showing up and of course also as soon as the user started entering data.
Behind a link there is a form which edits data (postal addresses) which are shown on the main form and should be updated there after editing.
As a user I don‘t care if the form has been submitted or "just" filled in - hence I suggest to create a modal whenever there‘s data in your form.
Another possibility of improving usability is to create links with target attribute. Both, modal and target, impose their own issues so it‘s always a trade-off.
I'm using Drupal 7 and HAVE to use the Form Maker (https://drupal.org/project/drupal-form) module. Since it's not a normal form, I don't know how to do something like hooking as Drupal form submission Q/A explains for normal forms.
The available options for "action after submission" for those in-database forms are:
Stay on form.
Link to an article.
Display custom text.
Redirect to an URL.
Is there any way I can handle the form submission? e.g.: Is there a way to reference the form state for the submitted form in the url I specify if using (e.g.) option 4? (or whatever mechanism exists to recover that data by knowing+referencing the submitted record).
BTW I'm a total drupal n00b, and couldnt Find TFM to R (so I can follow the RTM principle) about that special issue in the Form Maker doc.
It looks like this module still uses the form API, so you should just be able to use hook_form_alter() to modify these forms. I'm sure there's some kind of naming convention for the IDs of these forms, which will allow you to apply changes exclusively to form maker forms.
If you need to customize the handling of form submissions, you can include your own submit handler by using the #submit form attribute. Note: the example in the link adds the submit handler to a field in the form, but in most cases I add the submit handler to the form array itself. (i.e. $form['#submit'] = array("submit_callback"))
Edit in response to comments
You do not need to reference a form_id when invoking hook_form_alter(). Instead, you can invoke it globally, which will cause drupal to call your hook on every form. As you can see from the documentation link I provided, the $form_id is passed to the function, and you can use that to conditionally modify the form. Please look at the comments on the documentation page for usage examples.
Unless these forms are being embedded using a third party service, if this module is actually legitimate it will be hooking its forms through the form API. Implement hook_form_alter(), and print off the form_id's that are passed to the function. Go to a page that has one of this forms on it, and see what gets printed.
(Also, [form_id]_form_alter() is not the correct syntax for invoking this hook on specific forms. Should be hook_form_[form_id]_alter(), where hook is your module name.)
Currently, when I design my forms, I like to keep the name of the submit button equal to the id of the form. Then, in my php, I just do if(isset($_POST['submitName'])) in order to check if a form has been submitted and which form has been submitted.
Firstly, are there any security problems or design flaws with this method?
One problem I have encountered is when I wish to overlay my forms with javascript in order to provide faster validation to the user. For example, whilst I obviously need to retain server side validation, it is more convenient for the user if an error message is displayed inline, upon blurring an input. Additionally, it would be good to provide entire form validation, upon clicking the submit button.
Therefore, when the user clicks on the form's submit button, I am stopping the default action, doing my validation, and then attempting to renable the traditional submit functionality, if the validation passes. In order to do this, I am using the form.submit() method but, unfortunately, this doesn't send the submit button variable (as it should be as form.submit() can be called without any button being clicked). This means my PHP script fails to detect that the form has been submitted.
What is the correct way to work around this? It seems like the standard solution is to add a hidden field into the form, upon passing validation, which has the name of form's id. Then when form.submit() is called, this is passed along in place of the submit button. However, this solution seems very ungraceful to me and so I am wondering whether I should:
a) Use an alternative method to detect which form has been submitted which doesn't rely rely on passing the submit button. If so what alternative is there? Obviously, just having an extra hidden field from the start isn't any better.
b) Use an alternative Javascript solution which allows me to retain my non-Javascript design. For example, is there an alternative to form.submit() which allows me to pass in extra data?
c) Suck it up and just insert a hidden field using Javascript.
UPDATE:
I've accepted the correct answer but I just wanted to clarify my mistake here so it would be more helpful for others. I use Mootools and I very naively believed that when I used addEvent('submit' ...) I needed to immediately call event.stop() in order to prevent the from from being submitted. Actually this is not the case and I can just call event.stop() only if validation fails. Otherwise, the default submit gets fired, as usual, and using form.submit() becomes completely unnecessary.
You could send the forms to different handlers with action=file1.php and action=file2.php.
Are they processed using a bunch of the same code? Put that into separate files, include the commonalities, and write the unique bits in each of the handling files. Don't hack, organize.
For Javascript validation, don't halt the default action then resume, instead do this:
if (validation != valid) {
return false;
}
That way if JS is turned off or the validation fails, the form action/event is intact and it behaves as expected, otherwise it bonks. And certainly, certainly retain server-side validation. That's the "real" validation, the client-side is only to please the user and save them time. Never rely on it for YOUR sake.
You can customize the action of the form to add a get key/value; such as action="formhandle.php?formid=10"
I'm using the Zend Framework and I'm about to hack up some of my controller code to do something that seems like there should be a pattern for already.
Currently when I only have one form, the form's action points back to the same action and controller as the one that generated the page. The controller's action function then verifies the form and if verification succeeds, does the desired action. If verification fails, it doesn't perform the action and the page is re-generated using the form that was validated so error messages appear in the correct place.
My situation now is that I have an action/controller that creates two forms and a list of items to the view for display. The view displays the list (say, for example, a list of users) and shows the forms (add user and create role - just as an example). What is the correct "Zend Framework" way to handle this? Should each of the forms' actions be pointing back to the same action/controller? If so, how does one handle validation?
My guess (and how I'm going to proceed for now) is to point both forms back to the controller, figure out which form was submitted, validate that form only, perform action on validation, or re-generate view on failure.
Yes. Let each form have different submit name and validate them based on that. But beware, when you validate wrong form, the error messages will appear ;) So test carefully.
You can submit the two forms to the two different actions of the same controller, and extract the list generation to a third method, and call it from indexAction, and the both form submission actions.
I have a Drupal module page where I am populating a form with a drop-down that contains a list of available parts of a set of files that the user can upload. Once the user uploads a file of a certain type, it removes that option from the list, and when all the available files are uploaded the form will not be rendered.
The problem is that Drupal is drawing the form before it carries out the submit action, so it appears to the user that the operation didn't work until they reload the page.
What is the common way to deal with this? Setting form_state['redirect'] to go to the page doesn't seem to work.
You modify your form so that it saves some information on the state of the form. Then you add a new case to the beginning of the submit function that returns immediately if you're not done uploading all the files, and it will redraw the form.
function modulename_uploader_form(&$form_stuff=null) {
//the function that sets your form array
$stuff = (isset($form_stuff['values'])) ?
$form_stuff['storage']['done_uploading'] :
false; //if values isnt set, this is the first visit.
$form_stuff['storage']['done_uploading'] = done_uploading();
.... the rest of your form creation function.
function modulename_uploader_submit($form, &$form_stuff) {
if($form_stuff['storage']['done_uploading']) {
return;
}
... rest of the function
make sure to unset the storage variable when you're done processing the form. You can also google multi page forms in drupal.
Setting $form_state['redirect'] in your submit handler will just cause the form to reload, fresh, without the old data. It's a way of clearing out the form so that old values don't hang around as defaults.
You probably want to use $form_state['rebuild'], which gives your form-building functions an opportunity to rebuild the form's actual structure, adding more fields or removing options from other fields after the form submit handlers run.
This blog post has a rough tutorial on doing multiple-stage forms in D6, and the Drupal 5 to 6 upgrade docs on Drupal.org contain a useful overview of how $form_state works and what its various flags are for.
The problem is that Drupal is drawing the form before it carries out the submit action, so it appears to the user that the operation didn't work until they reload the page.
I cannot believe it. Are sure about that?