I have a custom module right now in order to text AJAX functionality with Drupal Messages. The module has the following code (test_error.module):
<?php
function test_error_user_view_alter(&$build) {
//_assassinations_player_profile($build);
}
function test_error_form_alter(&$form, &$form_state, $form_id) {
$form['test_error'] = array(
'#type' => 'button',
'#name' => 'Error',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_error',
'wrapper' => 'the-wrapper-div-field',
),
);
$form['test_warning'] = array(
'#type' => 'button',
'#name' => 'Error',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_warning',
'wrapper' => 'the-wrapper-div-field',
),
);
return $form;
}
function test_error_error() {
drupal_set_message("Header error", 'error');
}
function test_error_warning() {
drupal_set_message("Header warning", 'warning');
}
Then, in page.tpl.php, I have the following to output $messages:
<div id="messages-wrap"><?php print $messages; ?></div>
The AJAX function happens when the button is clicked - setting the message - while the message only displays after the page reloads. I tried to hack my way through the return AJAX call like so:
jQuery(document).ready( function(){
jQuery('.ajax-processed').each( function(){
jQuery(this).unbind();
});
jQuery('#edit-test-warning, #edit-test-error').click( function() {
var the_form = jQuery(this).closest('form');
var form_action = the_form.attr('action');
var details = the_form.serialize();
jQuery.ajax({
type: "POST",
url: form_action,
data: details
}).done( function(){
jQuery('#messages-wrap').load("/ #messages-wrap");
});
});
});
The binding of a click event on the #edit-test-x buttons never occurs because of Drupal's native ajax.js preventing it by adding its ajax-x classes.
It's driving me crazy that this problem is so persistent and so difficult to solve when the goal is such a simple thing. What am I missing? Google searching and StackOverflow browsing has come up surprisingly fruitless.
Thanks!
At first, here is some explanations:
1. So you trying to render drupal messages as part of the form, you must to render drupal messages manually.
2. With using '#ajax' key, there is no additional (custom) JS required.
3. On the button click the form is rebuilded, so, all you need is to place message rendering code inside the form logic.
Code example for the simple case:
function test_error_form(&$form, &$form_state) {
$form['test_error'] = array(
'#type' => 'button',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_error',
'wrapper' => 'the-error-container',
),
);
$form['test_warning'] = array(
'#type' => 'button',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_warning',
'wrapper' => 'the-error-container',
),
);
return $form;
}
function test_error_error($form) {
drupal_set_message("Header error", 'error');
return array(
'#type' => 'markup',
'#markup' => theme('status_messages'),
);
}
function test_error_warning($form) {
drupal_set_message("Header warning", 'warning');
return array(
'#type' => 'markup',
'#markup' => theme('status_messages'),
);
}
Note, that you must have div with id="the-error-container" on the page.
If you want to render new drupal messages on the standard place, try to use ajax commands, like this:
$commands = array();
$commands[] = ajax_command_replace($selector, theme('status_messages'));
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
where $selector - is a css/jquery selector of your message area.
Please ask, if there is some unclear.
Related
I want to display custom form (which is custom module) in colorbox in each page.
I have created form in drupal 7 which is working fine if i run it by calling it in url but i need to call this module in colorbox.
my custom module(regform) code is
function regform_init() {
drupal_set_message('Our module is alive!');
}
function regform_menu() {
$items = array();
$items['regform'] = array(
'title' => 'Custom page',
'page callback' => 'drupal_get_form',
'page arguments' => array('regform_form'),
'access arguments' => array('access content'),
'access callback' => TRUE
);
return $items;
}
function regform_form($form, &$form_state) {
$form['#suffix'] = '<div id="test-ajax"></div>';
$form['email'] = array(
'#type' => 'textfield', //you can find a list of available types in the form api
'#title' => 'Enter Email',
'#size' => 50,
'#maxlength' => 50,
'#required' => TRUE, //make this field required
);
$form['submit_button'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#validate' => 'regform_form_validate',
'#ajax' => array(
'callback' => 'regform_form_ajax_callback',
'wrapper' => 'test-ajax'
),
'#submit' => array('regform_form_ajax_callback'),
);
return $form;
}
function regform_form_ajax_callback($form, &$form_state) {
/*Fire database query*/
/*Validation msg div block call here*/
return "<div id='test-ajax'></div>";
}
function regform_form_validate($form, &$form_state) {
if (trim($form_state['values']['email']) == ''){
form_set_error('email', t('Please Enter Email'));
}
if(!valid_email_address($form_state['values']['email'])){
form_set_error('email', t('Enter Valid Email'));
}
}
function regform_form_submit($form, &$form_state) {
$form_state['rebuild'] = TRUE;
$form_state['input'] = array();
}
This form is working fine.
Also I dont have any idea about how to use colorbox in drupal 7.
Any help will be appreciated.
Thanks in Advance.
I suggest to use chaos tools for modal popup form. Its easy to implement and integrate into Drupal 7.
A great example of Ctools modal form is given at here
For modal forms in Drupal, I highly suggest taking a look at chaos tools. It provides a great AJAX API (that can handle the form submission).
There is another module you can take a look at, modal forms. It's built on top of Ctools and provide an easy way to show forms in modal.
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.
I'm trying to understand drupal forms by trial and error (not getting along famously with Drupal Documentation), and I'm a bit confused as why doesn't this work:
function sform() {
$form['password'] = array(
'#type' => 'password',
'#title' => 'enter 1234'
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => '1234 and then click',
);
$form['#method'] = 'post';
return $form;
}
function sform_submit($form_id, $form) {
if (isset($form['values']['password']) && $form['values]']['password'] == "1234") {
drupal_set_message(t('Success;'), '');
}
else {
drupal_set_message("({$form['values']['password']})", 'warning');
drupal_set_message(t('Failure'), 'error');
}
}
I know it all extremely basic and the idea isn't for it to stay in any way like this. As I said I'm just prodding the API to see what works and how.
But the thing is, the basic check is that the "password" field exists and is equal to "1234". And it fails every time. In the failure branch I spit out what value I've got from "password", and I see that it was "1234" nonetheless...
Is there some very obvious reason why the comparison between $form['values']['password'] and "1234" shouldn't be working as I intend here???
You have a typo on your if test:
$form['values]']['password']
//should be
$form['values']['password']
Also it looks like you have your functions setup incorrectly, take a look here: https://api.drupal.org/api/drupal/includes!form.inc/group/form_api/7
You should be passing $form and $form_state (by reference) when using forms.
Taken from link above:
function my_module_example_form($form, &$form_state) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
function my_module_example_form_validate($form, &$form_state) {
// Validation logic.
}
function my_module_example_form_submit($form, &$form_state) {
// Submission logic.
}
Plus your menu hook should call drupal_get_form as the callback and your function name as the page arguements.
$items['sform'] = array(
'title' => 'My Form',
'page callback' => 'drupal_get_form',
'page arguments' => array('sform'),
'access arguments' => array('some rule'),
);
function MyModule_menu() {
$items['blah'] = array(
'title' = 'blah',
'page callback' => 'blah_page',
'type' => MENU_NORMAL_ITEM
);
$items['clickPath'] = array(
'title' => 'A title',
'page callback' => 'clickPath_page',
'type' => MENU_CALLBACK,
);
return $items;
}
function blah_page() {
$output = drupal_get_form(MyModule_form);
return $output;
}
function clickPath_page() {
return ('you clicked me!');
}
function MyModule_form($form,&$form_state) {
$output = '<div id="clickDiv">Click me</div>';
$form['blah'] = array(
'#type' => 'markup',
'#value' => $output,
'#ahah' => array(
'event' => 'click',
'path' => 'clickPath',
'wrapper' => 'clickDiv',
),
);
return $form;
}
Why won't the above work? Is it not possible to use ahah and events on form types of 'markup'? Do I have to use my own custom javascript?
You can stop reading here! I would like to end my sentences and question here, but stackoverflow is forcing me to input a minimum amount of characters. Apologies in advance!!!!
If you look at the Form API under "Special Elements" you can see that the #ahah attribute is not supported for the markup form type.
So I'm afraid you will have to roll your own JS in this case, or convert the markup element into a normal form element (which it doesn't look like will work for your purposes).
What I want to do is: I want to render a form on a page with a view. This view has a list of 'notes' (=CT Note). When you fill in the form, the note is stored, the form is cleared, and the new note is added to the list. All without page refreshes.
I create a module new_note, and addes this function:
function new_note_form($nodeid = NULL) {
ctools_include('ajax');
// drupal_add_js(drupal_get_path('module', 'custom_forms') . '/js/note_form.js');
//dpm($nodeid);
module_load_include('inc', 'node', 'node.pages');
$form = node_add('note');
$form['field_note_reference']['und']['#value'] = '2';
$form['field_note_reference']['und']['#validated'] = 'TRUE';
$form['field_note_reference']['#attributes']['class'][] = "hidden";
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
'#executes_submit_callback' => FALSE,
'#ajax' => array(
'callback' => 'ajax_note',
'wrapper' => 'status',
),
);
$output= drupal_render($form);
dpm($form);
print $output;
}
function ajax_note(&$form, &$form_state) {
return 'test';
}
I use this function in a display suite block field, which is rendered above the note list. So far so good.
The only problem is, that when I submit the form, the ajax is not called, and the normal submit is done.
Can anyone help me out
# Edit.
After what clive suggested I changed the code, and got the ajax working.
function new_notes_form($nodeid = NULL) {
global $user;
$node = (object) array(
'uid' => $user->uid,
'name' => (isset($user->name) ? $user->name : ''),
'type' => 'note',
'language' => LANGUAGE_NONE,
);
$form_state = array();
$form_state['build_info']['args'] = array($node);
form_load_include($form_state, 'inc', 'node', 'node.pages');
$form = drupal_build_form('note_node_form', $form_state);
$form['field_note_reference']['und']['#value'] = '2';
$form['field_note_reference']['#attributes']['class'][] = "hidden";
$form['submit'] = array(
'#type' => 'button',
'#value' => 'Submit',
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'ajax_note_replace',
'wrapper' => 'status',
),
);
return $form;
}
function ajax_note_replace(&$form, &$form_state) {
dpm("test");
dpm($form);
$output = '<h1>' . t('Hello World') . '</h1>';
// $node = node_load('6');
// $output .= drupal_render(node_view($node, $style = 'teaser', $options = array()));
ctools_include('ajax');
$commands = array();
$commands[] = ajax_command_prepend(".view-content", $output);
print ajax_render($commands); // this function exits.
exit;
}
#Clive, can you help me out with the rest ? I want to save the node on callback (if valid?). In the ajax callback my node-id is null because it is not stored yet? how can I validate and save the node, otherwise set the not valid form items to red as normal.
It's likely to be because you're sidestepping Drupal's proper methods for creating forms so the AJAX preprocessing won't be performed. If you have a look at drupal_get_form() (the function used pretty much exclusively to prepare a form in Drupal) you'll see it in turn calls drupal_build_form() which is what you need to do:
function new_note_form($form, &$form_state, $nodeid = NULL) {
$form_state['build_info']['args'] = array('note');
$form = drupal_build_form('node_add', $form_state);
$form['submit'] = array(
'#type' => 'button',
'#value' => 'Submit',
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'advanced_form_callback',
'wrapper' => 'status',
),
);
return $form;
}
echo render(drupal_get_form('new_note_form'));
I've changed the element from type submit to button because I find it works much better when you want to do some ajax processing, removed #executes_submit_callback, and added #limit_validation_errors which will stop the form from otherwise validating (I think that's what you were trying to do by setting #validated to TRUE but I might be wrong).
Hope that helps, it's untested but should give you a good place to start.