PageSourceSearch

https://fepam.rs.gov.br/matriz_common/versions/2.1.5/js/procergs/matriz.ui.js?2.1.5.161.6+1

js fepam.rs.gov.br collected 2026-09-24 21:49:11 UTC 78,403 bytes, 1,883 lines download raw bytes

1$(function () {
2    matriz.ui = matriz.ui || {};
3    matriz.ui.list = {
4        "create": function (type, $container, options) {
5            switch (type) {
6                case "data-table":
7                    return new matriz.ui.list.MatrizDataTable($container, options);
8                case "filtered-list":
9                    return new matriz.ui.list.MatrizFilteredList($container, options);
10                case "infinite-list":
11                    return new matriz.ui.list.MatrizInfiniteList($container, options);
12                case "navigate-list":
13                    return new matriz.ui.list.MatrizNavigateList($container, options);
14                default:
15                    return new matriz.ui.list.MatrizPagedList($container, options);
16            }
17        },
18        "pushdata": function (field, data, requestfield) {
19            requestfield = requestfield || field;
20            if (this[field]) {
21                data[requestfield] = this[field];
22            }
23        }
24    };
25    matriz.ui.list.AbstractPagedList = function ($container, options) {
26
27        options = options || {};
28
29        this.loading = false;
30        this.pagecount = 0;
31        this.appendBody = false;
32        this.headers = {};
33
34        function initializeSearchField() {
35
36            this.$searchButton.off("click").on("click", (function (event) {
37                event.preventDefault();
38                this.filter(this.$searchBox.val());
39            }).bind(this));
40
41            if (this.$exportButton) {
42                this.$exportButton.off("click").on("click", (function (event) {
43                    event.preventDefault();
44                    this.export(this.$searchBox.val());
45                }).bind(this));
46            }
47
48            this.$searchBox.off("keypress").on("keypress", (function (event) {
49                if (event.keyCode === 13) {
50                    event.preventDefault();
51                    this.filter(this.$searchBox.val());
52                }
53            }).bind(this));
54        }
55
56        function initializePageSizeDropdown() {
57            this.$pageSizeControl.on("change", (function (e) {
58                this.setPageSize($(e.target).val());
59            }).bind(this));
60        }
61
62        function initializeArrays() {
63            if (typeof this.$container.attr("data-matriz-search-fields") === "string") {
64                this.searchableFields = this.$container.attr("data-matriz-search-fields").split(",");
65            }
66        }
67
68        function initializeSortSettings() {
69            var sortColumn = this.$container.attr("data-matriz-default-sort-column-name")
70                    ? this.$container.attr("data-matriz-default-sort-column-name") : undefined;
71            this.defaultSortDirection = this.$container.attr("data-matriz-default-sort-direction");
72            if (sortColumn) {
73                this.sortSettings = {
74                    "field": sortColumn,
75                    "direction": this.defaultSortDirection
76                };
77            }
78        }
79
80        function load() {
81            this.beforeDataLoad();
82            this.beforeDataLoadEffect();
83            this.loading = true;
84            $.ajax({
85                url: this.dataSourceUri,
86                data: this.getRequestData(),
87                context: this,
88                accepts: "application/json",
89                headers: this.headers
90            }).done(function (data) {
91                this.afterDataLoad(data);
92                if (this.callback instanceof Function) {
93                    this.callback(data);
94                }
95                this.$container.trigger("matriz.ui.list.loaded");
96                matriz.ui.init.void();
97            }).fail(function (jqXHR, textStatus, errorThrown) {
98                matriz.ajax.messages.fail.default(jqXHR, textStatus, errorThrown);
99            }).always(function () {
100                this.afterDataLoadEffect();
101                this.loading = false;
102            });
103        }
104
105        function download() {
106            this.beforeDataLoad();
107            this.beforeDataLoadEffect();
108            this.loading = true;
109            $.ajax({
110                url: this.dataSourceUri.replace("lista-data-table", "exportar"),
111                data: this.getRequestData(),
112                context: this,
113                headers: this.headers,
114                xhrFields: {
115                    responseType: 'blob'
116                },
117            }).done(function (data) {
118                this.afterDataLoad(data);
119                var a = document.createElement("a");
120                var url = window.URL.createObjectURL(data);
121                a.href = url;
122                a.download = "export.csv";
123                document.body.append(a);
124                a.click();
125                a.remove();
126                window.URL.revokeObjectURL(url);
127                this.$container.trigger("matriz.ui.list.loaded");
128                matriz.ui.init.void();
129            }).fail(function (jqXHR, textStatus, errorThrown) {
130                matriz.ajax.messages.fail.default(jqXHR, textStatus, errorThrown);
131            }).always(function () {
132                this.afterDataLoadEffect();
133                this.loading = false;
134            });
135        }
136
137        function $getSearchBox() {
138            var $searchFilter = $container.find(".matriz-ui-pagedlist-filter");
139            var $searchText = $searchFilter.find("[data-matriz-action='filterData']");
140            if ($searchText.length === 0) {
141                $searchText = $searchFilter.find("input[type=text]");
142            }
143            return $searchText;
144        }
145
146        function $getSearchButton() {
147            var $searchFilter = $container.find(".matriz-ui-pagedlist-filter");
148            var $searchButton = $searchFilter.find("[data-matriz-action='filter']");
149            if ($searchButton.length === 0) {
150                $searchButton = $searchFilter.find("button");
151            }
152            return $searchButton;
153        }
154
155        function $getExportButton() {
156            var $searchFilter = $container.find(".matriz-ui-pagedlist-filter");
157            var $exportButton = $searchFilter.find("[data-matriz-action='export']");
158            if ($exportButton.length === 0) {
159                $exportButton = null;
160            }
161            return $exportButton;
162        }
163
164        this.initializeEvents = function () {
165            initializePageSizeDropdown.call(this);
166            initializeSearchField.call(this);
167        };
168
169        this.initializeParameters = function () {
170            this.currentPage = matriz.utils.url.param("pagina") || 1;
171            this.startitem = 0;
172            this.enditem = 0;
173            this.$container = $container;
174            this.$searchBox = $getSearchBox();
175            this.$searchButton = $getSearchButton();
176            this.$exportButton = $getExportButton();
177            this.$pageSizeControl = $container.find(":input.matriz-ui-pagedlist-pagesize");
178            this.dataSourceUri = this.$container.attr("data-matriz-source-uri");
179            this.filterData = this.$searchBox.val();
180            this.pageSize = this.$pageSizeControl.val();
181            this.searchableFields = [];
182            this.recordCount = -1;
183            if (options !== undefined) {
184                this.callback = options.callback;
185            }
186            initializeSortSettings.call(this);
187            initializeArrays.call(this);
188        };
189
190        this.initialize = function () {
191            this.initializeParameters();
192            this.initializeEvents();
193        };
194
195        this.getRequestData = function () {
196            var data = options.data || {};
197            matriz.ui.list.pushdata.call(this, "currentPage", data);
198            matriz.ui.list.pushdata.call(this, "pageSize", data);
199            matriz.ui.list.pushdata.call(this, "filterData", data);
200            matriz.ui.list.pushdata.call(this, "searchableFields", data, "fields");
201            matriz.ui.list.pushdata.call(this, "userDefinedData", data, "user-data");
202            matriz.ui.list.pushdata.call(this, "sortSettings", data);
203            return data;
204        };
205
206        this.beforeDataLoad = function () {
207
208        };
209
210        this.afterDataLoad = function (data) {
211            if (this.appendBody) {
212                this.$container.find(".matriz-ui-pagedlist-body").append(data.body);
213            } else {
214                this.$container.find(".matriz-ui-pagedlist-body").html(data.body);
215            }
216
217            this.recordCount = data.recordcount;
218            this.startitem = parseInt(data.startitem);
219            this.enditem = parseInt(data.enditem);
220            this.pagecount = parseInt(data.pagecount);
221
222            if (this.recordCount > 0) {
223                var self = this;
224                this.$container.find(".matriz-ui-pagedlist-pagination").html(data.pagination);
225
226                this.$container.find("ul.pagination > li.first").click(function () {
227                    self.goto(1);
228                });
229
230                this.$container.find("ul.pagination > li.prev").click(function () {
231                    self.previous();
232                });
233
234                this.$container.find("ul.pagination > li.next").click(function () {
235                    self.next();
236                });
237
238                this.$container.find("ul.pagination >
238 li.last").click(function () {
239                    self.goto(data.pagecount);
240                });
241
242                this.$container.find("ul.pagination > li.page").click(function () {
243                    self.goto($(this).children("a").html());
244                });
245
246                this.$container.find("ul.pagination > li.active").click(function () {
247                    return false;
248                });
249
250                this.$container.find("ul.pagination > li.disabled").click(function () {
251                    return false;
252                });
253            } else {
254                this.$container.find(".matriz-ui-pagedlist-pagination").empty();
255            }
256        };
257
258        this.beforeDataLoadEffect = function () {
259            matriz.ui.loading.element.show($container, this.appendBody);
260        };
261
262        this.afterDataLoadEffect = function () {
263            matriz.ui.loading.element.hide($container, this.appendBody);
264        };
265
266        this.refresh = function () {
267            load.call(this);
268        };
269
270        this.navigate = function (options) {
271
272        };
273
274        this.goto = function (page) {
275            if (page !== this.currentPage) {
276                this.currentPage = parseInt(page);
277                this.refresh();
278            }
279        };
280
281        this.reset = function () {
282            this.currentPage = 1;
283            this.refresh();
284        };
285
286        this.next = function () {
287            this.goto(parseInt(this.currentPage) + 1);
288        };
289
290        this.previous = function () {
291            this.goto(parseInt(this.currentPage) - 1);
292        };
293
294        this.setPageSize = function (maxRecords) {
295            this.pageSize = maxRecords;
296            this.currentPage = 1;
297            this.refresh();
298        };
299
300        this.filter = function (text) {
301            this.filterData = text;
302            this.currentPage = 1;
303            this.refresh();
304            this.$container.trigger("matriz.ui.list.filter");
305        };
306
307        this.export = function (text) {
308            this.filterData = text;
309            download.call(this);
310        };
311
312        this.pageNumber = function () {
313            return this.currentPage;
314        };
315
316        this.pageItensCount = function () {
317            return (this.enditem - this.startitem) + 1;
318        };
319
320        this.reinit = function () {
321            this.initializeParameters();
322        };
323
324        this.isLoading = function() {
325            return this.loading;
326        };
327
328        this.pageCount = function() {
329            return this.pagecount;
330        };
331
332        this.addHeader = function(name, value) {
333            this.headers[name] = value;
334        };
335    };
336    matriz.ui.list.MatrizDataTable = function ($container, options) {
337        matriz.ui.list.AbstractPagedList.call(this, $container, options);
338
339        function getDirection(column) {
340            return column.children("span").attr("class").search("pull-right fa fa-caret-up") !== -1 ? "asc" : "desc";
341        }
342
343        function setUpSortingColumn($column) {
344            if (this.$currentSortingColumn) {
345                if (!$column.children("span").attr("class") || $column.children("span").attr("class").search("pull-right fa") === -1) {
346                    var defaultClass = this.defaultSortDirection === "asc" ? "fa-caret-up" : "fa-caret-down";
347                    $column.children("span").addClass("pull-right fa " + defaultClass);
348                } else {
349                    $column.children("span").toggleClass("fa-caret-up");
350                    $column.children("span").toggleClass("fa-caret-down");
351                }
352                $column.siblings().children("span").removeClass("pull-right fa fa-caret-up fa-caret-down");
353                this.$currentSortingColumn = $column;
354            }
355        }
356
357        function initializeArrays() {
358            var self = this;
359            this.$container.find("th").each(function () {
360                if ($(this).attr("data-matriz-field-sort")) {
361                    self.sortableFields.push($(this).attr("data-matriz-field-sort"));
362                }
363            });
364        }
365
366        function initializeSortingColumns() {
367            var self = this;
368            this.sortableFields.each(function (item, idx) {
369                self.$container.find("th[data-matriz-field-sort='" + item + "']").off("
369click");
370                self.$container.find("th[data-matriz-field-sort='" + item + "']").on("click", function (e) {
371                    setUpSortingColumn.call(self, $(this));
372                    self.sort(self.$currentSortingColumn.attr("data-matriz-field-sort"), getDirection(self.$currentSortingColumn));
373                });
374            });
375        }
376
377        function intializeCurrentSortingColumn() {
378            if (this.$container.attr("data-matriz-default-sort-column-number")) {
379                var columnNumber = this.$container.attr("data-matriz-default-sort-column-number")
380                        ? parseInt(this.$container.attr("data-matriz-default-sort-column-number")) : undefined;
381                this.$currentSortingColumn = columnNumber ?
382                        $(this.$container.find("th").get(columnNumber - 1)) : undefined;
383            } else if (this.$container.attr("data-matriz-default-sort-column-name")) {
384                this.$currentSortingColumn = this.$container.find("th[data-matriz-field-sort='" + this.$container.attr("data-matriz-default-sort-column-name") + "']");
385            } else {
386                this.$currentSortingColumn = undefined;
387            }
388        }
389
390        var __super_initialize = this.initializeParameters;
391        this.initializeParameters = function () {
392            __super_initialize.call(this);
393            intializeCurrentSortingColumn.call(this);
394            this.sortableFields = [];
395            if (this.$currentSortingColumn) {
396                var column = this.$currentSortingColumn.length > 0 ? this.$currentSortingColumn.attr("data-matriz-field-sort") : this.$container.attr("data-matriz-default-sort-column-name");
397                var direction = this.defaultSortDirection;
398                this.setSortSettings(column, direction);
399            }
400            initializeArrays.call(this);
401            initializeSortingColumns.call(this);
402            setUpSortingColumn.call(this, this.$currentSortingColumn);
403            this.refresh();
404        };
405
406        var __super_getRequestData = this.getRequestData;
407        this.getRequestData = function () {
408            var data = __super_getRequestData.call(this);
409            matriz.ui.list.pushdata.call(this, "sortSettings", data);
410            return data;
411        };
412
413        this.setSortSettings = function (column, direction) {
414            if ($.inArray(column, this.sortableFields) === -1) {
415                this.$container.find("th[data-matriz-field-sort] span").removeClass("pull-right fa fa-caret-up fa-caret-down");
416            }
417
418            this.sortSettings = {
419                "field": column,
420                "direction": direction
421            };
422        };
423
424        this.sort = function (column, direction) {
425            this.setSortSettings(column, direction);
426            this.refresh();
427        };
428    };
429    matriz.ui.list.MatrizPagedList = function ($container, options) {
430        matriz.ui.list.AbstractPagedList.call(this, $container, options);
431
432        var __super_initialize = this.initializeParameters;
433        this.initializeParameters = function () {
434            __super_initialize.call(this);
435            this.refresh();
436        };
437    };
438
439    matriz.ui.list.MatrizNavigateList = function ($container, options) {
440        matriz.ui.list.AbstractPagedList.call(this, $container, options);
441
442        var __super_initialize = this.initializeParameters;
443        var __super_beforeDataLoadEffect = this.beforeDataLoadEffect;
444        var __super_afterDataLoadEffect = this.afterDataLoadEffect;
445        var direction = undefined;
446        this.initializeParameters = function () {
447            __super_initialize.call(this);
448            this.refresh();
449        };
450
451
452        this.navigate = function (options) {
453            this.dataSourceUri = options.url;
454            direction = options.direction;
455            this.refresh();
456        }
457
458        this.beforeDataLoadEffect = function () {
459            if (direction === undefined) {
460                __super_beforeDataLoadEffect.call(this);
461            } else if (direction === "left") {
462                matriz.ui.loading.element.hideSlide($container, this.appendBody,"right", 100);
463            } else {
464                matriz.ui.loading.element.hideSlide($container, this.appendBody, "left", 100);
465            }
466        };
467
468        this.afterDataLoadEffect = function () {
469            if (direction === undefined) {
470                __super_afterDataLoadEffect.call(this);
471            } else {
472                setTimeout(function() {
473                    matriz.ui.loading.element.showSlide($container, this.appendBody,direction, 200);
474                },100);
475            }
476        };
477
478    };
479
480    matriz.ui.list.MatrizInfiniteList = function ($container, options) {
481        matriz.ui.list.MatrizPagedList.call(this, $container, options);
482
483        this.appendBody = true;
484
485        var $window = $(window);
486
487        $window.scroll((function () {
488            if ($window.scrollTop() + $window.innerHeight() >= $container.position().top + $container.height() && this.currentPage < this.pagecount && !this.loading) {
489                this.goto(this.currentPage + 1);
490            }
491        }).bind(this));
492
493        this.afterDataLoad = function(data) {
494            this.$container.find(".matriz-ui-pagedlist-body").append(data.body);
495            this.recordCount = data.recordcount;
496            this.pagecount = data.pagecount;
497            this.startitem = parseInt(data.startitem);
498            this.enditem = parseInt(data.enditem);
499        };
500    };
501    matriz.ui.list.MatrizFilteredList = function ($container, options) {
502        matriz.ui.list.MatrizDataTable.call(this, $container, options);
503
504        this.form = {};
505        this.$form = $container.find("form");
506        this.firstTimeLoaded = true;
507
508        this.ignoreFields = [ "ordem", "pagina" ];
509
510        this.isIgnoreField = function(field) {
511            return this.ignoreFields.indexOf(field) === -1;
512        };
513
514        this.isNoCache = function() {
515            for(var field in this.form) {
516                if (this.form[field] && this.isIgnoreField(field)) {
517                    return true;
518                }
519            }
520        };
521
522        this.prepareRequestData = function() {
523            this.form = {};
524            this.$form.serializeArray().each((function (formField) {
525                let textoEntreColchetes = /\[[^\]]+\]/;
526                if (textoEntreColchetes.test(formField.name)) {
527                    const keys = [];
528                    const regex = /([^\[\]]+)/g;
529                    let match;
530
531                    while ((match = regex.exec(formField.name)) !== null) {
532                        keys.push(match[1]);
533                    }
534
535                    keys.reduce((temp, key, index) => {
536                        const isLast = index === keys.length - 1;
537                        if (isLast) {
538                            if (formField.name.endsWith("[]")) {
539                                if (!Array.isArray(temp[key])) {
540                                    temp[key] = [];
541                                }
542                                temp[key].push(formField.value);
543                            } else {
544                                temp[key] = formField.value;
545                            }
546                        } else {
547                            if (!temp[key]) {
548                                temp[key] = {};
549                            }
550                        }
551                        return temp[key];
552                    }, this.form);
553                } else {
554                    if (formField.name.indexOf("[]") !== -1) {
555                        var multipleName = formField.name.split("[]")[0];
556                        if (typeof this.form[multipleName] === "undefined") {
557                            this.form[multipleName] = [];
558                        }
559                        this.form[multipleName].push(formField.value);
560                    } else {
561                        this.form[formField.name] = formField.value;
562                    }
563                }
564            }).bind(this));
565        };
566
567        var __super_getRequestData = this.getRequestData;
568        this.getRequestData = function () {
569            var data = __super_getRequestData.call(this);
570            matriz.ui.list.pushdata.call(this, "form", data);
571            return data;
572        };
573
574        var super__initialize = this.initialize;
575        this.initialize = function () {
576            matriz.utils.url.paramsToForm(this.$form);
577            super__initialize.call(this);
578        };
579
580        this.beforeDataLoad = function () {
581            var $inputCurrentPage = this.$form.find("[name='pagina']");
582
583            if (this.currentPage > 1) {
584                if (!$inputCurrentPage.length) {
585                    $inputCurrentPage = $("<input>").attr({
586                        "name": "pagina",
587                        "type": "hidden"
588                    }).prependTo(this.$form);
589                }
590                $inputCurrentPage.val(this.currentPage);
591            } else {
592                if ($inputCurrentPage.length) {
593                    $inputCurrentPage.remove();
594                }
595            }
596
597            if (!this.firstTimeLoaded) {
598                matriz.utils.url.search(this.$form);
599            } else {
600                this.firstTimeLoaded = false;
601            }
602
603            this.prepareRequestData();
604
605            if (this.isNoCache()) {
606                this.addHeader("Cache-Control", "no-cache, no-store");
607            }
608        };
609    };
610
611    matriz.ui.DynamicContentLoader = function (options) {
612
613        this.options = options === undefined ? {} : options;
614        this.options.data = this.options.data === undefined ? {} : this.options.data;
615
616        function loadTemplate() {
617            if (this.url === "") {
618                throw new Error("A url não foi atribuída ao DynamicContentLoader.");
619            }
620            var url = (this.__type) ? this.url + "/" + this.__type : this.url;
621            matriz.ui.loading.element.show(this.containers.$templatebody());
622            $.ajax({
623                url: url,
624                data: this.options.data,
625                context: this
626            }).done(function (data) {
627                this.onTemplateLoaded(data);
628            }).fail(function (jqXHR, textStatus, errorThrown) {
629                this.fail(jqXHR, textStatus, errorThrown, "Falha ao carregar template");
630            }).always(function () {
631
632            });
633        }
634
635        this.appendQueryString = function (uri, data) {
636            if (data instanceof Object) {
637                var fields = [];
638                for (var key in data) {
639                    fields.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
640                }
641                if (uri.search(/\?/) !== -1) {
642                    return uri + "&" + fields.join("&");
643                } else {
644                    return uri + "?" + fields.join("&");
645                }
646            } else {
647                return uri;
648            }
649        };
650
651        this.onTemplateLoaded = function (data) {
652            this.containers.$templatebody().html(data);
653            this.setUpMatrizAction();
654        };
655
656        this.setUpMatrizAction = function () {
657            var self = this;
658            this.containers.$main().find("[data-matriz-action]").each(function (index, element) {
659                var action = $(element).attr("data-matriz-action");
660                if (self.onMatrizAction && self.onMatrizAction[action] && typeof self.onMatrizAction[action] === "function") {
661                    $(element).off("click").on("click", function (e) {
662                        self.onMatrizAction[action].call(self, element);
663                    });
664                }
665            });
666        };
667
668        /**
669         * Inicializa a modal
670         */
671        this.start = function () {
672            loadTemplate.call(this);
673        };
674
675        /**
676         * Reinicializa a modal
677         */
678        this.refresh = function () {
679            loadTemplate.call(this);
680        };
681
682        /**
683         * Exibe mensagem de erro
684         */
685        this.fail = function (jqXHR, textStatus, errorThrown, message) {
686            if (options.events !== undefined && options.events.onError !== undefined) {
687                options.events.onError.call(this, {
688                    jqXHR: jqXHR,
689                    textStatus: textStatus,
690                    errorThrown: errorThrown,
691                    message: message
692                });
693            } else {
694                matriz.ajax.messages.fail.default(jqXHR, textStatus, errorThrown, message);
695            }
696        };
697    };
698    matriz.ui.MasterDetail = function (options) {
699
700        matriz.ui.DynamicContentLoader.call(this, options);
701
702        var editing = false;
703        this.__type = "modal";
704        this.__contentContainerSelector = " .modal-content";
705
706        function deleteItem(id) {
707            matriz.confirm("Esta ação é irreversível. Deseja prosseguir?", (function () {
708                $.ajax({
709                    url: this.url + "/" + id + "/excluir",
710                    context: this
711                }).done(function (data, textStatus, jqXHR) {
712                    this.onItemDeleted();
713                }).fail(function (jqXHR, textStatus, errorThrown) {
714                    matriz.ajax.messages.fail.default(jqXHR, textStatus, "Falha na tentativa de exclusão");
715                }).always(function () {
716
717                });
718            }).bind(this));
719        }
720
721        function loadItem(id) {
722            $.ajax({
723                url: this.url + "/" + id + "/editar",
724                context: this,
725                data: this.options.data
726            }).done(function (data, textStatus, jqXHR) {
727                this.onItemLoaded(data);
728            }).fail(function (jqXHR, textStatus, errorThrown) {
729                matriz.ajax.messages.fail.default(jqXHR, textStatus);
730            }).always(function () {
731
732            });
733        }
734
735        function save(form, saveAndLink, e) {
736            if ($(form).valid()) {
737                $.ajax({
738                    "url": this.appendQueryString($(form).attr("action"), this.options.data),
739                    "context": this,
740                    "data": $(form).serialize(),
741                    "type": "POST"
742                }).done(function (data) {
743                    matriz.box.notify.success("Registro salvo com sucesso.");
744
745                    if (saveAndLink) {
746                        this.link(data);
747                        this.onSaveAndLink();
748                    } else {
749                        this.onItemSaved();
750                    }
751                }).fail(function (jqXHR, textStatus, errorThrown) {
752                    matriz.ajax.messages.fail.default(jqXHR, textStatus);
753                }).always(function () {
754
755                });
756            }
757            if (e !== undefined) {
758                e.preventDefault();
759            }
760        }
761
762        function enableItem(id) {
763            $.ajax({
764                url: this.url + "/" + id + "/ativar",
765                context: this
766            }).done(function (data, textStatus, jqXHR) {
767                this.onItemEnabled();
768            }).fail(function (jqXHR, textStatus, errorThrown) {
769                matriz.ajax.messages.fail.default(jqXHR, textStatus, "Falha na tentativa de ativação");
770            }).always(function () {
771
772            });
773        }
774
775        function disableItem(id) {
776            $.ajax({
777                url: this.url + "/" + id + "/inativar",
778                context: this
779            }).done(function (data, textStatus, jqXHR) {
780                this.onItemDisabled();
781            }).fail(function (jqXHR, textStatus, errorThrown) {
782                matriz.ajax.messages.fail.default(jqXHR, textStatus, "Falha na tentativa de inativação");
783            }).always(function () {
784
785            });
786        }
787
788        function setUpDataTable() {
789            if (this.containers.$datalist() && this.containers.$datalist().length > 0) {
790                var uri = this.containers.$datalist().find(".matriz-ui-pagedlist-container").attr("data-matriz-source-uri");
791                this.containers.$datalist().find(".matriz-ui-pagedlist-container").attr("data-matriz-source-uri", this.appendQueryString(uri, this.options.data));
792                this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList({
793                    "callback": (function () {
794                        this.onDataTableLoaded();
795                    }).bind(this)
796                });
797            }
798        }
799
800        function setUpGoBackAction() {
801            var context = this;
802            this.containers.$main().find('[data-matriz-action="cancel"]').on("click", function () {
803                context.showTabs();
804            });
805        }
806
807        function setUpItemsAction() {
808            var context = this;
809            this.containers.$main().find(".matriz-ui-pagedlist-container [data-matriz-action='edit']").on("click", function (e) {
810                var id = $(this).attr("data-matriz-id");
811                loadItem.call(context, id);
812                e.preventDefault();
813            });
814
815            this.containers.$main().find(".matriz-ui-pagedlist-container .[data-matriz-action='delete']").on("click", function (e) {
816                var id = $(this).attr("data-matriz-id");
817                deleteItem.call(context, id);
818                e.preventDefault();
819            });
820
821            this.containers.$main().find(".matriz-ui-pagedlist-container .[data-matriz-action='enable']").on("click", function (e) {
822                var id = $(this).attr("data-matriz-id");
823                enableItem.call(context, id);
824                e.preventDefault();
825            });
826
827            this.containers.$main().find(".matriz-ui-pagedlist-container .[data-matriz-action='disable']").on("click", function (e) {
828                var id = $(this).attr("data-matriz-id");
829                disableItem.call(context, id);
830                e.preventDefault();
831            });
832        }
833
834        function setUpItemsCheckBoxes() {
835            var context = this;
836            this.containers.$main().find("td input[type='checkbox']").on("change", function () {
837                if (context.containers.$main().find("td input[type='checkbox']::checked").length === context.containers.$main().find("td input[type='checkbox']").length) {
838                    if (!context.containers.$main().find("[data-matriz-action='select-all']").prop("checked")) {
839                        context.containers.$main().find("[data-matriz-action='select-all']").prop("checked", true);
840                    }
841                } else {
842                    context.containers.$main().find("[data-matriz-action='select-all']").prop("checked", false);
843                }
844            });
845        }
846
847        function setUpLinkSelectedAction() {
848            var context = this;
849            this.containers.$main().find("[data-matriz-action='link-selected']").on("click", function () {
850                var items = [];
851                context.containers.$main().find("td input[type='checkbox']::checked").each(function (idx, item) {
852                    items.push({"id": $(item).attr("value"), "attributes": matriz.utils.dom.attributes($(this).get(0), /^data-/)});
853                }).promise().done(function () {
854                    context.onItemsLinked(items);
855                });
856            });
857        }
858
859        function setUpLinkItemAction() {
860            var context = this;
861            this.containers.$main().find("[data-matriz-action='link']").on("click", function () {
862                var items = [{
863                        "id": $(this).attr("data-matriz-id"),
864                        "attributes": matriz.utils.dom.attributes($(this).get(0), /^data-/)
865                    }];
866                context.onItemsLinked(items);
867            });
868        }
869
870
871        function setUpSelectAllItemsAction() {
872            var context = this;
873            this.containers.$main().find("[data-matriz-action='select-all']").prop("checked", false);
874            this.containers.$main().find("[data-matriz-action='select-all']").on("change", function () {
875                context.containers.$main().find("td input[type='checkbox']::enabled").prop("checked", $(this).prop("checked"));
876            });
877        }
878
879        this.validation = {
880            "errorClass": "label label-danger",
881            "errorElement": "div",
882            "highlight": false,
883            "submitHandler": function () {
884                return false;
885            }
886        };
887
888        /**
889         * Método utilizado para relacionar uma biblioteca a um conteudo
890         */
891        this.link = function (data) {
892            if (matriz.utils.string.isInt(data)) {
893                data = {id: parseInt(data)};
894            }
895            try {
896                var dataTemp = $.parseJSON(data);
897                if (dataTemp) {
898                    data = dataTemp;
899                }
900            } catch (e) {
901            }
902            this.onItemsLinked([data]);
903        };
904
905        /**
906         * Evento executado quando os dados da lista são carregados
907         */
908        this.onDataTableLoaded = function () {
909            setUpItemsAction.call(this);
910            setUpItemsCheckBoxes.call(this);
911            setUpSelectAllItemsAction.call(this);
912            setUpLinkItemAction.call(this);
913        };
914
915        /**
916         * Evento executado quando o template da modal é carregado
917         */
918        this.onTemplateLoaded = function (data) {
919            $(this.containers.$templatebody()).html(data);
920            setUpDataTable.call(this);
921            setUpGoBackAction.call(this);
922            if (this.options.data.modo === "relacionamento" || this.options.data.modo === "conteudo-em-lote") {
923                setUpLinkSelectedAction.call(this);
924            }
925            this.containers.$new().find('form').validate(this.validation);
926            this.setUpSaveNew();
927            this.showTabs();
928            matriz.ui.init.modal(this.containers.$main());
929        };
930
931        /**
932         * Evento executado quando um item é excluido
933         */
934        this.onItemDeleted = function () {
935            matriz.box.notify.success("Registro excluído com sucesso.");
936            this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh");
937            this.showTabs();
938        };
939
940        /**
941         * Evento executado quando um item é carregado
942         */
943        this.onItemLoaded = function (data) {
944            $(this.containers.$edit()).html(data);
945            setUpGoBackAction.call(this);
946            this.showEdicao();
947            this.containers.$edit().find('form').validate(this.validation);
948            this.setUpSaveExistent();
949            matriz.ui.init.all();
950        };
951
952        /**
953         * Evento executado quando um item é salvo
954         */
955        this.onItemSaved = function () {
956            this.start();
957        };
958
959        /**
960         * Evento executado a ação de relacionar itens é executada
961         */
962        this.onItemsLinked = function (items) {
963            console.log(items);
964        };
965
966        /**
967         * Evento executado quando um item é salvo e relacionado
968         */
969        this.onSaveAndLink = function () {
970            $(this.containers.$linked().find('[data-toggle="modal"]').attr("href")).modal('hide');
971            this.containers.$linked().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh");
972        };
973
974        this.onItemEnabled = function () {
975            matriz.box.notify.success("Registro ativado com sucesso.");
976            this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh");
977            this.showTabs();
978        };
979
980        this.onItemDisabled = function () {
981            matriz.box.notify.success("Registro inativado com sucesso.");
982            this.containers.$datalist().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh");
983            this.showTabs();
984        };
985
986        /**
987         * Configura as ações para gravação de um novo item
988         */
989        this.setUpSaveNew = function () {
990            if (this.containers.$new() && this.containers.$new().length > 0) {
991                this.containers.$new().find('form').on("submit", save.bind(this, this.containers.$new().find('form')[0], undefined));
992                this.containers.$new().find('[data-matriz-action="save"]').on("click", (function (e) {
993                    this.containers.$new().find('form').trigger("submit");
994                    e.preventDefault();
995                }).bind(this));
996
997                if (this.options.data.modo === "relacionamento") {
998                    this.containers.$new().find('[data-matriz-action="save-and-link"]').on("click", (function (e) {
999                        save.call(this, this.containers.$new().find('form')[0], e);
1000                        e.preventDefault();
1001                    }).bind(this));
1002                }
1003            }
1004        };
1005
1006        /**
1007         * Configura as ações para gravação de um novo existente
1008         */
1009        this.setUpSaveExistent = function () {
1010            if (this.containers.$edit() && this.containers.$edit().length > 0) {
1011                this.containers.$edit().find('form').on("submit", save.bind(this, this.containers.$edit().find('form')[0], undefined));
1012                this.containers.$edit().find('[data-matriz-action="save"]').on("click", (function (e) {
1013                    this.containers.$edit().find('form').trigger("submit");
1014                    e.preventDefault();
1015                }).bind(this));
1016
1017                if (this.options.data.modo === "relacionamento") {
1018                    this.containers.$edit().find('[data-matriz-action="save-and-link"]').on("click", (function (e) {
1019                        save.call(this, this.containers.$edit().find('form')[0], true, e);
1020                        e.preventDefault();
1021                    }).bind(this));
1022                }
1023
1024            }
1025        };
1026
1027        /**
1028         * Exibe tab de edição e desativa a tab de lista e inclusão
1029         */
1030        this.showEdicao = function () {
1031            editing = true;
1032            //desabilita tabs de lista e inclusão
1033            this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"]').parent("li").addClass("disabled");
1034            this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').parent("li").addClass("disabled");
1035            //Exibe tab de edição
1036            this.containers.$main().find('a[href="#' + this.containers.$edit().attr("id") + '"]').show();
1037            this.containers.$main().find('a[href="#' + this.containers.$edit().attr("id") + '"]').tab('show');
1038            this.containers.$main().find('li.disabled a').click(function () {
1039                return !editing;
1040            });
1041
1042            this.containers.$main().find("[data-matriz-action='link-selected']").hide();
1043        };
1044
1045        /**
1046         * Ativa a tab de lista e inclusão e remove a tab de edição
1047         */
1048        this.showTabs = function () {
1049            editing = false;
1050            //configura o evento de clique das tabs
1051            this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"], a[href="#' + this.containers.$datalist().attr("id") + '"]').click(function (e) {
1052                $(this).tab('show');
1053                e.preventDefault();
1054            });
1055
1056            if (this.options.data.modo === "relacionamento" || this.options.data.modo === "conteudo-em-lote") {
1057                //Configura para que a tab de edição não exiba o botão de relacionamento
1058                this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"], a[href="#' + this.containers.$edit() + '"]').on('shown.bs.tab', (function (e) {
1059                    this.containers.$main().find("[data-matriz-action='link-selected']").hide();
1060                }).bind(this));
1061                //Configura para que a tab de lista exiba o botão de relacionamento
1062                this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').on('shown.bs.tab', (function (e) {
1063                    this.containers.$main().find("[data-matriz-action='link-selected']").show();
1064                }).bind(this));
1065            }
1066
1067            //habilita tabs de lista e inclusão
1068            if (this.containers.$datalist() && this.containers.$datalist().length > 0) {
1069                this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').tab('show');
1070            } else {
1071                this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"]').tab('show');
1072            }
1073
1074            this.containers.$main().find('a[href="#' + this.containers.$new().attr("id") + '"]').parent("li").removeClass("disabled");
1075            this.containers.$main().find('a[href="#' + this.containers.$datalist().attr("id") + '"]').parent("li").removeClass("disabled");
1076            //Oculta tab de edição
1077            this.containers.$main().find('a[href="#' + this.containers.$edit().attr("id") + '"]').hide();
1078
1079        };
1080
1081        this.show = function () {
1082            this.containers.$main().modal('show');
1083        };
1084
1085        this.hide = function () {
1086            this.containers.$main().modal('hide');
1087        };
1088
1089        var __super__start = this.start;
1090        this.start = function () {
1091            __super__start.call(this);
1092        };
1093
1094    };
1095    matriz.ui.MasterDetail.prototype = new matriz.ui.DynamicContentLoader();
1096    matriz.ui.Form = function (options) {
1097        matriz.ui.MasterDetail.call(this, options);
1098
1099        function loadItem(id) {
1100            this.showEdicao();
1101            matriz.ui.loading.element.show($(this.containers.$edit()));
1102
1103            $.ajax({
1104                url: this.url + "/" + id + "/editar",
1105                context: this,
1106                data: this.options.data
1107            }).done(function (data, textStatus, jqXHR) {
1108                this.onItemLoaded(data);
1109            }).fail(function (jqXHR, textStatus, errorThrown) {
1110                matriz.ajax.messages.fail.default(jqXHR, textStatus, errorThrown);
1111            }).always(function () {
1112
1113            });
1114        }
1115
1116        var __super_onTemplateLoaded = this.onTemplateLoaded;
1117        this.onTemplateLoaded = function (data) {
1118            __super_onTemplateLoaded.call(this, data);
1119            if (options.modo === "edicao") {
1120                loadItem.call(this, options.itemId);
1121            }
1122        };
1123
1124        /**
1125         * Evento executado quando um item é salvo
1126         */
1127        this.onItemSaved = function () {
1128            this.containers.$linked().find(".matriz-ui-pagedlist-container").matrizPagedList("refresh");
1129            this.hide();
1130        };
1131
1132    };
1133    matriz.ui.Form.prototype = new matriz.ui.MasterDetail();
1134
1135    matriz.ui.imagecropper = {
1136        ImageCroppingStep: function (options) {
1137
1138            var area = {
1139                "x": 0, "y": 0,
1140                "height": 0, "width": 0
1141            };
1142            var domImageDimension;
1143            var jcropApi = null;
1144            var minDimension = getMinDimension();
1145            var widthRelativeRatio = 1;
1146            var initialSelection = undefined;
1147
1148            function getDefaultSelection(dimension) {
1149                if (initialSelection === undefined) {
1150                    var x1, y1, x2, y2;
1151                    if (minDimension.width / minDimension.height <= dimension.width / dimension.height) {
1152                        y1 = 0;
1153                        y2 = dimension.height;
1154                        var w = (y2 * options.proportion.width) / options.proportion.height;
1155                        x1 = dimension.width / 2 - w / 2;
1156                        x2 = x1 + dimension.width;
1157                    } else {
1158                        x1 = 0;
1159                        x2 = dimension.width;
1160                        var h = (x2 * options.proportion.height) / options.proportion.width;
1161                        y1 = dimension.height / 2 - h / 2;
1162                        y2 = y1 + dimension.height;
1163                    }
1164                    return [x1, y1, x2, y2];
1165                } else {
1166                    return initialSelection;
1167                }
1168            }
1169
1170            function getMinDimension() {
1171                var minDimension = {
1172                    "width": 0, "height": 0
1173                };
1174                for (var i = 0, len = options.proportion.dimensions.length; i < len; i++) {
1175                    var minWidth = minDimension.width;
1176                    var minHeight = minDimension.height;
1177                    var opWidth = options.proportion.dimensions[i].width;
1178                    var opHeight = options.proportion.dimensions[i].height;
1179                    if (minWidth * minHeight === 0 || minWidth * minHeight < opWidth * opHeight) {
1180                        minDimension.width = options.proportion.dimensions[i].width;
1181                        minDimension.height = options.proportion.dimensions[i].height;
1182                    }
1183                }
1184                return minDimension;
1185            }
1186
1187            function getRelativeBasedDimension() {
1188                return {
1189                    "width": options.$container.find("img").width() * minDimension.width / area.width,
1190                    "height": options.$container.find("img").height() * minDimension.height / area.height
1191                };
1192            }
1193
1194            this.enter = function () {
1195                if (jcropApi) {
1196                    jcropApi.destroy();
1197                }
1198                options.$container.empty().addClass("matriz-loading-clock");
1199                var img = options.image.object;
1200                domImageDimension = {
1201                    width: img.width, height: img.height
1202                };
1203                if (area.width === 0 && area.height === 0) {
1204                    area = {
1205                        "x": 0, "y": 0,
1206                        "height": options.image.object.height, "width": options.image.object.width
1207                    };
1208                }
1209                var relativeMinDimension, $img, imgDimension;
1210                options.$container.removeClass("matriz-loading-clock");
1211                $img = $(img);
1212                $img.addClass("matriz-cropper-image")
1213                        .appendTo("<div />")
1214                        .parent()
1215                        .appendTo(options.$container);
1216                relativeMinDimension = getRelativeBasedDimension({"width": options.$container.find("img").width(), "height": options.$container.find("img").height()});
1217                imgDimension = {"width": $img.width(), "height": $img.height()};
1218                $img.parent()
1219                        .Jcrop({
1220                            "aspectRatio": options.proportion.width / options.proportion.height,
1221                            "minSize": [relativeMinDimension.width, relativeMinDimension.height],
1222                            "setSelect": getDefaultSelection(imgDimension)
1223                        }, function () {
1224                            jcropApi = this;
1225                        });
1226            };
1227
1228            this.getRealSelection = function () {
1229                var imageselection = jcropApi.tellSelect();
1230                var selectedArea = {
1231                    "x": ((domImageDimension.width * widthRelativeRatio * imageselection.x) / options.$container.find("img").width()),
1232                    "y": ((domImageDimension.width * widthRelativeRatio * imageselection.y) / options.$container.find("img").width()),
1233                    "width": ((domImageDimension.width * widthRelativeRatio * imageselection.w) / options.$container.find("img").width()),
1234                    "height": ((domImageDimension.width * widthRelativeRatio * imageselection.h) / options.$container.find("img").width())
1235                };
1236                return selectedArea;
1237            };
1238
1239            this.getProportion = function () {
1240                return options.proportion;
1241            };
1242
1243            this.saveSelection = function () {
1244                var selection = jcropApi.tellSelect();
1245                initialSelection = [selection.x, selection.y, selection.x2, selection.y2];
1246            };
1247
1248        },
1249        StepController: function (options) {
1250
1251            var stepsStack = [];
1252            var stackLength = 0;
1253            var stepPointer = -1;
1254
1255            function checkSelection(area) {
1256                if (area.width === 0 && area.height === 0) {
1257                    throw new Error("Nenhuma área foi selecionada para recorte.");
1258                }
1259            }
1260
1261            function showStep() {
1262                stepsStack[stepPointer].enter();
1263                setUpActionsDisplay();
1264            }
1265
1266            function nextStep() {
1267                var area = {
1268                    "x": 0, "y": 0,
1269                    "width": 0, "height": 0
1270                };
1271                if (stepPointer >= 0) {
1272                    area = stepsStack[stepPointer].getRealSelection();
1273                    stepsStack[stepPointer].saveSelection();
1274                    checkSelection(area);
1275                }
1276                stepPointer++;
1277                showStep();
1278            }
1279
1280            function previousStep() {
1281                if (stepPointer >= 0) {
1282                    stepsStack[stepPointer].saveSelection();
1283                }
1284                stepPointer--;
1285                showStep();
1286            }
1287
1288            function finishCropping() {
1289                var crops = {};
1290                checkSelection(stepsStack[stepPointer].getRealSelection());
1291                for (var i = 0; i < stackLength; i++) {
1292                    var step = stepsStack[i];
1293                    crops[step.getProportion().id] = step.getRealSelection();
1294                    crops[step.getProportion().id].preview = step.getProportion().preview;
1295                    crops[step.getProportion().id].editingpreview = step.getProportion().editingpreview;
1296                    if (i === 0) {
1297                        options.initialSelection = step.getRealSelection();
1298                    }
1299                }
1300                options.onFinished({
1301                    "crops": crops,
1302                    "orientation": options.optiongroup.$orientation.filter(":checked").val(),
1303                    "dimension": stepsStack[0].getProportion().dimensions[0]
1304                });
1305            }
1306
1307            function orientationOptionGroupShow() {
1308                if (Object.keys(options.orientations).length === 1) {
1309                    options.optiongroup.$orientation.prop("disabled", true);
1310                } else {
1311                    options.optiongroup.$orientation.prop("disabled", false);
1312                }
1313            }
1314
1315            function setUpActionsDisplay() {
1316                if (stepPointer > 0) {
1317                    options.buttons.$back.show();
1318                    options.optiongroup.$orientation.attr("disabled", true);
1319                    options.optiongroup.$orientation.parents("label")
1320                            .addClass("matriz-desabilidato")
1321                            .addClass("matriz-inativo");
1322                } else {
1323                    options.buttons.$back.hide();
1324                    options.optiongroup.$orientation.attr("disabled", false);
1325                    options.optiongroup.$orientation.parents("label")
1326                            .removeClass("matriz-desabilidato")
1327                            .removeClass("matriz-inativo");
1328                    orientationOptionGroupShow();
1329                }
1330
1331                if (stepPointer === stackLength - 1) {
1332                    options.buttons.$next.hide();
1333                    options.buttons.$finish.show();
1334                } else {
1335                    options.buttons.$next.show();
1336                    options.buttons.$finish.hide();
1337                }
1338
1339                options.$body.find(".matriz-recorte-info").text(stepsStack[stepPointer].getProportion().title);
1340
1341            }
1342
1343            function setUpButtonActions() {
1344                options.buttons.$back.off();
1345                options.buttons.$back.on("click", function () {
1346                    previousStep();
1347                });
1348                options.buttons.$next.off();
1349                options.buttons.$next.on("click", function () {
1350                    try {
1351                        nextStep();
1352                    } catch (error) {
1353                        matriz.box.notify.danger(error.message);
1354                    }
1355                });
1356                options.buttons.$finish.off();
1357                options.buttons.$finish.on("click", function () {
1358                    try {
1359                        finishCropping();
1360                    } catch (error) {
1361                        matriz.box.notify.danger(error.message);
1362                    }
1363                });
1364            }
1365
1366            function setUpSteps() {
1367                var currentOrientation = options.optiongroup.$orientation.filter(":checked").val();
1368                var proportions = options.orientations[currentOrientation];
1369                stepsStack = [];
1370                stepPointer = -1;
1371                for (var keyProportion in proportions) {
1372                    var proportion = proportions[keyProportion];
1373                    var step = new matriz.ui.imagecropper.ImageCroppingStep({
1374                        "$container": options.$body.find(".matriz-cropper-image-container"),
1375                        "proportion": proportion,
1376                        "image": {
1377                            "id": options.image.id,
1378                            "object": options.image.object,
1379                            "orientation": options.image.orientation
1380                        },
1381                        "controller": this
1382                    });
1383                    stepsStack.push(step);
1384                }
1385                stackLength = stepsStack.length;
1386                if (stackLength > 0) {
1387                    nextStep();
1388                }
1389            }
1390
1391            function orientationReset() {
1392                if (options.initialSelection) {
1393                    options.image.orientation = options.initialSelection.width >= options.initialSelection.height ? "horizontal" : "vertical";
1394                }
1395                options.optiongroup.$orientation.filter("[value='" + options.image.orientation + "']")
1396                        .prop("checked", true)
1397                        .trigger("change");
1398                orientationOptionGroupShow();
1399            }
1400
1401            function setUpOrientationSelection() {
1402                options.optiongroup.$orientation.off();
1403                options.optiongroup.$orientation.on("change", function () {
1404                    setUpSteps();
1405                });
1406                orientationReset();
1407            }
1408
1409            this.start = function () {
1410                setUpButtonActions.call(this);
1411                setUpOrientationSelection.call(this);
1412            };
1413
1414            this.reset = function () {
1415                orientationReset();
1416            };
1417
1418        },
1419        /**
1420         *
1421         * @param Node options.modal
1422         * @param String options.image.src
1423         * @param String options.sizetype
1424         * @param Number options.dimensions.horizontal.pq.width
1425         * @param Number options.dimensions.horizontal.pq.height
1426         * @param Number options.dimensions.horizontal.md.width
1427         * @param Number options.dimensions.horizontal.md.height
1428         * @param Number options.dimensions.horizontal.gd.width
1429         * @param Number options.dimensions.horizontal.gd.height
1430         * @param Number options.dimensions.vertical.pq.width
1431         * @param Number options.dimensions.vertical.pq.height
1432         * @param Number options.dimensions.vertical.md.width
1433         * @param Number options.dimensions.vertical.md.height
1434         * @param Number options.dimensions.vertical.gd.width
1435         * @param Number options.dimensions.vertical.gd.height
1436         * @param Function options.imageValid
1437         * @param Function options.imageInvalid
1438         */
1439        ImageCropper: function (options) {
1440
1441            var orientationsConfig = {
1442                "horizontal": [
1443                    {"id": "16:9", "title": "Recorte proporcional de 16:9", "width": 16, "he
1443ight": 9,
1444                        "dimensions": [
1445                            {"id": "gd", "width": 800, "height": 450},
1446                            {"id": "md", "width": 608, "height": 342},
1447                            {"id": "pq", "width": 336, "height": 189}]
1448                    },
1449                    {"id": "ThumbHorizontal", "title": "Recorte quadrado", "width": 1, "height": 1, "dimensions": [{"id": "th", "width": 180, "height": 180}]}],
1450                "vertical": [
1451                    {"id": "3:4", "title": "Recorte proporcional de 3:4", "width": 3, "height": 4,
1452                        "dimensions": [
1453                            {"id": "gd", "width": 801, "height": 1068},
1454                            {"id": "md", "width": 600, "height": 800},
1455                            {"id": "pq", "width": 345, "height": 460}]
1456                    },
1457                    {"id": "ThumbVertical", "title": "Recorte quadrado", "width": 1, "height": 1, "dimensions": [{"id": "th", "width": 180, "height": 180}]}]
1458            };
1459            var originalimg;
1460            var $container;
1461            var $orientationOptionGroup;
1462            var $cancelButton;
1463            var $backButton;
1464            var $nextButton;
1465            var $finishButton;
1466            var $croppingBody;
1467            var $image;
1468            var imageOrientation;
1469            var largestDimensions = {
1470                "horizontal": {
1471                    "width": 0, "height": 0
1472                },
1473                "vertical": {
1474                    "width": 0, "height": 0
1475                }
1476            };
1477            var validOrientations = {};
1478            var stepController;
1479
1480            function abortCropping(error) {
1481                $container.modal("hide");
1482                matriz.box.notify.danger(error.message);
1483                if (options.onAbort) {
1484                    options.onAbort(error);
1485                }
1486            }
1487
1488            function getLargestDimensionByOrientation(orientation) {
1489                var orientationConfig = orientationsConfig[orientation];
1490                var maxDimension = {"width": 0, "height": 0}, currentMaxRate = 0;
1491                for (var keyProportion in orientationConfig) {
1492                    var dimensions = orientationConfig[keyProportion].dimensions;
1493                    for (var keyDimension in dimensions) {
1494                        var rate = dimensions[keyDimension].width * dimensions[keyDimension].height;
1495                        if (rate > currentMaxRate) {
1496                            maxDimension = dimensions[keyDimension];
1497                            currentMaxRate = rate;
1498                        }
1499                    }
1500                }
1501                return maxDimension;
1502            }
1503
1504            function setUpLargestDimensions() {
1505                largestDimensions["horizontal"] = getLargestDimensionByOrientation.call(this, "horizontal");
1506                largestDimensions["vertical"] = getLargestDimensionByOrientation.call(this, "vertical");
1507            }
1508
1509            function setUpImageOrientation() {
1510                if (originalimg.width >= originalimg.height) {
1511                    imageOrientation = "horizontal";
1512                } else {
1513                    imageOrientation = "vertical";
1514                }
1515            }
1516
1517            function addOrientationInValidOrientationsIfValid(orientation) {
1518                if (largestDimensions[orientation].width <= originalimg.width
1519                        && largestDimensions[orientation].height <= originalimg.height) {
1520                    validOrientations[orientation] = orientationsConfig[orientation];
1521                }
1522            }
1523
1524            function setUpValidOrientations() {
1525                addOrientationInValidOrientationsIfValid.call(this, "horizontal");
1526                addOrientationInValidOrientationsIfValid.call(this, "vertical");
1527                if (Object.keys(validOrientations).length === 0) {
1528                    var dimensions = [];
1529                    for (var orientation in largestDimensions) {
1530                        dimensions.push("<strong>" + largestDimensions[orientation].width + " x " + largestDimensions[orientation].height + " px</strong>");
1531                    }
1532                    var msg = "A imagem selecionada não possui tamanho suficiente para recorte.\r\n";
1533                    msg = msg.concat("Para efetuar o recorte a imagem deve possuir uma resolução mínima de ").concat(dimensions.join(" ou ").concat("."));
1534                    abortCropping(new Error(msg));
1535                }
1536            }
1537
1538            function onFinished(croppingData) {
1539                $container.hide();
1540                options.onFinished(croppingData);
1541            }
1542
1543            function onCancel() {
1544                $container.hide();
1545                options.onCancel();
1546            }
1547
1548            function setUpStepController() {
1549                stepController = new matriz.ui.imagecropper.StepController({
1550                    "$body": $croppingBody,
1551                    "buttons": {
1552                        "$back": $backButton,
1553                        "$next": $nextButton,
1554                        "$finish": $finishButton
1555                    },
1556                    "optiongroup": {
1557                        "$orientation": $orientationOptionGroup
1558                    },
1559                    "image": {
1560                        "id": options.imageId,
1561                        "object": originalimg,
1562                        "orientation": imageOrientation
1563                    },
1564                    "initialSelection": options.initialSelection,
1565                    "orientations": validOrientations,
1566                    "onFinished": onFinished.bind(this)
1567                });
1568            }
1569
1570            function setup() {
1571                matriz.ui.loadImage($image.attr("src")).done(function (img) {
1572                    originalimg = img;
1573                    setUpLargestDimensions.call(this);
1574                    setUpImageOrientation.call(this);
1575                    setUpValidOrientations.call(this);
1576                    setUpStepController();
1577                    matriz.ui.loading.element.hide($croppingBody);
1578                    stepController.start();
1579                }).fail(function (error) {
1580                    abortCropping(error);
1581                });
1582            }
1583
1584            function validateOptions() {
1585                if (!options.imageId) {
1586                    throw new Error("options.imageId não foi definido. Hint: imageId deve ser o identificador da imagem que será efetuada o recorte.");
1587                }
1588                if (!options.$container) {
1589                    throw new Error("options.$container não foi definido.");
1590                }
1591                if (!options.onCancel) {
1592                    throw new Error("options.$onCancel não foi definido.");
1593                }
1594                if (!options.onFinished) {
1595                    throw new Error("options.$onFinished não foi definido.");
1596                }
1597            }
1598
1599            function __construct() {
1600                validateOptions();
1601                orientationsConfig = options.dimensions || orientationsConfig;
1602                $container = options.$container;
1603                $image = $container.find("img");
1604                $cancelButton = $container.find("[data-matriz-action='cancel']");
1605                $backButton = $container.find("[data-matriz-action='back']").hide();
1606                $nextButton = $container.find("[data-matriz-action='next']").hide();
1607                $finishButton = $container.find("[data-matriz-action='finish']").hide();
1608                $croppingBody = $container;
1609                $orientationOptionGroup = $container.find("input[type='radio']");
1610            }
1611
1612            this.reset = function () {
1613                if (stepController) {
1614                    stepController.reset();
1615                }
1616            };
1617
1618            this.start = function () {
1619                matriz.ui.loading.element.show($croppingBody);
1620                setup.call(this);
1621                $cancelButton.off("click");
1622                $cancelButton.on("click", function () {
1623                    onCancel();
1624                });
1625            };
1626            __construct.call(this);
1627
1628        }
1629
1630    };
1631
1632    matriz.ui.tristatecheckbox = {
1633        check: function ($selector) {
1634            $selector.attr("data-matriz-state", matriz.ui.tristatecheckbox.enumstates.CHECKED);
1635            $selector.prop("indeterminate", false);
1636            $selector.attr("checked", true);
1637        },
1638        checked: function ($selector) {
1639            return $selector.attr("data-matriz-state") === matriz.ui.tristatecheckbox.enumstates.CHECKED;
1640        },
1641        enumstates: {
1642            "UNCHECKED": "0",
1643            "CHECKED": "1",
1644            "INDETERMINATE": "2"
1645        },
1646        destroy: function ($selector) {
1647            $selector.removeAttr("data-matriz-extended-type");
1648            $selector.removeAttr("data-matriz-state");
1649            $selector.each(function (idx, checkbox) {
1650                if ($(checkbox).prop("indeterminate")) {
1651                    $(checkbox).attr("checked", false);
1652                }
1653                $(checkbox).off("change");
1654            });
1655        },
1656        filterstates: function ($selector, states) {
1657            var query = [], len = states.length, i = 0;
1658            for (i = 0; i < len; i++) {
1659                query.push("[data-matriz-state='" + states[i] + "']");
1660            }
1661            return $selector.find(query.join(","));
1662        },
1663        indeterminate: function ($selector) {
1664            $selector.attr("data-matriz-state", matriz.ui.tristatecheckbox.enumstates.INDETERMINATE);
1665            $selector.attr("checked", false);
1666            $selector.prop("indeterminate", true);
1667        },
1668        indeterminated: function ($selector) {
1669            return $selector.attr("data-matriz-state") === matriz.ui.tristatecheckbox.enumstates.INDETERMINATE;
1670        },
1671        nextstate: function ($selector) {
1672            $selector.each(function (idx, checkbox) {
1673                var state = matriz.ui.tristatecheckbox.state($(checkbox));
1674                var states = matriz.ui.tristatecheckbox.states($(checkbox));
1675                var nextstate = states[(states.indexOf(state) + 1) % states.length];
1676                matriz.ui.tristatecheckbox.state($(checkbox), nextstate);
1677            });
1678        },
1679        state: function ($selector, state) {
1680            if (state === undefined) {
1681                return $selector.attr("data-matriz-state");
1682            } else {
1683                switch (state) {
1684                    case matriz.ui.tristatecheckbox.enumstates.UNCHECKED:
1685                        matriz.ui.tristatecheckbox.uncheck($selector);
1686                        break;
1687                    case matriz.ui.tristatecheckbox.enumstates.INDETERMINATE:
1688                        matriz.ui.tristatecheckbox.indeterminate($selector);
1689                        break;
1690                    case matriz.ui.tristatecheckbox.enumstates.CHECKED:
1691                        matriz.ui.tristatecheckbox.check($selector);
1692                        break;
1693                    default:
1694                        throw new Error("Unknown state: " + state);
1695                        break;
1696                }
1697            }
1698        },
1699        states: function ($selector, states) {
1700            if (states === undefined) {
1701                return $selector.data("matriz-states");
1702            } else {
1703                if (states instanceof Array) {
1704                    $selector.data("matriz-states", states);
1705                    $selector.each(function (idx, checkbox) {
1706                        matriz.ui.tristatecheckbox.state($(checkbox), states.first());
1707                    });
1708                } else {
1709                    throw new Error("States must be an array");
1710                }
1711            }
1712        },
1713        uncheck: function ($selector) {
1714            $selector.attr("data-matriz-state", matriz.ui.tristatecheckbox.enumstates.UNCHECKED);
1715            $selector.attr("checked", false);
1716            $selector.prop("indeterminate", false);
1717        },
1718        unchecked: function ($selector) {
1719            return $selector.attr("data-matriz-state") === matriz.ui.tristatecheckbox.enumstates.UNCHECKED;
1720        },
1721        init: function ($selector, states) {
1722            if ($selector instanceof jQuery) {
1723                var defaultstates = [matriz.ui.tristatecheckbox.enumstates.INDETERMINATE, matriz.ui.tristatecheckbox.enumstates.CHECKED, matriz.ui.tristatecheckbox.enumstates.UNCHECKED];
1724                matriz.ui.tristatecheckbox.states($selector, (states === undefined ? defaultstates : states));
1725                $selector.each(function (idx, checkbox) {
1726                    if ($(checkbox).prop("checked")) {
1727                        matriz.ui.tristatecheckbox.state($(checkbox), matriz.ui.tristatecheckbox.enumstates.CHECKED);
1728                    } else {
1729                        var firststate = matriz.ui.tristatecheckbox.states($(checkbox)).first()
1730                        matriz.ui.tristatecheckbox.state($(checkbox), firststate);
1731                    }
1732                    $(checkbox).on("change", function (e) {
1733                        e.preventDefault();
1734                        matriz.ui.tristatecheckbox.nextstate($(this));
1735                    });
1736                });
1737            } else {
1738                throw new Error("$selector is not a jQuery instance");
1739            }
1740        }
1741    };
1742
1743    matriz.ui.scrollTo = function (selector) {
1744        $("html, body").animate({
1745            scrollTop: $(selector).offset().top
1746        }, 400);
1747    };
1748
1749    matriz.ui.components = [];
1750
1751    matriz.ui.component = {
1752        "Factory": {
1753            create: function (container) {
1754                var component = $(container).attr("data-matriz-component");
1755                if (typeof matriz.ui.components[component] === "function") {
1756                    return new matriz.ui.components[component]();
1757                }
1758                throw new Error("Componente sem javascript: " + component);
1759            }
1760        },
1761        "Manager": {
1762            init: function () {
1763                $("[data-matriz-component]").each(function () {
1764                    try {
1765                        if ($(this).prop("data-matriz-loaded") !== true) {
1766                            $(this).prop("data-matriz-loaded", true);
1767
1768                            matriz.ui.component.Factory.create(this).init({
1769                                "container": this
1770                            });
1771                        }
1772                    } catch (e) {
1773                        console.warn(e.message);
1774                    }
1775                });
1776            }
1777        }
1778    };
1779
1780    matriz.ui.FileInput = function (options) {
1781        matriz.common.Event.call(this);
1782
1783        this.options = {
1784            url: null,
1785            button: null,
1786            multiple: false,
1787            maxsize: 0,
1788            extensions: ""
1789        };
1790
1791        this.files = [];
1792        this.filesResponse = [];
1793
1794        $.extend(this.options, options);
1795
1796        this.init = function () {
1797            var fileInput = new mOxie.FileInput({
1798                browse_button: this.options.button,
1799                multiple: this.options.multiple,
1800                accept: [{
1801                        title: "Selecione o arquivo para envio...",
1802                        extensions: this.options.extensions
1803                    }]
1804            });
1805
1806            fileInput.onchange = (function (e) {
1807                this.trigger("change");
1808
1809                this.files = [];
1810                this.filesResponse = [];
1811
1812                for (var key in e.target.files) {
1813                    var file = e.target.files[key];
1814                    var extension = ((file.name).split(".").pop()).toLowerCase();
1815
1816                    this.trigger("added", [file]);
1817
1818                    if (!this.options.maxsize || this.options.maxsize < file.size) {
1819                        if (!this.options.extensions || this.options.extensions.indexOf(extension)
1819 > -1) {
1820                            this.files.push(file);
1821                        } else {
1822                            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") + ".")]);
1823                        }
1824                    } else {
1825                        this.trigger("error", [file, new Error(matriz.utils.internationalization.translate("Tamanho do arquivo maior que", "matriz.ui") + " " + matriz.utils.file.toTamanhoExtenso(this.options.maxsize) + ".")]);
1826                    }
1827                }
1828
1829                var promises = this.files.map((function (file) {
1830                    return this.sendFile(file, this.options.url)
1831                            .done((function (response) {
1832                                this.filesResponse.push(response);
1833                                this.trigger("success", [file, response]);
1834                            }).bind(this))
1835                            .fail((function (error) {
1836                                this.trigger("error", [file, error]);
1837                            }).bind(this));
1838                }).bind(this));
1839
1840                $.when.apply(this, promises).always((function () {
1841                    this.trigger("complete", [this.files, this.filesResponse]);
1842                }).bind(this));
1843            }).bind(this);
1844
1845            fileInput.init();
1846        };
1847
1848        this.getFormData = function (data) {
1849            var formData = new mOxie.FormData();
1850            for (var key in data) {
1851                formData.append(key, data[key]);
1852            }
1853            return formData;
1854        };
1855
1856        this.sendFile = function (file, url) {
1857            var deferred = $.Deferred();
1858
1859            var xhr = new mOxie.XMLHttpRequest();
1860
1861            xhr.upload.onprogress = (function (e) {
1862                var progress = Math.round(e.loaded / e.total * 100) + "%";
1863                this.trigger("progress", [file, progress]);
1864            }).bind(this);
1865
1866            xhr.onload = (function (e) {
1867                var status = parseInt(xhr.status);
1868                if (status >= 200 && status < 300) {
1869                    deferred.resolve($.parseJSON(xhr.response));
1870                } else {
1871                    deferred.reject(new Error(xhr.response));
1872                }
1873            }).bind(this);
1874
1875            xhr.open("post", url);
1876            xhr.send(this.getFormData({"attachment": file}));
1877
1878            return deferred.promise();
1879        };
1880
1881        return this;
1882    };
1883});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.