$(function () { matriz.ui = matriz.ui || {}; matriz.ui.list = { "create": function (type, $container, options) { switch (type) { case "data-table": return new matriz.ui.list.MatrizDataTable($container, options); case "filtered-list": return new matriz.ui.list.MatrizFilteredList($container, options); case "infinite-list": return new matriz.ui.list.MatrizInfiniteList($container, options); default: return new matriz.ui.list.MatrizPagedList($container, options); } }, "pushdata": function (field, data, requestfield) { requestfield = requestfield || field; if (this[field]) { data[requestfield] = this[field]; } } }; matriz.ui.list.AbstractPagedList = function ($container, options) { options = options || {}; this.loading = false; this.pagecount = 0; this.appendBody = false; this.headers = {}; function initializeSearchField() { this.$searchButton.off("click").on("click", (function (event) { event.preventDefault(); this.filter(this.$searchBox.val()); }).bind(this)); this.$searchBox.off("keypress").on("keypress", (function (event) { if (event.keyCode === 13) { event.preventDefault(); this.filter(this.$searchBox.val()); } }).bind(this)); } function initializePageSizeDropdown() { this.$pageSizeControl.on("change", (function (e) { this.setPageSize($(e.target).val()); }).bind(this)); } function initializeArrays() { if (typeof this.$container.attr("data-matriz-search-fields") === "string") { this.searchableFields = this.$container.attr("data-matriz-search-fields").split(","); } } function initializeSortSettings() { var sortColumn = this.$container.attr("data-matriz-default-sort-column-name") ? this.$container.attr("data-matriz-default-sort-column-name") : undefined; this.defaultSortDirection = this.$container.attr("data-matriz-default-sort-direction"); if (sortColumn) { this.sortSettings = { "field": sortColumn, "direction": this.defaultSortDirection }; } } function load() { this.beforeDataLoad(); matriz.ui.loading.element.show($container, this.appendBody); this.loading = true; $.ajax({ url: this.dataSourceUri, data: this.getRequestData(), context: this, accepts: "application/json", headers: this.headers }).done(function (data) { this.afterDataLoad(data); if (this.callback instanceof Function) { this.callback(data); } this.$container.trigger("matriz.ui.list.loaded"); matriz.ui.init.void(); }).fail(function (jqXHR, textStatus, errorThrown) { matriz.ajax.messages.fail.default(jqXHR, textStatus, errorThrown); }).always(function () { matriz.ui.loading.element.hide($container, this.appendBody); this.loading = false; }); } function $getSearchBox() { var $searchFilter = $container.find(".matriz-ui-pagedlist-filter"); var $searchText = $searchFilter.find("[data-matriz-action='filterData']"); if ($searchText.length === 0) { $searchText = $searchFilter.find("input[type=text]"); } return $searchText; } function $getSearchButton() { var $searchFilter = $container.find(".matriz-ui-pagedlist-filter"); var $searchButton = $searchFilter.find("[data-matriz-action='filter']"); if ($searchButton.length === 0) { $searchButton = $searchFilter.find("button"); } return $searchButton; } this.initializeEvents = function () { initializePageSizeDropdown.call(this); initializeSearchField.call(this); }; this.initializeParameters = function () { this.currentPage = matriz.utils.url.param("pagina") || 1; this.startitem = 0; this.enditem = 0; this.$container = $container; this.$searchBox = $getSearchBox(); this.$searchButton = $getSearchButton(); this.$pageSizeControl = $container.find(":input.matriz-ui-pagedlist-pagesize"); this.dataSourceUri = this.$container.attr("data-matriz-source-uri"); this.filterData = this.$searchBox.val(); this.pageSize = this.$pageSizeControl.val(); this.searchableFields = []; this.recordCount = -1; if (options !== undefined) { this.callback = options.callback; } initializeSortSettings.call(this); initializeArrays.call(this); }; this.initialize = function () { this.initializeParameters(); this.initializeEvents(); }; this.getRequestData = function () { var data = options.data || {}; matriz.ui.list.pushdata.call(this, "currentPage", data); matriz.ui.list.pushdata.call(this, "pageSize", data); matriz.ui.list.pushdata.call(this, "filterData", data); matriz.ui.list.pushdata.call(this, "searchableFields", data, "fields"); matriz.ui.list.pushdata.call(this, "userDefinedData", data, "user-data"); matriz.ui.list.pushdata.call(this, "sortSettings", data); return data; }; this.beforeDataLoad = function () { }; this.afterDataLoad = function (data) { if (this.appendBody) { this.$container.find(".matriz-ui-pagedlist-body").append(data.body); } else { this.$container.find(".matriz-ui-pagedlist-body").html(data.body); } this.recordCount = data.recordcount; this.startitem = parseInt(data.startitem); this.enditem = parseInt(data.enditem); this.pagecount = parseInt(data.pagecount); if (this.recordCount > 0) { var self = this; this.$container.find(".matriz-ui-pagedlist-pagination").html(data.pagination); this.$container.find("ul.pagination > li.first").click(function () { self.goto(1); }); this.$container.find("ul.pagination > li.prev").click(function () { self.previous(); }); this.$container.find("ul.pagination > li.next").click(function () { self.next(); }); this.$container.find("ul.pagination > li.last").click(function () { self.goto(data.pagecount); }); this.$container.find("ul.pagination > li.page").click(function () { self.goto($(this).children("a").html()); }); this.$container.find("ul.pagination > li.active").click(function () { return false; }); this.$container.find("ul.pagination > li.disabled").click(function () { return false; }); } else { this.$container.find(".matriz-ui-pagedlist-pagination").empty(); } }; this.refresh = function () { load.call(this); }; this.goto = function (page) { if (page !== this.currentPage) { this.currentPage = parseInt(page); this.refresh(); } }; this.reset = function () { this.currentPage = 1; this.refresh(); }; this.next = function () { this.goto(parseInt(this.currentPage) + 1); }; this.previous = function () { this.goto(parseInt(this.currentPage) - 1); }; this.setPageSize = function (maxRecords) { this.pageSize = maxRecords; this.currentPage = 1; this.refresh(); }; this.filter = function (text) { this.filterData = text; this.currentPage = 1; this.refresh(); this.$container.trigger("matriz.ui.list.filter"); }; this.pageNumber = function () { return this.currentPage; }; this.pageItensCount = function () { return (this.enditem - this.startitem) + 1; }; this.reinit = function () { this.initializeParameters(); }; this.isLoading = function() { return this.loading; }; this.pageCount = function() { return this.pagecount; }; this.addHeader = function(name, value) { this.headers[name] = value; }; }; matriz.ui.list.MatrizDataTable = function ($container, options) { matriz.ui.list.AbstractPagedList.call(this, $container, options); function getDirection(column) { return column.children("span").attr("class").search("pull-right fa fa-caret-up") !== -1 ? "asc" : "desc"; } function setUpSortingColumn($column) { if (this.$currentSortingColumn) { if (!$column.children("span").attr("class") || $column.children("span").attr("class").search("pull-right fa") === -1) { var defaultClass = this.defaultSortDirection === "asc" ? "fa-caret-up" : "fa-caret-down"; $column.children("span").addClass("pull-right fa " + defaultClass); } else { $column.children("span").toggleClass("fa-caret-up"); $column.children("span").toggleClass("fa-caret-down"); } $column.siblings().children("span").removeClass("pull-right fa fa-caret-up fa-caret-down"); this.$currentSortingColumn = $column; } } function initializeArrays() { var self = this; this.$container.find("th").each(function () { if ($(this).attr("data-matriz-field-sort")) { self.sortableFields.push($(this).attr("data-matriz-field-sort")); } }); } function initializeSortingColumns() { var self = this; this.sortableFields.each(function (item, idx) { self.$container.find("th[data-matriz-field-sort='" + item + "']").off("click"); self.$container.find("th[data-matriz-field-sort='" + item + "']").on("click", function (e) { setUpSortingColumn.call(self, $(this)); self.sort(self.$currentSortingColumn.attr("data-matriz-field-sort"), getDirection(self.$currentSortingColumn)); }); }); } function intializeCurrentSortingColumn() { if (this.$container.attr("data-matriz-default-sort-column-number")) { var columnNumber = this.$container.attr("data-matriz-default-sort-column-number") ? parseInt(this.$container.attr("data-matriz-default-sort-column-number")) : undefined; this.$currentSortingColumn = columnNumber ? $(this.$container.find("th").get(columnNumber - 1)) : undefined; } else if (this.$container.attr("data-matriz-default-sort-column-name")) { this.$currentSortingColumn = this.$container.find("th[data-matriz-field-sort='" + this.$container.attr("data-matriz-default-sort-column-name") + "']"); } else { this.$currentSortingColumn = undefined; } } var __super_initialize = this.initializeParameters; this.initializeParameters = function () { __super_initialize.call(this); intializeCurrentSortingColumn.call(this); this.sortableFields = []; if (this.$currentSortingColumn) { var column = this.$currentSortingColumn.length > 0 ? this.$currentSortingColumn.attr("data-matriz-field-sort") : this.$container.attr("data-matriz-default-sort-column-name"); var direction = this.defaultSortDirection; this.setSortSettings(column, direction); } initializeArrays.call(this); initializeSortingColumns.call(this); setUpSortingColumn.call(this, this.$currentSortingColumn); this.refresh(); }; var __super_getRequestData = this.getRequestData; this.getRequestData = function () { var data = __super_getRequestData.call(this); matriz.ui.list.pushdata.call(this, "sortSettings", data); return data; }; this.setSortSettings = function (column, direction) { if ($.inArray(column, this.sortableFields) === -1) { this.$container.find("th[data-matriz-field-sort] span").removeClass("pull-right fa fa-caret-up fa-caret-down"); } this.sortSettings = { "field": column, "direction": direction }; }; this.sort = function (column, direction) { this.setSortSettings(column, direction); this.refresh(); }; }; matriz.ui.list.MatrizPagedList = function ($container, options) { matriz.ui.list.AbstractPagedList.call(this, $container, options); var __super_initialize = this.initializeParameters; this.initializeParameters = function () { __super_initialize.call(this); this.refresh(); }; }; matriz.ui.list.MatrizInfiniteList = function ($container, options) { matriz.ui.list.MatrizPagedList.call(this, $container, options); this.appendBody = true; var $window = $(window); $window.scroll((function () { if ($window.scrollTop() + $window.innerHeight() >= $container.position().top + $container.height() && this.currentPage < this.pagecount && !this.loading) { this.goto(this.currentPage + 1); } }).bind(this)); this.afterDataLoad = function(data) { this.$container.find(".matriz-ui-pagedlist-body").append(data.body); this.recordCount = data.recordcount; this.pagecount = data.pagecount; this.startitem = parseInt(data.startitem); this.enditem = parseInt(data.enditem); }; }; matriz.ui.list.MatrizFilteredList = function ($container, options) { matriz.ui.list.MatrizDataTable.call(this, $container, options); this.form = {}; this.$form = $container.find("form"); this.firstTimeLoaded = true; this.ignoreFields = [ "ordem", "pagina" ]; this.isIgnoreField = function(field) { return this.ignoreFields.indexOf(field) === -1; }; this.isNoCache = function() { for(var field in this.form) { if (this.form[field] && this.isIgnoreField(field)) { return true; } } }; this.prepareRequestData = function() { this.form = {}; this.$form.serializeArray().each((function (formField) { if (formField.name.indexOf("[]") !== -1) { var multipleName = formField.name.split("[]")[0]; if (typeof this.form[multipleName] === "undefined") { this.form[multipleName] = []; } this.form[multipleName].push(formField.value); } else { this.form[formField.name] = formField.value; } }).bind(this)); }; var __super_getRequestData = this.getRequestData; this.getRequestData = function () { var data = __super_getRequestData.call(this); matriz.ui.list.pushdata.call(this, "form", data); return data; }; var super__initialize = this.initialize; this.initialize = function () { matriz.utils.url.paramsToForm(this.$form); super__initialize.call(this); }; this.beforeDataLoad = function () { var $inputCurrentPage = this.$form.find("[name='pagina']"); if (this.currentPage > 1) { if (!$inputCurrentPage.length) { $inputCurrentPage = $("").attr({ "name": "pagina", "type": "hidden" }).prependTo(this.$form); } $inputCurrentPage.val(this.currentPage); } else { if ($inputCurrentPage.length) { $inputCurrentPage.remove(); } } if (!this.firstTimeLoaded) { matriz.utils.url.search(this.$form); } else { this.firstTimeLoaded = false; } this.prepareRequestData(); if (this.isNoCache()) { this.addHeader("Cache-Control", "no-cache, no-store"); } }; }; matriz.ui.DynamicContentLoader = function (options) { this.options = options === undefined ? {} : options; this.options.data = this.options.data === undefined ? {} : this.options.data; function loadTemplate() { if (this.url === "") { throw new Error("A url não foi atribuída ao DynamicContentLoader."); } var url = (this.__type) ? this.url + "/" + this.__type : this.url; matriz.ui.loading.element.show(this.containers.$templatebody()); $.ajax({ url: url, data: this.options.data, context: this }).done(function (data) { this.onTemplateLoaded(data); }).fail(function (jqXHR, textStatus, errorThrown) { this.fail(jqXHR, textStatus, errorThrown, "Falha ao carregar template"); }).always(function () { }); } this.appendQueryString = function (uri, data) { if (data instanceof Object) { var fields = []; for (var key in data) { fields.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key])); } if (uri.search(/\?/) !== -1) { return uri + "&" + fields.join("&"); } else { return uri + "?" + fields.join("&"); } } else { return uri; } }; this.onTemplateLoaded = function (data) { this.containers.$templatebody().html(data); this.setUpMatrizAction(); }; this.setUpMatrizAction = function () { var self = this; this.containers.$main().find("[data-matriz-action]").each(function (index, element) { var action = $(element).attr("data-matriz-action"); if (self.onMatrizAction && self.onMatrizAction[action] && typeof self.onMatrizAction[action] === "function") { $(element).off("click").on("click", function (e) { self.onMatrizAction[action].call(self, element); }); } }); }; /** * Inicializa a modal */ this.start = function () { loadTemplate.call(this); }; /** * Reinicializa a modal */ this.refresh = function () { loadTemplate.call(this); }; /** * Exibe mensagem de erro */ this.fail = function (jqXHR, textStatus, errorThrown, message) { if (options.events !== undefined && options.events.onError !== undefined) { options.events.onError.call(this, { jqXHR: jqXHR, textStatus: textStatus, errorThrown: errorThrown, message: message }); } else { matriz.ajax.messages.fail.default(jqXHR, textStatus, errorThrown, message); } }; }; matriz.ui.MasterDetail = function (options) { matriz.ui.DynamicContentLoader.call(this, options); var editing = false; this.__type = "modal"; this.__contentContainerSelector = " .modal-content"; function deleteItem(id) { matriz.confirm("Esta ação é irreversível. Deseja prosseguir?", (function () { $.ajax({ url: this.url + "/" + id + "/excluir", context: this }).done(function (data, textStatus, jqXHR) { this.onItemDeleted(); }).fail(function (jqXHR, textStatus, errorThrown) { matriz.ajax.messages.fail.default(jqXHR, textStatus, "Falha na tentativa de exclusão"); }).always(function () { }); }).bind(this)); } function loadItem(id) { $.ajax({ url: this.url + "/" + id + "/editar", context: this, data: this.options.data }).done(function (data, textStatus, jqXHR) { this.onItemLoaded(data); }).fail(function (jqXHR, textStatus, errorThrown) { matriz.ajax.messages.fail.default(jqXHR, textStatus); }).always(function () { }); } function save(form, saveAndLink, e) { if ($(form).valid()) { $.ajax({ "url": this.appendQueryString($(form).attr("action"), this.options.data), "context": this, "data": $(form).serialize(), "type": "POST" }).done(function (data) { matriz.box.notify.success("Registro salvo com sucesso."); if (saveAndLink) { this.link(data); this.onSaveAndLink(); } else { this.onItemSaved(); } }).fail(function (jqXHR, textStatus, errorThrown) { matriz.ajax.messages.fail.default(jqXHR, textStatus); }).always(function () { }); } if (e !== undefined) { e.preventDefault(); } } function enableItem(id) { $.ajax({ url: this.url + "/" + id + "/ativar", context: this }).done(function (data, textStatus, jqXHR) { this.onItemEnabled(); }).fail(function (jqXHR, textStatus, errorThrown) { matriz.ajax.messages.fail.default(jqXHR, textStatus, "Falha na tentativa de ativação"); }).always(function () { }); } function disableItem(id) { $.ajax({ url: this.url + "/" + id + "/inativar", context: this }).done(function (data, textStatus, jqXHR) { this.onItemDisabled(); }).fail(function (jqXHR, textStatus, errorThrown) { matriz.ajax.messages.fail.default(jqXHR, textStatus, "Falha na tentativa de inativação"); }).always(function () { }); } function setUpDataTable() { if (this.containers.$datalist() && this.containers.$datalist().length > 0) { var uri = this.containers.$datalist().find(".matriz-ui-pagedlist-container").attr("data-matriz-source-uri"); this.containers.$datalist().find(".matriz-ui-pagedlist-container").attr("data-matriz-source-uri", this.appendQueryString(uri, this.options.data)); this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList({ "callback": (function () { this.onDataTableLoaded(); }).bind(this) }); } } function setUpGoBackAction() { var context = this; this.containers.$main().find('[data-matriz-action="cancel"]').on("click", function () { context.showTabs(); }); } function setUpItemsAction() { var context = this; this.containers.$main().find(".matriz-ui-pagedlist-container [data-matriz-action='edit']").on("click", function (e) { var id = $(this).attr("data-matriz-id"); loadItem.call(context, id); e.preventDefault(); }); this.containers.$main().find(".matriz-ui-pagedlist-container .[data-matriz-action='delete']").on("click", function (e) { var id = $(this).attr("data-matriz-id"); deleteItem.call(context, id); e.preventDefault(); }); this.containers.$main().find(".matriz-ui-pagedlist-container .[data-matriz-action='enable']").on("click", function (e) { var id = $(this).attr("data-matriz-id"); enableItem.call(context, id); e.preventDefault(); }); this.containers.$main().find(".matriz-ui-pagedlist-container .[data-matriz-action='disable']").on("click", function (e) { var id = $(this).attr("data-matriz-id"); disableItem.call(context, id); e.preventDefault(); }); } function setUpItemsCheckBoxes() { var context = this; this.containers.$main().find("td input[type='checkbox']").on("change", function () { if (context.containers.$main().find("td input[type='checkbox']::checked").length === context.containers.$main().find("td input[type='checkbox']").length) { if (!context.containers.$main().find("[data-matriz-action='select-all']").prop("checked")) { context.containers.$main().find("[data-matriz-action='select-all']").prop("checked", true); } } else { context.containers.$main().find("[data-matriz-action='select-all']").prop("checked", false); } }); } function setUpLinkSelectedAction() { var context = this; this.containers.$main().find("[data-matriz-action='link-selected']").on("click", function () { var items = []; context.containers.$main().find("td input[type='checkbox']::checked").each(function (idx, item) { items.push({"id": $(item).attr("value"), "attributes": matriz.utils.dom.attributes($(this).get(0), /^data-/)}); }).promise().done(function () { context.onItemsLinked(items); }); }); } function setUpLinkItemAction() { var context = this; this.containers.$main().find("[data-matriz-action='link']").on("click", function () { var items = [{ "id": $(this).attr("data-matriz-id"), "attributes": matriz.utils.dom.attributes($(this).get(0), /^data-/) }]; context.onItemsLinked(items); }); } function setUpSelectAllItemsAction() { var context = this; this.containers.$main().find("[data-matriz-action='select-all']").prop("checked", false); this.containers.$main().find("[data-matriz-action='select-all']").on("change", function () { context.containers.$main().find("td input[type='checkbox']::enabled").prop("checked", $(this).prop("checked")); }); } this.validation = { "errorClass": "label label-danger", "errorElement": "div", "highlight": false, "submitHandler": function () { return false; } }; /** * Método utilizado para relacionar uma biblioteca a um conteudo */ this.link = function (data) { if (matriz.utils.string.isInt(data)) { data = {id: parseInt(data)}; } try { var dataTemp = $.parseJSON(data); if (dataTemp) { data = dataTemp; } } catch (e) { } this.onItemsLinked([data]); }; /** * Evento executado quando os dados da lista são carregados */ this.onDataTableLoaded = function () { setUpItemsAction.call(this); setUpItemsCheckBoxes.call(this); setUpSelectAllItemsAction.call(this); setUpLinkItemAction.call(this); }; /** * Evento executado quando o template da modal é carregado */ this.onTemplateLoaded = function (data) { $(this.containers.$templatebody()).html(data); setUpDataTable.call(this); setUpGoBackAction.call(this); if (this.options.data.modo === "relacionamento" || this.options.data.modo === "conteudo-em-lote") { setUpLinkSelectedAction.call(this); } this.containers.$new().find('form').validate(this.validation); this.setUpSaveNew(); this.showTabs(); matriz.ui.init.modal(this.containers.$main()); }; /** * Evento executado quando um item é excluido */ this.onItemDeleted = function () { matriz.box.notify.success("Registro excluído com sucesso."); this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh"); this.showTabs(); }; /** * Evento executado quando um item é carregado */ this.onItemLoaded = function (data) { $(this.containers.$edit()).html(data); setUpGoBackAction.call(this); this.showEdicao(); this.containers.$edit().find('form').validate(this.validation); this.setUpSaveExistent(); matriz.ui.init.all(); }; /** * Evento executado quando um item é salvo */ this.onItemSaved = function () { this.start(); }; /** * Evento executado a ação de relacionar itens é executada */ this.onItemsLinked = function (items) { console.log(items); }; /** * Evento executado quando um item é salvo e relacionado */ this.onSaveAndLink = function () { $(this.containers.$linked().find('[data-toggle="modal"]').attr("href")).modal('hide'); this.containers.$linked().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh"); }; this.onItemEnabled = function () { matriz.box.notify.success("Registro ativado com sucesso."); this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh"); this.showTabs(); }; this.onItemDisabled = function () { matriz.box.notify.success("Registro inativado com sucesso."); this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh"); this.showTabs(); }; /** * Configura as ações para gravação de um novo item */ this.setUpSaveNew = function () { if (this.containers.$new() && this.containers.$new().length > 0) { this.containers.$new().find('form').on("submit", save.bind(this, this.containers.$new().find('form')[0], undefined)); this.containers.$new().find('[data-matriz-action="save"]').on("click", (function (e) { this.containers.$new().find('form').trigger("submit"); e.preventDefault(); }).bind(this)); if (this.options.data.modo === "relacionamento") { this.containers.$new().find('[data-matriz-action="save-and-link"]').on("click", (function (e) { save.call(this, this.containers.$new().find('form')[0], e); e.preventDefault(); }).bind(this)); } } }; /** * Configura as ações para gravação de um novo existente */ this.setUpSaveExistent = function () { if (this.containers.$edit() && this.containers.$edit().length > 0) { this.containers.$edit().find('form').on("submit", save.bind(this, this.containers.$edit().find('form')[0], undefined)); this.containers.$edit().find('[data-matriz-action="save"]').on("click", (function (e) { this.containers.$edit().find('form').trigger("submit"); e.preventDefault(); }).bind(this)); if (this.options.data.modo === "relacionamento") { this.containers.$edit().find('[data-matriz-action="save-and-link"]').on("click", (function (e) { save.call(this, this.containers.$edit().find('form')[0], true, e); e.preventDefault(); }).bind(this)); } } }; /** * Exibe tab de edição e desativa a tab de lista e inclusão */ this.showEdicao = function () { editing = true; //desabilita tabs de lista e inclusão this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"]').parent("li").addClass("disabled"); this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').parent("li").addClass("disabled"); //Exibe tab de edição this.containers.$main().find('a[href="#' + this.containers.$edit().attr("id") + '"]').show(); this.containers.$main().find('a[href="#' + this.containers.$edit().attr("id") + '"]').tab('show'); this.containers.$main().find('li.disabled a').click(function () { return !editing; }); this.containers.$main().find("[data-matriz-action='link-selected']").hide(); }; /** * Ativa a tab de lista e inclusão e remove a tab de edição */ this.showTabs = function () { editing = false; //configura o evento de clique das tabs this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"], a[href="#' + this.containers.$datalist().attr("id") + '"]').click(function (e) { $(this).tab('show'); e.preventDefault(); }); if (this.options.data.modo === "relacionamento" || this.options.data.modo === "conteudo-em-lote") { //Configura para que a tab de edição não exiba o botão de relacionamento this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"], a[href="#' + this.containers.$edit() + '"]').on('shown.bs.tab', (function (e) { this.containers.$main().find("[data-matriz-action='link-selected']").hide(); }).bind(this)); //Configura para que a tab de lista exiba o botão de relacionamento this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').on('shown.bs.tab', (function (e) { this.containers.$main().find("[data-matriz-action='link-selected']").show(); }).bind(this)); } //habilita tabs de lista e inclusão if (this.containers.$datalist() && this.containers.$datalist().length > 0) { this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').tab('show'); } else { this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"]').tab('show'); } this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"]').parent("li").removeClass("disabled"); this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').parent("li").removeClass("disabled"); //Oculta tab de edição this.containers.$main().find('a[href="#' + this.containers.$edit().attr("id") + '"]').hide(); }; this.show = function () { this.containers.$main().modal('show'); }; this.hide = function () { this.containers.$main().modal('hide'); }; var __super__start = this.start; this.start = function () { __super__start.call(this); }; }; matriz.ui.MasterDetail.prototype = new matriz.ui.DynamicContentLoader(); matriz.ui.Form = function (options) { matriz.ui.MasterDetail.call(this, options); function loadItem(id) { this.showEdicao(); matriz.ui.loading.element.show($(this.containers.$edit())); $.ajax({ url: this.url + "/" + id + "/editar", context: this, data: this.options.data }).done(function (data, textStatus, jqXHR) { this.onItemLoaded(data); }).fail(function (jqXHR, textStatus, errorThrown) { matriz.ajax.messages.fail.default(jqXHR, textStatus, errorThrown); }).always(function () { }); } var __super_onTemplateLoaded = this.onTemplateLoaded; this.onTemplateLoaded = function (data) { __super_onTemplateLoaded.call(this, data); if (options.modo === "edicao") { loadItem.call(this, options.itemId); } }; /** * Evento executado quando um item é salvo */ this.onItemSaved = function () { this.containers.$linked().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh"); this.hide(); }; }; matriz.ui.Form.prototype = new matriz.ui.MasterDetail(); matriz.ui.imagecropper = { ImageCroppingStep: function (options) { var area = { "x": 0, "y": 0, "height": 0, "width": 0 }; var domImageDimension; var jcropApi = null; var minDimension = getMinDimension(); var widthRelativeRatio = 1; var initialSelection = undefined; function getDefaultSelection(dimension) { if (initialSelection === undefined) { var x1, y1, x2, y2; if (minDimension.width / minDimension.height <= dimension.width / dimension.height) { y1 = 0; y2 = dimension.height; var w = (y2 * options.proportion.width) / options.proportion.height; x1 = dimension.width / 2 - w / 2; x2 = x1 + dimension.width; } else { x1 = 0; x2 = dimension.width; var h = (x2 * options.proportion.height) / options.proportion.width; y1 = dimension.height / 2 - h / 2; y2 = y1 + dimension.height; } return [x1, y1, x2, y2]; } else { return initialSelection; } } function getMinDimension() { var minDimension = { "width": 0, "height": 0 }; for (var i = 0, len = options.proportion.dimensions.length; i < len; i++) { var minWidth = minDimension.width; var minHeight = minDimension.height; var opWidth = options.proportion.dimensions[i].width; var opHeight = options.proportion.dimensions[i].height; if (minWidth * minHeight === 0 || minWidth * minHeight < opWidth * opHeight) { minDimension.width = options.proportion.dimensions[i].width; minDimension.height = options.proportion.dimensions[i].height; } } return minDimension; } function getRelativeBasedDimension() { return { "width": options.$container.find("img").width() * minDimension.width / area.width, "height": options.$container.find("img").height() * minDimension.height / area.height }; } this.enter = function () { if (jcropApi) { jcropApi.destroy(); } options.$container.empty().addClass("matriz-loading-clock"); var img = options.image.object; domImageDimension = { width: img.width, height: img.height }; if (area.width === 0 && area.height === 0) { area = { "x": 0, "y": 0, "height": options.image.object.height, "width": options.image.object.width }; } var relativeMinDimension, $img, imgDimension; options.$container.removeClass("matriz-loading-clock"); $img = $(img); $img.addClass("matriz-cropper-image") .appendTo("
") .parent() .appendTo(options.$container); relativeMinDimension = getRelativeBasedDimension({"width": options.$container.find("img").width(), "height": options.$container.find("img").height()}); imgDimension = {"width": $img.width(), "height": $img.height()}; $img.parent() .Jcrop({ "aspectRatio": options.proportion.width / options.proportion.height, "minSize": [relativeMinDimension.width, relativeMinDimension.height], "setSelect": getDefaultSelection(imgDimension) }, function () { jcropApi = this; }); }; this.getRealSelection = function () { var imageselection = jcropApi.tellSelect(); var selectedArea = { "x": ((domImageDimension.width * widthRelativeRatio * imageselection.x) / options.$container.find("img").width()), "y": ((domImageDimension.width * widthRelativeRatio * imageselection.y) / options.$container.find("img").width()), "width": ((domImageDimension.width * widthRelativeRatio * imageselection.w) / options.$container.find("img").width()), "height": ((domImageDimension.width * widthRelativeRatio * imageselection.h) / options.$container.find("img").width()) }; return selectedArea; }; this.getProportion = function () { return options.proportion; }; this.saveSelection = function () { var selection = jcropApi.tellSelect(); initialSelection = [selection.x, selection.y, selection.x2, selection.y2]; }; }, StepController: function (options) { var stepsStack = []; var stackLength = 0; var stepPointer = -1; function checkSelection(area) { if (area.width === 0 && area.height === 0) { throw new Error("Nenhuma área foi selecionada para recorte."); } } function showStep() { stepsStack[stepPointer].enter(); setUpActionsDisplay(); } function nextStep() { var area = { "x": 0, "y": 0, "width": 0, "height": 0 }; if (stepPointer >= 0) { area = stepsStack[stepPointer].getRealSelection(); stepsStack[stepPointer].saveSelection(); checkSelection(area); } stepPointer++; showStep(); } function previousStep() { if (stepPointer >= 0) { stepsStack[stepPointer].saveSelection(); } stepPointer--; showStep(); } function finishCropping() { var crops = {}; checkSelection(stepsStack[stepPointer].getRealSelection()); for (var i = 0; i < stackLength; i++) { var step = stepsStack[i]; crops[step.getProportion().id] = step.getRealSelection(); crops[step.getProportion().id].preview = step.getProportion().preview; crops[step.getProportion().id].editingpreview = step.getProportion().editingpreview; if (i === 0) { options.initialSelection = step.getRealSelection(); } } options.onFinished({ "crops": crops, "orientation": options.optiongroup.$orientation.filter(":checked").val(), "dimension": stepsStack[0].getProportion().dimensions[0] }); } function orientationOptionGroupShow() { if (Object.keys(options.orientations).length === 1) { options.optiongroup.$orientation.prop("disabled", true); } else { options.optiongroup.$orientation.prop("disabled", false); } } function setUpActionsDisplay() { if (stepPointer > 0) { options.buttons.$back.show(); options.optiongroup.$orientation.attr("disabled", true); options.optiongroup.$orientation.parents("label") .addClass("matriz-desabilidato") .addClass("matriz-inativo"); } else { options.buttons.$back.hide(); options.optiongroup.$orientation.attr("disabled", false); options.optiongroup.$orientation.parents("label") .removeClass("matriz-desabilidato") .removeClass("matriz-inativo"); orientationOptionGroupShow(); } if (stepPointer === stackLength - 1) { options.buttons.$next.hide(); options.buttons.$finish.show(); } else { options.buttons.$next.show(); options.buttons.$finish.hide(); } options.$body.find(".matriz-recorte-info").text(stepsStack[stepPointer].getProportion().title); } function setUpButtonActions() { options.buttons.$back.off(); options.buttons.$back.on("click", function () { previousStep(); }); options.buttons.$next.off(); options.buttons.$next.on("click", function () { try { nextStep(); } catch (error) { matriz.box.notify.danger(error.message); } }); options.buttons.$finish.off(); options.buttons.$finish.on("click", function () { try { finishCropping(); } catch (error) { matriz.box.notify.danger(error.message); } }); } function setUpSteps() { var currentOrientation = options.optiongroup.$orientation.filter(":checked").val(); var proportions = options.orientations[currentOrientation]; stepsStack = []; stepPointer = -1; for (var keyProportion in proportions) { var proportion = proportions[keyProportion]; var step = new matriz.ui.imagecropper.ImageCroppingStep({ "$container": options.$body.find(".matriz-cropper-image-container"), "proportion": proportion, "image": { "id": options.image.id, "object": options.image.object, "orientation": options.image.orientation }, "controller": this }); stepsStack.push(step); } stackLength = stepsStack.length; if (stackLength > 0) { nextStep(); } } function orientationReset() { if (options.initialSelection) { options.image.orientation = options.initialSelection.width >= options.initialSelection.height ? "horizontal" : "vertical"; } options.optiongroup.$orientation.filter("[value='" + options.image.orientation + "']") .prop("checked", true) .trigger("change"); orientationOptionGroupShow(); } function setUpOrientationSelection() { options.optiongroup.$orientation.off(); options.optiongroup.$orientation.on("change", function () { setUpSteps(); }); orientationReset(); } this.start = function () { setUpButtonActions.call(this); setUpOrientationSelection.call(this); }; this.reset = function () { orientationReset(); }; }, /** * * @param Node options.modal * @param String options.image.src * @param String options.sizetype * @param Number options.dimensions.horizontal.pq.width * @param Number options.dimensions.horizontal.pq.height * @param Number options.dimensions.horizontal.md.width * @param Number options.dimensions.horizontal.md.height * @param Number options.dimensions.horizontal.gd.width * @param Number options.dimensions.horizontal.gd.height * @param Number options.dimensions.vertical.pq.width * @param Number options.dimensions.vertical.pq.height * @param Number options.dimensions.vertical.md.width * @param Number options.dimensions.vertical.md.height * @param Number options.dimensions.vertical.gd.width * @param Number options.dimensions.vertical.gd.height * @param Function options.imageValid * @param Function options.imageInvalid */ ImageCropper: function (options) { var orientationsConfig = { "horizontal": [ {"id": "16:9", "title": "Recorte proporcional de 16:9", "width": 16, "height": 9, "dimensions": [ {"id": "gd", "width": 800, "height": 450}, {"id": "md", "width": 608, "height": 342}, {"id": "pq", "width": 336, "height": 189}] }, {"id": "ThumbHorizontal", "title": "Recorte quadrado", "width": 1, "height": 1, "dimensions": [{"id": "th", "width": 180, "height": 180}]}], "vertical": [ {"id": "3:4", "title": "Recorte proporcional de 3:4", "width": 3, "height": 4, "dimensions": [ {"id": "gd", "width": 801, "height": 1068}, {"id": "md", "width": 600, "height": 800}, {"id": "pq", "width": 345, "height": 460}] }, {"id": "ThumbVertical", "title": "Recorte quadrado", "width": 1, "height": 1, "dimensions": [{"id": "th", "width": 180, "height": 180}]}] }; var originalimg; var $container; var $orientationOptionGroup; var $cancelButton; var $backButton; var $nextButton; var $finishButton; var $croppingBody; var $image; var imageOrientation; var largestDimensions = { "horizontal": { "width": 0, "height": 0 }, "vertical": { "width": 0, "height": 0 } }; var validOrientations = {}; var stepController; function abortCropping(error) { $container.modal("hide"); matriz.box.notify.danger(error.message); if (options.onAbort) { options.onAbort(error); } } function getLargestDimensionByOrientation(orientation) { var orientationConfig = orientationsConfig[orientation]; var maxDimension = {"width": 0, "height": 0}, currentMaxRate = 0; for (var keyProportion in orientationConfig) { var dimensions = orientationConfig[keyProportion].dimensions; for (var keyDimension in dimensions) { var rate = dimensions[keyDimension].width * dimensions[keyDimension].height; if (rate > currentMaxRate) { maxDimension = dimensions[keyDimension]; currentMaxRate = rate; } } } return maxDimension; } function setUpLargestDimensions() { largestDimensions["horizontal"] = getLargestDimensionByOrientation.call(this, "horizontal"); largestDimensions["vertical"] = getLargestDimensionByOrientation.call(this, "vertical"); } function setUpImageOrientation() { if (originalimg.width >= originalimg.height) { imageOrientation = "horizontal"; } else { imageOrientation = "vertical"; } } function addOrientationInValidOrientationsIfValid(orientation) { if (largestDimensions[orientation].width <= originalimg.width && largestDimensions[orientation].height <= originalimg.height) { validOrientations[orientation] = orientationsConfig[orientation]; } } function setUpValidOrientations() { addOrientationInValidOrientationsIfValid.call(this, "horizontal"); addOrientationInValidOrientationsIfValid.call(this, "vertical"); if (Object.keys(validOrientations).length === 0) { var dimensions = []; for (var orientation in largestDimensions) { dimensions.push("" + largestDimensions[orientation].width + " x " + largestDimensions[orientation].height + " px"); } var msg = "A imagem selecionada não possui tamanho suficiente para recorte.\r\n"; msg = msg.concat("Para efetuar o recorte a imagem deve possuir uma resolução mínima de ").concat(dimensions.join(" ou ").concat(".")); abortCropping(new Error(msg)); } } function onFinished(croppingData) { $container.hide(); options.onFinished(croppingData); } function onCancel() { $container.hide(); options.onCancel(); } function setUpStepController() { stepController = new matriz.ui.imagecropper.StepController({ "$body": $croppingBody, "buttons": { "$back": $backButton, "$next": $nextButton, "$finish": $finishButton }, "optiongroup": { "$orientation": $orientationOptionGroup }, "image": { "id": options.imageId, "object": originalimg, "orientation": imageOrientation }, "initialSelection": options.initialSelection, "orientations": validOrientations, "onFinished": onFinished.bind(this) }); } function setup() { matriz.ui.loadImage($image.attr("src")).done(function (img) { originalimg = img; setUpLargestDimensions.call(this); setUpImageOrientation.call(this); setUpValidOrientations.call(this); setUpStepController(); matriz.ui.loading.element.hide($croppingBody); stepController.start(); }).fail(function (error) { abortCropping(error); }); } function validateOptions() { if (!options.imageId) { throw new Error("options.imageId não foi definido. Hint: imageId deve ser o identificador da imagem que será efetuada o recorte."); } if (!options.$container) { throw new Error("options.$container não foi definido."); } if (!options.onCancel) { throw new Error("options.$onCancel não foi definido."); } if (!options.onFinished) { throw new Error("options.$onFinished não foi definido."); } } function __construct() { validateOptions(); orientationsConfig = options.dimensions || orientationsConfig; $container = options.$container; $image = $container.find("img"); $cancelButton = $container.find("[data-matriz-action='cancel']"); $backButton = $container.find("[data-matriz-action='back']").hide(); $nextButton = $container.find("[data-matriz-action='next']").hide(); $finishButton = $container.find("[data-matriz-action='finish']").hide(); $croppingBody = $container; $orientationOptionGroup = $container.find("input[type='radio']"); } this.reset = function () { if (stepController) { stepController.reset(); } }; this.start = function () { matriz.ui.loading.element.show($croppingBody); setup.call(this); $cancelButton.off("click"); $cancelButton.on("click", function () { onCancel(); }); }; __construct.call(this); } }; matriz.ui.tristatecheckbox = { check: function ($selector) { $selector.attr("data-matriz-state", matriz.ui.tristatecheckbox.enumstates.CHECKED); $selector.prop("indeterminate", false); $selector.attr("checked", true); }, checked: function ($selector) { return $selector.attr("data-matriz-state") === matriz.ui.tristatecheckbox.enumstates.CHECKED; }, enumstates: { "UNCHECKED": "0", "CHECKED": "1", "INDETERMINATE": "2" }, destroy: function ($selector) { $selector.removeAttr("data-matriz-extended-type"); $selector.removeAttr("data-matriz-state"); $selector.each(function (idx, checkbox) { if ($(checkbox).prop("indeterminate")) { $(checkbox).attr("checked", false); } $(checkbox).off("change"); }); }, filterstates: function ($selector, states) { var query = [], len = states.length, i = 0; for (i = 0; i < len; i++) { query.push("[data-matriz-state='" + states[i] + "']"); } return $selector.find(query.join(",")); }, indeterminate: function ($selector) { $selector.attr("data-matriz-state", matriz.ui.tristatecheckbox.enumstates.INDETERMINATE); $selector.attr("checked", false); $selector.prop("indeterminate", true); }, indeterminated: function ($selector) { return $selector.attr("data-matriz-state") === matriz.ui.tristatecheckbox.enumstates.INDETERMINATE; }, nextstate: function ($selector) { $selector.each(function (idx, checkbox) { var state = matriz.ui.tristatecheckbox.state($(checkbox)); var states = matriz.ui.tristatecheckbox.states($(checkbox)); var nextstate = states[(states.indexOf(state) + 1) % states.length]; matriz.ui.tristatecheckbox.state($(checkbox), nextstate); }); }, state: function ($selector, state) { if (state === undefined) { return $selector.attr("data-matriz-state"); } else { switch (state) { case matriz.ui.tristatecheckbox.enumstates.UNCHECKED: matriz.ui.tristatecheckbox.uncheck($selector); break; case matriz.ui.tristatecheckbox.enumstates.INDETERMINATE: matriz.ui.tristatecheckbox.indeterminate($selector); break; case matriz.ui.tristatecheckbox.enumstates.CHECKED: matriz.ui.tristatecheckbox.check($selector); break; default: throw new Error("Unknown state: " + state); break; } } }, states: function ($selector, states) { if (states === undefined) { return $selector.data("matriz-states"); } else { if (states instanceof Array) { $selector.data("matriz-states", states); $selector.each(function (idx, checkbox) { matriz.ui.tristatecheckbox.state($(checkbox), states.first()); }); } else { throw new Error("States must be an array"); } } }, uncheck: function ($selector) { $selector.attr("data-matriz-state", matriz.ui.tristatecheckbox.enumstates.UNCHECKED); $selector.attr("checked", false); $selector.prop("indeterminate", false); }, unchecked: function ($selector) { return $selector.attr("data-matriz-state") === matriz.ui.tristatecheckbox.enumstates.UNCHECKED; }, init: function ($selector, states) { if ($selector instanceof jQuery) { var defaultstates = [matriz.ui.tristatecheckbox.enumstates.INDETERMINATE, matriz.ui.tristatecheckbox.enumstates.CHECKED, matriz.ui.tristatecheckbox.enumstates.UNCHECKED]; matriz.ui.tristatecheckbox.states($selector, (states === undefined ? defaultstates : states)); $selector.each(function (idx, checkbox) { if ($(checkbox).prop("checked")) { matriz.ui.tristatecheckbox.state($(checkbox), matriz.ui.tristatecheckbox.enumstates.CHECKED); } else { var firststate = matriz.ui.tristatecheckbox.states($(checkbox)).first() matriz.ui.tristatecheckbox.state($(checkbox), firststate); } $(checkbox).on("change", function (e) { e.preventDefault(); matriz.ui.tristatecheckbox.nextstate($(this)); }); }); } else { throw new Error("$selector is not a jQuery instance"); } } }; matriz.ui.scrollTo = function (selector) { $("html, body").animate({ scrollTop: $(selector).offset().top }, 400); }; matriz.ui.components = []; matriz.ui.component = { "Factory": { create: function (container) { var component = $(container).attr("data-matriz-component"); if (typeof matriz.ui.components[component] === "function") { return new matriz.ui.components[component](); } throw new Error("Componente sem javascript: " + component); } }, "Manager": { init: function () { $("[data-matriz-component]").each(function () { try { if ($(this).prop("data-matriz-loaded") !== true) { $(this).prop("data-matriz-loaded", true); matriz.ui.component.Factory.create(this).init({ "container": this }); } } catch (e) { console.warn(e.message); } }); } } }; matriz.ui.FileInput = function (options) { matriz.common.Event.call(this); this.options = { url: null, button: null, multiple: false, maxsize: 0, extensions: "" }; this.files = []; this.filesResponse = []; $.extend(this.options, options); this.init = function () { var fileInput = new mOxie.FileInput({ browse_button: this.options.button, multiple: this.options.multiple, accept: [{ title: "Selecione o arquivo para envio...", extensions: this.options.extensions }] }); fileInput.onchange = (function (e) { this.trigger("change"); this.files = []; this.filesResponse = []; for (var key in e.target.files) { var file = e.target.files[key]; var extension = ((file.name).split(".").pop()).toLowerCase(); this.trigger("added", [file]); if (!this.options.maxsize || this.options.maxsize < file.size) { if (!this.options.extensions || this.options.extensions.indexOf(extension) > -1) { this.files.push(file); } else { this.trigger("error", [file, new Error(matriz.utils.internationalization.translate("Não foi possível selecionar o arquivo pois o tipo não é permitido", "matriz.ui") + ".")]); } } else { this.trigger("error", [file, new Error(matriz.utils.internationalization.translate("Tamanho do arquivo maior que", "matriz.ui") + " " + matriz.utils.file.toTamanhoExtenso(this.options.maxsize) + ".")]); } } var promises = this.files.map((function (file) { return this.sendFile(file, this.options.url) .done((function (response) { this.filesResponse.push(response); this.trigger("success", [file, response]); }).bind(this)) .fail((function (error) { this.trigger("error", [file, error]); }).bind(this)); }).bind(this)); $.when.apply(this, promises).always((function () { this.trigger("complete", [this.files, this.filesResponse]); }).bind(this)); }).bind(this); fileInput.init(); }; this.getFormData = function (data) { var formData = new mOxie.FormData(); for (var key in data) { formData.append(key, data[key]); } return formData; }; this.sendFile = function (file, url) { var deferred = $.Deferred(); var xhr = new mOxie.XMLHttpRequest(); xhr.upload.onprogress = (function (e) { var progress = Math.round(e.loaded / e.total * 100) + "%"; this.trigger("progress", [file, progress]); }).bind(this); xhr.onload = (function (e) { var status = parseInt(xhr.status); if (status >= 200 && status < 300) { deferred.resolve($.parseJSON(xhr.response)); } else { deferred.reject(new Error(xhr.response)); } }).bind(this); xhr.open("post", url); xhr.send(this.getFormData({"attachment": file})); return deferred.promise(); }; return this; }; });