Odyssey
lnappLookup.prg
1 <?php
2  /*
3  * Script: lnappLookup.v2
4  *
5  * Purpose: This script is used to maintain the Select Options for the Online
6  * Loan Applications system. Each drop down will be maintained here.
7  * Even for credit union specific options
8  *
9  * Parameters:
10  * No Parameters
11  * SPB-- 10/6/2015 version two update to kendo
12  */
13 
14  $monLibrary= dirname(__FILE__) . "/../library";
15  $sharedLibrary= dirname(__FILE__) . "/../../shared/library";
16  require_once("$monLibrary/cu_top.i");
17  require_once("$monLibrary/monitorView.i");
18  require_once("$monLibrary/ck_hticket.i");
19  require_once("$sharedLibrary/commonJsFunctions.i");
20 
21  if (!CheckPerm($link, $Hu, 'loanAppConfig', $_SERVER['REMOTE_ADDR'])) {
22  // ** Permissions failed
23  // ** redirect to new page
24  header("Location: /hcuadm/hcu_noperm.prg");
25  exit;
26  }
27 
28 // Globals
29 $dataFile= "lnappLookup.data";
30 $showSQL= false;
31 
32 printMonitorPageTop("Online Loan Application Lookup Options", $homecuKendoVersion, $cloudfrontDomainName);
33 ?>
34 
35 <style>
36  .popupForm .grid_12, .formContainer .grid_12 {
37  margin-bottom: 5px;
38  }
39 
40  #currentStatus {
41  position: fixed;
42  right: 20px;
43  top: 50px;
44  width: 250px;
45  padding: 10px;
46  z-index: 99;
47  display: block;
48  }
49 
50  .k-context-menu .k-item, .k-context-menu {
51  width: 150px !important;
52  }
53 </style>
54 
55 <script type="text/javascript">
56 
57 <?php
58 // Include common functions
59 getErrorsAreShownFunction();
60 getSetupDeleteConfirmDialogFunction();
61 getAddMinifiedActionStyleFunction();
62 getEscapeHTMLFunction();
63 getShowSQLFunction($showSQL);
64 getSetupValidatorInGridFunction();
65 getUseValidatorInGridFunction();
66 getShowWaitFunctions();
67 ?>
68 
69 <?php /* Initializes the grid. */ ?>
70 function initGrid()
71 {
72  var initialized= false;
73  var savedDetails= [];
74  var grid= $("#grid").kendoGrid({
75  dataSource: {
76  transport: {
77  read: {
78  url: "/hcuadm/<?php echo $dataFile; ?>?operation=read",
79  dataType: "json",
80  type: "POST"
81  },
82  create: {
83  url: "/hcuadm/<?php echo $dataFile; ?>?operation=createTop",
84  dataType: "json",
85  type: "POST"
86  },
87  update: {
88  url: "/hcuadm/<?php echo $dataFile; ?>?operation=updateTop",
89  dataType: "json",
90  type: "POST"
91  },
92  parameterMap: function (data, type) {
93  showWaitWindow();
94  if (type == "read")
95  return {};
96  else if (type == "create")
97  return {topTitle: data.topTitle}
98  else
99  {
100  return {topTitle: data.topTitle, topId: data.topId};
101  }
102  }
103  },
104  schema: {
105  model: {
106  id: "topId",
107  fields: {
108  topId: {type: "number"},
109  topTitle: {type: "title"},
110  details: {type: "odata"}
111  }
112  },
113  parse: function (data) {
114  hideWaitWindow();
115  showSQL(data);
116  $("#invalidRequestServerSide").val(errorsAreShown(data, "formValidateMainDiv"));
117 
118  if (data.operation == "update")
119  data.record[0].details= savedDetails;
120  return data.record;
121  }
122  },
123  sort: [{field: "topTitle"}]
124  },
125  columns: [
126  {field: "topId", title: "Id", width: "80px"},
127  {field: "topTitle", title: "Option Title"}
128  ],
129  sortable: true,
130  filterable: {extra: false},
131  toolbar: [{name: "create", text: ""}],
132  detailTemplate: "<div class=\"detailGrid\"></div>",
133  detailInit: function (eOuter) {
134  initDetailGrid(eOuter);
135  },
136  editable: {
137  mode: "popup",
138  template: kendo.template($("#topPopupTemplate").html()),
139  window: {
140  draggable: false,
141  resizable: false,
142  title: "",
143  actions: [],
144  width: 400
145  }
146  },
147  edit: function (eOuter)
148  {
149  setupValidatorInGrid(eOuter, false);
150 
151  if (eOuter.model.isNew())
152  {
153  $(".k-window-title").text("Add Lookup");
154  }
155  else
156  {
157  $(".k-window-title").text("Edit Lookup");
158  }
159  },
160  save: function (eOuter)
161  {
162  useValidatorInGrid(eOuter, false);
163 
164  if (!eOuter.model.isNew())
165  savedDetails= detailGrids[eOuter.model.topId+ ""].dataSource.data().slice(0);
166  },
167  cancel: function (eOuter)
168  {
169  this.cancelRow();
170  var grid= this;
171  var masterRows= $(this.tbody).find("tr.k-master-row");
172 
173  $(masterRows).off("mouseenter mouseleave");
174  $(masterRows).on("mouseenter", function () {
175  $(this).addClass("k-state-hover");
176  dataItemForMenu= grid.dataItem($(this));
177  gridForMenu= grid;
178  });
179  $(masterRows).on("mouseleave", function () {
180  $(this).removeClass("k-state-hover");
181  });
182  // Put it at the td level because expanding/collapsing the master row should not open up the edit.
183  $(masterRows).find("[role='gridcell']").on("click", function () {
184  gridForMenu= grid;
185  dataItemForMenu= grid.dataItem($(this).parent());
186  grid.editRow($(this).parent());
187  });
188 
189  eOuter.preventDefault();
190  return false;
191  },
192  dataBound: function (eOuter) {
193  var masterRows= $(this.tbody).find("tr.k-master-row");
194  var grid= this;
195  if (!initialized)
196  {
197  addMinifiedActionStyle(this, true);
198  initialized= true;
199 
200  // Make sure that all detail grids are initialized for "add subtask option"
201  $(masterRows).each(function() {
202  grid.expandRow($(this));
203  grid.collapseRow($(this));
204  });
205  }
206 
207  initContextMenu(this);
208 
209  $(masterRows).on("mouseenter", function () {
210  $(this).addClass("k-state-hover");
211  dataItemForMenu= grid.dataItem($(this));
212  gridForMenu= grid;
213  });
214  $(masterRows).on("mouseleave", function () {
215  $(this).removeClass("k-state-hover");
216  });
217  // Put it at the td level because expanding/collapsing the master row should not open up the edit.
218  $(masterRows).find("[role='gridcell']").on("click", function () {
219  gridForMenu= grid;
220  dataItemForMenu= grid.dataItem($(this).parent());
221  grid.editRow($(this).parent());
222  });
223  }
224  }).data("kendoGrid");
225 }
226 
227 <?php /* Initializes the bottom-level grid. */ ?>
228 function initDetailGrid(eOuter)
229 {
230  var initialized= false;
231  var detailData= eOuter.data.details.slice(0);
232  var detailGrid= eOuter.detailRow.find(".detailGrid").kendoGrid({
233  dataSource: {
234  transport: {
235  read: function (options) {
236  options.success(detailData);
237  },
238  create: function (options) {
239  $.post("/hcuadm/<?php echo $dataFile; ?>?operation=createBottom", {bottomValue: options.data.bottomValue, bottomText: options.data.bottomText, topId: eOuter.data.topId},
240  function (data) {
241  showSQL(data);
242  if (!errorsAreShown(data, "formValidatePopupDetailDiv"))
243  {
244  options.success(data.record);
245  eOuter.data.details= detailData.slice(0);
246  }
247  else
248  {
249  options.error(data.record);
250  }
251 
252  });
253  },
254  update: function (options) {
255  $.post("/hcuadm/<?php echo $dataFile; ?>?operation=updateBottom", {bottomValue: options.data.bottomValue, bottomText: options.data.bottomText, bottomId: options.data.bottomId},
256  function (data) {
257  showSQL(data);
258  if (!errorsAreShown(data, "formValidatePopupDetailDiv"))
259  {
260  options.success(data.record);
261  eOuter.data.details= detailData.slice(0);
262  }
263  else
264  {
265  options.error(data.record);
266  }
267 
268  });
269  }
270  },
271  schema: {
272  model: {
273  id: "bottomId",
274  fields: {
275  bottomId: {type: "number"},
276  bottomValue: {type: "string"},
277  bottomText: {type: "string"},
278  topId: {type: "number"}
279  }
280  }
281  },
282  sort: [{field: "bottomText", dir: "asc"}, {field: "bottomValue", dir: "asc"}]
283  },
284  columns: [
285  {field: "bottomId", title: "Id", width: "80px"},
286  {field: "bottomValue", title: "Answer Value"},
287  {field: "bottomText", title: "Answer Display"}
288  ],
289  sortable: true,
290  filterable: {extra: false},
291  editable: {
292  mode: "popup",
293  template: kendo.template($("#bottomPopupTemplate").html()),
294  window: {
295  draggable: false,
296  resizable: false,
297  title: "",
298  actions: [],
299  width: 400
300  }
301  },
302  edit: function (eInner)
303  {
304  setupValidatorInGrid(eInner, true);
305 
306  if (eInner.model.isNew())
307  {
308  $(".k-window-title").text("Add Detail");
309  }
310  else
311  {
312  $(".k-window-title").text("Edit Detail");
313  }
314  },
315  save: function (eInner)
316  {
317  useValidatorInGrid(eInner, true);
318  },
319  cancel: function (eInner)
320  {
321  this.cancelChanges();
322  var grid= this;
323  var detailRows= $(this.tbody).find("tr");
324 
325  $(detailRows).off("mouseenter mouseleave click");
326  $(detailRows).on("mouseenter", function () {
327  $(this).addClass("k-state-hover");
328  rowForMenu= $(this);
329  dataItemForMenu= grid.dataItem($(this));
330  gridForMenu= grid;
331  });
332  $(detailRows).on("mouseleave", function () {
333  $(this).removeClass("k-state-hover");
334  });
335  // Put it at the td level because expanding/collapsing the master row should not open up the edit.
336  $(detailRows).on("click", function () {
337  gridForMenu= grid;
338  dataItemForMenu= grid.dataItem($(this));
339  grid.editRow($(this));
340  });
341 
342  eInner.preventDefault();
343  return false;
344  },
345  dataBound: function (eInner)
346  {
347  var grid= this;
348  var detailRows= $(this.tbody).find("tr");
349  $(detailRows).on("mouseenter", function () {
350  $(this).addClass("k-state-hover");
351  rowForMenu= $(this);
352  dataItemForMenu= grid.dataItem($(this));
353  gridForMenu= grid;
354  });
355  $(detailRows).on("mouseleave", function () {
356  $(this).removeClass("k-state-hover");
357  });
358  // Put it at the td level because expanding/collapsing the master row should not open up the edit.
359  $(detailRows).on("click", function () {
360  gridForMenu= grid;
361  dataItemForMenu= grid.dataItem($(this));
362  grid.editRow($(this));
363  });
364  }
365  }).data("kendoGrid");
366 
367  detailGrids[eOuter.data.topId]= detailGrid;
368 }
369 
370 <?php /* Initializes the right-click menu at both levels of the grid. */ ?>
371 var dataItemForMenu= null, gridForMenu= null, rowForMenu= null, detailGrids= [];
372 function initContextMenu(grid)
373 {
374  var contextMenu= $("#contextMenu").data("kendoContextMenu");
375 
376  if (contextMenu == null)
377  {
378  var deleteConfirm= $("<div id='deleteDialog'></div>").kendoWindow({
379  content: {template: $("#deleteConfirmTemplate").html()},
380  draggable: false,
381  visible: false,
382  actions: [],
383  modal: true,
384  title: "Confirm deletion",
385  width: 400,
386  height: 125,
387  resizable: false
388  }).data("kendoWindow");
389 
390  $("#deleteDialog .deleteConfirmContinueBtn").click(function () {
391  var deleteDetails= typeof(dataItemForMenu.details) != "undefined" && Number(dataItemForMenu.details.length) > 0 ? "Y" : "N";
392  var isMaster= $(gridForMenu.tbody).find("tr.k-master-row").length > 0;
393  var url= "/hcuadm/<?php echo $dataFile; ?>?operation=" + (isMaster ? "deleteTop" : "deleteBottom");
394  var parameters= isMaster ? {topId: dataItemForMenu.topId, deleteDetails: deleteDetails} : {bottomId: dataItemForMenu.bottomId};
395  showWaitWindow();
396  $.post(url, parameters, function (data){
397  hideWaitWindow();
398  showSQL(data);
399 
400  // If no errors, then remove record from the grid
401  if (!errorsAreShown(data, "formValidateMainDiv"))
402  {
403  var data= gridForMenu.dataSource.data().slice(0);
404  var id= isMaster ? "topId" : "bottomId";
405  data= $.grep(data, function(n,i) { return n[id] != dataItemForMenu[id]; });
406  gridForMenu.dataSource.data(data);
407 
408  if (!isMaster)
409  {
410  var fullGridData= grid.dataSource.data().slice(0);
411  for(var i=0; i!= fullGridData.length; i++)
412  {
413  if (fullGridData[i].topId == dataItemForMenu.topId)
414  {
415  fullGridData[i].details= data;
416  break;
417  }
418  }
419  grid.dataSource.data(fullGridData);
420  }
421  }
422  });
423  deleteConfirm.close();
424  return false;
425  });
426 
427  $("#deleteDialog .deleteConfirmCancelBtn").click(function () {
428  deleteConfirm.close();
429  return false;
430  });
431 
432  var contextMenu= $("<div id='contextMenu'></div>").kendoContextMenu({
433  target: "#grid",
434  filter: ".k-master-row [role='gridcell'], .detailGrid .k-grid-content tr",
435  alignToAnchor: true,
436  orientation: "vertical",
437  popupCollision: false,
438  open: function (e)
439  {
440  this.remove("li");
441 
442  var options= [];
443  var grid= $(e.event.target).closest(".k-grid").data("kendoGrid");
444  var tr= $(e.event.target).closest("tr"); // If set at the tr level, it returns itself. If set at the td level, it return its parent.
445  var dataItem= grid.dataItem($(tr));
446 
447  if ($(grid.tbody).find(".k-master-row").length != 0)
448  {
449  options= [{text: "Edit", cssClass: "editLi"}, {text: "Delete", cssClass: "deleteLi"}, {text: "Add detail", cssClass: "addDetailLi"}];
450  }
451  else
452  {
453  options= [{text: "Edit", cssClass: "editLi"}, {text: "Delete", cssClass: "deleteLi"}];
454  }
455 
456  this.append(options);
457  },
458  select: function (e)
459  {
460  var item= $(e.item);
461  var tr= $(e.target).closest("tr"); // If set at the tr level, it returns itself. If set at the td level, it return its parent.
462  var grid= $(e.target).closest(".k-grid").data("kendoGrid");
463  var dataItem= grid.dataItem($(tr));
464 
465  if ($(item).hasClass("editLi"))
466  {
467  grid.editRow($(tr));
468  }
469  else if ($(item).hasClass("deleteLi"))
470  {
471  var numDetails= typeof(dataItem.details) == "undefined" ? 0 : Number(dataItem.details.length);
472 
473  if (numDetails > 0)
474  {
475  $("#detailDeleteMsg").show();
476  $("#detailDeleteMsg span").text(numDetails);
477  }
478  else
479  {
480  $("#detailDeleteMsg").hide();
481  }
482  deleteConfirm.open().center();
483  }
484  else if ($(item).hasClass("addDetailLi"))
485  {
486  detailGrids[dataItem.topId+ ""].addRow();
487  }
488  }
489  }).data("kendoContextMenu");
490  }
491  }
492 
493 $(document).ready(function () {
494  initGrid();
495 });
496 </script>
497 
498 <script id="topPopupTemplate" type="text/x-kendo-template">
499  <div id="formValidatePopupDiv" class="homecu-formStatus k-block k-error-colored" style="display:none;"></div>
500  <form id="popupForm" class="popupForm" data-role="validator" novalidate>
501  <div class="container_12">
502  <div class="grid_12">
503  <div class="grid_4 alpha">
504  <label>Title:</label>
505  </div>
506  <div class="grid_7">
507  <input type="text" class="k-input" name="topTitle" maxlength="50" required data-required-msg="Title is required" style="width: 100%">
508  </div>
509  <div class="grid_1 omega">
510  <span data-for='topTitle' class='k-invalid-msg'></span>
511  </div>
512  </div>
513  </div>
514  </form>
515 </script>
516 
517 <script id="bottomPopupTemplate" type="text/x-kendo-template">
518  <div id="formValidatePopupDetailDiv" class="homecu-formStatus k-block k-error-colored" style="display:none;"></div>
519  <form id="popupFormDetail" class="popupForm" data-role="validator" novalidate>
520  <div class="container_12">
521  <div class="grid_12" id="bottomIdRow" style="display: none;">
522  <div class="grid_4 alpha">
523  <label>Id:</label>
524  </div>
525  <div class="grid_7">
526  <div>#: bottomId #</div>
527  </div>
528  <div class="grid_1 omega">
529  &nbsp;
530  </div>
531  </div>
532  <div class="grid_12">
533  <div class="grid_4 alpha">
534  <label>Value:</label>
535  </div>
536  <div class="grid_7">
537  <input type="text" class="k-input" name="bottomValue" maxlength="50" required data-required-msg="Value is required" style="width: 100%">
538  </div>
539  <div class="grid_1 omega">
540  <span data-for='bottomValue' class='k-invalid-msg'></span>
541  </div>
542  </div>
543  <div class="grid_12">
544  <div class="grid_4 alpha">
545  <label>Text:</label>
546  </div>
547  <div class="grid_7">
548  <input type="text" class="k-input" name="bottomText" maxlength="50" required data-required-msg="Text is required" style="width: 100%">
549  </div>
550  <div class="grid_1 omega">
551  <span data-for='bottomText' class='k-invalid-msg'></span>
552  </div>
553  </div>
554  </div>
555  </form>
556 </script>
557 <script id="deleteConfirmTemplate" type="text/x-kendo-template">
558  <div class="k-edit-form-container">
559  <div class="container_12">
560  <div class="grid_12 message">Are you sure that you want to delete? <span id="detailDeleteMsg" style="display:none;">This will also delete <span>1</span> detail(s) as well.</div>
561  </div>
562  <div class="k-edit-buttons k-state-default">
563  <a class="k-button k-button-icontext deleteConfirmContinueBtn" href="\#">
564  <span class="k-icon k-i-check"></span>
565  Continue
566  </a>
567  <a class="k-button k-button-icontext deleteConfirmCancelBtn" href="\#">
568  <span class="k-icon k-i-cancel"></span>
569  Cancel
570  </a>
571  </div>
572  </div>
573 </script>
574 
575 <?php printMonitorPageMiddle("Online Loan Application Lookup Options"); ?>
576  <div id='hideSubmitWait' style='position:relative; left:-2000px;top:-2000px;'>
577  <div id='homecuSubmitWait' class='k-block' >
578  <div class='k-loading-image'></div>
579  </div>
580  </div>
581  <input type="hidden" id="invalidRequestClientSide">
582  <input type="hidden" id="invalidRequestServerSide">
583  <div class="container_12">
584  <div class="grid_12">
585  <div class="grid_7 alpha omega">
586  <div id="sqlOutput"></div>
587  </div>
588  </div>
589  <div class="grid_12">
590  <div class="grid_7 alpha omega">
591  <div id="formValidateMainDiv" class="k-block k-error-colored" style="display:none;"></div>
592  </div>
593  </div>
594  <div class="grid_12">
595  <div class="grid_7 alpha omega">
596  <div id="grid" style="width:100%"></div>
597  </div>
598  </div>
599  </div>
600 
601 <?php printMonitorPageBottom(); ?>