Jay
8 天以前 eca625c35d5ed64c98277d2f83963e46438f50ce
提交 | 用户 | 时间
e7c126 1 $(function() {
H 2
3     // init date tables
4     var jobTable = $("#job_list").dataTable({
5         "deferRender": true,
6         "processing" : true,
7         "serverSide": true,
8         "ajax": {
9             url: base_url + "/jobinfo/pageList",
10             type:"post",
11             data : function ( d ) {
12                 var obj = {};
325d2f 13                 obj.jobGroup = Number($('#jobGroup').val());
e7c126 14                 obj.triggerStatus = $('#triggerStatus').val();
H 15                 obj.jobDesc = $('#jobDesc').val();
16                 obj.executorHandler = $('#executorHandler').val();
17                 obj.author = $('#author').val();
18                 obj.start = d.start;
19                 obj.length = d.length;
20                 return obj;
21             }
22         },
23         "searching": false,
24         "ordering": false,
25         //"scrollX": true,    // scroll x,close self-adaption
26         "columns": [
27                     {
28                         "data": 'id',
29                         "bSortable": false,
30                         "visible" : true,
31                         "width":'7%'
32                     },
33                     {
34                         "data": 'jobGroup',
35                         "visible" : false,
36                         "render": function ( data, type, row ) {
37                             var groupMenu = $("#jobGroup").find("option");
38                             for ( var index in $("#jobGroup").find("option")) {
39                                 if ($(groupMenu[index]).attr('value') == data) {
40                                     return $(groupMenu[index]).html();
41                                 }
42                             }
43                             return data;
44                         }
45                     },
46                     {
47                         "data": 'jobDesc',
48                         "visible" : true,
49                         "width":'25%'
50                     },
51                     {
52                         "data": 'scheduleType',
53                         "visible" : true,
54                         "width":'13%',
55                         "render": function ( data, type, row ) {
56                             if (row.scheduleConf) {
57                                 return row.scheduleType + ':'+ row.scheduleConf;
58                             } else {
59                                 return row.scheduleType;
60                             }
61                         }
62                     },
63                     {
64                         "data": 'glueType',
65                         "width":'25%',
66                         "visible" : true,
67                         "render": function ( data, type, row ) {
68                             var glueTypeTitle = findGlueTypeTitle(row.glueType);
69                             if (row.executorHandler) {
70                                 return glueTypeTitle +":" + row.executorHandler;
71                             } else {
72                                 return glueTypeTitle;
73                             }
74                         }
75                     },
76                     { "data": 'executorParam', "visible" : false},
77                     {
78                         "data": 'addTime',
79                         "visible" : false,
80                         "render": function ( data, type, row ) {
81                             return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
82                         }
83                     },
84                     {
85                         "data": 'updateTime',
86                         "visible" : false,
87                         "render": function ( data, type, row ) {
88                             return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
89                         }
90                     },
91                     { "data": 'author', "visible" : true, "width":'10%'},
92                     { "data": 'alarmEmail', "visible" : false},
93                     {
94                         "data": 'triggerStatus',
95                         "width":'10%',
96                         "visible" : true,
97                         "render": function ( data, type, row ) {
98                             // status
99                             if (1 == data) {
100                                 return '<small class="label label-success" >RUNNING</small>';
101                             } else {
102                                 return '<small class="label label-default" >STOP</small>';
103                             }
104                             return data;
105                         }
106                     },
107                     {
108                         "data": I18n.system_opt ,
109                         "width":'10%',
110                         "render": function ( data, type, row ) {
111                             return function(){
112
113                                 // status
114                                 var start_stop_div = "";
115                                 if (1 == row.triggerStatus ) {
116                                     start_stop_div = '<li><a href="javascript:void(0);" class="job_operate" _type="job_pause" >'+ I18n.jobinfo_opt_stop +'</a></li>\n';
117                                 } else {
118                                     start_stop_div = '<li><a href="javascript:void(0);" class="job_operate" _type="job_resume" >'+ I18n.jobinfo_opt_start +'</a></li>\n';
119                                 }
120
121                                 // job_next_time_html
122                                 var job_next_time_html = '';
123                                 if (row.scheduleType == 'CRON' || row.scheduleType == 'FIX_RATE') {
124                                     job_next_time_html = '<li><a href="javascript:void(0);" class="job_next_time" >' + I18n.jobinfo_opt_next_time + '</a></li>\n';
125                                 }
126
127                                 // log url
128                                 var logHref = base_url +'/joblog?jobId='+ row.id;
129
130                                 // code url
131                                 var codeBtn = "";
132                                 if ('BEAN' != row.glueType) {
133                                     var codeUrl = base_url +'/jobcode?jobId='+ row.id;
134                                     codeBtn = '<li><a href="'+ codeUrl +'" target="_blank" >GLUE IDE</a></li>\n';
135                                     codeBtn += '<li class="divider"></li>\n';
136                                 }
137
138                                 // data
139                                 tableData['key'+row.id] = row;
140
141                                 // opt
142                                 var html = '<div class="btn-group">\n' +
143                                     '     <button type="button" class="btn btn-primary btn-sm">'+ I18n.system_opt +'</button>\n' +
144                                     '     <button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown">\n' +
145                                     '       <span class="caret"></span>\n' +
146                                     '       <span class="sr-only">Toggle Dropdown</span>\n' +
147                                     '     </button>\n' +
148                                     '     <ul class="dropdown-menu" role="menu" _id="'+ row.id +'" >\n' +
149                                     '       <li><a href="javascript:void(0);" class="job_trigger" >'+ I18n.jobinfo_opt_run +'</a></li>\n' +
150                                     '       <li><a href="'+ logHref +'">'+ I18n.jobinfo_opt_log +'</a></li>\n' +
151                                     '       <li><a href="javascript:void(0);" class="job_registryinfo" >' + I18n.jobinfo_opt_registryinfo + '</a></li>\n' +
152                                     job_next_time_html +
153                                     '       <li class="divider"></li>\n' +
154                                     codeBtn +
155                                     start_stop_div +
156                                     '       <li><a href="javascript:void(0);" class="update" >'+ I18n.system_opt_edit +'</a></li>\n' +
157                                     '       <li><a href="javascript:void(0);" class="job_operate" _type="job_del" >'+ I18n.system_opt_del +'</a></li>\n' +
158                                     '       <li><a href="javascript:void(0);" class="job_copy" >'+ I18n.system_opt_copy +'</a></li>\n' +
159                                     '     </ul>\n' +
160                                     '   </div>';
161
162                                 return html;
163                             };
164                         }
165                     }
166                 ],
167         "language" : {
168             "sProcessing" : I18n.dataTable_sProcessing ,
169             "sLengthMenu" : I18n.dataTable_sLengthMenu ,
170             "sZeroRecords" : I18n.dataTable_sZeroRecords ,
171             "sInfo" : I18n.dataTable_sInfo ,
172             "sInfoEmpty" : I18n.dataTable_sInfoEmpty ,
173             "sInfoFiltered" : I18n.dataTable_sInfoFiltered ,
174             "sInfoPostFix" : "",
175             "sSearch" : I18n.dataTable_sSearch ,
176             "sUrl" : "",
177             "sEmptyTable" : I18n.dataTable_sEmptyTable ,
178             "sLoadingRecords" : I18n.dataTable_sLoadingRecords ,
179             "sInfoThousands" : ",",
180             "oPaginate" : {
181                 "sFirst" : I18n.dataTable_sFirst ,
182                 "sPrevious" : I18n.dataTable_sPrevious ,
183                 "sNext" : I18n.dataTable_sNext ,
184                 "sLast" : I18n.dataTable_sLast
185             },
186             "oAria" : {
187                 "sSortAscending" : I18n.dataTable_sSortAscending ,
188                 "sSortDescending" : I18n.dataTable_sSortDescending
189             }
190         }
191     });
192
193     // table data
194     var tableData = {};
195
196     // search btn
197     $('#searchBtn').on('click', function(){
198         jobTable.fnDraw();
199     });
200
201     // jobGroup change
202     $('#jobGroup').on('change', function(){
203         //reload
204         var jobGroup = $('#jobGroup').val();
205         window.location.href = base_url + "/jobinfo?jobGroup=" + jobGroup;
206     });
207
208     // job operate
209     $("#job_list").on('click', '.job_operate',function() {
210         var typeName;
211         var url;
212         var needFresh = false;
213
214         var type = $(this).attr("_type");
215         if ("job_pause" == type) {
216             typeName = I18n.jobinfo_opt_stop ;
217             url = base_url + "/jobinfo/stop";
218             needFresh = true;
219         } else if ("job_resume" == type) {
220             typeName = I18n.jobinfo_opt_start ;
221             url = base_url + "/jobinfo/start";
222             needFresh = true;
223         } else if ("job_del" == type) {
224             typeName = I18n.system_opt_del ;
225             url = base_url + "/jobinfo/remove";
226             needFresh = true;
227         } else {
228             return;
229         }
230
231         var id = $(this).parents('ul').attr("_id");
232
233         layer.confirm( I18n.system_ok + typeName + '?', {
234             icon: 3,
235             title: I18n.system_tips ,
236             btn: [ I18n.system_ok, I18n.system_cancel ]
237         }, function(index){
238             layer.close(index);
239
240             $.ajax({
241                 type : 'POST',
242                 url : url,
243                 data : {
244                     "id" : id
245                 },
246                 dataType : "json",
247                 success : function(data){
248                     if (data.code == 200) {
249                         layer.msg( typeName + I18n.system_success );
250                         if (needFresh) {
251                             //window.location.reload();
252                             jobTable.fnDraw(false);
253                         }
254                     } else {
255                         layer.msg( data.msg || typeName + I18n.system_fail );
256                     }
257                 }
258             });
259         });
260     });
261
262     // job trigger
263     $("#job_list").on('click', '.job_trigger',function() {
264         var id = $(this).parents('ul').attr("_id");
265         var row = tableData['key'+id];
266
267         $("#jobTriggerModal .form input[name='id']").val( row.id );
268         $("#jobTriggerModal .form textarea[name='executorParam']").val( row.executorParam );
269
270         $('#jobTriggerModal').modal({backdrop: false, keyboard: false}).modal('show');
271     });
272     $("#jobTriggerModal .ok").on('click',function() {
273         $.ajax({
274             type : 'POST',
275             url : base_url + "/jobinfo/trigger",
276             data : {
277                 "id" : $("#jobTriggerModal .form input[name='id']").val(),
278                 "executorParam" : $("#jobTriggerModal .textarea[name='executorParam']").val(),
279                 "addressList" : $("#jobTriggerModal .textarea[name='addressList']").val()
280             },
281             dataType : "json",
282             success : function(data){
283                 if (data.code == 200) {
284                     $('#jobTriggerModal').modal('hide');
285
286                     layer.msg( I18n.jobinfo_opt_run + I18n.system_success );
287                 } else {
288                     layer.msg( data.msg || I18n.jobinfo_opt_run + I18n.system_fail );
289                 }
290             }
291         });
292     });
293     $("#jobTriggerModal").on('hide.bs.modal', function () {
294         $("#jobTriggerModal .form")[0].reset();
295     });
296
297
298     // job registryinfo
299     $("#job_list").on('click', '.job_registryinfo',function() {
300         var id = $(this).parents('ul').attr("_id");
301         var row = tableData['key'+id];
302
303         var jobGroup = row.jobGroup;
304
305         $.ajax({
306             type : 'POST',
307             url : base_url + "/jobgroup/loadById",
308             data : {
309                 "id" : jobGroup
310             },
311             dataType : "json",
312             success : function(data){
313
314                 var html = '<div>';
315                 if (data.code == 200 && data.content.registryList) {
316                     for (var index in data.content.registryList) {
317                         html += (parseInt(index)+1) + '. <span class="badge bg-green" >' + data.content.registryList[index] + '</span><br>';
318                     }
319                 }
320                 html += '</div>';
321
322                 layer.open({
323                     title: I18n.jobinfo_opt_registryinfo ,
324                     btn: [ I18n.system_ok ],
325                     content: html
326                 });
327
328             }
329         });
330
331     });
332
333     // job_next_time
334     $("#job_list").on('click', '.job_next_time',function() {
335         var id = $(this).parents('ul').attr("_id");
336         var row = tableData['key'+id];
337
338         $.ajax({
339             type : 'POST',
340             url : base_url + "/jobinfo/nextTriggerTime",
341             data : {
342                 "scheduleType" : row.scheduleType,
343                 "scheduleConf" : row.scheduleConf
344             },
345             dataType : "json",
346             success : function(data){
347
348                 if (data.code != 200) {
349                     layer.open({
350                         title: I18n.jobinfo_opt_next_time ,
351                         btn: [ I18n.system_ok ],
352                         content: data.msg
353                     });
354                 } else {
355                     var html = '<center>';
356                     if (data.code == 200 && data.content) {
357                         for (var index in data.content) {
358                             html += '<span>' + data.content[index] + '</span><br>';
359                         }
360                     }
361                     html += '</center>';
362
363                     layer.open({
364                         title: I18n.jobinfo_opt_next_time ,
365                         btn: [ I18n.system_ok ],
366                         content: html
367                     });
368                 }
369
370             }
371         });
372
373     });
374
375     // add
376     $(".add").click(function(){
377
378         // init-cronGen
379         $("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
380         $("#addModal .form input[name='schedule_conf_CRON']").cronGen({});
381
382         // 》init scheduleType
383         $("#updateModal .form select[name=scheduleType]").change();
384
385         // 》init glueType
386         $("#updateModal .form select[name=glueType]").change();
387
388         $('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
389     });
390     var addModalValidate = $("#addModal .form").validate({
391         errorElement : 'span',
392         errorClass : 'help-block',
393         focusInvalid : true,
394         rules : {
395             jobDesc : {
396                 required : true,
397                 maxlength: 50
398             },
399             author : {
400                 required : true
401             }/*,
402             executorTimeout : {
403                 digits:true
404             },
405             executorFailRetryCount : {
406                 digits:true
407             }*/
408         },
409         messages : {
410             jobDesc : {
411                 required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
412             },
413             author : {
414                 required : I18n.system_please_input + I18n.jobinfo_field_author
415             }/*,
416             executorTimeout : {
417                 digits: I18n.system_please_input + I18n.system_digits
418             },
419             executorFailRetryCount : {
420                 digits: I18n.system_please_input + I18n.system_digits
421             }*/
422         },
423         highlight : function(element) {
424             $(element).closest('.form-group').addClass('has-error');
425         },
426         success : function(label) {
427             label.closest('.form-group').removeClass('has-error');
428             label.remove();
429         },
430         errorPlacement : function(error, element) {
431             element.parent('div').append(error);
432         },
433         submitHandler : function(form) {
434
435             // process executorTimeout+executorFailRetryCount
436             var executorTimeout = $("#addModal .form input[name='executorTimeout']").val();
437             if(!/^\d+$/.test(executorTimeout)) {
438                 executorTimeout = 0;
439             }
440             $("#addModal .form input[name='executorTimeout']").val(executorTimeout);
441             var executorFailRetryCount = $("#addModal .form input[name='executorFailRetryCount']").val();
442             if(!/^\d+$/.test(executorFailRetryCount)) {
443                 executorFailRetryCount = 0;
444             }
445             $("#addModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount);
446
447             // process schedule_conf
448             var scheduleType = $("#addModal .form select[name='scheduleType']").val();
449             var scheduleConf;
450             if (scheduleType == 'CRON') {
451                 scheduleConf = $("#addModal .form input[name='cronGen_display']").val();
452             } else if (scheduleType == 'FIX_RATE') {
453                 scheduleConf = $("#addModal .form input[name='schedule_conf_FIX_RATE']").val();
454             } else if (scheduleType == 'FIX_DELAY') {
455                 scheduleConf = $("#addModal .form input[name='schedule_conf_FIX_DELAY']").val();
456             }
457             $("#addModal .form input[name='scheduleConf']").val( scheduleConf );
458
459             $.post(base_url + "/jobinfo/add",  $("#addModal .form").serialize(), function(data, status) {
460                 if (data.code == "200") {
461                     $('#addModal').modal('hide');
462                     layer.open({
463                         title: I18n.system_tips ,
464                         btn: [ I18n.system_ok ],
465                         content: I18n.system_add_suc ,
466                         icon: '1',
467                         end: function(layero, index){
468                             jobTable.fnDraw();
469                             //window.location.reload();
470                         }
471                     });
472                 } else {
473                     layer.open({
474                         title: I18n.system_tips ,
475                         btn: [ I18n.system_ok ],
476                         content: (data.msg || I18n.system_add_fail),
477                         icon: '2'
478                     });
479                 }
480             });
481         }
482     });
483     $("#addModal").on('hide.bs.modal', function () {
484         addModalValidate.resetForm();
485         $("#addModal .form")[0].reset();
486         $("#addModal .form .form-group").removeClass("has-error");
487         $(".remote_panel").show();    // remote
488
489         $("#addModal .form input[name='executorHandler']").removeAttr("readonly");
490     });
491
492     // scheduleType change
493     $(".scheduleType").change(function(){
494         var scheduleType = $(this).val();
495         $(this).parents("form").find(".schedule_conf").hide();
496         $(this).parents("form").find(".schedule_conf_" + scheduleType).show();
497
498     });
499
500     // glueType change
501     $(".glueType").change(function(){
502         // executorHandler
503         var $executorHandler = $(this).parents("form").find("input[name='executorHandler']");
504         var glueType = $(this).val();
505         if ('BEAN' != glueType) {
506             $executorHandler.val("");
507             $executorHandler.attr("readonly","readonly");
508         } else {
509             $executorHandler.removeAttr("readonly");
510         }
511     });
512
513     $("#addModal .glueType").change(function(){
514         // glueSource
515         var glueType = $(this).val();
516         if ('GLUE_GROOVY'==glueType){
517             $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_java").val() );
518         } else if ('GLUE_SHELL'==glueType){
519             $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_shell").val() );
520         } else if ('GLUE_PYTHON'==glueType){
521             $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_python").val() );
522         } else if ('GLUE_PHP'==glueType){
523             $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_php").val() );
524         } else if ('GLUE_NODEJS'==glueType){
525             $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_nodejs").val() );
526         } else if ('GLUE_POWERSHELL'==glueType){
527             $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_powershell").val() );
528         } else {
529             $("#addModal .form textarea[name='glueSource']").val("");
530         }
531     });
532
533     // update
534     $("#job_list").on('click', '.update',function() {
535
536         var id = $(this).parents('ul').attr("_id");
537         var row = tableData['key'+id];
538
539         // fill base
540         $("#updateModal .form input[name='id']").val( row.id );
541         $('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
542         $("#updateModal .form input[name='jobDesc']").val( row.jobDesc );
543         $("#updateModal .form input[name='author']").val( row.author );
544         $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail );
545
546         // fill trigger
547         $('#updateModal .form select[name=scheduleType] option[value='+ row.scheduleType +']').prop('selected', true);
548         $("#updateModal .form input[name='scheduleConf']").val( row.scheduleConf );
549         if (row.scheduleType == 'CRON') {
550             $("#updateModal .form input[name='schedule_conf_CRON']").val( row.scheduleConf );
551         } else if (row.scheduleType == 'FIX_RATE') {
552             $("#updateModal .form input[name='schedule_conf_FIX_RATE']").val( row.scheduleConf );
553         } else if (row.scheduleType == 'FIX_DELAY') {
554             $("#updateModal .form input[name='schedule_conf_FIX_DELAY']").val( row.scheduleConf );
555         }
556
557         // 》init scheduleType
558         $("#updateModal .form select[name=scheduleType]").change();
559
560         // fill job
561         $('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
562         $("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
563         $("#updateModal .form textarea[name='executorParam']").val( row.executorParam );
564
565         // 》init glueType
566         $("#updateModal .form select[name=glueType]").change();
567
568         // 》init-cronGen
569         $("#updateModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
570         $("#updateModal .form input[name='schedule_conf_CRON']").cronGen({});
571
572         // fill advanced
573         $('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
574         $("#updateModal .form input[name='childJobId']").val( row.childJobId );
575         $('#updateModal .form select[name=misfireStrategy] option[value='+ row.misfireStrategy +']').prop('selected', true);
576         $('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
577         $("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout );
578         $("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
579
580         // show
581         $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
582     });
583     var updateModalValidate = $("#updateModal .form").validate({
584         errorElement : 'span',
585         errorClass : 'help-block',
586         focusInvalid : true,
587
588         rules : {
589             jobDesc : {
590                 required : true,
591                 maxlength: 50
592             },
593             author : {
594                 required : true
595             }
596         },
597         messages : {
598             jobDesc : {
599                 required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
600             },
601             author : {
602                 required : I18n.system_please_input + I18n.jobinfo_field_author
603             }
604         },
605         highlight : function(element) {
606             $(element).closest('.form-group').addClass('has-error');
607         },
608         success : function(label) {
609             label.closest('.form-group').removeClass('has-error');
610             label.remove();
611         },
612         errorPlacement : function(error, element) {
613             element.parent('div').append(error);
614         },
615         submitHandler : function(form) {
616
617             // process executorTimeout + executorFailRetryCount
618             var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val();
619             if(!/^\d+$/.test(executorTimeout)) {
620                 executorTimeout = 0;
621             }
622             $("#updateModal .form input[name='executorTimeout']").val(executorTimeout);
623             var executorFailRetryCount = $("#updateModal .form input[name='executorFailRetryCount']").val();
624             if(!/^\d+$/.test(executorFailRetryCount)) {
625                 executorFailRetryCount = 0;
626             }
627             $("#updateModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount);
628
629
630             // process schedule_conf
631             var scheduleType = $("#updateModal .form select[name='scheduleType']").val();
632             var scheduleConf;
633             if (scheduleType == 'CRON') {
634                 scheduleConf = $("#updateModal .form input[name='cronGen_display']").val();
635             } else if (scheduleType == 'FIX_RATE') {
636                 scheduleConf = $("#updateModal .form input[name='schedule_conf_FIX_RATE']").val();
637             } else if (scheduleType == 'FIX_DELAY') {
638                 scheduleConf = $("#updateModal .form input[name='schedule_conf_FIX_DELAY']").val();
639             }
640             $("#updateModal .form input[name='scheduleConf']").val( scheduleConf );
641
642             // post
643             $.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) {
644                 if (data.code == "200") {
645                     $('#updateModal').modal('hide');
646                     layer.open({
647                         title: I18n.system_tips ,
648                         btn: [ I18n.system_ok ],
649                         content: I18n.system_update_suc ,
650                         icon: '1',
651                         end: function(layero, index){
652                             //window.location.reload();
653                             jobTable.fnDraw();
654                         }
655                     });
656                 } else {
657                     layer.open({
658                         title: I18n.system_tips ,
659                         btn: [ I18n.system_ok ],
660                         content: (data.msg || I18n.system_update_fail ),
661                         icon: '2'
662                     });
663                 }
664             });
665         }
666     });
667     $("#updateModal").on('hide.bs.modal', function () {
668         updateModalValidate.resetForm();
669         $("#updateModal .form")[0].reset();
670         $("#updateModal .form .form-group").removeClass("has-error");
671     });
672
673     /**
674      * find title by name, GlueType
675      */
676     function findGlueTypeTitle(glueType) {
677         var glueTypeTitle;
678         $("#addModal .form select[name=glueType] option").each(function () {
679             var name = $(this).val();
680             var title = $(this).text();
681             if (glueType == name) {
682                 glueTypeTitle = title;
683                 return false
684             }
685         });
686         return glueTypeTitle;
687     }
688
689     // job_copy
690     $("#job_list").on('click', '.job_copy',function() {
691
692         var id = $(this).parents('ul').attr("_id");
693         var row = tableData['key'+id];
694
695         // fill base
696         $('#addModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
697         $("#addModal .form input[name='jobDesc']").val( row.jobDesc );
698         $("#addModal .form input[name='author']").val( row.author );
699         $("#addModal .form input[name='alarmEmail']").val( row.alarmEmail );
700
701         // fill trigger
702         $('#addModal .form select[name=scheduleType] option[value='+ row.scheduleType +']').prop('selected', true);
703         $("#addModal .form input[name='scheduleConf']").val( row.scheduleConf );
704         if (row.scheduleType == 'CRON') {
705             $("#addModal .form input[name='schedule_conf_CRON']").val( row.scheduleConf );
706         } else if (row.scheduleType == 'FIX_RATE') {
707             $("#addModal .form input[name='schedule_conf_FIX_RATE']").val( row.scheduleConf );
708         } else if (row.scheduleType == 'FIX_DELAY') {
709             $("#addModal .form input[name='schedule_conf_FIX_DELAY']").val( row.scheduleConf );
710         }
711
712         // 》init scheduleType
713         $("#addModal .form select[name=scheduleType]").change();
714
715         // fill job
716         $('#addModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
717         $("#addModal .form input[name='executorHandler']").val( row.executorHandler );
718         $("#addModal .form textarea[name='executorParam']").val( row.executorParam );
719
720         // 》init glueType
721         $("#addModal .form select[name=glueType]").change();
722
723         // 》init-cronGen
724         $("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
725         $("#addModal .form input[name='schedule_conf_CRON']").cronGen({});
726
727         // fill advanced
728         $('#addModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
729         $("#addModal .form input[name='childJobId']").val( row.childJobId );
730         $('#addModal .form select[name=misfireStrategy] option[value='+ row.misfireStrategy +']').prop('selected', true);
731         $('#addModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
732         $("#addModal .form input[name='executorTimeout']").val( row.executorTimeout );
733         $("#addModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
734
735         // show
736         $('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
737     });
738
739 });