layui tree treegrid javascript js treetable 前端 jquery form

最近接了个活,被狠狠的坑了一把,也没有什么收获。接近尾声,把唯一的一点成果发出来。

新项目,没有完整的前端框架,选择了layui做为后台管理系统的前端js框架。layui挺好的(尤其是layui.use声明式的组件加载,要比提前大量的js文件引入优雅的多),但是毕竟是新的框架,可用的东西太少了,很多封装的组件也比较简单,适应不了后台复杂的展示功能。

新功能有个树表的展示,时间太紧了,常用的treetable做出来也与整个系统的页面风格不统一,无奈只能自己写个treetable的展示页了。

效果图:

layui tree treegrid javascript js treetable 前端 jquery form_第1张图片

主要方法:

openChild(elem,id)   节点打开关闭    

addChild(item,tr)   添加节点     

 	 addChildCity(id,$(tr).next()) 添加节点后的回调,自动把创建的节点添加到表格中
	 del(id,$that)  删除节点
 
  

整个过程中没有刷新操作,全部jquery实现table的变动。

        相对treetable组件,treetable是一行一个table组织起来的,这个treetable是整个一个表格。

        代码还没有整理封装,可以快速替换自己的样式和model。

layui的所有代码都封装layui.use中,外部不可见的,如果想外部调用layui的方法,可以先声明,在layui中再定义方法实现。例如:

var addChildCity = null; var del = null; 两个方法。

