Skip to content
This repository was archived by the owner on Mar 4, 2019. It is now read-only.

Commit 1bc2430

Browse files
unknownunknown
authored andcommitted
Following Changes made:
1. select field name is made configurable 2. sample module is renamed as example 3. Readme file contents are improved
1 parent 3a61744 commit 1bc2430

File tree

8 files changed

+187
-81
lines changed

8 files changed

+187
-81
lines changed

README.txt

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,81 @@
1-
Custom form field comprising chain of dependent select fields
2-
that can be plugged into Drupal forms programmatically.
1+
CONTENTS OF THIS FILE
2+
---------------------
3+
* Introduction
4+
* Requirements
5+
* Installation
6+
* Usage
7+
8+
INTRODUCTION
9+
------------
10+
This module helps adding a custom form field comprising chain of dependent
11+
select fields that can be plugged into Drupal forms pro-grammatically.
12+
This module is for developers only.
13+
14+
15+
REQUIREMENTS
16+
------------
17+
This module does not require any additional module as pre-requisites
18+
19+
20+
INSTALLATION
21+
------------
22+
Install as you would normally install a contributed Drupal module. See:
23+
https://drupal.org/documentation/install/modules-themes/modules-7
24+
for further information.
25+
26+
27+
USAGE
28+
-----
29+
30+
Fieldset Configuration
31+
----------------------
32+
33+
* #type: (String) Should be set to 'ajax_chain_select'.
34+
* #title: (String) The title of the fieldset. Default is empty string.
35+
* #config: (2-D Array) Select fields configuration (explained below).
36+
* #required_levels: (Integer) Till which level the selection is mandatory.
37+
E.g: if #required_levels is set to 2, the first 2 levels will be mandatory
38+
and rest will be optional. Default is 0 (zero).
39+
* #show_throbber: (Boolean) Whether to show throbber or not. Default is TRUE.
40+
* #progress_message: (String) The message to be shown with throbber.
41+
Default is 'Please wait..'
42+
* #data_callback: (String) A valid function name that takes the previous
43+
level selection and returns an array of next level elements.
44+
Refer to example module for better understanding.
45+
46+
E.g:
47+
48+
$form['region'] = array(
49+
'#type' => 'ajax_chain_select',
50+
'#title' => t('Region'),
51+
'#config' => $config,
52+
'#required_levels' => 3,
53+
'#show_throbber' => TRUE,
54+
'#progress_message' => t('Please wait..'),
55+
'#data_callback' => 'my_data_callback',
56+
);
57+
58+
Select Fields Configuration
59+
---------------------------
60+
Select fields configuration can be set using a 2-D array, where key represent
61+
the select field name and the value array represent its configuration as
62+
follows:
63+
64+
* #title:: (String) The title of the select field. Default is empty string.
65+
* #title_display: (String) The tile display of select field. Default is 'before'.
66+
* #empty_option: (String) The empty option to be shown when no value is selected. Default is '- Select -'.
67+
* #default_value: (Integer) The value for pre-selection. Default is NULL.
68+
69+
E.g:
70+
71+
$config = array(
72+
'country' => array(
73+
'#title' => t("Country"),
74+
'#empty_option' => 'Select Country',
75+
'#default_value' => 1,
76+
'#title_display' => 'before',
77+
),
78+
'state' => array(
79+
'#title' => t("State"),
80+
),
81+
);

ajax_chain_select.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
$("select.ajax-chain-select-select", context).change(function() {
1010
var current_el = this,
1111
parent_fieldset = $(current_el).parents('fieldset'),
12-
current_level = $(current_el).attr('level'),
1312
fieldset_settings = settings['ajax_chain_select'][$(parent_fieldset).attr('id')],
1413
current_level_id = this.value,
1514
url = Drupal.settings.basePath + 'ajax_chain_select/callback/',
@@ -18,7 +17,7 @@
1817
next_el = $(next_all[0]),
1918
dc = null,
2019
dch = null,
21-
next_level = (current_level * 1) + 1;
20+
next_level = next_el.find('select').attr('level');
2221

2322
for (var $i = 1; $i < next_all.length; $i++) {
2423
var next_ptr = $(next_all[$i]);

ajax_chain_select.module

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,20 @@ function ajax_chain_select_menu() {
2424
* Implements hook_element_info().
2525
*/
2626
function ajax_chain_select_element_info() {
27-
$elements['ac_select'] = array(
27+
$elements['ajax_chain_select'] = array(
2828
"#input" => TRUE,
29-
"#process" => array('ajax_chain_select_element_ac_select'),
29+
"#process" => array('ajax_chain_select_element_process'),
3030
);
3131
return $elements;
3232
}
3333

3434
/**
3535
* Process callback for ac_select.
3636
*/
37-
function ajax_chain_select_element_ac_select($element, &$form_state, $form) {
37+
function ajax_chain_select_element_process($element, &$form_state, $form) {
3838

3939
$element_name = $element['#name'];
4040
$config = !empty($element['#config']) ? $element['#config'] : array();
41-
$levels = !empty($element['#levels']) ? $element['#levels'] : 1;
4241
$required_levels = !empty($element['#required_levels']) ? $element['#required_levels'] : 0;
4342
$data_callback = !empty($element['#data_callback']) ? $element['#data_callback'] : '';
4443
$settings = array(
@@ -66,11 +65,12 @@ function ajax_chain_select_element_ac_select($element, &$form_state, $form) {
6665
'#type' => 'fieldset',
6766
'#tree' => TRUE,
6867
'#id' => !empty($element['#id']) ? $element['#id'] : drupal_html_id('edit-' . implode('-', $element['#parents'])),
69-
'#title' => !empty($element['#title']) ? $element['#title'] : array(),
68+
'#title' => !empty($element['#title']) ? $element['#title'] : '',
69+
'#title_display' => !empty($element['#title_display']) ? $element['#title_display'] : 'before',
7070
'#array_parents' => array(),
7171
'#element_validate' => array('ajax_chain_select_custom_validate'),
7272
'#states' => !empty($element['#states']) ? $element['#states'] : array(),
73-
'#levels' => $levels,
73+
'#config' => $config,
7474
'#data_callback' => $data_callback,
7575
);
7676

@@ -79,53 +79,62 @@ function ajax_chain_select_element_ac_select($element, &$form_state, $form) {
7979
'data' => array('ajax_chain_select' => array($region_element[$element_name]['#id'] => $settings)),
8080
);
8181

82-
for ($level = 0; $level < $levels; $level++) {
8382

84-
$previous_level = $level - 1;
83+
$index = 0;
84+
$levels_count = count($config);
85+
$levels = array_keys($config);
86+
$previous_level = $levels[0];
87+
$previous_level_config = $config[$previous_level];
88+
89+
foreach ($config as $level => $level_config) {
8590
$data = array();
8691

87-
switch ($level) {
92+
switch ($index) {
8893
case 0:
8994
$data = $data_callback($level);
9095
break;
9196

9297
default:
9398
if ($is_submitted) {
94-
if (!empty($submitted_values['level_' . $previous_level])) {
95-
$data = $data_callback($level, $submitted_values['level_' . $previous_level]);
99+
if (!empty($submitted_values[$previous_level])) {
100+
$data = $data_callback($level, $submitted_values[$previous_level]);
96101
}
97102
}
98103
else {
99-
if (!empty($config[$previous_level]['#default_value'])) {
100-
$data = $data_callback($level, $config[$previous_level]['#default_value']);
104+
if (!empty($previous_level_config['#default_value'])) {
105+
$data = $data_callback($level, $previous_level_config['#default_value']);
101106
}
102107
}
103108
break;
104109
}
105110

106111
// Default value must be part of data of that level, if not, nullify it.
107-
if (!empty($config[$level]['#default_value']) && !in_array($config[$level]['#default_value'], array_keys($data))) {
108-
unset($config[$level]['#default_value']);
112+
if (!empty($level_config['#default_value']) && !in_array($level_config['#default_value'], array_keys($data))) {
113+
unset($level_config['#default_value']);
109114
}
110115

111-
$region_element[$element_name]['level_' . $level] = array(
116+
$region_element[$element_name][$level] = array(
112117
'#type' => 'select',
113118
'#options' => $data,
114-
'#title' => !empty($config[$level]['#title']) ? $config[$level]['#title'] : 'Level ' . ($level + 1),
115-
'#empty_option' => !empty($config[$level]['#empty_option']) ? $config[$level]['#empty_option'] : '- Select -',
116-
'#required' => ($level < $required_levels) ? TRUE : FALSE,
119+
'#title' => !empty($level_config['#title']) ? t($level_config['#title']) : '',
120+
'#empty_option' => !empty($level_config['#empty_option']) ? $level_config['#empty_option'] : t('- Select -'),
121+
'#required' => ($index < $required_levels) ? TRUE : FALSE,
117122
'#validated' => TRUE,
118-
'#default_value' => !empty($config[$level]['#default_value']) ? $config[$level]['#default_value'] : NULL,
119-
'#title_display' => !empty($config[$level]['#title_display']) ? $config[$level]['#title_display'] : 'before',
123+
'#default_value' => !empty($level_config['#default_value']) ? $level_config['#default_value'] : NULL,
124+
'#title_display' => !empty($level_config['#title_display']) ? $level_config['#title_display'] : 'before',
120125
'#disabled' => (empty($data)) ? TRUE : FALSE,
121-
);
126+
'#attributes' => array('level' => $level)
127+
);
122128

123-
if ($level != $levels - 1) {
124-
$region_element[$element_name]['level_' . $level]['#attributes']['level'] = $level;
125-
$region_element[$element_name]['level_' . $level]['#attributes']['class'] = array('ajax-chain-select-select', 'ajax-progress-throbber');
129+
if ($index != $levels_count - 1) {
130+
$region_element[$element_name][$level]['#attributes']['class'] = array('ajax-chain-select-select');
126131
}
127-
}
128132

133+
$index++;
134+
$previous_level = $level;
135+
$previous_level_config = $level_config;
136+
}
137+
129138
$region_element[$element_name]['dc'] = array(
130139
'#type' => 'textfield',
131140
'#value' => base64_encode($element['#data_callback']),
@@ -147,28 +156,33 @@ function ajax_chain_select_element_ac_select($element, &$form_state, $form) {
147156
function ajax_chain_select_custom_validate(&$element, &$form_state, $form) {
148157
$values = $form_state['values'];
149158
$data_callback = $element['#data_callback'];
150-
$levels = $element['#levels'];
159+
$config = $element['#config'];
151160

152-
for ($level = 0; $level < $levels; $level++) {
161+
$index = 0;
162+
$levels = array_keys($config);
163+
$previous_level = $levels[0];
153164

154-
$previous_level = $level - 1;
165+
foreach ($config as $level => $level_config) {
155166

156-
if ($level > 0) {
157-
$data = $data_callback($level, $values['region']['level_' . $previous_level]);
167+
if ($index > 0) {
168+
$data = $data_callback($level, $values['region'][$previous_level]);
158169

159170
if (!empty($data)) {
160171

161-
if (empty($element['level_' . $level]['#options'])) {
162-
$element['level_' . $level]['#options'] = $data;
172+
if (empty($element[$level]['#options'])) {
173+
$element[$level]['#options'] = $data;
163174
}
164-
$element['level_' . $level]['#validated'] = FALSE;
165-
_form_validate($element['level_' . $level], $form_state);
175+
$element[$level]['#validated'] = FALSE;
176+
_form_validate($element[$level], $form_state);
166177
}
167178
}
168179
else {
169-
$element['level_' . $level]['#validated'] = FALSE;
170-
_form_validate($element['level_' . $level], $form_state);
180+
$element[$level]['#validated'] = FALSE;
181+
_form_validate($element[$level], $form_state);
171182
}
183+
184+
$index++;
185+
$previous_level = $level;
172186
}
173187
}
174188

@@ -178,7 +192,7 @@ function ajax_chain_select_custom_validate(&$element, &$form_state, $form) {
178192
function ajax_chain_select_element_callback($level = 1, $previous_level_key = 0, $dc = NULL, $dch = NULL) {
179193
$has_data = '0';
180194
$data_callback = '';
181-
$options = array();
195+
$options = '';
182196

183197
if (!empty($dc)) {
184198
$dc2 = base64_decode($dc);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
INTRODUCTION
2+
------------
3+
This module shows an example of how to use ajax chain select.
4+
5+
6+
REQUIREMENTS
7+
------------
8+
This module does not require any additional module as pre-requisites
9+
10+
11+
INSTALLATION
12+
------------
13+
Install as you would normally install a contributed Drupal module. See:
14+
https://drupal.org/documentation/install/modules-themes/modules-7
15+
for further information.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name = Ajax Chain Select Example
2+
description = "Example module for showing the use of Ajax Chain Select"
3+
package = Form Elements
4+
core = 7.x
5+
dependencies[] = ajax_chain_select

0 commit comments

Comments
 (0)