Skip to content

Instantly share code, notes, and snippets.

@blisteringherb
Created January 29, 2013 23:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save blisteringherb/4668953 to your computer and use it in GitHub Desktop.
Save blisteringherb/4668953 to your computer and use it in GitHub Desktop.
JS MSLO Autocomplete Module
(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