jquery.form.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /**
  2. * EasyUI for jQuery 1.5.5.6
  3. *
  4. * Copyright (c) 2009-2018 www.jeasyui.com. All rights reserved.
  5. *
  6. * Licensed under the freeware license: http://www.jeasyui.com/license_freeware.php
  7. * To use it on other terms please contact us: info@jeasyui.com
  8. *
  9. */
  10. /**
  11. * form - EasyUI for jQuery
  12. *
  13. */
  14. (function($){
  15. /**
  16. * submit the form
  17. */
  18. function ajaxSubmit(target, options){
  19. var opts = $.data(target, 'form').options;
  20. $.extend(opts, options||{});
  21. var param = $.extend({}, opts.queryParams);
  22. if (opts.onSubmit.call(target, param) == false){return;}
  23. // $(target).find('.textbox-text:focus').blur();
  24. var input = $(target).find('.textbox-text:focus');
  25. input.triggerHandler('blur');
  26. input.focus();
  27. var disabledFields = null; // the fields to be disabled
  28. if (opts.dirty){
  29. var ff = []; // all the dirty fields
  30. $.map(opts.dirtyFields, function(f){
  31. if ($(f).hasClass('textbox-f')){
  32. $(f).next().find('.textbox-value').each(function(){
  33. ff.push(this);
  34. });
  35. } else {
  36. ff.push(f);
  37. }
  38. });
  39. disabledFields = $(target).find('input[name]:enabled,textarea[name]:enabled,select[name]:enabled').filter(function(){
  40. return $.inArray(this, ff) == -1;
  41. });
  42. // disabledFields.attr('disabled', 'disabled');
  43. disabledFields._propAttr('disabled', true);
  44. }
  45. if (opts.ajax){
  46. if (opts.iframe){
  47. submitIframe(target, param);
  48. } else {
  49. if (window.FormData !== undefined){
  50. submitXhr(target, param);
  51. } else {
  52. submitIframe(target, param);
  53. }
  54. }
  55. } else {
  56. $(target).submit();
  57. }
  58. if (opts.dirty){
  59. // disabledFields.removeAttr('disabled');
  60. disabledFields._propAttr('disabled', false);
  61. }
  62. }
  63. function submitIframe(target, param){
  64. var opts = $.data(target, 'form').options;
  65. var frameId = 'easyui_frame_' + (new Date().getTime());
  66. var frame = $('<iframe id='+frameId+' name='+frameId+'></iframe>').appendTo('body')
  67. frame.attr('src', window.ActiveXObject ? 'javascript:false' : 'about:blank');
  68. frame.css({
  69. position:'absolute',
  70. top:-1000,
  71. left:-1000
  72. });
  73. frame.bind('load', cb);
  74. submit(param);
  75. function submit(param){
  76. var form = $(target);
  77. if (opts.url){
  78. form.attr('action', opts.url);
  79. }
  80. var t = form.attr('target'), a = form.attr('action');
  81. form.attr('target', frameId);
  82. var paramFields = $();
  83. try {
  84. for(var n in param){
  85. var field = $('<input type="hidden" name="' + n + '">').val(param[n]).appendTo(form);
  86. paramFields = paramFields.add(field);
  87. }
  88. checkState();
  89. form[0].submit();
  90. } finally {
  91. form.attr('action', a);
  92. t ? form.attr('target', t) : form.removeAttr('target');
  93. paramFields.remove();
  94. }
  95. }
  96. function checkState(){
  97. var f = $('#'+frameId);
  98. if (!f.length){return}
  99. try{
  100. var s = f.contents()[0].readyState;
  101. if (s && s.toLowerCase() == 'uninitialized'){
  102. setTimeout(checkState, 100);
  103. }
  104. } catch(e){
  105. cb();
  106. }
  107. }
  108. var checkCount = 10;
  109. function cb(){
  110. var f = $('#'+frameId);
  111. if (!f.length){return}
  112. f.unbind();
  113. var data = '';
  114. try{
  115. var body = f.contents().find('body');
  116. data = body.html();
  117. if (data == ''){
  118. if (--checkCount){
  119. setTimeout(cb, 100);
  120. return;
  121. }
  122. }
  123. var ta = body.find('>textarea');
  124. if (ta.length){
  125. data = ta.val();
  126. } else {
  127. var pre = body.find('>pre');
  128. if (pre.length){
  129. data = pre.html();
  130. }
  131. }
  132. } catch(e){
  133. }
  134. opts.success.call(target, data);
  135. setTimeout(function(){
  136. f.unbind();
  137. f.remove();
  138. }, 100);
  139. }
  140. }
  141. function submitXhr(target, param){
  142. var opts = $.data(target, 'form').options;
  143. var formData = new FormData($(target)[0]);
  144. for(var name in param){
  145. formData.append(name, param[name]);
  146. }
  147. $.ajax({
  148. url: opts.url,
  149. type: 'post',
  150. xhr: function(){
  151. var xhr = $.ajaxSettings.xhr();
  152. if (xhr.upload) {
  153. xhr.upload.addEventListener('progress', function(e){
  154. if (e.lengthComputable) {
  155. var total = e.total;
  156. var position = e.loaded || e.position;
  157. var percent = Math.ceil(position * 100 / total);
  158. opts.onProgress.call(target, percent);
  159. }
  160. }, false);
  161. }
  162. return xhr;
  163. },
  164. data: formData,
  165. dataType: 'html',
  166. cache: false,
  167. contentType: false,
  168. processData: false,
  169. complete: function(res){
  170. opts.success.call(target, res.responseText);
  171. }
  172. });
  173. }
  174. /**
  175. * load form data
  176. * if data is a URL string type load from remote site,
  177. * otherwise load from local data object.
  178. */
  179. function load(target, data){
  180. var opts = $.data(target, 'form').options;
  181. if (typeof data == 'string'){
  182. var param = {};
  183. if (opts.onBeforeLoad.call(target, param) == false) return;
  184. $.ajax({
  185. url: data,
  186. data: param,
  187. dataType: 'json',
  188. success: function(data){
  189. _load(data);
  190. },
  191. error: function(){
  192. opts.onLoadError.apply(target, arguments);
  193. }
  194. });
  195. } else {
  196. _load(data);
  197. }
  198. function _load(data){
  199. var form = $(target);
  200. for(var name in data){
  201. var val = data[name];
  202. if (!_checkField(name, val)){
  203. if (!_loadBox(name, val)){
  204. form.find('input[name="'+name+'"]').val(val);
  205. form.find('textarea[name="'+name+'"]').val(val);
  206. form.find('select[name="'+name+'"]').val(val);
  207. }
  208. }
  209. }
  210. opts.onLoadSuccess.call(target, data);
  211. form.form('validate');
  212. }
  213. /**
  214. * check the checkbox and radio fields
  215. */
  216. function _checkField(name, val){
  217. var plugins = ['switchbutton','radiobutton','checkbox'];
  218. for(var i=0; i<plugins.length; i++){
  219. var plugin = plugins[i];
  220. var cc = $(target).find('['+plugin+'Name="'+name+'"]');
  221. if (cc.length){
  222. cc[plugin]('uncheck');
  223. cc.each(function(){
  224. if (_isChecked($(this)[plugin]('options').value, val)){
  225. $(this)[plugin]('check');
  226. }
  227. });
  228. return true;
  229. }
  230. }
  231. var cc = $(target).find('input[name="'+name+'"][type=radio], input[name="'+name+'"][type=checkbox]');
  232. if (cc.length){
  233. cc._propAttr('checked', false);
  234. cc.each(function(){
  235. if (_isChecked($(this).val(), val)){
  236. $(this)._propAttr('checked', true);
  237. }
  238. });
  239. return true;
  240. }
  241. return false;
  242. }
  243. function _isChecked(v, val){
  244. if (v == String(val) || $.inArray(v, $.isArray(val)?val:[val]) >= 0){
  245. return true;
  246. } else {
  247. return false;
  248. }
  249. }
  250. function _loadBox(name, val){
  251. var field = $(target).find('[textboxName="'+name+'"],[sliderName="'+name+'"]');
  252. if (field.length){
  253. for(var i=0; i<opts.fieldTypes.length; i++){
  254. var type = opts.fieldTypes[i];
  255. var state = field.data(type);
  256. if (state){
  257. if (state.options.multiple || state.options.range){
  258. field[type]('setValues', val);
  259. } else {
  260. field[type]('setValue', val);
  261. }
  262. return true;
  263. }
  264. }
  265. }
  266. return false;
  267. }
  268. }
  269. /**
  270. * clear the form fields
  271. */
  272. function clear(target){
  273. $('input,select,textarea', target).each(function(){
  274. if ($(this).hasClass('textbox-value')){return;}
  275. var t = this.type, tag = this.tagName.toLowerCase();
  276. if (t == 'text' || t == 'hidden' || t == 'password' || tag == 'textarea'){
  277. this.value = '';
  278. } else if (t == 'file'){
  279. var file = $(this);
  280. if (!file.hasClass('textbox-value')){
  281. var newfile = file.clone().val('');
  282. newfile.insertAfter(file);
  283. if (file.data('validatebox')){
  284. file.validatebox('destroy');
  285. newfile.validatebox();
  286. } else {
  287. file.remove();
  288. }
  289. }
  290. } else if (t == 'checkbox' || t == 'radio'){
  291. this.checked = false;
  292. } else if (tag == 'select'){
  293. this.selectedIndex = -1;
  294. }
  295. });
  296. var tmp = $();
  297. var form = $(target);
  298. var opts = $.data(target, 'form').options;
  299. for(var i=0; i<opts.fieldTypes.length; i++){
  300. var type = opts.fieldTypes[i];
  301. var field = form.find('.'+type+'-f').not(tmp);
  302. if (field.length && field[type]){
  303. field[type]('clear');
  304. tmp = tmp.add(field);
  305. }
  306. }
  307. form.form('validate');
  308. }
  309. function reset(target){
  310. target.reset();
  311. var form = $(target);
  312. var opts = $.data(target, 'form').options;
  313. for(var i=opts.fieldTypes.length-1; i>=0; i--){
  314. var type = opts.fieldTypes[i];
  315. var field = form.find('.'+type+'-f');
  316. if (field.length && field[type]){
  317. field[type]('reset');
  318. }
  319. }
  320. form.form('validate');
  321. }
  322. /**
  323. * set the form to make it can submit with ajax.
  324. */
  325. function setForm(target){
  326. var options = $.data(target, 'form').options;
  327. $(target).unbind('.form');
  328. if (options.ajax){
  329. $(target).bind('submit.form', function(){
  330. setTimeout(function(){
  331. ajaxSubmit(target, options);
  332. }, 0);
  333. return false;
  334. });
  335. }
  336. $(target).bind('_change.form', function(e, t){
  337. if ($.inArray(t, options.dirtyFields) == -1){
  338. options.dirtyFields.push(t);
  339. }
  340. options.onChange.call(this, t);
  341. }).bind('change.form', function(e){
  342. var t = e.target;
  343. if (!$(t).hasClass('textbox-text')){
  344. if ($.inArray(t, options.dirtyFields) == -1){
  345. options.dirtyFields.push(t);
  346. }
  347. options.onChange.call(this, t);
  348. }
  349. });
  350. setValidation(target, options.novalidate);
  351. }
  352. function initForm(target, options){
  353. options = options || {};
  354. var state = $.data(target, 'form');
  355. if (state){
  356. $.extend(state.options, options);
  357. } else {
  358. $.data(target, 'form', {
  359. options: $.extend({}, $.fn.form.defaults, $.fn.form.parseOptions(target), options)
  360. });
  361. }
  362. }
  363. function validate(target){
  364. if ($.fn.validatebox){
  365. var t = $(target);
  366. t.find('.validatebox-text:not(:disabled)').validatebox('validate');
  367. var invalidbox = t.find('.validatebox-invalid');
  368. invalidbox.filter(':not(:disabled):first').focus();
  369. return invalidbox.length == 0;
  370. }
  371. return true;
  372. }
  373. function setValidation(target, novalidate){
  374. var opts = $.data(target, 'form').options;
  375. opts.novalidate = novalidate;
  376. $(target).find('.validatebox-text:not(:disabled)').validatebox(novalidate ? 'disableValidation' : 'enableValidation');
  377. }
  378. $.fn.form = function(options, param){
  379. if (typeof options == 'string'){
  380. this.each(function(){
  381. initForm(this);
  382. });
  383. return $.fn.form.methods[options](this, param);
  384. }
  385. return this.each(function(){
  386. initForm(this, options);
  387. setForm(this);
  388. });
  389. };
  390. $.fn.form.methods = {
  391. options: function(jq){
  392. return $.data(jq[0], 'form').options;
  393. },
  394. submit: function(jq, options){
  395. return jq.each(function(){
  396. ajaxSubmit(this, options);
  397. });
  398. },
  399. load: function(jq, data){
  400. return jq.each(function(){
  401. load(this, data);
  402. });
  403. },
  404. clear: function(jq){
  405. return jq.each(function(){
  406. clear(this);
  407. });
  408. },
  409. reset: function(jq){
  410. return jq.each(function(){
  411. reset(this);
  412. });
  413. },
  414. validate: function(jq){
  415. return validate(jq[0]);
  416. },
  417. disableValidation: function(jq){
  418. return jq.each(function(){
  419. setValidation(this, true);
  420. });
  421. },
  422. enableValidation: function(jq){
  423. return jq.each(function(){
  424. setValidation(this, false);
  425. });
  426. },
  427. resetValidation: function(jq){
  428. return jq.each(function(){
  429. $(this).find('.validatebox-text:not(:disabled)').validatebox('resetValidation');
  430. });
  431. },
  432. resetDirty: function(jq){
  433. return jq.each(function(){
  434. $(this).form('options').dirtyFields = [];
  435. });
  436. }
  437. };
  438. $.fn.form.parseOptions = function(target){
  439. var t = $(target);
  440. return $.extend({}, $.parser.parseOptions(target, [
  441. {ajax:'boolean',dirty:'boolean'}
  442. ]), {
  443. url: (t.attr('action') ? t.attr('action') : undefined)
  444. });
  445. };
  446. $.fn.form.defaults = {
  447. fieldTypes: ['tagbox','combobox','combotree','combogrid','combotreegrid','datetimebox','datebox','combo',
  448. 'datetimespinner','timespinner','numberspinner','spinner',
  449. 'slider','searchbox','numberbox','passwordbox','filebox','textbox','switchbutton','radiobutton','checkbox'],
  450. novalidate: false,
  451. ajax: true,
  452. iframe: true,
  453. dirty: false,
  454. dirtyFields: [],
  455. url: null,
  456. queryParams: {},
  457. onSubmit: function(param){return $(this).form('validate');},
  458. onProgress: function(percent){},
  459. success: function(data){},
  460. onBeforeLoad: function(param){},
  461. onLoadSuccess: function(data){},
  462. onLoadError: function(){},
  463. onChange: function(target){}
  464. };
  465. })(jQuery);