cronapp-framework-js 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/js/directives.js CHANGED
@@ -2484,7 +2484,8 @@
2484
2484
  };
2485
2485
 
2486
2486
  var column = this.getColumnByField(options, opt.field);
2487
- if (column.visibleCrud != undefined && !column.visibleCrud) {
2487
+ var visibleCrud = (column.visibleCrud == undefined || column.visibleCrud);
2488
+ if (!visibleCrud && !column.visible) {
2488
2489
  container.parent().find('.k-edit-label [for='+ column.field +']').parent().remove();
2489
2490
  container.remove();
2490
2491
  }
@@ -2495,8 +2496,13 @@
2495
2496
  var $input = $(`<input ${required} name="${opt.field}" id="${buttonId}" from-grid=true ng-model="${ngModel}" />`); //
2496
2497
  $input.data('change-grid-model', changeGridModel);
2497
2498
  $input.data('column-type', column.type);
2498
-
2499
- if (column.inputType == 'dynamicComboBox' || column.inputType == 'comboBox') {
2499
+
2500
+ if (!visibleCrud) {
2501
+ var valueModel = scope.$eval(`${ngModel}`);
2502
+ if (valueModel) {
2503
+ container.text(valueModel);
2504
+ }
2505
+ } else if (column.inputType == 'dynamicComboBox' || column.inputType == 'comboBox') {
2500
2506
  var kendoConfig = app.kendoHelper.getConfigComboboxSync(column.comboboxOptions, scope);
2501
2507
  kendoConfig.autoBind = true;
2502
2508
  kendoConfig.optionLabel = undefined;
@@ -2575,11 +2581,12 @@
2575
2581
  }, 200);
2576
2582
  }
2577
2583
 
