Skip to content
Snippets Groups Projects
search_input.js 5.29 KiB
/**
 * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
 *
 * BOKEH is free software; you can redistribute it and/or modify
 * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
 * the Free Software Foundation.
 *
 * There are special exceptions to the terms and conditions of the AGPL as it
 * is applied to this software (see README file).
 *
 * BOKEH is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
 *
 * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
 * along with BOKEH; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 */

(function ( $ ) {
  $.fn.search_input = function(options) {
    if ($('head').find('link[href*="search_input.css"]').length < 1) {
      $('head').append('<link media="screen" href="'
		       + baseUrl + '/public/opac/java/search_input/search_input.css" rel="stylesheet" type="text/css"></link>');
    }

    var default_input_id = 'default_search_input_id';
    var default_input_label = 'Rechercher';
    var default_fixed_display = '.search_input, .search_input *';

    if(undefined == options)
      options = {id : default_input_id,
		 label : default_input_label,
		 fixed_display : ''};

    if(undefined == options.id)
      options.id = default_input_id;

    if(undefined == options.label)
      options.label = default_input_label;

    if(undefined == options.fixed_display)
      options.fixed_display = '';

    if(options.fixed_display)
      options.fixed_display = ', ' + options.fixed_display;

    if (options.search_path && '' === options.search_path)
      delete options.search_path;

    var html = $(this);
    var not_found_class = 'search_input_not_found';

    var resetAll = function() {
      html
	.find('*')
	.not(default_fixed_display + options.fixed_display)
	.removeClass(not_found_class)
	.show();
    }


    var accentsTidy = function(s){
      var r = s.toLowerCase();
      r = r.replace(new RegExp("[àáâãäå]", 'g'),"a");
      r = r.replace(new RegExp("æ", 'g'),"ae");
      r = r.replace(new RegExp("ç", 'g'),"c");
      r = r.replace(new RegExp("[èéêë]", 'g'),"e");
      r = r.replace(new RegExp("[ìíîï]", 'g'),"i");
      r = r.replace(new RegExp("ñ", 'g'),"n");
      r = r.replace(new RegExp("[òóôõö]", 'g'),"o");
      r = r.replace(new RegExp("œ", 'g'),"oe");
      r = r.replace(new RegExp("[ùúûü]", 'g'),"u");
      r = r.replace(new RegExp("[ýÿ]", 'g'),"y");
      return r;
    };


    var highlightItems = function(elements) {
      resetAll();
      html.find('*').not(elements).not(default_fixed_display + options.fixed_display).addClass(not_found_class);
      html
	.find(elements)
	.parentsUntil(html)
	.not(default_fixed_display + options.fixed_display)
	.removeClass(not_found_class)
	.show();
    }


    var initRegex = function (searchText) {
      if (!searchText || searchText == "" || searchText == '*')
	return resetAll();

      searchText = accentsTidy(searchText);
      searchText = searchText.split(' ');
      searchText = searchText.filter(function(term){return term;});

      var reg_exps = [];
      $.each(searchText, function(index, term) {
	var reg = new RegExp('\\b' + term, 'i');
	reg_exps.push(reg);
      });

      return reg_exps;
    };


    var checkRegex = function (reg_exps, value) {
      var check = true;

      if ( ! reg_exps)
	return check;

      reg_exps.forEach(function (regexp) {
        check &= regexp.test(accentsTidy(value));
      });

      return check;
    };


    var onSearchInputChange = function(searchText) {
      if (options.search_path) {
        searchInSpecificPath(searchText);
        return;
      }

      var reg_exps = initRegex(searchText);
      var matches = html.find('*').contents().filter(function() {
        return 3 == this.nodeType && checkRegex(reg_exps, this.nodeValue);
      });

      highlightItems(matches);
    };


    var searchInSpecificPath = function (searchText) {
      var reg_exps = initRegex(searchText);
      var matches = html.find(options.search_path).contents().filter(function() {
        return 3 == this.nodeType && checkRegex(reg_exps, this.nodeValue);
      });

      resetAll();
      html
        .find(options.search_path)
        .addClass(not_found_class);

      matches
        .parent()
        .parent()
        .find(options.search_path)
        .removeClass(not_found_class);

      matches
        .parents()
        .siblings()
        .removeClass(not_found_class);

      matches
        .parents()
        .removeClass(not_found_class);
    };


    var search_input = (undefined == options.input)
	? html.prepend("<div class='search_input'>" +
		       "<form>" +
		       "<label for='" + options.id + "'>" + options.label + "</label>" +
		       "<input type='text' name='search_input' id='" + options.id +"'></input>" +
		       "</form>" +
		       "</div>").find('input')
	: $(options.input);

    search_input
      .on('keypress', function(event) {
	if (event.which == '13')
	  event.preventDefault();
      })
      .on('keyup', function(event){
	onSearchInputChange(this.value);
      })
      .end();
  }
} (jQuery));