Skip to content

Instantly share code, notes, and snippets.

@jrochkind
Created September 26, 2013 15:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrochkind/6715756 to your computer and use it in GitHub Desktop.
Save jrochkind/6715756 to your computer and use it in GitHub Desktop.
JH custom JS for blacklight_advanced_search to have differnet method of auto-complete multi-select for voluminous facets
/* Custom JS for Advanced Search Form */
jQuery(document).ready(function($) {
// A utility function we'll use to make a JQuery selector
// on a particular string 'id'. HTML id allows : or . chars,
// but need to be escaped in JQuery selectors.
// See http://docs.jquery.com/Frequently_Asked_Questions#How%5Fdo%5FI%5Fselect%5Fan%5Felement%5Fby%5Fan%5FID%5Fthat%5Fhas%5Fcharacters%5Fused%5Fin%5FCSS%5Fnotation.3F
function jq_id_select_escape(str_id) {
return str_id.replace(/(:|\.)/g,'\\$1');
}
// Make the facet labels float left so the autocomplete will be next to it
$(".facet_item h3").css({
"width": "30%",
"float": "left",
"clear": "left"
});
$('.limit_column ul').each(function(){
var ul = $(this);
// add an auto-completer with combo-box style toggle
var label = $(ul).prevAll("h3").text();
$(ul).before("<input type='text' class='advanced_facet_autocomplete'/> <a title='Show all "+label+"' class='advanced_facet_toggler ui-button ui-widget ui-state-default ui-button-icon-only ui-corner-right ui-button-icon'><span class='ui-button-icon-primary ui-icon ui-icon-triangle-1-s'></span><span class='ui-button-text'></span></a>");
//make the input an autocomplete that loads from ul
//when selected, checks relevant checkbox, and blanks
//out autocomplete textbox
$(ul).prevAll(".advanced_facet_autocomplete")
.keypress(function(e) {
//try to prevent enter in autocompletey field from submitting form.
if (e.which === 13) {
e.preventDefault();
return false;
}
})
.autocomplete({
source: function(req, add) {
// For each checkbox, add an option to the autocomplete select.
add(
jQuery.map(ul.children('li'), function(i) {
var maybe_match = $.trim($(i).text()).toLowerCase();
if ( ! $(i).find("input").attr("checked") &&
maybe_match.indexOf(req.term.toLowerCase()) === 0) {
//we use original_value rather than 'value'
//so it won't mean anything to autocomplete,
//but we can keep it for later, in our select
//event.
return {label: $.trim($(i).text()),
value: $.trim($(i).find("label").text()),
original_value: $(i).find('input').attr('id')
};
}
else {
return null;
}
}
)
);
},
select: function(event, ui) {
//to be able to find the checkbox by id even if the id
// has period's in it, we need to escape em in the jquery selector.
ul.find("input#"+jq_id_select_escape(ui.item.original_value)).attr("checked", true).trigger("change");
$(this).val('');
return false;
},
focus: function(event, ui) {
// Do NOT replace textbox contents with selection on
// focus -- otherwise confusing behavior if you close
// the autocomplete without an actual select, leaving
// the selected value in there.
event.preventDefault();
},
minLength: 0
})
.autocomplete("widget").css({
'max-height': '18em',
'overflow-y': 'auto',
'overflow-x': 'hidden',
'padding-right': '20px'
});
//make the combo-box thing turn the autocomplete on and off, copied
//from jquery-ui autocomplete combobox example.
$(ul).prevAll(".advanced_facet_toggler").click(function() {
var input = $(this).parent().find(".advanced_facet_autocomplete");
if (input.autocomplete("widget").is(":visible")) {
input.autocomplete("close");
return;
}
// bug workaround copied from autocomplete example
$( this ).blur();
// pass empty string as value to search for, displaying all results
input.autocomplete( "search", "" );
input.focus();
});
//move the container for displaying current constraints from
//the weird place it is to after the ul.
ul.closest(".facet_item").find(".adv_facet_selections").insertAfter(ul);
// hide the ul
ul.hide();
});
/* Stuff for handling the checkboxes */
/* When you click a checkbox, update readout */
/* Pass in a jquery obj holding the "selected facet element" spans, get back
a string for display representing currently checked things. */
function convertCheckboxesToBubbles(div) {
var checkbox_elements = $(div).find("input:checkbox");
var constraint_html = $('<span/>');
var checked = 0;
checkbox_elements.each(function() {
if ($(this).is(":checked")) {
checked += 1;
var c = $("<span/></span>").addClass("appliedFilter constraint")
.append( $("<span/>").addClass("filterValue").html($(this).nextAll("label").text()) )
.append( $("<a/>")
.addClass("btnRemove imgReplace")
.attr("title", "remove")
.attr("data-checkbox-id", $(this).attr('id'))
.click(function() {
var orig_id = $(this).attr("data-checkbox-id");
$(div).find("input#" + jq_id_select_escape(orig_id)).removeAttr("checked").trigger("change");
})
)
.appendTo( constraint_html );
}
});
if (checked > 1) {
constraint_html.prepend("Any of: ");
}
return constraint_html;
}
//Pass in JQuery object of zero or more <div class="facet_item"> blocks,
//that contain an h3, some checkboxes, and a span.adv_facet_selections for
//display of current selections. Will update the span.
function updateSelectedDisplay(facet_item) {
var displaySpan = $(facet_item).find("span.adv_facet_selections");
var displayHtml = convertCheckboxesToBubbles( facet_item );
displaySpan.html( displayHtml );
displaySpan.show();
}
// on page load, set initial constraint bubbles properly
// based on initial checkbox state.
$(".facet_item").each(function() {
updateSelectedDisplay(this);
});
// Everytime checkbox state changes, make sure
// we update constraint bubbles. We have our autocomplete
// making sure to change checkboxes on select, so that'll
// trigger this constraint display update too.
$(".facet_item input:checkbox").change( function() {
updateSelectedDisplay( $(this).closest(".facet_item"));
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment