Created
January 29, 2013 23:23
-
-
Save blisteringherb/4668953 to your computer and use it in GitHub Desktop.
JS MSLO Autocomplete Module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
Drupal.settings.mslo_taxonomy_autocomplete = {}; | |
})(jQuery); | |
Drupal.behaviors.mslo_taxonomy_autocomplete = function (context) { | |
$('#taxonomy-4-update input[type=text]').each(function () { | |
$(this).append("<a href='#' id='parentsToggle' class='active'>Hide hierarchy paths</a>"); | |
}); | |
// Debugging: Uncomment the following to make autocomplete suggestions pop-up persistently visible | |
//$('#taxonomy-4-update input[type=text]').unbind('blur'); | |
// Hide the error message alterting users to select a term | |
if ($('.existing-terms-wrapper').is('*')) {$('.no-values').hide();} | |
var pathsVisible = true; | |
$("#parentsToggle").click(function (event) { | |
event.preventDefault(); | |
if (pathsVisible === false) { | |
if ($("#edit-taxonomy-4-new-term-wrapper #autocomplete")) { | |
$("div#edit-taxonomy-4-new-term-wrapper div.item-list ul li:not(.first)").show(); | |
} | |
$("div.existing-terms-item-list ul li:not(.last)").fadeIn(); | |
$(this).text("Hide hierarchy paths").addClass("active"); | |
pathsVisible = true; | |
} else { | |
if ($("#edit-taxonomy-4-new-term-wrapper #autocomplete")) { | |
$("div#edit-taxonomy-4-new-term-wrapper div.item-list ul li:not(.first)").fadeOut(); | |
} | |
$("div.existing-terms-item-list ul li:not(.last)").fadeOut(); | |
$("div.existing-terms-item-list ul li.last"); | |
$(this).text("Show hierarchy paths").removeClass("active"); | |
pathsVisible = false; | |
} | |
}); | |
var buildBrowseList = function (data, ul) { | |
var items = []; | |
var newDepth; | |
var currentDepth = Math.ceil($('ul.term-list').length/2); | |
var clickedDepth = (typeof(ul) !== 'undefined') ? parseInt($(ul).attr('rel')) : 0; | |
if (typeof(clickedDepth) !== 'undefined') { | |
if (clickedDepth < currentDepth) { | |
newDepth = clickedDepth; | |
ul.nextAll().remove(); | |
} | |
else if (clickedDepth === 0 || clickedDepth === 1 || clickedDepth === currentDepth) { | |
newDepth = clickedDepth + 1; | |
} | |
} | |
items.push('<ul class="term-list" rel="'+ newDepth +'">'); | |
$.each(data, function (key, val) { | |
var children; | |
if (!$.isArray(val.children)) { | |
children = 'children'; | |
} | |
else { | |
children = ''; | |
} | |
items.push('<li class="' + children + '" id="' + key + '">' + val['list'] + '</li>'); | |
}); | |
items.push('</ul>'); | |
$(items.join('')).appendTo('.browse-dialog'); | |
} | |
var getBrowseList = function (url, element) { | |
var arr = url.split('/'); | |
var path = arr.pop(); | |
if (typeof(Drupal.settings.mslo_taxonomy_autocomplete[path]) !== 'undefined') { | |
buildBrowseList(Drupal.settings.mslo_taxonomy_autocomplete[path].data, element); | |
Drupal.attachBehaviors(); | |
} | |
else { | |
$.getJSON(url, function (data) { | |
buildBrowseList(data, element); | |
Drupal.attachBehaviors(); | |
Drupal.settings.mslo_taxonomy_autocomplete[path] = {'data': data}; | |
}); | |
} | |
} | |
var createBrowseDialog = function () { | |
$('.browse-link').after('<div class="browse-dialog"></div>'); | |
} | |
$('.browse-link').unbind('click').click(function() { | |
createBrowseDialog(); | |
var $browseDialog = $('.browse-dialog'); | |
$browseDialog.append('<div class="browse-dialog-header"><span class="close-browse-btn">add</span><span class="close-browse-btn">x cancel</span></div>'); | |
$browseDialog.wrap('<div class="browse-dialog-container" />'); | |
$browseDialog.removeClass('browse-inactive'); | |
if ($('body').hasClass('admin-expanded')) { | |
$('body').removeClass('admin-expanded'); | |
$('#admin-toolbar .admin-blocks').css('width', '0'); | |
} | |
getBrowseList('/admin/term_search/browse'); | |
return false; | |
}); | |
$('.browse-dialog label').unbind('click').click(function () { | |
var $ul = $(this).closest('ul'); | |
var tid = $(this).prev('input').attr('value'); | |
$(this).parents('li.children').siblings('li').find('label').removeClass('activeBrowseLabel'); | |
$(this).addClass('activeBrowseLabel'); | |
$('.term-list .active').removeClass('active'); | |
$('.term-list input:radio').attr({ | |
disabled: true, | |
checked: false | |
}); | |
getBrowseList('/admin/term_search/browse/' + tid, $ul); | |
return false; | |
}); | |
var submitSelectedTerm = function (value) { | |
$('#edit-taxonomy-4-class-all-new-term').attr('value', value['name']).text(value['name']); | |
$('#edit-taxonomy-4-class-all-new-term-tid').attr('value', value['tid']); | |
$('#edit-taxonomy-4-class-all-taxonomy-autocomplete-more').mousedown(); | |
} | |
$('.close-browse-btn').click(function() { | |
if ($(this).text() == 'add') { | |
var value = []; | |
value['name'] = $('.term-list input:checked').prev('label').text(); | |
value['tid'] = $('.term-list input:checked').attr('value'); | |
submitSelectedTerm(value); | |
} | |
$('.browse-dialog-container').remove(); | |
//$browseDialog.addClass('browse-inactive'); | |
}); | |
} | |
/** | |
* Handler for the form redirection completion. | |
* | |
* The core functionality has to be overwritten because core doesn't | |
* have a mechanism to register new ahah elements with Drupal.ahah.settings. | |
*/ | |
Drupal.ahah.prototype.success = function (response, status) { | |
var wrapper = $(this.wrapper); | |
var form = $(this.element).parents('form'); | |
// Manually insert HTML into the jQuery object, using $() directly crashes | |
// Safari with long string lengths. http://dev.jquery.com/ticket/1152 | |
var new_content = $('<div></div>').html(response.data); | |
// Restore the previous action and target to the form. | |
form.attr('action', this.form_action); | |
this.form_target ? form.attr('target', this.form_target) : form.removeAttr('target'); | |
this.form_encattr ? form.attr('target', this.form_encattr) : form.removeAttr('encattr'); | |
// Remove the progress element. | |
if (this.progress.element) { | |
$(this.progress.element).remove(); | |
} | |
if (this.progress.object) { | |
this.progress.object.stopMonitoring(); | |
} | |
$(this.element).removeClass('progress-disabled').attr('disabled', false); | |
// Add the new content to the page. | |
Drupal.freezeHeight(); | |
if (this.method === 'replace') { | |
wrapper.empty().append(new_content); | |
Drupal.behaviors.mslo_hub_form; | |
} | |
else { | |
wrapper[this.method](new_content); | |
} | |
// Immediately hide the new content if we're using any effects. | |
if (this.showEffect != 'show') { | |
new_content.hide(); | |
} | |
// Determine what effect use and what content will receive the effect, then | |
// show the new content. | |
if ($('.ahah-new-content', new_content).size() > 0) { | |
$('.ahah-new-content', new_content).hide(); | |
new_content.show(); | |
$(".ahah-new-content", new_content)[this.showEffect](this.showSpeed); | |
} | |
else if (this.showEffect != 'show') { | |
new_content[this.showEffect](this.showSpeed); | |
} | |
// Make sure that Drupal.settings.ahah knows about the new form elements | |
// that were added by the ahah callback. | |
if (typeof(response.settings) != 'undefined') { | |
$.extend(Drupal.settings.ahah, response.settings); | |
} | |
// Attach all javascript behaviors to the new content, if it was successfully | |
// added to the page, this if statement allows #ahah[wrapper] to be optional. | |
if (new_content.parents('html').length > 0) { | |
Drupal.attachBehaviors(new_content); | |
} | |
Drupal.unfreezeHeight(); | |
}; | |
/** | |
* Hides the autocomplete suggestions. | |
*/ | |
Drupal.jsAC.prototype.hidePopup = function (keycode) { | |
// Select item if the right key or mousebutton was pressed | |
if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) { | |
this.input.value = this.selected.autocompleteValue; | |
} | |
// Hide popup | |
var popup = this.popup; | |
if (popup) { | |
this.popup = null; | |
$(popup).fadeOut('fast', function () { $(popup).remove(); }); | |
} | |
this.selected = false; | |
}; | |
/** | |
* Performs a cached and delayed search | |
*/ | |
Drupal.ACDB.prototype.search = function (searchString) { | |
var db = this; | |
this.searchString = searchString; | |
// See if this key has been searched for before | |
if (this.cache[searchString]) { | |
return this.owner.found(this.cache[searchString]); | |
} | |
// Initiate delayed search | |
if (this.timer) { | |
clearTimeout(this.timer); | |
} | |
this.timer = setTimeout(function () { | |
db.owner.setStatus('begin'); | |
// Ajax GET request for autocompletion | |
$.ajax({ | |
type: "GET", | |
url: db.uri +'/'+ searchString, | |
dataType: 'json', | |
success: function (matches) { | |
if (typeof matches['status'] === 'undefined' || matches['status'] != 0) { | |
db.cache[searchString] = matches; | |
// Verify if these are still the matches the user wants to see | |
if (db.searchString === searchString) { | |
db.owner.found(matches); | |
} | |
db.owner.setStatus('found'); | |
} | |
}, | |
error: function (xmlhttp) { | |
alert(Drupal.ahahError(xmlhttp, db.uri)); | |
} | |
}); | |
}, this.delay); | |
}; | |
Drupal.ACDB.prototype.customSearch = function (searchString, field) { | |
searchString = searchString + "/" + $('#' + field).attr('rel'); | |
return this.search(searchString); | |
}; | |
/** | |
* Positions the suggestions popup and starts a search | |
*/ | |
Drupal.jsAC.prototype.populatePopup = function () { | |
if (this.input.value.length > 2) { | |
// Show popup | |
if (this.popup) { | |
$(this.popup).remove(); | |
} | |
this.selected = false; | |
this.popup = document.createElement('div'); | |
this.popup.id = 'autocomplete'; | |
this.popup.owner = this; | |
$(this.popup).css({ | |
marginTop: this.input.offsetHeight +'px', | |
width: (this.input.offsetWidth - 4) +'px', | |
display: 'none' | |
}); | |
$(this.input).before(this.popup); | |
// Do search | |
this.db.owner = this; | |
// Only use the custom search on autocomplete taxonomy fields. | |
if (this.input.id.substring(0, 13) === 'edit-taxonomy') { | |
this.db.customSearch(this.input.value, this.input.id); | |
} else { | |
this.db.search(this.input.value); | |
} | |
} | |
}; | |
/** | |
* Fills the suggestion popup with any matches received. | |
*/ | |
Drupal.jsAC.prototype.found = function (matches) { | |
// If no value in the textfield, do not show the popup. | |
if (!this.input.value.length) { | |
return false; | |
} | |
// Prepare matches. | |
var ul = document.createElement('ul'); | |
var ac = this; | |
for (key in matches) { | |
var li = document.createElement('li'); | |
if (typeof(matches[key]) === 'object') { | |
var label = matches[key]['label']; | |
} | |
else { | |
var label = value = matches[key]; | |
} | |
$(li) | |
.html('<div>'+ label +'</div>') | |
.mousedown(function () { ac.select(this); | |
// Only attempt to set the value of the hidden field if | |
// it's a node-form autocomplete field | |
if (typeof(matches[key]['tid']) != 'undefined') { | |
var hidden = $('#taxonomy-4-update input[type=text]:focus').attr('id'); | |
hidden += '-tid'; | |
$('#' + hidden).attr('value', this.autocompleteTID); | |
} | |
}) | |
.mouseover(function () { ac.highlight(this); }) | |
.mouseout(function () { ac.unhighlight(this); }); | |
if (typeof(matches[key]) === 'object') { | |
li.autocompleteValue = matches[key]['value']; | |
li.autocompleteTID = matches[key]['tid']; | |
} | |
else { | |
li.autocompleteValue = key; | |
} | |
$(ul).append(li); | |
} | |
// Show popup with matches, if any. | |
if (this.popup) { | |
if (ul.childNodes.length > 0) { | |
$(this.popup).empty().append(ul).show(); | |
} | |
else { | |
$(this.popup).css({visibility: 'hidden'}); | |
this.hidePopup(); | |
} | |
} | |
if ($("#parentsToggle").hasClass("active")) { | |
} else { | |
$("div#edit-taxonomy-4-new-term-wrapper div.item-list ul li:not(.first)").hide(); | |
} | |
}; | |
/** | |
* Rebinds autocompletion to prevent multiple search handlers. | |
*/ | |
Drupal.behaviors.rebindAutocomplete = function (context) { | |
// Unbind the behaviors to prevent multiple search handlers. | |
$("#edit-your-search-field").unbind('keydown').unbind('keyup').unbind('blur').removeClass('autocomplete-processed'); | |
// Rebind autocompletion with the new code. | |
Drupal.behaviors.autocomplete(context); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment