Skip to content

Instantly share code, notes, and snippets.

@mherchel
Last active December 10, 2016 23:19
Show Gist options
  • Save mherchel/f839241db5233fe0ef8c6192d7dd15b1 to your computer and use it in GitHub Desktop.
Save mherchel/f839241db5233fe0ef8c6192d7dd15b1 to your computer and use it in GitHub Desktop.
(function($){
Drupal.behaviors.addMoreRows = {
attach: function(context, settings) {
var $tripletWrapper = $('.js-advanced-triplet-wrapper', context);
var $removeButton = $('.js-advanced-button-remove', context);
var $addButton = $('.js-advanced-button-add', context);
var $clearButton = $('#gnus-advanced-search-form-advanced-form button[type="reset"]', context);
// Add additional option with correct text to each field select element
$('.search-triplet', context).each(function(i) {
var $fieldSelector = $('select[name*="fld-base"] option:first-child', this);
// Add custom option element within the select element
$fieldSelector.clone().insertAfter($fieldSelector);
$fieldSelector.text('Select a Field (optional)');
// Add X on each input text field to clear text
$('input[type="text"]', this).after('<button type="button" class="advanced-search__input-clear">' +
'<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="15.68" height="15.68" viewBox="0 0 15.68 15.68">' +
'<rect x="-1.18" y="6.35" width="18.64" height="3.52" transform="translate(7.82 -3.65) rotate(45)"/>' +
'<rect x="-1.18" y="6.35" width="18.64" height="3.52" transform="translate(19.33 7.82) rotate(135)"/>' +
'</svg>' +
'</button>');
// If input text field contains text, make sure that the search-triplet row is visible
if ($('input[type="text"]', this).val().length > 0) {
$(this).parent().removeClass('is-hidden');
}
// Show the X on the input text field if it contains text
if ($('input[type="text"]', this).attr('value').length > 0) {
$('.advanced-search__input-clear', this).css({'display' : 'block'});
}
});
// Listen for typing in any of the input text fields, and if it contains text afterwards, show the X
$('.search-triplet input[type="text"]', context).on('keyup', function() {
if ($(this).val().length > 0) {
$(this).parent().find('.advanced-search__input-clear').css({'display' : 'block'});
}
else {
$(this).parent().find('.advanced-search__input-clear').css({'display' : ''});
}
});
// When X button is clicked, clear the adjacent text input field
$('.advanced-search__input-clear', context).click(function() {
$(this).siblings('input[type="text"]').val('');
$(this).css({'display' : ''});
});
// Adds search triplet rows to the advanced search form
$addButton.click(function(e){
e.preventDefault(); // cancel default behavior
// Reveal next hidden tripletWrapper
$('.js-advanced-triplet-wrapper.is-hidden', context).first().removeClass('is-hidden');
// If all $tripletWrappers are visible disable addbutton
if(!$tripletWrapper.hasClass('is-hidden')) {
$addButton.prop('disabled', true);
}
// If previous tripletWrapper doesn't have the is-visible class enable removeButton
if(!$tripletWrapper.not(':visible').prev().hasClass('is-visible')) {
$removeButton.prop('disabled', false);
}
checkFormIsCollapsable();
});
// removeButton is disabled by default in form markup
$removeButton.click(function(e){
e.preventDefault(); // cancel default behavior
// Hide the last tripletWrapper and remove any text inside it
var field = $('.js-advanced-triplet-wrapper:not(.is-hidden)').last().addClass('is-hidden');
field.find("input[type=text], textarea").val("");
if ($('.triplet-wrapper').first().hasClass('is-hidden')) {
$removeButton.prop('disabled', true);
}
// If the last $tripletWrapper is not hidden enable $addbutton
if($tripletWrapper.not(':hidden').last()) {
$addButton.prop('disabled', false);
}
checkFormIsCollapsable();
});
// Ensure that clear button clears the original values from the advanced search results page
$clearButton.click(function() {
var $currentForm = $(this).closest('form');
$currentForm.find('input[type="text"], textarea').val("").attr('value', '');
$currentForm.find('.advanced-search__input-clear').css({'display' : ''});
$currentForm.find('option').removeAttr('selected');
$currentForm.find('option:first-child').attr('selected', 'selected');
$currentForm.find('select').change(); // Make sure change() event fires to reset all widgets to default
});
// Enable advanced form footer to be collapsed if there are more than 3 visible rows OR if it's mobile width
function checkFormIsCollapsable() {
// If the third triplet is hidden, and is not mobile, then do not make collapsable
if ($('.search-triplet:eq(2)', context).parent().hasClass('is-hidden') && $(window).width() >= 700) {
$('#gnus-advanced-search-form-advanced-form', context).removeClass('js-advanced-search--collapsable');
}
// Everything else make collapsable
else {
$('#gnus-advanced-search-form-advanced-form', context).addClass('js-advanced-search--collapsable');
}
}
checkFormIsCollapsable();
}
};
Drupal.behaviors.showHideAdvancedSearch = {
attach: function(context, settings) {
if ($('body', context).hasClass('page-results') || $('body', context).hasClass('page-document-view')) {
var $footer = $('.advanced-form-footer', context);
var $form = $('#gnus-advanced-search-form-advanced-form', context);
var collapsedByDefault = false;
// Collapse by default if on document view OR on mobile
if ($('body', context).hasClass('page-document-view') || $(window).width() <= 700) {
collapsedByDefault = true;
}
// Insert show/hide button
$footer.prepend('<div class="advanced-search--footer-gradient"></div><button type="button" class="advanced-search--show-hide">Hide</button>');
// If cookie is set, expand or collapse form
if ($.cookie('gnus_advanced_search_form.advanced_form_expanded') == 'expanded') {
$form.removeClass('js-advanced-search--footer-collapsed');
$('.advanced-search--show-hide', $footer).text('Hide');
}
else if ($.cookie('gnus_advanced_search_form.advanced_form_expanded') == 'collapsed') {
$form.addClass('js-advanced-search--footer-collapsed');
$('.advanced-search--show-hide', $footer).text('Show');
}
// Collapse by default
else if (collapsedByDefault == true) {
$('.advanced-search--show-hide', $footer).text('Show');
$form.addClass('js-advanced-search--footer-collapsed');
}
// Click event when show/hiding form
$('.advanced-search--footer-gradient, .advanced-search--show-hide', $footer).click(function() {
if ($form.hasClass('js-advanced-search--footer-collapsed')) {
$form.removeClass('js-advanced-search--footer-collapsed');
$('.advanced-search--show-hide', $footer).text('Hide');
$.cookie('gnus_advanced_search_form.advanced_form_expanded', 'expanded');
}
else {
$form.addClass('js-advanced-search--footer-collapsed');
$('.advanced-search--show-hide', $footer).text('Show');
$.cookie('gnus_advanced_search_form.advanced_form_expanded', 'collapsed');
}
$('.advanced-search--show-hide', $footer).focus();
});
}
}
};
/*
* Move the "Navigator Helpers" to appear below the search form
*/
Drupal.behaviors.contentNavigatorAdvancedHelper = {
attach: function (context, settings) {
var $feedbackContainer = $('.nbcore-navigator-items-feedback', context);
if ($feedbackContainer.length && $('.advanced-search---inner', context).length) {
var $elementDestination = $('.advanced-search---inner', context);
$elementDestination.append($feedbackContainer);
}
}
};
/*
* Move the "Results count" to appear below the search form
*/
Drupal.behaviors.contentResultsCount = {
attach: function (context, settings) {
var $resultscountContainer = $('.search-hits__count-meta', context);
var $elementDestination = $('.advanced-form-footer', context);
$elementDestination.append($resultscountContainer);
}
};
/*
* Adds dynamic HTML data attribute to custom widget (date, readability, word count, etc) parent elements.
* Inserts markup for "Date" info popup.
*/
Drupal.behaviors.advancedSearchCustomWidgets = {
attach: function (context, settings) {
// Function to add HTML date attribute indicating which "Select a Field" dropdown is selected,
// insert the date icon on date fields, and add a hover handler to show date popup.
function dateIconInsert(element) {
var $searchTripletParent = element.closest('.search-triplet'),
selectValue = element.val().toLowerCase();
// Add 'date-widget-type' HTML attribute to each triplet to indicate what widget is selected.
$searchTripletParent.attr('data-widget-type', selectValue);
// If "Date" is selected, append the icon for the popup. The icon contains text for accessibility reasons.
if (selectValue == 'ymd_date') {
$('.form-type-textfield[class*="form-item-val"]', $searchTripletParent).append('\
<div class="date-icon" tabindex="0">\
<div class="date-icon__text">\
<p>Input any date format, including a range or specific date.</p>\
<ul>\
<li><span class="eg">e.g.</span> 3/4/16</li>\
<li>past 2 days</li>\
<li>past 6 months</li>\
<li>January 1st, 2015</li>\
<li>2016</li>\
<li>2009-2012</li>\
<li>Nov-Dec 2015</li>\
<li>before 1/1/10</li>\
<li>after 12/31/15</li>\
</ul>\
</div>\
</div>');
// Create hover, focus, and blur handlers for date popup.
dateIconHover();
dateIconFocus();
dateIconBlur();
}
else {
// If something other than date is selected, remove the icon.
$('.date-icon', $searchTripletParent).remove();
}
}
// Function to insert the date info popup. Note the popup markup is copied from the icon's HTML, where it exists for a11y reasons.
function datePopupInsert(element) {
var $searchTripletParent = element.closest('.search-triplet'),
widgetOffset = $('.date-icon', $searchTripletParent).offset(),
widgetHeight = 300,
scrollTop = $(window, context).scrollTop(),
positionClass = ((widgetOffset.top - widgetHeight) > scrollTop) ? 'date-info__above' : 'date-info__below',
iconDimensions = ($('.date-icon', context).height()) ? $('.date-icon', context).height() : 18,
popupPositionLeft = widgetOffset.left + iconDimensions / 2,
popupPositionTop = (positionClass == 'date-info__above') ? widgetOffset.top - 10 : widgetOffset.top + iconDimensions + 10, // Popup will also be moved by CSS translation
dateInfoPopupID = 'date-popup__' + $searchTripletParent.attr('id'),
datePopupMarkupText = $('.date-icon', $searchTripletParent).html(),
datePopupMarkup = '<div id="' + dateInfoPopupID + '" class="date-info-popup date-info__above ' + positionClass + '" style="top: ' + popupPositionTop + 'px; left: ' + popupPositionLeft + 'px;">'
+ datePopupMarkupText
+ '<button type="button" class="date-info-popup__close">Close</button>'
+ '</div>';
// If the popup already exists, remove it.
$('#' + dateInfoPopupID).remove();
// Add the markup to the page.
$('body', context).append(datePopupMarkup);
// Mobile version has a close button. When it's clicked, modal disappears.
$('.date-info-popup__close', context).click(function() {
$('.date-info-popup', context).remove();
});
}
// Hover event handler for the Date popup. This positions the date popup above/below, and show/hides it.
// Only enabled for viewports larger than 700px.
function dateIconHover() {
if ($(window, context).width() >= 700) {
$('.date-icon', context).hover(
function () {
datePopupInsert($(this));
},
function () {
var element = $(this);
// Timeout after moving mouse off
setTimeout(function () {
var dateInfoPopupID = 'date-popup__' + element.closest('.search-triplet').attr('id');
$('#' + dateInfoPopupID).remove();
}, 1000);
}
);
}
}
// Focus handler for date popup for a11y.
function dateIconFocus() {
$('.date-icon', context).focus(function() {
datePopupInsert($(this));
});
}
// Blur handler for date popup for a11y. Only enabled for viewports larger than 700px.
function dateIconBlur() {
if ($(window, context).width() >= 700) {
$('.date-icon', context).blur(function () {
$('.date-info-popup', context).remove();
});
}
}
// On load, run dateIconInsert() against each "Select a Field" dropdown.
$('select[id^="edit-fld-base"]', context).each(function() {
dateIconInsert($(this));
});
// On "Select a Field" dropdown change, remove any date popups, and run dateIconInsert() against each "Select a Field" dropdown.
$('select[id^="edit-fld-base"]', context).change(function() {
$('.date-info-popup', context).remove();
dateIconInsert($(this));
});
}
}
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment