Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * JsGrid 0.0.1
- */
- (function ($) {
- var settings,
- state,
- ajax,
- dom,
- defaults = {
- dataset: {
- connection: null,
- ajaxUrl: null,
- id: null,
- form: null
- },
- controls: {
- isStateful: false,
- isControlsShow: true,
- pagination: 'bottom',
- headerCreate: null,
- headerEdit: null,
- headerButtonCreate: null,
- headerButtonEdit: null,
- formCreateClass: 'jsgrid-form-create',
- formCreateClearHidden: false,
- isSearch: false,
- searchPlaceholder: '',
- isAdd: false,
- isFastSave: false,
- isEdit: false,
- isDelete: true,
- isDeleteConfirm: true,
- deleteConfirmMessage: 'Удалить запись?',
- additional: null,
- controlsClass: '',
- perPageOptions: [10, 100, 500, 1000],
- isTotalShow: true,
- total: null,
- totalName: 'Всего: ',
- tableCssClass: '',
- },
- table: {
- page: 1,
- pages: null,
- limit: 50,
- orderBy: 'id',
- order: 'asc',
- searchColumn: '',
- searchValue: '',
- filters: {},
- },
- columns: {
- id: {
- name: null,
- isSearch: false,
- searchType: 'default',
- isSortable: false,
- render: function (content) {
- return '<td>' + content.id + '</td>';
- }
- },
- },
- container: {
- id: null,
- class: '.jsgrid-container',
- contentClass: '.jsgrid-content'
- }
- };
- ajax = {
- request: function (url, method, method_hidden, settings) {
- // Ajax запрос в контроллер
- var data;
- if (typeof settings.container !== 'undefined') {
- this.spinOn(settings);
- data = {
- dataset: settings.dataset,
- table: settings.table
- }
- }
- else data = settings;
- if (typeof data !== "string") data = $.param(data);
- if (method == 'post') return $.post(url, data + '&_method=' + method_hidden);
- else return $.get(url, data);
- },
- index: function (settings) {
- // Метод контроллера index
- return this.request(settings.dataset.ajaxUrl, 'get', 'get', settings);
- },
- create: function (settings) {
- // Метод контроллера create
- return this.request(settings.dataset.ajaxUrl + '/create', 'get', 'get', settings);
- },
- store: function (settings) {
- // Метод контроллера store
- return $.post(settings.dataset.ajaxUrl, settings.dataset.form);
- },
- edit: function (settings) {
- // Метод контроллера edit
- return $.get(settings.dataset.ajaxUrl + '/' + settings.dataset.id + '/edit', settings.dataset.form);
- },
- update: function (settings) {
- // Метод контроллера update
- return this.request(settings.dataset.ajaxUrl + '/' + settings.dataset.id, 'post', 'put', settings.dataset.form);
- },
- destroy: function (settings) {
- // Метод контроллера destroy
- return this.request(settings.dataset.ajaxUrl + '/' + settings.dataset.id, 'post', 'delete', settings);
- },
- setConnection: function (settings) {
- return 'dataset[connection]=' + settings.dataset.connection + '&';
- },
- spinMainOn: function (settings) {
- $('#' + settings.container.id + ' .jsgrid-content').html('<div class="spin-main text-xs-center"><i class="ficon-spin3 animate-spin"></i></div>');
- },
- spinOn: function (settings) {
- $('#' + settings.container.id + ' .jsgrid-ajax-spin').show();
- },
- spinOff: function (settings) {
- $('#' + settings.container.id + ' .jsgrid-ajax-spin').fadeOut();
- },
- cspinOn: function (container) {
- container.find('.jsgrid-ajax-spin').show();
- },
- cspinOff: function (container) {
- container.find('.jsgrid-ajax-spin').fadeOut();
- },
- typingTimer: 0,
- delay: function (ms) {
- var timer = 0;
- return function (callback) {
- clearTimeout(timer);
- timer = setTimeout(callback, ms);
- };
- }
- }
- state = {
- save: function (settings) {
- // Сохранение настроек в url
- window.history.pushState(null, null, '?' + settings.container.id + '=' + JSON.stringify(settings.table));
- },
- get: function (settings) {
- // Восстановление state
- if (typeof $('#' + settings.container.id).attr('data-settings') != 'undefined') {
- // Настройки из контейнера
- settings.table = JSON.parse($('#' + settings.container.id).attr('data-settings'));
- }
- else if (location.href.indexOf('?' + settings.container.id) >= 0) settings.table = JSON.parse(this.getParam(settings.container.id));
- },
- getParam: function (name) {
- var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
- return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
- }
- };
- dom = {
- render: function (settings) {
- // Отображение данных
- if (settings.controls.isStateful) state.save(settings);
- var html = '';
- var request = ajax.index(settings);
- request.done(function (result) {
- settings.controls.total = result.total;
- // Элементы управления
- if (settings.controls.isControlsShow) {
- html = '<div class="jsgrid-controls clearfix">';
- if (settings.controls.isTotalShow) html += '<div class="jsgrid-total small pull-xs-left">' + settings.controls.totalName + result.total + '</div>';
- html +=
- '<div class="pull-xs-right">' +
- '<i class="jsgrid-ajax-spin ficon-spin5 animate-spin pull-xs-left"></i>';
- // Поиск по всем полям
- if (settings.controls.isSearch) html += '<div class="jsgrid-search form-group pull-xs-left">' +
- '<div class="input-group input-group-sm">' +
- '<span class="ficon-search input-group-addon"></span>' +
- '<input class="form-control" value="' + settings.table.searchValue + '" placeholder="' + settings.controls.searchPlaceholder + '" />' +
- '</div>' +
- '</div>';
- html += '<div class="btn-group btn-group-sm" role="group">';
- if (settings.controls.isAdd) html += '<button class="jsgrid-action-create btn btn-secondary"><i class="ficon-plus"></i></button>';
- html +=
- '<button class="jsgrid-action-reload btn btn-secondary"><i class="ficon-arrows-cw"></i></button>' +
- '<div class="btn-group btn-group-sm" role="group">' +
- '<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' + settings.table.limit + '</button>' +
- '<div class="dropdown-menu dropdown-menu-right">';
- for (var i = 0; i < settings.controls.perPageOptions.length; i++) html += '<a class="jsgrid-action-pplset dropdown-item" href="#">' + settings.controls.perPageOptions[i] + '</a>';
- html += '</div>' +
- '</div>' +
- '</div>' +
- '</div>' +
- '</div>';
- }
- // Таблица
- html += '<div class="table-responsive"><table class="table ' + settings.controls.tableCssClass + '">';
- // Заголовки
- html += '<tr>';
- for (var column in settings.columns) {
- html += '<th data-name="' + column + '"';
- // Сортировка
- if (settings.table.orderBy == column) html += ' data-order="' + settings.table.order + '"';
- html += '>';
- if (settings.columns[column].isSortable) html += '<a href="#" class="jsgrid-action-sort">' + settings.columns[column].name + '</a>';
- else html += settings.columns[column].name;
- if (settings.table.orderBy == column) html += ' <i class="font-14 opacity-30 ficon-sort-' + settings.table.order + '"></i>';
- // Фильтры
- if (settings.columns[column].isSearch) {
- // Иконки поиска
- var filter_value = '', filter_css = '';
- if (typeof settings.table.filters[column] !== 'undefined' && settings.table.filters[column].value != '') filter_value = settings.table.filters[column].value;
- else filter_css = ' opacity-30';
- // Поиск >, <, Like
- if (settings.columns[column].searchType == 'default') {
- html += '<div class="jsgrid-filter-default dropdown pull-xs-right">' +
- '<i class="ficon-search dropdown-toggle' + filter_css + '" role="button" data-toggle="dropdown" aria-expanded="false"></i>' +
- '<div class="dropdown-menu dropdown-menu-right">' +
- '<div class="input-group">' +
- '<input class="filter-' + column + ' form-control" ' + 'value="' + filter_value + '"/>' +
- '<span class="input-group-btn">' +
- '<button class="jsgrid-action-filter btn btn-secondary btn-sm" data-type="default" data-column="' + column + '" data-container="filter-' + column + '" type="button"><i class="ficon-filter opacity-70"></i></button>' +
- '</span>' +
- '</div>' +
- '</div>';
- }
- // Select
- if (settings.columns[column].searchType == 'select') {
- html += '<div class="jsgrid-filter-select dropdown pull-xs-right"><i class="ficon-sort-alt-down dropdown-toggle' + filter_css + '" role="button" data-toggle="dropdown" aria-expanded="false"></i>' +
- '<div class="dropdown-menu dropdown-menu-right">';
- for (var i = 0; i < result.filters[column].length; i++) html += '<a href="#" class="jsgrid-action-filter dropdown-item" data-type="select" data-column="' + column + '" data-value="' + result.filters[column][i].value + '">' + result.filters[column][i].name + '</a>';
- html +=
- '</div>' +
- '</div>';
- }
- }
- html += '</th>';
- }
- html += '<th></th></tr>';
- // Контент
- for (var row in result.rows) {
- html += '<tr data-id="' + result.rows[row].id + '">';
- for (var column in settings.columns) if (typeof settings.columns[column] !== 'undefined') html += settings.columns[column].render(result.rows[row]);
- // Элементы управления
- html += '<td class="' + settings.controls.controlsClass + '">';
- if (typeof settings.controls.additional !== 'undefined') for (var el in settings.controls.additional) html += settings.controls.additional[el];
- if (settings.controls.isFastSave) html += '<a href="#" class="jsgrid-action-fastsave ficon-ok"></a>';
- if (settings.controls.isEdit) html += '<a href="#" class="jsgrid-action-edit ficon-cog"></a>';
- if (settings.controls.isDelete) html += '<a href="#" class="jsgrid-action-delete ficon-cancel"></a>';
- html += '</td></tr>';
- }
- html += '</table>';
- html += '</div>';
- html += dom.pagination(settings);
- $('#' + settings.container.id + ' > .jsgrid-content').html(html);
- ajax.spinOff(settings);
- });
- },
- pagination: function (settings) {
- // Постраничная навигация
- var active, pages, offset, previous, next;
- // Количество страниц
- if (settings.controls.total % settings.table.limit > 0) settings.table.pages = (settings.controls.total / settings.table.limit >> 0) + 1; else settings.table.pages = (settings.controls.total / settings.table.limit);
- // Центрирование текущей страницы
- if (settings.table.page > 2) offset = (settings.table.page - 2); else offset = 1;
- if (settings.table.page > 1) previous = settings.table.page - 1; else previous = 1;
- // Ограничение на видимую часть
- if (settings.table.pages - settings.table.page >= 2) pages = 5;
- else {
- if (settings.table.pages > 5) {
- if (settings.table.pages - settings.table.page == 0) pages = 3;
- if (settings.table.pages - settings.table.page == 1) pages = 4;
- }
- else pages = settings.table.pages;
- }
- if (settings.table.pages < 2) return '';
- if (settings.table.page == settings.table.pages) next = parseInt(settings.table.page);
- else next = parseInt(settings.table.page) + 1;
- var html = '<nav>' +
- '<ul class="pagination pagination-sm">' +
- '<li class="page-item"><a class="jsgrid-action-page page-link" data-page="1" href="#"><span aria-hidden="true">«</span></a></li>' +
- '<li class="page-item"><a class="jsgrid-action-page page-link" data-page="' + previous + '" href="#"><span aria-hidden="true">←</span></a></li>' +
- '<li class="page-item"><a class="jsgrid-action-page page-link" data-page="' + next + '" href="#"><span aria-hidden="true">→</span></a></li>';
- for (var i = offset; i <= (pages + offset - 1); i++) {
- if (i == settings.table.page) active = ' active'; else active = '';
- html += '<li class="page-item' + active + '"><a class="jsgrid-action-page page-link" data-page="' + i + '" href="#">' + i + '</a></li>';
- }
- html +=
- '<li class="page-item"><a class="jsgrid-action-page page-link" data-page="' + settings.table.pages + '" href="#"><span aria-hidden="true">»</span></a></li>' +
- '</ul>' +
- '</nav>';
- return html;
- },
- showErrors: function (form, messages) {
- // Показать ошибки
- $.each(messages, function (name, text) {
- form.find('input[name=' + name + ']').addClass('jsgrid-input-error');
- form.find('.jsgrid-validation-result').append(text + '<br />');
- });
- },
- removeErrors: function (form) {
- // Удалить ошибки
- form.find('.jsgrid-input-error').removeClass('jsgrid-input-error');
- form.find('.jsgrid-validation-result').html('');
- },
- handlers: function (container, settings) {
- // Поиск по всем полям
- container.on('keyup', '.jsgrid-search input', function (e) {
- var input = $('#' + settings.container.id + ' .jsgrid-search input');
- clearTimeout(ajax.typingTimer);
- ajax.typingTimer = setTimeout(function () {
- settings.table.searchColumn = 'all';
- settings.table.searchValue = input.val();
- dom.render(settings);
- setTimeout(function () {
- $('#' + settings.container.id + ' .jsgrid-search input').focus().val('').val(input.val());
- }, 500);
- }, 500);
- });
- container.on('keydown', '.jsgrid-search input', function (e) {
- clearTimeout(ajax.typingTimer);
- });
- // Удаление
- container.on('click', '.jsgrid-action-delete', function (e) {
- e.preventDefault();
- settings.dataset.id = $(this).closest('tr').attr('data-id');
- if (settings.controls.isDeleteConfirm) {
- if (confirm(settings.controls.deleteConfirmMessage)) ajax.destroy(settings);
- else return false;
- }
- else ajax.destroy(settings);
- $(this).closest('tr').fadeOut();
- dom.render(settings);
- });
- // Строк на страницу
- container.on('click', '.jsgrid-action-pplset', function (e) {
- e.preventDefault();
- settings.table.limit = $(this).text();
- dom.render(settings);
- });
- // Обновление таблицы
- container.on('click', '.jsgrid-action-reload', function (e) {
- e.preventDefault();
- settings.table.page = 1;
- settings.table.searchColumn = '';
- settings.table.searchValue = '';
- settings.table.filters = {};
- dom.render(settings);
- });
- // Сортировка
- container.on('click', '.jsgrid-action-sort', function (e) {
- e.preventDefault();
- var th = $(this).closest('th');
- if (!th.attr('data-order')) th.attr('data-order', 'desc');
- if (th.attr('data-order') == 'asc') settings.table.order = 'desc';
- else settings.table.order = 'asc';
- settings.table.orderBy = th.attr('data-name');
- dom.render(settings);
- });
- // Постраничная навигация
- container.on('click', '.jsgrid-action-page', function (e) {
- e.preventDefault();
- settings.table.page = $(this).attr('data-page');
- dom.render(settings);
- });
- // Фильтрация
- $(document).on('click', '.ficon-search.dropdown-toggle', function () {
- $(this).parent().find('input.form-control').focus();
- });
- container.on('click', '.jsgrid-action-filter', function (e) {
- e.preventDefault();
- var column, value, type;
- type = $(this).attr('data-type');
- column = $(this).attr('data-column');
- if (type == 'default') value = $('.' + $(this).attr('data-container')).val();
- if (type == 'select') value = $(this).attr('data-value');
- settings.table.filters[column] = {
- column: column,
- value: value,
- type: type,
- };
- dom.render(settings);
- });
- container.on('keyup', '.jsgrid-filter-default input.form-control', function (e) {
- if (e.which === 13) {
- var this_ = $(this).parent().find('.jsgrid-action-filter');
- var column = this_.attr('data-column');
- settings.table.filters[column] = {
- column: column,
- value: $('.' + this_.attr('data-container')).val(),
- type: this_.attr('data-type'),
- };
- dom.render(settings);
- }
- });
- // Модальное окно
- container.on('hidden.bs.modal', function (e) {
- var form = container.find('.jsgrid-form-create'), input;
- if (settings.controls.formCreateClearHidden) input = form.find('input');
- else input = form.find('input:not([type=hidden])');
- input.val('').removeClass('jsgrid-input-error');
- form.find('.jsgrid-validation-result').html('');
- });
- // Добавить
- container.on('click', '.jsgrid-action-create', function (e) {
- e.preventDefault();
- var modal = $('#' + settings.container.id + ' .' + settings.controls.formCreateClass);
- modal.find('form.jsgrid-form-main').attr('data-action', 'create');
- modal.find('.modal-title').text(settings.controls.headerCreate);
- modal.find('form.jsgrid-form-main button[type=submit]').text(settings.controls.headerButtonCreate);
- modal.modal('show');
- });
- container.on('submit', 'form[data-action=create]', function (e) {
- e.preventDefault();
- var form = $(this);
- ajax.cspinOn(form);
- dom.removeErrors(form);
- settings.dataset.form = ajax.setConnection(settings);
- settings.dataset.form += form.serialize();
- var request = ajax.store(settings);
- request.done(function (result) {
- if (result.length == 0) {
- form.closest('.modal').modal('hide');
- dom.render(settings);
- }
- else dom.showErrors(form, result);
- ajax.cspinOff(form);
- });
- });
- // Редактирование
- container.on('click', '.jsgrid-action-edit', function (e) {
- e.preventDefault();
- var modal = $('#' + settings.container.id + ' .' + settings.controls.formCreateClass);
- modal.find('form.jsgrid-form-main').attr('data-action', 'edit');
- modal.find('.modal-title').text(settings.controls.headerEdit);
- modal.find('form.jsgrid-form-main button[type=submit]').text(settings.controls.headerButtonEdit);
- settings.dataset.id = $(this).closest('tr').attr('data-id');
- settings.dataset.form = ajax.setConnection(settings);
- var form = $('#' + settings.container.id + ' .' + settings.controls.formCreateClass + ' form');
- ajax.cspinOn(form);
- var request = ajax.edit(settings);
- request.done(function (result) {
- $.each(result, function (name, value) {
- form.find('[name=' + name + ']').val(value);
- ajax.cspinOff(form);
- });
- });
- modal.modal('show');
- });
- container.on('submit', 'form[data-action=edit]', function (e) {
- e.preventDefault();
- var form = $(this);
- ajax.cspinOn(form);
- dom.removeErrors(form);
- settings.dataset.form = ajax.setConnection(settings);
- settings.dataset.form += form.serialize();
- var request = ajax.update(settings);
- request.done(function (result) {
- if (result.length == 0) {
- form.closest('.modal').modal('hide');
- dom.render(settings);
- }
- else dom.showErrors(form, result);
- ajax.cspinOff(form);
- });
- });
- // Быстрое сохранение
- container.on('click', '.jsgrid-action-fastsave', function (e) {
- e.preventDefault();
- var row = $(this).closest('tr');
- settings.dataset.form = ajax.setConnection(settings);
- settings.dataset.form += 'fastsave=1&';
- settings.dataset.id = row.attr('data-id');
- row.find('input').each(function () {
- settings.dataset.form += $(this).attr('name') + '=' + $(this).val() + '&';
- });
- var request = ajax.update(settings);
- request.done(function (result) {
- if (result.length == 0) dom.render(settings);
- else $.each(result, function (name, text) {
- alert(text);
- })
- });
- });
- }
- }
- $.fn.jsGrid = function (options) {
- if ($('#' + $(this).attr('id')).length > 0) {
- // Если плагин ещё не проинициализирован
- if (!this.data('jsgrid')) {
- settings = $.extend(true, {}, defaults, options);
- settings.container.id = $(this).attr('id');
- this.data('jsgrid', settings);
- ajax.spinMainOn(settings);
- // Обработчики событий
- dom.handlers(this, settings);
- // Проверка state
- state.get(settings);
- }
- else settings = this.data('jsgrid');
- dom.render(settings);
- }
- }
- })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement