Odyssey
mFeatureMnu.prg
1 <?php
2 /**
3  * mFeatureMnu.prg
4  *
5  * Presentation / edit script for maintaining the Credit Union Menu and Features
6  * This script will allow HomeCU to create a menu and set a Feature dependency for the menu items
7  *
8  * ** ERROR STATES **
9  * ** 900 -- permissions failed --> redirect screen
10  * ** 901 -- CU Code not found --> Print Error screen
11  *
12  * MWS 10/24/2016
13  *
14  */
15 
16  /* ** FORM VARIABLES ** */
17  $homecuSharedLibrary = dirname(__FILE__) . "/../../shared/library";
18  // ** Current monitor includes are in scripts folder
19  $homecuMonitorLibrary = dirname(__FILE__) . "/../../monitor/library";
20  $homecuMonitorScripts = dirname(__FILE__) . "/../../monitor/scripts";
21 
22  $importValues = Array();
23 
24 
25  $pageTitle = 'Build CU Menu';
26 
27 
28  try {
29  /* ** require needed scripts ** */
30  require_once("$homecuMonitorLibrary/cu_top.i");
31  require_once("$homecuMonitorLibrary/ck_hticket.i");
32  require_once("$homecuMonitorLibrary/monitorView.i");
33  require_once("$homecuMonitorLibrary/cu_pass.i");
34  require_once("$homecuSharedLibrary/dms_imp_val.i");
35  require_once("$homecuSharedLibrary/cu_flagconst.i");
36  require_once("$homecuSharedLibrary/dms_imp_val.i");
37 
38 
39  /* * IMPORT VARIABLES * */
40  $importFieldAry = Array (
41  "user_name" => array('filter' => FILTER_SANITIZE_STRING)
42  );
43  HCU_ImportVars($importValues, '', $importFieldAry);
44 
45  // ** AFTER importing, set the [cu] to the upper case of the user_name for query purposes
46  $importValues['cu'] = strtoupper($importValues['user_name']);
47 
48 
49  if (!CheckPerm($dbh, $Hu, basename($_SERVER['SCRIPT_NAME']), $_SERVER['REMOTE_ADDR'])) {
50  // ** Permissions failed
51  // ** redirect to new page
52  throw new ErrorException('permissions failed', 900);
53  }
54 
55  /* Validate the user_name exists in cuadmin table */
56  $sql = "SELECT count(*) as count FROM cuadmin WHERE cu = '" . prep_save($importValues['cu'], 10) . "'; ";
57  $cntRs = db_query($sql, $dbh);
58  $cntRow = db_fetch_all($cntRs);
59 
60  if ($cntRow[0]['count'] == 0) {
61  // ** There were no records found with this cu code
62  throw new ErrorException('Unknown Credit Union', 901);
63  }
64 
65 
66  /* ** PRINT PAGE TOP ** */
67  printMonitorPageTop($pageTitle, $homecuKendoVersion, $cloudfrontDomainName, $bootstrapVersion, $fontawesomeVersion, true);
68 
69  /* ** LOCAL STYLE CLASSES ** */
70 ?>
71  <style>
72  #page-contents {
73  margin-top: 25px;
74  }
75  .div-content-right {
76  text-align: right;
77  }
78 
79  input[type="checkbox"] {
80  margin: 2px 0 0;
81  }
82 
83  .local-indent {
84  margin-left: 15px;
85  }
86  .local-indent .radio,
87  .local-indent .checkbox,
88  .local-indent .radio-inline,
89  .local-indent .checkbox-inline {
90  margin-left: 15px;
91  }
92  #local-detail-list {
93 
94  }
95  .local-no-icon {
96  display: inline-block;
97  margin-left: 16px;
98  }
99  .local-menu-root {
100  color: rgba(0, 90, 210, 1);
101  }
102  .local-add-td-row {
103  color: rgba(22, 123, 57, .85);
104  }
105  .local-td-grab {
106  text-overflow: unset !important;
107  }
108  .local-td-no-grab {
109  display: inline-block;
110  }
111  .local-td-col-1 {
112  display: inline-block;
113  width: 16px;
114  }
115 
116  .radio-inline p {
117  margin-top: 5px;
118  }
119  .form-horizontal .radio,
120  .form-horizontal .checkbox,
121  .form-horizontal .radio-inline,
122  .form-horizontal .checkbox-inline {
123  padding-top: 0px;
124  }
125  .local-k-template .local-k-edit-buttons {
126  clear: both;
127  text-align: right;
128  border-width: 1px 0 0;
129  border-style: solid;
130  position: relative;
131  bottom: -1em;
132  padding: .6em;
133  }
134  #local-icon-delete {
135  float:left;
136  margin-top: 8px;
137  }
138  .local-table-flags {
139  float:right;
140  }
141  #local-menu-readonly {
142  color: rgba(224, 1, 1, .84);
143  display: none;
144  }
145  #local-error {
146  display: none;
147  }
148  .local-error-text {
149  display: inline-block;
150  vertical-align: top;
151  margin-top: 10px;
152  }
153  .local-error-text ul {
154  list-style: none;
155  }
156  .local-error-text ul li {
157  margin-left: 10px;
158  }
159  .local-error-icon {
160  display: inline-block;
161  padding: 20px;
162  }
163 
164  #localHideSubmitWait {
165  position: relative;
166  left: -2000px;
167  top: -2000px;
168  }
169 
170  #formStatus {
171  padding: 10px;
172  }
173  .local-menu-action {
174  display: none;
175  }
176  .local-menu-action.local-show {
177  display: block;
178  }
179 
180  #showIcon {
181  position: relative;
182  top: 5px;
183  }
184  div.h4 .local-tooltip,
185  label.h4 .local-tooltip {
186  font-size: 12px;
187  }
188 
189  .localSaveMenuDiv {
190  position: fixed;
191  top: 75px;
192  width: inherit;
193  padding: inherit;
194  margin: inherit;
195  text-align: right;
196  padding-right: 5px;
197  }
198 
199 
200 
201  @media (max-width: 991px) {
202  .localSaveMenuDiv {
203  right: 0px;
204  }
205  }
206 
207  @media (min-width: 991px) {
208  .localSaveMenuDiv div {
209  position: relative;
210  left: -45px;
211  }
212  }
213  </style>
214 <?php
215  printMonitorPageMiddle($pageTitle);
216 
217 
218  /* ** PAGE CONTENTS ** */
219 ?>
220  <div id='localHideSubmitWait'>
221  <div id='localSubmitWait' class='k-block' >
222  <div class='k-loading-image'></div>
223  </div>
224  </div>
225  <div id="page-contents">
226  <!-- Main Container -->
227 
228 
229 
230  <div class="container">
231 
232  <?php // To set the same to the same as the grid. ?>
233  <div class="local-menu-action localSaveMenuDiv"><div>
234  <a class="" href="javascript:CancelMenuChanges();" >Cancel</a>
235  &nbsp;&nbsp;&nbsp;
236  <button class="k-button k-primary " type="submit" onclick="SaveMenu();"><span class="fa fa-floppy-o"></span>&nbsp;Save Menu</button>
237  </div></div>
238 
239  <!-- Action buttons -->
240  <div class="row hcu-form-group-spacer">
241  <div class="col-sm-7 col-md-8">
242  <div id="formStatus" class="homecu-formStatus k-block k-error-colored" style="display:none;"></div>
243 
244  </div>
245 
246  </div> <!-- row -->
247  <!-- Data Table / Properties -->
248  <div class="row">
249  <!-- Data Table -->
250  <div class="col-xs-12">
251 
252 
253  <!-- Tree View -->
254  <div class="hcu-no-td-border" id="menu-grid"></div>
255  </div>
256  </div> <!-- row -->
257  </div> <!-- container -->
258  </div> <!-- page-contents -->
259 <?php
260  /* ** END PAGE CONTENTS ** */
261  /* ** PRINT PAGE END ** */
262  printMonitorPageBottom();
263 
264  /* ** LOCAL SCRIPT ** */
265 ?>
266  <script>
267  /* ** DECLARE EMPTY DATA VARIABLES ** */
268  var window_stack = []; // Active Window array to click on overlay functionality
269 
270  var dataSettingsPlatforms = [],
271  dataSettingsIcons = [],
272  dataSettingsFeatures = [],
273  dataSettingsScripts = [],
274  dataSettingsLang = [{en_US: true}],
275 
276  dsPlatforms,
277  dsFeatureMenu,
278  dsFeatureList,
279  dsScriptList,
280  dsIcons,
281 
282  editTemplate,
283  windowTemplate,
284  actionDialog,
285  editMenuItem,
286  displayLangCode = 'en_US',
287  menuItemGrid,
288  menuDirty = false;
289 
290  $(document).ready(function() {
291 
292  $(".local-menu-action").appendTo("body");
293 
294  /* ***************************
295  * **** KENDO.DATASOURCE ****
296  *************************** */
297 
298  var dsSettings = new kendo.data.DataSource({
299  transport: {
300  read: {
301  type: "GET",
302  url: 'mFeatureMnu.data',
303  dataType: "json",
304  contentType: 'application/json',
305  data: {
306  api_action: 'settings',
307  cu: '<?php echo $importValues['cu']; ?>'
308  }
309  },
310  cache: false
311  },
312  schema: {
313  type: 'json',
314  parse: function(response) {
315  responsePass = false;
316  returnData = [];
317  // ** Verify the response packet is well formed, if it is NOT, then
318  // * Simply return a homecuError with that message
319  try {
320  returnData = response.Results[0];
321  } catch(err) {
322  returnData = [{homecuErrors: "Error Parsing Result From Server"}];
323  }
324  return returnData;
325  },
326  errors: function (response) {
327  responsePass = false;
328  responseInfo = '';
329  try {
330  // ** Look for the errors being returned from the server
331  if (response.homecuErrors) {
332  if (response.homecuErrors.length > 0) {
333  return response.homecuErrors;
334  }
335  } else {
336  // * Check for existence of homecuData
337  if (!response.homecuData) {
338  throw "Error Parsing Result From Server";
339  }
340  }
341  } catch (err) {
342  return err;
343  }
344  },
345  requestStart: function(response) {
346  ShowWaitWindow();
347  },
348  requestEnd: function(response) {
349  CloseWaitWindow();
350  },
351  data: function (response) {
352  /* PARSE RESPONSE DATA */
353  var returnData = Array();
354 
355  try {
356  if (response.homecuData) {
357  /* ** MENU PLATFORMS ** */
358  dataSettingsPlatforms = (response.homecuData.menuplatforms ? response.homecuData.menuplatforms : []);
359  dsPlatforms.data(dataSettingsPlatforms);
360 
361  /* ** MENU ICONS ** */
362  dataSettingsIcons = (response.homecuData.menuicons ? response.homecuData.menuicons : []);
363  dsIcons.data(dataSettingsIcons);
364 
365  /* ** MENU FEATURES ** */
366  dataSettingsFeatures = (response.homecuData.features ? response.homecuData.features : []);
367  dsFeatureList.data(dataSettingsFeatures);
368 
369  /* ** MENU SCREENS ** */
370  dataSettingsScripts = (response.homecuData.scripts ? response.homecuData.scripts : []);
371  dsScriptList.data(dataSettingsScripts);
372 
373  dataSettingsLang = (response.homecuData.lang ? response.homecuData.lang : dataSettingsLang);
374  SetLangOptions();
375 
376 
377  returnData = response.homecuData;
378  } else {
379 
380  throw "Error Parsing Result From Server";
381  }
382  } catch (err) {
383 
384  // ** Need to report the message to the main screen
385  /* *** REPORT THE ERROR *** */
386 
387  returnData = [];
388  }
389 
390  return [response];
391 
392  }
393  },
394  error: function(error) {
395  }
396  });
397 
398  /* ***************************
399  * **** KENDO.DATASOURCE ****
400  *************************** */
401  dsFeatureMenu = new kendo.data.DataSource({
402  batch: true,
403  autoSync: false,
404  transport: {
405  read: {
406  type: "GET",
407  url: 'mFeatureMnu.data',
408  dataType: "json",
409  contentType: 'application/json',
410  data: {
411  api_action: 'read',
412  cu: '<?php echo $importValues['cu']; ?>'
413  }
414  },
415  update: {
416  url: 'mFeatureMnu.data?cu=<?php echo $importValues['cu']; ?>',
417  contentType: "application/x-www-form-urlencoded",
418  data: {
419  api_action: 'update',
420  cu: '<?php echo $importValues['cu']; ?>',
421  deleted: null,
422  models: null
423  },
424  type: "POST",
425  dataType: "json",
426  cache: false
427  },
428  destroy: {
429  url: 'mFeatureMnu.data?cu=<?php echo $importValues['cu']; ?>',
430  data: {
431  api_action: 'ignore',
432  cu: '<?php echo $importValues['cu']; ?>'
433  },
434  dataType: "json",
435  type: "POST",
436  cache: false
437  },
438 
439 
440  parameterMap: function(data, type) {
441 
442  try {
443  if (type == 'update') {
444  var setData = {cu: data.cu, api_action: data.api_action, data_deleted: kendo.stringify(dsFeatureMenu.destroyed()), data_updated: kendo.stringify(data.models)};
445  return setData;
446  } else if (type == 'read') {
447  return data;
448  } else if (type == 'destroy') {
449  return {cu: data.cu, api_action: data.api_action};
450  } else {
451  return [];
452  }
453  } catch (err) {
454  return false;
455  }
456  }
457  },
458  requestStart: function(e) {
459  if (e.type != 'read' && e.type != 'update') {
460  e.preventDefault();
461  }
462  ClearErrorMsgs();
463  ShowWaitWindow();
464 
465  },
466  requestEnd: function(response) {
467  CloseWaitWindow();
468  },
469  schema: {
470  type: 'json',
471  parse: function(response) {
472  responsePass = false;
473  returnData = [];
474  // ** Verify the response packet is well formed, if it is NOT, then
475  // * Simply return a homecuError with that message
476  try {
477  returnData = response.Results[0];
478 
479  /* **** **** */
480  // * Possibly have Parse break down the MenuItemAttr into the different Detail values
481 
482 
483  } catch(err) {
484  returnData = [{homecuErrors: "Error Parsing Result From Server"}];
485  }
486  return returnData;
487  },
488  errors: function(response) {
489  responsePass = false;
490  responseInfo = '';
491  try {
492  // ** Look for the errors being returned from the server
493  if (response.homecuErrors) {
494  if (response.homecuErrors.length > 0) {
495 
496  return response.homecuErrors;
497  }
498  } else {
499  // * Check for existence of homecuData
500  if (!response.homecuData) {
501  throw "Error Parsing Result From Server";
502  }
503  }
504  } catch (err) {
505  return err;
506  }
507  },
508  data: function(response) {
509  /* PARSE RESPONSE DATA */
510  var returnData = Array();
511 
512  try {
513  if (response.homecuData) {
514  if (response.homecuData.featuremenu) {
515  // ** Read
516  returnData = response.homecuData.featuremenu;
517  } else if (response.homecuData.featuresave) {
518  // ** Should this loop through the current dsFeatureMenu data..
519  // Modify ID fields and return that??
520 
521  // * Show update status
522  //
523  // ShowErrorMsgs(response.homecuData.status);
524  $.homecuValidator.displayMessage(response.homecuData.status, $.homecuValidator.settings.statusInfo);
525  // ** Update
526  if (response.homecuData.featuresave.updateId) {
527  UpdateRecordId(response.homecuData.featuresave.updateId);
528  }
529  returnData = true;// Not sure what to return at this time
530  } else if (response.homecuData.featureignore) {
531  // ** Ignore this -- BUT dont' throw an error
532 
533  }
534 
535  } else {
536 
537  throw "Error Parsing Result From Server";
538  }
539  } catch (err) {
540 
541  // ** Need to report the message to the main screen
542  /* *** REPORT THE ERROR *** */
543  returnData = [];
544  }
545 
546  return returnData;
547 
548  },
549  model: {
550  id: "MenuItemId",
551  parentId: "ParentId",
552  /* do I need some sort of data mapping to map the values out of the json object into a usable field ??? 10.24.2016 */
553  fields: {
554  MenuItemId: { type: "number", nullable: false },
555  GridOrder: { type: "number", nullable: false },
556  Cu: { type: "string"},
557  DisplayOrder: { type: "number" },
558  FeatureCode: { type: "string" },
559  FeatureDesc: { type: "string" },
560  ParentId: { nullable: true, type: "number" },
561  MenuItemType: { type: "string" },
562  MenuItemAttr: { type: "string" },
563  details_platform_dsk: { type: "boolean" },
564  details_platform_mbl: { type: "boolean" },
565  details_platform_app: { type: "boolean" },
566  details_display_en_US: { type: "string" },
567  details_display_es_US: { type: "string" },
568  details_display_pl_US: { type: "string" },
569  details_fa_icon: { type: "string" },
570  details_href: { type: "string" },
571  details_hrefUrlQuery: { type: "number" },
572  details_target: { type: "number" },
573  details_message: { type: "number" },
574  details_hrefExtraParam: { type: "string" },
575  details_collapse_group: { type: "boolean" },
576  details_memacct_filter: { type: "string"}
577  }
578  }
579  },
580  change: function(e) {
581  if (!this.dataLoading) {
582  ShowActionButton();
583  }
584  },
585  sync: function(e) {
586  dsFeatureMenu.dataLoading = false;
587  HideActionButton();
588  },
589  error: function(error) {
590  if (error.errors) {
591  // ShowErrorMsgs(error.errors);
592  $.homecuValidator.displayMessage(error.errors, $.homecuValidator.settings.statusError);
593  } else {
594  // ShowErrorMsgs("Unknown Error");
595  $.homecuValidator.displayMessage("Unknown Error", $.homecuValidator.settings.statusError);
596  }
597  },
598  sort: { field: "GridOrder", dir: "asc" },
599  newItemId: -500, /* Large enough to account for loaded menu options */
600  dataLoading: false
601  });
602 
603 
604  dsFeatureList = new kendo.data.DataSource({
605  data: dataSettingsFeatures,
606  sort: {field: 'description', dir: 'asc'}
607  });
608  dsScriptList = new kendo.data.DataSource({
609  data: dataSettingsScripts,
610  sort: {field: 'description', dir: 'asc'}
611  });
612  dsPlatforms = new kendo.data.DataSource({
613  data: dataSettingsPlatforms
614  });
615  dsIcons = new kendo.data.DataSource({
616  data: dataSettingsIcons
617  });
618 
619 
620  /* ***************************
621  * **** KENDO.GRID ****
622  *************************** */
623 
624  menuItemGrid = $('#menu-grid').kendoGrid({
625 
626  dataSource: dsFeatureMenu,
627  autoBind: false,
628  toolbar: kendo.template($('#header-treelist').html()),
629  editable: {
630  mode: "popup",
631  template: kendo.template($('#edit-detail-row').html())
632  },
633  rowTemplate: kendo.template($("#menu-row").html()),
634  change: function(e) {
635 
636  },
637  saveChanges: function(e) {
638 
639  },
640  save: function(e) {
641 
642  },
643  columns: [
644  { title: '', width:10 },
645  { title: '', width:20 },
646  { field: 'details_display_en_US', title: "Display", width:"25%" },
647  { field: 'FeatureCode', title: "Applied Feature", width:"25%" },
648  { field: 'Cu', title: "Link Detail" }
649  ]
650  }).data('kendoGrid');
651 
652 
653 
654  /* ***************************
655  * **** KENDO.SORTABLE ****
656  *************************** */
657 
658  $('#menu-grid').kendoSortable({
659  filterDONOTUSE: "tbody>tr.local-tr-grab",
660  filter: "tbody>tr",
661  cursor: "move",
662  hint: function(e) {
663  var itemType = 'D'; // Default to normal type
664  var itemHint = '';
665  try {
666  var dataItem = menuItemGrid.dataSource.getByUid(e[0].dataset.uid);
667  if (dataItem.MenuItemType !== undefined) {
668  itemType = dataItem.MenuItemType;
669  }
670 
671  } catch (err) {
672  // graceful catch to any issue
673  }
674 
675  // * Based on Type Different String
676  switch (itemType) {
677  case 'H':
678  itemHint = "Menu Group";
679  break;
680  case 'S':
681  itemHint = "Top Link";
682  break;
683  default:
684  itemHint = "Link";
685  break;
686 
687  }
688  itemHint = "<span style='font-weight: 700; color: blue;margin-right :20px;'>" + itemHint + "</span>";
689 
690  return $("<span></span>")
691  .html(itemHint + " <i class='fa fa-ellipsis-v'></i>&nbsp;&nbsp;" + $(e).children('td')[2].innerHTML)
692  .css("color", "rgba(0, 0, 0, .8)")
693  .css('margin-left', '-60px');
694 
695  },
696  placeholder: function(element) {
697  return element.clone().css({
698  "opacity": 0.3,
699  "border": "1px dashed #000000"
700  });
701  },
702  start: function(e) {
703 
704  // ** IF a filter is currently applied to the grid, then
705  // do NOT allow them to reorder
706 
707  var dataItem = menuItemGrid.dataSource.getByUid(e.item.data("uid"));
708 
709  // ** Do NOT allow 'Add Item' columns from being moved
710  if (dataItem.MenuItemId === -9999 || dsFeatureMenu.filter() !== undefined) {
711  e.preventDefault();
712  }
713  },
714  move: function(e) {
715 
716  },
717  end: function(e) {
718  try {
719  var alterIdx,
720  menuView = dsFeatureMenu.view(),
721  childDataItem,
722  childIdxStart,
723  childIdxEnd,
724  childLoopIdx,
725  oldIndex = e.oldIndex,
726  newIndex = e.newIndex,
727  data = menuItemGrid.dataSource.data(),
728  dataItem = menuItemGrid.dataSource.getByUid(e.item.data("uid"));
729 
730  var moveParentId = dataItem.MenuItemId;
731 
732 
733  /**
734  *
735  * Current Grid View has NOT been updated
736  * oldIndex is still the position withing the view the item existed before move
737  *
738  */
739 
740  if (dataItem.ParentId === null && dataItem.MenuItemType === 'H') {
741 
742  /**
743  * **** MOVE VALIDATION ****
744  * CAN PARENT MOVE HERE?
745  */
746  /* ** Next Item Must Be Parent ** */
747  /* ** May not move to the last item in the list ** */
748  if (newIndex === (menuView.length - 1)) {
749  e.preventDefault();
750  return;
751  } else {
752  // * get the next item in the list
753  if (oldIndex < newIndex) {
754  // * *moving down menu
755  childDataItem = menuView[newIndex + 1];
756  } else {
757  // * move up menu
758  childDataItem = menuView[newIndex ];
759  }
760 
761  if (childDataItem.ParentId !== null) {
762  e.preventDefault();
763  return;
764  }
765 
766  }
767 
768 
769  // ** GO to the oldIndex location
770  for (childLoopIdx = oldIndex + 1; oldIndex < menuView.length - 1; childLoopIdx++) {
771  // ** Loop until the parentId doesn't match the children
772  childDataItem = menuView[childLoopIdx];
773 
774  if (childIdxStart === undefined && childDataItem.ParentId === moveParentId) {
775  // * We have a child of the item being moved and we have NOT yet set the childStart Index
776  childIdxStart = childLoopIdx; // SET The childLoopIdx
777  } else if (childDataItem.ParentId !== moveParentId) {
778  // ** Parent Id no longer matches.. So break from loop
779  break;
780  }
781 
782  }
783  if (childIdxStart !== undefined) {
784  // * started the child List.
785  // * REcord the end, which would be the last childLoopIdx - 1
786  childIdxEnd = childLoopIdx - 1;
787  }
788 
789  // ** We now have the view list of children
790  if (oldIndex < newIndex) {
791  /* ** DOWN MENU ** */
792 
793  // * In reverse order these will be placed starting at the newIndex, then decrement
794  for ( childLoopIdx = childIdxEnd; childLoopIdx >= childIdxStart; childLoopIdx--) {
795  // Move these items to the newIndex
796  childDataItem = menuView[childLoopIdx];
797  alterIdx = newIndex - (childIdxEnd - childLoopIdx);
798 
799  childDataItem.GridOrder = alterIdx;
800  childDataItem.dirty = true;
801 
802  }
803  // Set the moved parent item
804  dataItem.GridOrder = newIndex - (childIdxEnd - childIdxStart) - 1;
805 
806  // ** Now I need to cleanup ANY items between dataItem.GridOrder and oldIndex
807 
808  var lastMoveChild = oldIndex + (childIdxEnd - childIdxStart + 1);
809  for (childLoopIdx = newIndex; childLoopIdx > lastMoveChild; childLoopIdx--) {
810  childDataItem = menuView[childLoopIdx];
811  alterIdx = childLoopIdx - (childIdxEnd - childIdxStart);
812  // ** + 1 to account for the zero based array
813  childDataItem.GridOrder = childDataItem.GridOrder - (newIndex - dataItem.GridOrder + 1);
814  childDataItem.dirty = true;
815  }
816 
817 
818 
819  } else {
820  /* ** UP MENU ** */
821  // ** The item is being moved up the menu
822  for (childLoopIdx = childIdxStart; childLoopIdx <= childIdxEnd; childLoopIdx++) {
823  childDataItem = menuView[childLoopIdx];
824  alterIdx = newIndex + (childLoopIdx - childIdxStart) + 1;
825 
826  childDataItem.GridOrder = alterIdx;
827  childDataItem.dirty = true;
828  }
829  // The main item moves to the index specified (no alterations)
830  dataItem.GridOrder = newIndex;
831 
832 
833  var alterListEnd = oldIndex + (childIdxEnd - childIdxStart) + 1;
834  alterListEnd = (alterListEnd > menuView.length - 1 ? menuView.length - 1: alterListEnd);
835  alterListEnd = oldIndex;
836  // ** Clean up ordering from the end of the newly moved children to the end of the view
837  for (childLoopIdx = newIndex; childLoopIdx < alterListEnd; childLoopIdx++) {
838  // ** We have wo different calculations
839  childDataItem = menuView[childLoopIdx];
840  // * From the newIndex to start of oldIndex + children
841  // Move these up the list to fill the vacuum
842  alterIdx = (childIdxEnd - childIdxStart) + 2;
843  childDataItem.GridOrder = childDataItem.GridOrder + alterIdx;
844  childDataItem.dirty = true;
845  // * From oldIndex to the end of the loop is a v
846 
847  // * From the End of the freshly moved Items, before the start of the oldIndex
848  // ** These simply move the amount
849  // * And those
850 
851  }
852 
853 
854 
855  }
856 
857  } else if (dataItem.ParentId === null && dataItem.MenuItemType === 'S') {
858  /* ** MOVE A MENU LINK ** */
859 
860  /**
861  * **** MOVE VALIDATION ****
862  * CAN MENU LINK MOVE HERE?
863  */
864  /* ** Next Item Must Be Parent ** */
865  /* ** May not move to the last item in the list ** */
866  if (newIndex === (menuView.length - 1)) {
867  e.preventDefault();
868  return;
869  } else {
870  // * get the next item in the list
871  if (oldIndex < newIndex) {
872  // * *moving down menu
873  childDataItem = menuView[newIndex + 1];
874  } else {
875  // * move up menu
876  childDataItem = menuView[newIndex ];
877  }
878 
879  if (childDataItem.ParentId !== null) {
880  e.preventDefault();
881  return;
882  }
883 
884  }
885 
886  /* REORDER THE GRID */
887  /* ** CONTINUE MOVING THE CHILD ** */
888  dataItem.GridOrder = newIndex;
889  dataItem.dirty = true;
890 
891  if (newIndex > oldIndex) {
892  // * Renumber the GridOrder
893  for (childLoopIdx = newIndex; childLoopIdx > oldIndex; childLoopIdx--) {
894  childDataItem = menuView[childLoopIdx];
895  childDataItem.GridOrder = childDataItem.GridOrder - 1;
896  childDataItem.dirty = true;
897  }
898  } else {
899  // * Renumber the GridOrder
900  for (childLoopIdx = newIndex; childLoopIdx < oldIndex; childLoopIdx++) {
901  childDataItem = menuView[childLoopIdx];
902  childDataItem.GridOrder = childDataItem.GridOrder + 1;
903  childDataItem.dirty = true;
904  }
905 
906  }
907 
908  } else {
909  /* ** MOVE A CHILD ** */
910  /* ** It may only move where the next item is a child ** */
911  var groupParentId;
912  if (newIndex === (menuView.length - 1)) {
913  e.preventDefault();
914  return;
915  } else {
916  // * get the next item in the list
917  if (oldIndex < newIndex) {
918  // * *moving down menu
919  childDataItem = menuView[newIndex + 1];
920  } else {
921  // * move up menu
922  childDataItem = menuView[newIndex ];
923  }
924 
925  if (childDataItem.ParentId === null) {
926  e.preventDefault();
927  return;
928  } else {
929  // This should be the desired group
930  groupParentId = childDataItem.ParentId;
931  }
932 
933  }
934 
935  /* ** CONTINUE MOVING THE CHILD ** */
936  dataItem.GridOrder = newIndex;
937  dataItem.ParentId = groupParentId;
938  dataItem.dirty = true;
939 
940  if (newIndex > oldIndex) {
941  // * Renumber the GridOrder
942  for (childLoopIdx = newIndex; childLoopIdx > oldIndex; childLoopIdx--) {
943  childDataItem = menuView[childLoopIdx];
944  childDataItem.GridOrder = childDataItem.GridOrder - 1;
945  childDataItem.dirty = true;
946  }
947  } else {
948  // * Renumber the GridOrder
949  for (childLoopIdx = newIndex; childLoopIdx < oldIndex; childLoopIdx++) {
950  childDataItem = menuView[childLoopIdx];
951  childDataItem.GridOrder = childDataItem.GridOrder + 1;
952  childDataItem.dirty = true;
953  }
954 
955  }
956 
957 
958  }
959 
960  menuItemGrid.dataSource.sort({field:"GridOrder", dir: "asc"});
961 
962  menuItemGrid.refresh();
963 
964  RenumberDisplayOrder();
965  menuItemGrid.refresh();
966 
967  } catch (err) {
968  // * *Something went wrong cancel the move
969  e.preventDefault();
970  kendo.alert(err, 'Unable to complete request');
971  }
972  }
973 
974  });
975 
976  /* ***************************
977  * **** KENDO.OBSERVABLE ****
978  *************************** */
979  editMenuItem = kendo.observable({
980 
981  localdsIcons: dsIcons,
982  localdataSettingsLang: dataSettingsLang,
983  localdsFeatureList: dsFeatureList,
984  localdsScriptList: dsScriptList,
985  sourceMenu: dsFeatureMenu,
986 
987  sourceItem: null,
988  data: null,
989 
990  updateBtnText: null,
991  checkMenuGroupItem: false,
992 
993  setSelectedItem: function(newSelectedItem) {
994  // ** Create a clone of the data row and use this for the changes
995  var cloneItem = JSON.parse(JSON.stringify(newSelectedItem));
996 
997  this.set('sourceMenu', dsFeatureMenu);
998 
999  this.set('sourceItem', newSelectedItem);
1000  this.set('data', cloneItem);
1001  /* Refresh Globals */
1002  this.set('localdataSettingsLang', dataSettingsLang);
1003 
1004  // * *Set attributes based on the selected Record
1005  this.set('isUpdate', (newSelectedItem.MenuItemId > 0));
1006  this.set('hasChanges', false);
1007  this._UpdateBtnText();
1008 
1009  this.setShowIcon();
1010 
1011  if ($('#menu-platforms').val() == 'D' || $('#menu-platforms').val() == 'M') {
1012  $('#lnkDelete').hide();
1013  } else {
1014  $('#lnkDelete').show();
1015  }
1016 
1017  // enable message checkbox if new window is checked
1018  if (newSelectedItem.details_target === 1) {
1019  $('#detailsExtMsg').removeAttr("disabled");
1020  } else {
1021  $('#detailsExtMsg').attr("disabled", true);
1022  }
1023  },
1024 
1025  _UpdateBtnText: function () {
1026  retHtml = '<span class="fa fa-check"></span>&nbsp;Update';
1027 
1028  this.set('updateBtnText', retHtml);
1029  },
1030  change: function() {
1031  this.set('hasChanges', true);
1032  this._UpdateBtnText();
1033 
1034  if (this.hasChanges) {
1035 
1036  }
1037  },
1038  changeIcon: function() {
1039 
1040  this.setShowIcon();
1041  this.change();
1042  },
1043  hasChanges: false,
1044  isUpdate: false,
1045  isNew: function() {
1046  return !this.isUpdate;
1047  },
1048 
1049  /* ** METHODS ** */
1050  ShowLang: function(langCodes) {
1051 
1052  switch (langCodes) {
1053  case "en_US":
1054  return true;
1055  case "es_US":
1056  return this.localdataSettingsLang.es_US;
1057  case "pl_US":
1058  return this.localdataSettingsLang.pl_US;
1059  default:
1060  return false;
1061  }
1062  },
1063 
1064  setShowIcon: function() {
1065  $('#showIcon').removeClass();
1066 
1067  $('#showIcon').addClass('fa');
1068  $('#showIcon').addClass('fa-' + this.data.details_fa_icon);
1069  $('#showIcon').addClass('fa-2x');
1070 
1071  },
1072  /* ** EVENTS ** */
1073 
1074  MenuType: function() {
1075  var showSection = (this.data.MenuItemType === 'S');
1076  if (showSection) {
1077  $('#detailsUrlSetup').show();
1078  } else {
1079  $('#detailsUrlSetup').hide();
1080  }
1081  this.change();
1082 
1083  },
1084 
1085  CloseMe() {
1086  // ** This will close the currently opened window
1087 
1088  // REVERT Form Status back to main FORM
1089  $.homecuValidator.setup({formStatusField: 'formStatus'});
1090 
1091  windowTemplate.close();
1092  },
1093  itemSave: function(e) {
1094  e.preventDefault();
1095 
1096  var errors = [];
1097  var itemIdx,
1098  addIdx;
1099 
1100  if (!this.hasChanges) {
1101  //windowTemplate.close();
1102  this.CloseMe();
1103  return;
1104  }
1105  /* CUSTOM VALIDATION
1106  errors[errors.length] = 'new error';
1107  */
1108 
1109  // VALIDATE FORM ELEMENTS
1110  if ($.homecuValidator.homecuValidate) {
1111 
1112  // SHOW ANY ERRORS
1113  if (errors.length > 0) {
1114 
1115  // ERROR FOUND FOR BAD TRANSACTIONS
1116  $.homecuValidator.homecuResetMessage = $.homecuValidator.homecuValidate;
1117  $.homecuValidator.displayMessage(errors, $.homecuValidator.settings.statusError);
1118  $.homecuValidator.homecuResetMessage = true;
1119  $.homecuValidator.homecuValidate = false;
1120  } else {
1121 
1122 
1123 
1124  // NO ERROR, SAVE TO DATASOURCE
1125  this.sourceItem.details_platform_dsk = this.data.details_platform_dsk;
1126  this.sourceItem.details_platform_mbl = this.data.details_platform_mbl;
1127  this.sourceItem.details_platform_app = this.data.details_platform_app;
1128 
1129  this.sourceItem.details_collapse_group = this.data.details_collapse_group;
1130 
1131  // Move values from local to datasource
1132  this.sourceItem.details_display_en_US = this.data.details_display_en_US;
1133  if (this.data.details_display_es_US) {
1134  this.sourceItem.details_display_es_US = this.data.details_display_es_US;
1135  }
1136  if (this.data.details_display_pl_US) {
1137  this.sourceItem.details_display_pl_US = this.data.details_display_pl_US;
1138  }
1139  this.sourceItem.FeatureCode = this.data.FeatureCode;
1140  this.sourceItem.details_target = (this.data.details_target ? 1 : 0);
1141  this.sourceItem.details_message = (this.data.details_message ? 1 : 0);
1142  // Where to grab the screenname??
1143  // **
1144  this.sourceItem.details_href = this.data.details_href;
1145 
1146  this.sourceItem.details_hrefUrlQuery = (this.data.details_hrefUrlQuery ? 1 : 0);
1147  this.sourceItem.details_hrefExtraParam = this.data.details_hrefExtraParam;
1148  this.sourceItem.details_fa_icon = this.data.details_fa_icon;
1149 
1150  this.sourceItem.details_memacct_filter = this.data.details_memacct_filter;
1151 
1152  this.sourceItem.dirty = true;
1153  ShowActionButton();
1154 
1155  menuItemGrid.refresh();
1156 
1157  this.CloseMe();
1158  }
1159  }
1160  },
1161  itemCancel: function(e) {
1162  e.preventDefault();
1163 
1164  if (this.hasChanges) {
1165  // Need to as the user if they
1166 
1167 
1168  var cancelMsg = "Changes have been made to the menu item.</br>Do you wish to discard your changes?";
1169  actionDialog = $("<div id='confirmDialog'></div>")
1170  .appendTo("body")
1171  .kendoDialog({
1172  content: cancelMsg,
1173  title: "Discard Changes?",
1174  close: function(e) {
1175  window_stack.pop();
1176  },
1177  actions: [{
1178  text: "No",
1179  action: function(e) {
1180  // ** Close the current dialog
1181  }
1182  }, {
1183  text: "Yes",
1184  primary: true,
1185  action: function(e) {
1186  /* ** DISCARD CHANGES ** */
1187  /* ** Perform a grid refresh, but I have not changed the row yet, it's all in the clone right now ** */
1188  // * *Need to
1189  menuItemGrid.refresh();
1190 
1191  // windowTemplate.close();
1192  editMenuItem.CloseMe();
1193  }
1194  }]
1195  }).data("kendoDialog");
1196 
1197 
1198  window_stack.push(function(e) {
1199  actionDialog.close(e);
1200  });
1201 
1202  } else {
1203  // ** NO changes.. Close window
1204  // windowTemplate.close();
1205  this.CloseMe();
1206  }
1207 
1208  },
1209  itemDelete: function(e) {
1210  e.preventDefault();
1211 
1212  var deleteMsg;
1213  if (this.data.MenuItemType === 'H') {
1214  deleteMsg = "Deleting this menu group will also delete all links in the group.<br/>Are you sure you wish to continue?";
1215  } else {
1216  deleteMsg = "Deleting this menu item can not be undone.<br/>Are you sure you wish to continue?";
1217  }
1218 
1219 
1220 
1221 
1222  actionDialog = $("<div id='confirmDialog'></div>")
1223  .appendTo("body")
1224  .kendoDialog({
1225  content: deleteMsg,
1226  title: "Delete Menu Option?",
1227  open: function() {
1228  },
1229  close: function(e) {
1230  window_stack.pop();
1231  },
1232  actions: [{
1233  text: "No",
1234  action: function(e) {
1235  /* ** NO ACTION NEEDED ** */
1236 
1237  }
1238  }, {
1239  text: "Yes",
1240  primary: true,
1241  action: function(e) {
1242  /* ** DELETE RECORD ** */
1243 
1244  var childLoopIdx,
1245  childId = editMenuItem.data.GridOrder,
1246  childItemCount=0,
1247  removeParentId = editMenuItem.data.MenuItemId,
1248  childDataItem;
1249 
1250  /* ** DELETE MENU ITEM / GROUP ** */
1251  if (editMenuItem.data.MenuItemType === 'H') {
1252  /* DELETE PARENT AND CHILDREN */
1253 
1254  //for (childLoopIdx = childId + 1; childLoopIdx < dsFeatureMenu.view().length; childLoopIdx++) {
1255  for (childLoopIdx = dsFeatureMenu.view().length - 1; childLoopIdx >= childId; childLoopIdx--) {
1256  childDataItem = dsFeatureMenu.view()[childLoopIdx];
1257  if (childDataItem.ParentId === removeParentId || childDataItem.MenuItemId === removeParentId) {
1258  // ** Remove if parent Id matches
1259  dsFeatureMenu.remove(childDataItem);
1260  childItemCount++;
1261  }
1262  }
1263 
1264  } else {
1265  /* DELETE THIS ROW ONLY */
1266  childItemCount = 1;
1267 
1268  dsFeatureMenu.remove(editMenuItem.sourceItem);
1269 
1270  }
1271 
1272  for (childLoopIdx = childId; childLoopIdx < dsFeatureMenu.view().length; childLoopIdx++) {
1273  childDataItem = dsFeatureMenu.view()[childLoopIdx];
1274  childDataItem.GridOrder = childDataItem.GridOrder - childItemCount;
1275  childDataItem.DisplayOrder = (childDataItem.DisplayOrder === null ? childDataItem.DisplayOrder : childDataItem.DisplayOrder - childItemCount);
1276  childDataItem.dirty = true;
1277  }
1278 
1279 
1280  menuItemGrid.refresh();
1281 
1282  // windowTemplate.close();
1283  editMenuItem.CloseMe();
1284 
1285  // REVERT Form Status back to main FORM
1286  $.homecuValidator.setup({formStatusField: 'formStatus'});
1287 
1288 
1289  }
1290  }]
1291  }).data('kendoDialog');
1292  window_stack.push(function(e) {
1293  actionDialog.close(e);
1294  });
1295 
1296  },
1297  showEditForm: function() {
1298  OpenEditWindow();
1299  }
1300  });
1301 
1302 
1303  $("#menu-platforms").kendoDropDownList({
1304  dataSource: dsPlatforms,
1305  dataTextField: 'display',
1306  dataValueField: 'code',
1307  change: function(e) {
1308  // * Modify the filter for the grid
1309  var curValue = this.value();
1310  switch (curValue) {
1311  case "D":
1312  dsFeatureMenu.filter({field: 'details_platform_dsk', operator: 'eq', value: true});
1313  $('#local-menu-readonly').show();
1314  break;
1315  case "M":
1316  dsFeatureMenu.filter({field: 'details_platform_mbl', operator: 'eq', value: true});
1317  $('#local-menu-readonly').show();
1318  break;
1319  case "A":
1320  dsFeatureMenu.filter({field: 'details_platform_app', operator: 'eq', value: true});
1321  $('#local-menu-readonly').show();
1322  break;
1323  default:
1324  dsFeatureMenu.filter({});
1325  $('#local-menu-readonly').hide();
1326  }
1327  }
1328  });
1329 
1330  $('#x-featureList').kendoDropDownList({
1331  dataSource: dsFeatureList,
1332  dataTextField: 'description',
1333  dataValueField: 'featurecode',
1334  optionLabel: 'Select Related Feature...'
1335  });
1336  $('#x-scriptList').kendoComboBox({
1337  dataSource: dsScriptList,
1338  dataTextField: 'screenname',
1339  dataValueField: 'screenname',
1340  template: '<span class="k-state-default">#: data.description #</span>',
1341  });
1342 
1343 
1344  $('#menu-grid').on('click', 'tbody>tr td.local-add-menu-item .local-add-link', function() {
1345  var newUid;
1346  newUid = AddNewMenuItem(0, null, null);
1347 
1348  if (newUid !== undefined) {
1349  ShowEditDialog(newUid);
1350  }
1351  });
1352  $('#menu-grid').on('click', 'tbody>tr td.local-add-menu-item .local-add-group', function() {
1353  var newUid;
1354 
1355  newUid = AddNewMenuItem(2, null, null);
1356 
1357  if (newUid !== undefined) {
1358  ShowEditDialog(newUid);
1359  }
1360  });
1361 
1362  $('#menu-grid').on('click', 'tbody>tr td.local-add-item', function() {
1363  var dataUid = $(this).parent().data('uid'),
1364  dataItem = dsFeatureMenu.getByUid(dataUid),
1365  newUid;
1366 
1367  newUid = AddNewMenuItem(1, dataItem.GridOrder, dataItem.ParentId);
1368 
1369 
1370  if (newUid !== undefined) {
1371  ShowEditDialog(newUid);
1372  }
1373 
1374  });
1375  $('#menu-grid').on('dblclick', 'tbody>tr.local-tr-grab td:nth-child(1n+2)', function(e) {
1376 
1377 
1378  e.preventDefault();
1379  var dataUid = $(this).parent().data('uid');
1380 
1381  ShowEditDialog(dataUid);
1382  });
1383 
1384 
1385 
1386  editTemplate = kendo.template($('#edit-detail-row').html());
1387 
1388  windowTemplate = $('#windowTemplate').kendoWindow({
1389  title: 'Edit Menu',
1390  modal: true,
1391  visible: false,
1392  resizable: false,
1393  width: 400,
1394  actions: [],
1395  close: function() {
1396  // * pop the top,
1397  window_stack.pop();
1398  }
1399  }).data('kendoWindow');
1400 
1401 
1402 
1403  /* *** READ SETTINGS *** */
1404  dsSettings.fetch(function() {
1405  /* CASCADED LOADING OF DATA SOURCES */
1406 
1407  dsFeatureMenu.dataLoading = true;
1408  /* *** READ MENU DATASOURCE *** */
1409  dsFeatureMenu.fetch(function () {
1410  if (CheckDirtyFlag()) {
1411  ShowActionButton();
1412  }
1413  dsFeatureMenu.dataLoading = false;
1414  });
1415  });
1416 
1417  $.homecuValidator.setup({formStatusField: 'formStatus'});
1418 
1419 
1420  // enable message if Open In New Window is checked
1421  $('#detailsNewWin').change(function() {
1422  if (this.checked) {
1423  $('#detailsExtMsg').removeAttr("disabled");
1424  } else {
1425  $('#detailsExtMsg').attr("disabled", true);
1426  $('#detailsExtMsg').prop("checked", false);
1427  $('#detailsExtMsg').trigger("change");
1428  }
1429  });
1430 
1431 
1432  }); /* document.ready */
1433 
1434  /* Handling of user clicking on overlay, which should close active window */
1435  $(document).on("click", ".k-overlay", function (e) {
1436  if(window_stack.length > 0) {
1437  // ** Return anon func of last item, but keep intact -- dialog close should pop()
1438  fN = window_stack[window_stack.length - 1];
1439  var ret = fN(e);
1440  }
1441  });
1442 
1443 
1444  function ShowEditDialog(dataUid) {
1445  // Using the uid passed in, load the edit window
1446 
1447  var dataItem = dsFeatureMenu.getByUid(dataUid);
1448 
1449  editMenuItem.setSelectedItem(dataItem);
1450  OpenEditWindow();
1451 
1452  }
1453 
1454 
1455  /**
1456  *
1457  * @param menuType - Is this a Group Menu or Child Item
1458  * @param GridOrder - What view index should this replace? (not needed for Group Menu item)
1459  * @param menuParentId - What is the ParentId to assign (not needed for Group Menu item)
1460  */
1461  function AddNewMenuItem(menuType, GridOrder, menuParentId) {
1462  // ** This will add a new row to the datasource
1463  // It will also pop-up the editor window
1464  var newGridOrder,
1465  newDisplayOrder,
1466  newItemType,
1467  newIcon,
1468  newDefaultRow,
1469  addOnly=false,
1470  newUid;
1471  if (menuType === 0) {
1472  // This is a new item to an existing MENU GROUP
1473  //
1474  newItemType = 'S'; // Default to stand-alone, user can select Group in options
1475  // ** Added to the end of the list
1476  newGridOrder = dsFeatureMenu.view().length - 1;
1477 
1478  // * Need the Last Display Order value in the view..
1479  newDisplayOrder = FetchLastDisplayOrder() + 1;
1480  newIcon = 'anchor';
1481  } else if (menuType === 2) {
1482  // This is a new item to an existing MENU GROUP
1483  //
1484  newItemType = 'H'; // Default to stand-alone, user can select Group in options
1485  // ** Added to the end of the list
1486  newGridOrder = dsFeatureMenu.view().length - 1;
1487 
1488  // * Need the Last Display Order value in the view..
1489  newDisplayOrder = FetchLastDisplayOrder() + 1;
1490  newIcon = 'sitemap';
1491 
1492 
1493  } else if (menuType === 3) {
1494  // ** Add Item option for the group
1495  addOnly = true;
1496 
1497  newGridOrder = GridOrder;
1498 
1499  } else {
1500  // This is a new menu item added to the end of the list
1501  newItemType = 'D';
1502 
1503  newGridOrder = GridOrder;
1504 
1505  newDisplayOrder = dsFeatureMenu.view()[GridOrder-1].DisplayOrder + 1;
1506  newIcon = '';
1507  }
1508 
1509 
1510  if (menuType === 3) {
1511  newDefaultRow = {GridOrder : newGridOrder, DisplayOrder: null, MenuItemId : -9999, ParentId : menuParentId};
1512  } else {
1513  var defaultDisplay;
1514  switch (newItemType) {
1515  case 'H':
1516  defaultDisplay = 'New Menu Group';
1517  break;
1518  case 'S':
1519  defaultDisplay = 'New Menu Item';
1520  break;
1521  default:
1522  defaultDisplay = 'New Child Item';
1523  }
1524  newDefaultRow = {GridOrder : newGridOrder,
1525  MenuItemId : dsFeatureMenu.options.newItemId--,
1526  ParentId : menuParentId,
1527  Cu : '<?php echo $importValues['cu']; ?>',
1528  DisplayOrder : newDisplayOrder,
1529  FeatureCode : '',
1530  MenuItemType : newItemType,
1531  details_platform_dsk: true,
1532  details_platform_mbl: true,
1533  details_platform_app: false,
1534  details_collapse_group: false,
1535  MenuItemPlatform : ["M","D"],
1536  details_display_en_US : defaultDisplay,
1537  details_display_es_US : '',
1538  details_display_pl_US : '',
1539  details_fa_icon: newIcon,
1540  details_href : '',
1541  details_hrefUrlQuery : 0,
1542  details_target : 0,
1543  details_message : 0,
1544  details_hrefExtraParam: ''
1545  };
1546  }
1547 
1548 
1549  // ** I need to reorder all the GridOrder Columns
1550  var childLoopIdx,
1551  childDataItem;
1552  for (childLoopIdx = newGridOrder; childLoopIdx < dsFeatureMenu.view().length; childLoopIdx++) {
1553  childDataItem = dsFeatureMenu.view()[childLoopIdx];
1554  childDataItem.GridOrder = childDataItem.GridOrder + 1;
1555  childDataItem.DisplayOrder = (childDataItem.DisplayOrder === null ? childDataItem.DisplayOrder : childDataItem.DisplayOrder + 1);
1556  childDataItem.dirty = true;
1557  }
1558 
1559  // Grid is now ready for new row.
1560  menuItemGrid.dataSource.add(newDefaultRow).set('dirty', true);
1561 
1562  // * last item is the uid
1563  if (menuItemGrid.dataSource.data()[menuItemGrid.dataSource.data().length - 1].uid) {
1564  newUid = menuItemGrid.dataSource.data()[menuItemGrid.dataSource.data().length - 1].uid;
1565  }
1566  // ** Set the dirty flag
1567 
1568  // ** Add child Item for Parent Group
1569  if (menuType === 2) {
1570  AddNewMenuItem(3, newGridOrder + 1, newDefaultRow.MenuItemId);
1571  }
1572 
1573  if (!addOnly) {
1574 
1575  menuItemGrid.refresh();
1576  }
1577 
1578  return newUid;
1579  }
1580 
1581  function FetchLastDisplayOrder() {
1582  var retLast = 0;
1583  for (var idx = dsFeatureMenu.view().length -1; idx >= 0; idx--) {
1584  if (dsFeatureMenu.view()[idx].DisplayOrder !== null) {
1585  // * FOund a value -- return it
1586  return dsFeatureMenu.view()[idx].DisplayOrder;
1587  }
1588  }
1589 
1590  return retLast;
1591  }
1592 
1593  function DisplayUrlDetails(showSection) {
1594  if (showSection) {
1595  $('#detailsUrlSetup').show();
1596  } else {
1597  $('#detailsUrlSetup').hide();
1598  }
1599  }
1600 
1601 
1602  function OpenEditWindow() {
1603 
1604  $.homecuValidator.settings.formStatusField = "formStatus";
1605  $.homecuValidator.hideMessage();
1606  $.homecuValidator.setup({formValidate: "form-edit-template",
1607  validateOnClick: 'btnUpdate',
1608  formErrorTitle: "Fix the following item(s):",
1609  formStatusField: "editErrors",
1610  homecuCustomRules: {
1611  memfilter: function(input) {
1612  if (!$(input).is("[name='acctFilter']"))
1613  return true;
1614 
1615  var value= $(input).val().trim();
1616  if (value == "")
1617  return true; <?php // Blank is a valid option. ?>
1618 
1619  if (!value.match(/^\S*$/)) <?php // Allowing any name separated by commas. No spaces. ?>
1620  return false;
1621 
1622  return true;
1623  }
1624  }});
1625 
1626  kendo.bind($('#windowTemplate'), editMenuItem);
1627 
1628  windowTemplate.center().open();
1629 
1630  window_stack.push(function(e) {
1631  editMenuItem.itemCancel(e);
1632  });
1633  }
1634  function GetFeatureDesc(pFeatureCode) {
1635  // ** Lookup the value from the dataSettingsFeature
1636  var retFeatureDesc = pFeatureCode;
1637 
1638  $.each(dataSettingsFeatures, function(idx, record) {
1639  if (record.featurecode === pFeatureCode) {
1640  retFeatureDesc = record.description;
1641  return false;
1642  }
1643  });
1644 
1645  return retFeatureDesc;
1646  }
1647  function SetLangOptions() {
1648 
1649  $.each(dataSettingsLang, function(key, value) {
1650 
1651  if ($('#flag_link_' + key)) {
1652  $('#flag_link_' + key).show();
1653  }
1654  });
1655  }
1656  function FilterLanguage(pLangCode) {
1657  // **
1658  // ** Remove class from other options
1659  $.each($('.local-table-flags .flag_icons'), function() {
1660  $(this).removeClass('active');
1661  });
1662  // *set active flag for curren item
1663  $('.flag_icons_' + pLangCode).addClass('active');
1664 
1665  displayLangCode = pLangCode;
1666 
1667  menuItemGrid.refresh();
1668  }
1669 
1670  function SaveMenu() {
1671  /* **** SAVE MENU **** */
1672  dsFeatureMenu.dataLoading = true;
1673  dsFeatureMenu.sync();
1674  }
1675 
1676  function RenumberDisplayOrder() {
1677 
1678  var lastDisplayOrder = 0;
1679  for (var childLoopIdx = 0; childLoopIdx < dsFeatureMenu.view().length; childLoopIdx++) {
1680  childDataItem = dsFeatureMenu.view()[childLoopIdx];
1681 
1682  if (childDataItem.MenuItemId !== -9999) {
1683  lastDisplayOrder++; // Increment for each viewable option
1684  if (childDataItem.DisplayOrder !== lastDisplayOrder) {
1685  // ** Different -- set it now
1686  childDataItem.DisplayOrder = lastDisplayOrder;
1687  childDataItem.dirty = true;
1688  }
1689  }
1690  }
1691  }
1692 
1693  function ShowWaitWindow(pMsg) {
1694  // * pMsg - Not used at moment. ONLY Spinning icon will be seen, no text
1695  if (!submitWaitWindow) {
1696  $('#localSubmitWait').kendoWindow({
1697  title: false,
1698  resizable: false,
1699  modal: true,
1700  draggable: false,
1701  actions: [],
1702  height:55,
1703  minHeight:55,
1704  width:54,
1705  minWidth:54
1706  });
1707  submitWaitWindow = $("#localSubmitWait").data('kendoWindow');
1708 
1709  }
1710  submitWaitWindow.center().open();
1711  }
1712  function CloseWaitWindow() {
1713  if (submitWaitWindow) {
1714  submitWaitWindow.close();
1715  }
1716  }
1717  function CancelMenuChanges() {
1718  // ** Do we cancel all the changes to the menu??
1719  var cancelMsg = "Changes have been made to the menu layout.</br>Do you wish to discard your changes?";
1720  actionDialog = $("<div id='confirmDialog'></div>")
1721  .appendTo("body")
1722  .kendoDialog({
1723  content: cancelMsg,
1724  title: "Discard Changes?",
1725  close: function(e) {
1726  window_stack.pop();
1727  },
1728  actions: [{
1729  text: "No",
1730  action: function(e) {
1731  // ** Close the current dialog
1732  }
1733  }, {
1734  text: "Yes",
1735  primary: true,
1736  action: function(e) {
1737  /* ** DISCARD CHANGES ** */
1738  dsFeatureMenu.cancelChanges();
1739  // * *Need to
1740  menuItemGrid.refresh();
1741  HideActionButton();
1742  }
1743  }]
1744  }).data('kendoDialog');
1745  window_stack.push(function(e) {
1746  actionDialog.close(e);
1747  });
1748 
1749  }
1750  function CheckDirtyFlag() {
1751  var dirtFound = false;
1752  // ** If MenuItemId < 0, then this record is dirty
1753  for (var childLoopIdx = 0; childLoopIdx < dsFeatureMenu.view().length; childLoopIdx++) {
1754  childDataItem = dsFeatureMenu.view()[childLoopIdx];
1755 
1756  if (childDataItem.MenuItemId < 0 && childDataItem.MenuItemId !== -9999) {
1757  childDataItem.dirty = true;
1758  dirtFound = true;
1759  }
1760  }
1761  // ** Did this function find dirty data?
1762  return dirtFound;
1763  }
1764  function UpdateRecordId(pIdList) {
1765 
1766  if (pIdList instanceof Object) {
1767 
1768  // ** This function will update EACH Data Item from the data source
1769  for (var childLoopIdx = 0; childLoopIdx < dsFeatureMenu.view().length; childLoopIdx++) {
1770  childDataItem = dsFeatureMenu.view()[childLoopIdx];
1771 
1772  if (pIdList[childDataItem.MenuItemId]) {
1773  // ** Found -- set to new value
1774  childDataItem.MenuItemId = pIdList[childDataItem.MenuItemId];
1775  }
1776  if (pIdList[childDataItem.ParentId]) {
1777  // ** Found -- set to new value
1778  childDataItem.ParentId = pIdList[childDataItem.ParentId];
1779  }
1780  childDataItem.dirty = false;
1781  }
1782 
1783 
1784  }
1785 
1786  }
1787  function ClearErrorMsgs() {
1788  var $dispMsgField = $('#local-error');
1789 
1790  $('#local-error-text').html('');
1791 
1792  $dispMsgField.hide();
1793  }
1794  function ShowActionButton() {
1795  menuDirty = true;
1796  $('.local-menu-action').addClass('local-show');
1797  }
1798  function HideActionButton() {
1799  menuDirty = false;
1800  $('.local-menu-action').removeClass('local-show');
1801  }
1802  function ShowErrorMsgs(messages) {
1803  // This should accept if pMessage is a simple string
1804  // OR it is an array
1805  var $dispMsgField = $('#local-error');
1806  var objP = $('<p>Please Fix the following issue(s):<br/></p>');
1807  var objUl = $('<ul></ul>');
1808 
1809  if (typeof(messages) === 'string') {
1810  // ** Single Instance of String
1811  if (messages !== '') {
1812  var objLi = $('<li></li>');
1813  objLi.append(messages);
1814  objUl.append(objLi);
1815  }
1816  } else if (messages instanceof Object) {
1817  // ** Object
1818  $.each(messages, function(index, value) {
1819 
1820  if (value !== '') {
1821  var objLi = $('<li></li>');
1822  objLi.append(value);
1823  objUl.append(objLi);
1824  }
1825 
1826  });
1827  } else if (messages instanceof Array) {
1828  // ** Array of messages
1829  $.each(messages, function(index, value) {
1830  if (value !== '') {
1831  var objLi = $('<li></li>');
1832  objLi.append(value);
1833  objUl.append(objLi);
1834  }
1835  });
1836  }
1837 
1838  $('#local-error-text').append(objP);
1839  $('#local-error-text').append(objUl);
1840 
1841  if (objUl.children().length > 0) {
1842  $dispMsgField.show();
1843  }
1844  }
1845 
1846  // When the menu has been changed, we tend to forget to hit the save
1847  // button before leaving the page. Warn the user if the menu has changes
1848  // to save.
1849  window.onbeforeunload = function(e) {
1850 
1851  if (menuDirty) {
1852  return "The menu has not been saved. Are you sure you want to leave the page?";
1853  }
1854  }
1855 
1856  </script>
1857  <script id="header-treelist" type="text/x-kendo-template">
1858  <input id="menu-platforms" />
1859  <span id="local-menu-readonly"><span class="fa fa-ban">&nbsp;&nbsp;Menu Locked</span></span>
1860  <div class="local-table-flags">
1861  <a id="flag_link_en_US" style="display:none;" href="javascript:FilterLanguage('en_US');" title="Display English Text"><div class="flag_icons flag_icons_en_US active"></div></a>
1862  <a id="flag_link_es_US" style="display:none;" href="javascript:FilterLanguage('es_US');" title="Display Spanish Text"><div class="flag_icons flag_icons_es_US"></div></a>
1863  <a id="flag_link_pl_US" style="display:none;" href="javascript:FilterLanguage('pl_US');" title="Display Polish Text"><div class="flag_icons flag_icons_pl_US"></div></a>
1864  </div>
1865  </script>
1866  <script id="href-template" type="text/x-kendo-template">
1867  <span class="k-state-default">#: data.description #</span>
1868  </script>
1869  <script id="menu-row" type="text/x-kendo-template">
1870  <tr class="# if (MenuItemId !== -9999) { # local-tr-grab # } #" data-local-parentid="#: data.ParentId #" data-uid="#: uid #">
1871  # if (data.MenuItemId) { #
1872  # if (MenuItemId === -9999) { #
1873  <td class="local-td-col-1"><!--#: data.GridOrder # : #: data.DisplayOrder #--></td>
1874  # if (ParentId === null) { #
1875  <td role="gridcell" colspan="5" class="local-add-td-row local-add-menu-item" data-local-parentid="root"><span class="local-add-group"><i class="fa fa-plus"></i>&nbsp;New Menu Group</span>&nbsp;&nbsp;<span class="local-add-link"><i class="fa fa-plus"></i>&nbsp;New Menu Link</span></td>
1876  # } else { #
1877  <td role="gridcell" colspan="5" class="local-add-td-row local-add-item" data-local-parentid="#: data.ParentId #"><span class="local-no-icon"></span><i class="fa fa-plus"></i>&nbsp;New Child Item</td>
1878  # } #
1879  # } else { #
1880  <td class='local-td-col-1 local-td-grab'><!-- #: data.GridOrder # : #: data.DisplayOrder #--><i class="fa fa-ellipsis-v"></i></td>
1881  <td class='local-td-col-1 local-td-grab'><a href="javascript:ShowEditDialog('#= data.uid #')"><i class="fa fa-pencil-square-o"></i></a></td>
1882  #
1883  /* hard coded for each language code -- not as dynamic as could be */
1884  var displayValue = '';
1885  switch (displayLangCode) {
1886  case 'es_US':
1887  if (data.details_display_es_US) {
1888  displayValue = data.details_display_es_US;
1889  }
1890  break;
1891  case 'pl_US':
1892  if (data.details_display_pl_US) {
1893  displayValue = data.details_display_pl_US;
1894  }
1895  break;
1896  default:
1897 
1898  }
1899 
1900  if (displayValue === '') {
1901  displayValue = data.details_display_en_US;
1902  }
1903  #
1904  # if (data.details_fa_icon) { #
1905  <td role="gridcell" class="local-menu-root"><i class="fa fa-#: data.details_fa_icon # fa-fw"></i>&nbsp;#: displayValue #</td>
1906  # } else { #
1907  <td role="gridcell"><span class="local-no-icon">&nbsp;#: displayValue #</span></td>
1908  # } #
1909  <td role="gridcell">#: GetFeatureDesc(data.FeatureCode) #</td>
1910  #
1911  var lDetailLink = '';
1912 
1913  if (data.MenuItemType !== 'H') {
1914 
1915  if (data.details_target) {
1916 
1917  lDetailLink = (data.details_target === 1 ? '<span class="fa fa-external-link"></span>&nbsp;' : '') + lDetailLink;
1918  }
1919  if (data.details_href) {
1920  lDetailLink += data.details_href;
1921  }
1922  var paramSep = '?';
1923  if (data.details_hrefUrlQuery) {
1924  lDetailLink += (data.details_hrefUrlQuery === 1 ? "?cu=<?php echo $importValues['cu']; ?>" : "");
1925  paramSep = '&';
1926  }
1927  if (data.details_hrefExtraParam) {
1928  lDetailLink += (data.details_hrefExtraParam !== '' ? paramSep + data.details_hrefExtraParam : '');
1929  }
1930  }
1931  #
1932  <td colspan="2" role="gridcell">#= lDetailLink #</td>
1933  # } #
1934  # } else { #
1935  <td colspan=6>No records</td>
1936  # } #
1937 
1938  </tr>
1939  </script>
1940  <script type="text/x-kendo-template" id="cboIcon-template">
1941  <span class="k-state-default"><i class="fa fa-#: data.icon_name # fa-fw"></i>&nbsp;#: data.icon_name #</span>
1942  </script>
1943  <div id='edit-detail-row'></div>
1944  <div id="windowTemplate" style="display: none;" class="hcu-template" x-type="text/x-kendo-template">
1945  <div id='editErrors' style="display: none"></div>
1946  <form id="form-edit-template" name="form-edit-template">
1947 
1948  <div id="local-detail-list" class=" ">
1949  <div data-bind="visible: data.MenuItemType === 'H'">
1950  <div class="h4">Menu Group</div>
1951  </div>
1952  <div data-bind="visible: data.MenuItemType === 'D'">
1953  <div class="h4">Menu Group Link</div>
1954  </div>
1955  <div data-bind="visible: data.MenuItemType === 'S'">
1956  <div class="h4">Menu Link</div>
1957  </div>
1958 
1959  <!-- Properties Well -->
1960  <div class="form-horizontal well well-sm">
1961  <div class="">
1962  <div class="h4">View On <span data-role="tooltip" data-position="top" data-auto-hide="true" class="local-tooltip" title="Select the platforms that will show this menu item."><i class="fa fa-question-circle-o"></i></span></div>
1963  <div class="form-group hcu-form-group-spacer">
1964  <div class="local-indent">
1965  <label class="checkbox-inline">
1966  <input type="checkbox" id="platformDsk" name="platformDsk" value="1" data-bind="checked: data.details_platform_dsk, events: {change: change}"> Desktop
1967  </label>
1968  <label class="checkbox-inline">
1969  <input type="checkbox" id="platformMbl" name="platformMbl" value="1" data-bind="checked: data.details_platform_mbl, events: {change: change}"> Mobile Web
1970  </label>
1971  <label class="checkbox-inline">
1972  <input type="checkbox" id="platformApp" name="platformApp" value="1" data-bind="checked: data.details_platform_app, events: {change: change}"> App
1973  </label>
1974  </div>
1975  </div> <!-- form-group checkboxes -->
1976 
1977  <div class="h4">Display</div>
1978  <div data-bind="visible: data.MenuItemType !== 'D'">
1979  <div class="form-group hcu-form-group-spacer">
1980  <div class="local-indent">
1981  <label class="col-xs-12" for="scriptList">Menu Icon <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Select the icon name from the list, or enter the font-awesome icon name."><i class="fa fa-question-circle-o"></i></span></label>
1982  <div class="col-xs-12">
1983  <input id='cboIcon'
1984  name='cboIcon'
1985  data-role='combobox'
1986  data-template="cboIcon-template"
1987  data-text-field="icon_name"
1988  data-value-field="icon_name"
1989  data-placeholder="Select Icon..."
1990  data-bind="
1991  source: localdsIcons,
1992  value: data.details_fa_icon,
1993  events: {change: changeIcon}
1994  "
1995  />
1996  <span id='showIcon' class="fa fw" ></span>
1997  </div>
1998  </div>
1999  </div> <!-- ICON -->
2000  </div>
2001  <div data-bind="visible: data.MenuItemType === 'H'">
2002  <div class="form-group hcu-form-group-spacer">
2003  <div class="local-indent">
2004  <label class="checkbox-inline">
2005  <input type="checkbox" id="platformCollapseGroup" name="platformCollapseGroup" value="1" data-bind="checked: data.details_collapse_group, events: {change: change}">
2006  Collapse Group?
2007  <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="By default the menu group will be expanded on the banking side. Select this option to collapse the group instead."><i class="fa fa-question-circle-o"></i></span>
2008  </label>
2009  </div>
2010  </div> <!-- collapse group checkbox -->
2011  </div>
2012  <div data-bind="visible: ShowLang('en_US')">
2013  <div class="form-group hcu-form-group-spacer">
2014  <div class="local-indent">
2015  <label class="col-xs-12" for="en_US">English <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Enter the text to display for the English language."><i class="fa fa-question-circle-o"></i></span></label>
2016  <div class="col-xs-12">
2017  <input id="en_US" name="en_US" data-bind="value: data.details_display_en_US, events: {change: change}" data-placeholder="English Display Value" type="text" class="k-textbox k-autocomplete hcu-all-100" required validationMessage="Enter English Display" autocomplete="off"/>
2018  </div>
2019  </div>
2020  </div> <!-- Language Entry -->
2021  </div>
2022  <div id='lang_es_US' style-x="display:none;" data-bind="visible: ShowLang('es_US')">
2023  <div class="form-group hcu-form-group-spacer">
2024  <div class="local-indent">
2025  <label class="col-xs-12" for="es_US">Spanish <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Enter the text to display for the Spanish language."><i class="fa fa-question-circle-o"></i></span></label>
2026  <div class="col-xs-12">
2027  <input id="es_US" name="es_US" data-bind="value: data.details_display_es_US, events: {change: change}" data-placeholder="Spanish Display Value" type="text" class="k-textbox k-autocomplete hcu-all-100" validationMessage="Enter Spanish Display" autocomplete="off"/>
2028  </div>
2029  </div>
2030  </div> <!-- Language Entry -->
2031  </div>
2032  <div id='lang_pl_US' style-x="display:none;" data-bind="visible: ShowLang('pl_US')">
2033  <div class="form-group hcu-form-group-spacer">
2034  <div class="local-indent">
2035  <label class="col-xs-12" for="pl_US">Polish <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Enter the text to display for the Polish language."><i class="fa fa-question-circle-o"></i></span></label>
2036  <div class="col-xs-12">
2037  <input id="pl_US" name="pl_US" data-bind="value: data.details_display_pl_US, events: {change: change}" data-placeholder="Polish Display Value" type="text" class="k-textbox k-autocomplete hcu-all-100" validationMessage="Enter Polish Display" autocomplete="off"/>
2038  </div>
2039  </div>
2040  </div> <!-- Language Entry -->
2041  </div>
2042  <div id='detailsUrlSetup' data-bind="visible: data.MenuItemType !== 'H'">
2043  <div class="form-group hcu-form-group-spacer">
2044  <div class="local-indent">
2045  <label class="h4" for="featureList">Applied Feature <span data-role="tooltip" data-position="top" data-auto-hide="true" class="local-tooltip" title="Select the feature in which the user must have permission to see this item. Not selecting a feature will result in the menu item always being available."><i class="fa fa-question-circle-o"></i></span></label>
2046  <div class="col-xs-12">
2047  <input id="featureList"
2048  name=""
2049  class="hcu-all-100"
2050  data-role="dropdownlist"
2051  data-text-field="description"
2052  data-value-field="featurecode"
2053  data-option-label="Select Related Feature..."
2054  data-bind="
2055  source: localdsFeatureList,
2056  value: data.FeatureCode,
2057  events: {change: change}
2058  "
2059  />
2060  </div>
2061  </div>
2062  </div> <!-- Applied Feature -->
2063  <div class="h4">Details</div>
2064  <div class="form-group hcu-form-group-spacer">
2065  <div class="local-indent">
2066  <label class="checkbox-inline">
2067  <input type="checkbox" id="detailsNewWin" name="detailsNewWin" data-bind="checked: data.details_target, events: {change: change}" value="1">
2068  Open in New Window <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Select this option to open a new window to display the content."><i class="fa fa-question-circle-o"></i></span>
2069  </label>
2070  </div>
2071  <div class="local-indent">
2072  <label class="checkbox-inline">
2073  <input type="checkbox" id="detailsExtMsg" name="detailsExtMsg" data-bind="checked: data.details_message, events: {change: change}" value="1" >
2074  Show External Message <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Select this option to display the external message when opening in a new window:
2075  ''Please be aware that by clicking this link, your current Digital Banking session will end and you will be viewing content from another website. We encourage you to be aware of all privacy practices before giving information about yourself.''"><i class="fa fa-question-circle-o"></i></span>
2076  </label>
2077  </div>
2078  </div> <!-- form-group menu group -->
2079  <div class="form-group hcu-form-group-spacer">
2080  <div class="local-indent">
2081  <label class="col-xs-12" for="scriptList">URL Address <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Select the Home Banking script or enter a URL for this item."><i class="fa fa-question-circle-o"></i></span></label>
2082  <div class="col-xs-12">
2083  <input id="scriptList"
2084  name="scriptList" class="hcu-all-100"
2085  data-role="combobox"
2086  data-text-field="screenname"
2087  data-value-field="screenname"
2088  data-template='href-template'
2089  data-bind="
2090  source: localdsScriptList,
2091  value: data.details_href,
2092  events: {change: change}
2093  "/>
2094  </div>
2095  </div>
2096  </div> <!-- Screen Address -->
2097 
2098  <div class="form-group">
2099  <div class="local-indent">
2100  <label class="checkbox-inline">
2101  <input type="checkbox" id="details_auth" name="details_auth" data-bind="checked: data.details_hrefUrlQuery, events: {change: change}" value="1">
2102  Append CU Info <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Select this option to append the CU information on the URL address. ie cu=XYZ"><i class="fa fa-question-circle-o"></i></span>
2103  </label>
2104  </div>
2105  </div> <!-- form-group menu group -->
2106  <div class="form-group hcu-form-group-spacer">
2107  <div class="local-indent">
2108  <label class="col-xs-12" for="addtlParam">Additional URL Query <span data-role="tooltip" data-position="top" data-auto-hide="true" class="" title="Add any extra parameters to the URL here. ie one=sampe&two=fields"><i class="fa fa-question-circle-o"></i></span></label>
2109  <div class="col-xs-12">
2110  <input id="addtlParam" name="addtlParam" placeholder="key=value&key=value" type="text" class="k-textbox k-autocomplete hcu-all-100" data-bind="value: data.details_hrefExtraParam, events: {change: change}" validationMessage="Additional URL Query Parameters" autocomplete="off"/>
2111  </div>
2112  </div>
2113  </div>
2114 
2115  <div class="form-group hcu-form-group-spacer">
2116  <div class="local-indent">
2117  <label class="col-xs-12" for="acctFilter">Username Filter <span data-role="tooltip" data-position="top" data-auto-hide="true"
2118  title="App Menu Link Options. Leave blank to allow for all, or enter a comma separated list of usernames (no spaces)."><i class="fa fa-question-circle-o"></i></span></label>
2119  <div class="col-xs-12">
2120  <input id="acctFilter" name="acctFilter" placeholder="name1,name2,etc." type="text" class="k-textbox k-autocomplete hcu-all-100"
2121  data-bind="value: data.details_memacct_filter, events: {change: change}" validationMessage="Invalid Username filter" autocomplete="off"/>
2122  </div>
2123  </div>
2124 
2125  </div> <?php // form-group menu group ?>
2126  </div>
2127  </div> <!-- form-inline -->
2128  </div> <!-- well -->
2129  </div>
2130 
2131  <div class="hcu-edit-buttons k-state-default">
2132  <span class="hcu-icon-delete">
2133  <a id='lnkDelete' class="" href="##" data-bind="events: { click: itemDelete }" ><i class="fa fa-trash-o fa-lg"></i></a>
2134  </span>
2135  <a id='lnkCancel' class="" href="##" data-bind="events: { click: itemCancel }">Cancel</a>
2136  &nbsp;&nbsp;&nbsp;
2137  <a id="btnUpdate" class="k-button k-primary " href="" data-bind="html: updateBtnText, events: {click: itemSave }"></a>
2138  </div>
2139 
2140 
2141  </form>
2142  </div>
2143 
2144 <?php
2145 
2146  } catch (ErrorException $e) {
2147  // ** All else fails
2148  switch ($e->getCode()) {
2149  case 900:
2150  header("Location: /hcuadm/hcu_noperm.prg");
2151  exit;
2152  break;
2153  case 901:
2154  $url = "/hcuadm/cuinfoedit.prg?user_name=" . filter_var($importValues['cu'], FILTER_UNSAFE_RAW);
2155  echo "<p>Exception encountered, code: {$e->getCode()}, message: {$e->getMessage()}
2156  (Did you <a href=\"$url\">fully run CU set?</a>)</p>";
2157  break;
2158  default:
2159  echo "<p>Unidentified exception encountered, message: {$e->getMessage()}</p>";
2160  }
2161  }