Index: dependent.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/dependent/dependent.js,v retrieving revision 1.5.2.2 diff -u -p -r1.5.2.2 dependent.js --- dependent.js 14 Oct 2009 15:42:36 -0000 1.5.2.2 +++ dependent.js 2 Dec 2009 16:58:53 -0000 @@ -1,110 +1,67 @@ Drupal.behaviors.dependentFields = function(context) { - if(!Drupal.settings.dependentfield || !$(Drupal.settings.dependentfield).length) { + if (!Drupal.settings.dependentfields || !$(Drupal.settings.dependentfields).length) { return; } - jQuery.each(Drupal.settings.dependentfield, function(key, value) { - $('select[name^='+key+'], input[name^='+key+']').checkDependentFields(); - $('select[name^='+key+'], input[name^='+key+']').bind('change', function() { + jQuery.each(Drupal.settings.dependentfields, function(parent_id, children) { + $('#' + parent_id).checkDependentFields(); + $('#' + parent_id).bind('change', function() { $(this).checkDependentFields(); }); }); } jQuery.fn.checkDependentFields = function() { - if(!$(this).length) { + if (!$(this).length) { + // This is not a dependent field. return; } - var name = $(this).getCleanElementName(); - if(!Drupal.settings.dependentfield[name]) { + + var dom_id = $(this).attr('id'); + if (!Drupal.settings.dependentfields[dom_id]) { // This is not a dependent field. return; } - var settings = Drupal.settings.dependentfield[name]; - // If there is a value property, then this is a value-dependent field - if(settings.value) { - if($('select[name^='+name+']').length) { - // This is a select menu - var selector = 'select[name^='+name+']'; - } else if ($('input[name^='+name+']').length) { - // This is radio buttons - var selector = 'input[name^='+name+']'; - } else { - // This is an error - return; - } - $(selector).selCheckDependentFields(); - } else { - // This is a checkbox - $('input[name^='+name+']').cbCheckDependentFields(); - } -} - -jQuery.fn.cbCheckDependentFields = function() { - $(this).updateDependentFields($(this).is(':visible') && $(this).attr('checked')); -} - -jQuery.fn.selCheckDependentFields = function() { - var settings = Drupal.settings.dependentfield[$(this).getCleanElementName()]; - var onoff = $(this).is(':visible'); - if(onoff) { - var i = jQuery.inArray($(this).val(), settings.value); - onoff = i > -1; - } - $(this).updateDependentFields(onoff); -} - -jQuery.fn.updateDependentFields = function(onoff) { - var children = $(this).getDependentChildren(); - var name = $(this).getCleanElementName(); - var cur = $(this).val(); - if(!!Drupal.settings.dependentfield[name].value) { - var val = Drupal.settings.dependentfield[name].value; - var ons = new Array(); - var offs = new Array(); - jQuery.each(Drupal.settings.dependentfield[name].wrapper, function(i, child) { - if(!!val[i] && val[i] == cur) { - ons[i] = $('#' + child); + var settings = Drupal.settings.dependentfields[dom_id]; + switch ($(this).attr('type')) { + case 'checkbox': + var wrappers = Array(); + if ($(this).is(':checked')) { + jQuery.each(settings, function(wrapper_id, setting) { + $('#' + setting.wrapper_id).slideDown(); + }); } else { - offs[i] = $('#' + child); + jQuery.each(settings, function(wrapper_id, setting) { + $('#' + wrapper_id).slideUp(); + }); } - }); - $(this).toggleDependentFields(ons, true); - $(this).toggleDependentFields(offs, false); - } else { - $(this).toggleDependentFields(children, onoff); - } -} - -jQuery.fn.getDependentChildren = function() { - var name = $(this).getCleanElementName(); - var children = new Array(); - if(!Drupal.settings.dependentfield[name] - || typeof Drupal.settings.dependentfield[name] == 'undefined' - || !Drupal.settings.dependentfield[name].wrapper) { - return; - } - - jQuery.each(Drupal.settings.dependentfield[name].wrapper, function(i, child) { - children[i] = $('#'+child); - }); - return children; -} - -jQuery.fn.getCleanElementName = function() { - var name = $(this).attr('name'); - if(!!name) { - return name.replace('[value]', ''); + break; + default: + jQuery.each(settings, function(wrapper_id, setting) { + var val = $('#' + setting.parent_id).val(); + var found = false; + if (typeof val == 'object' || typeof val == 'array') { + jQuery.each(val, function(i, v) { + if (v == setting.dependent_value) { + found = true; + } + }); + } + else if (typeof val == 'string') { + if(val == setting.dependent_value) { + found = true; + } + } else { + // should not get here. + } + + if (found) { + $('#' + wrapper_id).slideDown(); + } else { + $('#' + wrapper_id).slideUp(); + } + + }); + break; } } - -jQuery.fn.toggleDependentFields = function(children, onoff) { - if(!children || !children.length) { return; } - jQuery.each(children, function() { - if(onoff) { - $(this).slideDown(); - } else { - $(this).slideUp(); - } - }); -} Index: dependent.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/dependent/dependent.module,v retrieving revision 1.5.2.2 diff -u -p -r1.5.2.2 dependent.module --- dependent.module 15 Oct 2009 13:22:49 -0000 1.5.2.2 +++ dependent.module 2 Dec 2009 16:58:54 -0000 @@ -23,16 +23,17 @@ function dependent_form_alter(&$form, &$ return $form; } else{ - //this is how we tell drupal that during submition the - // 'dependent_submition' function should be called - // $form['#submit']['dependent_submition'] = array($options); - $form['#submit'][] = 'dependent_submition'; - $form['#dependant_submition_options'] = array($options); + //this is how we tell drupal that during submission the + // 'dependent_submission' function should be called + // $form['#submit']['dependent_submission'] = array($options); + $form['#submit'][] = 'dependent_submission'; + $form['#dependent_submission_options'] = array($options); } } else if (strpos($form_id,'_node_form')){//this is a node form $content_type = $form['type']['#value']; - $dependencies=db_query("SELECT * FROM {field_dependencies} WHERE parent_node_type_name='%s'", $content_type); + $type_info = $form['#field_info']; + $dependencies = db_query("SELECT * FROM {field_dependencies} WHERE parent_node_type_name='%s'", $content_type); $dependencies_switch = FALSE; $form_dependencies = array(); while ($data = db_fetch_array($dependencies)) { @@ -40,37 +41,13 @@ function dependent_form_alter(&$form, &$ $form_dependencies[] = $data; } if ($dependencies_switch > 0) { + // TODO: enable dependent required fields. ie a dependent field that's + // required only if its parent is selected. dependent_unset_required_before_validation($form_id, $form); $form['#validate'][] = 'dependent_validate_required_fields'; - } - foreach ($form_dependencies as $field) { //the while loop is to support future development where a field can be dependent on many parents - $child_wrapper = 'wrapper-'.rand().'-'.$field['child_field_name']; - drupal_add_js(array('dependentfield' => array( - $field['parent_field_name'] => $child_wrapper - )), 'setting'); - if($field['option_text'] != 'no_value_needed') { - drupal_add_js(array('dependentvalue' => array( - $field['parent_field_name'] => $field['option_text'] - )), 'setting'); - } - $form[$field['child_field_name']]['#prefix'] = '
'; - $form[$field['child_field_name']]['#suffix'] = '
'; - } - foreach ($form as $key=>$value){ - if (strpos($key,'field')!==FALSE){//this is a field - if (isset($value['key']['#options'])){ - $index= array_search('N/A', $value['key']['#options']); - if ($index!==FALSE){ - $len=strlen($index); - $flag=($len==0); - if ($len==0){ - unset($form[$key]['key']['#options'][$index]); - } - } - } - } } - + $form['__dependent__'] = array('#type' => 'value', '#value' => $form_dependencies); + $form['#theme'] = 'dependent_fields'; drupal_add_css(drupal_get_path('module', 'dependent') .'/dependent.css'); drupal_add_js(drupal_get_path('module', 'dependent') .'/dependent.js'); } @@ -79,15 +56,85 @@ function dependent_form_alter(&$form, &$ } } +/** + * hook_theme implementation + */ +function dependent_theme() { + return array( + 'dependent_fields' => array('arguments' => array('form')), + ); +} + +/** + * For each dependent field, set up our javascript voodoo. + */ +function theme_dependent_fields($form) { + $settings = array(); + + // Given a form field name, recursively search for and return the field from + // the form array. + function __dependent_get_field($form, $field_name) { + if(!is_array($form)) { + return FALSE; + } + if(isset($form[$field_name])) { + return $form[$field_name]; + } + foreach($form as $key => $value) { + if(is_array($value)) { + $field = __dependent_get_field($value, $field_name); + if($field) { + return $field; + } + } + } + return FALSE; + } + + function __dependent_set_wrapper($child, &$form) { + $wrapper = 'wrapper-'.rand().'-'.$child['#id']; + $path = implode('][', $child['#array_parents']); + // TODO: eval is the quickest way to address a buried element in $form, but + // it feels pretty wrong. A clever recursive function might accomplish the + // same thing, but writing a recursion to take arguments by reference feels + // wrong too. + $eval = '$form[' . $path . ']["#prefix"] = "
"; + $form[' . $path . ']["#suffix"] = "
";'; + eval($eval); + return $wrapper; + } + + foreach ($form['__dependent__']['#value'] as $field) { + $parent = __dependent_get_field($form, $field['parent_field_name']); + $child = __dependent_get_field($form, $field['child_field_name']); + $field_info = $form['#field_info'][$field['parent_field_name']]; + $parent_id = $parent['value']['#id']; + $setting['dependent_value'] = FALSE; + if($field['option_text']) { + if($field_info['widget']['type'] == 'optionwidgets_buttons') { + $parent_id = $parent['value'][$field['option_text']]['#id']; + } else { + $setting['dependent_value'] = $field['option_text']; + } + } + $wrapper = __dependent_set_wrapper($child, $form); + $setting['wrapper_id'] = $wrapper; + $setting['parent_id'] = $parent_id; + $settings[$parent_id][$wrapper] = $setting; + } + drupal_add_js(array('dependentfields' => $settings), 'setting', 'header', FALSE, FALSE, FALSE); + return drupal_render($form); +} + /* * this function is being called when the admin saves field settings * $options - an array with all the options that this field can depend on. */ -function dependent_submition($form, &$form_state) { - $options = $form['#dependant_submition_options']; +function dependent_submission($form, &$form_state) { + $options = $form['#dependent_submission_options']; if ($form['#id'] == 'content-field-edit-form') { - //this is a submition of adding or editing a field type + //this is a submission of adding or editing a field type if (isset($options)) { //get the names of the content type and field type $content_type = $form_state['values']['type_name'];