I'm looking to add a custom captcha input into a Drupal Webform. The captcha I wish to use isn't available as a plugin so I want to hook the form as it is output and then add my captcha presentation script.
I already know how to catch a form with <theme>_form_alter(). What I'm not so sure of is how I can inject elements into the form at a certain point. If anyone knows of how to achieve this it would be useful.
You could add your script with a preventDefault on the form submit. Do your client-side validation then submit the form. Adding your javascript would be as follows:
/**
* Implements hook_form_alter().
*/
function MODULENAME_form_alter(&$form, &$form_state, $form_id) {
dpm($form_id);
if ($form_id == 'YOUR_FORM_ID_HERE') { // Example Form ID: webform_client_form_23
$form['#attached']['js'][] = drupal_get_path('module', 'MODULENAME') . 'path/to/example_file.js';
// OR
drupal_add_js(drupal_get_path('module', 'MODULENAME') . 'path/to/example_file.js');
}
}
You can do it with ease by overriding the default form creation. Create a file in your template folder for your webform say its webform-form-22.tpl.php..
Use the $form variable which is available by default. Place the form elements from the $form variable and place your custom captcha according to your requirement anywhere in the form, and validate in the hook custom_module_webform_submission_insert..
Related
I was wondering, does anyone know how can I add another button to a webform in Drupal 7 in addition to the submit button? I tried looking through Google as well as asking this question at the Drupal forums, with no luck. Could anyone please help?
Webform is a drupal form and you can use hook_form_alter: Lets say you have a custom module called mymodule and your webform id is 'webform_client_form_XXXXX'. Then use the sample code below.
/**
* Implements hook_form_alter.
*/
function mymodule_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'webform_client_form_XXXXX':
$form['actions']['custom_submit'] = array(
'#type' => 'submit',
'#value' => t('Custom Button'),
'#submit' => array('mymodule_custom_submit'),
);
$form['#validate'][] = 'mymodule_custom_validate';
break;
}
}
/**
* Custom validation handler for your webform.
*/
function mymodule_custom_validate($form, &$form_state) {
// your validation code
}
/**
* Custom submit handler for your form
*/
function mymodule_custom_submit($form, &$form_state) {
// your submit handler code
}
UPDATE:
You would have to substitute instances of mymodule in the above code with yoru modules's name. Also i have modified the hook_form_alter a little. I suggest you move your submit button under $form['actions'], so it would appear next to the current submit button.
To Clear Cache:
visit /admin/config/development/performance and click on Clear all cache button.
To find the weform form-id:
This tutorial on net discuss about how to find the form id. Please note that the id used in the form tag will have '-' (hyphen), that has to be replaced with '_'(underscore) to get the form-id.
Another method is to print the $form_id variable in hook_form_alter ( the function which we have defined above ) and visit the webform page. If there are no other forms on that page the printed id would be the one that correspond to webform. If you enable devel module then it is easier to display debugging information using excellent krumo library.
/**
* Implements hook_form_alter.
*/
function mymodule_form_alter(&$form, &$form_state, $form_id) {
// Below function would print out the form id in message area if devel module
// is enabled on the site.
dpm($form_id);
switch ($form_id) {
remove dpm( $form_id ); afterwards.
Knowing the webform id is easier than the methods described above. You only need to go to: content->webforms and place the mouse cursor over the edit option belonging to the webform you want the id.
Down the navigator screen the original path in the format node/id will appear. That node number is the XXX in webform_client_form_XXX.
You can use type Markup in webform. Theme the markup as it look a like the button same as your submit button.
and write JS for that. For e.g, you want to give reset button then onclick event should empty the values in those fields. Try this.
first create markup in webform for button then use java script for that when click on this it process request based on your requirement.
I want to create a form in Drupal 7.
User will select appropriate listbox, radio button options.
When user clicks Submit button, form will post related values to another php file with GET arguments.
Default submit button shows a confirmation page for email sending/registration. I couldn't make the form to post arguments to a php file by changing submit behaviour of the form.
For two days I tried Webform module to do this.
I would be happy if you can recommend me some way to make this? Examples, tryouts, modules, codes, etc
There are 'better' ways but this will do the trick in a custom module:
function mymodule_form_alter(&$form, &$form_state, $form_id) {
$nid = 1; // Or whatever the node ID of your webform is
if ($form_id == 'webform_client_form_' . $nid) {
$form['#action'] = 'my-script.php';
$form['#method'] = 'get';
}
}
Bear in mind of course that the original webform submission functions will not run so your webform data won't be saved to the database.
I have enabled Location User module and during user registration I am collecting 2 location fields Country and Postal Code. As I am theming user registration form, I want to remove the Location field-set around Country and Postal Code elements.
Could you please guide me?
To alter the location fieldset on content type forms you have to add an after build, like so
function hook_form_alter(&$form, &$form_state, $form_id) {
...
$form['#after_build'][] = 'alter_location_elements';
}
and the callback function would look something like this:
function alter_location_elements($form_element, &$form_state) {
$form_element['locations'][0]['street']['#type'] = 'hidden';
$form_element['locations'][0]['city']['#type'] = 'hidden';
$form_element['locations'][0]['postal_code']['#type'] = 'hidden';
return $form_element;
}
So far no straight answer for this as Location form structure is different from other form array. Basically using drupal_render function, I have populated postal code and country form element outside of the default Location field-set. So template was displaying empty Location field-set.
I rectified it using dirty technique - CSS hack for time being hiding field-set as below:
#user-register fieldset {display:none;}
For D6, the best way (don't use ['#type'] = 'hidden'; or unset(), these methods can produce bugs):
$form_element['locations'][0]['street']['#access'] = false;
In form_alter:
$form['field']['#access'] = false;
By Css:
display:none;
By Js:
$('#IDELEMENT').css('display') == "none"); or $('#IDELEMENT').hide;
It isn't necessary a id element.
If all you want to do is hide the fields from view, then a simple CSS class setting them to display:none; will do the trick.
If you want to actually change the fields that are presented in the form (as opposed to simply hiding them), you can override the fields in a form using the form_alter hook.
The form_alter hook allows you to override the contents of any form. For instance, if you want to add a field to the 'user_login' form, you could write a function like this:
function mymodule_form_user_login_alter(&$form, &$form_state, $form_id) {
$form['myfield'] = array(
'#type' => 'textfield',
'#title' => t('My new field')
);
}
Then when the user login form is displayed, it will now have your new field in it. You can set as many fields as you like in this $form array.
Likewise, you can remove a field from the form by unsetting it as follows:
unset($form['fieldname']);
The problem you will face, however, is that in Drupal 6, the form_alter hook is only available for modules, not themes. So you may need to create a small module to do what you need. I believe this limitation has been removed in Drupal 7.
See the Drupal Hook_Form_Alter documentation for more detail.
You may also want to see this link which is the Drupal bug ticket where they discussed adding the feature to allow form_alter on themes. You'll note that it is marked as fixed with the Drupal version number of 7.
Another option you have for the form is to write your own template for it in your theme. Using this, you can use drupal_render to output each field/fieldset in the form individually. This also allows you to do more complex theming if you want additional HTML code, etc. However, this method is fraught with danger, as if any other fields are added to the form later on, your theme will not be able to cope with it. Its generally not advised to render your form manually in this way.
Hope that helps.
I'm writing a module that acts on another module. The other module's submit form is at admin/settings/image-toolkit. When its form is submitted, my module needs to respond to that event.
What hook do I need to listen for and how do I know the name of the form?
I'm not even sure where to print dsm in this case to get more information about this form. Is there something like hook_nodeapi but for forms that I could give me more info about the form?
All forms come with a $form[#submit] property that describes what functions are run when the form submits. The default is formname_submit, of course, but you just need to add new ones to that array.
So, you should use hook_form_alter and add another item to the $form['#submit'] array.
You can get the form id easily using the Devel module, or by looking for in the HTML of the pages themselves. (Hyphens should be translated to underscores if you take the latter route)
I get system_image_toolkit_settings for that form on my installations, but that might be dependent on which image library you're using (I use GD).
Though, I'll admit I'm scratching my head a bit about what submit handlers you're wanting to add to that one ;p
Edit:
Some sample code in reply to OP's comment:
What you're basically looking for is this: (from http://drupal.org/node/144132)
function my_module_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'my_form') {
$form['#submit'][] = 'my_additional_submit_handler';
}
}
Of course, you'll need to follow that up with function my_additional_submit_handler in your custom module for anything to happen.
In a custom module, I have the following (to add javascript to a particular form):
function mymodule_form_mynode_node_form_alter(&$form, $form_state) {
drupal_add_js(drupal_get_path('module', 'mymodule') . '/js/mymodule.js', 'module');
}
This function does get called the form is first loaded (i.e. browse to http://myserver.com/node/add/mynode) however this php function does not get called when the same form is reloaded after the form has been invalidated (i.e. missed a required field after clicking 'Submit' or 'Preview').
What do I need to do to have the javascript file added after 'Submit' or 'Preview' is clicked?
Thanks,
John
To solve your problem, you'll need to create a theme function for the form where you render the form and add the js file.
You form alter is only called when the form is build. As forms are cached between request, the same and already build form is used on submit and preview.
You need to unsure that your code is called each time the form is rendered. As pointed out by googletorp, one way to do it is to use a custom form rendering function. You can also do it by attaching a post or pre-rendering function to your form. Actually, the custom, pre or post rendering function doesn't need to be for the form itself and can be used on any form element. Preferably the one which behavior is altered by the JavaScript.