还有比较坑的是layui.js加载组件路径的声明,开始使用的时候就是不能准确加载组件,无奈写死了请求路径方才可以。

		var p = n.createElement("script"), h = (a[m] ?  "/static/plugins/layui/lay/" : o.base(layui.js 76行)
	具体原因未找到,可能是自己使用的不太对吧。

还是要声明一下,如果使用layui,一定要确定自己有封装组件的能力和充足的时间,否则还是用功能完整的extjs吧,急就章赶出来的代码,实在不敢恭维。

过两天封装组件代码.......................................................................................




	
添加根节点
名称 简称 全拼 简拼 编码 是否主要 映射编码 序号 级别 操作
再附上一个layui可以使用的jquery-form组件(网上很多如何把jquery组件转成layui的说明,这个是转成功的):

/*
 * ! jQuery Form Plugin version: 3.50.0-2014.02.05 Requires jQuery v1.5 or later
 * Copyright (c) 2013 M. Alsup Examples and documentation at:
 * http://malsup.com/jquery/form/ Project repository:
 * https://github.com/malsup/form Dual licensed under the MIT and GPL licenses.
 * https://github.com/malsup/form#copyright-and-license
 */
/* global ActiveXObject */

// AMD support
layui.define(function(exports) {
	function jquery_form(jQuery) {
		// 插件代码区
		(function(factory) {
			"use strict";
			if (typeof define === 'function' && define.amd) {
				// using AMD; register as anon module
				define(['jquery'], factory);
			} else {
				// no AMD; invoke directly
				factory((typeof(jQuery) != 'undefined') ? jQuery : window.Zepto);
			}
		}

		(function($) {
			"use strict";

			/*
			 * Usage Note: ----------- Do not use both ajaxSubmit and ajaxForm
			 * on the same form. These functions are mutually exclusive. Use
			 * ajaxSubmit if you want to bind your own submit handler to the
			 * form. For example,
			 * 
			 * $(document).ready(function() { $('#myForm').on('submit',
			 * function(e) { e.preventDefault(); // <-- important
			 * $(this).ajaxSubmit({ target: '#output' }); }); });
			 * 
			 * Use ajaxForm when you want the plugin to manage all the event
			 * binding for you. For example,
			 * 
			 * $(document).ready(function() { $('#myForm').ajaxForm({ target:
			 * '#output' }); });
			 * 
			 * You can also use ajaxForm with delegation (requires jQuery
			 * v1.7+), so the form does not have to exist when you invoke
			 * ajaxForm:
			 * 
			 * $('#myForm').ajaxForm({ delegation: true, target: '#output' });
			 * 
			 * When using ajaxForm, the ajaxSubmit function will be invoked for
			 * you at the appropriate time.
			 */

			/**
			 * Feature detection
			 */
			var feature = {};
			feature.fileapi = $("").get(0).files !== undefined;
			feature.formdata = window.FormData !== undefined;

			var hasProp = !!$.fn.prop;

			// attr2 uses prop when it can but checks the return type for
			// an expected string. this accounts for the case where a form
			// contains inputs with names like "action" or "method"; in those
			// cases "prop" returns the element
			$.fn.attr2 = function() {
				if (!hasProp) {
					return this.attr.apply(this, arguments);
				}
				var val = this.prop.apply(this, arguments);
				if ((val && val.jquery) || typeof val === 'string') {
					return val;
				}
				return this.attr.apply(this, arguments);
			};

			/**
			 * ajaxSubmit() provides a mechanism for immediately submitting an
			 * HTML form using AJAX.
			 */
			$.fn.ajaxSubmit = function(options) {
				/* jshint scripturl:true */

				// fast fail if nothing selected
				// (http://dev.jquery.com/ticket/2752)
				if (!this.length) {
					log('ajaxSubmit: skipping submit process - no element selected');
					return this;
				}

				var method, action, url, $form = this;

				if (typeof options == 'function') {
					options = {
						success : options
					};
				} else if (options === undefined) {
					options = {};
				}

				method = options.type || this.attr2('method');
				action = options.url || this.attr2('action');

				url = (typeof action === 'string') ? $.trim(action) : '';
				url = url || window.location.href || '';
				if (url) {
					// clean url (don't include hash vaue)
					url = (url.match(/^([^#]+)/) || [])[1];
				}

				options = $.extend(true, {
							url : url,
							success : $.ajaxSettings.success,
							type : method || $.ajaxSettings.type,
							iframeSrc : /^https/i.test(window.location.href
									|| '') ? 'javascript:false' : 'about:blank'
						}, options);

				// hook for manipulating the form data before it is extracted;
				// convenient for use with rich editors like tinyMCE or
				// FCKEditor
				var veto = {};
				this.trigger('form-pre-serialize', [this, options, veto]);
				if (veto.veto) {
					log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
					return this;
				}

				// provide opportunity to alter form data before it is
				// serialized
				if (options.beforeSerialize
						&& options.beforeSerialize(this, options) === false) {
					log('ajaxSubmit: submit aborted via beforeSerialize callback');
					return this;
				}

				var traditional = options.traditional;
				if (traditional === undefined) {
					traditional = $.ajaxSettings.traditional;
				}

				var elements = [];
				var qx, a = this.formToArray(options.semantic, elements);
				if (options.data) {
					options.extraData = options.data;
					qx = $.param(options.data, traditional);
				}

				// give pre-submit callback an opportunity to abort the submit
				if (options.beforeSubmit
						&& options.beforeSubmit(a, this, options) === false) {
					log('ajaxSubmit: submit aborted via beforeSubmit callback');
					return this;
				}

				// fire vetoable 'validate' event
				this.trigger('form-submit-validate', [a, this, options, veto]);
				if (veto.veto) {
					log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
					return this;
				}

				var q = $.param(a, traditional);
				if (qx) {
					q = (q ? (q + '&' + qx) : qx);
				}
				if (options.type.toUpperCase() == 'GET') {
					options.url += (options.url.indexOf('?') >= 0 ? '&' : '?')
							+ q;
					options.data = null; // data is null for 'get'
				} else {
					options.data = q; // data is the query string for 'post'
				}

				var callbacks = [];
				if (options.resetForm) {
					callbacks.push(function() {
								$form.resetForm();
							});
				}
				if (options.clearForm) {
					callbacks.push(function() {
								$form.clearForm(options.includeHidden);
							});
				}

				// perform a load on the target only if dataType is not provided
				if (!options.dataType && options.target) {
					var oldSuccess = options.success || function() {
					};
					callbacks.push(function(data) {
						var fn = options.replaceTarget ? 'replaceWith' : 'html';
						$(options.target)[fn](data).each(oldSuccess, arguments);
					});
				} else if (options.success) {
					callbacks.push(options.success);
				}

				options.success = function(data, status, xhr) { // jQuery 1.4+
																// passes xhr as
																// 3rd arg
					var context = options.context || this; // jQuery 1.4+
															// supports scope
															// context
					for (var i = 0, max = callbacks.length; i < max; i++) {
						callbacks[i].apply(context, [data, status,
										xhr || $form, $form]);
					}
				};

				if (options.error) {
					var oldError = options.error;
					options.error = function(xhr, status, error) {
						var context = options.context || this;
						oldError.apply(context, [xhr, status, error, $form]);
					};
				}

				if (options.complete) {
					var oldComplete = options.complete;
					options.complete = function(xhr, status) {
						var context = options.context || this;
						oldComplete.apply(context, [xhr, status, $form]);
					};
				}

				// are there files to upload?

				// [value] (issue #113), also see comment:
				// https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
				var fileInputs = $('input[type=file]:enabled', this).filter(
						function() {
							return $(this).val() !== '';
						});

				var hasFileInputs = fileInputs.length > 0;
				var mp = 'multipart/form-data';
				var multipart = ($form.attr('enctype') == mp || $form
						.attr('encoding') == mp);

				var fileAPI = feature.fileapi && feature.formdata;
				log("fileAPI :" + fileAPI);
				var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;

				var jqxhr;

				// options.iframe allows user to force iframe mode
				// 06-NOV-09: now defaulting to iframe mode if file input is
				// detected
				if (options.iframe !== false
						&& (options.iframe || shouldUseFrame)) {
					// hack to fix Safari hang (thanks to Tim Molendijk for
					// this)
					// see:
					// http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
					if (options.closeKeepAlive) {
						$.get(options.closeKeepAlive, function() {
									jqxhr = fileUploadIframe(a);
								});
					} else {
						jqxhr = fileUploadIframe(a);
					}
				} else if ((hasFileInputs || multipart) && fileAPI) {
					jqxhr = fileUploadXhr(a);
				} else {
					jqxhr = $.ajax(options);
				}

				$form.removeData('jqxhr').data('jqxhr', jqxhr);

				// clear element array
				for (var k = 0; k < elements.length; k++) {
					elements[k] = null;
				}

				// fire 'notify' event
				this.trigger('form-submit-notify', [this, options]);
				return this;

				// utility fn for deep serialization
				function deepSerialize(extraData) {
					var serialized = $.param(extraData, options.traditional)
							.split('&');
					var len = serialized.length;
					var result = [];
					var i, part;
					for (i = 0; i < len; i++) {
						// #252; undo param space replacement
						serialized[i] = serialized[i].replace(/\+/g, ' ');
						part = serialized[i].split('=');
						// #278; use array instead of object storage, favoring
						// array serializations
						result.push([decodeURIComponent(part[0]),
								decodeURIComponent(part[1])]);
					}
					return result;
				}

				// XMLHttpRequest Level 2 file uploads (big hat tip to
				// francois2metz)
				function fileUploadXhr(a) {
					var formdata = new FormData();

					for (var i = 0; i < a.length; i++) {
						formdata.append(a[i].name, a[i].value);
					}

					if (options.extraData) {
						var serializedData = deepSerialize(options.extraData);
						for (i = 0; i < serializedData.length; i++) {
							if (serializedData[i]) {
								formdata.append(serializedData[i][0],
										serializedData[i][1]);
							}
						}
					}

					options.data = null;

					var s = $.extend(true, {}, $.ajaxSettings, options, {
								contentType : false,
								processData : false,
								cache : false,
								type : method || 'POST'
							});

					if (options.uploadProgress) {
						// workaround because jqXHR does not expose upload
						// property
						s.xhr = function() {
							var xhr = $.ajaxSettings.xhr();
							if (xhr.upload) {
								xhr.upload.addEventListener('progress',
										function(event) {
											var percent = 0;
											var position = event.loaded
													|| event.position; /*
																		 * event.position
																		 * is
																		 * deprecated
																		 */
											var total = event.total;
											if (event.lengthComputable) {
												percent = Math.ceil(position
														/ total * 100);
											}
											options.uploadProgress(event,
													position, total, percent);
										}, false);
							}
							return xhr;
						};
					}

					s.data = null;
					var beforeSend = s.beforeSend;
					s.beforeSend = function(xhr, o) {
						// Send FormData() provided by user
						if (options.formData) {
							o.data = options.formData;
						} else {
							o.data = formdata;
						}
						if (beforeSend) {
							beforeSend.call(this, xhr, o);
						}
					};
					return $.ajax(s);
				}

				// private function for handling file uploads (hat tip to
				// YAHOO!)
				function fileUploadIframe(a) {
					var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
					var deferred = $.Deferred();

					// #341
					deferred.abort = function(status) {
						xhr.abort(status);
					};

					if (a) {
						// ensure that every serialized input is still enabled
						for (i = 0; i < elements.length; i++) {
							el = $(elements[i]);
							if (hasProp) {
								el.prop('disabled', false);
							} else {
								el.removeAttr('disabled');
							}
						}
					}

					s = $.extend(true, {}, $.ajaxSettings, options);
					s.context = s.context || s;
					id = 'jqFormIO' + (new Date().getTime());
					if (s.iframeTarget) {
						$io = $(s.iframeTarget);
						n = $io.attr2('name');
						if (!n) {
							$io.attr2('name', id);
						} else {
							id = n;
						}
					} else {
						$io = $('