(function($) { /** * Attaches the tree behavior to the term widget form. */ Drupal.behaviors.termReferenceTree = { attach: function(context, settings) { // Bind the term expand/contract button to slide toggle the list underneath. $('.term-reference-tree-button', context).once('term-reference-tree-button').click(function() { $(this).toggleClass('term-reference-tree-collapsed'); $(this).siblings('ul').slideToggle('fast'); }); // An expand all button (unimplemented) /* $('.expandbutton').click(function() { $(this).siblings('.term-reference-tree-button').trigger('click'); }); */ $('.term-reference-tree', context).once('term-reference-tree').each(function() { // On page load, check whether the maximum number of choices is already selected. // If so, disable the other options. var tree = $(this); checkMaxChoices(tree, false); $(this).find('input[type=checkbox]').change(function() { checkMaxChoices(tree, $(this)); }); //On page load, check if the user wants a cascading selection. if($(this).hasClass('term-reference-tree-select-parents')) { $(this).find('.form-checkbox').parent().addClass('select-parents'); } //On page load, check if the user wants a track list. If so, add the //currently selected items to it. if($(this).hasClass('term-reference-tree-track-list-shown')) { var track_list_container = $(this).find('.term-reference-tree-track-list'); //Var to track whether using checkboxes or radio buttons. var input_type = ( $(this).has('input[type=checkbox]').length > 0 ) ? 'checkbox' : 'radio'; //Find all the checked controls. var checked_controls = $(this).find('input[type=' + input_type + ']:checked'); //Get their labels. var labels = checked_controls.next(); var label_element; //For each label of the checked boxes, add item to the track list. labels.each(function(index) { label_element = $(labels[index]); addItemToTrackList( track_list_container, //Where to add new item. label_element.html(), //Text of new item. $(label_element).attr('for'), //Id of control new item is for. input_type //checkbox or radio ); }); //End labels.each //Show "nothing selected" message, if needed. showNothingSelectedMessage(track_list_container); //Event - when an element on the track list is clicked on: // 1. Delete it. // 2. Uncheck the associated checkbox. //The event is bound to the track list container, not each element. $(track_list_container).click(function(event){ //Remove the "nothing selected" message if showing - add it later if needed. //removeNothingSelectedMessage(track_list_container); var event_target = $(event.target); var control_id = event_target.data('control_id'); if(control_id) { event_target.remove(); var checkbox = $('#' + control_id); checkbox.removeAttr('checked'); checkMaxChoices(tree, checkbox); //Show "nothing selected" message, if needed. showNothingSelectedMessage(track_list_container); } }); //Change track list when controls are clicked. $(this).find('.form-' + input_type).change(function(event){ //Remove the "nothing selected" message if showing - add it later if needed. removeNothingSelectedMessage(track_list_container); var event_target = $(event.target); var control_id = event_target.attr('id'); if ( event_target.attr('checked') ) { //Control checked - add item to the track list. label_element = event_target.next(); addItemToTrackList( track_list_container, //Where to add new item. label_element.html(), //Text of new item. $(label_element).attr('for'), //Id of control new item is for. input_type //checkbox or radio ); } else { //Checkbox unchecked. Remove from the track list. $('#' + control_id + '_list').remove(); } //Show "nothing selected" message, if needed. showNothingSelectedMessage(track_list_container); }); //End process checkbox changes. } //End Want a track list. //On page load, check if the user wants a cascading selection. if($(this).hasClass('term-reference-tree-cascading-selection')) { var mode_select = $(this).hasClass('term-reference-tree-cascading-selection-mode-select'); var mode_deselect = $(this).hasClass('term-reference-tree-cascading-selection-mode-deselect'); //Check children when checkboxes are clicked. $(this).find('.form-checkbox').change(function(event) { var event_target = $(event.target); var event_target_checked = event_target.is(':checked'); var control_id = event_target.attr('id'); var children = event_target.parent().next().children().find('> :not(ul) > input[id^="' + control_id + '-children"]'); if (!mode_select && !mode_deselect) { if(event_target_checked) { $(children).filter(':not(:checked)').click().trigger('change'); } else { $(children).filter(':checked').click().trigger('change'); } } else if (mode_select && event_target_checked) { $(children).filter(':not(:checked)').click().trigger('change'); } else if (mode_deselect && !event_target_checked) { $(children).filter(':checked').click().trigger('change'); } }); //End process checkbox changes. } //End Want a cascading checking. }); } }; /** * Add a new item to the track list. * If more than one item can be selected, the new item is positioned to * match the order of the terms in the checkbox tree. * * @param track_list_container Container where the new item will be added. * * @param item_text Text of the item to add. * * @param control_id Id of the checkbox/radio control the item matches. * * @param control_type Control type - 'checkbox' or 'radio'. */ function addItemToTrackList(track_list_container, item_text, control_id, control_type) { var new_item = $('