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,
);
Related
Let's assume that I have commerce website on Drupal. There is Drupal Commerce module. I want use api to retrieve complete orders from my store. Is it possible? I can't find any information how this requests looks like (what is response format etc.). Also I don't need php examples , maybe is there Rest API?
I think there are few ways to do it, from simple to (a bit) complex.
Since you mention retrieving data only, the simple way is to create a new Views listing out all orders, you can configure this views to render output as XML or as JSON. Module used can be Views data export, or Views datasource.
The second solution is to create a custom module which use hook_menu to create your custom endpoint URL, which calls a callback function where you can define the output you want
function YOURMODULE_menu() {
$items = array();
$items['api/order'] = array(
'title' => 'API Orders',
'page callback' => 'YOURMODULE_api_orders_callback',
'access arguments' => array('access content')
);
$items['api/order/%'] = array(
'title' => 'API Orders',
'page callback' => 'YOURMODULE_api_orders_callback',
'page arguments' => array(2),
'access arguments' => array('access content')
);
return $items;
}
function YOURMODULE_api_orders_callback($order_id = NULL) {
$order_ids = array();
if(!is_null($order)) {
array_push($order_ids, $order_id);
}
// Load all orders or only 1 order
// We can use commerce_order_load_multiple()
// or use EntityFieldQuery() if need a complex logic filtering orders
$orders = commerce_order_load_multiple($order_ids);
drupal_json_output($orders);
}
The last solution is to use Services modules, create a custom module and create your custom service where you can define your custom resource - in this case - commerce_order.
A tutorial to create custom services can be found here 👉https://valuebound.com/resources/blog/how-to-create-custom-web-services-for-drupal-7-0
This is for the DRUPAL ninjas:
I am creating a menu_hook for my custom module called testmodule;
I want to call a MENU_CALLBACK and return a loaded CCK object of a custom content type I created called "VideoNodes"
example:
$items['save_video_data/%my_custom_cck_type/%'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'save_data_to_db',
'access arguments' => array('Save Data to my_custom_cck_type'),
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'title' => 'Save a Data!'
);
Now, with the above code, my understanding is that I am telling drupal to load my_custom_cck_type and use the array(2) position (my argument) as the id field of the node to find it in the database.
I also understand that, I am going to need to create a my_custom_cck_type_load() function.
QUESTION:
What shoudl be in my_custom_cck_type_load()?? How shall I grab all of the custom fields associated with the CCK type into the returned object? Or does drupal do this for me?
I'll use node_load as an example for this. Out of the box Drupal's menu system will load nodes at paths like.
node/1/view
node/2/view
node/3/view
(note: the "/view" part of the path is often hidden because it's the default tab)
The menu item setup to do this looks something like:
$items['node/%node/view'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => 'blabla',
'page callback' => 'node_view',
'page arguments' => array(1)
/* more stuff */
);
In the real path the %node is replaced by a number, the NID of the node. This will cause menu to fire node_load using that number as the argument. We're also using %node as the page argument for the node_view callback. The argument that callback receives will be the fully loaded node object.
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.
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.