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 }
form.js

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="{&quot;ID&quot;:&quot;$[ID]&quot;,&quot;IID&quot;:&quot;$(autoid)&quot;}" /> 
   <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 });

 

 

posted @ 2015-11-19 14:37  枫伶忆  阅读(23018)  评论(6编辑  收藏  举报