I'm trying to submit a form and use hook_form_submit.
The problem is the form is displayed via ajax and this results in hook_form_submit not being called.
$items['ajaxgetform/%'] = array(
'page callback' => 'ajaxgetform',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK
);
function ajaxgetform($form_id) {
drupal_get_form($form_id);
return drupal_json($panel);
}
function_myform_form($form_state) {
$form['myform'] = array(
'#title' => 'myform value',
'#type' => 'textfield',
'#default_value' => 'myform default value'
);
$form['#action'] = url('myurl');
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'submit'
);
$form['#ajaxsubmit'] = TRUE;
return $form;
}
hook_form_alter() does get called.
Below doesn't get called?
function myform_form_submit($form, $form_state) {
// ...
}
I'm not sure if this is a common problem, but i've been stuck for hours trying to make it work.
If I remove $form['#action'] = url('myurl'); myform_form_submit() gets called. However I get a white screen with jason script.
There is no hook_form_submit(). Instead, you register submit handlers with $form['#submit']. So, if you want to call myform_form_submit() when the form gets submitted, add:
$form['#submit'][] = 'myform_form_submit';
to myform_form(). Take a look at the 5.x to 6.x form changes and the Forms API reference for more info.
Is your form displayed on the page at myurl ? In order for a form submission to be processed, the form as to be displayed (using drupal_get_form()) on the page used as action.
You may also try to se the form #redirect to the landing page URL instead of its #action. This way, the form is submitted to its generating URL but the user is redirected to your destination page after processing.
Related
Let's say I have custom module with Drupal.
I want to let user to type what skill their have in first form and after that show their skill as a title in second form and type percentage of their skill in textfield.
function skillbar_form($form, &$form_state) {
$form['html5'] = array(
'#type' => 'textfield',
'#title' => t('HTML5'),
'#default_value' => variable_get('html5'),
'#description' => t('Enter a percent of your HTML5 skill'),
);
return(system_settings_form($form));
}
Multistep Form is you friend, if you are building your form using the Form API.
Otherwise there are various modules which could help you in building forms with more than one step. A couple of them being:
Multi-step forms
Multi-Step Registration
Note: Multistep forms generally collect all the data from various steps. The data is mostly submitted at the final step (which is also a best practice).
You can pass the data from one form to another through URL in the submit form of first form.
function skillbar_form_submit($form, &$form_state){
$data_a = $form_state['values']['html5'];
$form_state['redirect'] = array('url_page2', $data_a);
}
In the other form just retrieve the data as by passing the $data_a as argument. So $var will have the value as 'html5'.
example_form($form ,&$form_state, $var){
...
}
And for the URL you will have to send it in items array
$items['url_page2/%'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('page2_form', 1),
'type' => MENU_CALLBACK,
'access callback' => TRUE,
);
Hi i have used this code
<?php
$elements = drupal_get_form("user_login");
$form = drupal_render($elements);
echo $form;
?>
to get the default Drupal login form for my site but I need to customize the HTML, I have found some pages in module/users but did not understand how to customize the structure.
The user login form for Drupal is built by the user_login function in user.module using Drupal Form API. If you need to customize it, you should do it using hook_form_alter() in your module
function YOUR_MODULE_NAME_form_alter(&$form, &$form_state, $form_id) {
if ($form_id=='user_login') {
// YOUR CUSTOM CODE FOR THE FORM GOES HERE
}
}
** EDIT, AFTER YOUR COMMENT **
You don't need to call the YOUR_MODULE_NAME_form_alter() function: Drupal does that for you via the hook mechanism everytime it needs to build a form, and, when $form_id=='user_login', it modifies the login form to allow your customization. The way Drupal does that is discussed in detail in drupal.org, just follow the link I wrote at the beginning of this answer.
The user login form is declared this way in user.module:
// Display login form:
$form['name'] = array('#type' => 'textfield',
'#title' => t('Username'),
'#size' => 60,
'#maxlength' => USERNAME_MAX_LENGTH,
'#required' => TRUE,
);
$form['name']['#description'] = t('Enter your #s username.', array('#s' => variable_get('site_name', 'Drupal')));
$form['pass'] = array('#type' => 'password',
'#title' => t('Password'),
'#description' => t('Enter the password that accompanies your username.'),
'#required' => TRUE,
);
$form['#validate'] = user_login_default_validators();
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
The $form array is passed by reference to your hook_form_alter() before being rendered, allowing for customization. So, let's say that you want to change the label of the textfield for the user name from "Username" to "Name of the User", you write
$form['name']['#title'] = t("Name of the User");
in your custom code. If you want to add another field to the form (a textarea, for example), you do
$form['otherfield'] = array(
'#title' => t('My new custom textarea'),
'#type' => 'textarea',
'#description' => t("A description of what this area is for"),
'#cols' => 10,
'#rows' => 3,
'#weight' => 20,
);
and Drupal will add the field to the user login form.
There are many different kind of fields and properties that you can customize this way: I encourage you to fully read the Form API documentation. This way you let Drupal take care of form generation, translation, rendering, validation and submission, also permitting to other modules to manipulate your form if needed.
I hope it's clear, have a good day.
use this in template.php
function themename_theme() {
$items = array();
$items['user_login'] = array(
'render element' => 'form',
'path' => drupal_get_path('theme', 'corporateclean') . '/templates',
'template' => 'user-login',
);
and create a template folder and within that create a file user-login.tpl.php and in this file you can put your html and could customize drupal login
I am creating a custom module. I want to implement a form that can be used as a block, and used in a query dialog (loaded with an ajax request). I have created the block no problem. I have also created the page callback function no problem.
So, I can load the form in a block and I can pull up the jquery dialog and it will get the form with an ajax request. But, It loads the form and the full page template complete with header and footer etc....
What I want to do is use a different page template when getting the ajax call so that all I get is the form. But, everything I've seen online seems to be a mix between drupal 6 and 7 and I haven't gotten anything to work.
here's my latest try:
in menu hook
$items['mymodule/get_form_ajax'] = array(
'title' => 'Ajax Form',
'type' => MENU_CALLBACK,
'page callback' => 'get_form_ajax',
'access arguments' => array('access content'),
);
Then I have the callback:
function get_form_ajax() {
$form = drupal_get_form('request_form');
$build['items'] = array(
'#theme' => 'request_form',
'#items' => $form,
);
return $build;
}
And then I have the theme registered this way:
function mymodule_theme($existing, $type, $theme, $path){
return array(
'request_form' => array(
'template' => 'request_form',
'render element' => 'form',
)
);
}
Anyway, this totally doesn't work. It just renders an empty page in the dialog. Any help will be appreciated.
Since you're making an AJAX call there's no need to let the page build as normal, you can simply print the rendered form out directly and call drupal_exit():
function get_form_ajax() {
$form = drupal_get_form('request_form');
echo render($form);
drupal_exit();
}
This will give you a nice clean form that inherits the styles from the page it's being loaded into, and still keeps the form tokens/cache in-tact.
which will be the best way to develop custom forms for drupal, for admin's part of the system?
thank you in advance!
First thing, you need a location to access your form from, preferably in the "admin/*" namespace if the form is only meant for administration.
If you're just showing a form, you could directly use drupal_get_form as page callback (but you could use any function to generate the HTML code, even mix with theme functions)
Also, you need to know which permission(s) is required to access the form.
By default, I used "access administration pages" but you probably should use something more specific, depending on what you intend the form for.
Let's say the path is "admin/build/something", you need to use hook_menu to register that path:
/**
* Implementation of hook_menu().
*/
function modulename_menu(){
return array(
'admin/build/something' => array(
'title' => 'Example Admin Form',
'description' => 'Admin form introduced by the MODULENAME module',
'type' => MENU_NORMAL_ITEM,
'page callback' => 'drupal_get_form',
'access arguments' => array('access administration pages'),
),
);
}
Now, to actually display a page: the value provided in "page arguments" was the name
of the function that drupal_get_form expects to provide the form structure
(which must be an associative array):
/**
* Form Structure
*/
function modulename_form_something(&$form_state){
$form = array();
$form['myfield'] = array(
'#title' => 'My Field',
'#description' => 'This is a basic text input field',
'#type' => 'textfield',
'#default_value' => $form_state['values']['myfield'],
);
//
// Here you can add more elements in the form
//
return $form;
}
Here is more informations about the Forms API, which you can use to make some pretty complex forms easily.
Now your form is displayed at "/admin/build/something", but you probably want to do soemthing with these data as well; by default, the validate and submit functions are named the same as the form structure function, with "_validate" and "_submit" respectively (however you can override this with #validate and #submit in the form structure).
For example, let's say the string "no" is not a valid value, everything else is accepted.
/**
* Form validation
*/
function modulename_form_something_validate($form, &$form_state){
if ($form_state['values']['myfield'] == 'no'){
form_set_error('myfield', '"<b>no</b>" is not a valid answer, try again.');
}
}
The validation is called first, however you should only check if data are alright in that function. If you need to perform actions when the form is received, do it in the "submit" handler instead because validate may be called several times while submit is called only once.
/**
* Form submission
*/
function modulename_form_something_submit(&$form, &$form_state){
//
// Here you can perform whatever action that form is made for.
//
drupal_set_message( 'The form has been sent. "myfield" has the following value: '.$form_state['values']['myfield'] );
}
Let's summarize, here's the whole modulename.module file:
<?php
/**
* Implementation of hook_menu().
*/
function modulename_menu(){
return array(
'admin/build/something' => array(
'title' => 'Example Admin Form',
'description' => 'Admin form introduced by the MODULENAME module',
'type' => MENU_NORMAL_ITEM,
'page callback' => 'drupal_get_form',
'page arguments' => 'modulename_form_something',
'access arguments' => array('access administration pages'),
),
);
}
/**
* Form Structure
*/
function modulename_form_something(&$form_state){
$form = array();
$form['myfield'] = array(
'#title' => 'My Field',
'#description' => 'This is a basic text input field',
'#type' => 'textfield',
'#default_value' => $form_state['values']['myfield'],
);
//
// Here you can add more elements in the form
//
return $form;
}
/**
* Form validation
*/
function modulename_form_something_validate($form, &$form_state){
if ($form_state['values']['myfield'] == 'no'){
form_set_error('myfield', '"<b>no</b>" is not a valid answer, try again.');
}
}
/**
* Form submission
*/
function modulename_form_something_submit(&$form, &$form_state){
//
// Here you can perform whatever action that form is made for.
//
drupal_set_message( 'The form has been sent. "myfield" has the following value: '.$form_state['values']['myfield'] );
}
Don't forget you also need a .info file for being able to install the module:
Source of modulename.info:
; $Id
name = Admin Form
description = This module adds an admin form
package = Example Module
core = "6.x"
version = "6.x-0.1-dev"
The Drupal form api system will help you make any form you need. If you need to store settings, system_settings_form is a nice shortcut.
The only difference when making admin forms, is to remember to set some sort of permission required, and to place the form somewhere in the /admin/ section of the site. There really isn't anything special about admin forms.
Unless I'm misunderstanding your question, I think you can avoid the hassle of Forms API by using the Webform module.
No code required, nice UI and built in statistics tools.
http://drupal.org/project/webform
Watch a couple tutorial videos and you'll be making just about any form in no time.
I have this form which accepts user’s input. What I like to do is, base on that user input, I’d like to retrieve data and display it back to user.
So far, I have implemented hook_menu and registered respective url of the form, and implemented a submit function referred by “#submit” attribute of submit button. I’ve also implemented data retrieval code and works great.
Here’s my problem – I don’t know how to display retrieved data. I’ve tried several approaches in an attempt to find the solution.
First, with theme function, hoping that printing the return value of it would display the data. Second, setting “#action” element of form array with newly registered url, as I thought using the same url as form would only cause drupal to return that form instead and not my data. So, I creates a static variable and stores all the retrieved data in it;this is done inside submit function by the way. When I checked this variable inside menu callback, this variable is not set.
To summarize my problem, form has different access url than form submit, such as
Form url – http://....?q=mymodule/form
Submit url (value of ”#action”) – http://....?q=mymodule/execute
, and the data I’ve set inside submit function to static variable is not available in menu callback. How do I make the data available?
Here’s part of my code -
static $retrieved_data;
function mymodule_menu() {
$command = array();
$command['mymodule/form'] = array(
'title' => 'user input',
'page callback' => 'response',
'page arguments' => array('form'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$command['mymodule/execute'] = array(
'title' => 'Search',
'page callback' => 'response',
'page arguments' => array('execute'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $command;
}
function _response($paRequest){
switch($paRequest){
case "form":
return drupal_get_form("_myform");
break;
case "execute":
return $retrieved_data;
break;
}
}
function _myform(&$form_state) {
$form['#action'] = url($base_path)."?mymodule/execute";
.....
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('_data_retrieve'),
);
return $form;
}
function _data_retrieve($form, &$form_state){
/*data retrieval code*/
........................
$retrieved_data = db_fetch_object($result);
}
Thanks a bunch
Your method seems a bit complicated there. When I make systems with a form, I tend to do it this way. In your MYMODULE_menu() I would change the 'page arguments' => array('form'), to 'page arguments' => array('NAME_OF_FORM_FUNCTION'), where NAME_OF_FORM_FUNCTION would be _myform in this case. I would rename it to MYMODULE_MYFORMNAME.
then create a function:
MYMODULE_MYFORMNAME_SUBMIT($form, &$state) {
// Enter code here to save the data from the form that is stored in $state
// to the database with an SQL query or a node_save($node) if you are
// creating a node.
}
After that you can retrieve the data from the database in your _data_retrieve function and call that on the page where you want to retrieve the data.