UNPKG

md-crud

Version:

Angular material directive to create customizable CRUD forms.

8 lines 34.3 kB
/** * md-crud - Angular material directive to create customizable CRUD forms. * @version v1.0.0 * @link https://github.com/ClassHP/md-crud * @license MIT */ angular.module("mdCrudTemplates",[]).run(["$templateCache",function(e){e.put("/views/crud.html",'<div class="md-default" layout="row" layout-align="start center"><md-button class="md-raised md-primary" ng-click="table.create($event)" ng-if="!options.noCreate" ng-disabled="isLoading">{{translate(text.createOption)}}</md-button><div ng-if="options.templateTools" ng-include="options.templateTools" flex layout="row"></div><div flex></div><div layout="row" ng-if="!options.noSearch" style="margin-bottom:5px"><md-button class="md-icon-button md-primary" ng-disabled="true"><md-icon>&#xE8B6;</md-icon></md-button><md-autocomplete md-search-text="searchText" type="search" placeholder="" md-items="item in []" md-search-text-change="onSearchTextChange(searchText)" md-delay="searchDelay"></md-autocomplete></div></div><div ng-if="formType == \'inline\' && rowCreate"><md-card flex layout-fill style="background-color: white"><md-crud-form options="options" ng-model="rowCreate" on-open="onOpen" on-edit="onEdit" on-detail="onDetail" on-cancel="onCancel" on-sussces="onSussces" on-submit="onSubmit" template-url="templateUrl" editable="true"></md-crud-form></md-card><br></div><md-table-container md-whiteframe="1"><table data-md-table md-progress="table.promise"><thead md-head data-md-order="table.order" md-on-reorder="table.refresh" style="background-color: white"><tr md-row><th md-column ng-repeat="field in fields" ng-if="!field.columnHiden && !field.columnHidden">{{translate(field.columnHeader || field.label)}}</th><th md-column style="min-width:132px;width:132px" ng-if="!options.noDelete && !options.noEdit"></th><th md-column style="min-width:60px;width:60px" ng-if="(options.noEdit && !options.noDelete) || (!options.noEdit && options.noDelete)"></th></tr></thead><tbody md-body><tr md-row md-select="row" ng-repeat-start="row in (options.serverSide ? table.rows : (table.rows | filter:searchText | limitTo: table.limit: (table.page - 1) * table.limit))" ng-mouseover="row.mouserover=true" ng-mouseleave="row.mouserover=false" ng-class="{ \'md-selected\': row.mouserover || rowSelected == row }" ng-click="table.detail(row, $event)" style="cursor:pointer"><td md-cell ng-repeat="field in fields" ng-if="!field.columnHiden && !field.columnHidden" ng-style="field.styleCell" md-crud-template="getTemplateColumn(field, row)"></td><td md-cell ng-if="!options.noDelete || !options.noEdit"><md-button class="md-icon-button md-accent" ng-show="row.mouserover || rowSelected == row " ng-click="table.edit(row, $event)" ng-if="!options.noEdit"><md-icon>&#xE3C9;</md-icon></md-button><md-button class="md-icon-button md-warn" ng-show="row.mouserover || rowSelected == row " ng-click="table.delete(row[options.id], $event)" ng-if="!options.noDelete"><md-icon>&#xE92B;</md-icon></md-button></td></tr><tr ng-repeat-end ng-if="rowSelected == row"><td colspan="{{countFieldsColums()}}" style="max-width: 0"><md-card layout-fill style="background-color: white"><md-crud-form ng-if="formEditable" options="options" ng-model="row" on-open="onOpen" on-edit="onEdit" on-detail="onDetail" on-cancel="onCancel" on-sussces="onSussces" on-submit="onSubmit" template-url="templateUrl" editable="formEditable" model-copy="true"></md-crud-form><md-crud-form ng-if="!formEditable" options="options" ng-model="row" on-open="onOpen" on-edit="onEdit" on-detail="onDetail" on-cancel="onCancel" on-sussces="onSussces" on-submit="onSubmit" template-url="templateUrl" editable="formEditable" model-copy="true"></md-crud-form></md-card></td></tr></tbody></table><md-table-pagination ng-if="!options.noPaginate" md-limit="table.limit" md-limit-options="table.limitOptions" md-page="table.page" md-total="{{options.serverSide ? table.total : (table.rows | filter:searchText).length}}" md-page-select md-label="{{table.labels()}}" style="background-color: white" md-on-paginate="table.onPaginate"></md-table-pagination></md-table-container>'),e.put("/views/crudForm.html",'<div layout-padding><form name="formCrud" ng-submit="isFormValid(formCrud) && save()" novalidate><md-crud-form-base flex layout="row" layout-wrap options="options" ng-model="item" form-type="formType" editable="editable" form-crud="formCrud" is-loading="isLoading"></md-crud-form-base><div ng-repeat="message in errors" md-colors="{ color: \'default-warn\' }" flex="grow">{{translate(message)}}</div><div layout="row" layout-align="center center" flex="grow" ng-if="!(formType==\'detail\' && options.noDetailButtons) && !options.noButtons"><md-button class="md-raised" ng-click="cancel()" ng-disabled="isLoading">{{translate(options.formCancelText || text.formCancel)}}</md-button><div flex="5"></div><md-button class="md-raised md-primary" type="submit" ng-disabled="ef(options.readonly, item) || readonly || isLoading">{{translate(options.formSubmitText || text.formSubmit)}}</md-button></div></form></div>'),e.put("/views/crudFormBase.html",'<div ng-repeat="field in fields" flex="{{field.flex || \'grow\'}}" flex-xs="100" ng-style="field.style" ng-if="(formType==\'create\' && !ef(field.createHiden || field.createHidden, item)) || (formType==\'edit\' && !ef(field.editHiden || field.editHidden, item)) || (formType==\'detail\' && !ef(field.detailHiden || field.detailHidden, item))"><div ng-switch="ef(field.type, item)" ng-if="!field.templateUrl && !field.template"><md-input-container class="md-block" flex ng-switch-default ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label>{{translate(field.label)}}</label><input ng-model="item[field.name]" name="{{field.name}}" ng-required="field.required" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-minlength="field.minlength" ng-maxlength="field.maxlength" ng-blur="field.onChange && field.onChange(item, formType)" ng-pattern="field.pattern" md-crud-input-validator="field.errorMessage" item="item"><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><md-input-container class="md-block" flex ng-switch-when="textarea" ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label>{{translate(field.label)}}</label><textarea ng-model="item[field.name]" name="{{field.name}}" ng-required="field.required" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-minlength="field.minlength" ng-maxlength="field.maxlength" rows="{{ field.rows || 3 }}" md-select-on-focus ng-blur="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item"></textarea><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><md-input-container class="md-block" flex ng-switch-when="email" ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label>{{translate(field.label)}}</label><input ng-model="item[field.name]" name="{{field.name}}" ng-required="field.required" type="email" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-minlength="field.minlength" ng-maxlength="field.maxlength" ng-pattern="field.pattern" ng-blur="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item"><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><md-input-container class="md-block" flexemail flex ng-switch-when="integer" ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label>{{translate(field.label)}}</label><input type="number" ng-model="item[field.name]" name="{{field.name}}" ng-required="field.required" md-crud-input-number ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-min="field.min" ng-max="field.max" step="{{field.step || 1}}" ng-blur="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item"><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><md-input-container class="md-block" flex ng-switch-when="decimal" ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label>{{translate(field.label)}}</label><input type="number" ng-model="item[field.name]" name="{{field.name}}" ng-required="field.required" md-crud-input-number ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-min="field.min" ng-max="field.max" step="{{field.step || \'any\'}}" ng-blur="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item"><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><div class="md-block" flex ng-switch-when="image"><lf-ng-md-file-input name="{{field.name}}" lf-files="files[field.name]" lf-mimetype="image/*" lf-placeholder="{{field.label}}" lf-browse-label="Abrir" lf-remove-label="Eliminar"></lf-ng-md-file-input><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div><br></div><div class="md-block" flex ng-switch-when="map"><ng-map zoom="{{field.zoom || 11}}" center="{{item[field.lat]}},{{item[field.lng]}}"><marker position="{{item[field.lat]}},{{item[field.lng]}}" title="drag me" draggable="true" on-dragend="onMarkerDrag()" data="{{field}}"></marker></ng-map></div><div class="md-block" flex ng-switch-when="boolean"><md-switch ng-model="item[field.name]" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" aria-label="field.label" ng-true-value="{{\'\\\'\'+ field.trueValue + \'\\\'\'}}" ng-if="field.trueValue" ng-change="field.onChange && field.onChange(item, formType)">{{translate(((item[field.name] == field.trueValue) ? field.trueLabel : field.falseLabel) || field.label)}}</md-switch><md-switch ng-model="item[field.name]" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" aria-label="field.label" ng-if="!field.trueValue" ng-change="field.onChange && field.onChange(item, formType)">{{translate((item[field.name] ? field.trueLabel : field.falseLabel) || field.label)}}</md-switch></div><md-input-container class="md-block" flex ng-switch-when="select" ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label>{{translate(field.label)}}</label><md-select ng-model="item[field.name]" ng-if="field.multiple" name="{{field.name}}" multiple="multiple" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-required="field.required" ng-change="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item" md-on-open="field.onOpen(item)"><md-option ng-value="option[field.value || \'value\']" ng-repeat="option in ef(field.data, item)"><md-text md-crud-template="templateSelect(field)"></md-text></md-option></md-select><md-select ng-model="item[field.name]" ng-if="!field.multiple" name="{{field.name}}" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-required="field.required" ng-change="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item" md-on-open="field.onOpen(item)"><md-option ng-if="!field.required"></md-option><md-option ng-value="option[field.value || \'value\']" ng-repeat="option in ef(field.data, item)" md-crud-template="templateSelect(field)"></md-option></md-select><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><md-input-container class="md-block" flex ng-switch-when="date" ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label>{{translate(field.label)}}</label><md-datepicker ng-model="item[field.name]" name="{{field.name}}" md-min-date="ef(field.minDate, item)" md-max-date="ef(field.maxDate, item)" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-required="field.required" md-crud-input-date aria-label="{{translate(field.label)}}" ng-change="field.onChange && field.onChange(item, formType)"></md-datepicker><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><md-input-container class="md-block" ng-switch-when="time" flex ng-class="{ \'hide-error-msg\': field.hideErrorMsg }"><label style="margin-left: 50px">{{translate(field.label)}}</label><div class="" layout="row" layout-align="start start"><md-button layout-nowrap ng-click="showTimePicker($event, item, field.name)" class="md-datepicker-button md-icon-button md-button md-ink-ripple" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading"><md-icon>access_time</md-icon></md-button><div flex><input class="md-datepicker-input md-input" type="time" name="{{field.name}}" ng-model="item[field.name]" md-crud-input-date aria-label="{{translate(field.label)}}" ng-required="field.required" flex ng-min="ef(field.min, item)" ng-max="ef(field.max, item)" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-blur="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item"><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></div></div></md-input-container><div class="md-block" ng-switch-when="datetime" flex layout="row" layout-align="start start"><md-input-container flex="none"><label style="overflow: visible;\r\n -webkit-transform: translate3d(0, 6px, 0) scale(0.75);\r\n transform: translate3d(0, 6px, 0) scale(0.75);\r\n -webkit-transition: width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s;\r\n transition: width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s;\r\n transition: transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s;\r\n transition: transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, width cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s, -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.4s">{{translate(field.label)}}</label><md-datepicker layout-nowrap ng-model="item[field.name]" name="{{field.name}}" md-min-date="ef(field.minDate, item)" md-max-date="ef(field.maxDate, item)" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-required="field.required" md-crud-input-date aria-label="{{translate(field.label)}}" ng-change="field.onChange && field.onChange(item, formType)"></md-datepicker><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></md-input-container><md-input-container><div class="" layout="row" layout-align="start start"><md-button layout-nowrap ng-click="showTimePicker($event, item, field.name)" class="md-datepicker-button md-icon-button md-button md-ink-ripple" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading"><md-icon>access_time</md-icon></md-button><div flex><input class="md-datepicker-input md-input" type="time" name="{{field.name}}" ng-model="item[field.name]" md-crud-input-date aria-label="{{translate(field.label)}}" ng-required="field.required" flex ng-min="field.min" ng-max="field.max" ng-disabled="ef(field.readonly, item) || ef(options.readonly, item) || readonly || isLoading" ng-blur="field.onChange && field.onChange(item, formType)" md-crud-input-validator="field.errorMessage" item="item"><div ng-messages="formCrud[field.name].$error" ng-messages-multiple><div ng-messages-include="/views/crudFormMessages.html"></div></div></div></div></md-input-container></div><div class="md-block" ng-switch-when="button" flex layout-align="{{field.align}}"><md-button ng-class="field.class" ng-click="field.onClick(item)"><md-icon ng-if="field.icon">{{field.icon}}</md-icon><md-tooltip md-autohide ng-if="field.tooltip">{{translate(field.tooltip)}}</md-tooltip>{{translate(field.label)}}</md-button></div><div class="md-block" flex ng-switch-when="label"><span>{{translate(field.label)}}</span></div></div><div ng-if="field.templateUrl" ng-include="field.templateUrl"></div><div ng-if="field.template" md-crud-template="ef(field.template, item)"></div></div>'),e.put("/views/crudFormDialog.html",'<md-dialog aria-label="Editar" flex="{{options.windowFlex}}"><md-toolbar><div class="md-toolbar-tools"><h2>{{ formTitle }}</h2><span flex></span><md-button class="md-icon-button" ng-click="cancelDialog()"><md-icon aria-label="Cerrar">close</md-icon></md-button></div></md-toolbar><md-dialog-content><md-crud-form options="options" ng-model="item" on-open="onOpen" on-edit="onEdit" on-detail="onDetail" on-cancel="onCancelDialog" on-sussces="onSusscesDialog" template-url="templateUrl" editable="formEditable" model-copy="true"></md-crud-form></md-dialog-content></md-dialog>'),e.put("/views/crudFormMessages.html",'<div ng-message="required">{{translate(field.messageRequired || text.messageRequired)}}</div><div ng-message="minlength">{{translate(field.messageMinlength || text.messageMinlength)}} ({{field.minlength}}).</div><div ng-message="maxlength">{{translate(field.messageMaxlength || text.messageMaxlength)}} ({{field.maxlength}}).</div><div ng-message="pattern">{{translate(field.messagePattern || text.messagePattern)}}</div><div ng-message="min">{{translate(field.messageMin || text.messageMin)}} ({{field.min}}).</div><div ng-message="max">{{translate(field.messageMax || text.messageMax)}} ({{field.max}}).</div><div ng-message="mimetype">{{translate(field.messageMimetype || text.messageMimetype)}}</div><div ng-message="valid">{{translate(field.messageValid || text.messageValid)}}</div><div ng-message="mindate">{{translate(field.messageMindate || text.messageMindate)}} {{field.minDate | date:\'shortDate\'}}.</div><div ng-message="maxdate">{{translate(field.messageMaxdate || text.messageMaxdate)}} {{field.maxDate | date:\'shortDate\'}}.</div><div ng-message="mdCrudInputValidator">{{translate(ef(field.errorMessage, item[field.name], item))}}</div>')}]),function(){"use strict";angular.module("mdCrudModule",["mdCrudTemplates"])}(),function(){"use strict";function e(e,t,i,n,a){function l(l,o,r){var d=e.text;l.text=d;var m=e.options.translate;l.translate=m;var s=l.options;s.id=s.id||"id",l.formType=t.evalDefined([r.formType,s.formType,e.options.formType]);var u=t.evalDefined([r.deleteConfirm,s.deleteConfirm,e.options.deleteConfirm]),f=t.evalDefined([r.autoRefresh,s.autoRefresh,e.options.autoRefresh]),c=t.evalDefined([r.getParams,s.getParams,{}]);l.searchText=r.searchText||s.searchText||"",l.searchDelay=r.searchDelay||s.searchDelay||(s.serverSide?500:0),l.fields=s.fields,l.rowSelected=null,l.rowCreate=null;var g=l.ef=t.evalFunction;l.stringToHtml=function(e,t){return a.trustAsHtml(n(e)(t))},s.offline||(l.isLoading=!0),l.getTemplateColumn=function(t,i){var n=t.templateColumn||t.columnTemplate||e.templateColumns[g(t.type,i)||"default"]||e.templateColumns.default;return n.replace("row[field.name]","row."+t.name)},l.getTemplateSelect=function(e){return e.templateSelect?e.templateSelect.replace("option","getOptionSelect(field, row)"):"{{translate(getOptionSelect(field, row)."+(e.text||"text")+")}}"},l.getOptionSelect=function(e,i){var n=t.evalFunction(e.data,i);for(var a in n)if(n[a][e.value||"value"]==i[e.name])return n[a];return i},l.onSearchTextChange=function(e){l.searchText=e,s.serverSide&&p.searchParam&&(l.table.page=1,s.refresh())};var p=angular.copy(e.options.serverSide||{});s.serverSide&&"boolean"!=typeof s.serverSide&&angular.extend(p,s.serverSide),l.countFieldsColums=function(){var e=0;for(var t in s.fields){var i=s.fields[t];i.columnHiden||i.columnHidden||e++}return e+2};var v=function(t){t.data||e.get({entity:t.entity}).then(function(e){t.data=e.data})};for(var b in s.fields){var h=s.fields[b];h.entity&&v(h)}l.table={rows:l.rows||[],refresh:function(t){l.isLoading=!0,angular.extend(c,t);var i=angular.copy(s.http||{});i.entity=s.entity,i.params=angular.copy(i.params||{}),angular.extend(i.params,c),s.serverSide&&(i.params[p.pageParam]=l.table.page,i.params[p.offsetParam]=(l.table.page-1)*l.table.limit,i.params[p.limitParam]=l.table.limit,i.params[p.searchParam]=""!=l.searchText?l.searchText:void 0),l.table.promise=e.get(i).then(function(e){l.isLoading=!1,s.serverSide?(l.table.rows=e.data[p.dataResponse],l.table.total=e.data[p.totalResponse]):l.table.rows=e.data})},create:function(e){e&&e.stopPropagation(),l.rowSelected=null,l.rowCreate={},"window"==l.formType&&w({},!0,e).then(function(e){})},edit:function(e,t){t.stopPropagation(),e[s.id]&&("inline"==l.formType&&(l.rowCreate=null,l.selectRow(e,!0)),"window"==l.formType&&w(e,!0,t).then(function(e){}))},detail:function(e,t){return s.editOnSelect?void l.table.edit(e,t):(t.stopPropagation(),"inline"==l.formType&&(l.rowCreate=null,l.rowSelected==e?l.rowSelected=null:s.noDetail||l.selectRow(e,!1)),void("window"==l.formType&&w(e,!1,t).then(function(e){})))},delete:function(i,n){l.rowSelected=null,n.stopPropagation();var a,o=this,r=this.rows.findIndex(function(e){return e[s.id]==i});if(s.offline)a=function(){o.rows.splice(r,1)};else{var f=angular.copy(s.http||{});f.entity=s.entity,f.id=i,a=function(){e.delete(f).then(function(e){o.rows.splice(r,1)},function(e){var i=d.deleteError;e&&e.error&&(i=e.error),t.showAlert(m(d.deleteErrorTitle),m(i),m(d.btnAlertOk))})}}u?t.showConfirm(m(d.deleteConfirmTitle),m(d.deleteConfirmMessage),m(d.deleteConfirmOk),m(d.btnConfirmCancel),m(d.btnConfirmCancel)).then(function(){a()}):a()},promise:null,order:"",limit:t.evalDefined([r.tableLimit,s.tableLimit,e.options.tableLimit]),limitOptions:t.evalDefined([r.limitOptions,s.limitOptions,e.options.limitOptions]),page:1,rowSelection:!1,selected:[],labels:function(){return{page:m(d.tablePaginationPage),rowsPerPage:m(d.tablePaginationRowsPerPage),of:m(d.tablePaginationOf)}},onPaginate:function(){s.serverSide&&l.table.refresh()}},s.refresh=function(e){l.table.refresh(e)},s.create=function(){l.table.create()},s.cancel=function(){l.rowSelected=null,l.rowCreate=null,i.cancel()},f&&s.refresh();var w=function(e,t,n){return l.formEditable=t,i.show({controller:["$scope","$mdDialog","mdCrudService","item","options",y],templateUrl:"/views/crudFormDialog.html",clickOutsideToClose:!0,fullscreen:!0,scope:l,preserveScope:!0,controllerAs:"vm",locals:{item:e,options:s},targetEvent:n,parent:o})};l.templateUrl=(s.form||{}).templateUrl,l.onOpen=function(e,t){(s.form||{}).onOpen&&s.form.onOpen(e,t)},l.onEdit=function(e){(s.form||{}).onEdit&&s.form.onEdit(e)},l.onDetail=function(e){(s.form||{}).onDetail&&s.form.onDetail(e)},l.onCancel=function(e){(s.form||{}).onCancel&&s.form.onCancel(e),l.rowSelected=null,l.rowCreate=null,e&&t.showAlert(m(d.generalErrorTitle),m(e),m(d.btnAlertOk))},l.onSussces=function(e,t){(s.form||{}).onSussces&&s.form.onSussces(e,t),"create"!=t||s.noCreateAdd||l.table.rows.unshift(e),l.rowSelected=null,l.rowCreate=null},l.onSubmit=function(e,t){(s.form||{}).onSubmit&&s.form.onSubmit(e,t)},l.selectRow=function(e,t){l.rowSelected=e,l.formEditable=t};var y=function(e,t,i,n,a){e.formTitle=m(n[a.id]?e.formEditable?d.editTitle:d.detailTitle:d.createTitle),e.item=n,e.onCancelDialog=function(i){e.onCancel(i),t.cancel()},e.onSusscesDialog=function(i,n){e.onSussces(i,n),t.hide(i)},e.cancelDialog=function(){e.onCancelDialog()}};l.onLoad&&l.onLoad()}var o={link:l,restrict:"EA",scope:{options:"=",onLoad:"=",rows:"="},templateUrl:"/views/crud.html"};return o}angular.module("mdCrudModule").directive("mdCrud",e),e.$inject=["mdCrudService","mdCrudToolsService","$mdDialog","$interpolate","$sce"]}(),function(){"use strict";function e(e,t,i,n,a,l,o){function r(i,l,r){var m=e.text;i.text=m;var s=e.options.translate;i.translate=s,i.stringToHtml=function(e,t){return a.trustAsHtml(n(e)(t))},i.templateSelect=function(e){var t=e.templateSelect||"<translate>{{option."+(e.text||"text")+"}}</translate>";return t},i.getModel=function(e,i){return i.model?t.evalFunction(i.model,e):e[i.name]};var u=i.options;i.fields=u.fields,i.readonly=0==i.editable,i.ef=t.evalFunction,i.isLoading=!1,i.item=i.modelCopy?angular.copy(i.ngModel||{}):i.ngModel;var f=i.item[u.id];if(i.formTitle=f?i.editable?m.editTitle:m.detailTitle:m.createTitle,i.formType=f?i.editable?"edit":"detail":"create",i.getContentUrl=function(e,t){return i.templateUrl||"/views/crudForm.html"},i.showTimePicker=function(e,t,i){d&&d(t[i],{targetEvent:e}).then(function(e){t[i]=e})},i.onOpen&&i.onOpen(i.item,i.formType),f&&!u.offline){i.isLoading=!0;var c=angular.copy(u.http||{});c.entity=u.entity,c.id=f,e.getById(c).then(function(e){angular.extend(i.item,e.data),"edit"==i.formType&&i.onEdit&&i.onEdit(i.item),"detail"==i.formType&&i.onDetail&&i.onDetail(i.item),i.isLoading=!1},function(e){i.onError&&i.onError(e),i.cancel(e)})}i.save=function(){if(i.onSubmit&&i.onSubmit(i.item,i.formType),u.offline)angular.extend(i.ngModel,i.item),i.onSussces&&i.onSussces(i.item,i.formType);else{var t,n=angular.copy(u.http||{});n.entity=u.entity,n.data=i.item,f?(n.id=i.ngModel[u.id],t=e.patch(n)):t=e.post(n),i.isLoading=!0,t.then(function(e){angular.extend(i.ngModel,e.data),i.onSussces&&i.onSussces(e.data,i.formType),i.isLoading=!1},function(e){e.details?i.errors=e.details:i.errors=[e.error],i.onError&&i.onError(e),i.isLoading=!1})}},i.cancel=function(e){i.onCancel&&i.onCancel(e)},i.onMarkerDrag=function(e){i.item[this.data.lat]=e.latLng.lat(),i.item[this.data.lng]=e.latLng.lng()},i.isFormValid=function(e){return!!e.$valid||(o[0].querySelector("form .ng-invalid").focus(),!1)}}var d;try{d=i.get("$mdpTimePicker")}catch(e){}var m={link:r,restrict:"EA",scope:{options:"=",ngModel:"=",onOpen:"=",onEdit:"=",onDetail:"=",onCancel:"=",onSussces:"=",onSubmit:"=",templateUrl:"<?",editable:"<?",modelCopy:"<?"},template:'<div ng-include="getContentUrl()"></div>'};return m}angular.module("mdCrudModule").directive("mdCrudForm",e),e.$inject=["mdCrudService","mdCrudToolsService","$injector","$interpolate","$sce","$compile","$document"]}(),function(){"use strict";function e(e,t,i,n,a,l,o){function r(i,l,o){var r=e.text;i.text=r,i.formType=i.formType||"detail";var m=e.options.translate;i.translate=m,i.stringToHtml=function(e,t){return a.trustAsHtml(n(e)(t))},i.templateSelect=function(e){var t=e.templateSelect||"<translate>{{option."+(e.text||"text")+"}}</translate>";return t};var s=i.options;i.fields=s.fields,i.readonly=0==i.editable;var u=function(t){t.data||e.get({entity:t.entity}).then(function(e){t.data=e.data})};for(var f in s.fields){var c=s.fields[f];c.entity&&u(c)}i.ef=t.evalFunction;i.ngModel[s.id];i.item=i.ngModel,i.showTimePicker=function(e,t,i){d&&d(t[i],{targetEvent:e}).then(function(e){t[i]=e})},i.onMarkerDrag=function(e){i.item[this.data.lat]=e.latLng.lat(),i.item[this.data.lng]=e.latLng.lng()}}var d;try{d=i.get("$mdpTimePicker")}catch(e){}var m={link:r,restrict:"EA",scope:{options:"=",ngModel:"=",formType:"=",formCrud:"=",editable:"<?",isLoading:"="},templateUrl:"/views/crudFormBase.html"};return m}angular.module("mdCrudModule").directive("mdCrudFormBase",e),e.$inject=["mdCrudService","mdCrudToolsService","$injector","$interpolate","$sce","$compile","$document"]}(),function(){"use strict";angular.module("mdCrudModule").directive("mdCrudInputNumber",function(){return{require:"ngModel",link:function(e,t,i,n){n.$parsers.push(function(e){return"number"!=typeof e?parseFloat(e):e}),n.$formatters.push(function(e){return"number"!=typeof e?parseFloat(e):e})}}}).directive("mdCrudInputBoolean",function(){return{require:"ngModel",link:function(e,t,i,n){n.$parsers.push(function(e){return"boolean"!=typeof e?"true"==e:e}),n.$formatters.push(function(e){return"boolean"!=typeof e?"true"==e:e})}}}).directive("mdCrudInputDate",function(){return{require:"ngModel",link:function(e,t,i,n){n.$parsers.push(function(e){return e instanceof Date?e:new Date(e)}),n.$formatters.push(function(e){return e instanceof Date?e:new Date(e)})}}}).directive("mdCrudInputValidator",function(){return{require:"ngModel",scope:{validator:"=mdCrudInputValidator",item:"=item"},link:function(e,t,i,n){n.$validators.mdCrudInputValidator=function(t){return angular.isFunction(e.validator)?!angular.isDefined(e.validator(t,e.item)):!angular.isDefined(e.validator)}}}})}(),function(){"use strict";function e(e){return function(t,i,n){t.$watch(function(e){return e.$eval(n.mdCrudTemplate)},function(n){i.html(n),e(i.contents())(t)})}}angular.module("mdCrudModule").directive("mdCrudTemplate",e),e.$inject=["$compile"]}(),function(){"use strict";function e(e,t,i,n){var a={rootApi:"/api",methodGet:"GET",methodPost:"POST",methodPatch:"PATCH",methodDelete:"DELETE",urlGet:"{{rootApi}}/{{entity}}",urlGetById:"{{rootApi}}/{{entity}}/{{id}}",urlPost:"{{rootApi}}/{{entity}}",urlPatch:"{{rootApi}}/{{entity}}/{{id}}",urlDelete:"{{rootApi}}/{{entity}}/{{id}}",functionHttp:function(n,l){return n.functionHttp?n.functionHttp(n):e(function(e,o){i({url:t(n.url)(n),method:n.method,params:n.params,data:n.data}).then(function(t){(n.functionData||a.functionData)(t,e,o,l)},function(e){o(e.data)})})},functionData:function(e,t,i,n){t(e)},formType:"inline",deleteConfirm:!0,tableLimit:10,limitOptions:[10,20,30],translate:function(e){return e},autoRefresh:!0,serverSide:{pageParam:"page",offsetParam:"offset",limitParam:"limit",searchParam:"search",dataResponse:"data",totalResponse:"total"}},l={editTitle:"Edit",detailTitle:"Detail",createTitle:"Create",deleteError:"Error while trying to delete row",deleteErrorTitle:"Error deleting",deleteConfirmTitle:"Delete",deleteConfirmMessage:"Are you sure you want to delete the row?",tablePaginationPage:"Page",tablePaginationRowsPerPage:"Rows per page:",tablePaginationOf:"of",createOption:"Create",btnConfirmOk:"Yes",btnConfirmCancel:"No",btnAlertOk:"Ok",generalErrorTitle:"Error",messageRequired:"Required",messageMinlength:"Min length",messageMaxlength:"Max length",messagePattern:"Invalid input format.",messageMin:"Min value",messageMax:"Max value",messageMimetype:"Invalid file type.",messageValid:"Invalid input format.",messageMindate:"Min date",messageMaxdate:"Max date",formCancel:"Cancel",formSubmit:"Save"},o={boolean:'<span><md-switch ng-model="row[field.name]" ng-disabled="true" aria-label="{{translate(field.label)}}" ng-true-value="{{\'\\\'\'+ field.trueValue + \'\\\'\'}}" ng-if="field.trueValue">{{translate(((row[field.name] == field.trueValue)? field.trueLabel : field.falseLabel) || "")}}</md-switch></span><span><md-switch ng-model="row[field.name]" ng-disabled="true" aria-label="{{translate(field.label)}}" ng-if="!field.trueValue">{{translate((row[field.name] ? field.trueLabel : field.falseLabel) || "")}}</md-switch></span>',image:'<image ng-src="{{row[field.name]}}" style="max-height:90px"></image>',date:'<span>{{ row[field.name] | date:"shortDate" }}</span>',time:'<span>{{ row[field.name] | date:"shortTime" }}</span>',datetime:'<span>{{ row[field.name] | date:"short" }}</span>',select:'<span md-crud-template="getTemplateSelect(field, row)"></span>',text:"<span>{{translate(row[field.name])}}</span>",button:'<md-button ng-class="field.class" ng-click="field.onClick(row, $event) || $event.stopPropagation()"><md-icon ng-if="field.icon">{{field.icon}}</md-icon><md-tooltip md-autohide ng-if="field.tooltip">{{translate(field.tooltip)}}</md-tooltip>{{translate(field.label)}}</md-button>',default:"<span>{{translate(row[field.name])}}</span>"};return{templateColumns:o, options:a,setDefaultTemplateColumns:function(e){angular.extend(o,n.removeNull(e))},setDefaultOptions:function(e){angular.extend(a,n.removeNull(e))},text:l,setDefaultText:function(e){angular.extend(l,n.removeNull(e))},get:function(e){var t={url:e.urlGet||a.urlGet,method:e.methodGet||a.methodGet,rootApi:a.rootApi};return angular.extend(t,n.removeNull(e)),a.functionHttp(t,"get")},getById:function(e){var t={url:e.urlGetById||a.urlGetById,method:e.methodGet||a.methodGet,rootApi:a.rootApi};return angular.extend(t,n.removeNull(e)),a.functionHttp(t,"getById")},post:function(e){var t={url:e.urlPost||a.urlPost,method:e.methodPost||a.methodPost,rootApi:a.rootApi};return angular.extend(t,n.removeNull(e)),a.functionHttp(t,"post")},patch:function(e){var t={url:e.urlPatch||a.urlPatch,method:e.methodPatch||a.methodPatch,rootApi:a.rootApi};return angular.extend(t,n.removeNull(e)),a.functionHttp(t,"patch")},delete:function(e){var t={url:e.urlDelete||a.urlDelete,method:e.methodDelete||a.methodDelete,rootApi:a.rootApi};return angular.extend(t,n.removeNull(e)),a.functionHttp(t,"delete")}}}angular.module("mdCrudModule").service("mdCrudService",["$q","$interpolate","$http","mdCrudToolsService",e])}(),function(){"use strict";function e(e){return{showConfirm:function(t,i,n,a){n=n||"Yes",a=a||"No";var l=e.confirm().title(t).ariaLabel(t).textContent(i).ok(n).cancel(a);return e.show(l)},showAlert:function(t,i,n){n=n||"Ok",e.show(e.alert().clickOutsideToClose(!0).title(t).ariaLabel(t).textContent(i).ok(n))},getBase64:function(e){return $q(function(t,i){var n=new FileReader;n.readAsDataURL(e),n.onload=function(){t(n.result)},n.onerror=function(e){i(e)}})},removeNullRecursive:function(e){var t=function(e,i){var n=i[e];if(null===n||void 0===n)delete i[e];else if("object"==typeof n)for(var a in n)t(a,n)};for(var i in e)t(i,e);return e},removeNull:function(e){for(var t in e){var i=e[t];null!==i&&void 0!==i||delete e[t]}return e},evalFunction:function(e,t,i,n,a,l){return angular.isFunction(e)?e(t,i,n,a,l):e},evalDefined:function(e){for(var t in e)if(angular.isDefined(e[t]))return e[t]}}}angular.module("mdCrudModule").service("mdCrudToolsService",["$mdDialog",e])}();