Skip to content

Instantly share code, notes, and snippets.

@Kcko
Last active December 14, 2019 14:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kcko/736aeb0efc6e32b399b70aecb73e7ffd to your computer and use it in GitHub Desktop.
Save Kcko/736aeb0efc6e32b399b70aecb73e7ffd to your computer and use it in GitHub Desktop.
/*!
* AW Eshop Filters
*
*
* @author Roman Janko <janko@andweb.cz>
* @since 30.01.2019 09:59:25
* @version 1.0.0
*
*/
;(function() {
'use strict';
function awEshopFilters(element, options) {
this.self = $(element);
this.settings = $.extend(true, {}, $.fn.awEshopFilters.defaults, options);
this.mainButton = $(this.settings.mainButton);
this.filterBody = $(this.settings.filterBody);
this.filterList = $(this.settings.filterList);
this.filterGroups = $(this.settings.filterGroups);
this.selectedFilterWrapper = $(this.settings.selectedFilterWrapper);
this.selectedFilterHeading = $(this.settings.selectedFilterHeading);
this.selectedFilterSet = $(this.settings.selectedFilterSet);
this.deleteAllFiltersBtn = $(this.settings.deleteAllFiltersBtn);
}
awEshopFilters.prototype = {
/* PRIVATE METHODS */
_create: function() {
this._bindMainButton();
this._bindFilterLinkClick();
this._bindFilterGroupItemClick();
this._bindFilterGroupItemSliderChange();
this._bindDeleleteAllFiltersBtn();
this._updateFilterSetState();
},
_bindMainButton: function() {
var that = this;
this.mainButton.on('click', function(e) {
e.preventDefault();
var $this = $(this);
var opened = $this.data('state') || 'closed'; // default state
var effect = that.settings.animation ? 'slideToggle' : 'toggle';
if (opened == 'closed') {
$this.data('state', 'opened');
$this.find('i').removeClass().addClass(that.settings.mainButtonClasses.opened);
} else {
$this.data('state', 'closed');
$this.find('i').removeClass().addClass(that.settings.mainButtonClasses.closed);
}
that.filterBody[effect]();
});
},
/**
* Current active list item from filter on left side
*/
_getGroup: function(groupId) {
var item = this.filterList
.find('li[data-groupid="'+groupId+'"]')
.children('a');
return {
'rank': item.parent().data('rank'),
'id': item.parent().data('groupid'),
'text': item.text(),
'item': item
}
},
_bindFilterLinkClick: function() {
var that = this;
this.filterList.find('a').on('click', function(e) {
e.preventDefault();
$('html, body').animate({
scrollTop: that.filterList.offset().top - 100
});
var $this = $(this);
var $parent = $this.parent();
var hasChildren = $parent.data('has-children') || 0;
var id = $parent.data('groupid');
that.filterList
.find('li')
.removeClass('active');
$parent
.addClass('active');
that.filterGroups
.hide();
that.filterGroups
.children()
.hide();
if (hasChildren) {
$parent
.children('ul')
.toggle();
var isVisible = $parent.children('ul').is(":visible") || 0;
$parent
.children('a')
.children('i')
.removeClass(function(i, s) {
$(this)
.removeClass(that.settings.filterLinkChildrenClass.closed)
.removeClass(that.settings.filterLinkChildrenClass.opened)
.addClass(
!isVisible ? that.settings.filterLinkChildrenClass.opened : that.settings.filterLinkChildrenClass.closed);
});
}
var foundedSomeGroup = that.filterGroups
.find('[data-groupid="'+id+'"]');
if (foundedSomeGroup.length) {
that.filterGroups.show();
foundedSomeGroup.show();
}
}).filter(':first').trigger('click');
},
_group: function() {
var that = this;
var add = function(group) {
var newGroup = $('<div>').attr('data-group', group.id)
.attr('data-rank', group.rank)
.html('<div>' + group.text + '</div>')
.appendTo(that.selectedFilterSet);
newGroup.append('<div>');
return newGroup;
};
var exists = function(groupId) {
var group = that.selectedFilterSet.find('[data-group="'+groupId+'"]');
return group.length > 0;
};
var remove = function(group) {
group.remove();
};
var removeGroupIsEmpty = function(groupId) {
var group = that.selectedFilterSet.find('[data-group="'+groupId+'"]');
if (group.find('a').length === 0) {
remove(group);
}
};
return {
add: add,
exists: exists,
remove: remove,
removeGroupIsEmpty: removeGroupIsEmpty
}
},
_bindFilterGroupItemSliderChange: function() {
var that = this;
that.filterGroups.on('change', '.range-slider-default', function(e) {
var $slider = $(this);
var from = $slider.data("from");
var to = $slider.data("to");
var value = $slider.prop("value").split(';'); // human readable values = text values
var group = that._getGroup($slider.data('groupid')); // curent active group
var dataValues = $slider.data('values').split(',');
// group doesnt exist yet, so we will add it
if (!that._group().exists(group.id)) {
var newGroup = that._group().add(group);
}
// target place for inserting a new selected range values
var targetPlace = $(that.selectedFilterSet).find('[data-group="'+group.id+'"]').find('div').eq(1);
// flush old value
targetPlace.empty();
// reset to default, because we are selecting default range, so we dont want to show it
if ($slider.data('range').length === dataValues.length) {
that._group().removeGroupIsEmpty(group.id);
that._showOrHideDeleteAllFiltersBtn();
that._updateFilterSetState();
return; // SKIP ...
}
var tpl = that.settings.selectedFilterItemTemplate;
var compiledTpl = tpl
.replace('{{name}}', value[0] + ' - ' + value[1])
.replace('{{itemid}}', $slider.data('itemid'));
var $filterItem = $(compiledTpl);
$filterItem.on('click.eshop-filter-item-slider', function(e) {
e.preventDefault();
that._resetSliderToDefault($slider);
that._removeFilterSlider($filterItem);
that._group().removeGroupIsEmpty(group.id);
that._showOrHideDeleteAllFiltersBtn();
that._updateFilterSetState();
//@TODO: callback will be applied from outside when we remove this
}).appendTo(targetPlace);
that._showOrHideDeleteAllFiltersBtn();
that._updateFilterSetState();
});
},
_bindFilterGroupItemClick: function() {
var that = this;
that.filterGroups.on('click filter:init', 'input[type="checkbox"]', function(e) {
var $checkbox = $(this);
var $label = $checkbox.parent().next('label');
var group = that._getGroup($checkbox.data('groupid')); // curent active group
// Has been added?
var $hasBeenAdded = that.selectedFilterSet
.find('[data-itemid="'+$checkbox.data('itemid')+'"]');
// group doesnt exist yet, so we will add it
if (!that._group().exists(group.id)) {
var newGroup = that._group().add(group);
}
// item has been already added?
if ($hasBeenAdded.length > 0) {
that._removeFilter($hasBeenAdded);
that._unselectCheckbox($checkbox);
that._group().removeGroupIsEmpty(group.id);
that._updateFilterSetState();
that.settings.selectedFilterItemClick.apply(that, [$hasBeenAdded, $checkbox, $label]);
return;
}
var tpl = that.settings.selectedFilterItemTemplate;
var compiledTpl = tpl
.replace('{{name}}', $label.text())
.replace('{{itemid}}', $checkbox.data('itemid'));
var $filterItem = $(compiledTpl);
$filterItem.on('click.eshop-filter-item', function(e, skipClick) {
e.preventDefault();
that._removeFilter($filterItem);
that._unselectCheckbox($checkbox);
that._group().removeGroupIsEmpty(group.id);
that._updateFilterSetState();
if(!skipClick)
that.settings.selectedFilterItemClick.apply(that, [$filterItem, $checkbox, $label]);
}).appendTo($(that.selectedFilterSet).find('[data-group="'+group.id+'"]').find('div').eq(1));
that._showOrHideDeleteAllFiltersBtn();
that._updateFilterSetState();
}).find('input[type="checkbox"]:checked').trigger('filter:init');
},
_bindDeleleteAllFiltersBtn: function() {
var that = this;
this.deleteAllFiltersBtn.on('click', function(e) {
var selectedFilterItems = that._getSelectedFilterItems();
selectedFilterItems.each(function() {
var $item = $(this);
$item.trigger('click.eshop-filter-item', [true]);
$item.trigger('click.eshop-filter-item-slider', [true]);
});
that.settings.deleteAllClick.apply(that);
});
},
_unselectCheckbox: function(checkbox) {
checkbox.prop('checked', false);
},
_removeFilter: function(o) {
o.off('.click.eshop-filter-item');
o.remove();
this._showOrHideDeleteAllFiltersBtn();
},
_removeFilterSlider: function(o) {
o.off('.click.eshop-filter-item-slider');
o.remove();
this._showOrHideDeleteAllFiltersBtn();
},
_resetSliderToDefault: function($slider) {
$slider.data("ionRangeSlider").reset();
},
_showOrHideDeleteAllFiltersBtn: function() {
var hasSomeFilterInside = this._getSelectedFilterItems();
if (hasSomeFilterInside.length === 0)
this.deleteAllFiltersBtn.addClass('-nod');
else
this.deleteAllFiltersBtn.removeClass('-nod');
},
_updateFilterSetState: function() {
var hasSomeFilterInside = this._getSelectedFilterItems();
if (hasSomeFilterInside.length === 0) {
this.selectedFilterWrapper.addClass('nod');
//this.selectedFilterSet.html('<p class="eshop-menu-filters__text-nothing-selected">' + this.selectedFilterSet.data('empty-text') + '</p>');
} else {
//this.selectedFilterSet.find('p.eshop-menu-filters__text-nothing-selected').remove();
this.selectedFilterWrapper.removeClass('nod');
}
},
_getSelectedFilterItems: function() {
return this.selectedFilterSet.find('a[data-itemid]');
},
/* PUBLIC METHODS */
update: function(data, cntKey) {
for (let k in data) {
var $input = this.filterGroups.find('[data-itemid="'+k+'"]');
if ($input.length) {
this.filterGroups.find('[data-count-itemid="'+k+'"]').text(data[k][cntKey]);
this.selectedFilterSet.find('[data-itemid="'+k+'"]').text($input.parent().next('label').text());
}
}
}
};
(function ($) {
$.fn.awEshopFilters = function(options) {
var
args = Array.prototype.slice.call(arguments, 1),
method = awEshopFilters.prototype[options];
return this.each(function() {
var self = $(this);
var instance = self.data('awEshopFilters');
if (!instance) {
instance = new awEshopFilters(this, options);
instance._create();
self.data('awEshopFilters', instance);
}
if (method && options.substring(0, 1) == '_')
$.error('Cannot use private method "' + options + '" outside of object');
if (method) {
method.apply(instance, args);
} else if (options && typeof options !== 'object') {
$.error('Method "' + options + '" not found.');
}
});
};
$.fn.awEshopFilters.defaults = {
animation: false,
animationSpeed: 0,
mainButton: '.eshop-menu-filters__main-button', // main toggler button = reveal below groups, is connected with filterBody
mainButtonClasses: {
opened: 'fa fa-angle-down',
closed: 'fa fa-angle-up',
},
filterBody: '.eshop-menu-filters__body',
filterList: '.eshop-menu-filters__filter-list', // menu with filter links
filterGroups: '.eshop-menu-filters__filter-groups', // aside filter groups = will be filtered by links in left menu
filterLinkChildrenClass: { // link with children classes for icon
opened: 'fa fa-plus-square',
closed: 'fa fa-minus-square',
},
selectedFilterWrapper: '.eshop-menu-filters__selected-filters', // wrapper for selected filters and textual information
selectedFilterHeading: '.eshop-menu-filters__selected-filter-heading', // title for selected filter name
selectedFilterSet: '.eshop-menu-filters__selected-filters-set',
deleteAllFiltersBtn: '.eshop-menu-filters__delete-all-filters',
selectedFilterItemTemplate: '<a href="#" class="badge badge-secondary mr-2 mb-2 p-1" data-itemid="{{itemid}}">{{name}}</a>',
selectedFilterItemClick: function(filterItem, checkbox, label) {
},
deleteAllClick: function() {
}
};
})(jQuery);
})();
/*!
* AW RANGE SLIDER
*
*
* @author Roman Janko <janko@andweb.cz>
* @version 1.0.0
*
*/
/*
AW RANGE SLIDER - wrapper over Range Slider http://ionden.com/a/plugins/ion.rangeSlider/index.html
*/
;(function() {
'use strict';
function awRangeSlider(element, options) {
this.self = element;
this.$self = $(element);
this.settings = $.extend(true, {}, $.fn.awRangeSlider.defaults, options);
this.instance = null;
this.ourFormControls = {
priceFrom: null,
priceTo: null,
select: null
};
}
awRangeSlider.prototype = {
/* PRIVATE METHODS */
_create: function() {
var oldOnFinish = this.settings.onFinish;
var that = this;
this.settings.onFinish = function(data) {
that.instance.trigger("finish");
oldOnFinish.apply(this, [data]);
};
this.instance = this.$self.ionRangeSlider(this.settings);
if (this.settings.sliderType == 'price') {
this._bindOnChangePrice();
} else {
this._bindOnChangeDefault();
}
},
_bindOnChangePrice: function() {
var that = this;
this.ourFormControls.priceFrom = this.$self.next();
this.ourFormControls.priceTo = this.$self.next().next();
this.instance.on("finish", function (e) {
var $inp = $(this);
var from = $inp.data("from");
var to = $inp.data("to");
that.ourFormControls.priceFrom.val(from).trigger('change');
that.ourFormControls.priceTo.val(to).trigger('change');
});
},
_bindOnChangeDefault: function() {
var that = this;
var select = this.ourFormControls.select = this.$self.next();
var options = select.find('option');
this._resetOptions(options);
//this._setSelectedAllOptions(options);
this.instance.on("finish", function (e) {
var $inp = $(this);
var dataValues = $inp.data('values').split(',');
var from = $inp.data("from");
var to = $inp.data("to");
var values = $inp.prop("value").split(';'); // human readable values = text values
var range = that._createRange(from, to);
$inp.data('range', range);
that._resetOptions(options);
// loop over selected items only when if we do not choose everything, it does not make a sense
if (dataValues.length != range.length) {
range.forEach(function(i) {
that._setSelectedOption(options.eq(i));
});
}
});
},
_createRange: function(start, end) {
var range = [];
for (var i = start; i <= end; i++) {
range.push(i);
}
return range;
},
_resetOptions: function(options) {
options.prop('selected', false);
},
_setSelectedOption: function(option) {
option.prop('selected', true);
},
_setSelectedAllOptions: function(options) {
options.prop('selected', true);
},
/* PUBLIC METHODS */
updateMinMax: function(min, max) {
var update = {
min: min,
//from: min,
max: max,
//to: max,
};
if(this.$self.data('min') == this.$self.data('from') || update.min >= this.$self.data('from')) {
update.from = update.min;
}
if(this.$self.data('max') == this.$self.data('to') || update.max <= this.$self.data('to')) {
update.to = update.max;
}
this.$self.data('min', update.min);
this.$self.data('max', update.max);
var inst = this.$self.data("ionRangeSlider");
inst.update(update);
}
};
(function ($) {
$.fn.awRangeSlider = function(options) {
var
args = Array.prototype.slice.call(arguments, 1),
method = awRangeSlider.prototype[options];
return this.each(function() {
var self = $(this);
var instance = self.data('awRangeSlider');
if (!instance) {
instance = new awRangeSlider(this, options);
instance._create();
self.data('awRangeSlider', instance);
}
if (method && options.substring(0, 1) == '_')
$.error('Cannot use private method "' + options + '" outside of object');
if (method) {
method.apply(instance, args);
} else if (options && typeof options !== 'object') {
$.error('Method "' + options + '" not found.');
}
});
};
$.fn.awRangeSlider.defaults = {
sliderType: 'price' // price || default
};
})(jQuery);
})();
/**
* jQuery Capty - A Caption Plugin - http://wbotelhos.com/capty
* ---------------------------------------------------------------------------------
*
* jQuery Capty is a plugin that creates captions over the images.
*
* Licensed under The MIT License
*
* @version 0.2.1
* @since 12.18.2010
* @author Washington Botelho dos Santos
* @documentation wbotelhos.com/capty
* @twitter twitter.com/wbotelhos
* @license opensource.org/licenses/mit-license.php MIT
* @package jQuery Plugins
*
* Usage with default values:
* ---------------------------------------------------------------------------------
* $('#capty').capty();
*
* <img id="capty" src="image.jpg" alt="Super Mario Bros.&reg;" width="150" height="150"/>
*
*/
;(function($) {
$.fn.capty = function(settings) {
var options = $.extend({}, $.fn.capty.defaults, settings);
if (this.length == 0) {
debug('Selector invalid or missing!');
return;
} else if (this.length > 1) {
return this.each(function() {
$.fn.capty.apply($(this), [settings]);
});
}
var $this = $(this),
name = $this.attr('name'),
$caption = $('<div class="' + options.cCaption + '"/>'),
$elem = $this;
if ($this.parent().is('a')) {
$elem = $this.parent();
}
var $image = $elem.wrap('<div class="' + options.cImage + '"/>').parent(),
$wrapper = $image.wrap('<div class="' + options.cWrapper + '"/>').parent();
$wrapper.css({
height: $this.height(),
overflow: 'hidden',
position: 'relative',
width: $this.width()
});
$caption.css({
height: options.height,
opacity: options.opacity,
position: 'relative'
})
.click(function(evt) {
evt.stopPropagation();
})
.appendTo($wrapper);
if (name) {
var $content = $(name);
if ($content.length) {
$content.appendTo($caption);
} else {
$caption.html('<span style="color: #F00;">Content invalid or missing!</span>');
}
} else {
$caption.html($this.attr('alt'));
}
if (options.prefix) {
$caption.prepend(options.prefix);
}
if (options.sufix) {
$caption.append(options.sufix);
}
if (options.animation == 'slide') {
$wrapper.hover(
function() {
$caption.animate({ top: (-1 * options.height) }, { duration: options.speed, queue: false });
},
function() {
$caption.animate({ top: 0 }, { duration: options.speed, queue: false });
}
);
} else if (options.animation == 'fade') {
$caption.css({
opacity: 0,
top: (-1 * options.height) + 'px'
});
$wrapper.hover(
function() {
$caption.stop().animate({ opacity: options.opacity }, options.speed);
},
function() {
$caption.stop().animate({ opacity: 0 }, options.speed);
}
);
} else if (options.animation == 'fixed') {
$caption.css('top', (-1 * options.height) + 'px');
} else {
debug($this.attr('id') + ': invalid animation!');
}
return $this;
};
function debug(message) {
if (window.console && window.console.log) {
window.console.log(message);
}
};
$.fn.capty.defaults = {
animation: 'slide',
cCaption: 'capty-caption',
cImage: 'capty-image',
cWrapper: 'capty-wrapper',
height: 30,
opacity: .7,
prefix: '',
speed: 200,
sufix: ''
};
})(jQuery);
/*!
* jQuery Checkall - A Checkbox Checker
*
* The MIT License
*
* author: Washington Botelho
* github: wbotelhos/checkall
* version: 0.1.0
*
*/
function Checkall(element, options) {
'use strict';
this.self = $(element);
this.opt = $.extend(true, {}, $.fn.checkall.defaults, options);
this.all = this.self.find(this.opt.all);
this.items = this.self.find(this.opt.item);
this.total = this.items.length;
}
Checkall.prototype._bindAll = function() {
'use strict';
var that = this;
this.all.on('change', function() {
that.items.prop('checked', this.checked);
});
};
Checkall.prototype._bindItems = function() {
'use strict';
this.items.on('change', this._inspect.bind(this));
};
Checkall.prototype._create = function() {
'use strict';
this._bindAll();
this._bindItems();
this._inspect();
};
Checkall.prototype._inspect = function() {
'use strict';
var checked = this.items.filter(':checked');
this.all.prop('checked', checked.length === this.total);
};
(function($) {
'use strict';
$.fn.checkall = function(options) {
var
args = Array.prototype.slice.call(arguments, 1),
method = Checkall.prototype[options];
return this.each(function() {
var
self = $(this),
instance = self.data('checkall');
if (!instance) {
instance = new Checkall(this, options);
instance._create();
self.data('checkall', instance);
}
if (method) {
method.apply(instance, args);
} else if (options && typeof options !== 'object') {
$.error('Method "' + options + '" not found.');
}
});
};
$.fn.checkall.defaults = {
all: '.checkall__all',
item: '.checkall__item'
};
})(jQuery);
/*!
* jQuery Checky - A Checkbox Restrictor
*
* The MIT License
*
* @author : Washington Botelho
* @doc : http://wbotelhos.com/checky
* @version : 0.1.0
*
*/
// done
function Checky(element, options) {
'use strict';
this.element = element;
this.self = $(element);
this.opt = $.extend(true, {}, $.fn.checky.defaults, options);
this.items = this.self.find(this.opt.item);
this.total = this.items.length;
this.checkeds = [];
}
// done
Checky.prototype._addInitials = function() {
'use strict';
var that = this;
this._checkeds().each(function() {
that.checkeds.push(this);
});
};
// done
Checky.prototype._addOrRemove = function(item) {
'use strict';
if (item.checked) {
this.checkeds.push(item);
} else {
var index = this.checkeds.indexOf(item);
if (index >= 0) {
this.checkeds.splice(index, 1);
}
this._enableOrDisable();
}
};
// done
Checky.prototype._bindItems = function() {
'use strict';
var that = this;
that.items.on('change', function() {
if (that.opt.type === 'radio') {
that._clean(this);
} else {
that._addOrRemove(this);
that._inspect();
}
});
};
// done
Checky.prototype._clean = function(item) {
'use strict';
this.items.filter(function() {
return this !== item;
}).removeAttr('checked');
};
// done
Checky.prototype._configure = function() {
'use strict';
if (this.opt.type === 'radio') {
this.opt.min = 0;
this.opt.max = 1;
}
};
// done
Checky.prototype._create = function() {
'use strict';
this._configure();
this._bindItems();
if (this.opt.type !== 'radio') {
this._addInitials();
this._inspect();
}
};
// done
Checky.prototype._checkeds = function() {
'use strict';
return this.items.filter(':checked');
};
// done
Checky.prototype._disable = function(boo) {
'use strict';
boo = boo === undefined || boo;
for (var i = 0; i < this.items.length; i++) {
if (this.checkeds.indexOf(this.items[i]) < 0) {
this.items[i].disabled = boo;
}
}
};
// done
Checky.prototype._enableOrDisable = function() {
'use strict';
if (this.opt.style === 'disable') {
this._disable(false);
}
};
// done
Checky.prototype._max = function() {
'use strict';
return this.opt.max && this._checkeds().length >= this.opt.max;
};
// done
Checky.prototype._min = function() {
'use strict';
return this.opt.min && this._checkeds().length < this.opt.min;
};
// done
Checky.prototype._select = function(item) {
'use strict';
item.checked = true;
this.checkeds.push(item);
};
// done
Checky.prototype._inspect = function() {
'use strict';
if (this._max()) {
this['_' + this.opt.style].call(this);
} else if (this._min()) {
var uncheckeds = this._uncheckeds();
for (var i = 0; i < this._toSelect(); i++) {
this._select(uncheckeds[i]);
}
}
};
// done
Checky.prototype._toSelect = function() {
'use strict';
if (!this.opt.min) {
return 0;
}
return this.opt.min - this._checkeds().length;
};
// done
Checky.prototype._uncheckeds = function() {
'use strict';
return this.items.filter(':not(:checked)');
};
// done
Checky.prototype._unselect = function() {
'use strict';
var item = this.checkeds.shift();
item.checked = false;
};
(function($) {
'use strict';
// done
$.fn.checky = function(options) {
var
args = Array.prototype.slice.call(arguments, 1),
method = Checky.prototype[options];
return this.each(function() {
var
self = $(this),
instance = self.data('checky');
if (!instance) {
instance = new Checky(this, options);
instance._create();
self.data('checky', instance);
}
if (method) {
method.apply(instance, args);
} else if (options && typeof options !== 'object') {
$.error('Method ' + options + ' does not exist!');
}
});
};
// done
$.fn.checky.defaults = {
item : '.checky',
max : undefined,
min : undefined,
style : 'disable',
type : 'checkbox'
};
})(jQuery);
/*!
* jQuery Complety - An Auto Complete Plugin
*
* The MIT License
*
* @author : Washington Botelho
* @doc : http://wbotelhos.com/complety
* @version : 0.1.1
*
*/
;(function() {
'use strict';
var keys = {
ALT: 18,
BACKSPACE: 8,
COMMAND: 91,
CTRL: 17,
DOWN: 40,
ENTER: 13,
ESC: 27,
LEFT: 37,
RIGHT: 39,
SHIFT: 16,
TAB: 9,
UP: 38
};
function Complety(el, options) {
this.el = el;
this.self = $(el);
this.opt = $.extend(true, {}, $.fn.complety.defaults, options);
}
Complety.prototype = {
_able: function() {
return this.currentValue && this.currentValue.length >= this.opt.minChars;
},
_ajax: function(url) {
this.loader('start');
var ajax = $.ajax(url);
if (this.xhrs.length) {
this.abort();
}
this.xhrs.push(ajax);
return ajax;
},
_always: function(json) {
this.loader('stop');
if ($.isFunction(this.opt.ajax.always)) {
this.opt.ajax.always.call(this, json);
}
},
_assigns: function() {
this.xhrs = [];
},
_binds: function() {
var that = this;
this.self.on('keydown.complety', function(evt) {
var
key = evt.which || evt.keyCode,
stopped = [keys.ENTER, keys.DOWN, keys.UP];
if (stopped.indexOf(key) >= 0) {
that._stop(evt);
}
});
this.self.on('keyup.complety', function(evt) {
that._onKeyUp(evt, this.value);
});
this.target.on('click.complety', this.opt.wrappers.item, function() {
that._select(this);
});
this.target.on('mouseenter.complety', this.opt.wrappers.item, function() {
that._hover(this);
});
},
_cache: function(json) {
this.opt.cache[this.url()] = json;
},
_clearDelay: function() {
clearTimeout(this.timeout);
},
_create: function() {
this._findWrappers();
this._assigns();
this._prepare();
this._binds();
this._map();
return this;
},
_decide: function(key) {
var action = this.actions[key];
if (action) {
action.call(this);
} else if (!this._isIgnoredKey(key)) {
this._search();
}
},
_done: function(json) {
if (json.length) {
this._cache(json);
this._render(json);
} else {
this._none();
}
if ($.isFunction(this.opt.ajax.done)) {
this.opt.ajax.done.call(this, json);
}
},
_fail: function(json) {
if (json.statusText !== 'abort' && $.isFunction(this.opt.ajax.fail)) {
this.opt.ajax.fail.call(this, json);
}
},
_findWrappers: function() {
this._setFieldWrapper();
this._setWrapper();
this._setNoneWrapper();
this._setTargetWrapper();
},
_getValue: function(suggestion) {
if ($.isFunction(this.opt.functions.getValue)) {
return this.opt.functions.getValue.call(this, suggestion);
}
return suggestion.id;
},
_highlight: function(suggestion) {
var highlight = $.extend(true, {}, suggestion);
for (var i = 0; i < this.opt.keys.length; i++) {
var
path = this.opt.keys[i].split('.'),
regex = new RegExp('(' + this.self.val() + ')', 'i'),
value = suggestion;
for (var j = 0; j < path.length; j++) {
value = value[path[j]];
}
if (value) {
highlight[this.opt.keys[i]] = value.replace(regex, '<b>$1</b>');
} else {
$.error('Missing key: ' + this.opt.keys[i]);
}
}
return highlight;
},
_highlights: function() {
var that = this;
return this.currentSuggestions.map(function(suggestion) {
return that._highlight(suggestion);
});
},
_highlightItem: function(number) {
var
index = number % this.target.data('total'),
clazz = this.opt.wrappers.itemSelected.replace('.', '');
this
.target
.data('current', index)
.find(this.opt.wrappers.item)
.removeClass(clazz)
.eq(index)
.addClass(clazz);
},
_hover: function(item) {
var items = this.target.find(this.opt.wrappers.item);
items.removeClass(this.opt.wrappers.itemSelected.replace('.', ''));
$(item).addClass(this.opt.wrappers.itemSelected.replace('.', ''));
},
_hovered: function() {
return this.target.find(this.opt.wrappers.itemSelected);
},
_isIgnoredKey: function(key) {
return [
keys.ALT,
keys.COMMAND,
keys.CTRL,
keys.LEFT,
keys.RIGHT,
keys.SHIFT
].indexOf(key) >= 0;
},
_map: function() {
if (!this.actions || !Object.keys(this.actions).length) {
this.actions = {};
this.actions[keys.ESC] = this.hide;
this.actions[keys.TAB] = this.hide;
this.actions[keys.UP] = this._moveUp;
this.actions[keys.DOWN] = this._moveDown;
this.actions[keys.ENTER] = function() {
var item = this._hovered();
if (item.length) {
this._select(item);
this.hide();
}
};
}
},
_current: function() {
var hovered = this._hovered();
return (hovered && hovered.index()) || this.target.data('current');
},
_moveDown: function() {
var current = this._current();
this.show();
this._highlightItem((current === undefined ? -1 : current) + 1);
},
_moveUp: function() {
var current = this._current();
this.show();
this._highlightItem((current || this.target.data('total')) - 1);
},
_none: function() {
var value = this.self.val();
this.hide();
this.none.html(this.opt.templates.none({ q: value })).show();
this.self.trigger('none', [value, this]);
},
_onKeyUp: function(evt, value) {
var key = evt.which || evt.keyCode;
this.currentValue = $.trim(value);
// if (this.currentValue) { // serch field cleans on esc so the items does not hide
this._decide(key);
this._stop(evt);
// }
},
_prepare: function() {
this.self.prop('autocomplete', 'off');
if (this.opt.suggestion) {
this.suggest(this.opt.suggestion);
}
},
_query: function() {
if (this._able()) {
var cached = this.opt.cache[this.url()];
if (cached) {
this._always(cached);
this._done(cached);
} else {
var
ajax = this._ajax(this.url()),
that = this;
ajax.always(function(json) {
that._always(json);
});
ajax.done(function(json) {
that._done(json);
});
ajax.fail(function(json) {
that._fail(json);
});
}
}
},
_render: function(json) {
this.currentSuggestions = json;
var html = this.opt.templates.search({ list: this._highlights() });
this.none.hide().empty();
this.target.html(html).data('total', json.length);
this.show();
},
_search: function() {
if (this.timeout) {
this.loader('stop');
this._clearDelay();
}
this.timeout = setTimeout(this._query.bind(this), this.opt.delay);
},
_setFieldWrapper: function() {
this.field = this.self.parent(this.opt.wrappers.field);
if (!this.field.length) {
var wrapper = this._wrapperFor('field');
this.field = this.self.wrap(wrapper).parent();
}
},
_select: function(item) {
var index = this.target.find(this.opt.wrappers.item).index(item);
this.suggest(this.currentSuggestions[index]);
},
_selected: function(suggestion) {
this.hide();
this.currentSuggestion = suggestion;
this.self.trigger('selected', [suggestion, this]);
if ($.isFunction(this.opt.callbacks.selected)) {
this.opt.callbacks.selected.call(this, suggestion);
}
},
_setNoneWrapper: function() {
this.none = this.wrapper.find(this.opt.wrappers.none);
if (!this.none.length) {
this.none = this._wrapperFor('none').appendTo(this.wrapper);
}
},
_setTargetWrapper: function() {
this.target = this.wrapper.find(this.opt.wrappers.target);
if (!this.target.length) {
this.target = this._wrapperFor('target').appendTo(this.wrapper);
}
},
_setWrapper: function() {
this.wrapper = this.field.closest(this.opt.wrappers.wrapper);
if (!this.wrapper.length) {
var wrapper = this._wrapperFor('wrapper');
this.wrapper = this.field.wrap(wrapper).parent();
}
},
_stop: function(evt) {
evt.preventDefault();
evt.stopImmediatePropagation();
evt.stopPropagation();
},
_wrapperFor: function(name) {
return $('<div />', { 'class': this.opt.wrappers[name].replace('.', '') });
},
abort: function() {
for (var i = 0; i < this.xhrs.length; i++) {
this.xhrs[i].abort();
}
this.xhrs = [];
return this;
},
hide: function() {
this._clearDelay();
this.target.hide();
this.none.hide();
this.visible = false;
return this;
},
loader: function(action) {
var boo = action === 'start';
// this.loading.toggle(boo);
if (boo) {
this.field.addClass(this.opt.wrappers.loading);
} else {
this.field.removeClass(this.opt.wrappers.loading);
}
return this;
},
readonly: function(boo) {
this.self.prop('readonly', boo);
return this;
},
show: function() {
if (!this.visible && this._able()) {
this.target.show();
this.visible = true;
}
return this;
},
suggest: function(suggestion) {
var value = this._getValue(suggestion);
this.self.val(value);
this._selected(suggestion);
},
suggestion: function() {
return this.currentSuggestion;
},
suggestions: function() {
return this.currentSuggestions;
},
url: function() {
return (this.self.data('url') || this.opt.url).replace(':q', this.currentValue);
},
wrappers: function() {
return {
field: this.field,
loading: this.loading,
none: this.none,
target: this.target,
wrapper: this.wrapper
};
}
};
(function($) {
$.fn.complety = function(options) {
var instances = this.map(function() {
var
self = $(this),
instance = self.data('complety');
if (!instance) {
instance = new Complety(this, options);
instance._create();
self.data('complety', instance);
}
return instance;
});
if (instances.length === 1) {
return instances[0];
}
return instances;
};
$.fn.complety.defaults = {
cache: {},
delay: 300,
keys: undefined,
minChars: 1,
suggestion: undefined,
url: undefined,
callbacks: {
selected: undefined
},
functions: {
getValue: undefined
},
ajax: {
always: undefined,
done: undefined,
fail: undefined
},
wrappers: {
field: '.complety__field',
item: '.complety__item',
itemSelected: '.complety__item--selected',
list: '.complety__list',
loading: '.complety__loading',
none: '.complety__none',
target: '.complety__target',
wrapper: '.complety'
}
};
})(jQuery);
})();
/*!
* AW {{PROJECTNAME}}
*
*
* @author {{firstname lastname}} <{{email}}>
* @version 1.0.0
*
*/
/*
{{PLUGIN}} => realname of project, eg: awBestPlugin
*/
;(function() {
'use strict';
function {{PLUGIN}}(element, options) {
this.self = $(element);
this.settings = $.extend(true, {}, $.fn.{{PLUGIN}}.defaults, options);
}
{{PLUGIN}}.prototype = {
/* PRIVATE METHODS */
_create: function() {
}
/* PUBLIC METHODS */
};
(function ($) {
$.fn.{{PLUGIN}} = function(options) {
var
args = Array.prototype.slice.call(arguments, 1),
method = {{PLUGIN}}.prototype[options];
return this.each(function() {
var self = $(this);
var instance = self.data('{{PLUGIN}}');
if (!instance) {
instance = new {{PLUGIN}}(this, options);
instance._create();
self.data('{{PLUGIN}}', instance);
}
if (method && options.substring(0, 1) == '_')
$.error('Cannot use private method "' + options + '" outside of object');
if (method) {
method.apply(instance, args);
} else if (options && typeof options !== 'object') {
$.error('Method "' + options + '" not found.');
}
});
};
$.fn.{{PLUGIN}}.defaults = {
};
})(jQuery);
})();
/*
* jQuery StarRatingSvg v1.2.0
*
* http://github.com/nashio/star-rating-svg
* Author: Ignacio Chavez
* hello@ignaciochavez.com
* Licensed under MIT
*/
;(function ( $, window, document, undefined ) {
'use strict';
// Create the defaults once
var pluginName = 'starRating';
var noop = function(){};
var defaults = {
totalStars: 5,
useFullStars: false,
starShape: 'straight',
emptyColor: 'lightgray',
hoverColor: 'orange',
activeColor: 'gold',
ratedColor: 'crimson',
useGradient: true,
readOnly: false,
disableAfterRate: true,
baseUrl: false,
starGradient: {
start: '#FEF7CD',
end: '#FF9511'
},
strokeWidth: 4,
strokeColor: 'black',
initialRating: 0,
starSize: 40,
callback: noop,
onHover: noop,
onLeave: noop
};
// The actual plugin constructor
var Plugin = function( element, options ) {
var _rating;
var newRating;
var roundFn;
this.element = element;
this.$el = $(element);
this.settings = $.extend( {}, defaults, options );
// grab rating if defined on the element
_rating = this.$el.data('rating') || this.settings.initialRating;
// round to the nearest half
roundFn = this.settings.forceRoundUp ? Math.ceil : Math.round;
newRating = (roundFn( _rating * 2 ) / 2).toFixed(1);
this._state = {
rating: newRating
};
// create unique id for stars
this._uid = Math.floor( Math.random() * 999 );
// override gradient if not used
if( !options.starGradient && !this.settings.useGradient ){
this.settings.starGradient.start = this.settings.starGradient.end = this.settings.activeColor;
}
this._defaults = defaults;
this._name = pluginName;
this.init();
};
var methods = {
init: function () {
this.renderMarkup();
this.addListeners();
this.initRating();
},
addListeners: function(){
if( this.settings.readOnly ){ return; }
this.$stars.on('mouseover', this.hoverRating.bind(this));
this.$stars.on('mouseout', this.restoreState.bind(this));
this.$stars.on('click', this.handleRating.bind(this));
},
// apply styles to hovered stars
hoverRating: function(e){
var index = this.getIndex(e);
this.paintStars(index, 'hovered');
this.settings.onHover(index + 1, this._state.rating, this.$el);
},
// clicked on a rate, apply style and state
handleRating: function(e){
var index = this.getIndex(e);
var rating = index + 1;
this.applyRating(rating, this.$el);
this.executeCallback( rating, this.$el );
if(this.settings.disableAfterRate){
this.$stars.off();
}
},
applyRating: function(rating){
var index = rating - 1;
// paint selected and remove hovered color
this.paintStars(index, 'rated');
this._state.rating = index + 1;
this._state.rated = true;
},
restoreState: function(e){
var index = this.getIndex(e);
var rating = this._state.rating || -1;
// determine star color depending on manually rated
var colorType = this._state.rated ? 'rated' : 'active';
this.paintStars(rating - 1, colorType);
this.settings.onLeave(index + 1, this._state.rating, this.$el);
},
getIndex: function(e){
var $target = $(e.currentTarget);
var width = $target.width();
var side = $(e.target).attr('data-side');
var minRating = this.settings.minRating;
// hovered outside the star, calculate by pixel instead
side = (!side) ? this.getOffsetByPixel(e, $target, width) : side;
side = (this.settings.useFullStars) ? 'right' : side ;
// get index for half or whole star
var index = $target.index() - ((side === 'left') ? 0.5 : 0);
// pointer is way to the left, rating should be none
index = ( index < 0.5 && (e.offsetX < width / 4) ) ? -1 : index;
// force minimum rating
index = ( minRating && minRating <= this.settings.totalStars && index < minRating ) ? minRating - 1 : index;
return index;
},
getOffsetByPixel: function(e, $target, width){
var leftX = e.pageX - $target.offset().left;
return ( leftX <= (width / 2) && !this.settings.useFullStars) ? 'left' : 'right';
},
initRating: function(){
this.paintStars(this._state.rating - 1, 'active');
},
paintStars: function(endIndex, stateClass){
var $polygonLeft;
var $polygonRight;
var leftClass;
var rightClass;
$.each(this.$stars, function(index, star){
$polygonLeft = $(star).find('[data-side="left"]');
$polygonRight = $(star).find('[data-side="right"]');
leftClass = rightClass = (index <= endIndex) ? stateClass : 'empty';
// has another half rating, add half star
leftClass = ( index - endIndex === 0.5 ) ? stateClass : leftClass;
$polygonLeft.attr('class', 'svg-' + leftClass + '-' + this._uid);
$polygonRight.attr('class', 'svg-' + rightClass + '-' + this._uid);
}.bind(this));
},
renderMarkup: function () {
var s = this.settings;
var baseUrl = s.baseUrl ? location.href.split('#')[0] : '';
// inject an svg manually to have control over attributes
var star = '<div class="jq-star" style="width:' + s.starSize+ 'px; height:' + s.starSize + 'px;"><svg version="1.0" class="jq-star-svg" shape-rendering="geometricPrecision" xmlns="http://www.w3.org/2000/svg" ' + this.getSvgDimensions(s.starShape) + ' stroke-width:' + s.strokeWidth + 'px;" xml:space="preserve"><style type="text/css">.svg-empty-' + this._uid + '{fill:url(' + baseUrl + '#' + this._uid + '_SVGID_1_);}.svg-hovered-' + this._uid + '{fill:url(' + baseUrl + '#' + this._uid + '_SVGID_2_);}.svg-active-' + this._uid + '{fill:url(' + baseUrl + '#' + this._uid + '_SVGID_3_);}.svg-rated-' + this._uid + '{fill:' + s.ratedColor + ';}</style>' +
this.getLinearGradient(this._uid + '_SVGID_1_', s.emptyColor, s.emptyColor, s.starShape) +
this.getLinearGradient(this._uid + '_SVGID_2_', s.hoverColor, s.hoverColor, s.starShape) +
this.getLinearGradient(this._uid + '_SVGID_3_', s.starGradient.start, s.starGradient.end, s.starShape) +
this.getVectorPath(this._uid, {
starShape: s.starShape,
strokeWidth: s.strokeWidth,
strokeColor: s.strokeColor
} ) +
'</svg></div>';
// inject svg markup
var starsMarkup = '';
for( var i = 0; i < s.totalStars; i++){
starsMarkup += star;
}
this.$el.append(starsMarkup);
this.$stars = this.$el.find('.jq-star');
},
getVectorPath: function(id, attrs){
return (attrs.starShape === 'rounded') ?
this.getRoundedVectorPath(id, attrs) : this.getSpikeVectorPath(id, attrs);
},
getSpikeVectorPath: function(id, attrs){
return '<polygon data-side="center" class="svg-empty-' + id + '" points="281.1,129.8 364,55.7 255.5,46.8 214,-59 172.5,46.8 64,55.4 146.8,129.7 121.1,241 212.9,181.1 213.9,181 306.5,241 " style="fill: transparent; stroke: ' + attrs.strokeColor + ';" />' +
'<polygon data-side="left" class="svg-empty-' + id + '" points="281.1,129.8 364,55.7 255.5,46.8 214,-59 172.5,46.8 64,55.4 146.8,129.7 121.1,241 213.9,181.1 213.9,181 306.5,241 " style="stroke-opacity: 0;" />' +
'<polygon data-side="right" class="svg-empty-' + id + '" points="364,55.7 255.5,46.8 214,-59 213.9,181 306.5,241 281.1,129.8 " style="stroke-opacity: 0;" />';
},
getRoundedVectorPath: function(id, attrs){
var fullPoints = 'M520.9,336.5c-3.8-11.8-14.2-20.5-26.5-22.2l-140.9-20.5l-63-127.7 c-5.5-11.2-16.8-18.2-29.3-18.2c-12.5,0-23.8,7-29.3,18.2l-63,127.7L28,314.2C15.7,316,5.4,324.7,1.6,336.5S1,361.3,9.9,370 l102,99.4l-24,140.3c-2.1,12.3,2.9,24.6,13,32c5.7,4.2,12.4,6.2,19.2,6.2c5.2,0,10.5-1.2,15.2-3.8l126-66.3l126,66.2 c4.8,2.6,10,3.8,15.2,3.8c6.8,0,13.5-2.1,19.2-6.2c10.1-7.3,15.1-19.7,13-32l-24-140.3l102-99.4 C521.6,361.3,524.8,348.3,520.9,336.5z';
return '<path data-side="center" class="svg-empty-' + id + '" d="' + fullPoints + '" style="stroke: ' + attrs.strokeColor + '; fill: transparent; " /><path data-side="right" class="svg-empty-' + id + '" d="' + fullPoints + '" style="stroke-opacity: 0;" /><path data-side="left" class="svg-empty-' + id + '" d="M121,648c-7.3,0-14.1-2.2-19.8-6.4c-10.4-7.6-15.6-20.3-13.4-33l24-139.9l-101.6-99 c-9.1-8.9-12.4-22.4-8.6-34.5c3.9-12.1,14.6-21.1,27.2-23l140.4-20.4L232,164.6c5.7-11.6,17.3-18.8,30.2-16.8c0.6,0,1,0.4,1,1 v430.1c0,0.4-0.2,0.7-0.5,0.9l-126,66.3C132,646.6,126.6,648,121,648z" style="stroke: ' + attrs.strokeColor + '; stroke-opacity: 0;" />';
},
getSvgDimensions: function(starShape){
return (starShape === 'rounded') ? 'width="550px" height="500.2px" viewBox="0 146.8 550 500.2" style="enable-background:new 0 0 550 500.2;' : 'x="0px" y="0px" width="305px" height="305px" viewBox="60 -62 309 309" style="enable-background:new 64 -59 305 305;';
},
getLinearGradient: function(id, startColor, endColor, starShape){
var height = (starShape === 'rounded') ? 500 : 250;
return '<linearGradient id="' + id + '" gradientUnits="userSpaceOnUse" x1="0" y1="-50" x2="0" y2="' + height + '"><stop offset="0" style="stop-color:' + startColor + '"/><stop offset="1" style="stop-color:' + endColor + '"/> </linearGradient>';
},
executeCallback: function(rating, $el){
var callback = this.settings.callback;
callback(rating, $el);
}
};
var publicMethods = {
unload: function() {
var _name = 'plugin_' + pluginName;
var $el = $(this);
var $starSet = $el.data(_name).$stars;
$starSet.off();
$el.removeData(_name).remove();
},
setRating: function(rating, round) {
var _name = 'plugin_' + pluginName;
var $el = $(this);
var $plugin = $el.data(_name);
if( rating > $plugin.settings.totalStars || rating < 0 ) { return; }
if( round ){
rating = Math.round(rating);
}
$plugin.applyRating(rating);
},
getRating: function() {
var _name = 'plugin_' + pluginName;
var $el = $(this);
var $starSet = $el.data(_name);
return $starSet._state.rating;
},
resize: function(newSize) {
var _name = 'plugin_' + pluginName;
var $el = $(this);
var $starSet = $el.data(_name);
var $stars = $starSet.$stars;
if(newSize <= 1 || newSize > 200) {
console.log('star size out of bounds');
return;
}
$stars = Array.prototype.slice.call($stars);
$stars.forEach(function(star){
$(star).css({
'width': newSize + 'px',
'height': newSize + 'px'
});
});
},
setReadOnly: function(flag) {
var _name = 'plugin_' + pluginName;
var $el = $(this);
var $plugin = $el.data(_name);
if(flag === true){
$plugin.$stars.off('mouseover mouseout click');
} else {
$plugin.settings.readOnly = false;
$plugin.addListeners();
}
}
};
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, methods);
$.fn[ pluginName ] = function ( options ) {
// if options is a public method
if( !$.isPlainObject(options) ){
if( publicMethods.hasOwnProperty(options) ){
return publicMethods[options].apply(this, Array.prototype.slice.call(arguments, 1));
} else {
$.error('Method '+ options +' does not exist on ' + pluginName + '.js');
}
}
return this.each(function() {
// preventing against multiple instantiations
if ( !$.data( this, 'plugin_' + pluginName ) ) {
$.data( this, 'plugin_' + pluginName, new Plugin( this, options ) );
}
});
};
})( jQuery, window, document );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment