I have a Drupal form wherein someone inputs information, and I need to do a database query to check if it is valid before submitting. I would like to either have a button the user can click to check the validity (or have it be done automatically after the user leaves that field), and then display some information about his selection.
I know I can use hook_form_submit to review a form when it is submitted and then stop the process if there are any errors, but I would like the user to be able to confirm they have selected the correct thing before submitting the form.
I haven't personally tried this module, but it might be what you're looking for:
http://drupal.org/project/ajax
If you're just looking for a way to do real-time lookups (e.g. entering the book barcode and getting the title), you can also use Drupal's autocomplete feature, but it will require you to write your own autocomplete function to handle the database lookups.
Take a look at: Basic form with validate handler. You really just need to add a function similar to mymodule_myform_validate($form, &$form_state) { ... }. From the linked page:
"This adds a new form field and a way to validate it with a validate function, also referred to as a validate handler."
<?php
function my_module_menu() {
$items = array();
$items['my_module/form'] = array(
'title' => t('My form'),
'page callback' => 'my_module_form',
'access arguments' => array('access content'),
'description' => t('My form'),
'type' => MENU_CALLBACK,
);
return $items;
}
function my_module_form() {
return drupal_get_form('my_module_my_form');
}
function my_module_my_form($form_state) {
$form['name'] = array(
'#type' => 'fieldset',
'#title' => t('Name'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['name']['first'] = array(
'#type' => 'textfield',
'#title' => t('First name'),
'#required' => TRUE,
'#default_value' => "First name",
'#description' => "Please enter your first name.",
'#size' => 20,
'#maxlength' => 20,
);
$form['name']['last'] = array(
'#type' => 'textfield',
'#title' => t('Last name'),
'#required' => TRUE,
);
// New form field added to permit entry of year of birth.
// The data entered into this field will be validated with
// the default validation function.
$form['year_of_birth'] = array(
'#type' => 'textfield',
'#title' => "Year of birth",
'#description' => 'Format is "YYYY"',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
// This adds a handler/function to validate the data entered into the
// "year of birth" field to make sure it's between the values of 1900
// and 2000. If not, it displays an error. The value report is // $form_state['values'] (see http://drupal.org/node/144132#form-state).
//
// Notice the name of the function. It is simply the name of the form
// followed by '_validate'. This is the default validation function.
function my_module_my_form_validate($form, &$form_state) {
$year_of_birth = $form_state['values']['year_of_birth'];
if ($year_of_birth && ($year_of_birth < 1900 || $year_of_birth > 2000)) {
form_set_error('year_of_birth', 'Enter a year between 1900 and 2000.');
}
}
?>
Related
I have been working on creating a custom form with an autocomplete field that will search the database for a specific content type's field values and bring back the results so the user can select one for that input box.
My main problem is actually knowing how to target the specific field in the database.
The database information resides in a content type called 'Parts' and within that content type there is a field called 'cross_reference'.
We have thousands of parts and each one has many cross reference values as the 'cross_reference' field is set to unlimited. I need the autocomplete of the custom form to look through these 'cross_reference' values.
Menu and Page
function frontcross_menu(){
$items['frontcross'] = array(
'title' => 'Front Cross',
'page callback' => 'frontcross_page_callback',
'access arguments' => array('access content'),
'description' => t('Front cross'),
'type' => MENU_CALLBACK,
);
$items['cross/autocomplete'] = array(
'title' => 'Autocomplete for cross',
'page callback' => '_cross_autocomplete',
'access arguments' => array('use autocomplete'),
'type' => MENU_CALLBACK
);
return $items;
}
function frontcross_page_callback(){
return drupal_get_form('frontcross_form');
}
Form
function frontcross_form($form,&$form_state){
$form = array(
'#method' => 'post','#default_value' => 'Status Message',
'#id' => 'frontcross_form',
'field_across_reference_value' => array(
'#type' => 'textfield',
'#required' => FALSE,
'#autocomplete_path' => 'cross/autocomplete',
),
'submit' => array(
'#type' => 'submit',
'#value' => t('Submit'),
'#name' => t('Submit'),
'#id' => t('Submit'),
),
);
$form["#submit"][] = 'frontcross_submit';
return $form;
}
Submit
This function puts the form information into a URL query string on the catalogue results page
function frontcross_submit($form,&$form_state){
$options = array('' => TRUE);
$options['query']['field_cross_reference_value'] = $frontcrossval;
$frontcrossval = trim($form_state['values']['field_across_reference_value']);
if($frontcrossval){
$options['query']['field_cross_reference_value'] = $frontcrossval;
}
$form_state['redirect'] = url($GLOBALS['base_url'].'/cross-reference',$options);
}
Autocomplete Function
This is the part that I am stuck on. It needs to look though the database for values that belong to content type 'Part' and its field 'cross_reference' which has multiple values.
I have left the below code as the example I found.
function _cross_autocomplete($string) {
$matches = array();
$result = db_select('cities', 'c')
->fields('c', array('city'))
->condition('city', '%' . db_like($string) . '%', 'LIKE')
->execute();
foreach ($result as $row) {
$matches[$row->city] = check_plain($row->city);
}
drupal_json_output($matches);
}
I hope my explanation is concise enough. Help will be greatly appreciated.
Thanks
Jo
I created a simple user form that allows the user to give a database name and when the user submitt the drupal site will be connected to the given databasename, I defined my database in the file settings.php: myDataBase and when I try
db_set_active('myDataBase');
it works fine but when I type myDataBase in the text field and submitt and then use the submitted value to connect to the database it didnt work.
<?php
function testform_menu() {
$items = array();
$items['test'] = array(
'title' => 'connect an external database',
'page callback' => 'drupal_get_form',
'page arguments' => array('testform'),
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function testform($form, &$form_state) {
$form = array();
$form['Databasename'] = array(
'#type' => 'textfield',
'#title' => t('enter the database name'),
'#description' => t('a user interface to switch between databases'),
'#size' => 28,
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
function testform_validate($form, &$form_state) {
}
function testform_submit($form, &$form_state) {
if (db_set_active('myDataBase'))
{
drupal_set_message('database connected'); // works
}
// $database_name =$form_state['values']['Databasename']; // ius not working!!
// if ($database_name ) {
// db_set_active($database_name); // I even tried to parsing the submitted value to a string but didnt work in both case
// drupal_set_message(t('connected to the database'.' '.$database_name));
// }
db_set_active();
}
You need a function to manage your form submit, for example:
function testform_submit($form, &$form_state)
{
//Do your stuff
}
Or you can define the submit function using the #submit key in your form:
'#submit' => array('your_custom_function_name')
More info: https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#submit_property
Inside this function you can process your form.
inside form hook:
$count = 1;
while($slice = db_fetch_array($fruit)){
$section = $slice['section'];
$form[$section][$count] = array(
'#type' => $slice['type'],
'#title' => $slice['title'],
'#value' =>$slice['value'],
//'#default_value' => $slice['default_value'],
'#disabled' => $true_statement,
'#size' => $slice['size'],
'#description' => $slice['description'],
'#options' => unserialize($slice['options']),
'#prefix' => $slice['prefix'],
'#suffix' => $slice['suffix'],
);
$count = $count+1;
}
inside save :
function student_grant_save($form, &$form_state) {
$vari = $form_state['values']['2']; //or question count # 3,4,5...etc...
drupal_set_message(t('hi').$vari);
}
only the hi gets printed. Why can't i see the form value that the user imputed?
i used dpm($form_state); and I see that i have value entries but they are blank even though user entered them in. For some reason the 'value' entry in my mysql table that has all the question atributes, is taking over the 'default_value' and not letting the user alter the form values upon submit. Is there any way around this?
I have created a custom module and have used 'hook_form' to create a custom form. I have then created a new page using menu callback and inserted this form on it
This form basically is to create nodes from the frontend. I have all the same fields as in the backend.
Form code:
function input_simple_form($form, &$form_submit) {
$form['title'] = array(
'#type' => 'textfield',
'#default_value' => '',
'#required' => TRUE,
'#title' => 'Title',
'#maxlength' => 1024,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
How do I save this, or how do I tell the hook_form that this is for a specific content type? I know how to use node_save but not sure how I would implement this with the hook_form.
How do I go about achieving what I want?
Thanks
Robert
Use in your callback function:
$my_form = drupal_get_form('input_simple_form');
echo $my_form;
if your are using hook_theme to theme your page parce $my_form as variable and print it in your template/theme file.
After having just registered a new account and created a profile how would I log a user in?
I have tried :
global $user;
$user = user_load($account->uid);
or
global $user;
$user = user_load(array('mail' => $_POST['email'], 'pass' => trim($_POST['password'])));
but neither work and the second results in an error about array_flip.
I'm going to answer this for future reference, because the third answer above is wrong, and the first answer will work but is unnecessary (it replicates the experience of the user submitting the login form, calling all validators etc, and presumably you have already done that validation or you wouldn't be trying to log the user in directly.
This will work as expected, assuming you have $username and $password from your own form or function, and you know the user is not logged in:
if ($uid = user_authenticate($username, $password)) {
global $user;
$user = user_load($uid);
$login_array = array ('name' => $username);
user_login_finalize($login_array);
}
First you validate the username and password you have. If you get back a non-zero UID, the authentication succeeded. You create an array that provides the one possibly necessary piece of information that was in the original login form, and pass it to user_login_finalize(), which does all the rest (not just regenerating the session, but also recording the login properly, and calling login hooks).
Drupal does it using user_login_finalize from user_login_submit, you can invoke the same thing yourself with this code:
$form_state['uid'] = $account->uid;
user_login_submit(array(), $form_state);
You can login programmatically in D7 using the following code.
global $user;
$user = user_load($uid);
drupal_session_regenerate();
That should log in the user with the given user id.
/**
* Drupal 7 Programmatically user Login
*/
function hook_menu(){
$itmes['user/form'] = array(
'title' => t('Example Form'),
'description' => 'Drupal Example Form',
'page callback' => 'drupal_get_form',
'page arguments' => array('example_form'),
'access callback' => TRUE,
'type' => MENU_LOCAL_TASK,
);
return $itmes;
}
function otp_login_form($form, &$form_state){
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#description' => t('Enter your #site_name username.',
array('#site_name'=> variable_get('site_name'))),
'#required' => TRUE,
'#size' => 60,
'#maxlength' => 60,
'#weight' => 2,
);
$form['password'] = array(
'#type' => 'password',
'#title' => t('Password'),
'#description' => t('Enter the password that accompanies your username.'),
'#required' => TRUE,
'#size' => 60,
'#maxlength' => 60,
'#weight' => 3,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Login'),
'#weight' => 4,
);
return $form;
}
function otp_login_form_submit($form, &$form_state){
if(user_authenticate($form_state['values']['name'], $form_state['values']['password'])) {
$user_obj = user_load_by_name($form_state['values']['name']);
$form_state['uid'] = $user_obj->uid;
user_login_submit($form,$form_state);
return true;
}
else {
form_set_error('name', t('Sorry, unrecognized username or password.'));
watchdog('user', 'Login attempt by unregistered user %user.', array('%user' => $form_state['values']['name']));
}
}