2578
- function getCommandForEditButtonDatabase(opt, command) {
2584
+ function getCommandForEditButtonDatabase(opt, command, iconClass) {
2579
2585
  var cmd;
2580
2586
  let idForCommand = app.common.generateId();
2581
2587
  let ariaLabel = $translate.instant('Edit');
2582
- let template = `<a href class='k-button k-grid-edit k-grid-${idForCommand}' aria-label='${ariaLabel}'><span class='k-icon k-i-edit'></span></a>`;
2588
+ let iconEditClass = iconClass ? iconClass : "k-icon k-i-edit";
2589
+ let template = `<a href class='k-button k-grid-edit k-grid-${idForCommand}' aria-label='${ariaLabel}'><span class='${iconEditClass}'></span></a>`;
2583
2590
  if ((opt.editable == 'popupCustom') || (opt.editable == 'datasource')) {
2584
2591
  cmd = {
2585
2592
  name: idForCommand,
@@ -2619,11 +2626,12 @@
2619
2626
  return cmd;
2620
2627
  }
2621
2628
 
2622
- function getCommandForRemoveButtonDatabase(opt, command) {
2629
+ function getCommandForRemoveButtonDatabase(opt, command, iconClass) {
2623
2630
  var cmd;
2624
2631
  let idForCommand = app.common.generateId();
2625
2632
  let ariaLabel = $translate.instant('Remove');
2626
- let template = `<a href class='k-button k-grid-delete k-grid-${idForCommand}' aria-label='${ariaLabel}'><span class='k-icon k-i-close'></span></a>`;
2633
+ let iconDeleteClass = iconClass ? iconClass : "k-icon k-i-close";
2634
+ let template = `<a href class='k-button k-grid-delete k-grid-${idForCommand}' aria-label='${ariaLabel}'><span class='${iconDeleteClass}'></span></a>`;
2627
2635
 
2628
2636
  if ((opt.editable == 'popupCustom') || (opt.editable == 'datasource')) {
2629
2637
  cmd = {
@@ -2818,10 +2826,10 @@
2818
2826
  command.forEach(function(f) {
2819
2827
  var cmd;
2820
2828
  if ( f == "edit") {
2821
- cmd = getCommandForEditButtonDatabase.bind(this)(options, f);
2829
+ cmd = getCommandForEditButtonDatabase.bind(this)(options, f, column.iconEditClass);
2822
2830
  }
2823
2831
  else {
2824
- cmd = getCommandForRemoveButtonDatabase.bind(this)(options, f);
2832
+ cmd = getCommandForRemoveButtonDatabase.bind(this)(options, f, column.iconDeleteClass);
2825
2833
  }
2826
2834
  commands.push(cmd);
2827
2835
  }.bind(this));
@@ -4221,29 +4229,31 @@
4221
4229
  }
4222
4230
 
4223
4231
  options.virtual.valueMapper = async function (options) {
4224
- if (!combobox || combobox.isEvaluating) return;
4225
- combobox.isEvaluating = true;
4226
-
4227
- var _dataSource = _options.dataSource.transport.options.cronappDatasource;
4228
- $log.debug("valueMapper.findObj | " + attrs['id'] + " | " + options.value);
4229
-
4230
- try {
4231
- let currentValue = combobox.value();
4232
-
4233
- let data = await _dataSource.findObj([options.value], false);
4234
- if (Array.isArray(data)) data = data[0];
4235
-
4236
- if (currentValue === combobox.value()) {
4237
- options.success(data);
4238
- }
4239
- } catch (e) {
4240
- options.success(null);
4241
- } finally {
4242
- combobox.isEvaluating = false;
4232
+ await waitRender();
4233
+ $log.debug(`valueMapper | ${attrs['id']} | ${options.value}`);
4234
+
4235
+ if (lastValueMapper && lastValueMapper.completed === false) lastValueMapper.canceled = true;
4236
+ lastValueMapper = options;
4237
+
4238
+ const { optionLabel, dataValueField } = _options.combobox.options;
4239
+ const dataSource = _options.dataSource.transport.options.cronappDatasource;
4240
+
4241
+ if (options.canceled || !options.value || (optionLabel[dataValueField] && options.value === "")) {
4242
+ return options.success(null);
4243
4243
  }
4244
- };
4244
+
4245
+ _options.combobox.isEvaluating = true;
4246
+
4247
+ dataSource.findObj([options.value], false, (data) => {
4248
+ if (options.canceled) return;
4249
+ options.success(Array.isArray(data) ? data[0] : data);
4250
+ $log.debug(`valueMapper.success | ${attrs['id']} | ${data}`);
4251
+ }, () => options.success(null), [dataValueField]);
4252
+
4253
+ options.completed = _options.combobox.isEvaluating = false;
4254
+ };
4245
4255
  }
4246
-
4256
+
4247
4257
  options.messages = {
4248
4258
  noData: attrs.noResultsMessage ? attrs.noResultsMessage : "NO DATA FOUND"
4249
4259
  };
@@ -4270,13 +4280,20 @@
4270
4280
  _compileAngular(scope, combobox.element[0]);
4271
4281
  }
4272
4282
  };
4273
-
4274
4283
 
4275
4284
  options.filtering = attrs.ngFiltering ? function () {
4276
4285
  scope.$eval(attrs.ngFiltering);
4277
4286
  } : undefined;
4278
4287
 
4279
4288
  options.open = function (e) {
4289
+ if (!combobox._originalClose) {
4290
+ combobox._originalClose = combobox.close;
4291
+ }
4292
+ combobox.close = () => {};
4293
+ setTimeout(() => {
4294
+ combobox.close = combobox._originalClose;
4295
+ }, 500);
4296
+
4280
4297
  if (!dataSourceScreen.fetched || (dataSourceScreen.lastLoadedTime !== combobox.dataSource.lastLoadedTime)) {
4281
4298
  combobox.options.firstLazyRead = true;
4282
4299
  combobox.dataSource.read();
@@ -4287,6 +4304,7 @@
4287
4304
  if (!combobox.dataSource.data().some(item => item[combobox.options.dataValueField] === "")) {
4288
4305
  combobox.dataSource.add(emptyOption);
4289
4306
  }
4307
+ forceEmptyLineSelected();
4290
4308
  };
4291
4309
 
4292
4310
  options.select = attrs.ngSelect ? function (e) {
@@ -4339,6 +4357,8 @@
4339
4357
  setTimeout(() => {
4340
4358
  scrolling = false;
4341
4359
  }, 300);
4360
+
4361
+ forceEmptyLineSelected();
4342
4362
  });
4343
4363
 
4344
4364
  combobox.bind("change", function () {
@@ -4490,11 +4510,13 @@
4490
4510
  */
4491
4511
  if (ngModelCtrl) {
4492
4512
  ngModelCtrl.$formatters.push(function (value) {
4493
- if (value === undefined || value === "") {
4513
+ $log.debug("$formatters | " + attrs['id'] + " | " + value);
4514
+ if (value === undefined || (value === "" && select.optionLabelValue === undefined)) {
4494
4515
  value = "";
4495
4516
  modelSetter(scope, value);
4496
4517
  }
4497
- return value;
4518
+ forceChangeModel(value);
4519
+ return value;
4498
4520
  });
4499
4521
 
4500
4522
  ngModelCtrl.$parsers.push(function (value) {
@@ -4538,12 +4560,6 @@
4538
4560
  select.initValue = null;
4539
4561
  }
4540
4562
 
4541
- if (select.initValue === null || select.initValue === "" || !select.initValue) {
4542
- combobox.value("");
4543
- modelSetter(_scope, "");
4544
- }
4545
-
4546
-
4547
4563
  if (combobox.dataSource.transport && combobox.dataSource.transport.options) {
4548
4564
  combobox.dataSource.transport.options.combobox = combobox;
4549
4565
  combobox.dataSource.transport.options.$compile = $compile;
@@ -5498,101 +5514,134 @@
5498
5514
  }])
5499
5515
 
5500
5516
  .directive('cronBreadcrumbs', function ($rootScope) {
5501
- 'use strict';
5502
- return {
5503
- restrict: 'E',
5504
- replace: true,
5505
- link: function (scope, element, attrs) {
5506
-
5507
- var bcAction = attrs.ngInit ? attrs.ngInit : null;
5508
- const bcDelimiterIcon = attrs.crnDelimiterIcon;
5509
- const bcTypeMenu = attrs.typeMenu;
5510
- const bcMenuId = attrs.idMenu ? attrs.idMenu : null;
5511
- const bcId = attrs.id;
5512
- const bcIconRoot = attrs.breadcrumbIcon ? attrs.breadcrumbIcon : null;
5513
- const bcList = [];
5514
-
5515
- const fillAction = async () => {
5517
+ 'use strict';
5518
+ return {
5519
+ restrict: 'E',
5520
+ replace: true,
5521
+ link: function (scope, element, attrs) {
5522
+
5523
+ let bcAction = attrs.ngInit ? attrs.ngInit : null;
5524
+ let bcList = [];
5525
+ const bcDelimiterIcon = attrs.crnDelimiterIcon;
5526
+ const bcTypeMenu = attrs.typeMenu;
5527
+ const bcMenuId = attrs.idMenu ? attrs.idMenu : null;
5528
+ const bcId = attrs.id;
5529
+ const bcIconRoot = attrs.breadcrumbIcon ? attrs.breadcrumbIcon : null;
5530
+
5531
+
5532
+ const destroyBreadcrumb = () => {
5533
+ const $bcElement = $(`#${bcId}`);
5534
+ if ($bcElement.data('kendoBreadcrumb')) {
5535
+ $bcElement.data('kendoBreadcrumb').destroy();
5536
+ $bcElement.empty();
5537
+ }
5538
+ };
5539
+
5540
+
5541
+ const fillAction = async () => {
5516
5542
  const shortVersion = bcAction.replace("cronapi.client('js.", 'blockly.js.');
5517
5543
  bcAction = shortVersion.replace("').run()", '');
5518
5544
  bcAction = scope.$eval(bcAction);
5519
5545
  bcList = await bcAction();
5520
5546
 
5521
5547
  const onclick = async (e) => {
5522
- if (e.item.action) {
5548
+ if (e.item.action) {
5523
5549
  e.item.action();
5524
5550
  }
5525
5551
  };
5526
5552
 
5553
+
5554
+ destroyBreadcrumb();
5555
+
5556
+
5527
5557
  $(`#${bcId}`).kendoBreadcrumb({
5528
5558
  items: bcList,
5529
5559
  delimiterIcon: bcDelimiterIcon,
5530
5560
  navigational: true,
5531
- click : onclick
5561
+ click: onclick
5532
5562
  });
5533
- }
5563
+ };
5534
5564
 
5535
- const clearAction = (action) => {
5536
- if (action) {
5537
- return action.replace("cronapi.screen.changeView('", '').replace("', [])", '');
5538
- }
5539
- return "#/home";
5540
- }
5541
5565
 
5542
- if (bcAction && bcTypeMenu === "idBloco") {
5543
- fillAction();
5544
- } else {
5545
- var observer = new MutationObserver((mutation, observer) => {
5566
+ const clearAction = (action) => {
5567
+ if (action) {
5568
+ return action.replace("cronapi.screen.changeView('", '').replace("', [])", '');
5569
+ }
5570
+ return "#/home";
5571
+ };
5572
+
5573
+
5574
+ if (bcAction && bcTypeMenu === "idBloco") {
5575
+ fillAction();
5576
+ }
5577
+
5578
+ else {
5579
+ var observer = new MutationObserver((mutation, obs) => {
5546
5580
  const $parent = $(`#${bcMenuId}`).parent();
5547
5581
  const attrOptions = $parent.attr('options');
5582
+
5548
5583
  if (attrOptions) {
5549
- observer.disconnect(); // stop observing
5550
5584
 
5551
- const options = JSON.parse(attrOptions);
5552
- const page = document.location.hash || 'home';
5585
+ obs.disconnect();
5553
5586
 
5554
- const findTrace = (array, action, path = []) => {
5555
- for (let i = 0; i < array.length; i++) {
5556
- var item = array[i];
5557
- item.action = clearAction(item.action);
5558
- if (item.action === action) {
5559
- return [...path, item];
5560
- }
5561
- if (item.menuItems) {
5562
- const result = findTrace(item.menuItems, action, [...path, item]);
5563
- if (result) {
5564
- return result;
5565
- }
5587
+ const options = JSON.parse(attrOptions);
5588
+ const page = document.location.hash || 'home';
5589
+
5590
+ const findTrace = (array, action, path = []) => {
5591
+ for (let i = 0; i < array.length; i++) {
5592
+ var item = array[i];
5593
+ item.action = clearAction(item.action);
5594
+ if (item.action === action) {
5595
+ return [...path, item];
5596
+ }
5597
+ if (item.menuItems) {
5598
+ const result = findTrace(item.menuItems, action, [...path, item]);
5599
+ if (result) {
5600
+ return result;
5566
5601
  }
5567
5602
  }
5568
- return null;
5569
5603
  }
5604
+ return null;
5605
+ };
5570
5606
 
5571
- const trace = findTrace(options.subMenuOptions, page);
5572
- if (trace) {
5573
- for (var index in trace) {
5574
- const item = trace[index];
5575
- bcList.push({
5576
- type: index == 0 ? 'rootitem' : 'item',
5577
- href: item.action,
5578
- text: item.title,
5579
- showText: true,
5580
- showIcon: false
5581
- });
5582
- }
5583
- $(`#${bcId}`).kendoBreadcrumb({
5584
- items: bcList,
5585
- delimiterIcon: bcDelimiterIcon,
5586
- navigational: true
5587
- });
5607
+
5608
+ const trace = findTrace(options.subMenuOptions, page);
5609
+ if (trace) {
5610
+ bcList = [];
5611
+ for (var index in trace) {
5612
+ const item = trace[index];
5613
+ bcList.push({
5614
+ type: index == 0 ? 'rootitem' : 'item',
5615
+ href: item.action,
5616
+ text: item.title,
5617
+ showText: true,
5618
+ showIcon: false
5619
+ });
5588
5620
  }
5621
+
5622
+
5623
+ destroyBreadcrumb();
5624
+
5625
+
5626
+ $(`#${bcId}`).kendoBreadcrumb({
5627
+ items: bcList,
5628
+ delimiterIcon: bcDelimiterIcon,
5629
+ navigational: true
5630
+ });
5631
+ }
5589
5632
  }
5590
- });
5591
- observer.observe(document.body, { childList : true});
5633
+ });
5634
+
5635
+
5636
+ observer.observe(document.body, {
5637
+ childList: true,
5638
+ attributes: true,
5639
+ subtree: true
5640
+ });
5641
+ }
5592
5642
  }
5593
- }
5594
- }
5595
- })
5643
+ };
5644
+ })
5596
5645
 
5597
5646
  .directive('ngInitialValue', function($parse) {
5598
5647
  return {
@@ -5988,41 +6037,74 @@
5988
6037
  return {
5989
6038
  restrict: 'EA',
5990
6039
  link: function(scope, element, attrs) {
5991
- let nextPageInfinite = {
5992
- isVisible: false,
5993
- checkVisibility: function(visible) {
5994
- var dataSource = attrs.crnInfiniteScroll ? scope.$eval(attrs.crnInfiniteScroll) : attrs.crnDatasource ? scope.$eval(attrs.crnDatasource): undefined;
5995
- if (dataSource) {
5996
- if (nextPageInfinite.isVisible !== visible) {
5997
- nextPageInfinite.isVisible = visible;
5998
- if (nextPageInfinite.isVisible) {
5999
- if (dataSource.loaded && dataSource.loadedFinish) {
6000
- dataSource.nextPage();
6001
- } else {
6002
- let intervalNextPage = setInterval(function() {
6003
- if (dataSource.loaded && dataSource.loadedFinish) {
6004
- dataSource.nextPage();
6005
- clearInterval(intervalNextPage);
6006
- }
6007
- }, 250);
6008
- }
6009
- }
6010
- }
6011
- }
6012
- },
6013
- eventScroll: function() {
6040
+ let infiniteScrollController = {
6041
+ isFirstTime: true,
6042
+ isRunning: false,
6043
+ datasource: undefined,
6044
+ isVisible: function() { // verifica se o fim do componente esta aparecendo
6014
6045
  var topElem = element.offset().top;
6015
6046
  var botElem = element.offset().top + element.outerHeight();
6016
6047
  var botScrn = $(window).scrollTop() + $(window).innerHeight();
6017
6048
  var topScrn = $(window).scrollTop();
6018
- nextPageInfinite.checkVisibility((botScrn > topElem) && (topScrn < botElem));
6049
+ return (botScrn > topElem) && (topScrn < botElem);
6050
+ },
6051
+ loadNextPage: function() {
6052
+ if (infiniteScrollController.datasource === undefined) {
6053
+ infiniteScrollController.datasource = attrs.crnInfiniteScroll ? scope.$eval(attrs.crnInfiniteScroll) : attrs.crnDatasource ? scope.$eval(attrs.crnDatasource): undefined;
6054
+ }
6055
+ if (infiniteScrollController.datasource && infiniteScrollController.datasource.loaded && infiniteScrollController.datasource.loadedFinish) {
6056
+ infiniteScrollController.datasource.nextPage();
6057
+ return true;
6058
+ }
6059
+ return false;
6060
+ },
6061
+ setStopped: function() {
6062
+ infiniteScrollController.isRunning = false;
6063
+ if (infiniteScrollController.isFirstTime) { // Foi executado pelo load, agora inclui evento do scroll
6064
+ infiniteScrollController.isFirstTime = false;
6065
+ $(window).scroll(infiniteScrollController.executeInfinityScroll);
6066
+ }
6067
+ },
6068
+ executeInfinityScroll: function() {
6069
+ if (!infiniteScrollController.isRunning) { // semaforo para evitar execuções simultaneas causada pelo scrolling
6070
+ infiniteScrollController.isRunning = true;
6071
+ let retries = 0;
6072
+ let intervalNextPage = setInterval(function() {
6073
+ if (infiniteScrollController.isVisible()) {
6074
+ // Fim do area esta visivel, carregar pagina.
6075
+ if (!infiniteScrollController.loadNextPage()) {
6076
+ // Não conseguiu carregar a pagina
6077
+ if (retries < 5 && infiniteScrollController.isVisible()) {
6078
+ // tenta de novo enquanto o componente esta visivel (maximo 5 vezes)
6079
+ retries = retries + 1;
6080
+ } else {
6081
+ // para de verificar, ultrapasou 5 tentativas ou o componente não esta mais visivel
6082
+ infiniteScrollController.setStopped();
6083
+ clearInterval(intervalNextPage);
6084
+ }
6085
+ } else if (!infiniteScrollController.isVisible()) {
6086
+ // Carregou pagina
6087
+ // para de verificar pois o componente não esta mais visivel
6088
+ infiniteScrollController.setStopped();
6089
+ clearInterval(intervalNextPage);
6090
+ } else {
6091
+ // Carregou pagina
6092
+ // zera tentativas pois o componente esta visivel e a pagina foi carregada,
6093
+ // tentará nova pagina (ocorre se o numero de registros carregados for menor que o tamanho da tela
6094
+ retries = 0;
6095
+ }
6096
+ } else {
6097
+ // Fim do area nao esta visivel, para de verificar.
6098
+ infiniteScrollController.setStopped();
6099
+ }
6100
+ }, 250);
6101
+ }
6019
6102
  }
6020
6103
  };
6021
- $(window).scroll(nextPageInfinite.eventScroll);
6022
- $(window).ready(nextPageInfinite.eventScroll);
6104
+ $(window).ready(infiniteScrollController.executeInfinityScroll);
6023
6105
  }
6024
6106
  };
6025
- }]);
6107
+ }])
6026
6108
 
6027
6109
  }(app));
6028
6110
 
@@ -6043,63 +6125,181 @@ function maskDirective($compile, $translate, $parse, attrName) {
6043
6125
  return;
6044
6126
 
6045
6127
  var modelGetter = $parse(attrs['ngModel']);
6046
-
6047
6128
  var modelSetter = modelGetter.assign;
6048
6129
 
6049
-
6050
6130
  var $element = $(element);
6051
6131
  if ($element.data('alreadycompiled'))
6052
6132
  return;
6133
+
6053
6134
  $element.data('alreadycompiled', true);
6054
6135
  $element.data('$compile', $compile);
6055
6136
 
6056
6137
  var type = $element.attr("type");
6138
+
6139
+ if (type === "email") {
6140
+ $element.inputmask("email").attr("novalidate", "novalidate");
6141
+ $element.next(".k-tooltip-validation").remove();
6057
6142
 
6058
- if (type == "checkbox" || type == "password" || type == "url"){
6143
+ const observer = new MutationObserver(() => {
6144
+ const tooltip = $element.next(".k-tooltip-validation");
6145
+ if (tooltip.length) tooltip.remove();
6146
+ });
6147
+
6148
+ observer.observe($element[0].parentNode, { childList: true, subtree: true });
6059
6149
  return;
6150
+ }
6151
+
6152
+ if ([
6153
+ "week",
6154
+ "date",
6155
+ "time",
6156
+ "datetime-local",
6157
+ "month",
6158
+ "datetime",
6159
+ "time-local",
6160
+ ].includes(type)) {
6161
+ const iconClass = [
6162
+ "week",
6163
+ "dat",
6164
+ "month",
6165
+ "datetime-local",
6166
+ "datetime",
6167
+ ].includes(type)
6168
+ ? "fa fa-calendar-o"
6169
+ : "fa fa-clock-o";
6170
+
6171
+ const iconWrapper = document.createElement("span");
6172
+ iconWrapper.className = "input-icon-wrapper";
6173
+ iconWrapper.innerHTML = `<i class="${iconClass}" style="cursor: pointer; font-weight: 600;"></i>`;
6174
+
6175
+ const auxInput = document.createElement("input");
6176
+ auxInput.type = type;
6177
+ auxInput.style.position = "absolute";
6178
+ auxInput.style.opacity = "0";
6179
+ auxInput.style.pointerEvents = "none";
6180
+
6181
+ $element.after(iconWrapper);
6182
+ iconWrapper.appendChild(auxInput);
6183
+
6184
+ iconWrapper.addEventListener("click", () => {
6185
+ auxInput.focus();
6186
+ });
6187
+
6188
+ auxInput.addEventListener("change", () => {
6189
+ $element.val(auxInput.value);
6190
+ $element.trigger("input");
6191
+ });
6192
+
6193
+ scope.$watch(
6194
+ () => $element.attr("exibir-icone"),
6195
+ (newValue) => {
6196
+ if (newValue === "true") {
6197
+ iconWrapper.style.display = "inline-block";
6198
+ } else {
6199
+ iconWrapper.style.display = "none";
6200
+ }
6201
+ }
6202
+ );
6060
6203
  }
6061
6204
 
6062
- if(type == "color" || type == "range"){
6063
- $element[0].classList.remove("form-control");
6064
- $element[0].classList.remove("k-textbox");
6205
+ if (["checkbox", "password", "url", "color", "range"].includes(type)) {
6206
+ if (["color", "range"].includes(type)) {
6207
+ $element[0].classList.remove("form-control", "k-textbox");
6208
+ }
6065
6209
  return;
6066
6210
  }
6067
6211
 
6068
- $element.data("type", type);
6069
-
6070
- $element.attr("type", "text");
6212
+ if (!["color", "range", "checkbox"].includes(type)) {
6213
+ $element.data("type", type);
6214
+ $element.attr("type", "text");
6215
+ }
6071
6216
 
6072
6217
  if (ngModelCtrl) {
6073
6218
  ngModelCtrl.$formatters = [];
6074
6219
  ngModelCtrl.$parsers = [];
6075
6220
  }
6076
6221
 
6077
- if (attrs.asDate !== undefined && type == 'text')
6078
- type = "date";
6079
-
6080
- var textMask = true;
6081
-
6082
- var removeMask = false;
6222
+ var attrMask =
6223
+ attrs.mask || attrs.format || parseMaskType(type, $translate);
6224
+ var mask = attrMask.replace(";1", "").replace(";0", "").trim();
6225
+
6226
+ if (!mask) return;
6227
+
6228
+ const placeholder = generateCustomPlaceholder(type, mask);
6229
+ $element.attr("placeholder", placeholder);
6230
+
6231
+ if ([
6232
+ "week",
6233
+ "date",
6234
+ "time",
6235
+ "datetime-local",
6236
+ "month",
6237
+ "datetime",
6238
+ "time-local",
6239
+ ].includes(type)) {
6240
+ $element.addClass("dark-placeholder");
6241
+ }
6083
6242
 
6084
- var attrMask = attrs.mask || attrs.format;
6243
+ $element.on("input blur", function () {
6244
+ if (!$element.val()) {
6245
+ $element.attr("placeholder", placeholder);
6246
+ } else {
6247
+ $element.attr("placeholder", "");
6248
+ }
6249
+ });
6085
6250
 
6086
- if (!attrMask) {
6087
- attrMask = parseMaskType(type, $translate);
6251
+ if (["date", "datetime-local", "datetime", "time", "time-local"].includes(
6252
+ type
6253
+ )) {
6254
+ $element.datetimepicker({
6255
+ format: mask,
6256
+ locale: $translate.use(),
6257
+ });
6258
+ } else if (["number", "money", "integer"].includes(type)) {
6259
+ $element.inputmask("numeric", {
6260
+ prefix: "",
6261
+ rightAlign: false,
6262
+ });
6088
6263
  } else {
6089
- attrMask = parseMaskType(attrMask, $translate);
6090
- }
6091
-
6092
- if (attrMask.endsWith(";0")) {
6093
- removeMask = true;
6264
+ $element.mask(mask);
6094
6265
  }
6095
6266
 
6096
- var mask = attrMask.replace(';1', '').replace(';0', '').trim();
6097
- if (mask == undefined || mask.length == 0) {
6098
- return;
6267
+ function generateCustomPlaceholder(type, mask) {
6268
+ switch (type) {
6269
+ case "week":
6270
+ return "Semana --, ----";
6271
+ case "month":
6272
+ return "-------- de ----";
6273
+ case "time":
6274
+ case "time-local":
6275
+ return "--:--";
6276
+ case "datetime-local":
6277
+ case "datetime":
6278
+ return "dd/mm/aaaa --:--";
6279
+ case "date":
6280
+ return "dd/mm/aaaa";
6281
+ default:
6282
+ return mask
6283
+ .replace(/D/g, "d")
6284
+ .replace(/M/g, "m")
6285
+ .replace(/Y/g, "a")
6286
+ .replace(/H/g, "h")
6287
+ .replace(/m/g, "m")
6288
+ .replace(/s/g, "s")
6289
+ .replace(/-/g, "-")
6290
+ .replace(/:/g, ":")
6291
+ .replace(/\//g, "/");
6292
+ }
6099
6293
  }
6100
6294
 
6101
- if (type == 'date' || type == 'datetime' || type == 'datetime-local' || type == 'month' || type == 'time' || type == 'time-local' || type == 'week') {
6102
-
6295
+ if ([
6296
+ "date",
6297
+ "datetime",
6298
+ "datetime-local",
6299
+ "month",
6300
+ "time",
6301
+ "week",
6302
+ ].includes(type)) {
6103
6303
  var options = {
6104
6304
  format: mask,
6105
6305
  locale: $translate.use(),
@@ -6123,27 +6323,55 @@ function maskDirective($compile, $translate, $parse, attrName) {
6123
6323
  }
6124
6324
  };
6125
6325
 
6126
- if (mask != 'DD/MM/YYYY' && mask != 'MM/DD/YYYY') {
6127
- options.sideBySide = true;
6128
- }
6129
-
6130
- var useUTC = type == 'date' || type == 'datetime' || type == 'time';
6131
-
6132
- if (!window.fixedTimeZone) {
6133
- useUTC = false;
6326
+ if ($element.attr('from-grid')) {
6327
+ var openPopup = function () {
6328
+ var popup = $(this).offset();
6329
+ var isBelowInput = true;
6330
+ var datetimepickerShowing = $(this)
6331
+ .parent()
6332
+ .find(".bootstrap-datetimepicker-widget.dropdown-menu");
6333
+ if (!datetimepickerShowing.length) {
6334
+ isBelowInput = false;
6335
+ datetimepickerShowing = $(this)
6336
+ .parent()
6337
+ .find(".bootstrap-datetimepicker-widget.dropdown-menu.top");
6338
+ }
6339
+ if ($(datetimepickerShowing).offset()) {
6340
+ datetimepickerShowing.appendTo("body");
6341
+ var popupTop = isBelowInput
6342
+ ? popup.top + $element.outerHeight()
6343
+ : popup.top - datetimepickerShowing.outerHeight();
6344
+ datetimepickerShowing.css({
6345
+ top: popupTop,
6346
+ left: popup.left,
6347
+ zIndex: 999999,
6348
+ });
6349
+ }
6350
+ };
6351
+ $element.on("click", openPopup);
6352
+ $element.on("focus", function () {
6353
+ setTimeout(openPopup.bind(this), 100);
6354
+ });
6134
6355
  }
6135
6356
 
6136
- $element.data('mask', mask);
6137
- $element.data('useUTC', useUTC);
6357
+ $element.datetimepicker(options);
6138
6358
 
6139
6359
  if ($element.attr('from-grid')) {
6140
6360
  var openPopup = function() {
6141
6361
  var popup = $(this).offset();
6142
6362
  var isBellowInput = true;
6143
- var datetimepickerShowing = $(this).parent().find('.bootstrap-datetimepicker-widget.dropdown-menu.usetwentyfour.bottom');
6363
+ var datetimepickerShowing = $(this)
6364
+ .parent()
6365
+ .find(
6366
+ '.bootstrap-datetimepicker-widget.dropdown-menu.usetwentyfour.bottom'
6367
+ );
6144
6368
  if (!datetimepickerShowing.length) {
6145
6369
  isBellowInput = false;
6146
- datetimepickerShowing = $(this).parent().find('.bootstrap-datetimepicker-widget.dropdown-menu.usetwentyfour.top');
6370
+ datetimepickerShowing = $(this)
6371
+ .parent()
6372
+ .find(
6373
+ '.bootstrap-datetimepicker-widget.dropdown-menu.usetwentyfour.top'
6374
+ );
6147
6375
  }
6148
6376
  if ($(datetimepickerShowing).offset()) {
6149
6377
  var popupLeft = $(datetimepickerShowing).offset().left;
@@ -6151,11 +6379,10 @@ function maskDirective($compile, $translate, $parse, attrName) {
6151
6379
  var grid = $('body');
6152
6380
  datetimepickerShowing.appendTo(grid);
6153
6381
 
6154
- var popupTop = 0
6382
+ var popupTop = 0;
6155
6383
  if (!isBellowInput)
6156
6384
  popupTop = popup.top - ($(datetimepickerShowing).height() + 15);
6157
- else
6158
- popupTop = popup.top + 35;
6385
+ else popupTop = popup.top + 35;
6159
6386
 
6160
6387
  datetimepickerShowing.css("top", popupTop);
6161
6388
  datetimepickerShowing.css("bottom", "auto");
@@ -6194,10 +6421,8 @@ function maskDirective($compile, $translate, $parse, attrName) {
6194
6421
  $element.val(momentDate.format(mask));
6195
6422
  $element.data('initial-value', null);
6196
6423
  }
6197
-
6198
- }
6199
- else {
6200
- $element.wrap("<div style=\"position:relative\"></div>");
6424
+ } else {
6425
+ $element.wrap('<div style="position:relative"></div>');
6201
6426
  }
6202
6427
  $element.datetimepicker(options);
6203
6428
  if (attrs.fromGrid !== "true") {
@@ -6208,7 +6433,7 @@ function maskDirective($compile, $translate, $parse, attrName) {
6208
6433
  var value = $element.val();
6209
6434
  var momentDate = null;
6210
6435
  if (useUTC) {
6211
- momentDate = moment(value, mask).utcOffset(window.timeZoneOffset, true);
6436
+ momentDate = moment(value, mask).utcOffset( window.timeZoneOffset, true);
6212
6437
  } else {
6213
6438
  momentDate = moment(value, mask);
6214
6439
  }
@@ -6223,48 +6448,27 @@ function maskDirective($compile, $translate, $parse, attrName) {
6223
6448
  });
6224
6449
  }
6225
6450
 
6226
- if (ngModelCtrl ) {
6227
- ngModelCtrl.$formatters.push(function (value) {
6228
- if (value) {
6229
- return formatWithMomentAs(mask, useUTC, value, "string");
6230
- }
6231
-
6232
- if(value === null){
6233
- var dp = $element.datetimepicker(options).data('DateTimePicker');
6234
- dp.date(null);
6235
- }
6451
+ if (ngModelCtrl) {
6452
+ ngModelCtrl.$formatters.push((value) =>
6453
+ value ? moment(value).format(mask) : null
6454
+ );
6236
6455
 
6237
- return null;
6456
+ ngModelCtrl.$parsers.push((value) => {
6457
+ var momentDate = moment(value, mask);
6458
+ return momentDate.isValid() ? momentDate.toDate() : null;
6238
6459
  });
6239
6460
 
6240
- ngModelCtrl.$parsers.push(function (value) {
6241
- if (value) {
6242
- if (value instanceof Date) {
6243
- return value;
6244
- }
6245
- var momentDate = null;
6246
- if (useUTC) {
6247
- momentDate = moment(value, mask).utcOffset(window.timeZoneOffset, true);
6248
- } else {
6249
- momentDate = moment(value, mask);
6250
- }
6251
- if (type == 'time' || type == 'time-local') {
6252
- momentDate = momentDate.year(1970).dayOfYear(1).month(0);
6253
- }
6254
- if (typeof value === "string" && (value.length < mask.length)) {
6255
- let tempValue = formatWithMomentAs(mask, useUTC, value, "string");
6256
- if (tempValue.startsWith(value) && (value.length < tempValue.length) && (isNaN(tempValue[value.length]) || tempValue[value.length] === " ")) {
6257
- ngModelCtrl.$$element.val(tempValue.substring(0, value.length + 1));
6258
- }
6259
- }
6260
- return momentDate.toDate();
6261
- }
6262
-
6263
- return null;
6461
+ $element.on('dp.change', function () {
6462
+ scope.$apply(() => {
6463
+ var value = $element.val();
6464
+ var momentDate = moment(value, mask);
6465
+ if (momentDate.isValid())
6466
+ ngModelCtrl.$setViewValue(momentDate.toDate());
6467
+ });
6264
6468
  });
6265
6469
  }
6266
-
6267
- } else if (type == 'number' || type == 'money' || type == 'integer' || type == 'money-decimal') {
6470
+ }
6471
+ else if (type == 'number' || type == 'money' || type == 'integer' || type == 'money-decimal') {
6268
6472
  removeMask = true;
6269
6473
 
6270
6474
  var currency = mask.trim().replace(/\./g, '').replace(/\,/g, '').replace(/#/g, '').replace(/0/g, '').replace(/9/g, '');
@@ -6317,45 +6521,40 @@ function maskDirective($compile, $translate, $parse, attrName) {
6317
6521
  }
6318
6522
 
6319
6523
  var ipOptions = {
6320
- 'rightAlign': (type == 'money' || type == 'money-decimal'),
6321
- 'unmaskAsNumber': true,
6322
- 'allowMinus': true,
6323
- 'prefix': prefix,
6324
- 'suffix': suffix,
6325
- 'radixPoint': decimal,
6326
- 'digits': precision,
6327
- 'numericInput' : (type == 'money-decimal')
6524
+ rightAlign: ['money', 'money-decimal'].includes(type),
6525
+ allowMinus: true,
6526
+ prefix: prefix,
6527
+ suffix: suffix,
6528
+ radixPoint: decimal,
6529
+ digits: precision,
6530
+ groupSeparator: thousands,
6531
+ autoGroup: !!thousands,
6328
6532
  };
6329
6533
 
6330
- if (thousands) {
6331
- ipOptions['autoGroup'] = true;
6332
- ipOptions['groupSeparator'] = thousands;
6333
- }
6334
-
6335
- $(element).inputmask(inputmaskType, ipOptions);
6336
- useInputMaskPlugin(element, ngModelCtrl, scope, modelSetter, mask);
6534
+ $element.inputmask(inputmaskType, ipOptions);
6535
+ useInputMaskPlugin($element, ngModelCtrl, scope, modelSetter, mask);
6337
6536
  }
6338
- else if (type == 'text' || type == 'tel' || type == 'string') {
6339
-
6340
- let charToNumber = ['D','M', 'Y', 'H', 'm','s'];
6341
- let verifyMaskDateForText = (mask) => { charToNumber.forEach((c) => mask = mask.replaceAll(c,'9')); return mask};
6537
+ else {
6538
+ let charToNumber = ['D', 'M', 'Y', 'H', 'm', 's'];
6539
+ let verifyMaskDateForText = (mask) => {
6540
+ charToNumber.forEach((c) => (mask = mask.replaceAll(c, "9")));
6541
+ return mask;
6542
+ };
6342
6543
  mask = verifyMaskDateForText(mask);
6343
6544
 
6344
6545
  if(!attrs.maskPlaceholder){
6345
6546
  $element.mask(mask);
6346
- useMaskPlugin(element, ngModelCtrl, scope, modelSetter, removeMask);
6347
- }
6348
- else{
6349
- options = {};
6350
- options['placeholder'] = attrs.maskPlaceholder;
6351
- $(element).inputmask(mask, options);
6352
- if(removeMask){
6353
- useInputMaskPlugin(element, ngModelCtrl, scope, modelSetter, mask);
6354
- }
6547
+ useMaskPlugin($element, ngModelCtrl, scope, modelSetter, false);
6548
+ } else {
6549
+ var options = {
6550
+ placeholder: attrs.maskPlaceholder,
6551
+ };
6552
+ $element.inputmask(mask, options);
6553
+ useInputMaskPlugin($element, ngModelCtrl, scope, modelSetter, mask);
6355
6554
  }
6356
6555
  }
6357
- }
6358
- }
6556
+ },
6557
+ };
6359
6558
  }
6360
6559
 
6361
6560
  function useInputMaskPlugin(element, ngModelCtrl, scope, modelSetter, mask){