123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- !(function ($) {
- var UWidget = function (element, options) {
- this.init($(element), options);
- };
- UWidget.prototype = {
- options: {
- url: null,
- handler: null,
- template: null,
- sort: {
- enabled: false,
- name: 'sort',
- values: ['id', 'date'],
- labels: ['Identifier', 'Date']
- },
- direction: {
- enabled: false,
- name: 'direction',
- values: ['desc', 'asc'],
- labels: ['Descending', 'Ascending']
- },
- filters: {
- ebabled: false,
- name: 'filters',
- values: [],
- labels: []
- }
- },
- init: function ($element, options) {
- this.$element = $element;
- this.options = $.extend(true, {}, this.options, options);
- this._xhrCache = {};
- if (!this.options.url || !this.options.handler || !this.options.template)
- throw new Error('You must define a widget url, an ajax handler and a template');
- this
- ._initActions()
- ._initFromDOM()
- .fetch();
- },
- _initActions: function () {
- var i, checked;
- this.$actions = $('<span class="uwidget-actions"></span>');
- if (this.options.sort.enabled) {
- this.$sort = $('<select name="'+ this.options.sort.name +'"></select>')
- .on('change', false, $.proxy(this._updateActions, this));
- for (i = 0; i < this.options.sort.values.length; i++)
- this.$sort.append('<option value="' + this.options.sort.values[i] + '">' + this.options.sort.labels[i] + '</option>');
- this.$actions.append(this.$sort);
- }
- if (this.options.direction.enabled) {
- this.$direction = $('<select name="'+ this.options.direction.name +'"></select>')
- .on('change', false, $.proxy(this._updateActions, this));
- for (i = 0; i < this.options.direction.values.length; i++)
- this.$direction.append('<option value="' + this.options.direction.values[i] + '">' + this.options.direction.labels[i] + '</option>');
- this.$actions.append(this.$direction);
- }
- if (this.options.filters.enabled) {
- this.$filters = $('<span class="filters"></span>')
- .on('change', false, $.proxy(this._updateActions, this));
- for (i = 0; i < this.options.filters.values.length; i++) {
- checked = this.$element.data('filters') && new RegExp(this.options.filters.labels[i], 'i').test(this.$element.data('filters'));
- this.$filters.append(this.options.filters.labels[i] + ' <input type="checkbox" name="filters[]" value="' + this.options.filters.values[i] + '" ' + (checked ? 'checked' : '') + '/>');
- }
- this.$actions.append(this.$filters);
- }
- this.$container = $('<ul class="uwidget-container"></ul>');
- this.$info = $('<span class="uwidget-info"><a href="#" target="_blank">UWidget</a></span>');
- this.$element
- .append(this.$actions)
- .append(this.$container)
- .append(this.$info);
- this._updateActions();
- return this;
- },
- _initFromDOM: function () {
- if (this.$element.data('width'))
- this.$element.css('width', this.$element.data('width'));
- if (this.$element.data('height')) {
- this.$element.css('height', this.$element.data('height'));
- this.$container.css('height', this.$element.height() - this.$actions.height() - this.$info.height());
- }
- return this;
- },
- _updateActions: function () {
- if (this.options.sort.enabled)
- this.$element.data('sort', this.$sort.val());
- if (this.options.direction.enabled)
- this.$element.data('direction', this.$direction.val());
- if (this.options.filters.enabled) {
- var val = [];
- this.$actions.find('input[type=checkbox]:checked').each(function () {
- val.push($(this).val());
- });
- this.$element.data('filters', val.join(', '));
- }
- this.fetch();
- },
- getUrl: function () {
- var url = ('function' === typeof this.options.url ? this.options.url(this.options) : this.options.url),
- options = ['sort', 'direction', 'filters'],
- value = '';
- url += -1 !== url.indexOf('?') ? '&uwidget' : '?uwidget';
- for (var i = 0; i < options.length; i++) {
- value = this.$element.data([options[i]] + '');
- if (this.options[options[i]].enabled && value.length)
- url += '&' + this.options[options[i]].name + '=' + value;
- }
- return url;
- },
- fetch: function () {
- var that = this,
- url = that.getUrl();
- this.$element
- .removeClass('error')
- .removeClass('fetched')
- .addClass('fetching');
- if ('undefined' !== typeof this._xhrCache[url])
- return this._updateCollection.apply(this, this._xhrCache[url]);
- $.ajax($.extend(true, {}, {
- url: url
- }, that.$element.data('remoteOptions')))
- .done(function () {
- that._updateCollection.apply(that, arguments);
- that._xhrCache[url] = arguments;
- })
- .fail(function () {
- that.$container.addClass('error');
- })
- .always(function () {
- that.$container.removeClass('fetching');
- });
- },
- _updateCollection: function (collection) {
- this.$container.html('').addClass('fetched');
- collection = this.options.handler.apply(this, arguments);
- for (var i = 0; i < collection.length; i++)
- this.$container.append(tmpl(this.options.template, collection[i]));
- }
- };
- $.fn.UWidget = function (options) {
- return new UWidget(this, options);
- };
- // Simple JavaScript Templating
- // John Resig - http://ejohn.org/ - MIT Licensed
- (function(){
- var cache = {};
- this.tmpl = function tmpl(str, data){
- // Figure out if we're getting a template, or if we need to
- // load the template - and be sure to cache the result.
- var fn = !/\W/.test(str) ?
- cache[str] = cache[str] ||
- tmpl(document.getElementById(str).innerHTML) :
- // Generate a reusable function that will serve as a template
- // generator (and which will be cached).
- new Function("obj",
- "var p=[],print=function(){p.push.apply(p,arguments);};" +
- // Introduce the data as local variables using with(){}
- "with(obj){p.push('" +
- // Convert the template into pure JavaScript
- str
- .replace(/[\r\t\n]/g, " ")
- .split("<%").join("\t")
- .replace(/((^|%>)[^\t]*)'/g, "$1\r")
- .replace(/\t=(.*?)%>/g, "',$1,'")
- .split("\t").join("');")
- .split("%>").join("p.push('")
- .split("\r").join("\\'")
- + "');}return p.join('');");
- // Provide some basic currying to the user
- return data ? fn(data) : fn;
- };
- })();
- })(window.jQuery);
|