diff --git a/README.md b/README.md
index 2cfa861..f0c0e89 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,16 @@
# Madlib
+
+The madlib module uses the Drupal Form API to display text about Giraffes in a fun way.
+
+It is currently working with the minimum desired functionality. On both JS enabled clients and JS disabled clients.
+
+POSSIBLE ADDITIONS:
+
+* Errors output to screen on each element during ajax callback
+* Add AJAX to the submit button
+* Recognition (intelligence) of JS enabled clients versus JS disabled clients (possible form value)
+
+REFACTOR:
+
+* Separate user input ajax from submit ajax
+* Separate validation into two categories the entire form versus a single element
diff --git a/madlib.admin.inc b/madlib.admin.inc
new file mode 100644
index 0000000..df9a1ba
--- /dev/null
+++ b/madlib.admin.inc
@@ -0,0 +1,34 @@
+ 'checkbox',
+ '#title' => t('Debug mode'),
+ '#default_value' => variable_get('madlib_checkbox', 0),
+ '#description' => t('Turn on/off debug mode'),
+ );
+
+ return system_settings_form($form);
+}
+
+/**
+ * Madlib administration menu block page.
+ */
+function madlib_admin_menu_block_page() {
+ $build = array(
+ 'header_text' => array(
+ '#type' => 'markup',
+ '#markup' => '
' . l(t('Madlib Settings'), 'admin/config/madlib/settings') . '
',
+ ),
+ );
+ return $build;
+}
diff --git a/madlib.info b/madlib.info
index fa612f1..452a1d5 100644
--- a/madlib.info
+++ b/madlib.info
@@ -3,4 +3,4 @@ description = Madlib form
core = 7.x
package = Custom
-configure = admin/madlib
+configure = admin/config/madlib/settings
diff --git a/madlib.module b/madlib.module
index 886dc6c..f88ad62 100644
--- a/madlib.module
+++ b/madlib.module
@@ -10,19 +10,28 @@
function madlib_menu() {
$items = array();
- $items['admin/madlib'] = array(
+ $items['admin/config/madlib'] = array(
'title' => 'Madlib',
- 'description' => 'Madlib Settings',
+ 'description' => 'Settings for the Madlib module.',
+ 'page callback' => 'madlib_admin_menu_block_page',
+ 'access arguments' => array('administer madlib settings'),
+ 'file' => 'madlib.admin.inc',
+ 'file path' => drupal_get_path('module', 'madlib'),
+ );
+
+ $items['admin/config/madlib/settings'] = array(
+ 'title' => 'Madlib Settings',
+ 'description' => 'Settings for the Madlib module.',
'page callback' => 'drupal_get_form',
- 'page arguments' => array('madlib_admin'),
- 'access arguments' => array('administer settings'),
- 'type' => MENU_NORMAL_ITEM,
- 'expanded' => TRUE,
+ 'page arguments' => array('madlib_admin_settings'),
+ 'access arguments' => array('administer madlib settings'),
+ 'file' => 'madlib.admin.inc',
+ 'file path' => drupal_get_path('module', 'madlib'),
);
$items['madlib'] = array(
- 'title' => 'Madlib',
- 'description' => 'Madlib Skeleton Form',
+ 'title' => 'Have I got a Giraffe for You!',
+ 'description' => 'A madlib using drupal form api',
'page callback' => 'drupal_get_form',
'page arguments' => array('madlib_form'),
'access arguments' => array('view published content'),
@@ -45,19 +54,16 @@ function madlib_permission() {
}
/**
- * Page callback for administration settings.
+ * Implements hook_form_alter().
*/
-function madlib_admin() {
- $form = array();
-
- $form['madlib_checkbox'] = array(
- '#type' => 'checkbox',
- '#title' => t('Debug mode'),
- '#default_value' => variable_get('madlib_checkbox', 0),
- '#description' => t('Turn on/off debug mode'),
- );
-
- return system_settings_form($form);
+function madlib_form_alter(&$form, &$form_state, $form_id) {
+ if ($form_id == 'madlib_form') {
+ if (variable_get('madlib_checkbox', 0) == 1) {
+ $form['madlib_note'] = array(
+ '#markup' => '
DEBUG MODE: ON
',
+ );
+ }
+ }
}
/**
@@ -65,11 +71,23 @@ function madlib_admin() {
*/
function madlib_form($form, &$form_state) {
+ $form['madlib_ajax_status_messages'] = array(
+ '#type' => 'markup',
+ '#prefix' => '',
+ '#suffix' => '
',
+ );
+
$form['madlib_section_1_fieldset'] = array(
'#type' => 'fieldset',
'#title' => t('Section 1'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
+ '#attributes' => array('class' => array('madlib_hide_me')),
+ '#states' => array(
+ 'invisible' => array(
+ ':input[name="madlib_hidden"]' => array('value' => 'yes'),
+ ),
+ ),
);
$form['madlib_section_1_fieldset']['madlib_plural_noun_1_textfield'] = array(
@@ -79,6 +97,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_1_fieldset']['madlib_plural_noun_2_textfield'] = array(
@@ -88,6 +109,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_1_fieldset']['madlib_part_of_body_1_textfield'] = array(
@@ -97,6 +121,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_2_fieldset'] = array(
@@ -104,6 +131,12 @@ function madlib_form($form, &$form_state) {
'#title' => t('Section 2'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
+ '#attributes' => array('class' => array('madlib_hide_me')),
+ '#states' => array(
+ 'invisible' => array(
+ ':input[name="madlib_hidden"]' => array('value' => 'yes'),
+ ),
+ ),
);
$form['madlib_section_2_fieldset']['madlib_number_select'] = array(
@@ -123,6 +156,9 @@ function madlib_form($form, &$form_state) {
),
'#default_value' => variable_get('madlib_number_select', ''),
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_2_fieldset']['madlib_plural_noun_3_textfield'] = array(
@@ -132,6 +168,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_2_fieldset']['madlib_part_of_body_2_textfield'] = array(
@@ -141,6 +180,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_2_fieldset']['madlib_type_of_liquid_textfield'] = array(
@@ -150,6 +192,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_2_fieldset']['madlib_part_of_body_plural_textfield'] = array(
@@ -159,6 +204,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset'] = array(
@@ -166,25 +214,34 @@ function madlib_form($form, &$form_state) {
'#title' => t('Section 3'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
+ '#attributes' => array('class' => array('madlib_hide_me')),
+ '#states' => array(
+ 'invisible' => array(
+ ':input[name="madlib_hidden"]' => array('value' => 'yes'),
+ ),
+ ),
);
$form['madlib_section_3_fieldset']['madlib_part_of_body_3_select'] = array(
'#type' => 'select',
'#title' => t('Part of the body'),
'#options' => array(
- 'head' => array(
+ t('head') => array(
0 => t('eyes'),
1 => t('nose'),
),
- 'torso' => array(
- 0 => t('stomach'),
+ t('torso') => array(
+ 2 => t('stomach'),
),
- 'legs' => array(
- 0 => t('feet'),
+ t('legs') => array(
+ 3 => t('feet'),
),
),
'#default_value' => variable_get('madlib_part_of_body_3_select', ''),
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_adjective_1_textfield'] = array(
@@ -194,6 +251,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_plural_noun_4_textfield'] = array(
@@ -203,6 +263,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_adjective_2_textfield'] = array(
@@ -212,6 +275,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_adjective_3_textfield'] = array(
@@ -221,6 +287,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_verb_ing_textfield'] = array(
@@ -230,6 +299,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_noun_1_textfield'] = array(
@@ -239,6 +311,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_plural_noun_5_textfield'] = array(
@@ -248,6 +323,9 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_section_3_fieldset']['madlib_noun_2_textfield'] = array(
@@ -257,28 +335,212 @@ function madlib_form($form, &$form_state) {
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
+ '#ajax' => array(
+ 'callback' => 'madlib_form_ajax_user_input_callback',
+ ),
);
$form['madlib_submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
+ '#attributes' => array('class' => array('madlib_hide_me')),
+ '#states' => array(
+ 'invisible' => array(
+ ':input[name="madlib_hidden"]' => array('value' => 'yes'),
+ ),
+ ),
);
$form['madlib_note'] = array(
- '#markup' => 'Click it, you know you want to.
',
+ '#markup' => 'Click it, you know you want to.
',
+ '#states' => array(
+ 'invisible' => array(
+ ':input[name="madlib_hidden"]' => array('value' => 'yes'),
+ ),
+ ),
+ );
+
+ // For non-JS enabled clients we need to set this form element so that
+ // form states know what state the form is in (show / hide).
+ if ($form_state['rebuild'] == FALSE ||
+ (variable_get('madlib_checkbox', 0) == 1)) {
+ $form['madlib_hidden'] = array(
+ '#type' => 'hidden',
+ '#value' => 'no',
+ );
+ }
+ else {
+ $form['madlib_hidden'] = array(
+ '#type' => 'hidden',
+ '#value' => 'yes',
+ );
+
+ // Apparently we can't hide markup type so we set it equal to nothing.
+ $form['madlib_note'] = array();
+ }
+
+ // If JS is enabled we only need the div.
+ $form['madlib_output'] = array(
+ '#type' => 'markup',
+ '#prefix' => '',
+ '#suffix' => '
',
+ '#markup' => '',
+ '#states' => array(
+ 'visible' => array(
+ ':input[name="madlib_hidden"]' => array('value' => 'yes'),
+ ),
+ ),
);
+ // If JS is disabled output the madlib.
+ if ($form_state['rebuild'] == TRUE) {
+ $form['madlib_output']['#markup']
+ = madlib_form_output_text_with_t($form, $form_state);
+ }
+
+ // If JS is disabled and debug is off output the madlib and clear form array.
+ if ($form_state['rebuild'] == TRUE &&
+ variable_get('madlib_checkbox', 0) == 0) {
+
+ $form = array();
+ $form['madlib_output']['#markup']
+ = madlib_form_output_text_with_t($form, $form_state);
+ }
+
return $form;
}
+/**
+ * AJAX callback for user inputs.
+ *
+ * @return array
+ * Renderable array (the markup element)
+ */
+function madlib_form_ajax_user_input_callback($form, &$form_state) {
+
+ // If the form has not been rebuilt allow the user to enter
+ // data and change nothing.
+ if ($form_state['rebuild'] == TRUE) {
+
+ // Clear previous messages (error) or they pile up and display all at once.
+ drupal_get_messages();
+
+ // Validation function is NOT automatically called so we must call it.
+ // TODO: may be related to returning commands instead of part of a form.
+ madlib_form_validate($form, $form_state);
+ $errors = form_get_errors();
+
+ $commands = array();
+
+ // AJAX commands to run if the form did not pass validation.
+ if (!empty($errors)) {
+ $commands[] = ajax_command_replace('#madlib_output_div',
+ '');
+ }
+
+ // AJAX command to run if the form passed validation.
+ else {
+
+ // Passed validation and debug mode is ON.
+ if (variable_get('madlib_checkbox', 0) == 1) {
+ drupal_set_message(t('Answers received'));
+ }
+
+ // Passed validation and debug mode is OFF.
+ elseif (variable_get('madlib_checkbox', 0) == 0) {
+ drupal_set_message(t('Answers received'));
+ $commands[]
+ = ajax_command_css('.madlib_hide_me', array('display' => none));
+ }
+
+ // Common ajax commands for a validated form (no errors) and has been
+ // rebuilt at least once.
+ $commands[]
+ = ajax_command_replace('.messages', '');
+ $commands[]
+ = ajax_command_replace('#madlib_ajax_status_messages',
+ '' .
+ theme('status_messages') . '
');
+ $commands[]
+ = ajax_command_replace('#madlib_output_div',
+ madlib_form_output_text_with_t($form,
+ $form_state));
+ $commands[]
+ = ajax_command_invoke('input.error', 'removeClass', array('error'));
+ }
+ }
+
+ return array('#type' => 'ajax', '#commands' => $commands);
+}
+
/**
* Madlib validate handler.
*/
function madlib_form_validate($form, &$form_state) {
- $verb_ing = $form_state['values']['madlib_verb_ing_textfield'];
- if (strtolower(substr($verb_ing, strlen($verb_ing) - 3, 3)) != 'ing') {
- form_set_error('madlib_verb_ing_textfield',
+ $required_keys = array(
+ 'madlib_plural_noun_1_textfield',
+ 'madlib_plural_noun_2_textfield',
+ 'madlib_plural_noun_3_textfield',
+ 'madlib_plural_noun_4_textfield',
+ 'madlib_plural_noun_5_textfield',
+ 'madlib_part_of_body_1_textfield',
+ 'madlib_part_of_body_2_textfield',
+ 'madlib_part_of_body_3_select',
+ 'madlib_number_select',
+ 'madlib_type_of_liquid_textfield',
+ 'madlib_part_of_body_plural_textfield',
+ 'madlib_adjective_1_textfield',
+ 'madlib_adjective_2_textfield',
+ 'madlib_adjective_3_textfield',
+ 'madlib_verb_ing_textfield',
+ 'madlib_noun_1_textfield',
+ 'madlib_noun_2_textfield',
+ );
+
+ $valid_keys = $required_keys;
+ array_push($valid_keys,
+ 'madlib_ajax_status_messages',
+ 'madlib_submit',
+ 'madlib_note',
+ 'madlib_output',
+ 'madlib_hidden',
+ 'form_build_id',
+ 'form_token',
+ 'form_id',
+ 'op'
+ );
+
+ if (!empty($form_state['values']['madlib_verb_ing_textfield'])) {
+ $verb_ing = $form_state['values']['madlib_verb_ing_textfield'];
+
+ if (strtolower(substr($verb_ing, strlen($verb_ing) - 3, 3)) != 'ing') {
+ form_set_error('madlib_verb_ing_textfield',
'Verb_ing: Please enter a word that ends in "ing"');
+ }
+ }
+
+ foreach ($form_state['values'] as $form_item_key => $value) {
+
+ $plain_form_item_key = check_plain($form_item_key);
+ $plain_value = check_plain($value);
+
+ if (in_array($plain_form_item_key, $valid_keys)) {
+
+ if ($plain_value <> $value) {
+ form_set_error($plain_form_item_key,
+ $plain_form_item_key . ': A form value should not contain anything other than plain text');
+ }
+
+ if (in_array($plain_form_item_key, $required_keys)) {
+ if ($plain_value == '') {
+ form_set_error($plain_value,
+ $plain_form_item_key . ': is a required text field, please enter a value');
+ }
+ }
+ }
+ else {
+ form_set_error($plain_form_item_key, $plain_form_item_key . ': Form key not recognized');
+ }
}
}
@@ -289,3 +551,108 @@ function madlib_form_submit($form, &$form_state) {
drupal_set_message(t('Answers received'));
$form_state['rebuild'] = TRUE;
}
+
+/**
+ * Madlib form output text in the t().
+ */
+function madlib_form_output_text_with_t($form, &$form_state) {
+
+ // CYA for logic flaws, if this function is called with errors return nothing.
+ madlib_form_validate($form, $form_state);
+ $errors = form_get_errors();
+ if (!empty($errors)) {
+ return;
+ }
+
+ if (empty($form_state['values']['madlib_plural_noun_1_textfield'])) {
+ return;
+ }
+
+ // Find selected body part value.
+ $body_part_text_value = '';
+
+ $body_part_options
+ = $form_state['complete form']['madlib_section_3_fieldset']['madlib_part_of_body_3_select']['#options'];
+
+ foreach ($body_part_options as $array) {
+ foreach ($array as $body_part => $text_value) {
+ if ($body_part == $form_state['values']['madlib_part_of_body_3_select']) {
+ $body_part_text_value = $text_value;
+ }
+ }
+ }
+
+ // Correct a/an to a or an.
+ // Technically this isn't 100% correct but it is better than before.
+ $vowels = array('a', 'e', 'i', 'o', 'u');
+
+ $madlib_adjective_2_textfield_a_an = '';
+ if (in_array(substr(check_plain($form_state['values']['madlib_adjective_2_textfield']), 0, 1), $vowels)) {
+ $madlib_adjective_2_textfield_a_an = 'a';
+ }
+ else {
+ $madlib_adjective_2_textfield_a_an = 'an';
+ }
+
+ $madlib_adjective_3_textfield_a_an = '';
+ if (in_array(substr(check_plain($form_state['values']['madlib_adjective_3_textfield']), 0, 1), $vowels)) {
+ $madlib_adjective_3_textfield_a_an = 'a';
+ }
+ else {
+ $madlib_adjective_3_textfield_a_an = 'an';
+ }
+
+ // For cleaner code create two variables.
+ $madlib_number_select_value = $form_state['values']['madlib_number_select'];
+ $madlib_number_select
+ = $form_state['complete form']['madlib_section_2_fieldset']['madlib_number_select']['#options'][$madlib_number_select_value];
+
+ // Generate the text using the t().
+ $output
+ = '' .
+ t(
+ 'Giraffes have aroused the curiousity of @madlib_plural_noun_1_textfield
+ since earliest times. The giraffe is the tallest of all living @madlib_plural_noun_2_textfield
+ , but scientists are unable to explain how it got its long @madlib_part_of_body_1_textfield
+ . The giraffe\'s tremendous height, which might reach @madlib_number_select
+ @madlib_plural_noun_3_textfield
+ , comes mostly from its legs and @madlib_part_of_body_2_textfield
+ . If a giraffe wants to take a drink of @madlib_type_of_liquid_textfield
+ from the ground, it has @madlib_part_of_body_plural_textfield
+ far apart in order to reach down and lap up the water with its huge @body_part_text_value
+ . The giraffe has @madlib_adjective_1_textfield
+ ears that are sensitive to the faintest @madlib_plural_noun_4_textfield
+ , and it has @madlib_adjective_2_textfield_a_an @madlib_adjective_2_textfield
+ sense of smell and sight. When attacked,
+ a giraffe can put up @madlib_adjective_2_textfield_a_an @madlib_adjective_3_textfield
+ fight by @madlib_verb_ing_textfield
+ out with its hind legs and using its head like a sledge @madlib_noun_1_textfield
+ . Finally, a giraffe can gallop at more than thirty @madlib_plural_noun_5_textfield
+ an hour when pursued and can outrun the fastest @madlib_noun_2_textfield
+ .',
+ array(
+ '@madlib_plural_noun_1_textfield' => $form_state['values']['madlib_plural_noun_1_textfield'],
+ '@madlib_plural_noun_2_textfield' => $form_state['values']['madlib_plural_noun_2_textfield'],
+ '@madlib_part_of_body_1_textfield' => $form_state['values']['madlib_part_of_body_1_textfield'],
+ '@madlib_number_select' => $madlib_number_select,
+ '@madlib_plural_noun_3_textfield' => $form_state['values']['madlib_plural_noun_3_textfield'],
+ '@madlib_part_of_body_2_textfield' => $form_state['values']['madlib_part_of_body_2_textfield'],
+ '@madlib_type_of_liquid_textfield' => $form_state['values']['madlib_type_of_liquid_textfield'],
+ '@madlib_part_of_body_plural_textfield' => $form_state['values']['madlib_part_of_body_plural_textfield'],
+ '@body_part_text_value' => $body_part_text_value,
+ '@madlib_adjective_1_textfield' => $form_state['values']['madlib_adjective_1_textfield'],
+ '@madlib_plural_noun_4_textfield' => $form_state['values']['madlib_plural_noun_4_textfield'],
+ '@madlib_adjective_2_textfield_a_an' => $madlib_adjective_2_textfield_a_an,
+ '@madlib_adjective_2_textfield' => $form_state['values']['madlib_adjective_2_textfield'],
+ '@madlib_adjective_3_textfield_a_an' => $madlib_adjective_3_textfield_a_an,
+ '@madlib_adjective_3_textfield' => $form_state['values']['madlib_adjective_3_textfield'],
+ '@madlib_verb_ing_textfield' => $form_state['values']['madlib_verb_ing_textfield'],
+ '@madlib_noun_1_textfield' => $form_state['values']['madlib_noun_1_textfield'],
+ '@madlib_plural_noun_5_textfield' => $form_state['values']['madlib_plural_noun_5_textfield'],
+ '@madlib_noun_2_textfield' => $form_state['values']['madlib_noun_2_textfield'],
+ )
+ ) .
+ '
';
+
+ return $output;
+}