HTML5 LocalStorage 本地存储
1.前言
HTML5 storage提供了一种方式让网站能够把信息存储到你本地的计算机上,并再以后需要的时候进行获取。这个概念和cookie相似,区别是它是为了更大容量存储设计的。Cookie的大小是受限的,并且每次你请求一个新的页面的时候cookie都会被发送过去。HTML5的storage是存储在你的计算机上,网站在页面加载完毕后可以通过Javascript来获取这些数据。首先自然是检测浏览器是否支持本地存储。在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,从名字应该可以很清楚的辨认二者的区别,前者是一直存在本地的,后者只是伴随着session,窗口一旦关闭就没了。二者用法完全相同,这里以localStorage为例。
if(window.localStorage){
alert('支持localStorage');
}else{
alert('不支持localStorage');
}
2.基本用法
存储数据的方法就是直接给window.localStorage添加一个属性,例如:window.localStorage.a 或者 window.localStorage["a"]。它的读取、写、删除操作方法很简单,是以键值对的方式存在的,如下:
localStorage.name = "kobi";//设置name为"kobi"
localStorage["name"] = "koko";//设置name为"koko",覆盖上面的值
localStorage.setItem("age","18");//设置age为"18"
var a1 = localStorage["name"];//获取name的值
var a2 = localStorage.age;//获取age的值
var b = localStorage.getItem("name");//获取name的值
localStorage.removeItem("c");//清除c的值
这里最推荐使用的自然是getItem()和setItem(),清除键值对使用removeItem()。如果希望一次性清除所有的键值对,可以使用clear()。另外,HTML5还提供了一个key()方法,可以在不知道有哪些键值的时候使用,如下:
var storage = window.localStorage;
function showStorage(){
for(var i=0;i<storage.length;i++){
//key(i)获得相应的键,再用getItem()方法获得对应的值
document.write(storage.key(i)+ " : " + storage.getItem(storage.key(i)) + "<br>");
}
}
3.业务需求
表单实时保存数据,下次打开则提示是否继续编辑。图片等控件不支持,只支持简单的控件。【防止突然断电或浏览器崩溃时,下次打开还可以继续编辑并保存】。这样自然而然就想到了HTML5的本地存储功能。既然js写的烂,写的差,就当练手了。
其实这些数据的保存很简单,无非就是一些简单的标签数据的保存。先来一个最简单的js版本。
1 /** 2 * 功能:保存用户修改完form标签内容在LocalStorage中。 3 * 作者:黄金锋 (549387177@qq.com) 4 * 日期:2015-11-1 11:14:01 5 * 修改:2015-11-11 16:09:00 6 * 版本:version 2.0 7 */ 8 9 define(function () { 10 11 //从localStorage中加载数据 12 function onload(form) { 13 14 var fh = form_handler; 15 var p = fh.getParams(form); 16 if (!p.bimId || !p.formId || !p.iid) { 17 return; 18 } 19 var id = 'FORM_' + DCI.LoginUser.UserId + '_' + p.bimId + '_' + p.formId + '_' + p.iid; 20 //alert(id); 21 22 var formDataDb; 23 var allControl = $(form).find("input:text[name],textarea[name]"); 24 25 //从本地取 26 var storage = localStorage.getItem(id); 27 if (storage != null) { 28 var myData = JSON.parse(storage); 29 allControl.each(function (i, e) { 30 var name = $(e).attr("name"); 31 if (myData[name] != null) { 32 $(e).val(myData[name]); 33 $(e).change(); 34 } 35 }); 36 } 37 38 39 //绑定change事件 40 allControl.each(function (i, el) { 41 var name = $(el).attr('name'); 42 if (name) { 43 $(el).on('change', function () { 44 onchange(this); 45 }); 46 } 47 }); 48 49 //保存修改的数据 50 function onchange(el) { 51 var storage = localStorage.getItem(id); 52 if (storage == null) { 53 formDataDb = new Object(); 54 var key = $(el).attr("name"); 55 var value = $(el).val(); 56 formDataDb[key] = value; 57 localStorage.setItem(id, JSON.stringify(formDataDb)); 58 } else { 59 var myData = JSON.parse(storage); 60 var key = $(el).attr("name"); 61 var value = $(el).val(); 62 myData[key] = value; 63 localStorage.setItem(id, JSON.stringify(myData)); 64 } 65 } 66 }; 67 68 //删除localStorage中的数据 69 function onsave(form) { 70 var fh = form_handler; 71 var p = fh.getParams(form); 72 var id = 'FORM_' + DCI.LoginUser.UserId + '_' + p.bimId + '_' + p.formId + '_' + p.iid; 73 localStorage.removeItem(id); 74 75 var allGrid = $(form).find(".form-table"); 76 var formId = $(form).data("formid"); 77 allGrid.each(function (index,element) { 78 var formName = $(element).find("input:hidden[data-formid]").attr("name"); 79 var storageKey = "FORM_" + formId + "_" + formName; 80 localStorage.removeItem(storageKey); 81 }); 82 } 83 84 return { 85 onload: onload, 86 onsave: onsave, 87 } 88 });
表单都是自动通过模版生成的,这里附上表单加载需要的form.js.
1 if (!window.form_handler) {//防止重复加载 2 window.f_action = new (function () { //表单事件处理对象,封装表单事件的处理程序 3 4 this.seltime = function () { 5 if ($.fn.datetimepicker) { 6 var $input = $(this).parent().find('input'); 7 if (!$input.attr('readonly')) { 8 var format; 9 if (!$input.data('datetimepicker')) { //添加日期控件 10 format = form_handler.getElDateFormat($input); 11 var minView = 2; 12 if (format.indexOf('i') >= 0) 13 minView = 0; 14 var form = $(this).closest('form'); 15 $input.datetimepicker({ 16 startDate: new Date('100/1/1'), 17 endDate: new Date('10000/1/1'), 18 format: format, 19 language: 'zh-CN', 20 todayHighlight: true, 21 autoclose: true, 22 minView: minView, 23 todayBtn: true, 24 forceParse: false, 25 container: form 26 }); 27 } 28 $input.datetimepicker('show'); 29 30 var val = form_handler.getElDateValue($input, format); 31 if (val) { 32 var date = new Date(val); 33 if (date && date != 'Invalid Date') 34 $input.datetimepicker('update', date); 35 } 36 } 37 } 38 }; 39 40 this.joinControl = function (sender, target, value, isExpression, conditionFields, isDataSource) { 41 if (!$(sender).attr('readonly')) 42 form_handler.joinControl(sender, target, value, isExpression, conditionFields, isDataSource); 43 }; 44 45 this.runMethod = function (sender, method, params) { 46 if (!$(sender).attr('readonly')) { 47 require(['form.run'], function () { 48 var func = eval('form_run.' + method); 49 if (func) { 50 var form = $(sender).parents('form'); 51 var b = form_handler.getParams(form); 52 func.call(sender, form, b, params); 53 } 54 else 55 alert('未实现函数' + method); 56 }); 57 } 58 }; 59 60 this.selectGlossary = function (sender) { 61 var ctrl = $(sender).parent().find('input,textarea'); 62 if (ctrl.length) { 63 if (!ctrl.attr('readonly')) { 64 var field = ctrl.attr('name'); 65 var form = $(sender).closest('form'); 66 var formId = form.data('formid'); 67 var glossaryKey = ctrl.data('glossary'); 68 require(['glossary'], function () { 69 g_action.showGlossary(formId + '_' + field, ctrl, form, glossaryKey, function (ctrl) { 70 var el; 71 if ($(ctrl).css('position') == 'absolute') 72 el = $(ctrl); 73 else //寻找绝对定位的父节点 74 $(ctrl).parentsUntil('form').each(function (i, e) { 75 if ($(e).css('position') == 'absolute') 76 el = $(e); 77 }); 78 if (el) { 79 var position = $(el).position(); 80 return { 81 top: position.top + $(el).height(), 82 left: position.left, 83 }; 84 } 85 }); 86 }); 87 } 88 } 89 }; 90 91 this.runform = function (sender, formtype, formId, variables, controls, iid) { 92 var mainForm = $(sender).closest('form'); 93 if (formtype == 'changeform') { 94 for (var i in controls) { 95 if (controls[i][1].indexOf('$[ID]') > -1 && !form_handler.getElValue(mainForm, controls[i][0])) { 96 alert('找不到记录。'); 97 return; 98 } 99 } 100 } 101 var reg = /\$\[([^[\]]+)\]/g; 102 var data = { 103 }; 104 data.formId = formId; 105 data.formType = formtype; 106 data.dialogId = 'DialogRunForm'; 107 if (iid) { 108 data.iid = iid.replace(reg, function (str, subStr) { 109 return form_handler.getElValue(mainForm, subStr); 110 }); 111 } 112 var url = DefaultUrl + 'Form/DialogRunForm'; 113 showAjaxDialog(data.dialogId, url, data, true, document.body, function (state, data) { 114 if (state == 'ok') { 115 var childForm = $('#DialogRunForm form'); 116 if (formtype == 'addform') { 117 var idVal = childForm.find('[name="ID"]').val(); 118 childForm.data('iid', idVal); 119 childForm.data('bimid', idVal);//兼容3.0 120 form_handler.submitForm(childForm, submitFormCallback, document.body); 121 } 122 else if (formtype == 'changeform') { 123 form_handler.submitForm(childForm, submitFormCallback, document.body); 124 } 125 else if (formtype == 'queryform') { 126 if (childForm.find('table tr.active').length) 127 submitFormCallback(); 128 else 129 alert('请选择一行。'); 130 } 131 } 132 133 function submitFormCallback() { 134 for (var i in controls) { 135 var c = controls[i]; 136 var v = c[1].replace(reg, function (str, subStr) { 137 return form_handler.getElValue(childForm, subStr); 138 }); 139 form_handler.getEl(mainForm, c[0]).val(v); 140 } 141 $('#DialogRunForm').modal('hide'); 142 } 143 }, function (data, btn) { 144 $('#DialogRunForm .modal-title').text($(sender).val()); 145 form_handler.openFormCallback($('#DialogRunForm form')); 146 }); 147 }; 148 149 this.urlChanged = function (scrop, iframeclass) { 150 var url = $(scrop).val(); 151 $('.' + iframeclass).attr('src', url); 152 }; 153 })(); 154 155 window.form_handler = new function () { //表单操作对象,提供接口供外部调用 156 157 var $this = this; 158 159 this.openFormCallback = function (form, dirtyCallback) { 160 161 initElement();//初始化基本元素 162 initCtrl();//初始化控件 163 initModify();//修改痕迹 164 onload();//load事件 165 166 function initElement() { 167 var allControl = $(form).find('input:text,input:checkbox,input:radio,input:hidden,textarea'); 168 allControl.each(function (i, el) { 169 var name = $(el).attr('name'); 170 if (name) { 171 $(el).on('change', function () { 172 onchange(this); 173 }); 174 } 175 }); 176 $(form).find('input:checkbox,input:radio').change(function (e) { 177 if ($(this).is('input:radio')) { 178 var name = $(this).attr('name'); 179 $(form).find('input:radio[name="' + name + '"]').val('0').data('dirty', true); 180 } 181 if ($(this).is(':checked')) 182 $(this).val('1'); 183 else 184 $(this).val('0'); 185 }); 186 $(form).find('input[readonly],textarea[readonly]').keydown(function (evt) { 187 if (evt.keyCode == 8) return false 188 }); 189 //触发事件 190 allControl.each(function (i, el) { 191 if ($(el).attr('data-dirty') == 'true') { 192 $(el).change();//联动 193 } 194 }); 195 } 196 197 function onchange(el) { 198 var d = $(form).data('dirty'); 199 $(form).data('dirty', true);//表单已修改 200 $(el).data('dirty', true);//控件已修改 201 if (!d && dirtyCallback) 202 dirtyCallback(form); 203 } 204 205 function initCtrl() { 206 initGrid(); 207 reqCtrl('.form-img:not(.hidden):not([disabled])', ['form.ctrl.image']); 208 reqCtrl('.richtextbox:not(.hidden)', ['form.ctrl.richtextbox']); 209 reqCtrl('.user-picker:not(.hidden)', ['form.ctrl.userpicker']); 210 reqCtrl('.form-chart:not(.hidden)', ['form.ctrl.chart']); 211 reqCtrl('.popover-toggle:not(.hidden)', ['form.ctrl.popover']); 212 reqCtrl('.Iframe:not(.hidden)', ['form.ctrl.Iframe']); 213 reqCtrl('.form-codeimage:not(.hidden)', ['form.ctrl.codeimg']); 214 } 215 216 function initGrid() { 217 $(form).find('.form-table').each(function (i, cform) { 218 var ipt = $(cform).find('input[name]'); 219 var formId = ipt.data('formid'); 220 var init = JSON.parse($(cform).find('input[data-param="init"]').val()); 221 var initsame = JSON.parse($(cform).find('input[data-param="initsame"]').val()); 222 $(cform).on('click', 'tr', selrow); 223 $(cform).find('.form-table-body').scroll(scrollTable); 224 $(cform).on('click', 'td.form-table-edit', editRow); 225 226 if (!$(cform).hasClass('disabled')) { 227 $(cform).on('click', function (event) { 228 if (!$(event.target).is('input[name]')) 229 ipt.click(); 230 }); 231 $(cform).on('click', '.form-table-footer button.add-row', addRow); 232 if (initsame.length) 233 $(cform).on('click', '.form-table-footer button.add-samerow', addRow); 234 else 235 $(cform).find('button.add-samerow').remove(); 236 $(cform).on('click', '.form-table-footer button.del-row', delRow); 237 $(cform).on('change', 'td input[type="checkbox"]', chkChange); 238 if (ipt.data('dirty')) { 239 $(cform).find('tr').data('insert', true); 240 } 241 } 242 else { 243 $(cform).find('input[type="checkbox"]').attr('disabled', 'disabled'); 244 $(cform).find('.form-table-footer').remove(); 245 $(cform).find('.form-table-body').css('bottom', 0); 246 } 247 dataGridTplRender($(cform).find('table')); 248 249 function chkChange() { 250 var $this = $(this); 251 var val = '0'; 252 if ($this.is(':checked')) 253 val = '1'; 254 $this.val(val); 255 var tr = $(this).closest('tr'); 256 tr.data('update', true); 257 ipt.change(); 258 if (window.localStorage) { 259 var table = $this.closest('table'); 260 var name = table.find('colgroup col').eq($this.closest('td').index()).data('index'); 261 var row_data = { 262 }; 263 row_data[name] = val; 264 require(['form.storage'], function (s) { 265 s.ongridedit(form, table, row_data, tr); 266 }); 267 } 268 } 269 270 function selrow() { 271 $(this).siblings().removeClass('active'); 272 $(this).addClass('active'); 273 } 274 275 function scrollTable() { 276 var left = $(this).scrollLeft(); 277 $(this).siblings('.form-table-header').css('margin-left', -left); 278 } 279 280 function editRow(e) { 281 var data = { 282 formId: formId, 283 readOnly: $(cform).hasClass('disabled') ? 1 : 0 284 }; 285 var tr = $(this).closest('tr'); 286 showAjaxDialog('DialogGridRow', DefaultUrl + 'Form/DialogGridRow', data, true, document.body, function (state, data) { 287 if (state == 'ok') { 288 if ($(cform).hasClass('disabled')) { 289 $('#DialogGridRow').modal('hide'); 290 } 291 else if ($this.validateForm($('#DialogGridRow form'))) { 292 var table = tr.closest('table'); 293 var row_data = { 294 }; 295 var cells = tr.find('td'); 296 table.find('colgroup col').each(function (idx, el) { 297 var index = $(el).data('index'); 298 if (index) { 299 var ctrl = $('#DialogGridRow form [name="' + index + '"]'); 300 var td = cells.eq(idx); 301 if (ctrl.length) { 302 var type = $(el).data('type'); 303 var text = ctrl.val(); 304 if (type == 'CheckBox') {//复选框 305 var ck = td.find('input[type="checkbox"]'); 306 ck.val(text); 307 if (text == '1') 308 ck.prop('checked', true); 309 else 310 ck.prop('checked', false); 311 } 312 else { 313 td.text(text); 314 } 315 } 316 var ipt = td.find('input'); 317 if (ipt.length) 318 row_data[index] = ipt.val(); 319 else 320 row_data[index] = td.text(); 321 } 322 }); 323 if (window.form_tpl) { 324 table.find('colgroup col').each(function (idx, el) { 325 if ($(el).data('type') == 'Template') { 326 var tpl = eval('form_tpl.' + $(el).data('tpl')); 327 if (tpl) { 328 cells.eq(idx).html(tpl(row_data, cells.eq(idx - 1).text())); 329 } 330 } 331 }); 332 } 333 if (window.localStorage) 334 require(['form.storage'], function (s) { 335 s.ongridedit(form, table, row_data, tr); 336 }); 337 $('#DialogGridRow').modal('hide'); 338 tr.data('update', true); 339 ipt.change(); 340 tr.click(); 341 } 342 } 343 }, 344 function () { 345 if ($(cform).hasClass('disabled')) 346 $('#DialogGridRow .modal-title').text('查看'); 347 else 348 $('#DialogGridRow .modal-title').text('编辑'); 349 var childForm = $('#DialogGridRow form'); 350 $this.openFormCallback(childForm); 351 //获取列信息 352 var table = tr.parents('table'); 353 table.find('colgroup col').each(function (idx, el) { 354 var td = tr.find('td').eq(idx); 355 var ck = td.find('input[type="checkbox"]'); 356 var value; 357 if (ck.length > 0) value = ck.val(); 358 else value = td.text(); 359 var target = $('#DialogGridRow form [name="' + $(el).data('index') + '"]').val(value); 360 if (target.is(':checkbox')) { 361 if (value == '1') 362 target.attr('checked', 'checked'); 363 else 364 target.removeAttr('checked'); 365 } 366 }); 367 }); 368 } 369 370 function addRow() { 371 var btn = $(this); 372 var selRow = $(cform).find('table tr.active'); 373 if (btn.is('.add-samerow') && !selRow.length) { 374 alert('请选择行。'); 375 return; 376 } 377 var data = { 378 formId: formId 379 }; 380 var table = $(cform).find('table'); 381 showAjaxDialog('DialogGridRow', DefaultUrl + 'Form/DialogGridRow', data, true, document.body, function (state, data) { 382 if (state == 'ok') { 383 var childForm = $('#DialogGridRow form'); 384 var iid = childForm.data('iid'); 385 if (iid) { 386 if ($this.validateForm(childForm)) { 387 var tr = $('<tr></tr>'); 388 var row_data = { 389 }; 390 table.find('colgroup col').each(function (idx, el) { 391 var td = $('<td></td>'); 392 if (idx == 0) { 393 td.append('<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>'); 394 td.addClass('form-table-edit'); 395 } 396 else { 397 var index = $(el).data('index'); 398 if (index) { 399 if (index == 'IID') {//主键 400 row_data['IID'] = iid; 401 td.text(iid); 402 } 403 else if (index == 'ID') { 404 row_data['ID'] = form.data('bimid'); 405 td.text(row_data['ID']); 406 } 407 else { 408 var ctrl = $('#DialogGridRow form [name="' + index + '"]'); 409 if (ctrl.length) { 410 var type = $(el).data('type') 411 var text = ctrl.val(); 412 if (type == 'CheckBox') { 413 var val = text == '1' ? '1' : '0'; 414 td.append('<input type="checkbox" value="' + val + '" ' + (val == '1' ? 'checked="checked"' : '') + ' />'); 415 } 416 else { 417 td.text(text) 418 } 419 row_data[index] = text; 420 } 421 } 422 } 423 } 424 if ($(el).attr('width') == '0') 425 td.addClass('hidden'); 426 td.appendTo(tr); 427 }); 428 if (window.form_tpl) { 429 var cells = tr.find('td'); 430 table.find('colgroup col').each(function (idx, el) { 431 if ($(el).data('type') == 'Template') { 432 var tpl = eval('form_tpl.' + $(el).data('tpl')); 433 cells.eq(idx).html(tpl(row_data, cells.eq(idx - 1).text())); 434 } 435 }); 436 } 437 438 table.append(tr); 439 if (window.localStorage) 440 require(['form.storage'], function (s) { 441 s.ongridadd(form, table, row_data, tr); 442 }); 443 $('#DialogGridRow').modal('hide'); 444 tr.data('insert', true); 445 refreshGridRownum(table); 446 ipt.change(); 447 448 tr.click(); 449 } 450 } 451 } 452 }, function () { 453 $('#DialogGridRow .modal-title').text('新增'); 454 var childForm = $('#DialogGridRow form'); 455 $this.openFormCallback(childForm); 456 $.ajax({ 457 url: DefaultUrl + 'Form/GetChildFormIID', 458 type: 'post', 459 data: { 460 formId: formId 461 }, 462 cache: false, 463 loadingScope: document.body, 464 success: function (r) { 465 var iid = r.Data[0][0]; 466 childForm.data('iid', iid); 467 } 468 }); 469 for (var key in init) { 470 if (key != 'IID') { 471 var value = init[key]; 472 var reg = /\$\[([^[\]]+)\]/g; 473 var value = value.replace(reg, function (str, subStr) { 474 return $this.getElValue(form, subStr); 475 }); 476 childForm.find('[name="' + key + '"]').val(value); 477 } 478 } 479 if (btn.is('.add-samerow')) {//新增相同 480 var table = selRow.closest('table'); 481 var cols = table.find('colgroup col'); 482 $.each(initsame, function () { 483 var key = this; 484 cols.each(function (idx, el) { 485 if ($(el).data('index') == key) { 486 var td = selRow.find('td').eq(idx); 487 var ck = td.find('input[type="checkbox"]'); 488 var value; 489 if (ck.length > 0) value = ck.val(); 490 else value = td.text(); 491 var target = $('#DialogGridRow form [name="' + key + '"]').val(value); 492 if (target.is(':checkbox')) { 493 if (value == '1') 494 target.attr('checked', 'checked'); 495 else 496 target.removeAttr('checked'); 497 } 498 return false; 499 } 500 }); 501 }); 502 } 503 }); 504 } 505 506 function delRow(e) { 507 var table = $(cform).find('table'); 508 var tr = table.find('tr.active'); 509 if (tr.length) { 510 tr.removeClass('active').hide(); 511 if (window.localStorage) { 512 require(['form.storage'], function (s) { 513 s.ongriddel(form, table, tr); 514 }); 515 } 516 tr.data('delete', true); 517 if (tr.data('insert')) 518 tr.remove(); 519 refreshGridRownum($(cform).find('table')); 520 ipt.change(); 521 } 522 else 523 alert('请选择行。'); 524 } 525 }); 526 } 527 528 function reqCtrl(selector, deps) { 529 var ctrls = $(form).find(selector); 530 if (ctrls.length) { 531 require(deps, function (r) { 532 ctrls.each(function () { 533 if (r instanceof Function) 534 r.apply(this); 535 else if (r instanceof Object) 536 r.onload.apply(this); 537 }) 538 }); 539 } 540 } 541 542 function initModify() { 543 544 $(form).mousedown(function (e) { 545 if ($(form).data('readmark-loaded') && $(e.target).is('input:text,input:checkbox,input:hidden,textarea') && $(e.target).data('modified')) { 546 var el = e.target; 547 var name = $(el).attr('name'); 548 if (name) { 549 if (!$(el).data('show-popover')) { 550 $(el).data('show-popover', true); 551 //$(el).data('timer', setTimeout(function (el) { 552 var iid = $(form).data('iid'); 553 var formId = $(form).data('formid'); 554 $(el).data('getting-modifyLog', true); 555 $.ajax({ 556 url: DefaultUrl + 'Form/ModifyLogData', 557 data: { 558 iid: iid, formId: formId, field: name 559 }, 560 cache: false, 561 loadingScope: document.body, 562 success: function (r) { 563 if ($(r).find('ul li').length && $(el).data('show-popover')) { 564 $(form).find('.popover').remove(); 565 $(el).popover({ 566 content: r, 567 html: true, 568 trigger: 'manual', 569 placement: 'left', 570 animation: true, 571 container: $(form), 572 template: '<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>' 573 }); 574 $(el).popover('show'); 575 $(form).find('.popover').mouseenter(function () { 576 $(el).data('show-popover', false); 577 }).mouseleave(function () { 578 $(el).popover('destroy'); 579 }); 580 } 581 }, 582 complete: function () { 583 $(el).data('getting-modifyLog', false); 584 } 585 }); 586 //}, 100, el)); 587 } 588 } 589 } 590 }); 591 592 $(form).mouseout(function (e) { 593 if ($(form).data('readmark-loaded') && $(e.target).is('input:text,input:checkbox,input:hidden,textarea') && $(e.target).data('modified')) { 594 var el = e.target; 595 if (!$(el).data('getting-modifyLog')) { 596 var name = $(el).attr('name'); 597 if (name) { 598 //var t = $(this).data('timer'); 599 //if (t) 600 // clearTimeout(t); 601 if ($(form).find('.popover').length) { 602 if ($(el).data('show-popover')) { 603 setTimeout(function () { 604 if ($(el).data('show-popover')) { 605 $(el).data('show-popover', false); 606 $(el).popover('destroy'); 607 } 608 }, 100); 609 } 610 } 611 else { 612 $(el).data('show-popover', false); 613 $(el).popover('destroy'); 614 } 615 } 616 } 617 } 618 }); 619 } 620 621 function onload() { 622 if (window.localStorage) 623 require(['form.storage'], function (s) { 624 s.onload(form); 625 }); 626 if ($(form).data('onload')) 627 (function () { 628 eval($(form).data('onload')); 629 }).apply(form); 630 } 631 }; 632 633 function dataGridTplRender(table) { 634 if (table.find('colgroup col[data-type="Template"]').length) { 635 require(['form.tpl'], function () {//模板列 636 var cols = []; 637 var tpls = []; 638 table.find('colgroup col').each(function (idx, el) {//获取列信息 639 cols[idx] = $(el).data('index'); 640 if ($(el).data('type') == 'Template') { 641 var tplStr = $(el).data('tpl'); 642 var tpl = eval('form_tpl.' + tplStr); 643 if (tpl != null) 644 tpls.push({ index: idx, tpl: tpl }); 645 else//告知错误原因 646 alert('模板[' + tplStr + ']没定义。'); 647 } 648 }); 649 if (tpls.length) { 650 table.find('tr').each(function (idx, el) { 651 var row_data = {}; 652 var cells = $(el).find('td'); 653 cells.each(function (idx, el) {//获取行数据 654 if (cols[idx]) { 655 var ipt = $(el).find('input'); 656 if (ipt.length) 657 row_data[cols[idx]] = ipt.val(); 658 else 659 row_data[cols[idx]] = $(el).text(); 660 } 661 }); 662 $.each(tpls, function () { 663 var td = cells.eq(this.index); 664 td.html(this.tpl(row_data, cells.eq(this.index - 1).text())); 665 }); 666 }); 667 } 668 }); 669 } 670 } 671 672 this.joinControl = function (sender, target, value, isExpression, conditionFields, isDataSource) { 673 if (isDataSource) {//数据源 674 $this.getDataSource(sender, value, [target], conditionFields); 675 } 676 else { 677 var result; 678 if ((result = /\$\{substr,([^,]+),(\d+),(\d+)\}\s+([^\s]+)/.exec(value)) != null) {//截取字符串,谁设计的!!!! 679 var sourceField = result[1]; 680 var startIdx = result[2]; 681 var length = result[3]; 682 var targetField = result[4]; 683 var form = $(sender).closest('form'); 684 var sourceValue = $this.getElValue(form, sourceField.replace('@', '#')); 685 if (sourceValue != null) { 686 $this.getEl(form, targetField).val(sourceValue.substr(parseInt(startIdx), parseInt(length))).change();//联动 687 } 688 } 689 else if ((result = /\$\{toStr,([^,]+),([^,]+)\}/.exec(value)) != null) { //日期格式转换,又是谁设计的!!! 690 var name = result[1]; 691 var format = result[2]; 692 var form = $(sender).closest('form'); 693 var el = $this.getEl(form, name); 694 if (el.length) { 695 var val = $this.getElDateValue(el); 696 if (val) { 697 var date = new Date(val); 698 var targetValue = $this.getFomatDate(date, format); 699 form.find('[name="' + target + '"]').val(targetValue).change();//联动 700 } 701 } 702 } 703 else { //取值,包括系统值(从服务端)和其它字段值(从客户端),然后计算值 704 var sysName = { 705 }; 706 var reg = /\$\{([^{}]+)\}/g; 707 var i = 0; 708 while ((result = reg.exec(value)) != null) { 709 sysName['[' + i + ']'] = result[1]; 710 i++; 711 } 712 if (i > 0) { //服务端取系统值 713 $.ajax({ 714 url: DefaultUrl + 'Form/GetSysValue', 715 type: 'post', 716 cache: false, 717 data: sysName, 718 success: function (r) { 719 joinControlCallback(sender, target, value, isExpression, r, isDataSource); 720 }, 721 error: function () { 722 alert('取系统值失败!'); 723 } 724 }); 725 } 726 else { 727 joinControlCallback(sender, target, value, isExpression, { 728 }, isDataSource); 729 } 730 } 731 } 732 }; 733 734 function joinControlCallback(sender, target, value, isExpression, sysValue) { 735 try { 736 var form = $(sender).closest('form'); 737 var $target, matches; 738 if (matches = (/([^:]+):item:([^:]+)/gi).exec(target)) 739 $target = getSelectCell(form, matches).cell; 740 else 741 $target = form.find('[name="' + target + '"],[data-name="' + target + '"]'); 742 743 if ($target.length) { 744 var reg = /\$\[([^[\]]+)\]/g; 745 var value = value.replace(reg, function (str, subStr) { 746 if (subStr.substr(0, 1) == '#') { 747 var el = form.find('[name="' + subStr.substr(1) + '"]'); 748 if (el.data('combobox')) 749 return getComboBoxValueText(el).text; 750 } 751 return $this.getElValue(form, subStr); 752 }); 753 reg = /\$\{([^{}]+)\}/g; 754 value = value.replace(reg, function (str, subStr) { 755 return sysValue[subStr]; 756 }); 757 if (isExpression) { 758 value = calcValue(value); 759 } 760 //联动 761 if ($target.is(':text,textarea')) { 762 var ov = $target.val(); 763 if (!(!ov && !value || ov == value)) { 764 $target.val(value); 765 $target.change(); 766 } 767 } 768 else if ($target.is('td')) {//子表的单元格 769 var ov = $target.text(); 770 if (!(!ov && !value || ov == value)) { 771 $target.text(value); 772 $target.parent('tr').data('update', true); 773 $target.closest('.form-table').find('input[name]').change(); 774 } 775 } 776 else if ($target.data('codeimg')) {//二维码条形码 777 require(['form.ctrl.codeimg'], function (obj) { 778 obj.changeVal($target, value); 779 }); 780 } 781 } 782 } 783 catch (err) { 784 alert("脚本错误!"); 785 } 786 787 function calcValue(value) { 788 value = value.replace(/toNumber\(\s*\)/, '0').replace(/roundFloat\(\s*,\s*\d+\s*\)/, '0'); 789 value = eval(value); 790 791 if (isNaN(value) || value == null) 792 return ''; 793 if (typeof (value) == 'number') { 794 var str = String(value); 795 if (/\.[0-9]{8}/.test(str))//脚本坑爹的算术运算 796 str = String(roundFloat(value, 2)); 797 return str; 798 } 799 return String(value); 800 } 801 } 802 803 this.getDataSource = function (sender, sourceId, fields, conditionFields, callback) { 804 var form = $(sender).closest('form'); 805 var data = $this.getParams(form); 806 data.sourceId = sourceId; 807 data.fieldName = fields.length > 0 ? fields[0] : null; 808 for (var i in conditionFields) { 809 var f = conditionFields[i]; 810 var value; 811 if (f == 'ID')//后期或者改成服务端处理 812 value = data.bimId; 813 else 814 value = $this.getElValue(form, f); 815 data['F[' + f + ']'] = value; 816 } 817 $.ajax({ 818 url: DefaultUrl + 'Form/GetFormDataSource', 819 type: 'post', 820 cache: false, 821 data: data, 822 loadingScope: document.body, 823 success: function (r) { 824 for (var i in fields) { 825 var control = form.find('[name="' + fields[i] + '"],[data-name="' + fields[i] + '"]'); 826 if (control.data('combobox')) { 827 var ul = control.siblings('ul'); 828 ul.empty(); 829 for (var j in r.Data) { 830 ul.append($('<li></li>').text(r.Data[j][1]).data('value', r.Data[j][0])); 831 } 832 } 833 else if (control.data('datagrid')) {//查询表单才用 834 var hash = { 835 }; 836 for (var i = 0; i < r.Metadata.length; i++) 837 hash[r.Metadata[i].ID] = i; 838 var box = control.closest('.form-table'); 839 var cols = box.find('table colgroup col'); 840 var map = { 841 }; //映射 842 for (var i = 0; i < cols.length; i++) { 843 var name = cols.eq(i).data('index'); 844 if (name && hash[name] != undefined) { 845 map[i] = { 846 idx: hash[name], col: cols.eq(i) 847 }; 848 } 849 else { 850 map[i] = { 851 col: cols.eq(i) 852 }; 853 } 854 } 855 var tb = box.find('table'); 856 tb.find('tr').remove(); 857 for (var i = 0; i < r.Data.length; i++) { 858 var tr = $('<tr></tr>'); 859 var disabled = box.hasClass('disabled'); 860 var disabledStr = disabled ? 'disabled="disabled"' : ''; 861 for (var j = 0; j < cols.length; j++) { 862 var td = $('<td></td>'); 863 if (!disabled && j == 0) { 864 td.addClass('form-table-edit'); 865 td.append('<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>'); 866 } 867 else if (map[j].idx != undefined) { 868 if (cols.eq(j).data('type') == 'CheckBox') { 869 var v = r.Data[i][map[j].idx]; 870 if (v == 1 || v == '1') 871 td.append('<input type="checkbox" value="1" checked="checked" ' + disabledStr + ' />'); 872 else 873 td.append('<input type="checkbox" value="0" ' + disabledStr + ' />') 874 } 875 else { 876 td.text(r.Data[i][map[j].idx]); 877 } 878 } 879 if (map[j].col.attr('width') == 0) 880 td.addClass('hidden'); 881 tr.append(td); 882 } 883 tb.append(tr); 884 } 885 dataGridTplRender(tb); 886 refreshGridRownum(tb); 887 } 888 else if (control.hasClass('form-chart')) {//图表控件 889 var accountId = r.Data.accountid; 890 if (accountId) { 891 var query = {}, j = 0; 892 for (var i = 0; i < r.Data.conditions.length; i++) { 893 var c = r.Data.conditions[i]; 894 if (c.value) { 895 var empty = true, hasCtrl = false; 896 var v = c.value.replace(/\$\[([^[\]$]+)\]/g, function (str, name) { 897 hasCtrl = true; 898 var elv = $this.getElValue(form, name); 899 if (elv) empty = false; 900 return elv; 901 }); 902 if (!(hasCtrl && c.checkNullField == 'true' && empty)) 903 query['filters[' + (j++) + ']'] = v; 904 } 905 } 906 require(['form.ctrl.chart'], function (c) { 907 c.loadChart(control, accountId, query); 908 }); 909 } 910 } 911 else if (control.is('input') || control.is('textarea')) { 912 if (r.Data.length > 0 && r.Data[0].length > 0) { 913 var value = r.Data[0][0] 914 var change = false; 915 if (control.is(':text,textarea')) { 916 var ov = control.val(); 917 if (!(!ov && !value || ov == value)) 918 change = true; 919 } 920 if (change) { 921 control.val(value); 922 control.change(); 923 } 924 } 925 } 926 } 927 if (callback) 928 callback(r); 929 }, 930 error: function () { 931 alert('数据源' + sourceId + '获取失败。'); 932 } 933 }); 934 }; 935 936 this.getEl = function (form, name) { 937 return form.find('[name="' + name + '"]'); 938 }; 939 940 this.getElValue = function (form, name) { //获得元素值 941 var val = ''; 942 var matches; 943 if (matches = (/([^:]+):format:([^:]+)/gi).exec(name)) {//时间格式 944 name = matches[1]; 945 var f = matches[2]; 946 var el = form.find('[name="' + name + '"]'); 947 if (el.hasClass('datetime')) { 948 var dateStr = this.getElDateValue(el); 949 if (dateStr) { 950 var date = new Date(dateStr); 951 val = this.getFomatDate(date, f); 952 } 953 } 954 else { 955 val = el.val(); 956 } 957 } 958 else if (matches = (/([^:]+):item:([^:]+)/gi).exec(name)) { //选中行的值 959 var elInfo = getSelectCell(form, matches); 960 name = elInfo.name; 961 if (elInfo.cell.length) 962 val = elInfo.cell.text(); 963 } 964 else if (matches = (/([^:]+):sum:([^:]+)/gi).exec(name)) { //计算子表列总和 965 name = matches[1]; 966 var colname = matches[2]; 967 var el = form.find('[name="' + name + '"]').parent(); 968 var table = el.find('table'); 969 var idx = -1; 970 var sum = 0; 971 var err = false; 972 table.find('colgroup:first').find('col').each(function (i, e) { 973 if ($(e).data('index') == colname) 974 idx = i; 975 }); 976 if (idx > -1) { 977 table.find('tr').each(function (i, e) { 978 if ($(e).is(':visible')) { 979 var num = $(e).find('td').eq(idx).text(); 980 if (num != null && num != '') { 981 var v = parseFloat(num); 982 if (isNaN(v)) { 983 if (!err) { 984 alert(num + '不是数字'); 985 err = true; 986 } 987 } 988 else 989 sum += v; 990 } 991 } 992 }); 993 } 994 if (err) val = ''; 995 else val = sum.toString(); 996 } 997 else if (matches = /#([^#]+)/.exec(name)) { 998 var el = form.find('[name="' + matches[1] + '"]'); 999 if (el.data('combobox')) 1000 val = getComboBoxValueText(el).text; 1001 } 1002 else { 1003 var el = form.find('[name="' + name + '"]'); 1004 if (el.data('combobox')) 1005 val = getComboBoxValueText(el).value; 1006 else 1007 val = el.val(); 1008 } 1009 if (val != null) 1010 return val; 1011 else return ''; 1012 }; 1013 1014 function getComboBoxValueText(input) { 1015 var val = input.val(); 1016 var ul = input.siblings('ul'); 1017 var lis = ul.find('li'); 1018 for (var i = 0; i < lis.length; i++) { 1019 var li = lis.eq(i) 1020 var text = li.text(); 1021 if (!val && !text || val == text) { 1022 return { 1023 value: li.data('value'), text: text 1024 }; 1025 } 1026 } 1027 return { 1028 value: input.val(), text: input.val() 1029 }; 1030 } 1031 1032 function getSelectCell(form, matches) { 1033 var name = matches[1]; 1034 var colname = matches[2]; 1035 var table = $(form).find('[name="' + name + '"]').closest('.form-table').find('table'); 1036 var tr = table.find('tr.active'); 1037 var cell; 1038 if (tr.length) { 1039 var idx = -1; 1040 table.find('colgroup').find('col').each(function (i, e) { 1041 if ($(e).data('index') == colname) 1042 idx = i; 1043 }); 1044 if (idx > -1) { 1045 cell = tr.find('td').eq(idx); 1046 } 1047 } 1048 return { name: name, cell: cell ? cell : $() }; 1049 } 1050 1051 this.formatValue = function (form, value) { 1052 return value.replace(/\$\[([^[\]$]+)\]/, function (str, name) { 1053 return $this.getElValue(form, name); 1054 }); 1055 } 1056 1057 this.getFomatDate = function (date, format) { 1058 return format.replace(/y+/gi, function (str) { 1059 var year = date.getFullYear().toString(); 1060 if (str.length == 2) 1061 return year.length > 1 ? year.substr(year.length - 2) : year; 1062 return year; 1063 }).replace(/m+/gi, function (str) { 1064 var month = (date.getMonth() + 1).toString(); 1065 if (str.length == 2) 1066 return month.length > 1 ? month : '0' + month; 1067 return month; 1068 }).replace(/d+/gi, function (str) { 1069 var day = date.getDate().toString(); 1070 if (str.length == 2) 1071 return day.length > 1 ? day : '0' + day; 1072 return day; 1073 }).replace(/h+/gi, function (str) { 1074 var hour = date.getHours().toString(); 1075 if (str.length == 2) 1076 return hour.length > 1 ? hour : '0' + hour; 1077 return hour; 1078 }).replace(/i+/gi, function (str) { 1079 var minute = date.getMinutes().toString(); 1080 if (str.length == 2) 1081 return minute.length > 1 ? minute : '0' + minute; 1082 return minute; 1083 }).replace(/s+/gi, function (str) { 1084 var second = date.getSeconds().toString(); 1085 if (str.length == 2) 1086 return second.length > 1 ? second : '0' + second; 1087 return second; 1088 }); 1089 }; 1090 1091 this.getElDateFormat = function (el) { 1092 var format = $(el).data('date-format'); 1093 if (!format) //yyyy-mm-dd hh:ii:ss 1094 format = 'yyyy-m-d'; 1095 else 1096 format = format.replace(/y+/gi, 'yyyy') 1097 .replace(/m+/gi, 'm') 1098 .replace(/d+/gi, 'd') 1099 .replace(/h+/gi, 'h') 1100 .replace(/i+/gi, 'i') 1101 .replace(/s+/gi, 's'); 1102 return format; 1103 } 1104 1105 this.getElDateValue = function (el, format) { 1106 var value = $(el).val(); 1107 if (value) { 1108 if (!format) { 1109 format = this.getElDateFormat(el); 1110 } 1111 var year, month, day, hour, minute, second; 1112 var replace = []; 1113 var regex = new RegExp('^' + format.replace(/y+|m+|d+|h+|i+|s+/gi, function (str) { 1114 replace.push(str); 1115 return '(\\d+)' 1116 }) + '$'); 1117 var matches = regex.exec(value); 1118 if (matches) { 1119 for (var i = 0; i < replace.length; i++) { 1120 var replaceStr = replace[i]; 1121 var replaceValue = matches[i + 1]; 1122 switch (replaceStr) { 1123 case 'yyyy': year = replaceValue; break; 1124 case 'm': month = replaceValue; break; 1125 case 'd': day = replaceValue; break; 1126 case 'h': hour = replaceValue; break; 1127 case 'i': minute = replaceValue; break; 1128 case 's': second = replaceValue; break; 1129 } 1130 } 1131 return validateDate(parseInt(year, 10), parseInt(month, 10), parseInt(day, 10), parseInt(hour, 10), parseInt(minute, 10), parseInt(second, 10)); 1132 } 1133 } 1134 }; 1135 1136 function validateDate(year, month, day, hour, minute, second) { //校验日期是否合法 1137 if (!isNaN(year) && (year < 100 || year > 9999)) //js:[100,未知] .net,oracle:[1,9999] 1138 return; 1139 if (!isNaN(month) && (month < 1 || month > 12)) 1140 return; 1141 if (!isNaN(day)) { 1142 if (!isNaN(year) && !isNaN(month)) { 1143 var maxDay; 1144 if (month == 2) {//检测闰年 1145 if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0) 1146 maxDay = 29; 1147 else 1148 maxDay = 28; 1149 } 1150 else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) 1151 maxDay = 31; 1152 else 1153 maxDay = 30; 1154 if (day < 1 || day > maxDay) 1155 return; 1156 } 1157 else 1158 return; 1159 } 1160 if (!isNaN(hour) && (hour < 0 || hour > 23)) 1161 return; 1162 if (!isNaN(minute) && (minute < 0 || minute > 59)) 1163 return; 1164 if (!isNaN(second) && (second < 0 || second > 59)) 1165 return; 1166 1167 return (isNaN(year) ? '100' : year) + '/' + 1168 (isNaN(month) ? '1' : month) + '/' + 1169 (isNaN(day) ? '1' : day) + ' ' + 1170 (isNaN(hour) ? '0' : hour) + ':' + 1171 (isNaN(minute) ? '0' : minute) + ':' + 1172 (isNaN(second) ? '0' : second); 1173 } 1174 1175 this.validateForm = function (form, invalidHandler) { 1176 if ($.fn.validate) { 1177 $(form).data('invalid-handler', invalidHandler) 1178 var validator = $(form).validate({ 1179 showErrors: function (errMap, errList) { 1180 this.defaultShowErrors(); 1181 }, 1182 errorPlacement: function (label, element) { 1183 $(form).append(label); 1184 var el = $(element); 1185 if ($(element).css('position') != 'absolute') { 1186 var closest = element.parentsUntil('form'); 1187 for (var i = closest.length - 1; i >= 0; i--) { 1188 if (closest.eq(i).css('position') == 'absolute') { 1189 el = closest.eq(i); 1190 break; 1191 } 1192 } 1193 } 1194 var left = parseFloat(el.css('left').substring(0, el.css('left').length - 2)); 1195 var top = parseFloat(el.css('top').substring(0, el.css('top').length - 2)); 1196 left = isNaN(left) ? 0 : left; 1197 top = isNaN(top) ? 0 : top; 1198 label.css('position', 'absolute') 1199 .css('left', left) 1200 .css('top', top + $(element).outerHeight()); 1201 1202 }, 1203 invalidHandler: function (ev, validator) { 1204 var invalidHandler = $(form).data('invalid-handler'); 1205 if (invalidHandler) 1206 invalidHandler(ev, validator); 1207 }, 1208 ignore: '' 1209 }); 1210 return validator.form(); 1211 } 1212 return false; 1213 }; 1214 1215 this.submitForm = function (form, callback, maskBody, invalidHandler) { //包含验证 1216 if ($(form).data('beforesave') && (function () { eval($(form).data('beforesave')) }).apply(form) == false) 1217 return; 1218 if ($this.validateForm(form, invalidHandler)) 1219 $this.saveForm(form, callback, maskBody); 1220 }; 1221 1222 this.saveForm = function (form, callback, maskBody, checkRule) { 1223 var data = $this.getFormData(form); 1224 data.checkRule = checkRule; 1225 $.ajax({ 1226 url: DefaultUrl + 'Form/Edit', 1227 data: data, 1228 type: 'POST', 1229 cache: false, 1230 loadingScope: document.body, 1231 success: function (r) { 1232 if (r.result == 'SUCCESS') { 1233 $(form).data('dirty', false); 1234 if (window.localStorage) 1235 require(['form.storage'], function (s) { 1236 s.onsave(form); 1237 }); 1238 if (callback) 1239 callback(r); 1240 } 1241 else if (r.result) { 1242 alert('《' + $(form).data('title') + '》保存失败:' + r.message); 1243 } 1244 else { 1245 DCI.systemRule.showRuleDialog(r, function (dialogId) { 1246 $this.saveForm(form, callback, maskBody, true); 1247 }); 1248 } 1249 }, 1250 error: function () { 1251 alert('《' + $(form).data('title') + '》保存失败。'); 1252 } 1253 }); 1254 }; 1255 1256 this.getFormData = function (form) { 1257 var data = $this.getParams(form); 1258 $this.getGridData(form); //子表 1259 form.find('input:text,input:checkbox,input:radio,input:hidden,textarea').each(function (i, el) { 1260 if ($(el).data('dirty') || $(el).data('submit')) { 1261 var name = $(el).attr('name'); 1262 if (name) { 1263 if ($(el).hasClass('datetime')) { 1264 data['F[' + name + ']'] = $this.getElDateValue($(el)); 1265 } 1266 else if ($(el).data('combobox')) { 1267 var valueText = getComboBoxValueText($(el)); 1268 data['F[' + name + ']'] = valueText.value; 1269 data['F[#' + name + ']'] = valueText.text; 1270 } 1271 else if ($(el).is(':radio')) { 1272 data['F[' + $(el).data('name') + ']'] = $(el).val(); 1273 } 1274 else if ($(el).data('getdata')) { 1275 data['F[' + name + ']'] = $(el).data('getdata')(); 1276 } 1277 else { 1278 data['F[' + name + ']'] = $(el).val(); 1279 } 1280 } 1281 } 1282 }); 1283 return data; 1284 } 1285 1286 this.getGridData = function (form) { 1287 $(form).find('table').each(function (idx, tb) { 1288 var container = $(tb).parents('.form-table'); 1289 var input = container.children('input[name]'); 1290 if (input.data('dirty')) { 1291 var data = { 1292 insert: [], update: [], del: [], idCol: 0, cols: [] 1293 }; 1294 var rowIdCol = -1; //行标识所在列 1295 var sCol = []; //记录要提交的列 1296 $(tb).find('colgroup col').each(function (idx, col) { 1297 var colName = $(col).data('index'); 1298 if (colName) { 1299 if (colName == 'IID') 1300 rowIdCol = idx; 1301 data.cols.push(colName); 1302 sCol[idx] = true; 1303 } 1304 }); 1305 1306 $(tb).find('tr').each(function (idx, tr) { 1307 if ($(tr).data('delete')) { //删除 1308 var rowId = $(tr).find('td').eq(rowIdCol).text(); 1309 data.del.push(rowId); 1310 } 1311 else if ($(tr).data('insert')) { //插入 1312 data.insert.push(getRowData(tr, sCol)); 1313 } 1314 else if ($(tr).data('update')) { //更新 1315 data.update.push(getRowData(tr, sCol)); 1316 } 1317 }); 1318 1319 input.val(JSON.stringify(data)); 1320 } 1321 }); 1322 1323 function getRowData(tr, sCol) { 1324 var data = []; 1325 $(tr).find('td').each(function (idx, el) { 1326 if (sCol[idx]) { 1327 var ipt = $(el).find('input'); 1328 if (ipt.length > 0) { 1329 data.push(ipt.val()) 1330 } 1331 else { 1332 data.push($(el).text()); 1333 } 1334 } 1335 }); 1336 return data; 1337 } 1338 }; 1339 1340 function refreshGridRownum(table) { 1341 var idx = -1; 1342 $(table).find('colgroup:first col').each(function (i, e) { 1343 if ($(e).data('type') == 'RowNumber') { 1344 idx = i; 1345 } 1346 }); 1347 if (idx > -1) { 1348 var rownum = 0; 1349 $(table).find('tr').each(function (i, e) { 1350 if (!$(e).data('delete')) 1351 $(e).find('td').eq(idx).text(++rownum); 1352 }); 1353 } 1354 } 1355 1356 this.getParams = function (form) { 1357 var iid = form.data('iid'); 1358 var bimId = form.data('bimid'); 1359 var formId = form.data('formid'); 1360 var actId = form.data('actid'); 1361 var contextId = form.data('contextid'); 1362 var key = form.data('key'); 1363 return { 1364 iid: iid, bimId: bimId, formId: formId, actId: actId, contextId: contextId, key: key 1365 }; 1366 }; 1367 1368 this.showForm = function (data, callback, closeCallback, loadCallback) { 1369 var fromName = "ShowForm"; 1370 if (data.fromName) fromName = data.fromName;//默认为ShowForm 1371 data.key = data.contextId; 1372 data.dialogId = 'Dialog_' + fromName; 1373 var url = DefaultUrl + 'Form/Dialog_ShowForm'; 1374 showAjaxDialog(data.dialogId, url, data, true, document.body, function (state, data) { 1375 if (state == 'ok') { 1376 if (callback) 1377 callback(data); 1378 } else { 1379 if (closeCallback) 1380 closeCallback(data); 1381 } 1382 }, function (data, btn) { 1383 var showform = $('#Dialog_' + fromName).find('form'); 1384 //if (!showform.data('readonly')) 1385 $this.openFormCallback(showform);//初始化控件 1386 if (loadCallback) 1387 loadCallback(data) 1388 //DCI.systemRule.showRuleDialog_Added(null, btn); 1389 }); 1390 }; 1391 1392 this.showModifyFields = function (form) { 1393 if ($(form).is(':visible') && !$(form).data('readmark-loaded')) { 1394 $(form).data('readmark-loaded', true); 1395 $(form).find('span.readMark').remove(); 1396 var b = $this.getParams(form); 1397 $.ajax({ 1398 url: DefaultUrl + 'Form/GetModifyFields', 1399 data: { 1400 iid: b.iid, formId: b.formId 1401 }, 1402 type: 'post', 1403 loadingScope: document.body, 1404 success: function (r) { 1405 for (var i in r) { 1406 var element = $this.getEl(form, r[i]); 1407 if (element.length && element.is(':visible')) { 1408 element.data('modified', true); 1409 var el = element; 1410 if (element.css('position') != 'absolute') { 1411 var closest = element.parentsUntil('form'); 1412 for (var i = closest.length - 1; i >= 0; i--) { 1413 if (closest.eq(i).css('position') == 'absolute') { 1414 el = closest.eq(i); 1415 break; 1416 } 1417 } 1418 } 1419 var left = parseFloat(el.css('left').substring(0, el.css('left').length - 2)); 1420 var top = parseFloat(el.css('top').substring(0, el.css('top').length - 2)); 1421 left = isNaN(left) ? 0 : left; 1422 top = isNaN(top) ? 0 : top; 1423 $('<span class="readMark"></span>').css('position', 'absolute') 1424 .css('left', left + el.outerWidth()) 1425 .css('top', top) 1426 .appendTo($(form)); 1427 } 1428 } 1429 }, 1430 error: function () { 1431 alert('修改痕迹获取失败。'); 1432 } 1433 }); 1434 } 1435 }; 1436 1437 this.removeModifyMark = function (form) { 1438 $(form).data('readmark-loaded', false); 1439 $(form).find('span.readMark').remove(); 1440 }; 1441 }; 1442 1443 window.toNumber = function (str) { 1444 if (str) 1445 return parseFloat(str); 1446 return 0; 1447 } 1448 1449 window.roundFloat = function (number, digits) { 1450 return Math.round(number * Math.pow(10, digits)) / Math.pow(10, digits); 1451 } 1452 1453 $(function () { 1454 require(['css!form.style']); 1455 require(['jquery.validate'], function () { 1456 $.extend($.validator.messages, { 1457 'required': '这是必填项' 1458 }); 1459 $.validator.addMethod("pattern", function (value, element, param) { 1460 if (!value) { 1461 return true; 1462 } 1463 if (typeof param === "string") { 1464 param = new RegExp("^(?:" + param + ")$"); 1465 } 1466 return param.test(value); 1467 }, "输入的格式不正确"); 1468 1469 $.validator.addMethod("datetime", function (value, element) { 1470 if (!value) 1471 return true; 1472 var val = form_handler.getElDateValue($(element)); 1473 if (val) return true; 1474 return false; 1475 }, "日期时间不正确"); 1476 1477 $.validator.addMethod('MaxNumber', function (value, element, param) { 1478 return compareNumber.call(this, value, element, param, function (a, b) { 1479 if (isNaN(b) || !isNaN(a) && a <= b) 1480 return true; 1481 $(element).data('msg-MaxNumber', '请输入小于或等于' + b + '的数值'); 1482 return false; 1483 }); 1484 }, function (param, element) { 1485 return $(element).data('msg-MaxNumber'); 1486 }); 1487 1488 $.validator.addMethod('MinNumber', function (value, element, param) { 1489 return compareNumber.call(this, value, element, param, function (a, b) { 1490 if (isNaN(b) || !isNaN(a) && a >= b) 1491 return true; 1492 $(element).data('msg-MinNumber', '请输入大于或等于' + b + '的数值'); 1493 return false; 1494 }); 1495 }, function (param, element) { 1496 return $(element).data('msg-MinNumber'); 1497 }); 1498 1499 $.validator.addMethod('DecimalDigits', function (value, element, param) { 1500 if (!value) 1501 return true; 1502 if (isNumber(value)) { 1503 var len = 0; 1504 var dotIdx = value.lastIndexOf('.'); 1505 if (dotIdx > -1) { 1506 var digit = value.substr(dotIdx + 1); 1507 var zEnd = 0; 1508 for (var i = digit.length - 1; i >= 0; i--) { 1509 if (digit[i] == '0') zEnd++; 1510 else break; 1511 } 1512 len = digit.length - zEnd; 1513 } 1514 if (len <= param) 1515 return true; 1516 } 1517 return false; 1518 }, '请输入小数最多精确到{0}位的数值'); 1519 1520 $.validator.addMethod('MaxDatetime', function (value, element, param) { 1521 return compareDateTime.call(this, value, element, param, function (a, b, str) { 1522 if (b == 'Invalid Date' || a != 'Invalid Date' && a <= b) 1523 return true; 1524 $(element).data('msg-MaxDatetime', '请输入小于或等于' + str + '的日期时间'); 1525 }); 1526 }, function (param, element) { 1527 return $(element).data('msg-MaxDatetime'); 1528 }); 1529 1530 $.validator.addMethod('MinDatetime', function (value, element, param) { 1531 return compareDateTime.call(this, value, element, param, function (a, b, str) { 1532 if (b == 'Invalid Date' || a != 'Invalid Date' && a >= b) 1533 return true; 1534 $(element).data('msg-MinDatetime', '请输入大于或等于' + str + '的日期时间'); 1535 }); 1536 }, function (param, element) { 1537 return $(element).data('msg-MinDatetime'); 1538 }); 1539 1540 function isNumber(value) { 1541 return /^[0-9]+(?:\.[0-9]+){0,1}$/.test(value); 1542 } 1543 1544 function compareNumber(value, element, param, fn) { 1545 if (!value) 1546 return true; 1547 var n = isNumber(value) ? parseFloat(value) : NaN; 1548 var n2 = NaN; 1549 if (typeof param === 'number') { 1550 n2 = param; 1551 } 1552 else if (typeof param === 'string') { 1553 var m = /\$\[([^[\]]+)\]/.exec(param); 1554 if (m) { 1555 var form = $(element).closest('form'); 1556 var relVal = form_handler.getElValue(form, m[1]); 1557 n2 = isNumber(relVal) ? parseFloat(relVal) : NaN; 1558 } 1559 } 1560 return fn(n, n2); 1561 } 1562 1563 function compareDateTime(value, element, param, fn) { 1564 if (!value) 1565 return true; 1566 var t = new Date(form_handler.getElDateValue($(element))), t2, str; 1567 var m = /\$\[([^[\]]+)\]/.exec(param); 1568 if (m) { 1569 var form = $(element).closest('form'); 1570 var relEl = form_handler.getEl(form, m[1]); 1571 t2 = new Date(form_handler.getElDateValue(relEl)); 1572 str = relEl.val(); 1573 } 1574 else { 1575 t2 = new Date(param); 1576 str = form_handler.getFomatDate(t2, form_handler.getElDateFormat($(element))); 1577 } 1578 return fn(t, t2, str); 1579 } 1580 }); 1581 1582 $(document).on('mousedown', function (e) { 1583 if ($(e.target).closest('.data-picker .dropdown-menu').length === 0) //下拉框 1584 $('.form-content .data-picker>ul').hide(); 1585 if ($(e.target).closest('.PS-allPeopleList').length === 0) //人员选择框 1586 $('.form-content .PS-allPeopleList').remove(); 1587 if ($(e.target).closest('.user-picker').length === 0)//人员筛选列表 1588 $('.user-picker .user-picker-search-list').hide(); 1589 }); 1590 1591 $(document).on('click', '.form-content .data-picker>span,.form-content .data-picker>input.dropdown', null, function (e) { 1592 var picker = $(e.currentTarget).closest('.data-picker'); 1593 var input = picker.find('input') 1594 if (!input.attr('readonly')) { 1595 picker.find('ul').show(); 1596 var val = input.val(); 1597 var ul = input.siblings('ul'); 1598 var lis = ul.find('li').removeClass('selected'); 1599 for (var i = 0; i < lis.length; i++) { 1600 var li = lis.eq(i); 1601 var text = li.text(); 1602 if (!val && !text || val == text) { 1603 li.addClass('selected'); 1604 break; 1605 } 1606 } 1607 } 1608 }); 1609 1610 $(document).on('click', '.form-content .data-picker li', null, function (e) { 1611 var picker = $(this).closest('.data-picker'); 1612 var input = picker.find('input'); 1613 if (!$(this).hasClass('selected')) 1614 input.val($(this).text()).change(); 1615 var idxchange = input.data('indexchange'); 1616 if (idxchange) { 1617 (function () { 1618 eval(idxchange); 1619 }).call(input); 1620 } 1621 picker.find('ul').hide(); 1622 }); 1623 }); 1624 }
4.Grid控件的数据保存
Grid控件其实就是一个div,公司的一些页面表单都是动态生成的,表单上面的控件也是动态生成的,所有很多东西都是自己手写的。下面是Grid控件的结构。
<div class="FM000103-SBCLBJ form-table "> <input data-datagrid="true" data-formid="FM000034" name="SBCLBJ" type="hidden" /> <input data-param="init" type="hidden" value="{"ID":"$[ID]","IID":"$(autoid)"}" /> <input data-param="initsame" type="hidden" value="[]" /> <div class="form-table-header"> <div style="width:48px;"> 编辑 </div> <div style="width:50px;"> 序号 </div> <div style="width:60px;"> 是否上传 </div> <div style="width:380px;"> 申报材料内容 </div> <div style="width:80px;"> 备注 </div> </div> <div class="form-table-body"> <table class="table-hover"> <colgroup span="6"> <col width="48" /> <col width="50" data-type="RowNumber" /> <col width="0" data-type="Label" data-index="ID" class="hidden" /> <col width="0" data-type="Label" data-index="IID" class="hidden" /> <col width="60" data-type="CheckBox" data-index="CDZL" /> <col width="380" data-type="TextArea" data-index="ATDESC" /> <col width="80" data-type="TextArea" data-index="BZ" /> </colgroup> <tbody> <tr> <td class="form-table-edit"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></td> <td>1</td> <td class="hidden">BM00001141</td> <td class="hidden">4643</td> <td><input type="checkbox" value="1" checked="checked" /></td> <td>11111</td> <td>2222</td> </tr> <tr> <td class="form-table-edit"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span></td> <td>2</td> <td class="hidden">BM00001141</td> <td class="hidden">4644</td> <td><input type="checkbox" value="0" /></td> <td>87789789789798789</td> <td>333</td> </tr> </tbody> </table> </div> <div class="form-table-footer"> <button type="button" class="btn add-row">新增</button> <button type="button" class="btn del-row">删除</button> </div> </div>
下面是完成Grid数据保存的js.
1 /** 2 * 功能:保存用户修改完form标签内容在LocalStorage中。 3 * 作者:黄金锋 (549387177@qq.com) 4 * 日期:2015-11-1 11:14:01 5 * 修改:2015-11-19 16:09:00 6 * 版本:version 3.0 7 */ 8 9 define(function () { 10 11 //从localStorage中加载数据 12 function onload(form) { 13 14 var fh = form_handler; 15 var p = fh.getParams(form); 16 if (!p.bimId || !p.formId || !p.iid) { 17 return; 18 } 19 var id = 'FORM_' + DCI.LoginUser.UserId + '_' + p.bimId + '_' + p.formId + '_' + p.iid; 20 21 var formDataDb; 22 var allControl = $(form).find("input:text[name],textarea[name]"); 23 24 //从本地取 25 var storage = localStorage.getItem(id); 26 if (storage != null) 27 { 28 if (confirm("是否加载缓存数据")) { 29 30 var myData = JSON.parse(storage); 31 allControl.each(function (i, e) { 32 var name = $(e).attr("name"); 33 if (myData[name] != null) { 34 $(e).val(myData[name]); 35 $(e).change(); 36 } 37 }); 38 } 39 } 40 41 var allGrid = $(form).find(".form-table"); 42 var formId = $(form).data("formid"); 43 var formStorage= localStorage.getItem("FORM_" + formId + "_isGridData"); 44 if (formStorage=="1") 45 { 46 if (confirm("是否加载Grid缓存数据")) 47 { 48 //给Grid控件赋值 49 allGrid.each(function (index, element) { 50 var formName = $(element).find("input:hidden[data-formid]").attr("name"); 51 var ipt = $(element).find("input[name]"); 52 var table = $(element).find("input:hidden[data-formid]").siblings(".form-table-body").find(".table-hover"); 53 var storageKey = "FORM_" + formId + "_" + formName; 54 var data = localStorage.getItem(storageKey); 55 var myData = JSON.parse(data); 56 if (myData != null) { 57 alert(data); 58 var InsertTotal = myData["Total"]["InsertTotal"]; 59 var DelTotal = myData["Total"]["DelTotal"]; 60 var UpdateTotal = myData["Total"]["UpdateTotal"]; 61 var trIIDIndex = myData["trIIDIndex"]["IID"]; 62 if (InsertTotal > 0) { 63 for (var i = 0; i < InsertTotal; i++) { 64 var tr = $('<tr></tr>'); 65 var row_data = myData["Insert"][i]; 66 table.find('colgroup col').each(function (idx, el) { 67 var td = $('<td></td>'); 68 if (idx == 0) { 69 td.append('<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>'); 70 td.addClass('form-table-edit'); 71 } 72 else { 73 var index = $(el).data('index'); 74 var type = $(el).data('type') 75 if (type == "RowNumber") { 76 var val = row_data["RowNumber"]; 77 td.html(val); 78 } 79 if (type == "CheckBox") { 80 var val = row_data[index]; 81 td.append('<input type="checkbox" value="' + val + '" ' + (val == '1' ? 'checked="checked"' : '') + ' />'); 82 } 83 if (index && type != "CheckBox") { 84 td.html(row_data[index]); 85 } 86 } 87 if ($(el).attr('width') == '0') 88 td.addClass('hidden'); 89 td.appendTo(tr); 90 }); 91 //table.find("tbody").append(tr); 92 table.append(tr); 93 94 tr.data("insert", true); 95 ipt.change(); 96 } 97 } 98 99 if (UpdateTotal > 0) { 100 101 for (var i = 0; i < UpdateTotal; i++) { 102 var row_data = myData["Update"][i]; 103 var trIID = row_data["trIID"]; 104 var trIndex; 105 table.find("tr").each(function (idx, ele) 106 { 107 var iid = $(ele).find("td").eq(trIIDIndex).html(); 108 if (iid == trIID) { 109 trIndex = idx; 110 } 111 }); 112 113 var cells = table.find("tr").eq(trIndex); 114 table.find('colgroup col').each(function (idx, el) 115 { 116 var index = $(el).data('index'); 117 if (index) 118 { 119 var td = cells.find("td").eq(idx); 120 var type = $(el).data('type'); 121 var test =new Object(); 122 123 var text = row_data[index]; 124 125 if (type == 'CheckBox') 126 { 127 128 var ck = td.find('input[type="checkbox"]'); 129 if (text == '1') 130 ck.prop('checked', true); 131 else 132 ck.prop('checked', false); 133 } 134 else 135 { 136 td.text(text); 137 } 138 } 139 }); 140 cells.data("update", true); 141 ipt.change(); 142 143 } 144 } 145 146 if (DelTotal > 0) { 147 for (var i = 0; i < DelTotal; i++) { 148 var row_data = myData["Del"][i]; 149 var trIID = row_data["trIID"]; 150 table.find("tr").each(function (idx,ele) { 151 var iid = $(ele).find("td").eq(trIIDIndex).html(); 152 if ( iid== trIID) 153 { 154 $(this).css("display", "none"); 155 $(this).data("delete", true); 156 ipt.change(); 157 } 158 }); 159 160 } 161 } 162 163 164 } 165 }); 166 } 167 } 168 169 170 171 //绑定change事件 172 allControl.each(function (i, el) { 173 var name = $(el).attr('name'); 174 if (name) { 175 $(el).on('change', function () { 176 onchange(this); 177 }); 178 } 179 }); 180 181 //保存修改的数据 182 function onchange(el) { 183 var storage = localStorage.getItem(id); 184 if (storage == null) { 185 formDataDb = new Object(); 186 var key = $(el).attr("name"); 187 var value = $(el).val(); 188 formDataDb[key] = value; 189 localStorage.setItem(id, JSON.stringify(formDataDb)); 190 } else { 191 var myData = JSON.parse(storage); 192 var key = $(el).attr("name"); 193 var value = $(el).val(); 194 myData[key] = value; 195 localStorage.setItem(id, JSON.stringify(myData)); 196 } 197 } 198 }; 199 200 //删除localStorage中的数据 201 function onsave(form) { 202 var fh = form_handler; 203 var p = fh.getParams(form); 204 var id = 'FORM_' + DCI.LoginUser.UserId + '_' + p.bimId + '_' + p.formId + '_' + p.iid; 205 localStorage.removeItem(id); 206 207 208 var allGrid = $(form).find(".form-table"); 209 var formId = $(form).data("formid"); 210 allGrid.each(function (index,element) { 211 var formName = $(element).find("input:hidden[data-formid]").attr("name"); 212 var storageKey = "FORM_" + formId + "_" + formName; 213 localStorage.removeItem(storageKey); 214 }); 215 216 localStorage.setItem("FORM_" + formId + "_isGridData", null); 217 } 218 219 function ongridadd(form, table, data, tr) { 220 var inputflag = table.closest("div .form-table").find("input:hidden[data-formid]") 221 var storageKey; 222 var formId = $(form).data("formid");; 223 localStorage.setItem("FORM_" + formId + "_isGridData", "1"); 224 var RowNumber = table.find(".active").children().eq(1).html(); 225 var trIIDIndex; 226 var trIID; 227 table.find("col").each(function (idx, ele) { 228 if ($(ele).data("index") == "IID") { 229 trIID = table.find(".active").children().eq(idx).html(); 230 trIIDIndex = idx; 231 } 232 }); 233 var InsertObj = { trIID: trIID, RowNumber: RowNumber }; 234 235 var columnArr = table.children().find("[data-index]"); 236 if (columnArr) { 237 columnArr.each(function (index, element) { 238 var flag = $(element).data("index"); 239 InsertObj[flag] = data[flag]; 240 }); 241 } 242 243 if (inputflag && trIID) 244 { 245 storageKey = "FORM_" + formId + "_" + inputflag.attr("name"); 246 //var mydata = "{'Insert':[{'trIID':'1','ID':'test','IID':'测试'},{'trIID':'2','ID':'test2','IID':'测试2'}],'Update':[{'trIID':'3','ID':'test3','IID':'测试3'},{'trIID':'4','ID':'test4','IID':'测试4'}],'Del':[{'trIID':'1'},{'trIID':'2'}]}"; 247 248 var getLocalStorage = localStorage.getItem(storageKey); 249 if (getLocalStorage) { 250 251 var dataObj = JSON.parse(getLocalStorage); 252 var InsertTotal = dataObj["Total"]["InsertTotal"]; 253 254 dataObj["Insert"][InsertTotal] = InsertObj; 255 dataObj["Total"]["InsertTotal"] = InsertTotal + 1; 256 localStorage.setItem(storageKey, JSON.stringify(dataObj)); 257 258 } else 259 { 260 var mydata = { Total: { InsertTotal: 1, UpdateTotal: 0, DelTotal: 0 }, Insert: [InsertObj], Update: [], Del: [], Notes: { storageKey: storageKey }, trIIDIndex: { IID: trIIDIndex } }; 261 localStorage.setItem(storageKey, JSON.stringify(mydata)); 262 } 263 } 264 265 } 266 267 function ongridedit(form, table, data, tr) { 268 269 var inputflag = table.closest("div .form-table").find("input:hidden[data-formid]") 270 var formId = $(form).data("formid"); 271 var storageKey = "FORM_" + formId + "_" + inputflag.attr("name"); 272 localStorage.setItem("FORM_" + formId + "_isGridData", "1"); 273 var mySourceData = {}; 274 var trIIDIndex; 275 table.find("col").each(function (idx, ele) 276 { 277 var index = $(ele).data("index"); 278 var type = $(ele).data("type"); 279 if (index) 280 { 281 if (type == "CheckBox") 282 { 283 var val = table.find(".active").children().eq(idx).html(); 284 var value =$(val).val(); 285 mySourceData[index] = value; 286 } 287 else 288 { 289 if (index == "IID") 290 { 291 trIIDIndex = idx; 292 } 293 mySourceData[index] = table.find(".active").children().eq(idx).html(); 294 } 295 } 296 }); 297 298 var trIID = mySourceData["IID"]; 299 var UpdateObj = { trIID: trIID }; 300 $.extend(UpdateObj, mySourceData); 301 302 var getLocalStorage = localStorage.getItem(storageKey); 303 if (getLocalStorage) 304 { 305 var dataObj = JSON.parse(getLocalStorage); 306 var InsertTotal = dataObj["Total"]["InsertTotal"]; 307 var UpdateTotal = dataObj["Total"]["UpdateTotal"]; 308 309 310 311 if (InsertTotal > 0)//新增后在编辑 312 { 313 for (var i = 0; i < InsertTotal; i++) { 314 var row_data = dataObj["Insert"][i]; 315 if (row_data["trIID"] == trIID) { 316 $.extend(dataObj["Insert"][i], UpdateObj); 317 } 318 } 319 } 320 321 if (UpdateTotal > 0)//编辑之后在编辑 322 { 323 for (var i = 0; i < UpdateTotal; i++) { 324 var row_data = dataObj["Update"][i]; 325 if (row_data["trIID"] == trIID) { 326 $.extend(dataObj["Update"][i], UpdateObj); 327 } 328 } 329 } 330 331 var UpdateTotal = dataObj["Total"]["UpdateTotal"]; 332 dataObj["Update"][UpdateTotal] = UpdateObj; 333 dataObj["Total"]["UpdateTotal"] = UpdateTotal + 1; 334 335 336 localStorage.setItem(storageKey, JSON.stringify(dataObj)); 337 } 338 else 339 { 340 341 var mydata = { Total: { InsertTotal: 0, UpdateTotal: 1, DelTotal: 0 }, Insert: [], Update: [UpdateObj], Del: [], Notes: { storageKey: storageKey }, trIIDIndex: { IID: trIIDIndex } }; 342 localStorage.setItem(storageKey, JSON.stringify(mydata)); 343 } 344 345 346 var testdata = localStorage.getItem(storageKey); 347 var myData = JSON.parse(testdata); 348 if (testdata != null) { 349 alert(testdata); 350 //alert(mydata); 351 //alert(myData["Total"]["InsertTotal"]); 352 //alert(myData["Insert"][0]["ID"]); 353 } 354 } 355 356 function ongriddel(form, table, tr) { 357 var inputflag = table.closest("div .form-table").find("input:hidden[data-formid]") 358 var formId = $(form).data("formid"); 359 var storageKey = "FORM_" + formId + "_" + inputflag.attr("name");; 360 localStorage.setItem("FORM_" + formId + "_isGridData", "1"); 361 var trIIDIndex; 362 var trIID; 363 table.find("col").each(function (idx, ele) { 364 if ($(ele).data("index") == "IID") 365 { 366 trIIDIndex = idx; 367 trIID = tr.find("td").eq(idx).html(); 368 } 369 }); 370 371 var DelObj = { trIID: trIID }; 372 373 var getLocalStorage = localStorage.getItem(storageKey); 374 if (getLocalStorage) { 375 376 var dataObj = JSON.parse(getLocalStorage); 377 var isInsertData = false; 378 var isUpdateDel = false; 379 var InsertTotal = dataObj["Total"]["InsertTotal"]; 380 var DelTotal = dataObj["Total"]["DelTotal"]; 381 var UpdateTotal = dataObj["Total"]["UpdateTotal"]; 382 383 384 if (InsertTotal > 0) { 385 386 for (var i = 0; i < InsertTotal; i++) { 387 var row_data = dataObj["Insert"][i]; 388 if (row_data["trIID"] == trIID) { 389 isInsertData = true; 390 dataObj["Insert"][i] = null; 391 } 392 } 393 } 394 395 if (UpdateTotal>0) 396 { 397 for (var i = 0; i < UpdateTotal; i++) { 398 var row_data = dataObj["Update"][i]; 399 if (row_data["trIID"] == trIID) { 400 isUpdateDel = true; 401 dataObj["Update"][i] = null; 402 } 403 } 404 } 405 406 407 if (isInsertData) 408 { 409 var tempArr = []; 410 for (var i = 0; i < InsertTotal; i++) { 411 if (dataObj["Insert"][i] != null) { 412 tempArr[i]=dataObj["Insert"][i]; 413 } 414 } 415 416 dataObj["Insert"] = tempArr; 417 dataObj["Total"]["InsertTotal"] = InsertTotal - 1; 418 } 419 else 420 { 421 422 if (isUpdateDel) 423 { 424 var tempArr = []; 425 for (var i = 0; i < InsertTotal; i++) { 426 if (dataObj["Update"][i] != null) { 427 tempArr[i] = dataObj["Update"][i]; 428 } 429 } 430 431 dataObj["Update"] = tempArr; 432 dataObj["Total"]["UpdateTotal"] = UpdateTotal - 1; 433 434 } 435 436 dataObj["Del"][DelTotal] = DelObj; 437 dataObj["Total"]["DelTotal"] = DelTotal + 1; 438 439 } 440 441 localStorage.setItem(storageKey, JSON.stringify(dataObj)); 442 if (dataObj["Total"]["InsertTotal"] == 0 && dataObj["Total"]["UpdateTotal"] == 0 && dataObj["Total"]["DelTotal"] == 0) 443 { 444 localStorage.setItem("FORM_" + formId + "_isGridData", null); 445 } 446 447 448 } else 449 { 450 var mydata = { Total: { InsertTotal: 0, UpdateTotal: 0, DelTotal: 1 }, Insert: [], Update: [], Del: [DelObj], Notes: { storageKey: storageKey }, trIIDIndex: { IID: trIIDIndex } }; 451 localStorage.setItem(storageKey, JSON.stringify(mydata)); 452 } 453 454 } 455 456 return { 457 onload: onload, 458 onsave: onsave, 459 ongridadd: ongridadd, 460 ongridedit: ongridedit, 461 ongriddel: ongriddel 462 } 463 });