Drupal 7 - Form Api ajax callback causes Synchronous XMLHttpRequest deprecation - php

I have two forms on my Drupal page, one form is populating its fields when value of the first form is changed (when you choose an item from a select box). It seems to work fine, untill I try to submit the form, which won't do much, since in my browser it says this error:
[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
<?php
function my_form($form, &$form_state) {
$form['form_1'] = [
'#type' => 'fieldset',
'#title' => "Select box",
'#collapsible' => FALSE,
'#collapsed' => FALSE,
];
$form['form_1']['id'] = [
'#title' => t('Choose:') ,
'#type' => 'select',
'#options' => [
'1' => 'ONE',
'2' => 'TWO',
'3' => 'THREE'
],
'#required' => '1',
'#ajax' => [
'callback' => 'my_form_state_ajax_callback',
'wrapper' => 'form_edit',
],
];
//--------
$form['form_2'] = [
'#type' => 'fieldset',
'#title' => "This is form",
'#collapsible' => FALSE,
'#collapsed' => FALSE,
'#prefix' => '<div id ="form_edit">',
'#suffix' => '</div>',
];
$form['form_2']['name'] = [
'#type' => 'textfield',
'#title' => 'Name',
'#required' => TRUE,
];
$form['form_2']['button'] = [
'#type' => 'submit',
'#value' => "Create",
'#submit' => ['my_form_submit'],
];
return $form;
}
function my_form_state_ajax_callback($form, &$form_state) {
$values = $form_state['values'];
$id = $values['id'];
if($id > 0) {
$form['form_2']['name']['#value'] = "this works!";
} else {
if(isset($form['form_2']['name']['#value'])) unset($form['form_2']['name']['#value']);
}
return $form['form_2'];
}
How to fix this error? It doesn't really matter what is inside the callback function, it can be empty and the error will still occur.. What am I doing wrong?

Related

Drupal 7: how do I save module settings?

I am trying to create some settings for a module and am following the guide on Drupal.org. I am also comparing my work to existing modules.
The config menu appears in the correct place with the correct fields but when I hit save no input is saved. (I have run cache clear and registry rebuild.)
Would anyone know what I am doing wrong here? I cannot see how my stuff differs.
On my .admin.inc file I have set the form as such:
function contact_page_settings() {
$form = array();
$config = contact_page_default_settings();
$form['#tree'] = TRUE;
$form['contact_page_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Top Section'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'top-title' => array(
'#type' => 'textfield',
'#title' => t('Top title'),
'#default_value' => !empty($config['top-title']) ? $config['top-title'] : '',
),
'top-left' => array(
'#type' => 'text_format',
'#title' => t('Top left'),
'#default_value' => !empty($config['top-left']) ? $config['top-left'] : '',
),
'top-right' => array(
'#type' => 'text_format',
'#title' => t('Top right'),
'#default_value' => !empty($config['top-right']) ? $config['top-right'] : '',
),
);
return system_settings_form($form);
}
On my .module file I have:
function contact_page_menu() {
$items = array();
$items['admin/settings/contact-page'] = array(
'title' => 'Contact Page content',
'page callback' => 'drupal_get_form',
'access arguments' => array('administer site configuration'),
'page arguments' => array('contact_page_settings'),
'type' => MENU_NORMAL_ITEM,
'file' => '/admin/contact_page.admin.inc',
);
return $items;
}
function contact_page_default_settings() {
$defaults = array(
'top-tile' => 'Top title',
'top-left' => 'Top left',
'top-right' => 'Top right',
);
$config = variable_get('contact_page_settings', array());
return array_merge($defaults, $config);
}
OK, so I found out the values were saving - just they were not appearing in my text areas when I reloaded the config page.
The problem was that I was using text_format fields which save data as an array. I needed to get the value property of that array as my default value.
So, I just added ['value'] to the default_value ternary expression:
'#default_value' => !empty($config['top-right']['value']) ? $config['top-right']['value'] : '',

Autocomplete function in drupal

I have a function autocomplete like this:
function find_noreff_auto($string=NULL){
$matches = array();
db_set_active('data');
$result = db_query("SELECT * FROM reffnum where LOWER(noreff) LIKE LOWER('%%$string%%') AND journaled='0' AND noreff NOT IN (SELECT noreff from tmpreffnum) ORDER BY noreff ASC");
while ($row=db_fetch_object($result) )
{
$matches[$row->noreff.'-'.number_format($row->nominal,2)] = t($row->noreff.': '.number_format($row->nominal, 2));
}
drupal_json($matches);
drupal_set_message($matches);
}
This function:
1. If I write some character, it search from reffnum the noreff value
2. If I select one value, it give me result like this: NOREFF123 - 1.000,00
And this is the form:
$form['input']['noreff10'] = array(
'#type' => 'textfield',
'#title' => t('No Reff10'),
'#size' => 60,
'#default_value' => $noreff10,
'#description' => 'Nominal from '.$noreff10.' is '.$nominalnoreff10,
'#autocomplete_path' =>'noreff/autocomplete',
'#ahah' => array(
'event' => 'change',
'path' => ahah_helper_path(array('inputan')),
'wrapper' => 'inputan-wrapper',
'method' => 'replace',
'progress' => 'throbber',
),
'#prefix' => '<div class="s-form">', '#suffix' => '</div>',
);
I want $nominalnoreff10. What should I have to do?
$nominalnoreff10 = $noreff10['nominal']; doesn't give me the value.

Drupal custom form remembering textfield data

I am setting up a configuration page for a new module and I am having trouble getting my textfield to remember data I previously entered.
I am setting #default_value by calling variable_get but the value never gets reset in the textfield. It is however correctly stored as a variable and visible on the variable editor page.
Below is a code fragment:
$form = array();
$form['username'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#default_value' => variable_get('username', '' ),
'#description' => t('supply the username'),
'#maxlength' => 30,
'#required' => TRUE,
'#weight' => -1,
);
return system_settings_form($form);
How can I fix this?
Updated code
The submit function is as follows:
function mymodule_settings_submit($form, &$form_state){
drupal_set_message('form submit responding : ' . $form_state['values']['username'] );
variable_set( 'username', $form_state['values']['username'] );
}
Updated code #2
The full code:
function my_module_init(){
}
function my_module_menu(){
$items = array();
$items['admin/settings/helper'] = array(
'title' => 'helper',
'page callback' => 'drupal_get_form',
'page arguments' => array('helper_setup'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function helper_setup(){
$node_types = node_get_types('names');
$form = array();
$form['username'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#default_value' => variable_get('username', '' ),
'#description' => t('supply the username'),
'#maxlength' => 30,
'#required' => TRUE,
'#weight' => -1,
);
$form['#submit'][] = 'my_module_settings_submit';
return system_settings_form($form);
}
function my_module_validate($form, &$form_state){
die('validation area responding!');
}
function my_module_settings_submit($form, &$form_state){
drupal_set_message('form submit responding : ' . $form_state['values']['username'] );
variable_set( 'username', $form_state['values']['username'] );
}
in your form submit function you should insert variable_set('variableName' , 'value') variables is not inserted automatically..
UPDATE:
$form['username'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#default_value' => variable_get('username', '' ),
'#description' => t('supply the username'),
'#maxlength' => 30,
'#required' => TRUE,
'#weight' => -1,
);
$form['#submit'][] = '_myform_submit_function' ;
return system_settings_form($form);
now lets build your submit function
function _myform_submit_function($form,&$form_state ) {
variable_set('username', $form_state['values']['username']) ;
drupal_set_message('form submit responding : ' . $form_state['values']['username'] );
}
now clear the cache and tell me if its working or not

Theming a form in Drupal which has to be a part of an Entity's Content

I've a form in my module (mymodule)...
function mymodule_form()
{
$form['mytext'] = array(
'#title' => 'Password',
'#type' => 'password',
'#size' => 10,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Cool!',
);
$form['cool_submit'] = array(
'#type' => 'submit',
'#value' => 'Cool Submit!',
);
return $form;
}
I've used the hook_entity_view hook to display this form under all drupal entities that are displayed.
function mymodule_entity_view($entity, $type, $view_mode, $langcode) {
$entity->content['myadditionalfield'] = mymodule_form();
}
When showing this form, drupal adds a DIV tag to the mytext (password field) by itself. I want to override this and provide my own DIV tags and theme to this form. How do I do it?
Thanks :-)
I worked further on this question to solve it. And the problem got solved. I changed the above code...
function mymodule_entity_view($entity, $type, $view_mode, $langcode) {
$element = array(
'start' => array(
'#type' => 'button',
'#name' => 'start',
'#button_type' => 'submit',
),
'my_text' => array(
'#type' => 'textfield',
'#size' => 30,
'#maxlength' => 50,
),
'my_submit' => array(
'#type' => 'button',
'#name' => 'Submit Discussion',
'#button_type' => 'submit',
),
);
$entity->content['disc_bar'] = $element;
}
And the problem kept creeping up whenever a textfield or a password field was rendered. I checked the type array in systems elements info function (a elements_info hook) and found that textfield and password fields come with a default value for the #theme-wrapper. I tried to override it by this way...
'my_text' => array(
'#type' => 'textfield',
'#size' => 30,
'#maxlength' => 50,
'#theme-wrapper' => '',
),
and It worked. Its not generating any additional division tags... :-)

Drupal: How to Render Results of Form on Same Page as Form

How would I print the results of a form submission on the same page as the form itself?
Relevant hook_menu:
$items['admin/content/ncbi_subsites/paths'] = array(
'title' => 'Paths',
'description' => 'Paths for a particular subsite',
'page callback' => 'ncbi_subsites_show_path_page',
'access arguments' => array( 'administer site configuration' ),
'type' => MENU_LOCAL_TASK,
);
page callback:
function ncbi_subsites_show_path_page() {
$f = drupal_get_form('_ncbi_subsites_show_paths_form');
return $f;
}
Form building function:
function _ncbi_subsites_show_paths_form() {
// bunch of code here
$form['subsite'] = array(
'#title' => t('Subsites'),
'#type' => 'select',
'#description' => 'Choose a subsite to get its paths',
'#default_value' => 'Choose a subsite',
'#options'=> $tmp,
);
$form['showthem'] = array(
'#type' => 'submit',
'#value' => 'Show paths',
'#submit' => array( 'ncbi_subsites_show_paths_submit'),
);
return $form;
}
Submit function (skipped validate function for brevity)
function ncbi_subsites_show_paths_submit( &$form, &$form_state ) {
//dpm ( $form_state );
$subsite_name = $form_state['values']['subsite'];
$subsite = new Subsite( $subsite_name ); //y own class that I use internally in this module
$paths = $subsite->normalized_paths;
// build list
$list = theme_item_list( $paths );
}
If I print that $list variable, it is exactly what I want, but I am not sure how to get it into the page with the original form page built from 'ncbi_subsites_show_path_page'. Any help is much appreciated!
The key information in the link Nikit posted is $form_state['rebuild']. Here's some info from Drupal 7 documentation that I believe applies the same for Drupal 6...
$form_state['rebuild']: Normally, after the entire
form processing is completed and
submit handlers ran, a form is
considered to be done and
drupal_redirect_form() will redirect
the user to a new page using a GET
request (so a browser refresh does not
re-submit the form). However, if
'rebuild' has been set to TRUE, then a
new copy of the form is immediately
built and sent to the browser; instead
of a redirect. This is used for
multi-step forms, such as wizards and
confirmation forms. Also, if a form
validation handler has set 'rebuild'
to TRUE and a validation error
occurred, then the form is rebuilt
prior to being returned, enabling form
elements to be altered, as appropriate
to the particular validation error.
This is a full working example of a page and a list on the same page
<?php
/*
* Implements hook_mennu()
*/
function test_menu() {
$items['test'] = array(
'title' => t('Test'),
'page callback' => 'test_search_page',
'access callback' => True,
);
return $items;
}
function test_search_page(){
$form = drupal_get_form('test_search_form');
return $form;
}
function test_search_form($form, &$form_state){
$header = array(t('id'), t('name'), t('firstname'));
$rows = Null;
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#required' => True,
'#default_value' => isset($_GET['name']) ? $_GET['name'] : Null
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('submit'),
);
if (isset($_GET['name'])){
$rows = get_data();
}
$form['table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => t('Aucun résultat.')
);
$form['pager'] = array('#markup' => theme('pager'));
/*
if (isset($form_state['table'])) {
$form['table'] = $form_state['table'];
}
$form['pager'] = array('#markup' => theme('pager'));
*/
return $form;
}
function test_search_form_submit($form, &$form_state){
$form_state['redirect'] = array(
// $path
'test',
// $options
array('query' => array('name' => $form_state['values']['name'])),
// $http_response_code
302,
);
}
//$header = array(t('id'), t('name'), t('firstname'));
function get_data(){
$data = array(
0 => array(
'id' => '0',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
1 => array(
'id' => '1',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
2 => array(
'id' => '2',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
3 => array(
'id' => '3',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
4 => array(
'id' => '4',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
5 => array(
'id' => '5',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
6 => array(
'id' => '6',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
7 => array(
'id' => '7',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
8 => array(
'id' => '8',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
9 => array(
'id' => '9',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
10 => array(
'id' => '10',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
),
11 => array(
'id' => '11',
'name' => 'pokpokpok',
'firstname' => 'pokpokpok',
)
);
$paging = pager_array_splice($data, 2);
return $paging;
}
/*
$header = array(t('id'), t('name'), t('firstname'));
$form_state['table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $paging,
'#empty' => t('Aucun r?sultat.')
);
$form_state['rebuild'] = True;*/
function pager_array_splice($data, $limit = 9, $element = 0) {
global $pager_page_array, $pager_total, $pager_total_items;
$page = isset($_GET['page']) ? $_GET['page'] : '';
// Convert comma-separated $page to an array, used by other functions.
$pager_page_array = explode(',', $page);
// We calculate the total of pages as ceil(items / limit).
$pager_total_items[$element] = count($data);
$pager_total[$element] = ceil($pager_total_items[$element] / $limit);
$pager_page_array[$element] = max(0, min((int)$pager_page_array[$element], ((int)$pager_total[$element]) - 1));
return array_slice($data, $pager_page_array[$element] * $limit, $limit, TRUE);
}
Drupal6 node.module and dblog.module do this for admin/content/node and admin/reports/dblog by providing a page callback which includes the rendered form in its output.
modules/dblog/dblog.admin.inc
dblog_overview()
modules/node/node.admin.inc
node_admin_nodes()
In form submit, updated filter settings are stored in $_SESSION.
In the page callback it renders the results based on the filter settings stored in $_SESSION.
$_SESSION is just another global here (albeit a persistent one).
For Drupal7 I find that if you use $form_state['rebuild'], then the form variables can be best accessed from the PHP super-global variable $_POST (or $_REQUEST). However, if you use $form_state['redirect'], the solution with $_SESSION is better (instead of using $_GET or $_REQUEST).
I find this issue quite tricky even for experts. Maybe Drupal has some more easy and intuitive way that we don't know.
For Drupal 8, if you have a form implementing FormBase I found I needed to set the form to be rebuilt to allow using the form state during render of the form after a successful form submission:
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->setRebuild(TRUE);
}
By default, the form will submit and process the form, then redirect, then build the form again and at that point you don't have the form state (unless you've passed the form state as part of a query parameter in the redirect).

Categories