mirror of
https://github.com/ExactTarget/fuelux.git
synced 2026-01-10 15:08:02 -05:00
226 lines
5.4 KiB
JavaScript
226 lines
5.4 KiB
JavaScript
/* global jQuery:true */
|
|
|
|
/*
|
|
* Fuel UX Search
|
|
* https://github.com/ExactTarget/fuelux
|
|
*
|
|
* Copyright (c) 2014 ExactTarget
|
|
* Licensed under the BSD New license.
|
|
*/
|
|
|
|
// -- BEGIN UMD WRAPPER PREFACE --
|
|
|
|
// For more information on UMD visit:
|
|
// https://github.com/umdjs/umd/blob/master/jqueryPlugin.js
|
|
|
|
(function umdFactory (factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// if AMD loader is available, register as an anonymous module.
|
|
define(['jquery'], factory);
|
|
} else if (typeof exports === 'object') {
|
|
// Node/CommonJS
|
|
module.exports = factory(require('jquery'));
|
|
} else {
|
|
// OR use browser globals if AMD is not present
|
|
factory(jQuery);
|
|
}
|
|
}(function SearchWrapper ($) {
|
|
// -- END UMD WRAPPER PREFACE --
|
|
|
|
// -- BEGIN MODULE CODE HERE --
|
|
|
|
var old = $.fn.search;
|
|
|
|
// SEARCH CONSTRUCTOR AND PROTOTYPE
|
|
|
|
var Search = function (element, options) {
|
|
this.$element = $(element);
|
|
this.$repeater = $(element).closest('.repeater');
|
|
this.options = $.extend({}, $.fn.search.defaults, options);
|
|
|
|
if (this.$element.attr('data-searchOnKeyPress') === 'true'){
|
|
this.options.searchOnKeyPress = true;
|
|
}
|
|
|
|
this.$button = this.$element.find('button');
|
|
this.$input = this.$element.find('input');
|
|
this.$icon = this.$element.find('.glyphicon, .fuelux-icon');
|
|
|
|
this.$button.on('click.fu.search', $.proxy(this.buttonclicked, this));
|
|
this.$input.on('keyup.fu.search', $.proxy(this.keypress, this));
|
|
|
|
if (this.$repeater.length > 0) {
|
|
this.$repeater.on('rendered.fu.repeater', $.proxy(this.clearPending, this));
|
|
}
|
|
|
|
this.activeSearch = '';
|
|
};
|
|
|
|
Search.prototype = {
|
|
constructor: Search,
|
|
|
|
destroy: function () {
|
|
this.$element.remove();
|
|
// any external bindings
|
|
// [none]
|
|
// set input value attrbute
|
|
this.$element.find('input').each(function () {
|
|
$(this).attr('value', $(this).val());
|
|
});
|
|
// empty elements to return to original markup
|
|
// [none]
|
|
// returns string of markup
|
|
return this.$element[0].outerHTML;
|
|
},
|
|
|
|
search: function (searchText) {
|
|
if (this.$icon.hasClass('glyphicon')) {
|
|
this.$icon.removeClass('glyphicon-search').addClass('glyphicon-remove');
|
|
}
|
|
if (this.$icon.hasClass('fuelux-icon')) {
|
|
this.$icon.removeClass('fuelux-icon-search').addClass('fuelux-icon-remove');
|
|
}
|
|
|
|
this.activeSearch = searchText;
|
|
this.$element.addClass('searched pending');
|
|
this.$element.trigger('searched.fu.search', searchText);
|
|
},
|
|
|
|
clear: function () {
|
|
if (this.$icon.hasClass('glyphicon')) {
|
|
this.$icon.removeClass('glyphicon-remove').addClass('glyphicon-search');
|
|
}
|
|
if (this.$icon.hasClass('fuelux-icon')) {
|
|
this.$icon.removeClass('fuelux-icon-remove').addClass('fuelux-icon-search');
|
|
}
|
|
|
|
if (this.$element.hasClass('pending')) {
|
|
this.$element.trigger('canceled.fu.search');
|
|
}
|
|
|
|
this.activeSearch = '';
|
|
this.$input.val('');
|
|
this.$element.trigger('cleared.fu.search');
|
|
this.$element.removeClass('searched pending');
|
|
},
|
|
|
|
clearPending: function () {
|
|
this.$element.removeClass('pending');
|
|
},
|
|
|
|
action: function () {
|
|
var val = this.$input.val();
|
|
|
|
if (val && val.length > 0) {
|
|
this.search(val);
|
|
} else {
|
|
this.clear();
|
|
}
|
|
},
|
|
|
|
buttonclicked: function (e) {
|
|
e.preventDefault();
|
|
if ($(e.currentTarget).is('.disabled, :disabled')) return;
|
|
|
|
if (this.$element.hasClass('pending') || this.$element.hasClass('searched')) {
|
|
this.clear();
|
|
} else {
|
|
this.action();
|
|
}
|
|
},
|
|
|
|
keypress: function (e) {
|
|
var ENTER_KEY_CODE = 13;
|
|
var TAB_KEY_CODE = 9;
|
|
var ESC_KEY_CODE = 27;
|
|
|
|
if (e.which === ENTER_KEY_CODE) {
|
|
e.preventDefault();
|
|
this.action();
|
|
} else if (e.which === TAB_KEY_CODE) {
|
|
e.preventDefault();
|
|
} else if (e.which === ESC_KEY_CODE) {
|
|
e.preventDefault();
|
|
this.clear();
|
|
} else if (this.options.searchOnKeyPress) {
|
|
// search on other keypress
|
|
this.action();
|
|
}
|
|
},
|
|
|
|
disable: function () {
|
|
this.$element.addClass('disabled');
|
|
this.$input.attr('disabled', 'disabled');
|
|
|
|
if (!this.options.allowCancel) {
|
|
this.$button.addClass('disabled');
|
|
}
|
|
},
|
|
|
|
enable: function () {
|
|
this.$element.removeClass('disabled');
|
|
this.$input.removeAttr('disabled');
|
|
this.$button.removeClass('disabled');
|
|
}
|
|
};
|
|
|
|
|
|
// SEARCH PLUGIN DEFINITION
|
|
|
|
$.fn.search = function (option) {
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
var methodReturn;
|
|
|
|
var $set = this.each(function () {
|
|
var $this = $(this);
|
|
var data = $this.data('fu.search');
|
|
var options = typeof option === 'object' && option;
|
|
|
|
if (!data) {
|
|
$this.data('fu.search', (data = new Search(this, options)));
|
|
}
|
|
|
|
if (typeof option === 'string') {
|
|
methodReturn = data[option].apply(data, args);
|
|
}
|
|
});
|
|
|
|
return (methodReturn === undefined) ? $set : methodReturn;
|
|
};
|
|
|
|
$.fn.search.defaults = {
|
|
clearOnEmpty: false,
|
|
searchOnKeyPress: false,
|
|
allowCancel: false
|
|
};
|
|
|
|
$.fn.search.Constructor = Search;
|
|
|
|
$.fn.search.noConflict = function () {
|
|
$.fn.search = old;
|
|
return this;
|
|
};
|
|
|
|
|
|
// DATA-API
|
|
|
|
$(document).on('mousedown.fu.search.data-api', '[data-initialize=search]', function (e) {
|
|
var $control = $(e.target).closest('.search');
|
|
if (!$control.data('fu.search')) {
|
|
$control.search($control.data());
|
|
}
|
|
});
|
|
|
|
// Must be domReady for AMD compatibility
|
|
$(function () {
|
|
$('[data-initialize=search]').each(function () {
|
|
var $this = $(this);
|
|
if ($this.data('fu.search')) return;
|
|
$this.search($this.data());
|
|
});
|
|
});
|
|
|
|
// -- BEGIN UMD WRAPPER AFTERWORD --
|
|
}));
|
|
// -- END UMD WRAPPER AFTERWORD --
|