diff --git a/.gitignore b/.gitignore index be0d9e8..53ee1db 100644 --- a/.gitignore +++ b/.gitignore @@ -342,4 +342,5 @@ healthchecksdb /WaterCloud.Web/DataProtection /WaterCloud.Web/wwwroot/file/local/20221006 /HT.Cloud.Web/wwwroot/report -/HT.Cloud.sln +/HT.Cloud.Web/watercloudnetdb.db-journal +/RabbitMq \ No newline at end of file diff --git a/HT.Cloud.Code/Cache/MemoryCacheHelper.cs b/HT.Cloud.Code/Cache/MemoryCacheHelper.cs index 3abb7b6..88027d2 100644 --- a/HT.Cloud.Code/Cache/MemoryCacheHelper.cs +++ b/HT.Cloud.Code/Cache/MemoryCacheHelper.cs @@ -212,16 +212,33 @@ namespace HT.Cloud.Code /// public static List GetCacheKeys() { - const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; - var entries = Cache.GetType().GetField("_entries", flags).GetValue(Cache); - var cacheItems = entries as IDictionary; - var keys = new List(); - if (cacheItems == null) return keys; - foreach (DictionaryEntry cacheItem in cacheItems) - { - keys.Add(cacheItem.Key.ToString()); - } - return keys; - } - } +#if NET8_0 + const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; + var entries = Cache.GetType().GetField("_coherentState", flags)?.GetValue(Cache); + var cacheItems = entries?.GetType()?.GetProperty("EntriesCollection", flags)?.GetValue(entries) as ICollection; //entries as IDictionary; + var keys = new List(); + if (cacheItems == null) return keys; + foreach (var item in cacheItems) + { + var methodInfo = item.GetType().GetProperty("Key"); + + var val = methodInfo.GetValue(item); + + keys.Add(val.ToString()); + } + return keys; +#else + const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; + var entries = Cache.GetType().GetField("_entries", flags).GetValue(Cache); + var cacheItems = entries as IDictionary; + var keys = new List(); + if (cacheItems == null) return keys; + foreach (DictionaryEntry cacheItem in cacheItems) + { + keys.Add(cacheItem.Key.ToString()); + } + return keys; +#endif + } + } } \ No newline at end of file diff --git a/HT.Cloud.Code/DefaultStartUp.cs b/HT.Cloud.Code/DefaultStartUp.cs index 2870400..f91f5b1 100644 --- a/HT.Cloud.Code/DefaultStartUp.cs +++ b/HT.Cloud.Code/DefaultStartUp.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; +using Serenity.Abstractions; using System; using System.Collections.Generic; using System.IO; @@ -23,8 +24,8 @@ namespace HT.Cloud.Code { public class DefaultStartUp { - protected IConfiguration Configuration { get; } - protected IWebHostEnvironment WebHostEnvironment { get; set; } + protected IConfiguration Configuration { get; set; } + protected IWebHostEnvironment WebHostEnvironment { get; set; } public DefaultStartUp(IConfiguration configuration, IWebHostEnvironment env) { @@ -37,7 +38,14 @@ namespace HT.Cloud.Code public virtual void ConfigureServices(IServiceCollection services) { GlobalContext.SystemConfig = Configuration.GetSection("SystemConfig").Get(); - GlobalContext.Services = services; + var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + //没有设置环境变量就默认生产环境 + if (string.IsNullOrWhiteSpace(environment)) + environment = "Production"; + Configuration = new ConfigurationBuilder().AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true).Build(); + + GlobalContext.SystemConfig = Configuration.GetSection("SystemConfig").Get(); + GlobalContext.Services = services; GlobalContext.Configuration = Configuration; services.Configure(options => { @@ -135,9 +143,10 @@ namespace HT.Cloud.Code public virtual void Configure(IApplicationBuilder app) { - //实时通讯跨域 - app.UseCors("CorsPolicy"); - if (WebHostEnvironment.IsDevelopment()) + GlobalContext.RootServices = app.ApplicationServices; + //实时通讯跨域 + app.UseCors("CorsPolicy"); + if (WebHostEnvironment.IsDevelopment()) { GlobalContext.SystemConfig.Debug = true; app.UseDeveloperExceptionPage(); @@ -155,16 +164,18 @@ namespace HT.Cloud.Code }); //启用 Gzip 和 Brotil 压缩功能 app.UseResponseCompression(); - app.Use(next => context => - { + app.Use(async (context, next) => + { context.Request.EnableBuffering(); - return next(context); - }); + // 执行下一个中间件 + await next.Invoke(); + // 释放所有未托管的服务提供器 + GlobalContext.DisposeUnmanagedObjects(); + }); //session app.UseSession(); //路径 app.UseRouting(); - GlobalContext.RootServices = app.ApplicationServices; } } @@ -312,54 +323,24 @@ namespace HT.Cloud.Code public static IServiceCollection AddWorkerService( this IServiceCollection @this) { - var ret = new List(); - try - { - var listAssemblies = new List(); - - var assemblies1 = Directory.GetFiles(AppContext.BaseDirectory, "*.dll"); - - foreach( var assembly in assemblies1) - { - Console.WriteLine(assembly); - } - - var assemblies = Directory.GetFiles(AppContext.BaseDirectory, "*.dll") - .Select(x => x.Substring(@"\").Substring(@"/").Replace(".dll", "")); - //.Select(x => Assembly.Load(x)).ToArray(); - foreach (var assembliesFile in assemblies) - { - try - { - Console.WriteLine(assembliesFile+"\n"); - listAssemblies.Add(Assembly.Load(assembliesFile)); - } - catch(Exception ex) - { - Console.WriteLine(ex.ToString()); - } - - } - var arrAssemblies = listAssemblies.ToArray(); - //排除列表 - var ignoreList = new List { "EventBusHostedService" }; - foreach (var item in arrAssemblies) - { - ret.AddRange(item.GetTypes() //获取当前类库下所有类型 - .Where(t => typeof(BackgroundService).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型 - .Where(t => !t.IsAbstract && t.IsClass && !ignoreList.Contains(t.Name)));//获取非抽象类 排除接口继承 - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - foreach (var item in ret) - { - @this.AddTransient(typeof(IHostedService), item); - } - return @this; - } + var ret = new List(); + var assemblies = Directory.GetFiles(AppContext.BaseDirectory, "HT.Cloud.*.dll") + .Select(x => x.Substring(@"\").Substring(@"/").Replace(".dll", "")) + .Select(x => Assembly.Load(x)).ToArray(); + //排除列表 + var ignoreList = new List { "EventBusHostedService" }; + foreach (var item in assemblies) + { + ret.AddRange(item.GetTypes() //获取当前类库下所有类型 + .Where(t => typeof(BackgroundService).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型 + .Where(t => !t.IsAbstract && t.IsClass && !ignoreList.Contains(t.Name)));//获取非抽象类 排除接口继承 + } + foreach (var item in ret) + { + @this.AddTransient(typeof(IHostedService), item); + } + return @this; + } #endregion AddWorkerService diff --git a/HT.Cloud.Code/Flow/FlowNode.cs b/HT.Cloud.Code/Flow/FlowNode.cs index 95940f4..51fa8ea 100644 --- a/HT.Cloud.Code/Flow/FlowNode.cs +++ b/HT.Cloud.Code/Flow/FlowNode.cs @@ -36,8 +36,11 @@ public const string SPECIAL_USER = "SPECIAL_USER"; //指定用户 public const string ALL_USER = "ALL_USER"; //所有用户 public const string SPECIAL_ROLE = "SPECIAL_ROLE"; //指定角色 - public const string RUNTIME_SPECIAL_ROLE = "RUNTIME_SPECIAL_ROLE"; //运行时指定角色 - public const string RUNTIME_SPECIAL_USER = "RUNTIME_SPECIAL_USER"; //运行时指定用户 + public const string DEPARTMENT_MANAGER = "DEPARTMENT_MANAGER"; //部门负责人 + public const string USER_MANAGER = "USER_MANAGER"; //直属上级 + public const string MORE_USER_MANAGER = "MORE_USER_MANAGER"; //连续多级直属上级 + public const string RUNTIME_SPECIAL_ROLE = "RUNTIME_SPECIAL_ROLE"; //运行时指定角色 + public const string RUNTIME_SPECIAL_USER = "RUNTIME_SPECIAL_USER"; //运行时指定用户 /// /// 节点执行权限类型 @@ -94,13 +97,13 @@ public string[] roles { get; set; } public string[] orgs { get; set; } public bool currentDepart { get; set; } - } + } - /// - /// 节点执行结果标签 - /// - public class Tag - { + /// + /// 节点执行结果标签 + /// + public class Tag + { /// /// 1: 通过 /// 2:不通过 diff --git a/HT.Cloud.Code/Globals/GlobalContext.cs b/HT.Cloud.Code/Globals/GlobalContext.cs index dc088f3..ed08e2c 100644 --- a/HT.Cloud.Code/Globals/GlobalContext.cs +++ b/HT.Cloud.Code/Globals/GlobalContext.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Linq; using System.Reflection; @@ -13,24 +14,39 @@ using HT.Cloud.Code.Model; namespace HT.Cloud.Code { - public class GlobalContext + public static class GlobalContext { - /// - /// 服务集合 - /// - public static IServiceCollection Services { get; set; } - /// - /// 根服务 - /// - public static IServiceProvider RootServices { get; set; } + /// + /// 构造函数 + /// + static GlobalContext() + { + // 未托管的对象 + UnmanagedObjects = new ConcurrentBag(); + } + /// + /// 服务集合 + /// + public static IServiceCollection Services { get; set; } + + /// + /// 根服务 + /// + public static IServiceProvider RootServices { get; set; } public static IConfiguration Configuration { get; set; } public static IWebHostEnvironment HostingEnvironment { get; set; } - public static HttpContext HttpContext => RootServices?.GetService()?.HttpContext; - public static SystemConfig SystemConfig { get; set; } + /// + /// 未托管的对象集合 + /// + public static readonly ConcurrentBag UnmanagedObjects; + + public static HttpContext HttpContext => RootServices?.GetService()?.HttpContext; + + public static SystemConfig SystemConfig { get; set; } /// /// 获取请求生存周期的服务(未注册返回null) @@ -91,27 +107,70 @@ namespace HT.Cloud.Code { return RootServices; } - if (HttpContext?.RequestServices != null) - { - return HttpContext.RequestServices; - } + // 第二选择是获取 HttpContext 对象的 RequestServices + var httpContext = HttpContext; + if (httpContext?.RequestServices != null) return httpContext.RequestServices; + // 第三选择,创建新的作用域并返回服务提供器 else if (RootServices != null) { - using var scoped = RootServices.CreateScope(); + var scoped = RootServices.CreateScope(); + UnmanagedObjects.Add(scoped); return scoped.ServiceProvider; } + // 第四选择,构建新的服务对象(性能最差) else { - using var serviceProvider = Services.BuildServiceProvider(); + var serviceProvider = Services.BuildServiceProvider(); + UnmanagedObjects.Add(serviceProvider); return serviceProvider; } } + + + /// + /// GC 回收默认间隔 + /// + private const int GC_COLLECT_INTERVAL_SECONDS = 5; + + /// + /// 记录最近 GC 回收时间 + /// + private static DateTime? LastGCCollectTime { get; set; } + + /// + /// 释放所有未托管的对象 + /// + public static void DisposeUnmanagedObjects() + { + foreach (var dsp in UnmanagedObjects) + { + try + { + dsp?.Dispose(); + } + finally { } + } + + // 强制手动回收 GC 内存 + if (UnmanagedObjects.Any()) + { + var nowTime = DateTime.UtcNow; + if ((LastGCCollectTime == null || (nowTime - LastGCCollectTime.Value).TotalSeconds > GC_COLLECT_INTERVAL_SECONDS)) + { + LastGCCollectTime = nowTime; + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + } + + UnmanagedObjects.Clear(); + } /// /// 获取版本号 /// /// public static string GetVersion() - { + { Version version = Assembly.GetEntryAssembly().GetName().Version; return version.ToString(); } @@ -145,7 +204,7 @@ namespace HT.Cloud.Code { int second = 365 * 24 * 60 * 60; context.Context.Response.Headers.Add("Cache-Control", new[] { "public,max-age=" + second }); - context.Context.Response.Headers.Add("Expires", new[] { DateTime.UtcNow.AddYears(1).ToString("R") }); // Format RFC1123 - } + context.Context.Response.Headers.Add("Expires", new[] { DateTime.UtcNow.AddYears(1).ToString("R") }); // Format RFC1123 + } } } \ No newline at end of file diff --git a/HT.Cloud.Code/HT.Cloud.Code.csproj b/HT.Cloud.Code/HT.Cloud.Code.csproj index b530757..c5b815a 100644 --- a/HT.Cloud.Code/HT.Cloud.Code.csproj +++ b/HT.Cloud.Code/HT.Cloud.Code.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 @@ -35,22 +35,19 @@ - - - + + + - - - - - - + + + - - + + - + diff --git a/HT.Cloud.Code/Operator/OperatorModel.cs b/HT.Cloud.Code/Operator/OperatorModel.cs index 2592d01..4890293 100644 --- a/HT.Cloud.Code/Operator/OperatorModel.cs +++ b/HT.Cloud.Code/Operator/OperatorModel.cs @@ -32,7 +32,6 @@ namespace HT.Cloud.Code public bool IsAdmin { get; set; } public bool IsBoss { get; set; } public bool IsSenior { get; set; } - public bool IsLeaderInDepts { get; set; } public bool IsSaleman { get; set; } // 拓展字段,2019-03-03 diff --git a/HT.Cloud.CodeGenerator/HT.Cloud.CodeGenerator.csproj b/HT.Cloud.CodeGenerator/HT.Cloud.CodeGenerator.csproj index fc5cb9f..d362d4a 100644 --- a/HT.Cloud.CodeGenerator/HT.Cloud.CodeGenerator.csproj +++ b/HT.Cloud.CodeGenerator/HT.Cloud.CodeGenerator.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 @@ -9,7 +9,7 @@ - + diff --git a/HT.Cloud.Data/HT.Cloud.DataBase.csproj b/HT.Cloud.Data/HT.Cloud.DataBase.csproj index 666b91f..e9a6a60 100644 --- a/HT.Cloud.Data/HT.Cloud.DataBase.csproj +++ b/HT.Cloud.Data/HT.Cloud.DataBase.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 @@ -12,7 +12,7 @@ - + diff --git a/HT.Cloud.Domain/Entity/SystemManage/FormEntity.cs b/HT.Cloud.Domain/Entity/SystemManage/FormEntity.cs index da85642..063b6ac 100644 --- a/HT.Cloud.Domain/Entity/SystemManage/FormEntity.cs +++ b/HT.Cloud.Domain/Entity/SystemManage/FormEntity.cs @@ -68,7 +68,7 @@ namespace HT.Cloud.Domain.SystemManage /// 表单参数Json /// /// - [SugarColumn(IsNullable = true, ColumnName = "F_Content", ColumnDataType = "nvarchar(50)", ColumnDescription = "表单参数Json")] + [SugarColumn(IsNullable = true, ColumnName = "F_Content", ColumnDataType = "longtext", ColumnDescription = "表单参数Json")] public string F_Content { get; set; } /// diff --git a/HT.Cloud.Domain/Entity/SystemOrganize/Extend/OrganizeExtend.cs b/HT.Cloud.Domain/Entity/SystemOrganize/Extend/OrganizeExtend.cs new file mode 100644 index 0000000..f24c14f --- /dev/null +++ b/HT.Cloud.Domain/Entity/SystemOrganize/Extend/OrganizeExtend.cs @@ -0,0 +1,18 @@ +using SqlSugar; + +namespace HT.Cloud.Domain.SystemOrganize +{ + /// + /// 创 建:超级管理员 + /// 日 期:2023-12-25 08:54 + /// 描 述:组织实体扩展类 + /// + [SugarTable("sys_organize")] + [TenantAttribute("0")] + public class OrganizeExtend : OrganizeEntity + { + //使用导入错误信息 + public string ErrorMsg { get; set; } + public string F_ManagerName { get; set; } + } +} diff --git a/HT.Cloud.Domain/Entity/SystemOrganize/Extend/UserExtend.cs b/HT.Cloud.Domain/Entity/SystemOrganize/Extend/UserExtend.cs index c9609a3..d092605 100644 --- a/HT.Cloud.Domain/Entity/SystemOrganize/Extend/UserExtend.cs +++ b/HT.Cloud.Domain/Entity/SystemOrganize/Extend/UserExtend.cs @@ -22,5 +22,6 @@ namespace HT.Cloud.Domain.SystemOrganize public string F_DutyName { get; set; } public string F_CompanyName { get; set; } - } + public string F_ManagerName { get; set; } + } } \ No newline at end of file diff --git a/HT.Cloud.Domain/Entity/SystemOrganize/OrganizeEntity.cs b/HT.Cloud.Domain/Entity/SystemOrganize/OrganizeEntity.cs index e55d8b8..b5e485e 100644 --- a/HT.Cloud.Domain/Entity/SystemOrganize/OrganizeEntity.cs +++ b/HT.Cloud.Domain/Entity/SystemOrganize/OrganizeEntity.cs @@ -64,10 +64,10 @@ namespace HT.Cloud.Domain.SystemOrganize [SugarColumn(IsNullable = true, ColumnName = "F_CategoryId", ColumnDataType = "nvarchar(50)", ColumnDescription = "类型")] public string F_CategoryId { get; set; } - /// - /// - /// - [SugarColumn(IsNullable = true, ColumnName = "F_ManagerId", ColumnDataType = "nvarchar(50)")] + /// + /// 部门负责人 + /// + [SugarColumn(IsNullable = true, ColumnName = "F_ManagerId", ColumnDataType = "nvarchar(50)")] public string F_ManagerId { get; set; } /// diff --git a/HT.Cloud.Domain/Entity/SystemSecurity/OpenJobEntity.cs b/HT.Cloud.Domain/Entity/SystemSecurity/OpenJobEntity.cs index 0ad6706..5573833 100644 --- a/HT.Cloud.Domain/Entity/SystemSecurity/OpenJobEntity.cs +++ b/HT.Cloud.Domain/Entity/SystemSecurity/OpenJobEntity.cs @@ -87,7 +87,7 @@ namespace HT.Cloud.Domain.SystemSecurity /// 上次发生错误信息 /// [Description("上次发生错误信息")] - [SugarColumn(IsNullable = true, ColumnDescription = "上次发生错误信息")] + [SugarColumn(IsNullable = true, ColumnDescription = "上次发生错误信息", ColumnDataType = "nvarchar(200)")] public string F_LastRunErrMsg { get; set; } /// diff --git a/HT.Cloud.Domain/HT.Cloud.Domain.csproj b/HT.Cloud.Domain/HT.Cloud.Domain.csproj index 876c5c5..05a874b 100644 --- a/HT.Cloud.Domain/HT.Cloud.Domain.csproj +++ b/HT.Cloud.Domain/HT.Cloud.Domain.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 @@ -9,8 +9,8 @@ - - + + diff --git a/HT.Cloud.Service/AutoJob/JobExecute.cs b/HT.Cloud.Service/AutoJob/JobExecute.cs index b706c96..dc1aa85 100644 --- a/HT.Cloud.Service/AutoJob/JobExecute.cs +++ b/HT.Cloud.Service/AutoJob/JobExecute.cs @@ -42,8 +42,7 @@ namespace HT.Cloud.Service.AutoJob { foreach (var item in DBInitialize.GetConnectionConfigs(false)) { - string temp = item.ConfigId; - db.GetConnection(temp).DefaultConfig(); + db.GetConnection(item.ConfigId).DefaultConfig(); } }); string jobId = ""; @@ -84,7 +83,7 @@ namespace HT.Cloud.Service.AutoJob //反射执行就行 var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; //反射取指定前后缀的dll - var referencedAssemblies = Directory.GetFiles(path, "WaterCloud.*.dll").Select(Assembly.LoadFrom).ToArray(); + var referencedAssemblies = Directory.GetFiles(path, "HT.Cloud.*.dll").Select(Assembly.LoadFrom).ToArray(); var types = referencedAssemblies .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces() .Contains(typeof(IJobTask)))).ToArray(); diff --git a/HT.Cloud.Service/Event/BaseEventSource.cs b/HT.Cloud.Service/Event/BaseEventSource.cs index 454eda1..1431998 100644 --- a/HT.Cloud.Service/Event/BaseEventSource.cs +++ b/HT.Cloud.Service/Event/BaseEventSource.cs @@ -5,8 +5,8 @@ using HT.Cloud.Code; namespace HT.Cloud.Service.Event { - public class BaseEventSource : IEventSource - { + public class BaseEventSource : IEventSource + { public BaseEventSource() { } @@ -41,5 +41,7 @@ namespace HT.Cloud.Service.Event [Newtonsoft.Json.JsonIgnore] [System.Text.Json.Serialization.JsonIgnore] public CancellationToken CancellationToken { get; set; } - } + + public bool IsConsumOnce => true; + } } diff --git a/HT.Cloud.Service/Event/LogEventSubscriber.cs b/HT.Cloud.Service/Event/LogEventSubscriber.cs index e27e6e8..824ec5c 100644 --- a/HT.Cloud.Service/Event/LogEventSubscriber.cs +++ b/HT.Cloud.Service/Event/LogEventSubscriber.cs @@ -28,8 +28,7 @@ namespace HT.Cloud.Service.Event { foreach (var item in DBInitialize.GetConnectionConfigs(false)) { - string temp = item.ConfigId; - db.GetConnection(temp).DefaultConfig(); + db.GetConnection(item.ConfigId).DefaultConfig(); } }); await new LogService(dbContext).WriteDbLog(input, user); diff --git a/HT.Cloud.Service/FlowManage/FlowinstanceService.cs b/HT.Cloud.Service/FlowManage/FlowinstanceService.cs index fa0451d..f60a954 100644 --- a/HT.Cloud.Service/FlowManage/FlowinstanceService.cs +++ b/HT.Cloud.Service/FlowManage/FlowinstanceService.cs @@ -15,6 +15,7 @@ using HT.Cloud.Domain.InfoManage; using HT.Cloud.Domain.SystemManage; using HT.Cloud.Domain.SystemOrganize; using HT.Cloud.Service.InfoManage; +using static iTextSharp.text.pdf.AcroFields; namespace HT.Cloud.Service.FlowManage { @@ -343,15 +344,23 @@ namespace HT.Cloud.Service.FlowManage wfruntime.MakeTagNode(wfruntime.currentNodeId, tag); if (tag.Taged == (int)TagState.Ok) { - flowInstance.F_PreviousId = flowInstance.F_ActivityId; - flowInstance.F_ActivityId = wfruntime.nextNodeId; - flowInstance.F_ActivityType = wfruntime.nextNodeType; - flowInstance.F_ActivityName = wfruntime.nextNode.name; - flowInstance.F_MakerList = (wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime, request) : ""); - flowInstance.F_IsFinish = (wfruntime.nextNodeType == 4 ? 1 : 0); - await AddTransHistory(wfruntime); - } - else + var roleIds = user.RoleId.Split(','); + if (wfruntime.currentNode.setInfo.NodeDesignate == Setinfo.MORE_USER_MANAGER && roleIds.Intersect(wfruntime.currentNode.setInfo.NodeDesignateData.roles).Count() == 0) + { + flowInstance.F_MakerList = GetNodeMarkers(wfruntime.currentNode); + } + else + { + flowInstance.F_PreviousId = flowInstance.F_ActivityId; + flowInstance.F_ActivityId = wfruntime.nextNodeId; + flowInstance.F_ActivityType = wfruntime.nextNodeType; + flowInstance.F_ActivityName = wfruntime.nextNode.name; + flowInstance.F_IsFinish = (wfruntime.nextNodeType == 4 ? 1 : 0); + flowInstance.F_MakerList = (wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime, request) : ""); + } + await AddTransHistory(wfruntime); + } + else { flowInstance.F_IsFinish = 3; //表示该节点不同意 } @@ -384,9 +393,9 @@ namespace HT.Cloud.Service.FlowManage { if (!string.IsNullOrEmpty(flowInstance.F_DbName)) { - formDic.Add("F_LastModifyUserId", this.currentuser.UserId); - formDic.Add("F_LastModifyTime", DateTime.Now); - formDic.Add("F_LastModifyUserName", this.currentuser.UserName); + formDic.TryAdd("F_LastModifyUserId", this.currentuser.UserId); + formDic.TryAdd("F_LastModifyTime", DateTime.Now); + formDic.TryAdd("F_LastModifyUserName", this.currentuser.UserName); flowInstance.F_FrmData = formDic.ToJson(); var data = repository.Db.DbMaintenance.GetColumnInfosByTableName(flowInstance.F_DbName, false); List oldID = formDic.Keys.ToList();//原来数据(原来ID) @@ -629,8 +638,27 @@ namespace HT.Cloud.Service.FlowManage users = users.Distinct().ToList(); makerList = JsonHelper.ArrayToString(users, makerList); } - else if (node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE || node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER) - { + else if (node.setInfo.NodeDesignate == Setinfo.DEPARTMENT_MANAGER)//部门负责人 + { + var orgs = node.setInfo.NodeDesignateData.orgs; + if (node.setInfo.NodeDesignateData.currentDepart) + { + var temp = repository.Db.Queryable().InSingle(flowCreator); + orgs = temp.F_OrganizeId.Split(','); + } + var managers = repository.Db.Queryable().Where(a => orgs.Contains(a.F_Id) && !string.IsNullOrEmpty(a.F_ManagerId)).Select(a => a.F_ManagerId).ToList(); + makerList = JsonHelper.ArrayToString(managers, makerList); + } + else if (node.setInfo.NodeDesignate == Setinfo.USER_MANAGER || node.setInfo.NodeDesignate == Setinfo.MORE_USER_MANAGER)//直属上级、直属上级多级负责人 + { + var temp = repository.Db.Queryable().InSingle(currentuser.UserId); + if (temp != null) + { + makerList = temp.F_ManagerId; + } + } + else if (node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE || node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER) + { //如果是运行时选定的用户,则暂不处理。由上个节点审批时选定 } } @@ -703,11 +731,43 @@ namespace HT.Cloud.Service.FlowManage users = users.Distinct().ToList(); flowinstance.NextMakerName = string.Join(',', repository.Db.Queryable().Where(a => users.Contains(a.F_Id)).Select(a => a.F_RealName).ToList()); } - } - if (runtime.currentNode != null && runtime.currentNode.setInfo != null && runtime.currentNodeType != 4) + else if (flowinstance.NextNodeDesignateType == Setinfo.DEPARTMENT_MANAGER)//部门负责人 + { + var orgs = runtime.nextNode.setInfo.NodeDesignateData.orgs; + if (runtime.nextNode.setInfo.NodeDesignateData.currentDepart) + { + var userEntity = repository.Db.Queryable().InSingle(flowinstance.F_CreatorUserId); + orgs = userEntity.F_OrganizeId.Split(','); + } + var departments = repository.Db.Queryable().Where(a => orgs.Contains(a.F_Id) && !string.IsNullOrEmpty(a.F_ManagerId)).Select(a => a.F_ManagerId).ToList(); + var departmentNames = repository.Db.Queryable().Where(a => departments.Contains(a.F_Id)).Select(a => a.F_RealName).ToList(); + flowinstance.NextMakerName = string.Join(',', departmentNames); + } + else if (flowinstance.NextNodeDesignateType == Setinfo.USER_MANAGER || flowinstance.NextNodeDesignateType == Setinfo.MORE_USER_MANAGER)//直属上级、直属上级多级负责人 + { + var userEntity = repository.Db.Queryable().InSingle(currentuser.UserId); + if (userEntity != null) + { + var manager = repository.Db.Queryable().InSingle(userEntity.F_ManagerId); + flowinstance.NextMakerName = manager?.F_RealName; + } + } + } + if (runtime.currentNode != null && runtime.currentNode.setInfo != null && runtime.currentNodeType != 4) { flowinstance.CurrentNodeDesignateType = runtime.currentNode.setInfo.NodeDesignate; - if (flowinstance.F_MakerList != "1" && !string.IsNullOrEmpty(flowinstance.F_MakerList)) + var roles = runtime.currentNode.setInfo.NodeDesignateData.roles; + var currentRoles = currentuser.RoleId.Split(","); + if (flowinstance.CurrentNodeDesignateType == Setinfo.MORE_USER_MANAGER && currentRoles.Intersect(roles).Count() == 0) + { + var userEntity = repository.Db.Queryable().InSingle(currentuser.UserId); + if (userEntity != null) + { + var manager = repository.Db.Queryable().InSingle(userEntity.F_ManagerId); + flowinstance.NextMakerName = manager?.F_RealName; + } + } + if (flowinstance.F_MakerList != "1" && !string.IsNullOrEmpty(flowinstance.F_MakerList)) { var temps = flowinstance.F_MakerList.Split(','); flowinstance.CurrentMakerName = string.Join(',', repository.Db.Queryable().Where(a => temps.Contains(a.F_Id)).Select(a => a.F_RealName).ToList()); @@ -867,10 +927,10 @@ namespace HT.Cloud.Service.FlowManage if (!string.IsNullOrEmpty(entity.F_DbName)) { var formDic = entity.F_FrmData.ToObject>(); - formDic.Add("F_CreatorUserId", this.currentuser.UserId); - formDic.Add("F_CreatorTime", DateTime.Now); - formDic.Add("F_CreatorUserName", this.currentuser.UserName); - formDic.Add("F_Id", Utils.GuId()); + formDic.TryAdd("F_CreatorUserId", this.currentuser.UserId); + formDic.TryAdd("F_CreatorTime", DateTime.Now); + formDic.TryAdd("F_CreatorUserName", this.currentuser.UserName); + formDic.TryAdd("F_Id", Utils.GuId()); entity.F_FrmData = formDic.ToJson(); var data = repository.Db.DbMaintenance.GetColumnInfosByTableName(entity.F_DbName, false); List oldID = formDic.Keys.ToList();//原来数据(原来ID) @@ -1028,9 +1088,9 @@ namespace HT.Cloud.Service.FlowManage { if (!string.IsNullOrEmpty(entity.F_DbName)) { - formDic.Add("F_LastModifyUserId", this.currentuser.UserId); - formDic.Add("F_LastModifyTime", DateTime.Now); - formDic.Add("F_LastModifyUserName", this.currentuser.UserName); + formDic.TryAdd("F_LastModifyUserId", this.currentuser.UserId); + formDic.TryAdd("F_LastModifyTime", DateTime.Now); + formDic.TryAdd("F_LastModifyUserName", this.currentuser.UserName); entity.F_FrmData = formDic.ToJson(); var data = repository.Db.DbMaintenance.GetColumnInfosByTableName(entity.F_DbName, false); List oldID = formDic.Keys.ToList();//原来数据(原来ID) diff --git a/HT.Cloud.Service/HT.Cloud.Service.csproj b/HT.Cloud.Service/HT.Cloud.Service.csproj index ac25546..64ae348 100644 --- a/HT.Cloud.Service/HT.Cloud.Service.csproj +++ b/HT.Cloud.Service/HT.Cloud.Service.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 @@ -9,9 +9,9 @@ - - - + + + diff --git a/HT.Cloud.Service/Infrastructure/BaseService.cs b/HT.Cloud.Service/Infrastructure/BaseService.cs index 159adf7..6306d90 100644 --- a/HT.Cloud.Service/Infrastructure/BaseService.cs +++ b/HT.Cloud.Service/Infrastructure/BaseService.cs @@ -47,8 +47,8 @@ namespace HT.Cloud.Service else { var dblist = DBInitialize.GetConnectionConfigs(false); - _context.AsTenant().AddConnection(dblist.FirstOrDefault(a => a.ConfigId == currentuser.DbNumber)); - repository.ChangeEntityDb(currentuser.DbNumber); + _context.AsTenant().AddConnection(dblist.FirstOrDefault(a => a.ConfigId.ToString() == currentuser.DbNumber)); + repository.ChangeEntityDb(currentuser.DbNumber); repository.Db.DefaultConfig(); } } diff --git a/HT.Cloud.Service/Infrastructure/ServiceSetup.cs b/HT.Cloud.Service/Infrastructure/ServiceSetup.cs index 675fe76..287f418 100644 --- a/HT.Cloud.Service/Infrastructure/ServiceSetup.cs +++ b/HT.Cloud.Service/Infrastructure/ServiceSetup.cs @@ -37,9 +37,8 @@ namespace HT.Cloud.Service { foreach (var item in configList) { - string temp = item.ConfigId; - db.GetConnection(temp).DefaultConfig(); - } + db.GetConnection(item.ConfigId).DefaultConfig(); + } }); //注入数据库连接 // 注册 SqlSugar diff --git a/HT.Cloud.Service/SystemManage/FlowschemeService.cs b/HT.Cloud.Service/SystemManage/FlowschemeService.cs index e7a04bf..4e98d4d 100644 --- a/HT.Cloud.Service/SystemManage/FlowschemeService.cs +++ b/HT.Cloud.Service/SystemManage/FlowschemeService.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System.Xml.Linq; using HT.Cloud.Code; using HT.Cloud.DataBase; using HT.Cloud.Domain.FlowManage; @@ -133,8 +134,28 @@ namespace HT.Cloud.Service.SystemManage users = users.Distinct().ToList(); temp.NextMakerName = string.Join(',', repository.Db.Queryable().Where(a => users.Contains(a.F_Id)).Select(a => a.F_RealName).ToList()); } - } - return temp; + else if (temp.NextNodeDesignateType == Setinfo.DEPARTMENT_MANAGER)//部门负责人 + { + var orgs = runtime.nextNode.setInfo.NodeDesignateData.orgs; + if (runtime.nextNode.setInfo.NodeDesignateData.currentDepart) + { + orgs = currentuser.OrganizeId.Split(','); + } + var departments = repository.Db.Queryable().Where(a => orgs.Contains(a.F_Id) && !string.IsNullOrEmpty(a.F_ManagerId)).Select(a => a.F_ManagerId).ToList(); + var departmentNames = repository.Db.Queryable().Where(a => departments.Contains(a.F_Id)).Select(a => a.F_RealName).ToList(); + temp.NextMakerName = string.Join(',', departmentNames); + } + else if (temp.NextNodeDesignateType == Setinfo.USER_MANAGER || temp.NextNodeDesignateType == Setinfo.MORE_USER_MANAGER)//直属上级、直属上级多级负责人 + { + var userEntity = repository.Db.Queryable().InSingle(currentuser.UserId); + if (userEntity != null) + { + var manager = repository.Db.Queryable().InSingle(userEntity.F_ManagerId); + temp.NextMakerName = manager?.F_RealName; + } + } + } + return temp; } #region 提交数据 diff --git a/HT.Cloud.Service/SystemOrganize/OrganizeService.cs b/HT.Cloud.Service/SystemOrganize/OrganizeService.cs index d90ca43..1fd3505 100644 --- a/HT.Cloud.Service/SystemOrganize/OrganizeService.cs +++ b/HT.Cloud.Service/SystemOrganize/OrganizeService.cs @@ -1,8 +1,8 @@ /******************************************************************************* - * Copyright © 2020 HT.Cloud.Framework 版权所有 - * Author: HT.Cloud - * Description: WaterCloud快速开发平台 - * Website: +* Copyright © 2020 WaterCloud.Framework 版权所有 +* Author: WaterCloud +* Description: WaterCloud快速开发平台 +* Website: *********************************************************************************/ using SqlSugar; @@ -13,68 +13,82 @@ using HT.Cloud.Domain.SystemOrganize; namespace HT.Cloud.Service.SystemOrganize { - public class OrganizeService : BaseService, IDenpendency - { - public OrganizeService(ISqlSugarClient context) : base(context) - { - } + public class OrganizeService : BaseService, IDenpendency + { + public OrganizeService(ISqlSugarClient context) : base(context) + { + } - public async Task> GetList() - { - var query = repository.IQueryable(); - return await query.Where(a => a.F_DeleteMark == false).ToListAsync(); - } + public async Task> GetList() + { + var query = GetQuery(); + return await query.Where(a => a.F_DeleteMark == false).ToListAsync(); + } - public async Task> GetLookList() - { - var query = repository.IQueryable().Where(a => a.F_DeleteMark == false); - query = GetDataPrivilege("a", "", query); - return await query.OrderBy(a => a.F_SortCode).ToListAsync(); - } + public async Task> GetLookList() + { + var query = GetQuery().Where(a => a.F_DeleteMark == false); + query = GetDataPrivilege("a", "", query); + return await query.OrderBy(a => a.F_SortCode).ToListAsync(); + } - public async Task GetLookForm(string keyValue) - { - var data = await repository.FindEntity(keyValue); - return GetFieldsFilterData(data); - } + public async Task GetLookForm(string keyValue) + { + var data = await GetQuery().FirstAsync(a => a.F_Id == keyValue); + return GetFieldsFilterData(data); + } - public async Task GetForm(string keyValue) - { - var data = await repository.FindEntity(keyValue); - return data; - } + public async Task GetForm(string keyValue) + { + var data = await GetQuery().FirstAsync(a => a.F_Id == keyValue); + return data; + } - public async Task DeleteForm(string keyValue) - { - if (await repository.IQueryable(a => a.F_ParentId.Equals(keyValue)).AnyAsync()) - { - throw new Exception("删除失败!操作的对象包含了下级数据。"); - } - else - { - if (await repository.Db.Queryable().Where(a => a.F_CompanyId == keyValue).AnyAsync() || await repository.Db.Queryable().Where(a => a.F_OrganizeId == keyValue).AnyAsync()) - { - throw new Exception("组织使用中,无法删除"); - } - await repository.Delete(a => a.F_Id == keyValue); - } - } - public async Task SubmitForm(OrganizeEntity organizeEntity, string keyValue) - { - if (!string.IsNullOrEmpty(keyValue)) - { - organizeEntity.Modify(keyValue); - await repository.Update(organizeEntity); - } - else - { - organizeEntity.F_AllowDelete = false; - organizeEntity.F_AllowEdit = false; - organizeEntity.F_DeleteMark = false; - organizeEntity.Create(); - await repository.Insert(organizeEntity); - } - } - } + private ISugarQueryable GetQuery() + { + var query = repository.Db.Queryable((a, b) => new JoinQueryInfos( + JoinType.Left, a.F_ManagerId == b.F_Id + )).Where(a => a.F_DeleteMark == false) + .Select((a, b) => new OrganizeExtend + { + F_Id = a.F_Id.SelectAll(), + F_ManagerName = b.F_RealName + }).MergeTable(); + return query; + } + + public async Task DeleteForm(string keyValue) + { + if (await repository.IQueryable(a => a.F_ParentId.Equals(keyValue)).AnyAsync()) + { + throw new Exception("删除失败!操作的对象包含了下级数据。"); + } + else + { + if (await repository.Db.Queryable().Where(a => a.F_CompanyId == keyValue).AnyAsync() || await repository.Db.Queryable().Where(a => a.F_OrganizeId == keyValue).AnyAsync()) + { + throw new Exception("组织使用中,无法删除"); + } + await repository.Delete(a => a.F_Id == keyValue); + } + } + + public async Task SubmitForm(OrganizeEntity organizeEntity, string keyValue) + { + if (!string.IsNullOrEmpty(keyValue)) + { + organizeEntity.Modify(keyValue); + await repository.Update(organizeEntity); + } + else + { + organizeEntity.F_AllowDelete = false; + organizeEntity.F_AllowEdit = false; + organizeEntity.F_DeleteMark = false; + organizeEntity.Create(); + await repository.Insert(organizeEntity); + } + } + } } \ No newline at end of file diff --git a/HT.Cloud.Service/SystemOrganize/UserService.cs b/HT.Cloud.Service/SystemOrganize/UserService.cs index 851b4a5..ceeedc5 100644 --- a/HT.Cloud.Service/SystemOrganize/UserService.cs +++ b/HT.Cloud.Service/SystemOrganize/UserService.cs @@ -1,8 +1,8 @@ /******************************************************************************* - * Copyright © 2020 HT.Cloud.Framework 版权所有 - * Author: HT.Cloud - * Description: WaterCloud快速开发平台 - * Website: +* Copyright © 2020 WaterCloud.Framework 版权所有 +* Author: WaterCloud +* Description: WaterCloud快速开发平台 +* Website: *********************************************************************************/ using SqlSugar; @@ -19,362 +19,376 @@ using HT.Cloud.Service.SystemSecurity; namespace HT.Cloud.Service.SystemOrganize { - public class UserService : BaseService, IDenpendency - { - public SystemSetService syssetApp { get; set; } - public FilterIPService ipApp { get; set; } + public class UserService : BaseService, IDenpendency + { + public SystemSetService syssetApp { get; set; } + public FilterIPService ipApp { get; set; } - /// - /// 缓存操作类 - /// - private string cacheKeyOperator = GlobalContext.SystemConfig.ProjectPrefix + "_operator_";// +登录者token + /// + /// 缓存操作类 + /// + private string cacheKeyOperator = GlobalContext.SystemConfig.ProjectPrefix + "_operator_";// +登录者token - //获取类名 + //获取类名 - public UserService(ISqlSugarClient context) : base(context) - { - } + public UserService(ISqlSugarClient context) : base(context) + { + } - public async Task> GetLookList(SoulPage pagination, string keyword) - { - //反格式化显示只能用"等于",其他不支持 - Dictionary> dic = new Dictionary>(); - Dictionary enabledTemp = new Dictionary(); - enabledTemp.Add("1", "有效"); - enabledTemp.Add("0", "无效"); - dic.Add("F_EnabledMark", enabledTemp); - Dictionary sexTemp = new Dictionary(); - var sexList = await GlobalContext.GetService().GetItemList("104"); - foreach (var item in sexList) - { - sexTemp.Add(item.F_ItemCode, item.F_ItemName); - } - dic.Add("F_Gender", sexTemp); - pagination = ChangeSoulData(dic, pagination); - //获取数据权限 - var query = GetQuery().Where(a => a.F_IsAdmin == false); - if (!string.IsNullOrEmpty(keyword)) - { - query = query.Where(a => a.F_Account.Contains(keyword) || a.F_RealName.Contains(keyword) || a.F_MobilePhone.Contains(keyword)); - } - query = GetDataPrivilege("a", "", query); - var data = await query.ToPageListAsync(pagination); - var roles = repository.Db.Queryable().ToList(); - var orgs = repository.Db.Queryable().ToList(); - foreach (var item in data) - { - string[] roleIds = item.F_RoleId.Split(','); - string[] departmentIds = item.F_OrganizeId.Split(','); - item.F_OrganizeName = string.Join(',', orgs.Where(a => departmentIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); - item.F_RoleName = string.Join(',', roles.Where(a => roleIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); - } - return data; - } + public async Task> GetLookList(SoulPage pagination, string keyword) + { + //反格式化显示只能用"等于",其他不支持 + Dictionary> dic = new Dictionary>(); + Dictionary enabledTemp = new Dictionary(); + enabledTemp.Add("1", "有效"); + enabledTemp.Add("0", "无效"); + dic.Add("F_EnabledMark", enabledTemp); + Dictionary sexTemp = new Dictionary(); + var sexList = await GlobalContext.GetService().GetItemList("104"); + foreach (var item in sexList) + { + sexTemp.Add(item.F_ItemCode, item.F_ItemName); + } + dic.Add("F_Gender", sexTemp); + pagination = ChangeSoulData(dic, pagination); + //获取数据权限 + var query = GetQuery().Where(a => a.F_IsAdmin == false); + if (!string.IsNullOrEmpty(keyword)) + { + query = query.Where(a => a.F_Account.Contains(keyword) || a.F_RealName.Contains(keyword) || a.F_MobilePhone.Contains(keyword)); + } + query = GetDataPrivilege("a", "", query); + var data = await query.ToPageListAsync(pagination); + var roles = repository.Db.Queryable().ToList(); + var orgs = repository.Db.Queryable().ToList(); + foreach (var item in data) + { + string[] roleIds = item.F_RoleId.Split(','); + string[] departmentIds = item.F_OrganizeId.Split(','); + item.F_OrganizeName = string.Join(',', orgs.Where(a => departmentIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); + item.F_RoleName = string.Join(',', roles.Where(a => roleIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); + item.F_IsLeaderInDepts = orgs.Any(a => departmentIds.Contains(a.F_Id) && a.F_ManagerId == item.F_Id); + } + return data; + } - public async Task> GetList(string keyword) - { - var cachedata = GetQuery().Where(a => a.F_IsAdmin == false); - if (!string.IsNullOrEmpty(keyword)) - { - cachedata = cachedata.Where(a => a.F_Account.Contains(keyword) || a.F_RealName.Contains(keyword) || a.F_MobilePhone.Contains(keyword)); - } - var data = await cachedata.OrderBy(a => a.F_Account).ToListAsync(); - var roles = await repository.Db.Queryable().ToListAsync(); - var orgs = await repository.Db.Queryable().ToListAsync(); - foreach (var item in data) - { - string[] roleIds = item.F_RoleId.Split(','); - string[] departmentIds = item.F_OrganizeId.Split(','); - item.F_OrganizeName = string.Join(',', orgs.Where(a => departmentIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); - item.F_RoleName = string.Join(',', roles.Where(a => roleIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); - } - return data; - } + public async Task> GetList(string keyword) + { + var cachedata = GetQuery().Where(a => a.F_IsAdmin == false); + if (!string.IsNullOrEmpty(keyword)) + { + cachedata = cachedata.Where(a => a.F_Account.Contains(keyword) || a.F_RealName.Contains(keyword) || a.F_MobilePhone.Contains(keyword)); + } + var data = await cachedata.OrderBy(a => a.F_Account).ToListAsync(); + var roles = await repository.Db.Queryable().ToListAsync(); + var orgs = await repository.Db.Queryable().ToListAsync(); + foreach (var item in data) + { + string[] roleIds = item.F_RoleId.Split(','); + string[] departmentIds = item.F_OrganizeId.Split(','); + item.F_OrganizeName = string.Join(',', orgs.Where(a => departmentIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); + item.F_RoleName = string.Join(',', roles.Where(a => roleIds.Contains(a.F_Id)).Select(a => a.F_FullName).ToList()); + item.F_IsLeaderInDepts = orgs.Any(a => departmentIds.Contains(a.F_Id) && a.F_ManagerId == item.F_Id); + } + return data; + } - private ISugarQueryable GetQuery() - { - var query = repository.Db.Queryable((a, b, c) => new JoinQueryInfos( - JoinType.Left, a.F_DutyId == b.F_Id, - JoinType.Left, a.F_CompanyId == c.F_Id - )).Where(a => a.F_DeleteMark == false) - .Select((a, b, c) => new UserExtend - { - F_Id = a.F_Id, - F_IsSenior = a.F_IsSenior, - F_SecurityLevel = a.F_SecurityLevel, - F_Account = a.F_Account, - F_DingTalkAvatar = a.F_DingTalkAvatar, - F_IsAdmin = a.F_IsAdmin, - F_Birthday = a.F_Birthday, - F_CompanyName = c.F_CompanyName, - F_CreatorTime = a.F_CreatorTime, - F_CreatorUserId = a.F_CreatorUserId, - F_OrganizeId = a.F_OrganizeId, - F_Description = a.F_Description, - F_DingTalkUserId = a.F_DingTalkUserId, - F_DingTalkUserName = a.F_DingTalkUserName, - F_DutyId = a.F_DutyId, - F_DutyName = b.F_FullName, - F_Email = a.F_Email, - F_EnabledMark = a.F_EnabledMark, - F_Gender = a.F_Gender, - F_HeadIcon = a.F_HeadIcon, - F_HeadImgUrl = a.F_HeadImgUrl, - F_IsBoss = a.F_IsBoss, - F_IsLeaderInDepts = a.F_IsLeaderInDepts, - F_ManagerId = a.F_ManagerId, - F_MobilePhone = a.F_MobilePhone, - F_NickName = a.F_NickName, - F_CompanyId = a.F_CompanyId, - F_RealName = a.F_RealName, - F_Remark = a.F_RealName, - F_RoleId = a.F_RoleId, - F_Signature = a.F_Signature, - F_SortCode = a.F_SortCode, - F_WeChat = a.F_WeChat, - F_WxNickName = a.F_WxNickName, - F_WxOpenId = a.F_WxOpenId, - F_OrganizeName = "", - F_RoleName = "" - }).MergeTable(); - return query; - } + private ISugarQueryable GetQuery() + { + var query = repository.Db.Queryable((a, b, c, d) => new JoinQueryInfos( + JoinType.Left, a.F_DutyId == b.F_Id, + JoinType.Left, a.F_CompanyId == c.F_Id, + JoinType.Left, a.F_ManagerId == d.F_Id + )).Where(a => a.F_DeleteMark == false) + .Select((a, b, c, d) => new UserExtend + { + F_Id = a.F_Id, + F_IsSenior = a.F_IsSenior, + F_SecurityLevel = a.F_SecurityLevel, + F_Account = a.F_Account, + F_DingTalkAvatar = a.F_DingTalkAvatar, + F_IsAdmin = a.F_IsAdmin, + F_Birthday = a.F_Birthday, + F_CompanyName = c.F_CompanyName, + F_CreatorTime = a.F_CreatorTime, + F_CreatorUserId = a.F_CreatorUserId, + F_OrganizeId = a.F_OrganizeId, + F_Description = a.F_Description, + F_DingTalkUserId = a.F_DingTalkUserId, + F_DingTalkUserName = a.F_DingTalkUserName, + F_DutyId = a.F_DutyId, + F_DutyName = b.F_FullName, + F_Email = a.F_Email, + F_EnabledMark = a.F_EnabledMark, + F_Gender = a.F_Gender, + F_HeadIcon = a.F_HeadIcon, + F_HeadImgUrl = a.F_HeadImgUrl, + F_IsBoss = a.F_IsBoss, + F_ManagerId = a.F_ManagerId, + F_ManagerName = d.F_RealName, + F_MobilePhone = a.F_MobilePhone, + F_NickName = a.F_NickName, + F_CompanyId = a.F_CompanyId, + F_RealName = a.F_RealName, + F_Remark = a.F_RealName, + F_RoleId = a.F_RoleId, + F_Signature = a.F_Signature, + F_SortCode = a.F_SortCode, + F_WeChat = a.F_WeChat, + F_WxNickName = a.F_WxNickName, + F_WxOpenId = a.F_WxOpenId, + F_OrganizeName = "", + F_RoleName = "" + }).MergeTable(); + return query; + } - public async Task SubmitUserForm(UserEntity userEntity) - { - await repository.Update(userEntity); - } + public async Task SubmitUserForm(UserEntity userEntity) + { + await repository.Update(userEntity); + } - public async Task> GetUserList(string keyword) - { - var query = repository.IQueryable(); - if (!string.IsNullOrEmpty(keyword)) - { - query = query.Where(a => a.F_Account.Contains(keyword) || a.F_RealName.Contains(keyword) || a.F_MobilePhone.Contains(keyword)); - } - return await query.Where(a => a.F_EnabledMark == true && a.F_DeleteMark == false).OrderBy(a => a.F_Account).ToListAsync(); - } + public async Task> GetUserList(string keyword) + { + var query = repository.IQueryable(); + if (!string.IsNullOrEmpty(keyword)) + { + query = query.Where(a => a.F_Account.Contains(keyword) || a.F_RealName.Contains(keyword) || a.F_MobilePhone.Contains(keyword)); + } + return await query.Where(a => a.F_EnabledMark == true && a.F_DeleteMark == false).OrderBy(a => a.F_Account).ToListAsync(); + } - public async Task GetForm(string keyValue) - { - var data = await repository.FindEntity(keyValue); - return data; - } + public async Task GetForm(string keyValue) + { + var data = await GetQuery().FirstAsync(a => a.F_Id == keyValue); + return data; + } - public async Task GetFormExtend(string keyValue) - { - var data = await repository.FindEntity(keyValue); - string[] temp; - if (data.F_RoleId != null) - { - temp = data.F_RoleId.Split(','); - data.F_RoleName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); - } - if (data.F_OrganizeId != null) - { - temp = data.F_OrganizeId.Split(','); - data.F_OrganizeName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); - } - return data; - } + public async Task GetFormExtend(string keyValue) + { + var data = await GetQuery().FirstAsync(a => a.F_Id == keyValue); + string[] temp; + if (data.F_RoleId != null) + { + temp = data.F_RoleId.Split(','); + data.F_RoleName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); + } + if (data.F_OrganizeId != null) + { + temp = data.F_OrganizeId.Split(','); + data.F_OrganizeName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); + data.F_IsLeaderInDepts = repository.Db.Queryable().Any(a => temp.Contains(a.F_Id) && a.F_ManagerId == data.F_Id); + } + return data; + } - public async Task GetLookForm(string keyValue) - { - var data = await repository.FindEntity(keyValue); - string[] temp; - if (data.F_RoleId != null) - { - temp = data.F_RoleId.Split(','); - data.F_RoleName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); - } - if (data.F_OrganizeId != null) - { - temp = data.F_OrganizeId.Split(','); - data.F_OrganizeName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); - } - return GetFieldsFilterData(data); - } + public async Task GetLookForm(string keyValue) + { + var data = await GetQuery().FirstAsync(a => a.F_Id == keyValue); + string[] temp; + if (data.F_RoleId != null) + { + temp = data.F_RoleId.Split(','); + data.F_RoleName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); + } + if (data.F_OrganizeId != null) + { + temp = data.F_OrganizeId.Split(','); + data.F_OrganizeName = string.Join(",", repository.Db.Queryable().Where(a => temp.Contains(a.F_Id)).Select(a => a.F_FullName).ToList().ToArray()); + data.F_IsLeaderInDepts = repository.Db.Queryable().Any(a => temp.Contains(a.F_Id) && a.F_ManagerId == data.F_Id); + } + return GetFieldsFilterData(data); + } - public async Task DeleteForm(string keyValue) - { - repository.Db.Ado.BeginTran(); - await repository.Delete(a => a.F_Id == keyValue); - await repository.Db.Deleteable(a => a.F_UserId == keyValue).ExecuteCommandAsync(); - repository.Db.Ado.CommitTran(); - } + public async Task DeleteForm(string keyValue) + { + repository.Db.Ado.BeginTran(); + await repository.Delete(a => a.F_Id == keyValue); + await repository.Db.Deleteable(a => a.F_UserId == keyValue).ExecuteCommandAsync(); + repository.Db.Ado.CommitTran(); + } - public async Task SubmitForm(UserEntity userEntity, UserLogOnEntity userLogOnEntity, string keyValue) - { - if (!string.IsNullOrEmpty(keyValue)) - { - userEntity.Modify(keyValue); - } - else - { - userEntity.Create(); - userLogOnEntity.F_Id = Utils.GuId(); - userLogOnEntity.F_UserId = userEntity.F_Id; - userLogOnEntity.F_ErrorNum = 0; - userLogOnEntity.F_UserOnLine = false; - userLogOnEntity.F_LogOnCount = 0; - } - repository.Db.Ado.BeginTran(); - if (!string.IsNullOrEmpty(keyValue)) - { - await repository.Update(userEntity); - } - else - { - userLogOnEntity.F_Id = userEntity.F_Id; - userLogOnEntity.F_UserId = userEntity.F_Id; - userLogOnEntity.F_UserSecretkey = Md5.md5(Utils.CreateNo(), 16).ToLower(); - userLogOnEntity.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(userLogOnEntity.F_UserPassword, 32).ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower(); - await repository.Insert(userEntity); - await repository.Db.Insertable(userLogOnEntity).ExecuteCommandAsync(); - } - repository.Db.Ado.CommitTran(); - } + public async Task SubmitForm(UserEntity userEntity, UserLogOnEntity userLogOnEntity, string keyValue) + { + if (!string.IsNullOrEmpty(keyValue)) + { + //自己不能作为自己的直属上级 + if (keyValue == userEntity.F_ManagerId) + { + userEntity.F_ManagerId = null; + } + if (userEntity.F_ManagerId.Contains(",")) + { + throw new Exception("只能选择一个直属上级"); + } + userEntity.Modify(keyValue); + } + else + { + userEntity.Create(); + userLogOnEntity.F_Id = Utils.GuId(); + userLogOnEntity.F_UserId = userEntity.F_Id; + userLogOnEntity.F_ErrorNum = 0; + userLogOnEntity.F_UserOnLine = false; + userLogOnEntity.F_LogOnCount = 0; + } + repository.Db.Ado.BeginTran(); + if (!string.IsNullOrEmpty(keyValue)) + { + await repository.Update(userEntity); + } + else + { + userLogOnEntity.F_Id = userEntity.F_Id; + userLogOnEntity.F_UserId = userEntity.F_Id; + userLogOnEntity.F_UserSecretkey = Md5.md5(Utils.CreateNo(), 16).ToLower(); + userLogOnEntity.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(userLogOnEntity.F_UserPassword, 32).ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower(); + await repository.Insert(userEntity); + await repository.Db.Insertable(userLogOnEntity).ExecuteCommandAsync(); + } + repository.Db.Ado.CommitTran(); + } - public async Task UpdateForm(UserEntity userEntity) - { - await repository.Update(userEntity); - } + public async Task UpdateForm(UserEntity userEntity) + { + await repository.Update(userEntity); + } - /// - /// 登录判断 - /// - /// - /// - /// - public async Task CheckLogin(string username, string password, string localurl) - { - //根据登录公司查找公司 - if (GlobalContext.SystemConfig.SqlMode == Define.SQL_TENANT) - { - repository.ChangeEntityDb(GlobalContext.SystemConfig.MainDbNumber); - var setTemp = (await syssetApp.GetList()).Where(a => localurl.Contains(a.F_HostUrl)).FirstOrDefault(); - if (setTemp != null) - { - if (setTemp.F_EndTime < DateTime.Now.Date) - { - throw new Exception("租户已到期,请联系供应商"); - } - if (!_context.AsTenant().IsAnyConnection(setTemp.F_DbNumber)) - { - var dblist = DBInitialize.GetConnectionConfigs(true); - _context.AsTenant().AddConnection(dblist.FirstOrDefault(a => a.ConfigId == setTemp.F_DbNumber)); - repository.ChangeEntityDb(setTemp.F_DbNumber); - repository.Db.DefaultConfig(); - } - else - { - repository.ChangeEntityDb(setTemp.F_DbNumber); - } - } - } - if (!(await CheckIP())) - { - throw new Exception("IP受限"); - } - UserEntity userEntity = await repository.IQueryable().SingleAsync(a => a.F_Account == username); - if (userEntity != null) - { - if (userEntity.F_EnabledMark == true) - { - //缓存用户账户信息 - var userLogOnEntity = await CacheHelper.GetAsync(cacheKeyOperator + "info_" + userEntity.F_Id); - if (userLogOnEntity == null) - { - userLogOnEntity = new OperatorUserInfo(); - UserLogOnEntity entity = await repository.Db.Queryable().InSingleAsync(userEntity.F_Id); - userLogOnEntity.F_UserPassword = entity.F_UserPassword; - userLogOnEntity.F_UserSecretkey = entity.F_UserSecretkey; - userLogOnEntity.F_AllowEndTime = entity.F_AllowEndTime; - userLogOnEntity.F_AllowStartTime = entity.F_AllowStartTime; - userLogOnEntity.F_AnswerQuestion = entity.F_AnswerQuestion; - userLogOnEntity.F_ChangePasswordDate = entity.F_ChangePasswordDate; - userLogOnEntity.F_FirstVisitTime = entity.F_FirstVisitTime; - userLogOnEntity.F_LastVisitTime = entity.F_LastVisitTime; - userLogOnEntity.F_LockEndDate = entity.F_LockEndDate; - userLogOnEntity.F_LockStartDate = entity.F_LockStartDate; - userLogOnEntity.F_LogOnCount = entity.F_LogOnCount; - userLogOnEntity.F_PreviousVisitTime = entity.F_PreviousVisitTime; - userLogOnEntity.F_Question = entity.F_Question; - userLogOnEntity.F_Theme = entity.F_Theme; - await CacheHelper.SetAsync(cacheKeyOperator + "info_" + userEntity.F_Id, userLogOnEntity); - } - if (userLogOnEntity == null) - { - throw new Exception("账户未初始化设置密码,请联系管理员"); - } - string dbPassword = Md5.md5(DESEncrypt.Encrypt(password.ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower(); - if (dbPassword == userLogOnEntity.F_UserPassword) - { - if (userEntity.F_IsAdmin != true) - { - var list = userEntity.F_RoleId.Split(','); - var rolelist = repository.Db.Queryable().Where(a => list.Contains(a.F_Id) && a.F_EnabledMark == true).ToList(); - if (!rolelist.Any()) - { - throw new Exception("账户未设置权限,请联系管理员"); - } - } - DateTime lastVisitTime = DateTime.Now; - int LogOnCount = (userLogOnEntity.F_LogOnCount).ToInt() + 1; - if (userLogOnEntity.F_LastVisitTime != null) - { - userLogOnEntity.F_PreviousVisitTime = userLogOnEntity.F_LastVisitTime.ToDate(); - } - userLogOnEntity.F_LastVisitTime = lastVisitTime; - userLogOnEntity.F_LogOnCount = LogOnCount; - userLogOnEntity.F_UserOnLine = true; - await CacheHelper.RemoveAsync(cacheKeyOperator + "info_" + userEntity.F_Id); - await CacheHelper.SetAsync(cacheKeyOperator + "info_" + userEntity.F_Id, userLogOnEntity); - await OperatorProvider.Provider.ClearCurrentErrorNum(); - return userEntity; - } - else - { - //登录错误不超过指定次数 - int num = await OperatorProvider.Provider.AddCurrentErrorNum(); - int errorcount = GlobalContext.SystemConfig.LoginErrorCount ?? 4; - string erornum = (errorcount - num).ToString(); - if (num == errorcount) - { - FilterIPEntity ipentity = new FilterIPEntity(); - ipentity.F_Id = Utils.GuId(); - ipentity.F_StartIP = WebHelper.Ip; - ipentity.F_CreatorTime = DateTime.Now; - ipentity.F_DeleteMark = false; - ipentity.F_EnabledMark = true; - ipentity.F_Type = false; - //默认封禁12小时 - ipentity.F_EndTime = DateTime.Now.AddHours(12); - await ipApp.SubmitForm(ipentity, null); - await OperatorProvider.Provider.ClearCurrentErrorNum(); - throw new Exception("密码不正确,IP被锁定"); - } - else - { - throw new Exception("密码不正确,请重新输入,还有" + erornum + "次机会"); - } - } - } - else - { - throw new Exception("账户被系统锁定,请联系管理员"); - } - } - else - { - throw new Exception("账户不存在,请重新输入"); - } - } + /// + /// 登录判断 + /// + /// + /// + /// + public async Task CheckLogin(string username, string password, string localurl) + { + //根据登录公司查找公司 + if (GlobalContext.SystemConfig.SqlMode == Define.SQL_TENANT) + { + repository.ChangeEntityDb(GlobalContext.SystemConfig.MainDbNumber); + var setTemp = (await syssetApp.GetList()).Where(a => localurl.Contains(a.F_HostUrl)).FirstOrDefault(); + if (setTemp != null) + { + if (setTemp.F_EndTime < DateTime.Now.Date) + { + throw new Exception("租户已到期,请联系供应商"); + } + if (!_context.AsTenant().IsAnyConnection(setTemp.F_DbNumber)) + { + var dblist = DBInitialize.GetConnectionConfigs(true); + _context.AsTenant().AddConnection(dblist.FirstOrDefault(a => a.ConfigId.ToString() == setTemp.F_DbNumber)); + repository.ChangeEntityDb(setTemp.F_DbNumber); + repository.Db.DefaultConfig(); + } + else + { + repository.ChangeEntityDb(setTemp.F_DbNumber); + } + } + } + if (!(await CheckIP())) + { + throw new Exception("IP受限"); + } + UserEntity userEntity = await repository.IQueryable().SingleAsync(a => a.F_Account == username); + if (userEntity != null) + { + if (userEntity.F_EnabledMark == true) + { + //缓存用户账户信息 + var userLogOnEntity = await CacheHelper.GetAsync(cacheKeyOperator + "info_" + userEntity.F_Id); + if (userLogOnEntity == null) + { + userLogOnEntity = new OperatorUserInfo(); + UserLogOnEntity entity = await repository.Db.Queryable().InSingleAsync(userEntity.F_Id); + userLogOnEntity.F_UserPassword = entity.F_UserPassword; + userLogOnEntity.F_UserSecretkey = entity.F_UserSecretkey; + userLogOnEntity.F_AllowEndTime = entity.F_AllowEndTime; + userLogOnEntity.F_AllowStartTime = entity.F_AllowStartTime; + userLogOnEntity.F_AnswerQuestion = entity.F_AnswerQuestion; + userLogOnEntity.F_ChangePasswordDate = entity.F_ChangePasswordDate; + userLogOnEntity.F_FirstVisitTime = entity.F_FirstVisitTime; + userLogOnEntity.F_LastVisitTime = entity.F_LastVisitTime; + userLogOnEntity.F_LockEndDate = entity.F_LockEndDate; + userLogOnEntity.F_LockStartDate = entity.F_LockStartDate; + userLogOnEntity.F_LogOnCount = entity.F_LogOnCount; + userLogOnEntity.F_PreviousVisitTime = entity.F_PreviousVisitTime; + userLogOnEntity.F_Question = entity.F_Question; + userLogOnEntity.F_Theme = entity.F_Theme; + await CacheHelper.SetAsync(cacheKeyOperator + "info_" + userEntity.F_Id, userLogOnEntity); + } + if (userLogOnEntity == null) + { + throw new Exception("账户未初始化设置密码,请联系管理员"); + } + string dbPassword = Md5.md5(DESEncrypt.Encrypt(password.ToLower(), userLogOnEntity.F_UserSecretkey).ToLower(), 32).ToLower(); + if (dbPassword == userLogOnEntity.F_UserPassword) + { + if (userEntity.F_IsAdmin != true) + { + var list = userEntity.F_RoleId.Split(','); + var rolelist = repository.Db.Queryable().Where(a => list.Contains(a.F_Id) && a.F_EnabledMark == true).ToList(); + if (!rolelist.Any()) + { + throw new Exception("账户未设置权限,请联系管理员"); + } + } + DateTime lastVisitTime = DateTime.Now; + int LogOnCount = (userLogOnEntity.F_LogOnCount).ToInt() + 1; + if (userLogOnEntity.F_LastVisitTime != null) + { + userLogOnEntity.F_PreviousVisitTime = userLogOnEntity.F_LastVisitTime.ToDate(); + } + userLogOnEntity.F_LastVisitTime = lastVisitTime; + userLogOnEntity.F_LogOnCount = LogOnCount; + userLogOnEntity.F_UserOnLine = true; + await CacheHelper.RemoveAsync(cacheKeyOperator + "info_" + userEntity.F_Id); + await CacheHelper.SetAsync(cacheKeyOperator + "info_" + userEntity.F_Id, userLogOnEntity); + await OperatorProvider.Provider.ClearCurrentErrorNum(); + return userEntity; + } + else + { + //登录错误不超过指定次数 + int num = await OperatorProvider.Provider.AddCurrentErrorNum(); + int errorcount = GlobalContext.SystemConfig.LoginErrorCount ?? 4; + string erornum = (errorcount - num).ToString(); + if (num == errorcount) + { + FilterIPEntity ipentity = new FilterIPEntity(); + ipentity.F_Id = Utils.GuId(); + ipentity.F_StartIP = WebHelper.Ip; + ipentity.F_CreatorTime = DateTime.Now; + ipentity.F_DeleteMark = false; + ipentity.F_EnabledMark = true; + ipentity.F_Type = false; + //默认封禁12小时 + ipentity.F_EndTime = DateTime.Now.AddHours(12); + await ipApp.SubmitForm(ipentity, null); + await OperatorProvider.Provider.ClearCurrentErrorNum(); + throw new Exception("密码不正确,IP被锁定"); + } + else + { + throw new Exception("密码不正确,请重新输入,还有" + erornum + "次机会"); + } + } + } + else + { + throw new Exception("账户被系统锁定,请联系管理员"); + } + } + else + { + throw new Exception("账户不存在,请重新输入"); + } + } - private async Task CheckIP() - { - string ip = WebHelper.Ip; - return await ipApp.CheckIP(ip); - } - } + private async Task CheckIP() + { + string ip = WebHelper.Ip; + return await ipApp.CheckIP(ip); + } + } } \ No newline at end of file diff --git a/HT.Cloud.Web/Areas/FlowManage/Views/Flowinstance/Verification.cshtml b/HT.Cloud.Web/Areas/FlowManage/Views/Flowinstance/Verification.cshtml index bcb27e6..85445a9 100644 --- a/HT.Cloud.Web/Areas/FlowManage/Views/Flowinstance/Verification.cshtml +++ b/HT.Cloud.Web/Areas/FlowManage/Views/Flowinstance/Verification.cshtml @@ -77,7 +77,7 @@ $('#CurrentMakerName').parent().parent().remove(); } NextNodeDesignateType = data.NextNodeDesignateType; - if (!data.NextNodeDesignateType) { + if (!data.NextNodeDesignateType && data.CurrentNodeDesignateType != "MORE_USER_MANAGER") { $('#NextMakerName').parent().parent().remove(); } else if (data.NextNodeDesignateType == "RUNTIME_SPECIAL_ROLE") { diff --git a/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/Index.cshtml b/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/Index.cshtml index 8eb114b..483b70f 100644 --- a/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/Index.cshtml +++ b/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/Index.cshtml @@ -134,7 +134,7 @@ var queryJson = data.field.temp_keyword; //执行搜索重载 options.where = { keyword: queryJson }; - commonTable.reloadtabletree(options); + commonTable.rendertreetable(options); itemId = null; return false; }); diff --git a/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/NodeInfo.cshtml b/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/NodeInfo.cshtml index 4c486aa..8a277c5 100644 --- a/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/NodeInfo.cshtml +++ b/HT.Cloud.Web/Areas/SystemManage/Views/Flowscheme/NodeInfo.cshtml @@ -1,4 +1,4 @@ -@{ +@{ ViewBag.Title = "Form"; Layout = "~/Views/Shared/_Form.cshtml"; } @@ -70,19 +70,33 @@ + + + - +
+
+ +
+
+
+ +
-
+
+
+
+
+
@@ -123,13 +137,18 @@ NodeDesignate: "ALL_USER", NodeConfluenceType: "all", ThirdPartyUrl: "", - CanWriteFormItemIds:[] + CanWriteFormItemIds: [] }; $('#specialrole').addClass("layui-hide"); $('#specialuser').addClass("layui-hide"); $('#alluser').removeClass("layui-hide"); + $('#department').addClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); + $('#stoprole').addClass("layui-hide"); + var userids = ''; var roleids = ''; + var orgids = ''; //初始化节点设置信息 if (node.setInfo != null) { tmp = Object.assign({}, tmp, node.setInfo); @@ -137,31 +156,68 @@ form.val("adminform", { "NodeDesignate": 'SPECIAL_USER' //对应radio的value }); - userids = tmp.NodeDesignateData.users; + userids = tmp.NodeDesignateData.users.join(','); + $('#stoprole').addClass("layui-hide"); + $('#department').addClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); $('#specialrole').addClass("layui-hide"); $('#specialuser').removeClass("layui-hide"); $('#alluser').addClass("layui-hide"); - - } else if (tmp.NodeDesignate === "SPECIAL_ROLE" && tmp.NodeDesignateData.roles.length > 0) { form.val("adminform", { "NodeDesignate": 'SPECIAL_ROLE' //对应radio的value }); - roleids = tmp.NodeDesignateData.roles; + roleids = tmp.NodeDesignateData.roles.join(','); + $('#stoprole').addClass("layui-hide"); + $('#department').removeClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); $('#specialrole').removeClass("layui-hide"); $('#specialuser').addClass("layui-hide"); $('#alluser').addClass("layui-hide"); form.val("adminform", { "currentDepart": tmp.NodeDesignateData.currentDepart }); + } else if (tmp.NodeDesignate === "DEPARTMENT_MANAGER") { + form.val("adminform", { + "NodeDesignate": 'DEPARTMENT_MANAGER' //对应radio的value + }); + if (tmp.NodeDesignateData.orgs.length > 0) { + orgids = tmp.NodeDesignateData.orgs.join(','); + } + $('#stoprole').addClass("layui-hide"); + $('#department').removeClass("layui-hide"); + $('#departmentmanager').removeClass("layui-hide"); + $('#specialrole').addClass("layui-hide"); + $('#specialuser').addClass("layui-hide"); + $('#alluser').addClass("layui-hide"); + form.val("adminform", { + "currentDepart": tmp.NodeDesignateData.currentDepart + }); + } else if (tmp.NodeDesignate === "MORE_USER_MANAGER" && tmp.NodeDesignateData.roles.length > 0) { + form.val("adminform", { + "NodeDesignate": 'MORE_USER_MANAGER' //对应radio的value + }); + roleids = tmp.NodeDesignateData.roles.join(','); + $('#stoprole').removeClass("layui-hide"); + $('#department').addClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); + $('#specialrole').removeClass("layui-hide"); + $('#specialuser').addClass("layui-hide"); + $('#alluser').addClass("layui-hide"); + } else { + $('#stoprole').addClass("layui-hide"); + $('#department').addClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); + $('#specialrole').addClass("layui-hide"); + $('#specialuser').addClass("layui-hide"); + $('#alluser').removeClass("layui-hide"); } } - var xmData=[]; - for (var i = 0; i < valueList.length; i++) - { + var xmData = []; + for (var i = 0; i < valueList.length; i++) { xmData.push({ - value:i, + value: i, name: valueList[i] }); } @@ -241,6 +297,41 @@ } ]] }); + var options = { + id: 'OrganizeId', + elem: '#OrganizeId', + url: '/SystemOrganize/Organize/GetTreeGridJson', + where: { ids: !!orgids ? orgids : "" }, + treeIdName: 'F_Id', // id字段名称 + treePidName: 'F_ParentId', // pid字段名称 + height: 'full-160', + toolbar: false,//工具栏 + cols: [[ + { type: 'checkbox' }, + { field: 'F_FullName', title: '名称', width: 250 }, + { field: 'F_EnCode', title: '编号', width: 200 }, + { + field: 'F_CategoryId', title: '分类', width: 120, + templet: function (d) { + return top.clients.dataItems["OrganizeCategory"][d.F_CategoryId] == null ? "" : top.clients.dataItems["OrganizeCategory"][d.F_CategoryId]; + } + }, + { + field: 'F_ManagerName', title: '负责人', width: 120 + }, + { + field: 'F_EnabledMark', title: '状态', width: 80, + templet: function (d) { + if (d.F_EnabledMark == true) { + return "有效"; + } else { + return "无效"; + } + } + } + ]], + }; + commonTable.rendertreetable(options); common.val('adminform', tmp); if (Method == "Details") { common.setReadOnly('adminform'); @@ -261,15 +352,38 @@ function (data) { tmp.NodeDesignate = data.value; if (data.value === "SPECIAL_USER") { + $('#stoprole').addClass("layui-hide"); + $('#department').addClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); $('#specialrole').addClass("layui-hide"); $('#specialuser').removeClass("layui-hide"); $('#alluser').addClass("layui-hide"); } else if (data.value === "SPECIAL_ROLE") { + $('#stoprole').addClass("layui-hide"); + $('#department').removeClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); + $('#specialrole').removeClass("layui-hide"); + $('#specialuser').addClass("layui-hide"); + $('#alluser').addClass("layui-hide"); + } else if (data.value === "DEPARTMENT_MANAGER") { + $('#stoprole').addClass("layui-hide"); + $('#department').removeClass("layui-hide"); + $('#departmentmanager').removeClass("layui-hide"); + $('#specialrole').addClass("layui-hide"); + $('#specialuser').addClass("layui-hide"); + $('#alluser').addClass("layui-hide"); + } else if (data.value === "MORE_USER_MANAGER") { + $('#stoprole').removeClass("layui-hide"); + $('#department').addClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); $('#specialrole').removeClass("layui-hide"); $('#specialuser').addClass("layui-hide"); $('#alluser').addClass("layui-hide"); } else { + $('#stoprole').addClass("layui-hide"); + $('#department').addClass("layui-hide"); + $('#departmentmanager').addClass("layui-hide"); $('#specialrole').addClass("layui-hide"); $('#specialuser').addClass("layui-hide"); $('#alluser').removeClass("layui-hide"); @@ -281,16 +395,22 @@ getVal = function () { var users = []; var roles = []; + var orgs = []; if (tmp.NodeDesignate === "SPECIAL_USER") { var checkStatus = table.checkStatus("UserId").data; for (var i = 0; i < checkStatus.length; i++) { users.push(checkStatus[i].F_Id); } - } else if (tmp.NodeDesignate === "SPECIAL_ROLE") { + } else if (tmp.NodeDesignate === "SPECIAL_ROLE" || tmp.NodeDesignate === "MORE_USER_MANAGER") { var checkStatus = table.checkStatus("RoleId").data; for (var i = 0; i < checkStatus.length; i++) { roles.push(checkStatus[i].F_Id); } + } else if (tmp.NodeDesignate === "DEPARTMENT_MANAGER") { + var checkStatus = table.checkStatus("OrganizeId").data; + for (var i = 0; i < checkStatus.length; i++) { + orgs.push(checkStatus[i].F_Id); + } } tmp.NodeRejectType = $('#NodeRejectType').val(); tmp.NodeConfluenceType = $('#NodeConfluenceType').val(); @@ -302,7 +422,7 @@ NodeDesignateData: { //节点指定操作人 users: users, roles: roles, - orgs: [], + orgs: orgs, currentDepart: $('#currentDepart').is(':checked') ? true : false, } }; diff --git a/HT.Cloud.Web/Areas/SystemManage/Views/Form/Index.cshtml b/HT.Cloud.Web/Areas/SystemManage/Views/Form/Index.cshtml index 92b69d5..82997ac 100644 --- a/HT.Cloud.Web/Areas/SystemManage/Views/Form/Index.cshtml +++ b/HT.Cloud.Web/Areas/SystemManage/Views/Form/Index.cshtml @@ -155,7 +155,7 @@ var queryJson = data.field.temp_keyword; //执行搜索重载 options.where = { keyword: queryJson }; - commonTable.reloadtabletree(options); + commonTable.rendertreetable(options); itemId = null; return false; }); diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Controllers/UserController.cs b/HT.Cloud.Web/Areas/SystemOrganize/Controllers/UserController.cs index ee3ffe8..c821012 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Controllers/UserController.cs +++ b/HT.Cloud.Web/Areas/SystemOrganize/Controllers/UserController.cs @@ -70,32 +70,6 @@ namespace HT.Cloud.Web.Areas.SystemOrganize.Controllers public async Task GetFormJson(string keyValue) { var data = await _service.GetLookForm(keyValue); - if (!string.IsNullOrEmpty(data.F_OrganizeId)) - { - List str = new List(); - foreach (var item in data.F_OrganizeId.Split(',')) - { - var temp = await _orgService.GetForm(item); - if (temp != null) - { - str.Add(temp.F_FullName); - } - } - data.F_OrganizeName = string.Join(" ", str.ToArray()); - } - if (!string.IsNullOrEmpty(data.F_RoleId)) - { - List str = new List(); - foreach (var item in data.F_RoleId.Split(',')) - { - var temp = await _roleService.GetForm(item); - if (temp != null) - { - str.Add(temp.F_FullName); - } - } - data.F_RoleName = string.Join(" ", str.ToArray()); - } return Content(data.ToJson()); } @@ -104,32 +78,6 @@ namespace HT.Cloud.Web.Areas.SystemOrganize.Controllers public async Task GetUserFormJson() { var data = await _service.GetFormExtend(_service.currentuser.UserId); - if (!string.IsNullOrEmpty(data.F_OrganizeId)) - { - List str = new List(); - foreach (var item in data.F_OrganizeId.Split(',')) - { - var temp = await _orgService.GetForm(item); - if (temp != null) - { - str.Add(temp.F_FullName); - } - } - data.F_OrganizeName = string.Join(" ", str.ToArray()); - } - if (!string.IsNullOrEmpty(data.F_RoleId)) - { - List str = new List(); - foreach (var item in data.F_RoleId.Split(',')) - { - var temp = await _roleService.GetForm(item); - if (temp != null) - { - str.Add(temp.F_FullName); - } - } - data.F_RoleName = string.Join(" ", str.ToArray()); - } return Content(data.ToJson("yyyy-MM-dd")); } diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/AddForm.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/AddForm.cshtml index 5a8ca65..5196c88 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/AddForm.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/AddForm.cshtml @@ -31,6 +31,9 @@ return top.clients.dataItems["OrganizeCategory"][d.F_CategoryId] == null ? "" : top.clients.dataItems["OrganizeCategory"][d.F_CategoryId]; } }, + { + field: 'F_ManagerName', title: '负责人', width: 120 + }, { field: 'F_EnabledMark', title: '状态', width: 80, templet: function (d) { diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Details.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Details.cshtml index 2e5d0c9..f03a6f8 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Details.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Details.cshtml @@ -38,6 +38,25 @@ }); } }); + function search(fileds) { + layui.use(['jquery', 'form', 'common'], function () { + var form = layui.form, + $ = layui.$, + common = layui.common; + //不同弹窗 + if (fileds == '用户') { + common.modalOpen({ + title: "选择用户", + url: "/SystemOrganize/User/AddForm?name=" + "F_ManagerName" + "&value=" + "F_ManagerId" + "&ids=" + $('#F_ManagerId').val(), + width: "650px", + height: "600px", + }); + } + else { + return false; + } + }); + }
@@ -71,6 +90,13 @@
+
+ +
+ + +
+
diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Form.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Form.cshtml index f230d58..98cd6c9 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Form.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Form.cshtml @@ -76,6 +76,25 @@ return false; }); }); + function search(fileds) { + layui.use(['jquery', 'form', 'common'], function () { + var form = layui.form, + $ = layui.$, + common = layui.common; + //不同弹窗 + if (fileds == '用户') { + common.modalOpen({ + title: "选择用户", + url: "/SystemOrganize/User/AddForm?name=" + "F_ManagerName" + "&value=" + "F_ManagerId" + "&ids=" + $('#F_ManagerId').val(), + width: "650px", + height: "600px", + }); + } + else { + return false; + } + }); + }
@@ -109,6 +128,13 @@
+
+ +
+ + +
+
diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Index.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Index.cshtml index bf12a90..61b651a 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Index.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/Organize/Index.cshtml @@ -29,6 +29,9 @@ return top.clients.dataItems["OrganizeCategory"][d.F_CategoryId] == null ? "" : top.clients.dataItems["OrganizeCategory"][d.F_CategoryId]; } }, + { + field: 'F_ManagerName', title: '负责人', width: 120, sort: true, filter: true + }, { field: 'F_EnabledMark', title: '状态', width: 80, filter: true, templet: function (d) { diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/AddForm.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/AddForm.cshtml index 4e311be..98b1ef8 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/AddForm.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/AddForm.cshtml @@ -38,7 +38,10 @@ field: 'F_CompanyName', title: '公司名称', width: 150, sort: true }, { - field: 'F_OrganizeName', title: '部门名称', width: 200, sort: true + field: 'F_OrganizeName', title: '部门名称', width: 200, sort: true + }, + { + field: 'F_ManagerName', title: '直属上级', width: 200, sort: true }, { field: 'F_EnabledMark', title: '状态', width: 80, sort: true, diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Details.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Details.cshtml index 9854b52..4cbff66 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Details.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Details.cshtml @@ -155,12 +155,10 @@
- +
- + +
diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Form.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Form.cshtml index 5d29ba5..680a393 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Form.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Form.cshtml @@ -8,6 +8,15 @@ $ = layui.$, common = layui.common, laydate = layui.laydate; + // 自定义验证规则 + form.verify({ + pass: function (value, elem) { + var EXP = /^[\S]{6,12}$/; + if (value && !EXP.test(value)) { + return '密码必须6到12位,且不能出现空格'; + } + } + }); var keyValue = $.request("keyValue"); //权限字段 common.authorizeFields('adminform'); @@ -94,7 +103,15 @@ else if (fileds == '部门') { common.modalOpen({ title: "选择组织", - url: "/SystemOrganize/Organize/AddForm?name=" + "F_OrganizeName" + "&value=" + "F_OrganizeId" + "&ids=" + $('#F_OrganizeId').val(), + url: "/SystemOrganize/Organize/AddForm?name=" + "F_OrganizeName" + "&value=" + "F_OrganizeId" + "&ids=" + $('#F_OrganizeId').val() + "&managerkey=" + $('#F_ManagerId').val() + "&managername=" + $('#F_ManagerName').val(), + width: "650px", + height: "600px", + }); + } + else if (fileds == '用户') { + common.modalOpen({ + title: "选择用户", + url: "/SystemOrganize/User/AddForm?name=" + "F_ManagerName" + "&value=" + "F_ManagerId" + "&ids=" + $('#F_ManagerId').val(), width: "650px", height: "600px", }); @@ -188,18 +205,19 @@
-
- -
- -
-
+
+ +
+ +
+
+
@@ -212,12 +230,10 @@
- +
- + +
diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Index.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Index.cshtml index ffc69bd..b08f824 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Index.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/Index.cshtml @@ -38,9 +38,25 @@ { field: 'F_OrganizeName', title: '部门名称', width: 200, sort: true }, + { + field: 'F_IsLeaderInDepts', title: '部门主管', width: 120, + templet: function (d) { + if (d.F_IsLeaderInDepts == true) { + return ""; + } else { + return ""; + } + } + }, + { + field: 'F_ManagerName', title: '直属上级', width: 120, sort: true, filter: true + }, { field: 'F_DutyName', title: '岗位名称', width: 120, sort: true, filter: true }, + { + field: 'F_RoleName', title: '角色', width: 120, sort: true + }, { field: 'F_EnabledMark', title: '状态', width: 80, sort: true, filter: true, templet: function (d) { diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/RevisePassword.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/RevisePassword.cshtml index 5638430..3866f97 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/RevisePassword.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/RevisePassword.cshtml @@ -8,6 +8,15 @@ $ = layui.$, common = layui.common, laydate = layui.laydate; + // 自定义验证规则 + form.verify({ + pass: function (value, elem) { + var EXP = /^[\S]{6,12}$/; + if (value && !EXP.test(value)) { + return '密码必须6到12位,且不能出现空格'; + } + } + }); var keyValue = $.request("keyValue"); //权限字段 common.authorizeFields('useradmin'); diff --git a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/ReviseSelfPassword.cshtml b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/ReviseSelfPassword.cshtml index 2049edb..b56384f 100644 --- a/HT.Cloud.Web/Areas/SystemOrganize/Views/User/ReviseSelfPassword.cshtml +++ b/HT.Cloud.Web/Areas/SystemOrganize/Views/User/ReviseSelfPassword.cshtml @@ -13,6 +13,12 @@ if (value != layui.$('input[name="F_UserPassword"]').val()) { return '密码不相同请重新输入!' } + }, + pass: function (value, elem) { + var EXP = /^[\S]{6,12}$/; + if (value && !EXP.test(value)) { + return '密码必须6到12位,且不能出现空格'; + } } }); wcLoading.close(); diff --git a/HT.Cloud.Web/Controllers/Api/UserController.cs b/HT.Cloud.Web/Controllers/Api/UserController.cs index 161b685..abd25e3 100644 --- a/HT.Cloud.Web/Controllers/Api/UserController.cs +++ b/HT.Cloud.Web/Controllers/Api/UserController.cs @@ -76,7 +76,6 @@ namespace HT.Cloud.Web operatorModel.WxOpenId = userEntity.F_WxOpenId; operatorModel.IsAdmin = userEntity.F_IsAdmin.Value; operatorModel.IsBoss = userEntity.F_IsBoss.Value; - operatorModel.IsLeaderInDepts = userEntity.F_IsLeaderInDepts.Value; operatorModel.IsSenior = userEntity.F_IsSenior.Value; SystemSetEntity setEntity = await _setService.GetForm(userEntity.F_CompanyId); operatorModel.DbNumber = setEntity.F_DbNumber; diff --git a/HT.Cloud.Web/Controllers/ClientsDataController.cs b/HT.Cloud.Web/Controllers/ClientsDataController.cs index 8ad3ced..9139e7e 100644 --- a/HT.Cloud.Web/Controllers/ClientsDataController.cs +++ b/HT.Cloud.Web/Controllers/ClientsDataController.cs @@ -100,8 +100,8 @@ namespace HT.Cloud.Web.Controllers } Dictionary dictionary = new Dictionary(); var list = await _roleAuthorizeService.GetMenuList(roleId); - foreach (ModuleEntity item in list.Where(a => a.F_UrlAddress != null)) - { + foreach (ModuleEntity item in list.Where(a => !string.IsNullOrEmpty(a.F_UrlAddress))) + { dictionary.Add(item.F_UrlAddress, item.F_IsFields ?? false); } return dictionary; diff --git a/HT.Cloud.Web/Controllers/LoginController.cs b/HT.Cloud.Web/Controllers/LoginController.cs index c687b84..b2b5636 100644 --- a/HT.Cloud.Web/Controllers/LoginController.cs +++ b/HT.Cloud.Web/Controllers/LoginController.cs @@ -180,7 +180,6 @@ namespace HT.Cloud.Web.Controllers operatorModel.IsSuperAdmin = userEntity.F_IsAdmin.Value; operatorModel.IsAdmin = userEntity.F_IsAdmin.Value; operatorModel.IsBoss = userEntity.F_IsBoss.Value; - operatorModel.IsLeaderInDepts = userEntity.F_IsLeaderInDepts.Value; operatorModel.IsSenior = userEntity.F_IsSenior.Value; SystemSetEntity setEntity = await _setService.GetForm(userEntity.F_CompanyId); operatorModel.DbNumber = setEntity.F_DbNumber; diff --git a/HT.Cloud.Web/DataProtection/key-326966fb-bc2e-4016-b6a2-42e74a9dd6b7.xml b/HT.Cloud.Web/DataProtection/key-326966fb-bc2e-4016-b6a2-42e74a9dd6b7.xml new file mode 100644 index 0000000..c3bc3e7 --- /dev/null +++ b/HT.Cloud.Web/DataProtection/key-326966fb-bc2e-4016-b6a2-42e74a9dd6b7.xml @@ -0,0 +1,16 @@ + + + 2024-11-13T14:50:26.4663737Z + 2024-11-13T14:50:26.1242399Z + 2025-02-11T14:50:26.1242399Z + + + + + + + yuYXmAsF00RGxnDRBcg7CCR9yV3XBcIxxcBGdZ9lUlX+nWua1gg+Jet+gpfAlBriBDzR0BcXXc6p68vGbGag9Q== + + + + \ No newline at end of file diff --git a/HT.Cloud.Web/HT.Cloud.Web.csproj b/HT.Cloud.Web/HT.Cloud.Web.csproj index a0e0636..3f7900a 100644 --- a/HT.Cloud.Web/HT.Cloud.Web.csproj +++ b/HT.Cloud.Web/HT.Cloud.Web.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 c1fb91bb-fd9e-4a3a-8c93-b84e89a0941a Linux 3.0.0-preview @@ -27,6 +27,7 @@ + @@ -50,20 +51,20 @@
- - + + - - - - - + + + + + - - - - - + + + + + @@ -85,7 +86,7 @@
- + @@ -100,7 +101,13 @@ - + + + + + + +
diff --git a/HT.Cloud.Web/Properties/PublishProfiles/FolderProfile.pubxml b/HT.Cloud.Web/Properties/PublishProfiles/FolderProfile.pubxml index 9a4b0e7..cc7dfd2 100644 --- a/HT.Cloud.Web/Properties/PublishProfiles/FolderProfile.pubxml +++ b/HT.Cloud.Web/Properties/PublishProfiles/FolderProfile.pubxml @@ -14,11 +14,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem <_TargetId>Folder - net6.0 + net8.0 fe158a99-8b94-4f95-9daa-ac14b7738bb7 - false + true win-x64 false true + false \ No newline at end of file diff --git a/HT.Cloud.Web/Properties/PublishProfiles/WaterCloud.pubxml b/HT.Cloud.Web/Properties/PublishProfiles/WaterCloud.pubxml index fc5c333..60c2553 100644 --- a/HT.Cloud.Web/Properties/PublishProfiles/WaterCloud.pubxml +++ b/HT.Cloud.Web/Properties/PublishProfiles/WaterCloud.pubxml @@ -12,7 +12,7 @@ true false - net6.0 + net8.0 fe158a99-8b94-4f95-9daa-ac14b7738bb7 false E:\CloudPublish diff --git a/HT.Cloud.Web/Properties/launchSettings.json b/HT.Cloud.Web/Properties/launchSettings.json index b2730ce..a68adbe 100644 --- a/HT.Cloud.Web/Properties/launchSettings.json +++ b/HT.Cloud.Web/Properties/launchSettings.json @@ -16,7 +16,7 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5000", - "nativeDebugging": true + "nativeDebugging": false }, "Docker": { "commandName": "Docker", diff --git a/HT.Cloud.Web/Startup.cs b/HT.Cloud.Web/Startup.cs index 5c8af28..e7bf6a1 100644 --- a/HT.Cloud.Web/Startup.cs +++ b/HT.Cloud.Web/Startup.cs @@ -22,7 +22,7 @@ namespace HT.Cloud.Web { public class Startup : DefaultStartUp { - private List _plugins = new List { "WaterCloud.Service" }; + private List _plugins = new List { "HT.Cloud.Service" }; public Startup(IConfiguration configuration, IWebHostEnvironment env) : base(configuration, env) { } @@ -73,7 +73,7 @@ namespace HT.Cloud.Web var plugDir = Directory.GetCurrentDirectory() + "/Plugins"; if (!Directory.Exists(plugDir)) Directory.CreateDirectory(plugDir); - base.ConfigureServices(services); + //base.ConfigureServices(services); var paths = Directory.GetDirectories(plugDir); var hostAssembly = Assembly.GetExecutingAssembly(); foreach (var path in paths) diff --git a/HT.Cloud.Web/Views/Home/UserSetting.cshtml b/HT.Cloud.Web/Views/Home/UserSetting.cshtml index 5b641ac..3af645e 100644 --- a/HT.Cloud.Web/Views/Home/UserSetting.cshtml +++ b/HT.Cloud.Web/Views/Home/UserSetting.cshtml @@ -45,9 +45,9 @@
- +
- +
diff --git a/HT.Cloud.Web/appsettings.Development.json b/HT.Cloud.Web/appsettings.Development.json new file mode 100644 index 0000000..127b33a --- /dev/null +++ b/HT.Cloud.Web/appsettings.Development.json @@ -0,0 +1,67 @@ +{ + "urls": "http://*:8058", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "SystemConfig": { + "SystemDescription": "喷煤系统", //系统备注 + "Demo": false, // 是否是演示模式 账号admin 密码0000 + "LoginMultiple": false, // 是否允许一个账户在多处登录 + "AllowCorsSite": "http://localhost:8058", // 允许的其他站点访问Api + "DBProvider": "SqlServer", //SqlServer //Oracle + "DBConnectionString": "Zk48ARnbLq1Lk+lzxvCij+l0UiJ189taFaddb/34UyhBPBAHSDyHdS5dutbRWXGxlB3irVANGspZH0aUGsZNhgOpKckKaqqcVBG/KSADYUGggflobsqEueRv3iuj+qZBa4+vrwj/6cVpUB7juwkiRHCBXFHGcQRd/wAtU6j4XM7gJWyvkLT5x564tsAezSn4MyX/smNuq93X1aONLHhZhA==", + "DBCommandTimeout": 180, // 数据库超时时间,单位秒 + "CacheProvider": "Memory", // 缓存使用方式 Redis/Memory + "RedisConnectionString": "127.0.0.1:6379", //docker部署 172.17.0.1 + "TokenName": "WC-Token", //api Token名称 + "LoginExpire": 12, //登录缓存过期时间(小时) + "HomePage": "../Home/Default", //登录主页地址 + "MainDbNumber": "0", //主程序数据库 + "DataDBNumber": "1", //数据仓库数据库 + "LocalLAN": false, //是否局域网 + "OpenQuartz": true, //定时任务开启 + "SqlMode": "MoreSql", //数据库模式多租户或者多库 "MoreSql" + "ProjectPrefix": "watercloud", //项目中的前缀 + "ReviseSystem": false, //是否重置密码 + "LoginErrorCount": 18, //登录错误次数 + "IsCluster": false, //集群参数 开启时需要去quartz下载响应数据库 + "NeedClear": false, //是否删除定时调度任务 + "SqlConfig": [ + { + "DBNumber": "1", + "DBProvider": "SqlServer", //MySql //Oracle + "DBConnectionString": "Zk48ARnbLq1Lk+lzxvCij+l0UiJ189taFaddb/34UyhBPBAHSDyHdS5dutbRWXGxlB3irVANGspZH0aUGsZNhgOpKckKaqqcVBG/KSADYUGggflobsqEueRv3iuj+qZBa4+vrwj/6cVpUB7juwkiRHCBXFHGcQRd/wAtU6j4XM7gJWyvkLT5x564tsAezSn4MyX/smNuq93X1aONLHhZhA==" + } + ], + "RabbitMq": { + "Enabled": false, + "HostName": "localhost", + "UserName": "root", //默认guest + "Password": "root", //默认guest + "Port": 5672, + "VirtualHost": "/" + }, + "DocumentSettings": { + "DocumentTitle": "WaterCloud API", + "GroupOpenApiInfos": [ + { + "Group": "Default", + "Title": "WaterCloud API", + "Description": "WaterCloud .NET敏捷开发框架
项目地址:https://gitee.com/qian_wei_hong/WaterCloud", + "Version": "1.0.0" + }, + { + "Group": "V2", + "Title": "V2", + "Description": "WaterCloud .NET敏捷开发框架
项目地址:https://gitee.com/qian_wei_hong/WaterCloud", + "Version": "1.0.0" + } + ] + } + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/HT.Cloud.Web/appsettings.Production.json b/HT.Cloud.Web/appsettings.Production.json new file mode 100644 index 0000000..127b33a --- /dev/null +++ b/HT.Cloud.Web/appsettings.Production.json @@ -0,0 +1,67 @@ +{ + "urls": "http://*:8058", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "SystemConfig": { + "SystemDescription": "喷煤系统", //系统备注 + "Demo": false, // 是否是演示模式 账号admin 密码0000 + "LoginMultiple": false, // 是否允许一个账户在多处登录 + "AllowCorsSite": "http://localhost:8058", // 允许的其他站点访问Api + "DBProvider": "SqlServer", //SqlServer //Oracle + "DBConnectionString": "Zk48ARnbLq1Lk+lzxvCij+l0UiJ189taFaddb/34UyhBPBAHSDyHdS5dutbRWXGxlB3irVANGspZH0aUGsZNhgOpKckKaqqcVBG/KSADYUGggflobsqEueRv3iuj+qZBa4+vrwj/6cVpUB7juwkiRHCBXFHGcQRd/wAtU6j4XM7gJWyvkLT5x564tsAezSn4MyX/smNuq93X1aONLHhZhA==", + "DBCommandTimeout": 180, // 数据库超时时间,单位秒 + "CacheProvider": "Memory", // 缓存使用方式 Redis/Memory + "RedisConnectionString": "127.0.0.1:6379", //docker部署 172.17.0.1 + "TokenName": "WC-Token", //api Token名称 + "LoginExpire": 12, //登录缓存过期时间(小时) + "HomePage": "../Home/Default", //登录主页地址 + "MainDbNumber": "0", //主程序数据库 + "DataDBNumber": "1", //数据仓库数据库 + "LocalLAN": false, //是否局域网 + "OpenQuartz": true, //定时任务开启 + "SqlMode": "MoreSql", //数据库模式多租户或者多库 "MoreSql" + "ProjectPrefix": "watercloud", //项目中的前缀 + "ReviseSystem": false, //是否重置密码 + "LoginErrorCount": 18, //登录错误次数 + "IsCluster": false, //集群参数 开启时需要去quartz下载响应数据库 + "NeedClear": false, //是否删除定时调度任务 + "SqlConfig": [ + { + "DBNumber": "1", + "DBProvider": "SqlServer", //MySql //Oracle + "DBConnectionString": "Zk48ARnbLq1Lk+lzxvCij+l0UiJ189taFaddb/34UyhBPBAHSDyHdS5dutbRWXGxlB3irVANGspZH0aUGsZNhgOpKckKaqqcVBG/KSADYUGggflobsqEueRv3iuj+qZBa4+vrwj/6cVpUB7juwkiRHCBXFHGcQRd/wAtU6j4XM7gJWyvkLT5x564tsAezSn4MyX/smNuq93X1aONLHhZhA==" + } + ], + "RabbitMq": { + "Enabled": false, + "HostName": "localhost", + "UserName": "root", //默认guest + "Password": "root", //默认guest + "Port": 5672, + "VirtualHost": "/" + }, + "DocumentSettings": { + "DocumentTitle": "WaterCloud API", + "GroupOpenApiInfos": [ + { + "Group": "Default", + "Title": "WaterCloud API", + "Description": "WaterCloud .NET敏捷开发框架
项目地址:https://gitee.com/qian_wei_hong/WaterCloud", + "Version": "1.0.0" + }, + { + "Group": "V2", + "Title": "V2", + "Description": "WaterCloud .NET敏捷开发框架
项目地址:https://gitee.com/qian_wei_hong/WaterCloud", + "Version": "1.0.0" + } + ] + } + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/HT.Cloud.Web/wwwroot/file/PrintApp.zip b/HT.Cloud.Web/wwwroot/file/PrintApp.zip index d850c43..f77322c 100644 Binary files a/HT.Cloud.Web/wwwroot/file/PrintApp.zip and b/HT.Cloud.Web/wwwroot/file/PrintApp.zip differ diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/cardTable/cardTable.js b/HT.Cloud.Web/wwwroot/js/lay-module/cardTable/cardTable.js index 7ba31ee..0df6bbb 100644 --- a/HT.Cloud.Web/wwwroot/js/lay-module/cardTable/cardTable.js +++ b/HT.Cloud.Web/wwwroot/js/lay-module/cardTable/cardTable.js @@ -191,7 +191,7 @@ layui.define(['table', 'laypage', 'jquery', 'element', 'laytpl'], function (expo var reElem = obj; $(reElem).addClass('layui-table-click').siblings().removeClass('layui-table-click'); item.id = reElem.id; - if (!obj.id || obj.nodeName != "DIV") { + if (!obj.id || obj.nodeName == "DIV") { item.id = item.id.replace('card_', ''); } var option = _instances[elem].option; diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.js b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.js index fb6e17f..c71d255 100644 --- a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.js +++ b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.js @@ -4,1568 +4,1568 @@ * @author: yelog * @link: https://github.com/yelog/layui-soul-table * @license: MIT - * @version: v1.6.1 + * @version: v1.9.0 */ layui.define(['table', 'tableFilter', 'tableChild', 'tableMerge'], function (exports) { - var tableFilter = layui.tableFilter, - tableChild = layui.tableChild, - tableMerge = layui.tableMerge, - $ = layui.$, - table = layui.table, - HIDE = 'layui-hide', - tables = {}, - originCols = {}, - defaultConfig = { // 默认配置开关 - fixTotal: false, // 修复合计行固定列问题 - drag: true, // 列拖动 - rowDrag: false, // 行拖动 - autoColumnWidth: true, // 自动列宽 - contextmenu: false, // 右键菜单 - fixResize: true, // 修改有固定列的拖动列宽的位置为左边线 - overflow: false, // 自定义内容超出样式 - fixFixedScroll: true, // 固定列支持鼠标滚轮滚动 - filter: false // 筛选及记忆相关 - }, - _BODY = $('body'), - _DOC = $(document); + var tableFilter = layui.tableFilter, + tableChild = layui.tableChild, + tableMerge = layui.tableMerge, + $ = layui.$, + table = layui.table, + HIDE = 'layui-hide', + tables = {}, + originCols = {}, + defaultConfig = { // 默认配置开关 + fixTotal: false, // 修复合计行固定列问题 + drag: true, // 列拖动 + rowDrag: false, // 行拖动 + autoColumnWidth: true, // 自动列宽 + contextmenu: false, // 右键菜单 + fixResize: true, // 修改有固定列的拖动列宽的位置为左边线 + overflow: false, // 自定义内容超出样式 + fixFixedScroll: true, // 固定列支持鼠标滚轮滚动 + filter: false // 筛选及记忆相关 + }, + _BODY = $('body'), + _DOC = $(document); - // 封装方法 - var mod = { - render: function (myTable) { - // 记录表格配置,方便直接通过 tableId 调用方法 - tables[myTable.id] = myTable - var curConfig = $.extend({}, defaultConfig, myTable); - if (curConfig.filter && curConfig.filter.cache) { - var storeKey = location.pathname + location.hash + myTable.id; - var colsStr = this.deepStringify(myTable.cols); - // 记录表格列的原始配置 - if (!originCols[myTable.id]) { // 只在第一次 render 时生效 - originCols[myTable.id] = this.deepClone(myTable.cols) + // 封装方法 + var mod = { + render: function (myTable) { + // 记录表格配置,方便直接通过 tableId 调用方法 + tables[myTable.id] = myTable + var curConfig = $.extend({}, defaultConfig, myTable); + if (curConfig.filter && curConfig.filter.cache) { + var storeKey = location.pathname + location.hash + myTable.id; + var colsStr = this.deepStringify(myTable.cols); + // 记录表格列的原始配置 + if (!originCols[myTable.id]) { // 只在第一次 render 时生效 + originCols[myTable.id] = this.deepClone(myTable.cols) - var curTableSession = localStorage.getItem(storeKey); - if (curTableSession && colsStr === localStorage.getItem('origin' + storeKey)) { - this.updateCols(myTable, this.deepParse(curTableSession)); - } else { - localStorage.setItem('origin' + storeKey, colsStr) - localStorage.removeItem(storeKey) - } - } - } else { - // 如果没有开启记忆,则清除 - this.clearCache(myTable); - } - - tableFilter.render(myTable); - tableChild.render(myTable); - tableMerge.render(myTable); - - // 初始化暂停配置 - this.suspendConfig[myTable.id] = { - drag: false, - rowDrag: false - } - // 修复合计栏固定列问题 - if (curConfig.fixTotal) { - this.fixTotal(myTable) - } - if (curConfig.drag) { - this.drag(myTable, curConfig.drag); - } - if (curConfig.rowDrag) { - this.rowDrag(myTable, curConfig.rowDrag) - } - if (curConfig.autoColumnWidth) { - this.autoColumnWidth(myTable, curConfig.autoColumnWidth) - } - - this.contextmenu(myTable, curConfig.contextmenu); - - if (curConfig.fixResize) { - this.fixResizeRightFixed(myTable); - } - - if (curConfig.overflow) { - this.overflow(myTable, curConfig.overflow); - } - - if (curConfig.fixFixedScroll) { - this.fixFixedScroll(myTable); - } - } - , config: function (configObj) { - if (typeof configObj === 'object') { - $.extend(true, defaultConfig, configObj); - } - } - , updateCols: function (myTable, cols) { - var i, j, lastKeyMap = {}, columnKey, newCols = [], col = [], - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $fixedHead = $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table'), - $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $fixedHead), - $noFixedHead = $tableBox.children('.layui-table-header').children('table'), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $noFixedBody = $tableBox.children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody); - - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - myTable.cols[i][j]['oldPos'] = i + '-' + j - lastKeyMap[myTable.cols[i][j].key] = myTable.cols[i][j] - } - } - - for (i = 0; i < cols.length; i++) { - col = [] - for (j = 0; j < cols[i].length; j++) { - columnKey = myTable.index + '-' + cols[i][j].key; - // 同步列宽 - if (cols[i][j].width && lastKeyMap[cols[i][j].key] !== cols[i][j].width) { - this.getCssRule(myTable, columnKey, function (item) { - item.style.width = (cols[i][j].width ? cols[i][j].width : 0) + 'px' - }) - } - // 同步隐藏 - if (lastKeyMap[cols[i][j].key].hide !== cols[i][j].hide) { - $tableHead.find('th[data-key="' + columnKey + '"]')[cols[i][j].hide ? 'addClass' : 'removeClass']('layui-hide') - $tableBody.find('td[data-key="' + columnKey + '"]')[cols[i][j].hide ? 'addClass' : 'removeClass']('layui-hide') - } - - // 同步顺序 - if (lastKeyMap[cols[i][j].key].oldPos !== (i + '-' + j) || lastKeyMap[cols[i][j].key].fixed !== cols[i][j].fixed) { - if (cols[i][j].fixed !== lastKeyMap[cols[i][j].key].fixed) { - myTable.cols = cols; - table.reload(myTable.id) - return; - } - } - lastKeyMap[cols[i][j].key].fixed = cols[i][j].fixed; - lastKeyMap[cols[i][j].key].width = cols[i][j].width; - lastKeyMap[cols[i][j].key].hide = cols[i][j].hide; - col.push(lastKeyMap[cols[i][j].key]) - } - newCols.push(col) - } - $noFixedHead.children().children('tr').each(function () { - innerHandler(this, 'th') - }) - $noFixedBody.children().children('tr').each(function () { - innerHandler(this, 'td') - }) - - function innerHandler(_this, domName) { - for (i = 0; i < cols.length; i++) { - for (j = 0; j < cols[i].length; j++) { - columnKey = myTable.index + '-' + cols[i][j].key; - var curKey = $(_this).children(domName + ':eq(' + j + ')').attr('data-key'); - if (curKey !== columnKey) { - $(_this).children(domName + ':eq(' + j + ')').before($(_this).children(domName + '[data-key="' + columnKey + '"]')) - if (cols[i][j].fixed) { - var $curRow = (domName === 'th' ? $fixedHead : $fixedBody).children().children(domName === 'th' ? 'tr' : 'tr[data-index="' + $(_this).attr('data-index') + '"]') - $curRow.children(domName + '[data-key="' + curKey + '"]').before($curRow.children(domName + '[data-key="' + columnKey + '"]')) - } - } - } - } - } - - myTable.cols = newCols; - - table.resize(myTable.id) - } - /** - * excel表格导出 - * @param myTable - * @param curExcel - */ - , export: function (myTable, curExcel) { - tableFilter.export(myTable.config || myTable, curExcel); - } - , getCssRule: function (that, key, callback) { - var style = that.elem.next().find('style')[0] - , sheet = style.sheet || style.styleSheet || {} - , rules = sheet.cssRules || sheet.rules; - layui.each(rules, function (i, item) { - if (item.selectorText === ('.laytable-cell-' + key)) { - return callback(item), true; - } - }); - } - , autoColumnWidth: function (myTable, autoColumnWidthConfig) { - var _this = this; - if (typeof myTable === 'object') { - innerColumnWidth(_this, myTable) - } else if (typeof myTable === 'string') { - innerColumnWidth(_this, tables[myTable]) - } else if (typeof myTable === 'undefined') { - layui.each(tables, function () { - innerColumnWidth(_this, this) - }); - } - - function innerColumnWidth(_this, myTable) { - var $table = $(myTable.elem), - th = $table.next().children('.layui-table-box').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), - fixTh = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), - $tableBodytr = $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr'), - $totalTr = $table.next().children('.layui-table-total').find('tr'); - String.prototype.width = function (font) { - var f = font || _BODY.css('font'), - o = $('
' + this + '
') - .css({ - 'position': 'absolute', - 'float': 'left', - 'white-space': 'nowrap', - 'visibility': 'hidden', - 'font': f - }) - .appendTo(_BODY), - w = o.width(); - - o.remove(); - return w; - } - if (typeof autoColumnWidthConfig === 'undefined' || typeof autoColumnWidthConfig.dblclick === 'undefined' || autoColumnWidthConfig.dblclick) { - th.add(fixTh).on('dblclick', function (e) { - var othis = $(this), - pLeft = e.clientX - othis.offset().left; - handleColumnWidth(myTable, othis, othis.parents('.layui-table-fixed-r').length > 0 ? pLeft <= 10 : othis.width() - pLeft <= 10); - }) - } - // 初始化表格后,自动调整所有列宽 - if (autoColumnWidthConfig && autoColumnWidthConfig.init) { - th.add(fixTh).each(function (e) { - var colKey = $(this).attr('data-key').split('-') - if (myTable.cols[colKey[1]][colKey[2]].autoWidth !== false && (!Array.isArray(autoColumnWidthConfig.init) || autoColumnWidthConfig.init.indexOf($(this).attr('data-field')) !== -1)) { - handleColumnWidth(myTable, $(this), true); - } - }) - } - - function handleColumnWidth(myTable, othis, isHandle) { - var key = othis.data('key') - , keyArray = key.split('-') - , curKey = keyArray.length === 3 ? keyArray[1] + '-' + keyArray[2] : '' - if (othis.attr('colspan') > 1 || othis.data('unresize')) { - return; - } - if (isHandle) { - var maxWidth = othis.text().width(othis.css('font')) + 21, font = othis.css('font'); - $tableBodytr.children('td[data-key="' + key + '"]').each(function (index, elem) { - var curWidth = 0 - if ($(this).children().children() && $(this).children().children().length > 0) { - curWidth += $(this).children().html().width(font) - } else { - curWidth = $(this).text().width(font); - } - - // var curWidth = $(this).text().width(font); - if (maxWidth < curWidth) { - maxWidth = curWidth - } - }) - if ($totalTr.length > 0) { - var curWidth = $totalTr.children('td[data-key="' + key + '"]').text().width(font) - if (maxWidth < curWidth) { - maxWidth = curWidth - } - - } - - maxWidth += 32; - - _this.getCssRule(myTable, key, function (item) { - item.style.width = maxWidth + 'px' - }); - for (var i = 0; i < myTable.cols.length; i++) { - for (var j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].key === curKey) { - myTable.cols[i][j].width = maxWidth; - break; - } - } - } - } - } - } - } - /** - * 左右拖拽调整列顺序、向上拖隐藏列 - * @param myTable - */ - , drag: function (myTable, dragConfig) { - if (myTable.cols.length > 1) { - // 如果是复杂表头,则自动禁用拖动效果 - return; - } - var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $noFixedBody = $tableBox.children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - $totalTable = $table.next().children('.layui-table-total').children('table'), - $fixedTotalTable = $table.next().children('.layui-table-total').children('table.layui-table-total-fixed'), - $noFixedTotalTable = $table.next().children('.layui-table-total').children('table:eq(0)'), - tableId = myTable.id, - isSimple = dragConfig === 'simple' || (dragConfig && dragConfig.type === 'simple'), // 是否为简易拖拽 - toolbar = dragConfig && dragConfig.toolbar, // 是否开启工具栏 - isDragging = false, isStart = false; - - if (!$tableHead.attr('drag')) { - $tableHead.attr('drag', true); - if (toolbar) { - $tableBox.append('
左固定
不固定
右固定
') - var $dragBar = $tableBox.children('.soul-drag-bar'); - $dragBar.children('div').on('mouseenter', function () { - $(this).addClass('active') - }).on('mouseleave', function () { - $(this).removeClass('active') - }) - } - - $tableHead.find('th').each(function () { - var $this = $(this), - field = $this.data('field'), - key = $this.data('key'); - if (!key) { - return; - } - - var keyArray = key.split('-'), - curColumn = myTable.cols[keyArray[1]][keyArray[2]], - curKey = keyArray[1] + '-' + keyArray[2], - isInFixed = $this.parents('.layui-table-fixed').length > 0; - // 绑定鼠标按下事件 - $(this).find('span:first,.laytable-cell-checkbox') - .css('cursor', 'move') - .on('mousedown', function (e) { - // 暂停或者非鼠标左键都不执行 - if (_this.suspendConfig[tableId].drag || e.button !== 0) { - return; - } - e.preventDefault(); - var $cloneHead = $this.clone().css('visibility', 'hidden'), - originLeft = $this.position().left, - originTop = $this.offset().top, - disX = e.clientX - originLeft, // 鼠标距离被移动元素左侧的距离 - color = $this.parents('tr:eq(0)').css("background-color"), - width = $this.width(), moveDistince = 0, - $that = $(this), - isFixed = curColumn.fixed; - isStart = true; - //区分click、drag事件 - - - // 阻止文本选中 - _DOC.bind("selectstart", function () { - return false; - }); - - // 移动事件 - _BODY.on('mousemove', function (e) { - if (isStart && $cloneHead) { - $tableBox.removeClass('no-left-border'); - if (!isDragging) { - if (toolbar) { - $dragBar.attr('data-type', isFixed || 'none') - $dragBar.addClass('active') - } - - $this.after($cloneHead); - $this.addClass('isDrag').css({ - 'position': 'absolute', - 'z-index': 1, - 'border-left': '1px solid #e6e6e6', - 'background-color': color, - 'width': width + 1 - }); - - if (isSimple) { - //设置蒙板 - } else { - (isInFixed ? $fixedBody : $tableBody).find('td[data-key="' + key + '"]').each(function () { - $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); - $(this).addClass('isDrag').css({ - 'position': 'absolute', - 'z-index': 1, - 'border-left': '1px solid #e6e6e6', - 'background-color': $(this).css('background-color'), - 'width': width + 1 - }); - }) - if ($totalTable.length > 0) { - (isInFixed ? $fixedTotalTable : $totalTable).find('td[data-key="' + key + '"]').each(function () { - $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); - $(this).addClass('isDrag').css({ - 'position': 'absolute', - 'z-index': 1, - 'background-color': $(this).parents('tr:eq(0)').css('background-color'), - 'width': width + 1 - }); - }) - } - } - } - isDragging = true; - var x, y, i, j, tempCols, - left = e.clientX - disX, // 计算当前被移动列左侧位置应该哪里 - $leftTh = $cloneHead.prev().prev(), - hasLeftTh = $leftTh.length > 0, - leftKey = hasLeftTh ? $leftTh.data('key').split('-') : [], - $rightTh = $cloneHead.next().hasClass('layui-table-patch') ? [] : $cloneHead.next(), - hasRightTh = $rightTh.length > 0, - rightKey = hasRightTh ? $rightTh.data('key').split('-') : [], - leftMove = hasLeftTh && ($cloneHead.position().left - left > $leftTh.width() / 2.0), - rightMove = hasRightTh && (left - $cloneHead.position().left > $rightTh.width() / 2.0); - moveDistince = Math.abs($cloneHead.position().left - left); //记录移动距离 - // 移动到左右两端、checbox/radio 固定列等停止移动 - if ($cloneHead.position().left - left > 0 - ? !hasLeftTh || !!isFixed !== !!myTable.cols[leftKey[1]][leftKey[2]].fixed - : !hasRightTh || !!isFixed !== !!myTable.cols[rightKey[1]][rightKey[2]].fixed) { - $this.css('left', $cloneHead.position().left); - $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function (e) { - $(this).prev().css('left', $cloneHead.position().left); - }) - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function (e) { - $(this).prev().css('left', $cloneHead.position().left); - }) - } - $tableBox.addClass('no-left-border'); - return; - } - $this.css('left', left); - - if (leftMove) { - $cloneHead.after($leftTh); - - // 更新隐藏列顺序 - $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').after($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').prev()) - - // 更新配置信息 - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].key === curKey) { - x = i; - y = j; - break; - } - } - if (typeof x !== 'undefined' && typeof y !== 'undefined') { - break; - } - } - tempCols = myTable.cols[x][y - 1]; - myTable.cols[x][y - 1] = myTable.cols[x][y]; - myTable.cols[x][y] = tempCols; - _this.fixTableRemember(myTable); - } else if (rightMove) { - $cloneHead.prev().before($rightTh); - - // 更新隐藏列顺序 - $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').before($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').next()) - - // 更新配置信息 - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].key === curKey) { - x = i; - y = j; - break; - } - } - if (typeof x !== 'undefined' && typeof y !== 'undefined') { - break; - } - } - tempCols = myTable.cols[x][y + 1]; - myTable.cols[x][y + 1] = myTable.cols[x][y]; - myTable.cols[x][y] = tempCols; - _this.fixTableRemember(myTable); - } - - $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().css('left', left); - - if (leftMove) { - if ($(this).prev().prev().length !== 0) { - $(this).after($(this).prev().prev()); - } - } else if (rightMove) { - if ($(this).next().length !== 0) { - $(this).prev().before($(this).next()); - } - } - }) - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().css('left', left); - - if (leftMove) { - if ($(this).prev().prev().length !== 0) { - $(this).after($(this).prev().prev()); - } - } else if (rightMove) { - if ($(this).next().length !== 0) { - $(this).prev().before($(this).next()); - } - } - }) - } - - /* 拖动隐藏列 */ - if (e.clientY - originTop < -15) { - if ($('#column-remove').length === 0) { - _BODY.append('') - } - $('#column-remove').css({ - top: e.clientY - $('#column-remove').height() / 2, - left: e.clientX - $('#column-remove').width() / 2, - 'font-size': (originTop - e.clientY) + 'px' - }) - $('#column-remove').show(); - } else { - $('#column-remove').hide(); - } - } - }).on('mouseup', function () { - _DOC.unbind("selectstart"); - _BODY.off('mousemove').off('mouseup') - if (isStart && $cloneHead) { - isStart = false; - if (isDragging) { - if (curColumn.type !== 'checkbox') { - $that.on('click', function (e) { - e.stopPropagation(); - }); - } - - isDragging = false; - $tableBox.removeClass('no-left-border') - $this.removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'border-left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $this.next().remove(); - var prefKey = $this.prev().data('key'); - if (isFixed) { - var $noFixedTh = $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + key + '"]'); - if (prefKey) { - $noFixedTh.parent().children('th[data-key="' + prefKey + '"]').after($noFixedTh) - } else { - if (isFixed === 'right') { - if ($this.siblings().length > 0) { - $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + $this.next().data('key') + '"]').prev().after($noFixedTh); - } - } else { - $noFixedTh.parent().prepend(''); - $noFixedTh.parent().children('th:first').after($noFixedTh); - $noFixedTh.parent().children('th:first').remove(); - } - - } - } - if (isSimple) { - $tableBody.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - if ($this.siblings().length > 0) { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - } - } else if (isInFixed) { - $noFixedBody.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - if ($this.siblings().length > 0) { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - $fixedBody.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'border-left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - if ($totalTable.length > 0) { - $noFixedTotalTable.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - $fixedTotalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - } - } else { - $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - } - } - - $cloneHead = null; - - // 处理 toolbar 事件 - if (toolbar) { - if ($dragBar.children('.active').length > 0 && $dragBar.children('.active').attr('data-type') !== $dragBar.attr('data-type')) { - var targetFix = $dragBar.children('.active').attr('data-type'), - i, j, curPos, targetPos; - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if (targetFix === 'right' || (targetFix === 'none' && $dragBar.attr('data-type') === 'right')) { - if (typeof targetPos === 'undefined') { - if (myTable.cols[i][j].fixed === 'right') { - targetPos = { x: i, y: j }; - } else if (j === myTable.cols[i].length - 1) { - targetPos = { x: i, y: j + 1 }; - } - - } - } else { - if (typeof targetPos === 'undefined' && (!myTable.cols[i][j].fixed || myTable.cols[i][j].fixed === 'right')) { - targetPos = { x: i, y: j }; - } - } - if (myTable.cols[i][j].key === curKey) { - curPos = { x: i, y: j }; - } - } - } - curColumn['fixed'] = targetFix === 'none' ? false : targetFix; - - if (curPos.y !== targetPos.y) { - myTable.cols[curPos.x].splice(curPos.y, 1); - - if (curPos.y < targetPos.y) { - targetPos.y -= 1 - } - - myTable.cols[targetPos.x].splice(targetPos.y, 0, curColumn) - - _this.fixTableRemember(myTable); - } - table.reload(tableId) - } - $dragBar.removeClass('active') - } - - } else { - $that.unbind('click'); - } - if ($('#column-remove').is(':visible')) { - $tableHead.find('thead>tr>th[data-key=' + key + ']').addClass(HIDE); - $tableBody.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); - $totalTable.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); - // 同步配置 - curColumn['hide'] = true - _this.fixTableRemember(myTable); - // 更新下拉隐藏 - $('#soul-columns' + tableId).find('li[data-value="' + field + '"]>input').prop('checked', false); - tableFilter.resize(myTable) - } - $('#column-remove').hide(); - } - }) - }); - }) - } - }, - rowDrag: function (myTable, rowDragConfig) { - var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $noFixedBody = $tableBox.children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - tableId = myTable.id, - isDragging = false, - trigger = rowDragConfig.trigger || 'row', - syncNumber = rowDragConfig.numbers !== false, - numberColumnKey = null, numberStart = 0, - $trs = trigger === 'row' ? $tableBody.children('tbody').children('tr') : $tableBody.find(trigger), - i, j; - if (trigger !== 'row') { - $tableBody.find(trigger).css('cursor', 'move') - } - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].type === 'numbers') { - numberColumnKey = myTable.index + '-' + i + '-' + j; - numberStart = parseInt($noFixedBody.find('td[data-key="' + numberColumnKey + '"]:first').text()); - break; - } - } - } - $trs.on('mousedown', function (e) { - // 被暂停 或者 不是鼠标左键 则取消拖拽效果 - if (_this.suspendConfig[tableId].rowDrag || e.button !== 0) { - return; - } - var $this = trigger === 'row' ? $(this) : $(this).parents('tr:eq(0)'), - index = parseInt($this.data('index')), // 被拖拽行索引 - $bodyTr = $noFixedBody.children('tbody').children('tr[data-index=' + index + ']'), // 被拖拽行(非固定列) - $cloneTr = $bodyTr.clone().css('visibility', 'hidden'), // 占位行 - $FixBodyTr = $fixedBody.children('tbody').children('tr[data-index=' + index + ']'), // 被拖拽行(固定列) - bodyScrollTop = $tableBox.children('.layui-table-body').scrollTop(), // 记录当前滚动条位置 - originTop = $this.position().top, // 被拖拽行当前位置 - disY = e.clientY - originTop; // 鼠标距离被拖拽行上侧的距离 - - _BODY.on('mousemove', function (e) { - // 刚被拖动 - if (!isDragging) { - isDragging = true; - // 设置鼠标样式 - // $table.next().find('style').append('.layui-table-view .layui-table td{cursor: move;}.layui-table tr{transition: none}') - var style = $table.next().find('style')[0], - sheet = style.sheet || style.styleSheet || {}; - _this.addCSSRule(sheet, '.layui-table-view .layui-table td', 'cursor: move') - _this.addCSSRule(sheet, '.layui-table tr', 'transition: none') - - $tableBox.addClass('noselect'); // 禁止选中文本 - - $bodyTr.after($cloneTr); - $bodyTr.css({ - 'position': 'absolute', - 'z-index': 1 - }) - - $FixBodyTr.each(function () { - $(this).after($(this).clone().css('visibility', 'hidden')) - $(this).css({ - 'position': 'absolute', - 'z-index': 102 - }) - }) - } - - var top = e.clientY - disY + ($tableBox.children('.layui-table-body').scrollTop() - bodyScrollTop), // 计算当前被移动行top位置应该哪里 - trTop = $cloneTr.position().top, //当前行所在位置 - $UpTr = $bodyTr.prev(), - hasUpTr = $UpTr.length > 0, - $downTr = $cloneTr.next(), - hasDownTr = $downTr.length > 0, - upMove = hasUpTr && (trTop - top > $UpTr.height() / 2.0), - downMove = hasDownTr && (top - trTop > $downTr.height() / 2.0); - - if (trTop - top > 0 ? !hasUpTr : !hasDownTr) { - $bodyTr.css('top', trTop); - $FixBodyTr.each(function () { - $(this).css('top', trTop); - }) - return; - } - - $bodyTr.css('top', top); - $FixBodyTr.each(function () { - $(this).css('top', top); - }) - - if (upMove) { - updateDataIndex($bodyTr, -1) - $cloneTr.after(updateDataIndex($UpTr, 1)); - $FixBodyTr.each(function () { - updateDataIndex($(this), -1) - $(this).next().after(updateDataIndex($(this).prev(), 1)); - }) - } else if (downMove) { - updateDataIndex($bodyTr, 1).before(updateDataIndex($downTr, -1)) - $FixBodyTr.each(function () { - updateDataIndex($(this), 1); - $(this).before(updateDataIndex($(this).next().next(), -1)); - }) - } - - // 同步 data-index - function updateDataIndex($el, diff) { - var tempIndex = parseInt($el.data('index')) + diff; - $el.data('index', tempIndex); - $el.attr('data-index', tempIndex); - return $el - } - - }).on('mouseup', function (e) { - _BODY.off('mousemove').off('mouseup'); - - if (isDragging) { - isDragging = false; - - $tableBox.removeClass('noselect'); // 取消禁止选中文本 - $bodyTr.css({ 'position': 'inherit', 'z-index': 'inherit' }); - $bodyTr.next().remove(); - $FixBodyTr.each(function () { - $(this).css({ 'position': 'inherit', 'z-index': 'inherit' }); - $(this).next().remove() - }) - - // 恢复样式 - var style = $table.next().find('style')[0], - sheet = style.sheet || style.styleSheet || {}, - rules = sheet.cssRules || sheet.rules; - layui.each(rules, function (i, item) { - if (item.selectorText === ('.layui-table-view .layui-table td')) { - item.style.cursor = 'default'; - } - }); - - var newIndex = $this.index(), - cache = table.cache[tableId]; - if (newIndex !== index) { // 有位置变动 - // 如果 before 返回 false,则还原拖拽 - if (typeof rowDragConfig.before === 'function' - && rowDragConfig.before.call(myTable, { - row: cache[index], - newIndex: newIndex, - oldIndex: index, - cache: cache - }) === false) { - - // 同步 data-index - function updateDataIndex($el, setIndex) { - $el.data('index', setIndex); - $el.attr('data-index', setIndex); - return $el - } - - // 还原位置和索引 - if (newIndex < index) { - for (i = newIndex; i < index; i++) { - updateDataIndex($noFixedBody.find('tr[data-index="' + (i + 1) + '"]'), i) - updateDataIndex($fixedBody.find('tr[data-index="' + (i + 1) + '"]'), i) - } - updateDataIndex($bodyTr, index) - $noFixedBody.find('tr[data-index="' + (index - 1) + '"]').after($bodyTr) - $FixBodyTr.each(function () { - updateDataIndex($(this), index) - $(this).parent().children('tr[data-index="' + (index - 1) + '"]').after($(this)) - }) - } else { - for (i = newIndex; i > index; i--) { - updateDataIndex($noFixedBody.find('tr[data-index="' + (i - 1) + '"]'), i) - updateDataIndex($fixedBody.find('tr[data-index="' + (i - 1) + '"]'), i) - } - updateDataIndex($bodyTr, index) - $noFixedBody.find('tr[data-index="' + (index + 1) + '"]').before($bodyTr) - $FixBodyTr.each(function () { - updateDataIndex($(this), index) - $(this).parent().children('tr[data-index="' + (index + 1) + '"]').before($(this)) - }) - } - return; - } - - var row = cache.splice(index, 1)[0]; - cache.splice(newIndex, 0, row); - if (numberColumnKey && syncNumber) { - // 进行序号重排 - var sortedIndexs = [newIndex, index].sort() - for (i = sortedIndexs[0]; i <= sortedIndexs[1]; i++) { - var curIndex = numberStart + i; - $fixedBody.find('td[data-key="' + numberColumnKey + '"]:eq(' + i + ')').children().html(curIndex) - $noFixedBody.find('td[data-key="' + numberColumnKey + '"]:eq(' + i + ')').children().html(curIndex) - cache[i][table.config.indexName] = curIndex - 1 - } - } - if (typeof rowDragConfig.done === 'function') { - - rowDragConfig.done.call(myTable, { - row: row, - newIndex: newIndex, - oldIndex: index, - cache: cache - }) - } - } - - } - }) - }) - }, - fixTableRemember: function (myTable, dict) { - - if (typeof myTable.filter === 'undefined' ? (defaultConfig.filter && defaultConfig.filter.cache) : myTable.filter.cache) { - if (dict && dict.rule) { - var curKey = dict.rule.selectorText.split('-')[3] + '-' + dict.rule.selectorText.split('-')[4]; - for (var i = 0; i < myTable.cols.length; i++) { - for (var j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].key === curKey) { - myTable.cols[i][j].width = dict.rule.style.width.replace('px', ''); - break; - } - } - - } - } - var storeKey = location.pathname + location.hash + myTable.id; - localStorage.setItem(storeKey, this.deepStringify(myTable.cols)) - } - }, - clearCache: function (myTable) { - if (!myTable) { - return; - } - var tableId; - if (typeof myTable === 'object') { - if (typeof myTable.config !== 'undefined') { - tableId = myTable.config.id - } else { - tableId = myTable.id - } - } else { - tableId = myTable - } - localStorage.removeItem(location.pathname + location.hash + tableId) - if (originCols[tableId]) { - this.updateCols(tables[tableId], this.deepClone(originCols[tableId])) - } - }, - overflow: function (myTable, overflowConfig) { - var options = {}; - if (typeof overflowConfig === 'string') { - options = { - type: overflowConfig - } - } else if (typeof overflowConfig === 'object') { - options = overflowConfig - } else { - return; - } - var $table = $(myTable.elem), - layHeader = $table.next().find('.layui-table-header'), - layBody = $table.next().find('.layui-table-body'), - layTotal = $table.next().find('.layui-table-total'), - tooltipIndex, - hoverTime = options.hoverTime || 0, - tooltipTimeOut, - color = options.color || 'white', - bgColor = options.bgColor || 'black', - minWidth = options.minWidth || 300, - maxWidth = options.maxWidth || 300; - - if (options.type === 'tips') { - layBody.off('mouseenter', 'td').off('mouseleave', 'td').on('mouseenter', 'td', function () { - var _this = this; - tooltipTimeOut = setTimeout(function () { - toopTip.call(_this) - }, hoverTime) - }).on('mouseleave', 'td', function () { - toopTip.call(this, 'hide') - }) - if (options.header) { - layHeader.off('mouseenter', 'th').off('mouseleave', 'th').on('mouseenter', 'th', function () { - var _this = this; - tooltipTimeOut = setTimeout(function () { - toopTip.call(_this) - }, hoverTime) - }).on('mouseleave', 'th', function () { - toopTip.call(this, 'hide') - }) - } - if (options.total) { - layTotal.off('mouseenter', 'td').off('mouseleave', 'td').on('mouseenter', 'td', function () { - var _this = this; - tooltipTimeOut = setTimeout(function () { - toopTip.call(_this) - }, hoverTime) - }).on('mouseleave', 'td', function () { - toopTip.call(this, 'hide') - }) - } - - function toopTip(hide) { - clearTimeout(tooltipTimeOut); - var othis = $(this) - , elemCell = othis.children('.layui-table-cell') - , width = elemCell.outerWidth() - , layerWidth = width < minWidth ? minWidth : width > maxWidth ? maxWidth : width; - if (othis.data('off')) return; - - if (hide) { - layer.close(tooltipIndex) - } else if (elemCell.prop('scrollWidth') > width) { - tooltipIndex = layer.tips('' + $(this).text() + '', this, { - tips: [1, bgColor], - maxWidth: layerWidth, - time: 0 - }); - } - } - } else if (options.type === 'title') { - layBody.off('mouseenter', 'td').on('mouseenter', 'td', function () { - var othis = $(this) - , elemCell = othis.children('.layui-table-cell'); - if (othis.data('off')) return; - - if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { - elemCell.attr('title', $(this).text()) - } - }) - if (options.header) { - layHeader.off('mouseenter', 'th').on('mouseenter', 'th', function () { - var othis = $(this) - , elemCell = othis.children('.layui-table-cell'); - if (othis.data('off')) return; - - if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { - elemCell.attr('title', $(this).text()) - } - }) - } - if (options.total) { - layTotal.off('mouseenter', 'td').on('mouseenter', 'td', function () { - var othis = $(this) - , elemCell = othis.children('.layui-table-cell'); - if (othis.data('off')) return; - - if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { - elemCell.attr('title', $(this).text()) - } - }) - } - } - - }, - // 右键菜单配置 - contextmenu: function (myTable, contextmenuConfig) { - var $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - $totalTable = $table.next().children('.layui-table-total').children('table'), - tableId = myTable.id, - header = contextmenuConfig ? contextmenuConfig.header : '', - body = contextmenuConfig ? contextmenuConfig.body : '', - total = contextmenuConfig ? contextmenuConfig.total : '', - options = { - header: { box: $tableHead, tag: 'th', opts: header, cols: {} }, - body: { box: $tableBody, tag: 'td', opts: body, cols: {}, isBody: true }, - total: { box: $totalTable, tag: 'td', opts: total, cols: {} } - }, - hasColsContext = false; - - for (var i = 0; i < myTable.cols.length; i++) { - for (var j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].contextmenu) { - hasColsContext = true - options.header.cols[myTable.cols[i][j].key] = myTable.cols[i][j].contextmenu.header - options.body.cols[myTable.cols[i][j].key] = myTable.cols[i][j].contextmenu.body - options.total.cols[myTable.cols[i][j].key] = myTable.cols[i][j].contextmenu.total - } - } - } - - if (!contextmenuConfig && !hasColsContext) { - return; - } - - - for (var name in options) { - (function (name) { - options[name].box.find(options[name].tag).on('contextmenu', function (e) { - $('#soul-table-contextmenu-wrapper').remove(); - _BODY.append('
'); - $('#soul-table-contextmenu-wrapper').on('click', function (e) { - e.stopPropagation() - }) - var curColsOpts = options[name].cols[$(this).data('key').substr($(this).data('key').indexOf('-') + 1)]; - if (curColsOpts === false) { - return false - } else if (curColsOpts && curColsOpts.length > 0) { - genePanel($('#soul-table-contextmenu-wrapper'), e.pageX, e.pageY, curColsOpts, $(this), options[name].box, options[name].tag, options[name].isBody); - return false - } else if (options[name].opts === false) { - return false - } else if (options[name].opts && options[name].opts.length > 0) { - genePanel($('#soul-table-contextmenu-wrapper'), e.pageX, e.pageY, options[name].opts, $(this), options[name].box, options[name].tag, options[name].isBody); - return false - } - }) - })(name) - } - - - _BODY.on('click', function () { - $('#soul-table-contextmenu-wrapper').remove(); - }) - - function genePanel($parent, left, top, options, $this, box, tag, isBody) { - var html = [], i; - - html.push('
    '); - for (i = 0; i < options.length; i++) { - html.push('
  • ') - if (options[i].icon) { - html.push('') - } else { - html.push('') - } - html.push(options[i].name) - - if (options[i].children && options[i].children.length > 0) { - html.push('') - } - - html.push('
  • ') - } - html.push('
'); - $parent.append(html.join('')); - var $curPanel = $parent.children().last(); - if (top + $curPanel.outerHeight() > _BODY.prop('scrollHeight')) { - top = top - $curPanel.outerHeight() - if (top < 0) { - top = 0 - } - } - if ($parent.parent().data('direction') === 'left' && ($parent.offset().left - $curPanel.outerWidth()) > 0) { - left = -$curPanel.outerWidth(); - $curPanel.data('direction', 'left') - } else if (left + $curPanel.outerWidth() + $parent.offset().left > _BODY.prop('scrollWidth')) { - left = left - $curPanel.outerWidth() - $parent.outerWidth() - if (left + $parent.offset().left < 0) { - left = -$parent.offset().left - } - $curPanel.data('direction', 'left') - } - $curPanel.css({ - top: top + 'px', - left: left + 'px' - }) - - for (i = 0; i < options.length; i++) { - if (typeof options[i].click === "function") { - (function (i) { - $parent.children('.soul-table-contextmenu:last').children('li[data-index="' + i + '"]').on('click', function () { - var index = $this.parents('tr:eq(0)').data('index'), - tr = box.find('tr[data-index="' + index + '"]'), - row = layui.table.cache[tableId][index]; - - options[i].click.call(myTable, { - cell: $this, - elem: tag === 'th' ? $this : isBody ? box.children('tbody').children('tr[data-index="' + index + '"]').children('[data-key="' + $this.data('key') + '"]') : box.find('[data-key="' + $this.data('key') + '"]'), - trElem: box.children('tbody').children('tr[data-index="' + index + '"]'), - text: $this.text(), - field: $this.data('field'), - del: !isBody ? '' : function () { - table.cache[tableId][index] = []; - tr.remove(); - table.resize(tableId); - }, - update: !isBody ? '' : function (fields) { - fields = fields || {}; - layui.each(fields, function (key, value) { - if (key in row) { - var templet, td = tr.children('td[data-field="' + key + '"]'); - row[key] = value; - table.eachCols(tableId, function (i, item2) { - if (item2.field == key && item2.templet) { - templet = item2.templet; - } - }); - td.children('.layui-table-cell').html(function () { - return templet ? function () { - return typeof templet === 'function' - ? templet(row) - : layui.laytpl($(templet).html() || value).render(row) - }() : value; - }()); - td.data('content', value); - } - }); - }, - row: isBody ? row : {}, - }) - $('#soul-table-contextmenu-wrapper').remove(); - }) - })(i) - } - } - $parent.children('.soul-table-contextmenu:last').children('li').on('mouseenter', function (e) { - e.stopPropagation() - $(this).siblings('.contextmenu-children').children('ul').remove(); - if ($(this).hasClass('contextmenu-children')) { - genePanel($(this), $(this).outerWidth(), $(this).position().top, options[$(this).data('index')].children, $this, box, tag, isBody) - } - }) - } - - }, - fixTotal: function (myTable) { - var $table = $(myTable.elem), - $total = $table.next().children('.layui-table-total'), - style = $table.next().find('style')[0], - sheet = style.sheet || style.styleSheet || {}; - if ($total.length > 0) { - var $tableBox = $table.next().children('.layui-table-box'), - $fixedLeft = $tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), - $fixedRight = $tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), - html = []; - - $total.children('.layui-table-total-fixed').remove() - - if ($fixedLeft.length > 0) { - this.addCSSRule(sheet, '.layui-table-total-fixed-l .layui-table-patch', 'display: none') - $table.next().css('position', 'relative'); - html.push(''); - $fixedLeft.each(function () { - if ($(this).data('key')) { - html.push($total.children('table:eq(0)').find('[data-key="' + $(this).data('key') + '"]').prop("outerHTML")) - } - }) - html.push('
'); - $total.append(html.join('')) - } - if ($fixedRight.length > 0) { - this.addCSSRule(sheet, '.layui-table-total-fixed-r td:first-child', 'border-left:1px solid #e6e6e6') - this.addCSSRule(sheet, '.layui-table-total-fixed-r td:last-child', 'border-left: none') - $table.next().css('position', 'relative'); - html = []; - html.push(''); - $fixedRight.each(function () { - html.push($total.children('table:eq(0)').find('[data-key="' + $(this).data('key') + '"]').prop("outerHTML")) - }) - html.push('
') - $total.append(html.join('')) - } - } - - }, - fixResizeRightFixed: function (myTable) { - var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $fixedHead = $tableBox.children('.layui-table-fixed-r').children('.layui-table-header').children('table'), - dict = {}, resizing, ELEM_SORT = 'layui-table-sort', - ELEM_NO_SORT = 'layui-table-sort-invalid'; - if ($fixedHead.length > 0) { - $fixedHead.find('th').off('mousemove').on('mousemove', function (e) { - var othis = $(this) - , oLeft = othis.offset().left - , pLeft = e.clientX - oLeft; - if (othis.data('unresize') || dict.resizeStart) { - return; - } - if (othis.width() - pLeft <= 10) { - _BODY.css('cursor', 'initial') - } - dict.allowResize = pLeft <= 10; //是否处于拖拽允许区域 - _BODY.css('cursor', (dict.allowResize ? 'col-resize' : '')); - }).off('mousedown').on('mousedown', function (e) { - var othis = $(this); - if (dict.allowResize) { - othis.find('.' + ELEM_SORT).removeClass(ELEM_SORT).addClass(ELEM_NO_SORT) - var key = othis.data('key'); - e.preventDefault(); - dict.resizeStart = true; //开始拖拽 - dict.offset = [e.clientX, e.clientY]; //记录初始坐标 - - _this.getCssRule(myTable, key, function (item) { - var width = item.style.width || othis.outerWidth(); - dict.rule = item; - dict.ruleWidth = parseFloat(width); - dict.othis = othis; - dict.minWidth = othis.data('minwidth') || myTable.cellMinWidth; - }); - } - }); - //拖拽中 - _DOC.on('mousemove', function (e) { - if (dict.resizeStart) { - layui.soulTable.fixTableRemember(myTable, dict) - e.preventDefault(); - if (dict.rule) { - var setWidth = dict.ruleWidth - e.clientX + dict.offset[0]; - if (setWidth < dict.minWidth) setWidth = dict.minWidth; - dict.rule.style.width = setWidth + 'px'; - } - resizing = 1 - } - }).on('mouseup', function (e) { - if (dict.resizeStart) { - setTimeout(function () { - dict.othis.find('.' + ELEM_NO_SORT).removeClass(ELEM_NO_SORT).addClass(ELEM_SORT) - _BODY.css('cursor', ''); - dict = {}; - _this.scrollPatch(myTable); - }, 30) - } - if (resizing === 2) { - resizing = null; - } - }); - } - }, - fixFixedScroll: function (myTable) { - var $table = $(myTable.elem), - layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), - layMain = $table.next().children('.layui-table-box').children('.layui-table-main'); - - layFixed.on('mouseenter', function () { - $(this).children('.layui-table-body').addClass('soul-fixed-scroll').on('scroll', function () { - var scrollTop = $(this).scrollTop() - // layFixed.children('.layui-table-body[class!="soul-fixed-scroll"]').scrollTop(scrollTop); - layMain.scrollTop(scrollTop); - }) - }).on('mouseleave', function () { - $(this).children('.layui-table-body').removeClass('soul-fixed-scroll').off('scroll'); - }) - }, - scrollPatch: function (myTable) { - var $table = $(myTable.elem), - layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'), - layTotal = $table.next().children('.layui-table-total'), - layMain = $table.next().children('.layui-table-box').children('.layui-table-main'), - layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), - layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'), - layMainTable = layMain.children('table'), - scollWidth = layMain.width() - layMain.prop('clientWidth'), - scollHeight = layMain.height() - layMain.prop('clientHeight'), - outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度 - - //添加补丁 - , addPatch = function (elem) { - if (scollWidth && scollHeight) { - elem = elem.eq(0); - if (!elem.find('.layui-table-patch')[0]) { - var patchElem = $('
'); //补丁元素 - patchElem.find('div').css({ - width: scollWidth - }); - elem.find('tr').append(patchElem); - } - } else { - elem.find('.layui-table-patch').remove(); - } - } - - addPatch(layHeader); - addPatch(layTotal); - - //固定列区域高度 - var mainHeight = layMain.height() - , fixHeight = mainHeight - scollHeight; - layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto'); - - //表格宽度小于容器宽度时,隐藏固定列 - layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE); - - //操作栏 - layFixRight.css('right', scollWidth - 1); - }, - /** - * 一键粘贴 - * @param {String} text [需要 copy 的属性,默认是 innerText,主要用途例如赋值 a 标签上的 href 链接] - * - * range + selection - * - * 1.创建一个 range - * 2.把内容放入 range - * 3.把 range 放入 selection - * - * 注意:参数 attr 不能是自定义属性 - * 注意:对于 user-select: none 的元素无效 - * 注意:当 id 为 false 且 attr 不会空,会直接复制 attr 的内容 - */ - copy: function (text) { - var target; - - if (text) { - target = document.createElement('div'); - target.id = 'tempTarget'; - target.style.opacity = '0'; - target.innerText = text; - document.body.appendChild(target); - } else { - target = document.querySelector('#' + id); - } - - try { - var range = document.createRange(); - range.selectNode(target); - window.getSelection().removeAllRanges(); - window.getSelection().addRange(range); - document.execCommand('copy'); - window.getSelection().removeAllRanges(); - } catch (e) { - console.log('复制失败') - } - - if (text) { - // remove temp target - target.parentElement.removeChild(target); - } - }, - addCSSRule: function (sheet, selector, rules, index) { - if ('insertRule' in sheet) { - sheet.insertRule(selector + '{' + rules + '}', index) - } else if ('addRule' in sheet) { - sheet.addRule(selector, rules, index) - } - }, - deepStringify: function (obj) { - var JSON_SERIALIZE_FIX = { - PREFIX: "[[JSON_FUN_PREFIX_", - SUFFIX: "_JSON_FUN_SUFFIX]]" - }; - return JSON.stringify(obj, function (key, value) { - if (typeof value === 'function') { - return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX; - } - return value; - }); - }, - deepParse: function (str) { - var JSON_SERIALIZE_FIX = { - PREFIX: "[[JSON_FUN_PREFIX_", - SUFFIX: "_JSON_FUN_SUFFIX]]" - }; - return JSON.parse(str, function (key, value) { - if (typeof value === 'string' && - value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) { - return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")"); - } - return value; - }) || {}; - }, - clearFilter: function (myTable) { - tableFilter.clearFilter(myTable); - }, - cache: tableFilter.cache, - // 深度克隆-不丢失方法 - deepClone: function (obj) { - var newObj = Array.isArray(obj) ? [] : {} - if (obj && typeof obj === "object") { - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key]; - } - } - } - return newObj - }, - clearOriginCols: function (tableId) { - if (tableId) { - delete originCols[tableId] - } else { - originCols = {} - } - }, - suspendConfig: {}, - /** - * 暂停某个特性 - * @param tableId - * @param type 暂停的类型,支持 'drag' 'rowDrag' - * @param value true/false - */ - suspend: function (tableId, type, value) { - this.suspendConfig[tableId][type] = value + var curTableSession = localStorage.getItem(storeKey); + if (curTableSession && colsStr === localStorage.getItem('origin' + storeKey)) { + this.updateCols(myTable, this.deepParse(curTableSession)); + } else { + localStorage.setItem('origin' + storeKey, colsStr) + localStorage.removeItem(storeKey) + } } + } else { + // 如果没有开启记忆,则清除 + this.clearCache(myTable); + } + + tableFilter.render(myTable); + tableChild.render(myTable); + tableMerge.render(myTable); + + // 初始化暂停配置 + this.suspendConfig[myTable.id] = { + drag: false, + rowDrag: false + } + // 修复合计栏固定列问题 + if (curConfig.fixTotal) { + this.fixTotal(myTable) + } + if (curConfig.drag) { + this.drag(myTable, curConfig.drag); + } + if (curConfig.rowDrag) { + this.rowDrag(myTable, curConfig.rowDrag) + } + if (curConfig.autoColumnWidth) { + this.autoColumnWidth(myTable, curConfig.autoColumnWidth) + } + + this.contextmenu(myTable, curConfig.contextmenu); + + if (curConfig.fixResize) { + this.fixResizeRightFixed(myTable); + } + + if (curConfig.overflow) { + this.overflow(myTable, curConfig.overflow); + } + + if (curConfig.fixFixedScroll) { + this.fixFixedScroll(myTable); + } } + , config: function (configObj) { + if (typeof configObj === 'object') { + $.extend(true, defaultConfig, configObj); + } + } + , updateCols: function (myTable, cols) { + var i, j, lastKeyMap = {}, columnKey, newCols = [], col = [], + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $fixedHead = $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table'), + $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $fixedHead), + $noFixedHead = $tableBox.children('.layui-table-header').children('table'), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $noFixedBody = $tableBox.children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody); - // 输出 - exports('soulTable', mod); + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + myTable.cols[i][j]['oldPos'] = i + '-' + j + lastKeyMap[myTable.cols[i][j].key] = myTable.cols[i][j] + } + } + + for (i = 0; i < cols.length; i++) { + col = [] + for (j = 0; j < cols[i].length; j++) { + columnKey = cols[i][j].key; + // 同步列宽 + if (cols[i][j].width && lastKeyMap[cols[i][j].key] !== cols[i][j].width) { + this.getCssRule(myTable, columnKey, function (item) { + item.style.width = (cols[i][j].width ? cols[i][j].width : 0) + 'px' + }) + } + // 同步隐藏 + if (lastKeyMap[cols[i][j].key].hide !== cols[i][j].hide) { + $tableHead.find('th[data-key="' + columnKey + '"]')[cols[i][j].hide ? 'addClass' : 'removeClass']('layui-hide') + $tableBody.find('td[data-key="' + columnKey + '"]')[cols[i][j].hide ? 'addClass' : 'removeClass']('layui-hide') + } + + // 同步顺序 + if (lastKeyMap[cols[i][j].key].oldPos !== (i + '-' + j) || lastKeyMap[cols[i][j].key].fixed !== cols[i][j].fixed) { + myTable.cols = cols; + table.reload(myTable.id) + return; + // 实现不 reload 调整列顺序 + + } + lastKeyMap[cols[i][j].key].fixed = cols[i][j].fixed; + lastKeyMap[cols[i][j].key].width = cols[i][j].width; + lastKeyMap[cols[i][j].key].hide = cols[i][j].hide; + col.push(lastKeyMap[cols[i][j].key]) + } + newCols.push(col) + } + $noFixedHead.children().children('tr').each(function () { + innerHandler(this, 'th') + }) + $noFixedBody.children().children('tr').each(function () { + innerHandler(this, 'td') + }) + + function innerHandler(_this, domName) { + for (i = 0; i < cols.length; i++) { + for (j = 0; j < cols[i].length; j++) { + columnKey = myTable.index + '-' + cols[i][j].key; + var curKey = $(_this).children(domName + ':eq(' + j + ')').attr('data-key'); + if (curKey !== columnKey) { + $(_this).children(domName + ':eq(' + j + ')').before($(_this).children(domName + '[data-key="' + columnKey + '"]')) + if (cols[i][j].fixed) { + var $curRow = (domName === 'th' ? $fixedHead : $fixedBody).children().children(domName === 'th' ? 'tr' : 'tr[data-index="' + $(_this).attr('data-index') + '"]') + $curRow.children(domName + '[data-key="' + curKey + '"]').before($curRow.children(domName + '[data-key="' + columnKey + '"]')) + } + } + } + } + } + + myTable.cols = newCols; + + table.resize(myTable.id) + } + /** + * excel表格导出 + * @param myTable + * @param curExcel + */ + , export: function (myTable, curExcel) { + tableFilter.export(myTable.config || myTable, curExcel); + } + , getCssRule: function (that, key, callback) { + var style = that.elem.next().find('style')[0] + , sheet = style.sheet || style.styleSheet || {} + , rules = sheet.cssRules || sheet.rules; + layui.each(rules, function (i, item) { + if (item.selectorText === ('.laytable-cell-' + key)) { + return callback(item), true; + } + }); + } + , autoColumnWidth: function (myTable, autoColumnWidthConfig) { + var _this = this; + if (typeof myTable === 'object') { + innerColumnWidth(_this, myTable) + } else if (typeof myTable === 'string') { + innerColumnWidth(_this, tables[myTable]) + } else if (typeof myTable === 'undefined') { + layui.each(tables, function () { + innerColumnWidth(_this, this) + }); + } + + function innerColumnWidth(_this, myTable) { + var $table = $(myTable.elem), + th = $table.next().children('.layui-table-box').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), + fixTh = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), + $tableBodytr = $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr'), + $totalTr = $table.next().children('.layui-table-total').find('tr'); + String.prototype.width = function (font) { + var f = font || _BODY.css('font'), + o = $('
' + this + '
') + .css({ + 'position': 'absolute', + 'float': 'left', + 'white-space': 'nowrap', + 'visibility': 'hidden', + 'font': f + }) + .appendTo(_BODY), + w = o.width(); + + o.remove(); + return w; + } + if (typeof autoColumnWidthConfig === 'undefined' || typeof autoColumnWidthConfig.dblclick === 'undefined' || autoColumnWidthConfig.dblclick) { + th.add(fixTh).on('dblclick', function (e) { + var othis = $(this), + pLeft = e.clientX - othis.offset().left; + handleColumnWidth(myTable, othis, othis.parents('.layui-table-fixed-r').length > 0 ? pLeft <= 10 : othis.width() - pLeft <= 10); + }) + } + // 初始化表格后,自动调整所有列宽 + if (autoColumnWidthConfig && autoColumnWidthConfig.init) { + th.add(fixTh).each(function (e) { + var colKey = $(this).attr('data-key').split('-') + if (myTable.cols[colKey[1]][colKey[2]].autoWidth !== false && (!Array.isArray(autoColumnWidthConfig.init) || autoColumnWidthConfig.init.indexOf($(this).attr('data-field')) !== -1)) { + handleColumnWidth(myTable, $(this), true); + } + }) + } + + function handleColumnWidth(myTable, othis, isHandle) { + var key = othis.data('key') + if (othis.attr('colspan') > 1 || othis.data('unresize')) { + return; + } + if (isHandle) { + var maxWidth = othis.text().width(othis.css('font')) + 21, font = othis.css('font'); + $tableBodytr.children('td[data-key="' + key + '"]').each(function (index, elem) { + var curWidth = 0 + if ($(this).children().children() && $(this).children().children().length > 0) { + curWidth += $(this).children().html().width(font) + } else { + curWidth = $(this).text().width(font); + } + + // var curWidth = $(this).text().width(font); + if (maxWidth < curWidth) { + maxWidth = curWidth + } + }) + if ($totalTr.length > 0) { + var curWidth = $totalTr.children('td[data-key="' + key + '"]').text().width(font) + if (maxWidth < curWidth) { + maxWidth = curWidth + } + + } + + maxWidth += 32; + + _this.getCssRule(myTable, key, function (item) { + item.style.width = maxWidth + 'px' + }); + for (var i = 0; i < myTable.cols.length; i++) { + for (var j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].key === key) { + myTable.cols[i][j].width = maxWidth; + break; + } + } + } + } + } + } + } + /** + * 左右拖拽调整列顺序、向上拖隐藏列 + * @param myTable + */ + , drag: function (myTable, dragConfig) { + if (myTable.cols.length > 1) { + // 如果是复杂表头,则自动禁用拖动效果 + return; + } + var _this = this, + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $noFixedBody = $tableBox.children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + $totalTable = $table.next().children('.layui-table-total').children('table'), + $fixedTotalTable = $table.next().children('.layui-table-total').children('table.layui-table-total-fixed'), + $noFixedTotalTable = $table.next().children('.layui-table-total').children('table:eq(0)'), + tableId = myTable.id, + isSimple = dragConfig === 'simple' || (dragConfig && dragConfig.type === 'simple'), // 是否为简易拖拽 + toolbar = dragConfig && dragConfig.toolbar, // 是否开启工具栏 + isDragging = false, isStart = false; + + if (!$tableHead.attr('drag')) { + $tableHead.attr('drag', true); + if (toolbar) { + $tableBox.append('
左固定
不固定
右固定
') + var $dragBar = $tableBox.children('.soul-drag-bar'); + $dragBar.children('div').on('mouseenter', function () { + $(this).addClass('active') + }).on('mouseleave', function () { + $(this).removeClass('active') + }) + } + + $tableHead.find('th').each(function () { + var $this = $(this), + field = $this.data('field'), + key = $this.data('key'); + if (!key) { + return; + } + + var keyArray = key.split('-'), + curColumn = myTable.cols[keyArray[1]][keyArray[2]], + curKey = myTable.index + '-' + keyArray[1] + '-' + keyArray[2], + isInFixed = $this.parents('.layui-table-fixed').length > 0; + // 绑定鼠标按下事件 + $(this).find('span:first,.laytable-cell-checkbox') + .css('cursor', 'move') + .on('mousedown', function (e) { + // 暂停或者非鼠标左键都不执行 + if (_this.suspendConfig[tableId].drag || e.button !== 0) { + return; + } + e.preventDefault(); + var $cloneHead = $this.clone().css('visibility', 'hidden'), + originLeft = $this.position().left, + originTop = $this.offset().top, + disX = e.clientX - originLeft, // 鼠标距离被移动元素左侧的距离 + color = $this.parents('tr:eq(0)').css("background-color"), + width = $this.width(), moveDistince = 0, + $that = $(this), + isFixed = curColumn.fixed; + isStart = true; + //区分click、drag事件 + + + // 阻止文本选中 + _DOC.bind("selectstart", function () { + return false; + }); + + // 移动事件 + _BODY.on('mousemove', function (e) { + if (isStart && $cloneHead) { + $tableBox.removeClass('no-left-border'); + if (!isDragging) { + if (toolbar) { + $dragBar.attr('data-type', isFixed || 'none') + $dragBar.addClass('active') + } + + $this.after($cloneHead); + $this.addClass('isDrag').css({ + 'position': 'absolute', + 'z-index': 1, + 'border-left': '1px solid #e6e6e6', + 'background-color': color, + 'width': width + 1 + }); + + if (isSimple) { + //设置蒙板 + } else { + (isInFixed ? $fixedBody : $tableBody).find('td[data-key="' + key + '"]').each(function () { + $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); + $(this).addClass('isDrag').css({ + 'position': 'absolute', + 'z-index': 1, + 'border-left': '1px solid #e6e6e6', + 'background-color': $(this).css('background-color'), + 'width': width + 1 + }); + }) + if ($totalTable.length > 0) { + (isInFixed ? $fixedTotalTable : $totalTable).find('td[data-key="' + key + '"]').each(function () { + $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); + $(this).addClass('isDrag').css({ + 'position': 'absolute', + 'z-index': 1, + 'background-color': $(this).parents('tr:eq(0)').css('background-color'), + 'width': width + 1 + }); + }) + } + } + } + isDragging = true; + var x, y, i, j, tempCols, + left = e.clientX - disX, // 计算当前被移动列左侧位置应该哪里 + $leftTh = $cloneHead.prev().prev(), + hasLeftTh = $leftTh.length > 0, + leftKey = hasLeftTh ? $leftTh.data('key').split('-') : [], + $rightTh = $cloneHead.next().hasClass('layui-table-patch') ? [] : $cloneHead.next(), + hasRightTh = $rightTh.length > 0, + rightKey = hasRightTh ? $rightTh.data('key').split('-') : [], + leftMove = hasLeftTh && ($cloneHead.position().left - left > $leftTh.width() / 2.0), + rightMove = hasRightTh && (left - $cloneHead.position().left > $rightTh.width() / 2.0); + moveDistince = Math.abs($cloneHead.position().left - left); //记录移动距离 + // 移动到左右两端、checbox/radio 固定列等停止移动 + if ($cloneHead.position().left - left > 0 + ? !hasLeftTh || !!isFixed !== !!myTable.cols[leftKey[1]][leftKey[2]].fixed + : !hasRightTh || !!isFixed !== !!myTable.cols[rightKey[1]][rightKey[2]].fixed) { + $this.css('left', $cloneHead.position().left); + $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function (e) { + $(this).prev().css('left', $cloneHead.position().left); + }) + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function (e) { + $(this).prev().css('left', $cloneHead.position().left); + }) + } + $tableBox.addClass('no-left-border'); + return; + } + $this.css('left', left); + + if (leftMove) { + $cloneHead.after($leftTh); + + // 更新隐藏列顺序 + $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').after($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').prev()) + + // 更新配置信息 + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].key === curKey) { + x = i; + y = j; + break; + } + } + if (typeof x !== 'undefined' && typeof y !== 'undefined') { + break; + } + } + tempCols = myTable.cols[x][y - 1]; + myTable.cols[x][y - 1] = myTable.cols[x][y]; + myTable.cols[x][y] = tempCols; + _this.fixTableRemember(myTable); + } else if (rightMove) { + $cloneHead.prev().before($rightTh); + + // 更新隐藏列顺序 + $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').before($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').next()) + + // 更新配置信息 + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].key === curKey) { + x = i; + y = j; + break; + } + } + if (typeof x !== 'undefined' && typeof y !== 'undefined') { + break; + } + } + tempCols = myTable.cols[x][y + 1]; + myTable.cols[x][y + 1] = myTable.cols[x][y]; + myTable.cols[x][y] = tempCols; + _this.fixTableRemember(myTable); + } + + $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().css('left', left); + + if (leftMove) { + if ($(this).prev().prev().length !== 0) { + $(this).after($(this).prev().prev()); + } + } else if (rightMove) { + if ($(this).next().length !== 0) { + $(this).prev().before($(this).next()); + } + } + }) + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().css('left', left); + + if (leftMove) { + if ($(this).prev().prev().length !== 0) { + $(this).after($(this).prev().prev()); + } + } else if (rightMove) { + if ($(this).next().length !== 0) { + $(this).prev().before($(this).next()); + } + } + }) + } + + /* 拖动隐藏列 */ + if (e.clientY - originTop < -15) { + if ($('#column-remove').length === 0) { + _BODY.append('') + } + $('#column-remove').css({ + top: e.clientY - $('#column-remove').height() / 2, + left: e.clientX - $('#column-remove').width() / 2, + 'font-size': (originTop - e.clientY) + 'px' + }) + $('#column-remove').show(); + } else { + $('#column-remove').hide(); + } + } + }).on('mouseup', function () { + _DOC.unbind("selectstart"); + _BODY.off('mousemove').off('mouseup') + if (isStart && $cloneHead) { + isStart = false; + if (isDragging) { + if (curColumn.type !== 'checkbox') { + $that.on('click', function (e) { + e.stopPropagation(); + }); + } + + isDragging = false; + $tableBox.removeClass('no-left-border') + $this.removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'border-left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $this.next().remove(); + var prefKey = $this.prev().data('key'); + if (isFixed) { + var $noFixedTh = $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + key + '"]'); + if (prefKey) { + $noFixedTh.parent().children('th[data-key="' + prefKey + '"]').after($noFixedTh) + } else { + if (isFixed === 'right') { + if ($this.siblings().length > 0) { + $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + $this.next().data('key') + '"]').prev().after($noFixedTh); + } + } else { + $noFixedTh.parent().prepend(''); + $noFixedTh.parent().children('th:first').after($noFixedTh); + $noFixedTh.parent().children('th:first').remove(); + } + + } + } + if (isSimple) { + $tableBody.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + if ($this.siblings().length > 0) { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + } + } else if (isInFixed) { + $noFixedBody.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + if ($this.siblings().length > 0) { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + $fixedBody.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'border-left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + if ($totalTable.length > 0) { + $noFixedTotalTable.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + $fixedTotalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + } + } else { + $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + } + } + + $cloneHead = null; + + // 处理 toolbar 事件 + if (toolbar) { + if ($dragBar.children('.active').length > 0 && $dragBar.children('.active').attr('data-type') !== $dragBar.attr('data-type')) { + var targetFix = $dragBar.children('.active').attr('data-type'), + i, j, curPos, targetPos; + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if (targetFix === 'right' || (targetFix === 'none' && $dragBar.attr('data-type') === 'right')) { + if (typeof targetPos === 'undefined') { + if (myTable.cols[i][j].fixed === 'right') { + targetPos = {x: i, y: j}; + } else if (j === myTable.cols[i].length - 1) { + targetPos = {x: i, y: j + 1}; + } + + } + } else { + if (typeof targetPos === 'undefined' && (!myTable.cols[i][j].fixed || myTable.cols[i][j].fixed === 'right')) { + targetPos = {x: i, y: j}; + } + } + if (myTable.cols[i][j].key === curKey) { + curPos = {x: i, y: j}; + } + } + } + curColumn['fixed'] = targetFix === 'none' ? false : targetFix; + + if (curPos.y !== targetPos.y) { + myTable.cols[curPos.x].splice(curPos.y, 1); + + if (curPos.y < targetPos.y) { + targetPos.y -= 1 + } + + myTable.cols[targetPos.x].splice(targetPos.y, 0, curColumn) + + _this.fixTableRemember(myTable); + } + table.reload(tableId) + } + $dragBar.removeClass('active') + } + + } else { + $that.unbind('click'); + } + if ($('#column-remove').is(':visible')) { + $tableHead.find('thead>tr>th[data-key=' + key + ']').addClass(HIDE); + $tableBody.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); + $totalTable.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); + // 同步配置 + curColumn['hide'] = true + _this.fixTableRemember(myTable); + // 更新下拉隐藏 + $('#soul-columns' + tableId).find('li[data-value="' + field + '"]>input').prop('checked', false); + tableFilter.resize(myTable) + } + $('#column-remove').hide(); + } + }) + }); + }) + } + }, + rowDrag: function (myTable, rowDragConfig) { + var _this = this, + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $noFixedBody = $tableBox.children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + tableId = myTable.id, + isDragging = false, + trigger = rowDragConfig.trigger || 'row', + syncNumber = rowDragConfig.numbers !== false, + numberColumnKey = null, numberStart = 0, + $trs = trigger === 'row' ? $tableBody.children('tbody').children('tr') : $tableBody.find(trigger), + i, j; + if (trigger !== 'row') { + $tableBody.find(trigger).css('cursor', 'move') + } + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].type === 'numbers') { + numberColumnKey = myTable.index + '-' + i + '-' + j; + numberStart = parseInt($noFixedBody.find('td[data-key="' + numberColumnKey + '"]:first').text()); + break; + } + } + } + $trs.on('mousedown', function (e) { + // 被暂停 或者 不是鼠标左键 则取消拖拽效果 + if (_this.suspendConfig[tableId].rowDrag || e.button !== 0) { + return; + } + var $this = trigger === 'row' ? $(this) : $(this).parents('tr:eq(0)'), + index = parseInt($this.data('index')), // 被拖拽行索引 + $bodyTr = $noFixedBody.children('tbody').children('tr[data-index=' + index + ']'), // 被拖拽行(非固定列) + $cloneTr = $bodyTr.clone().css('visibility', 'hidden'), // 占位行 + $FixBodyTr = $fixedBody.children('tbody').children('tr[data-index=' + index + ']'), // 被拖拽行(固定列) + bodyScrollTop = $tableBox.children('.layui-table-body').scrollTop(), // 记录当前滚动条位置 + originTop = $this.position().top, // 被拖拽行当前位置 + disY = e.clientY - originTop; // 鼠标距离被拖拽行上侧的距离 + + _BODY.on('mousemove', function (e) { + + // 刚被拖动 + if (!isDragging) { + isDragging = true; + // 设置鼠标样式 + // $table.next().find('style').append('.layui-table-view .layui-table td{cursor: move;}.layui-table tr{transition: none}') + var style = $table.next().find('style')[0], + sheet = style.sheet || style.styleSheet || {}; + _this.addCSSRule(sheet, '.layui-table-view .layui-table td', 'cursor: move') + _this.addCSSRule(sheet, '.layui-table tr', 'transition: none') + + $tableBox.addClass('noselect'); // 禁止选中文本 + + $bodyTr.after($cloneTr); + $bodyTr.css({ + 'position': 'absolute', + 'z-index': 1 + }) + + $FixBodyTr.each(function () { + $(this).after($(this).clone().css('visibility', 'hidden')) + $(this).css({ + 'position': 'absolute', + 'z-index': 102 + }) + }) + } + + var top = e.clientY - disY + ($tableBox.children('.layui-table-body').scrollTop() - bodyScrollTop), // 计算当前被移动行top位置应该哪里 + trTop = $cloneTr.position().top, //当前行所在位置 + $UpTr = $bodyTr.prev(), + hasUpTr = $UpTr.length > 0, + $downTr = $cloneTr.next(), + hasDownTr = $downTr.length > 0, + upMove = hasUpTr && (trTop - top > $UpTr.height() / 2.0), + downMove = hasDownTr && (top - trTop > $downTr.height() / 2.0); + + if (trTop - top > 0 ? !hasUpTr : !hasDownTr) { + $bodyTr.css('top', trTop); + $FixBodyTr.each(function () { + $(this).css('top', trTop); + }) + return; + } + + $bodyTr.css('top', top); + $FixBodyTr.each(function () { + $(this).css('top', top); + }) + + if (upMove) { + updateDataIndex($bodyTr, -1) + $cloneTr.after(updateDataIndex($UpTr, 1)); + $FixBodyTr.each(function () { + updateDataIndex($(this), -1) + $(this).next().after(updateDataIndex($(this).prev(), 1)); + }) + } else if (downMove) { + updateDataIndex($bodyTr, 1).before(updateDataIndex($downTr, -1)) + $FixBodyTr.each(function () { + updateDataIndex($(this), 1); + $(this).before(updateDataIndex($(this).next().next(), -1)); + }) + } + + // 同步 data-index + function updateDataIndex($el, diff) { + var tempIndex = parseInt($el.data('index')) + diff; + $el.data('index', tempIndex); + $el.attr('data-index', tempIndex); + return $el + } + + }).on('mouseup', function (e) { + _BODY.off('mousemove').off('mouseup'); + + if (isDragging) { + isDragging = false; + + $tableBox.removeClass('noselect'); // 取消禁止选中文本 + $bodyTr.css({'position': 'inherit', 'z-index': 'inherit'}); + $bodyTr.next().remove(); + $FixBodyTr.each(function () { + $(this).css({'position': 'inherit', 'z-index': 'inherit'}); + $(this).next().remove() + }) + + // 恢复样式 + var style = $table.next().find('style')[0], + sheet = style.sheet || style.styleSheet || {}, + rules = sheet.cssRules || sheet.rules; + layui.each(rules, function (i, item) { + if (item.selectorText === ('.layui-table-view .layui-table td')) { + item.style.cursor = 'default'; + } + }); + + var newIndex = $this.index(), + cache = table.cache[tableId]; + + if (newIndex !== index) { // 有位置变动 + // 如果 before 返回 false,则还原拖拽 + if (typeof rowDragConfig.before === 'function' + && rowDragConfig.before.call(myTable, { + row: cache[index], + newIndex: newIndex, + oldIndex: index, + cache: cache + }) === false) { + + // 同步 data-index + function updateDataIndex($el, setIndex) { + $el.data('index', setIndex); + $el.attr('data-index', setIndex); + return $el + } + + // 还原位置和索引 + if (newIndex < index) { + for (i = newIndex; i < index; i++) { + updateDataIndex($noFixedBody.find('tr[data-index="'+(i+1)+'"]'), i) + updateDataIndex($fixedBody.find('tr[data-index="'+(i+1)+'"]'), i) + } + updateDataIndex($bodyTr, index) + $noFixedBody.find('tr[data-index="'+(index - 1)+'"]').after($bodyTr) + $FixBodyTr.each(function () { + updateDataIndex($(this), index) + $(this).parent().children('tr[data-index="'+(index - 1)+'"]').after($(this)) + }) + } else { + for (i = newIndex; i > index; i--) { + updateDataIndex($noFixedBody.find('tr[data-index="'+(i-1)+'"]'), i) + updateDataIndex($fixedBody.find('tr[data-index="'+(i-1)+'"]'), i) + } + updateDataIndex($bodyTr, index) + $noFixedBody.find('tr[data-index="'+(index + 1)+'"]').before($bodyTr) + $FixBodyTr.each(function () { + updateDataIndex($(this), index) + $(this).parent().children('tr[data-index="'+(index + 1)+'"]').before($(this)) + }) + } + return; + } + + var row = cache.splice(index, 1)[0]; + cache.splice(newIndex, 0, row); + if (numberColumnKey && syncNumber) { + // 进行序号重排 + var sortedIndexs = [newIndex, index].sort() + for (i = sortedIndexs[0]; i <= sortedIndexs[1]; i++) { + var curIndex = numberStart + i; + $fixedBody.find('td[data-key="' + numberColumnKey + '"]:eq(' + i + ')').children().html(curIndex) + $noFixedBody.find('td[data-key="' + numberColumnKey + '"]:eq(' + i + ')').children().html(curIndex) + cache[i][table.config.indexName] = curIndex - 1 + } + } + if (typeof rowDragConfig.done === 'function') { + + rowDragConfig.done.call(myTable, { + row: row, + newIndex: newIndex, + oldIndex: index, + cache: cache + }) + } + } + + } + }) + }) + }, + fixTableRemember: function (myTable, dict) { + + if (typeof myTable.filter === 'undefined' ? (defaultConfig.filter && defaultConfig.filter.cache) : myTable.filter.cache) { + if (dict && dict.rule) { + var curKey = dict.rule.selectorText.split('-')[3] + '-' + dict.rule.selectorText.split('-')[4]; + for (var i = 0; i < myTable.cols.length; i++) { + for (var j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].key === curKey) { + myTable.cols[i][j].width = dict.rule.style.width.replace('px', ''); + break; + } + } + + } + } + var storeKey = location.pathname + location.hash + myTable.id; + localStorage.setItem(storeKey, this.deepStringify(myTable.cols)) + } + }, + clearCache: function (myTable) { + if (!myTable) { + return; + } + var tableId; + if (typeof myTable === 'object') { + if (typeof myTable.config !== 'undefined') { + tableId = myTable.config.id + } else { + tableId = myTable.id + } + } else { + tableId = myTable + } + localStorage.removeItem(location.pathname + location.hash + tableId) + if (originCols[tableId]) { + this.updateCols(tables[tableId], this.deepClone(originCols[tableId])) + } + }, + overflow: function (myTable, overflowConfig) { + var options = {}; + if (typeof overflowConfig === 'string') { + options = { + type: overflowConfig + } + } else if (typeof overflowConfig === 'object') { + options = overflowConfig + } else { + return; + } + var $table = $(myTable.elem), + layHeader = $table.next().find('.layui-table-header'), + layBody = $table.next().find('.layui-table-body'), + layTotal = $table.next().find('.layui-table-total'), + tooltipIndex, + hoverTime = options.hoverTime || 0, + tooltipTimeOut, + color = options.color || 'white', + bgColor = options.bgColor || 'black', + minWidth = options.minWidth || 300, + maxWidth = options.maxWidth || 300; + + if (options.type === 'tips') { + layBody.off('mouseenter', 'td').off('mouseleave', 'td').on('mouseenter', 'td', function () { + var _this = this; + tooltipTimeOut = setTimeout(function () { + toopTip.call(_this) + }, hoverTime) + }).on('mouseleave', 'td', function () { + toopTip.call(this, 'hide') + }) + if (options.header) { + layHeader.off('mouseenter', 'th').off('mouseleave', 'th').on('mouseenter', 'th', function () { + var _this = this; + tooltipTimeOut = setTimeout(function () { + toopTip.call(_this) + }, hoverTime) + }).on('mouseleave', 'th', function () { + toopTip.call(this, 'hide') + }) + } + if (options.total) { + layTotal.off('mouseenter', 'td').off('mouseleave', 'td').on('mouseenter', 'td', function () { + var _this = this; + tooltipTimeOut = setTimeout(function () { + toopTip.call(_this) + }, hoverTime) + }).on('mouseleave', 'td', function () { + toopTip.call(this, 'hide') + }) + } + + function toopTip(hide) { + clearTimeout(tooltipTimeOut); + var othis = $(this) + , elemCell = othis.children('.layui-table-cell') + , width = elemCell.outerWidth() + , layerWidth = width < minWidth ? minWidth : width > maxWidth ? maxWidth : width; + if (othis.data('off')) return; + + if (hide) { + layer.close(tooltipIndex) + } else if (elemCell.prop('scrollWidth') > width) { + tooltipIndex = layer.tips('' + $(this).text() + '', this, { + tips: [1, bgColor], + maxWidth: layerWidth, + time: 0 + }); + } + } + } else if (options.type === 'title') { + layBody.off('mouseenter', 'td').on('mouseenter', 'td', function () { + var othis = $(this) + , elemCell = othis.children('.layui-table-cell'); + if (othis.data('off')) return; + + if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { + elemCell.attr('title', $(this).text()) + } + }) + if (options.header) { + layHeader.off('mouseenter', 'th').on('mouseenter', 'th', function () { + var othis = $(this) + , elemCell = othis.children('.layui-table-cell'); + if (othis.data('off')) return; + + if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { + elemCell.attr('title', $(this).text()) + } + }) + } + if (options.total) { + layTotal.off('mouseenter', 'td').on('mouseenter', 'td', function () { + var othis = $(this) + , elemCell = othis.children('.layui-table-cell'); + if (othis.data('off')) return; + + if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { + elemCell.attr('title', $(this).text()) + } + }) + } + } + + }, + // 右键菜单配置 + contextmenu: function (myTable, contextmenuConfig) { + var $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + $totalTable = $table.next().children('.layui-table-total').children('table'), + tableId = myTable.id, + header = contextmenuConfig ? contextmenuConfig.header : '', + body = contextmenuConfig ? contextmenuConfig.body : '', + total = contextmenuConfig ? contextmenuConfig.total : '', + options = { + header: {box: $tableHead, tag: 'th', opts: header, cols: {}}, + body: {box: $tableBody, tag: 'td', opts: body, cols: {}, isBody: true}, + total: {box: $totalTable, tag: 'td', opts: total, cols: {}} + }, + hasColsContext = false; + + for (var i = 0; i < myTable.cols.length; i++) { + for (var j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].contextmenu) { + hasColsContext = true + options.header.cols[myTable.cols[i][j].key] = myTable.cols[i][j].contextmenu.header + options.body.cols[myTable.cols[i][j].key] = myTable.cols[i][j].contextmenu.body + options.total.cols[myTable.cols[i][j].key] = myTable.cols[i][j].contextmenu.total + } + } + } + + if (!contextmenuConfig && !hasColsContext) { + return; + } + + + for (var name in options) { + (function (name) { + options[name].box.find(options[name].tag).on('contextmenu', function (e) { + $('#soul-table-contextmenu-wrapper').remove(); + _BODY.append('
'); + $('#soul-table-contextmenu-wrapper').on('click', function (e) { + e.stopPropagation() + }) + var curColsOpts = options[name].cols[$(this).data('key')]; + if (curColsOpts === false) { + return false + } else if (curColsOpts && curColsOpts.length > 0) { + genePanel($('#soul-table-contextmenu-wrapper'), e.pageX, e.pageY, curColsOpts, $(this), options[name].box, options[name].tag, options[name].isBody); + return false + } else if (options[name].opts === false) { + return false + } else if (options[name].opts && options[name].opts.length > 0) { + genePanel($('#soul-table-contextmenu-wrapper'), e.pageX, e.pageY, options[name].opts, $(this), options[name].box, options[name].tag, options[name].isBody); + return false + } + }) + })(name) + } + + + _BODY.on('click', function () { + $('#soul-table-contextmenu-wrapper').remove(); + }) + + function genePanel($parent, left, top, options, $this, box, tag, isBody) { + var html = [], i; + + html.push('
    '); + for (i = 0; i < options.length; i++) { + html.push('
  • ') + if (options[i].icon) { + html.push('') + } else { + html.push('') + } + html.push(options[i].name) + + if (options[i].children && options[i].children.length > 0) { + html.push('') + } + + html.push('
  • ') + } + html.push('
'); + $parent.append(html.join('')); + var $curPanel = $parent.children().last(); + if (top + $curPanel.outerHeight() > _BODY.prop('scrollHeight')) { + top = top - $curPanel.outerHeight() + if (top < 0) { + top = 0 + } + } + if ($parent.parent().data('direction') === 'left' && ($parent.offset().left - $curPanel.outerWidth()) > 0) { + left = -$curPanel.outerWidth(); + $curPanel.data('direction', 'left') + } else if (left + $curPanel.outerWidth() + $parent.offset().left > _BODY.prop('scrollWidth')) { + left = left - $curPanel.outerWidth() - $parent.outerWidth() + if (left + $parent.offset().left < 0) { + left = -$parent.offset().left + } + $curPanel.data('direction', 'left') + } + $curPanel.css({ + top: top + 'px', + left: left + 'px' + }) + + for (i = 0; i < options.length; i++) { + if (typeof options[i].click === "function") { + (function (i) { + $parent.children('.soul-table-contextmenu:last').children('li[data-index="' + i + '"]').on('click', function () { + var index = $this.parents('tr:eq(0)').data('index'), + tr = box.find('tr[data-index="' + index + '"]'), + row = layui.table.cache[tableId][index]; + + options[i].click.call(myTable, { + cell: $this, + elem: tag === 'th' ? $this : isBody ? box.children('tbody').children('tr[data-index="' + index + '"]').children('[data-key="' + $this.data('key') + '"]') : box.find('[data-key="' + $this.data('key') + '"]'), + trElem: box.children('tbody').children('tr[data-index="' + index + '"]'), + text: $this.text(), + field: $this.data('field'), + del: !isBody ? '' : function () { + table.cache[tableId][index] = []; + tr.remove(); + table.resize(tableId); + }, + update: !isBody ? '' : function (fields) { + fields = fields || {}; + layui.each(fields, function (key, value) { + if (key in row) { + var templet, td = tr.children('td[data-field="' + key + '"]'); + row[key] = value; + table.eachCols(tableId, function (i, item2) { + if (item2.field == key && item2.templet) { + templet = item2.templet; + } + }); + td.children('.layui-table-cell').html(function () { + return templet ? function () { + return typeof templet === 'function' + ? templet(row) + : layui.laytpl($(templet).html() || value).render(row) + }() : value; + }()); + td.data('content', value); + } + }); + }, + row: isBody ? row : {}, + }) + $('#soul-table-contextmenu-wrapper').remove(); + }) + })(i) + } + } + $parent.children('.soul-table-contextmenu:last').children('li').on('mouseenter', function (e) { + e.stopPropagation() + $(this).siblings('.contextmenu-children').children('ul').remove(); + if ($(this).hasClass('contextmenu-children')) { + genePanel($(this), $(this).outerWidth(), $(this).position().top, options[$(this).data('index')].children, $this, box, tag, isBody) + } + }) + } + + }, + fixTotal: function (myTable) { + var $table = $(myTable.elem), + $total = $table.next().children('.layui-table-total'), + style = $table.next().find('style')[0], + sheet = style.sheet || style.styleSheet || {}; + if ($total.length > 0) { + var $tableBox = $table.next().children('.layui-table-box'), + $fixedLeft = $tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), + $fixedRight = $tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), + html = []; + + $total.children('.layui-table-total-fixed').remove() + + if ($fixedLeft.length > 0) { + this.addCSSRule(sheet, '.layui-table-total-fixed-l .layui-table-patch', 'display: none') + $table.next().css('position', 'relative'); + html.push(''); + $fixedLeft.each(function () { + if ($(this).data('key')) { + html.push($total.children('table:eq(0)').find('[data-key="' + $(this).data('key') + '"]').prop("outerHTML")) + } + }) + html.push('
'); + $total.append(html.join('')) + } + if ($fixedRight.length > 0) { + this.addCSSRule(sheet, '.layui-table-total-fixed-r td:first-child', 'border-left:1px solid #e6e6e6') + this.addCSSRule(sheet, '.layui-table-total-fixed-r td:last-child', 'border-left: none') + $table.next().css('position', 'relative'); + html = []; + html.push(''); + $fixedRight.each(function () { + html.push($total.children('table:eq(0)').find('[data-key="' + $(this).data('key') + '"]').prop("outerHTML")) + }) + html.push('
') + $total.append(html.join('')) + } + } + + }, + fixResizeRightFixed: function (myTable) { + var _this = this, + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $fixedHead = $tableBox.children('.layui-table-fixed-r').children('.layui-table-header').children('table'), + dict = {}, resizing, ELEM_SORT = 'layui-table-sort', + ELEM_NO_SORT = 'layui-table-sort-invalid'; + if ($fixedHead.length > 0) { + $fixedHead.find('th').off('mousemove').on('mousemove', function (e) { + var othis = $(this) + , oLeft = othis.offset().left + , pLeft = e.clientX - oLeft; + if (othis.data('unresize') || dict.resizeStart) { + return; + } + if (othis.width() - pLeft <= 10) { + _BODY.css('cursor', 'initial') + } + dict.allowResize = pLeft <= 10; //是否处于拖拽允许区域 + _BODY.css('cursor', (dict.allowResize ? 'col-resize' : '')); + }).off('mousedown').on('mousedown', function (e) { + var othis = $(this); + if (dict.allowResize) { + othis.find('.' + ELEM_SORT).removeClass(ELEM_SORT).addClass(ELEM_NO_SORT) + var key = othis.data('key'); + e.preventDefault(); + dict.resizeStart = true; //开始拖拽 + dict.offset = [e.clientX, e.clientY]; //记录初始坐标 + + _this.getCssRule(myTable, key, function (item) { + var width = item.style.width || othis.outerWidth(); + dict.rule = item; + dict.ruleWidth = parseFloat(width); + dict.othis = othis; + dict.minWidth = othis.data('minwidth') || myTable.cellMinWidth; + }); + } + }); + //拖拽中 + _DOC.on('mousemove', function (e) { + if (dict.resizeStart) { + layui.soulTable.fixTableRemember(myTable, dict) + e.preventDefault(); + if (dict.rule) { + var setWidth = dict.ruleWidth - e.clientX + dict.offset[0]; + if (setWidth < dict.minWidth) setWidth = dict.minWidth; + dict.rule.style.width = setWidth + 'px'; + } + resizing = 1 + } + }).on('mouseup', function (e) { + if (dict.resizeStart) { + setTimeout(function () { + dict.othis.find('.' + ELEM_NO_SORT).removeClass(ELEM_NO_SORT).addClass(ELEM_SORT) + _BODY.css('cursor', ''); + dict = {}; + _this.scrollPatch(myTable); + }, 30) + } + if (resizing === 2) { + resizing = null; + } + }); + } + }, + fixFixedScroll: function (myTable) { + var $table = $(myTable.elem), + layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), + layMain = $table.next().children('.layui-table-box').children('.layui-table-main'); + + layFixed.on('mouseenter', function () { + $(this).children('.layui-table-body').addClass('soul-fixed-scroll').on('scroll', function () { + var scrollTop = $(this).scrollTop() + // layFixed.children('.layui-table-body[class!="soul-fixed-scroll"]').scrollTop(scrollTop); + layMain.scrollTop(scrollTop); + }) + }).on('mouseleave', function () { + $(this).children('.layui-table-body').removeClass('soul-fixed-scroll').off('scroll'); + }) + }, + scrollPatch: function (myTable) { + var $table = $(myTable.elem), + layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'), + layTotal = $table.next().children('.layui-table-total'), + layMain = $table.next().children('.layui-table-box').children('.layui-table-main'), + layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), + layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'), + layMainTable = layMain.children('table'), + scollWidth = layMain.width() - layMain.prop('clientWidth'), + scollHeight = layMain.height() - layMain.prop('clientHeight'), + outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度 + + //添加补丁 + , addPatch = function (elem) { + if (scollWidth && scollHeight) { + elem = elem.eq(0); + if (!elem.find('.layui-table-patch')[0]) { + var patchElem = $('
'); //补丁元素 + patchElem.find('div').css({ + width: scollWidth + }); + elem.find('tr').append(patchElem); + } + } else { + elem.find('.layui-table-patch').remove(); + } + } + + addPatch(layHeader); + addPatch(layTotal); + + //固定列区域高度 + var mainHeight = layMain.height() + , fixHeight = mainHeight - scollHeight; + layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto'); + + //表格宽度小于容器宽度时,隐藏固定列 + layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE); + + //操作栏 + layFixRight.css('right', scollWidth - 1); + }, + /** + * 一键粘贴 + * @param {String} text [需要 copy 的属性,默认是 innerText,主要用途例如赋值 a 标签上的 href 链接] + * + * range + selection + * + * 1.创建一个 range + * 2.把内容放入 range + * 3.把 range 放入 selection + * + * 注意:参数 attr 不能是自定义属性 + * 注意:对于 user-select: none 的元素无效 + * 注意:当 id 为 false 且 attr 不会空,会直接复制 attr 的内容 + */ + copy: function (text) { + var target; + + if (text) { + target = document.createElement('div'); + target.id = 'tempTarget'; + target.style.opacity = '0'; + target.innerText = text; + document.body.appendChild(target); + } else { + target = document.querySelector('#' + id); + } + + try { + var range = document.createRange(); + range.selectNode(target); + window.getSelection().removeAllRanges(); + window.getSelection().addRange(range); + document.execCommand('copy'); + window.getSelection().removeAllRanges(); + } catch (e) { + console.log('复制失败') + } + + if (text) { + // remove temp target + target.parentElement.removeChild(target); + } + }, + addCSSRule: function (sheet, selector, rules, index) { + if ('insertRule' in sheet) { + sheet.insertRule(selector + '{' + rules + '}', index) + } else if ('addRule' in sheet) { + sheet.addRule(selector, rules, index) + } + }, + deepStringify: function (obj) { + var JSON_SERIALIZE_FIX = { + PREFIX: "[[JSON_FUN_PREFIX_", + SUFFIX: "_JSON_FUN_SUFFIX]]" + }; + return JSON.stringify(obj, function (key, value) { + if (typeof value === 'function') { + return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX; + } + return value; + }); + }, + deepParse: function (str) { + var JSON_SERIALIZE_FIX = { + PREFIX: "[[JSON_FUN_PREFIX_", + SUFFIX: "_JSON_FUN_SUFFIX]]" + }; + return JSON.parse(str, function (key, value) { + if (typeof value === 'string' && + value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) { + return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")"); + } + return value; + }) || {}; + }, + clearFilter: function (myTable) { + tableFilter.clearFilter(myTable); + }, + cache: tableFilter.cache, + // 深度克隆-不丢失方法 + deepClone: function (obj) { + var newObj = Array.isArray(obj) ? [] : {} + if (obj && typeof obj === "object") { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key]; + } + } + } + return newObj + }, + clearOriginCols: function (tableId) { + if (tableId) { + delete originCols[tableId] + } else { + originCols = {} + } + }, + suspendConfig: {}, + /** + * 暂停某个特性 + * @param tableId + * @param type 暂停的类型,支持 'drag' 'rowDrag' + * @param value true/false + */ + suspend: function (tableId, type, value) { + this.suspendConfig[tableId][type] = value + } + } + + // 输出 + exports('soulTable', mod); }); diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.slim.js b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.slim.js index 1ab920a..93cfb88 100644 --- a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.slim.js +++ b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/soulTable.slim.js @@ -4,28 +4,28 @@ * @author: yelog * @link: https://github.com/yelog/layui-soul-table * @license: MIT - * @version: v1.6.1 + * @version: v1.9.0 */ layui.define(['table'], function (exports) { var $ = layui.$, - table = layui.table, - HIDE = 'layui-hide', - tables = {}, - originCols = {}, - defaultConfig = { // 默认配置开关 - fixTotal: false, // 修复合计行固定列问题 - drag: true, // 列拖动 - rowDrag: false, // 行拖动 - autoColumnWidth: true, // 自动列宽 - contextmenu: false, // 右键菜单 - fixResize: true, // 修改有固定列的拖动列宽的位置为左边线 - overflow: false, // 自定义内容超出样式 - fixFixedScroll: true, // 固定列支持鼠标滚轮滚动 - filter: false // 筛选及记忆相关 - }, - _BODY = $('body'), - _DOC = $(document); + table = layui.table, + HIDE = 'layui-hide', + tables = {}, + originCols = {}, + defaultConfig = { // 默认配置开关 + fixTotal: false, // 修复合计行固定列问题 + drag: true, // 列拖动 + rowDrag: false, // 行拖动 + autoColumnWidth: true, // 自动列宽 + contextmenu: false, // 右键菜单 + fixResize: true, // 修改有固定列的拖动列宽的位置为左边线 + overflow: false, // 自定义内容超出样式 + fixFixedScroll: true, // 固定列支持鼠标滚轮滚动 + filter: false // 筛选及记忆相关 + }, + _BODY = $('body'), + _DOC = $(document); // 封装方法 var mod = { @@ -92,14 +92,14 @@ layui.define(['table'], function (exports) { } , updateCols: function (myTable, cols) { var i, j, lastKeyMap = {}, columnKey, newCols = [], col = [], - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $fixedHead = $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table'), - $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $fixedHead), - $noFixedHead = $tableBox.children('.layui-table-header').children('table'), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $noFixedBody = $tableBox.children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody); + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $fixedHead = $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table'), + $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $fixedHead), + $noFixedHead = $tableBox.children('.layui-table-header').children('table'), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $noFixedBody = $tableBox.children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody); for (i = 0; i < myTable.cols.length; i++) { for (j = 0; j < myTable.cols[i].length; j++) { @@ -111,7 +111,7 @@ layui.define(['table'], function (exports) { for (i = 0; i < cols.length; i++) { col = [] for (j = 0; j < cols[i].length; j++) { - columnKey = myTable.index + '-' + cols[i][j].key; + columnKey = cols[i][j].key; // 同步列宽 if (cols[i][j].width && lastKeyMap[cols[i][j].key] !== cols[i][j].width) { this.getCssRule(myTable, columnKey, function (item) { @@ -126,11 +126,11 @@ layui.define(['table'], function (exports) { // 同步顺序 if (lastKeyMap[cols[i][j].key].oldPos !== (i + '-' + j) || lastKeyMap[cols[i][j].key].fixed !== cols[i][j].fixed) { - if (cols[i][j].fixed !== lastKeyMap[cols[i][j].key].fixed) { - myTable.cols = cols; - table.reload(myTable.id) - return; - } + myTable.cols = cols; + table.reload(myTable.id) + return; + // 实现不 reload 调整列顺序 + } lastKeyMap[cols[i][j].key].fixed = cols[i][j].fixed; lastKeyMap[cols[i][j].key].width = cols[i][j].width; @@ -167,8 +167,8 @@ layui.define(['table'], function (exports) { } , getCssRule: function (that, key, callback) { var style = that.elem.next().find('style')[0] - , sheet = style.sheet || style.styleSheet || {} - , rules = sheet.cssRules || sheet.rules; + , sheet = style.sheet || style.styleSheet || {} + , rules = sheet.cssRules || sheet.rules; layui.each(rules, function (i, item) { if (item.selectorText === ('.laytable-cell-' + key)) { return callback(item), true; @@ -189,22 +189,22 @@ layui.define(['table'], function (exports) { function innerColumnWidth(_this, myTable) { var $table = $(myTable.elem), - th = $table.next().children('.layui-table-box').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), - fixTh = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), - $tableBodytr = $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr'), - $totalTr = $table.next().children('.layui-table-total').find('tr'); + th = $table.next().children('.layui-table-box').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), + fixTh = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-header').children('table').children('thead').children('tr').children('th'), + $tableBodytr = $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr'), + $totalTr = $table.next().children('.layui-table-total').find('tr'); String.prototype.width = function (font) { var f = font || _BODY.css('font'), - o = $('
' + this + '
') - .css({ - 'position': 'absolute', - 'float': 'left', - 'white-space': 'nowrap', - 'visibility': 'hidden', - 'font': f - }) - .appendTo(_BODY), - w = o.width(); + o = $('
' + this + '
') + .css({ + 'position': 'absolute', + 'float': 'left', + 'white-space': 'nowrap', + 'visibility': 'hidden', + 'font': f + }) + .appendTo(_BODY), + w = o.width(); o.remove(); return w; @@ -212,7 +212,7 @@ layui.define(['table'], function (exports) { if (typeof autoColumnWidthConfig === 'undefined' || typeof autoColumnWidthConfig.dblclick === 'undefined' || autoColumnWidthConfig.dblclick) { th.add(fixTh).on('dblclick', function (e) { var othis = $(this), - pLeft = e.clientX - othis.offset().left; + pLeft = e.clientX - othis.offset().left; handleColumnWidth(myTable, othis, othis.parents('.layui-table-fixed-r').length > 0 ? pLeft <= 10 : othis.width() - pLeft <= 10); }) } @@ -228,8 +228,6 @@ layui.define(['table'], function (exports) { function handleColumnWidth(myTable, othis, isHandle) { var key = othis.data('key') - , keyArray = key.split('-') - , curKey = keyArray.length === 3 ? keyArray[1] + '-' + keyArray[2] : '' if (othis.attr('colspan') > 1 || othis.data('unresize')) { return; } @@ -263,7 +261,7 @@ layui.define(['table'], function (exports) { }); for (var i = 0; i < myTable.cols.length; i++) { for (var j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].key === curKey) { + if (myTable.cols[i][j].key === key) { myTable.cols[i][j].width = maxWidth; break; } @@ -283,19 +281,19 @@ layui.define(['table'], function (exports) { return; } var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $noFixedBody = $tableBox.children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - $totalTable = $table.next().children('.layui-table-total').children('table'), - $fixedTotalTable = $table.next().children('.layui-table-total').children('table.layui-table-total-fixed'), - $noFixedTotalTable = $table.next().children('.layui-table-total').children('table:eq(0)'), - tableId = myTable.id, - isSimple = dragConfig === 'simple' || (dragConfig && dragConfig.type === 'simple'), // 是否为简易拖拽 - toolbar = dragConfig && dragConfig.toolbar, // 是否开启工具栏 - isDragging = false, isStart = false; + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $noFixedBody = $tableBox.children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + $totalTable = $table.next().children('.layui-table-total').children('table'), + $fixedTotalTable = $table.next().children('.layui-table-total').children('table.layui-table-total-fixed'), + $noFixedTotalTable = $table.next().children('.layui-table-total').children('table:eq(0)'), + tableId = myTable.id, + isSimple = dragConfig === 'simple' || (dragConfig && dragConfig.type === 'simple'), // 是否为简易拖拽 + toolbar = dragConfig && dragConfig.toolbar, // 是否开启工具栏 + isDragging = false, isStart = false; if (!$tableHead.attr('drag')) { $tableHead.attr('drag', true); @@ -311,466 +309,466 @@ layui.define(['table'], function (exports) { $tableHead.find('th').each(function () { var $this = $(this), - field = $this.data('field'), - key = $this.data('key'); + field = $this.data('field'), + key = $this.data('key'); if (!key) { return; } var keyArray = key.split('-'), - curColumn = myTable.cols[keyArray[1]][keyArray[2]], - curKey = keyArray[1] + '-' + keyArray[2], - isInFixed = $this.parents('.layui-table-fixed').length > 0; + curColumn = myTable.cols[keyArray[1]][keyArray[2]], + curKey = myTable.index + '-' + keyArray[1] + '-' + keyArray[2], + isInFixed = $this.parents('.layui-table-fixed').length > 0; // 绑定鼠标按下事件 $(this).find('span:first,.laytable-cell-checkbox') - .css('cursor', 'move') - .on('mousedown', function (e) { - // 暂停或者非鼠标左键都不执行 - if (_this.suspendConfig[tableId].drag || e.button !== 0) { - return; - } - e.preventDefault(); - var $cloneHead = $this.clone().css('visibility', 'hidden'), - originLeft = $this.position().left, - originTop = $this.offset().top, - disX = e.clientX - originLeft, // 鼠标距离被移动元素左侧的距离 - color = $this.parents('tr:eq(0)').css("background-color"), - width = $this.width(), moveDistince = 0, - $that = $(this), - isFixed = curColumn.fixed; - isStart = true; - //区分click、drag事件 + .css('cursor', 'move') + .on('mousedown', function (e) { + // 暂停或者非鼠标左键都不执行 + if (_this.suspendConfig[tableId].drag || e.button !== 0) { + return; + } + e.preventDefault(); + var $cloneHead = $this.clone().css('visibility', 'hidden'), + originLeft = $this.position().left, + originTop = $this.offset().top, + disX = e.clientX - originLeft, // 鼠标距离被移动元素左侧的距离 + color = $this.parents('tr:eq(0)').css("background-color"), + width = $this.width(), moveDistince = 0, + $that = $(this), + isFixed = curColumn.fixed; + isStart = true; + //区分click、drag事件 - // 阻止文本选中 - _DOC.bind("selectstart", function () { - return false; - }); + // 阻止文本选中 + _DOC.bind("selectstart", function () { + return false; + }); - // 移动事件 - _BODY.on('mousemove', function (e) { - if (isStart && $cloneHead) { - $tableBox.removeClass('no-left-border'); - if (!isDragging) { - if (toolbar) { - $dragBar.attr('data-type', isFixed || 'none') - $dragBar.addClass('active') - } + // 移动事件 + _BODY.on('mousemove', function (e) { + if (isStart && $cloneHead) { + $tableBox.removeClass('no-left-border'); + if (!isDragging) { + if (toolbar) { + $dragBar.attr('data-type', isFixed || 'none') + $dragBar.addClass('active') + } - $this.after($cloneHead); - $this.addClass('isDrag').css({ - 'position': 'absolute', - 'z-index': 1, - 'border-left': '1px solid #e6e6e6', - 'background-color': color, - 'width': width + 1 - }); + $this.after($cloneHead); + $this.addClass('isDrag').css({ + 'position': 'absolute', + 'z-index': 1, + 'border-left': '1px solid #e6e6e6', + 'background-color': color, + 'width': width + 1 + }); - if (isSimple) { - //设置蒙板 - } else { - (isInFixed ? $fixedBody : $tableBody).find('td[data-key="' + key + '"]').each(function () { - $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); - $(this).addClass('isDrag').css({ - 'position': 'absolute', - 'z-index': 1, - 'border-left': '1px solid #e6e6e6', - 'background-color': $(this).css('background-color'), - 'width': width + 1 - }); - }) - if ($totalTable.length > 0) { - (isInFixed ? $fixedTotalTable : $totalTable).find('td[data-key="' + key + '"]').each(function () { - $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); - $(this).addClass('isDrag').css({ - 'position': 'absolute', - 'z-index': 1, - 'background-color': $(this).parents('tr:eq(0)').css('background-color'), - 'width': width + 1 - }); - }) - } - } - } - isDragging = true; - var x, y, i, j, tempCols, - left = e.clientX - disX, // 计算当前被移动列左侧位置应该哪里 - $leftTh = $cloneHead.prev().prev(), - hasLeftTh = $leftTh.length > 0, - leftKey = hasLeftTh ? $leftTh.data('key').split('-') : [], - $rightTh = $cloneHead.next().hasClass('layui-table-patch') ? [] : $cloneHead.next(), - hasRightTh = $rightTh.length > 0, - rightKey = hasRightTh ? $rightTh.data('key').split('-') : [], - leftMove = hasLeftTh && ($cloneHead.position().left - left > $leftTh.width() / 2.0), - rightMove = hasRightTh && (left - $cloneHead.position().left > $rightTh.width() / 2.0); - moveDistince = Math.abs($cloneHead.position().left - left); //记录移动距离 - // 移动到左右两端、checbox/radio 固定列等停止移动 - if ($cloneHead.position().left - left > 0 - ? !hasLeftTh || !!isFixed !== !!myTable.cols[leftKey[1]][leftKey[2]].fixed - : !hasRightTh || !!isFixed !== !!myTable.cols[rightKey[1]][rightKey[2]].fixed) { - $this.css('left', $cloneHead.position().left); - $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function (e) { - $(this).prev().css('left', $cloneHead.position().left); - }) - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function (e) { - $(this).prev().css('left', $cloneHead.position().left); - }) - } - $tableBox.addClass('no-left-border'); - return; - } - $this.css('left', left); + if (isSimple) { + //设置蒙板 + } else { + (isInFixed ? $fixedBody : $tableBody).find('td[data-key="' + key + '"]').each(function () { + $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); + $(this).addClass('isDrag').css({ + 'position': 'absolute', + 'z-index': 1, + 'border-left': '1px solid #e6e6e6', + 'background-color': $(this).css('background-color'), + 'width': width + 1 + }); + }) + if ($totalTable.length > 0) { + (isInFixed ? $fixedTotalTable : $totalTable).find('td[data-key="' + key + '"]').each(function () { + $(this).after($(this).clone().css('visibility', 'hidden').attr('data-clone', '')); + $(this).addClass('isDrag').css({ + 'position': 'absolute', + 'z-index': 1, + 'background-color': $(this).parents('tr:eq(0)').css('background-color'), + 'width': width + 1 + }); + }) + } + } + } + isDragging = true; + var x, y, i, j, tempCols, + left = e.clientX - disX, // 计算当前被移动列左侧位置应该哪里 + $leftTh = $cloneHead.prev().prev(), + hasLeftTh = $leftTh.length > 0, + leftKey = hasLeftTh ? $leftTh.data('key').split('-') : [], + $rightTh = $cloneHead.next().hasClass('layui-table-patch') ? [] : $cloneHead.next(), + hasRightTh = $rightTh.length > 0, + rightKey = hasRightTh ? $rightTh.data('key').split('-') : [], + leftMove = hasLeftTh && ($cloneHead.position().left - left > $leftTh.width() / 2.0), + rightMove = hasRightTh && (left - $cloneHead.position().left > $rightTh.width() / 2.0); + moveDistince = Math.abs($cloneHead.position().left - left); //记录移动距离 + // 移动到左右两端、checbox/radio 固定列等停止移动 + if ($cloneHead.position().left - left > 0 + ? !hasLeftTh || !!isFixed !== !!myTable.cols[leftKey[1]][leftKey[2]].fixed + : !hasRightTh || !!isFixed !== !!myTable.cols[rightKey[1]][rightKey[2]].fixed) { + $this.css('left', $cloneHead.position().left); + $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function (e) { + $(this).prev().css('left', $cloneHead.position().left); + }) + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function (e) { + $(this).prev().css('left', $cloneHead.position().left); + }) + } + $tableBox.addClass('no-left-border'); + return; + } + $this.css('left', left); - if (leftMove) { - $cloneHead.after($leftTh); + if (leftMove) { + $cloneHead.after($leftTh); - // 更新隐藏列顺序 - $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').after($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').prev()) + // 更新隐藏列顺序 + $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').after($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').prev()) - // 更新配置信息 - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].key === curKey) { - x = i; - y = j; - break; - } - } - if (typeof x !== 'undefined' && typeof y !== 'undefined') { - break; - } - } - tempCols = myTable.cols[x][y - 1]; - myTable.cols[x][y - 1] = myTable.cols[x][y]; - myTable.cols[x][y] = tempCols; - _this.fixTableRemember(myTable); - } else if (rightMove) { - $cloneHead.prev().before($rightTh); + // 更新配置信息 + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].key === curKey) { + x = i; + y = j; + break; + } + } + if (typeof x !== 'undefined' && typeof y !== 'undefined') { + break; + } + } + tempCols = myTable.cols[x][y - 1]; + myTable.cols[x][y - 1] = myTable.cols[x][y]; + myTable.cols[x][y] = tempCols; + _this.fixTableRemember(myTable); + } else if (rightMove) { + $cloneHead.prev().before($rightTh); - // 更新隐藏列顺序 - $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').before($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').next()) + // 更新隐藏列顺序 + $('#soul-columns' + tableId + '>li[data-value="' + field + '"]').before($('#soul-columns' + tableId + '>li[data-value="' + field + '"]').next()) - // 更新配置信息 - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if (myTable.cols[i][j].key === curKey) { - x = i; - y = j; - break; - } - } - if (typeof x !== 'undefined' && typeof y !== 'undefined') { - break; - } - } - tempCols = myTable.cols[x][y + 1]; - myTable.cols[x][y + 1] = myTable.cols[x][y]; - myTable.cols[x][y] = tempCols; - _this.fixTableRemember(myTable); - } + // 更新配置信息 + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if (myTable.cols[i][j].key === curKey) { + x = i; + y = j; + break; + } + } + if (typeof x !== 'undefined' && typeof y !== 'undefined') { + break; + } + } + tempCols = myTable.cols[x][y + 1]; + myTable.cols[x][y + 1] = myTable.cols[x][y]; + myTable.cols[x][y] = tempCols; + _this.fixTableRemember(myTable); + } - $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().css('left', left); + $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().css('left', left); - if (leftMove) { - if ($(this).prev().prev().length !== 0) { - $(this).after($(this).prev().prev()); - } - } else if (rightMove) { - if ($(this).next().length !== 0) { - $(this).prev().before($(this).next()); - } - } - }) - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().css('left', left); + if (leftMove) { + if ($(this).prev().prev().length !== 0) { + $(this).after($(this).prev().prev()); + } + } else if (rightMove) { + if ($(this).next().length !== 0) { + $(this).prev().before($(this).next()); + } + } + }) + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().css('left', left); - if (leftMove) { - if ($(this).prev().prev().length !== 0) { - $(this).after($(this).prev().prev()); - } - } else if (rightMove) { - if ($(this).next().length !== 0) { - $(this).prev().before($(this).next()); - } - } - }) - } + if (leftMove) { + if ($(this).prev().prev().length !== 0) { + $(this).after($(this).prev().prev()); + } + } else if (rightMove) { + if ($(this).next().length !== 0) { + $(this).prev().before($(this).next()); + } + } + }) + } - /* 拖动隐藏列 */ - if (e.clientY - originTop < -15) { - if ($('#column-remove').length === 0) { - _BODY.append('') - } - $('#column-remove').css({ - top: e.clientY - $('#column-remove').height() / 2, - left: e.clientX - $('#column-remove').width() / 2, - 'font-size': (originTop - e.clientY) + 'px' - }) - $('#column-remove').show(); - } else { - $('#column-remove').hide(); - } - } - }).on('mouseup', function () { - _DOC.unbind("selectstart"); - _BODY.off('mousemove').off('mouseup') - if (isStart && $cloneHead) { - isStart = false; - if (isDragging) { - if (curColumn.type !== 'checkbox') { - $that.on('click', function (e) { - e.stopPropagation(); - }); - } + /* 拖动隐藏列 */ + if (e.clientY - originTop < -15) { + if ($('#column-remove').length === 0) { + _BODY.append('') + } + $('#column-remove').css({ + top: e.clientY - $('#column-remove').height() / 2, + left: e.clientX - $('#column-remove').width() / 2, + 'font-size': (originTop - e.clientY) + 'px' + }) + $('#column-remove').show(); + } else { + $('#column-remove').hide(); + } + } + }).on('mouseup', function () { + _DOC.unbind("selectstart"); + _BODY.off('mousemove').off('mouseup') + if (isStart && $cloneHead) { + isStart = false; + if (isDragging) { + if (curColumn.type !== 'checkbox') { + $that.on('click', function (e) { + e.stopPropagation(); + }); + } - isDragging = false; - $tableBox.removeClass('no-left-border') - $this.removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'border-left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $this.next().remove(); - var prefKey = $this.prev().data('key'); - if (isFixed) { - var $noFixedTh = $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + key + '"]'); - if (prefKey) { - $noFixedTh.parent().children('th[data-key="' + prefKey + '"]').after($noFixedTh) - } else { - if (isFixed === 'right') { - if ($this.siblings().length > 0) { - $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + $this.next().data('key') + '"]').prev().after($noFixedTh); - } - } else { - $noFixedTh.parent().prepend(''); - $noFixedTh.parent().children('th:first').after($noFixedTh); - $noFixedTh.parent().children('th:first').remove(); - } + isDragging = false; + $tableBox.removeClass('no-left-border') + $this.removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'border-left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $this.next().remove(); + var prefKey = $this.prev().data('key'); + if (isFixed) { + var $noFixedTh = $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + key + '"]'); + if (prefKey) { + $noFixedTh.parent().children('th[data-key="' + prefKey + '"]').after($noFixedTh) + } else { + if (isFixed === 'right') { + if ($this.siblings().length > 0) { + $tableBox.children('.layui-table-header').children('table').find('th[data-key="' + $this.next().data('key') + '"]').prev().after($noFixedTh); + } + } else { + $noFixedTh.parent().prepend(''); + $noFixedTh.parent().children('th:first').after($noFixedTh); + $noFixedTh.parent().children('th:first').remove(); + } - } - } - if (isSimple) { - $tableBody.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - if ($this.siblings().length > 0) { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - } - } else if (isInFixed) { - $noFixedBody.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - if ($this.siblings().length > 0) { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - $fixedBody.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'border-left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - if ($totalTable.length > 0) { - $noFixedTotalTable.find('td[data-key="' + key + '"]').each(function () { - if (prefKey) { - $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) - } else { - if (isFixed === 'right') { - var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); - if ($preTd.length > 0) { - $preTd.after($(this)); - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } else { - $(this).parent().prepend(''); - $(this).parent().children('td:first').after($(this)); - $(this).parent().children('td:first').remove(); - } - } - }); - $fixedTotalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - } - } else { - $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - if ($totalTable.length > 0) { - $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { - $(this).prev().removeClass('isDrag').css({ - 'position': 'relative', - 'z-index': 'inherit', - 'left': 'inherit', - 'width': 'inherit', - 'background-color': 'inherit' - }); - $(this).remove(); - }); - } - } + } + } + if (isSimple) { + $tableBody.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + if ($this.siblings().length > 0) { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + } + } else if (isInFixed) { + $noFixedBody.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + if ($this.siblings().length > 0) { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + $fixedBody.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'border-left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + if ($totalTable.length > 0) { + $noFixedTotalTable.find('td[data-key="' + key + '"]').each(function () { + if (prefKey) { + $(this).parent().children('td[data-key="' + prefKey + '"]').after($(this)) + } else { + if (isFixed === 'right') { + var $preTd = $(this).parent().children('td[data-key="' + $this.next().data('key') + '"]').prev(); + if ($preTd.length > 0) { + $preTd.after($(this)); + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } else { + $(this).parent().prepend(''); + $(this).parent().children('td:first').after($(this)); + $(this).parent().children('td:first').remove(); + } + } + }); + $fixedTotalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + } + } else { + $tableBody.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + if ($totalTable.length > 0) { + $totalTable.find('td[data-key="' + key + '"][data-clone]').each(function () { + $(this).prev().removeClass('isDrag').css({ + 'position': 'relative', + 'z-index': 'inherit', + 'left': 'inherit', + 'width': 'inherit', + 'background-color': 'inherit' + }); + $(this).remove(); + }); + } + } - $cloneHead = null; + $cloneHead = null; - // 处理 toolbar 事件 - if (toolbar) { - if ($dragBar.children('.active').length > 0 && $dragBar.children('.active').attr('data-type') !== $dragBar.attr('data-type')) { - var targetFix = $dragBar.children('.active').attr('data-type'), - i, j, curPos, targetPos; - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if (targetFix === 'right' || (targetFix === 'none' && $dragBar.attr('data-type') === 'right')) { - if (typeof targetPos === 'undefined') { - if (myTable.cols[i][j].fixed === 'right') { - targetPos = { x: i, y: j }; - } else if (j === myTable.cols[i].length - 1) { - targetPos = { x: i, y: j + 1 }; - } + // 处理 toolbar 事件 + if (toolbar) { + if ($dragBar.children('.active').length > 0 && $dragBar.children('.active').attr('data-type') !== $dragBar.attr('data-type')) { + var targetFix = $dragBar.children('.active').attr('data-type'), + i, j, curPos, targetPos; + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if (targetFix === 'right' || (targetFix === 'none' && $dragBar.attr('data-type') === 'right')) { + if (typeof targetPos === 'undefined') { + if (myTable.cols[i][j].fixed === 'right') { + targetPos = {x: i, y: j}; + } else if (j === myTable.cols[i].length - 1) { + targetPos = {x: i, y: j + 1}; + } - } - } else { - if (typeof targetPos === 'undefined' && (!myTable.cols[i][j].fixed || myTable.cols[i][j].fixed === 'right')) { - targetPos = { x: i, y: j }; - } - } - if (myTable.cols[i][j].key === curKey) { - curPos = { x: i, y: j }; - } - } - } - curColumn['fixed'] = targetFix === 'none' ? false : targetFix; + } + } else { + if (typeof targetPos === 'undefined' && (!myTable.cols[i][j].fixed || myTable.cols[i][j].fixed === 'right')) { + targetPos = {x: i, y: j}; + } + } + if (myTable.cols[i][j].key === curKey) { + curPos = {x: i, y: j}; + } + } + } + curColumn['fixed'] = targetFix === 'none' ? false : targetFix; - if (curPos.y !== targetPos.y) { - myTable.cols[curPos.x].splice(curPos.y, 1); + if (curPos.y !== targetPos.y) { + myTable.cols[curPos.x].splice(curPos.y, 1); - if (curPos.y < targetPos.y) { - targetPos.y -= 1 - } + if (curPos.y < targetPos.y) { + targetPos.y -= 1 + } - myTable.cols[targetPos.x].splice(targetPos.y, 0, curColumn) + myTable.cols[targetPos.x].splice(targetPos.y, 0, curColumn) - _this.fixTableRemember(myTable); - } - table.reload(tableId) - } - $dragBar.removeClass('active') - } + _this.fixTableRemember(myTable); + } + table.reload(tableId) + } + $dragBar.removeClass('active') + } - } else { - $that.unbind('click'); - } - if ($('#column-remove').is(':visible')) { - $tableHead.find('thead>tr>th[data-key=' + key + ']').addClass(HIDE); - $tableBody.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); - $totalTable.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); - // 同步配置 - curColumn['hide'] = true - _this.fixTableRemember(myTable); - // 更新下拉隐藏 - $('#soul-columns' + tableId).find('li[data-value="' + field + '"]>input').prop('checked', false); - } - $('#column-remove').hide(); - } - }) - }); + } else { + $that.unbind('click'); + } + if ($('#column-remove').is(':visible')) { + $tableHead.find('thead>tr>th[data-key=' + key + ']').addClass(HIDE); + $tableBody.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); + $totalTable.find('tbody>tr>td[data-key="' + key + '"]').addClass(HIDE); + // 同步配置 + curColumn['hide'] = true + _this.fixTableRemember(myTable); + // 更新下拉隐藏 + $('#soul-columns' + tableId).find('li[data-value="' + field + '"]>input').prop('checked', false); + } + $('#column-remove').hide(); + } + }) + }); }) } }, rowDrag: function (myTable, rowDragConfig) { var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $noFixedBody = $tableBox.children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - tableId = myTable.id, - isDragging = false, - trigger = rowDragConfig.trigger || 'row', - syncNumber = rowDragConfig.numbers !== false, - numberColumnKey = null, numberStart = 0, - $trs = trigger === 'row' ? $tableBody.children('tbody').children('tr') : $tableBody.find(trigger), - i, j; + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $noFixedBody = $tableBox.children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + tableId = myTable.id, + isDragging = false, + trigger = rowDragConfig.trigger || 'row', + syncNumber = rowDragConfig.numbers !== false, + numberColumnKey = null, numberStart = 0, + $trs = trigger === 'row' ? $tableBody.children('tbody').children('tr') : $tableBody.find(trigger), + i, j; if (trigger !== 'row') { $tableBody.find(trigger).css('cursor', 'move') } @@ -789,22 +787,23 @@ layui.define(['table'], function (exports) { return; } var $this = trigger === 'row' ? $(this) : $(this).parents('tr:eq(0)'), - index = parseInt($this.data('index')), - $bodyTr = $noFixedBody.children('tbody').children('tr[data-index=' + index + ']'), - $cloneTr = $bodyTr.clone().css('visibility', 'hidden'), - $FixBodyTr = $fixedBody.children('tbody').children('tr[data-index=' + index + ']'), - bodyScrollTop = $tableBox.children('.layui-table-body').scrollTop(), // 记录当前滚动条位置 - originTop = $this.position().top, - disY = e.clientY - originTop; // 鼠标距离被移动元素上侧的距离 + index = parseInt($this.data('index')), // 被拖拽行索引 + $bodyTr = $noFixedBody.children('tbody').children('tr[data-index=' + index + ']'), // 被拖拽行(非固定列) + $cloneTr = $bodyTr.clone().css('visibility', 'hidden'), // 占位行 + $FixBodyTr = $fixedBody.children('tbody').children('tr[data-index=' + index + ']'), // 被拖拽行(固定列) + bodyScrollTop = $tableBox.children('.layui-table-body').scrollTop(), // 记录当前滚动条位置 + originTop = $this.position().top, // 被拖拽行当前位置 + disY = e.clientY - originTop; // 鼠标距离被拖拽行上侧的距离 _BODY.on('mousemove', function (e) { + // 刚被拖动 if (!isDragging) { isDragging = true; // 设置鼠标样式 // $table.next().find('style').append('.layui-table-view .layui-table td{cursor: move;}.layui-table tr{transition: none}') var style = $table.next().find('style')[0], - sheet = style.sheet || style.styleSheet || {}; + sheet = style.sheet || style.styleSheet || {}; _this.addCSSRule(sheet, '.layui-table-view .layui-table td', 'cursor: move') _this.addCSSRule(sheet, '.layui-table tr', 'transition: none') @@ -826,13 +825,13 @@ layui.define(['table'], function (exports) { } var top = e.clientY - disY + ($tableBox.children('.layui-table-body').scrollTop() - bodyScrollTop), // 计算当前被移动行top位置应该哪里 - trTop = $cloneTr.position().top, //当前行所在位置 - $UpTr = $bodyTr.prev(), - hasUpTr = $UpTr.length > 0, - $downTr = $cloneTr.next(), - hasDownTr = $downTr.length > 0, - upMove = hasUpTr && (trTop - top > $UpTr.height() / 2.0), - downMove = hasDownTr && (top - trTop > $downTr.height() / 2.0); + trTop = $cloneTr.position().top, //当前行所在位置 + $UpTr = $bodyTr.prev(), + hasUpTr = $UpTr.length > 0, + $downTr = $cloneTr.next(), + hasDownTr = $downTr.length > 0, + upMove = hasUpTr && (trTop - top > $UpTr.height() / 2.0), + downMove = hasDownTr && (top - trTop > $downTr.height() / 2.0); if (trTop - top > 0 ? !hasUpTr : !hasDownTr) { $bodyTr.css('top', trTop); @@ -877,28 +876,71 @@ layui.define(['table'], function (exports) { isDragging = false; $tableBox.removeClass('noselect'); // 取消禁止选中文本 - $bodyTr.css({ 'position': 'inherit', 'z-index': 'inherit' }); + $bodyTr.css({'position': 'inherit', 'z-index': 'inherit'}); $bodyTr.next().remove(); $FixBodyTr.each(function () { - $(this).css({ 'position': 'inherit', 'z-index': 'inherit' }); + $(this).css({'position': 'inherit', 'z-index': 'inherit'}); $(this).next().remove() }) // 恢复样式 var style = $table.next().find('style')[0], - sheet = style.sheet || style.styleSheet || {}, - rules = sheet.cssRules || sheet.rules; + sheet = style.sheet || style.styleSheet || {}, + rules = sheet.cssRules || sheet.rules; layui.each(rules, function (i, item) { if (item.selectorText === ('.layui-table-view .layui-table td')) { item.style.cursor = 'default'; } }); - var newIndex = $this.index() + var newIndex = $this.index(), + cache = table.cache[tableId]; if (newIndex !== index) { // 有位置变动 - var cache = table.cache[tableId], - row = cache.splice(index, 1)[0]; + // 如果 before 返回 false,则还原拖拽 + if (typeof rowDragConfig.before === 'function' + && rowDragConfig.before.call(myTable, { + row: cache[index], + newIndex: newIndex, + oldIndex: index, + cache: cache + }) === false) { + + // 同步 data-index + function updateDataIndex($el, setIndex) { + $el.data('index', setIndex); + $el.attr('data-index', setIndex); + return $el + } + + // 还原位置和索引 + if (newIndex < index) { + for (i = newIndex; i < index; i++) { + updateDataIndex($noFixedBody.find('tr[data-index="'+(i+1)+'"]'), i) + updateDataIndex($fixedBody.find('tr[data-index="'+(i+1)+'"]'), i) + } + updateDataIndex($bodyTr, index) + $noFixedBody.find('tr[data-index="'+(index - 1)+'"]').after($bodyTr) + $FixBodyTr.each(function () { + updateDataIndex($(this), index) + $(this).parent().children('tr[data-index="'+(index - 1)+'"]').after($(this)) + }) + } else { + for (i = newIndex; i > index; i--) { + updateDataIndex($noFixedBody.find('tr[data-index="'+(i-1)+'"]'), i) + updateDataIndex($fixedBody.find('tr[data-index="'+(i-1)+'"]'), i) + } + updateDataIndex($bodyTr, index) + $noFixedBody.find('tr[data-index="'+(index + 1)+'"]').before($bodyTr) + $FixBodyTr.each(function () { + updateDataIndex($(this), index) + $(this).parent().children('tr[data-index="'+(index + 1)+'"]').before($(this)) + }) + } + return; + } + + var row = cache.splice(index, 1)[0]; cache.splice(newIndex, 0, row); if (numberColumnKey && syncNumber) { // 进行序号重排 @@ -975,16 +1017,16 @@ layui.define(['table'], function (exports) { return; } var $table = $(myTable.elem), - layHeader = $table.next().find('.layui-table-header'), - layBody = $table.next().find('.layui-table-body'), - layTotal = $table.next().find('.layui-table-total'), - tooltipIndex, - hoverTime = options.hoverTime || 0, - tooltipTimeOut, - color = options.color || 'white', - bgColor = options.bgColor || 'black', - minWidth = options.minWidth || 300, - maxWidth = options.maxWidth || 300; + layHeader = $table.next().find('.layui-table-header'), + layBody = $table.next().find('.layui-table-body'), + layTotal = $table.next().find('.layui-table-total'), + tooltipIndex, + hoverTime = options.hoverTime || 0, + tooltipTimeOut, + color = options.color || 'white', + bgColor = options.bgColor || 'black', + minWidth = options.minWidth || 300, + maxWidth = options.maxWidth || 300; if (options.type === 'tips') { layBody.off('mouseenter', 'td').off('mouseleave', 'td').on('mouseenter', 'td', function () { @@ -1019,9 +1061,9 @@ layui.define(['table'], function (exports) { function toopTip(hide) { clearTimeout(tooltipTimeOut); var othis = $(this) - , elemCell = othis.children('.layui-table-cell') - , width = elemCell.outerWidth() - , layerWidth = width < minWidth ? minWidth : width > maxWidth ? maxWidth : width; + , elemCell = othis.children('.layui-table-cell') + , width = elemCell.outerWidth() + , layerWidth = width < minWidth ? minWidth : width > maxWidth ? maxWidth : width; if (othis.data('off')) return; if (hide) { @@ -1037,7 +1079,7 @@ layui.define(['table'], function (exports) { } else if (options.type === 'title') { layBody.off('mouseenter', 'td').on('mouseenter', 'td', function () { var othis = $(this) - , elemCell = othis.children('.layui-table-cell'); + , elemCell = othis.children('.layui-table-cell'); if (othis.data('off')) return; if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { @@ -1047,7 +1089,7 @@ layui.define(['table'], function (exports) { if (options.header) { layHeader.off('mouseenter', 'th').on('mouseenter', 'th', function () { var othis = $(this) - , elemCell = othis.children('.layui-table-cell'); + , elemCell = othis.children('.layui-table-cell'); if (othis.data('off')) return; if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { @@ -1058,7 +1100,7 @@ layui.define(['table'], function (exports) { if (options.total) { layTotal.off('mouseenter', 'td').on('mouseenter', 'td', function () { var othis = $(this) - , elemCell = othis.children('.layui-table-cell'); + , elemCell = othis.children('.layui-table-cell'); if (othis.data('off')) return; if (elemCell.prop('scrollWidth') > elemCell.outerWidth()) { @@ -1072,21 +1114,21 @@ layui.define(['table'], function (exports) { // 右键菜单配置 contextmenu: function (myTable, contextmenuConfig) { var $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - $totalTable = $table.next().children('.layui-table-total').children('table'), - tableId = myTable.id, - header = contextmenuConfig ? contextmenuConfig.header : '', - body = contextmenuConfig ? contextmenuConfig.body : '', - total = contextmenuConfig ? contextmenuConfig.total : '', - options = { - header: { box: $tableHead, tag: 'th', opts: header, cols: {} }, - body: { box: $tableBody, tag: 'td', opts: body, cols: {}, isBody: true }, - total: { box: $totalTable, tag: 'td', opts: total, cols: {} } - }, - hasColsContext = false; + $tableBox = $table.next().children('.layui-table-box'), + $tableHead = $.merge($tableBox.children('.layui-table-header').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-header').children('table')), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + $totalTable = $table.next().children('.layui-table-total').children('table'), + tableId = myTable.id, + header = contextmenuConfig ? contextmenuConfig.header : '', + body = contextmenuConfig ? contextmenuConfig.body : '', + total = contextmenuConfig ? contextmenuConfig.total : '', + options = { + header: {box: $tableHead, tag: 'th', opts: header, cols: {}}, + body: {box: $tableBody, tag: 'td', opts: body, cols: {}, isBody: true}, + total: {box: $totalTable, tag: 'td', opts: total, cols: {}} + }, + hasColsContext = false; for (var i = 0; i < myTable.cols.length; i++) { for (var j = 0; j < myTable.cols[i].length; j++) { @@ -1112,7 +1154,7 @@ layui.define(['table'], function (exports) { $('#soul-table-contextmenu-wrapper').on('click', function (e) { e.stopPropagation() }) - var curColsOpts = options[name].cols[$(this).data('key').substr($(this).data('key').indexOf('-') + 1)]; + var curColsOpts = options[name].cols[$(this).data('key')]; if (curColsOpts === false) { return false } else if (curColsOpts && curColsOpts.length > 0) { @@ -1181,8 +1223,8 @@ layui.define(['table'], function (exports) { (function (i) { $parent.children('.soul-table-contextmenu:last').children('li[data-index="' + i + '"]').on('click', function () { var index = $this.parents('tr:eq(0)').data('index'), - tr = box.find('tr[data-index="' + index + '"]'), - row = layui.table.cache[tableId][index]; + tr = box.find('tr[data-index="' + index + '"]'), + row = layui.table.cache[tableId][index]; options[i].click.call(myTable, { cell: $this, @@ -1209,8 +1251,8 @@ layui.define(['table'], function (exports) { td.children('.layui-table-cell').html(function () { return templet ? function () { return typeof templet === 'function' - ? templet(row) - : layui.laytpl($(templet).html() || value).render(row) + ? templet(row) + : layui.laytpl($(templet).html() || value).render(row) }() : value; }()); td.data('content', value); @@ -1236,14 +1278,14 @@ layui.define(['table'], function (exports) { }, fixTotal: function (myTable) { var $table = $(myTable.elem), - $total = $table.next().children('.layui-table-total'), - style = $table.next().find('style')[0], - sheet = style.sheet || style.styleSheet || {}; + $total = $table.next().children('.layui-table-total'), + style = $table.next().find('style')[0], + sheet = style.sheet || style.styleSheet || {}; if ($total.length > 0) { var $tableBox = $table.next().children('.layui-table-box'), - $fixedLeft = $tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), - $fixedRight = $tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), - html = []; + $fixedLeft = $tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), + $fixedRight = $tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr:eq(0)').children('td'), + html = []; $total.children('.layui-table-total-fixed').remove() @@ -1276,16 +1318,16 @@ layui.define(['table'], function (exports) { }, fixResizeRightFixed: function (myTable) { var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $fixedHead = $tableBox.children('.layui-table-fixed-r').children('.layui-table-header').children('table'), - dict = {}, resizing, ELEM_SORT = 'layui-table-sort', - ELEM_NO_SORT = 'layui-table-sort-invalid'; + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $fixedHead = $tableBox.children('.layui-table-fixed-r').children('.layui-table-header').children('table'), + dict = {}, resizing, ELEM_SORT = 'layui-table-sort', + ELEM_NO_SORT = 'layui-table-sort-invalid'; if ($fixedHead.length > 0) { $fixedHead.find('th').off('mousemove').on('mousemove', function (e) { var othis = $(this) - , oLeft = othis.offset().left - , pLeft = e.clientX - oLeft; + , oLeft = othis.offset().left + , pLeft = e.clientX - oLeft; if (othis.data('unresize') || dict.resizeStart) { return; } @@ -1341,8 +1383,8 @@ layui.define(['table'], function (exports) { }, fixFixedScroll: function (myTable) { var $table = $(myTable.elem), - layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), - layMain = $table.next().children('.layui-table-box').children('.layui-table-main'); + layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), + layMain = $table.next().children('.layui-table-box').children('.layui-table-main'); layFixed.on('mouseenter', function () { $(this).children('.layui-table-body').addClass('soul-fixed-scroll').on('scroll', function () { @@ -1356,38 +1398,38 @@ layui.define(['table'], function (exports) { }, scrollPatch: function (myTable) { var $table = $(myTable.elem), - layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'), - layTotal = $table.next().children('.layui-table-total'), - layMain = $table.next().children('.layui-table-box').children('.layui-table-main'), - layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), - layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'), - layMainTable = layMain.children('table'), - scollWidth = layMain.width() - layMain.prop('clientWidth'), - scollHeight = layMain.height() - layMain.prop('clientHeight'), - outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度 + layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'), + layTotal = $table.next().children('.layui-table-total'), + layMain = $table.next().children('.layui-table-box').children('.layui-table-main'), + layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), + layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'), + layMainTable = layMain.children('table'), + scollWidth = layMain.width() - layMain.prop('clientWidth'), + scollHeight = layMain.height() - layMain.prop('clientHeight'), + outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度 - //添加补丁 - , addPatch = function (elem) { - if (scollWidth && scollHeight) { - elem = elem.eq(0); - if (!elem.find('.layui-table-patch')[0]) { - var patchElem = $('
'); //补丁元素 - patchElem.find('div').css({ - width: scollWidth - }); - elem.find('tr').append(patchElem); - } - } else { - elem.find('.layui-table-patch').remove(); - } - } + //添加补丁 + , addPatch = function (elem) { + if (scollWidth && scollHeight) { + elem = elem.eq(0); + if (!elem.find('.layui-table-patch')[0]) { + var patchElem = $('
'); //补丁元素 + patchElem.find('div').css({ + width: scollWidth + }); + elem.find('tr').append(patchElem); + } + } else { + elem.find('.layui-table-patch').remove(); + } + } addPatch(layHeader); addPatch(layTotal); //固定列区域高度 var mainHeight = layMain.height() - , fixHeight = mainHeight - scollHeight; + , fixHeight = mainHeight - scollHeight; layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto'); //表格宽度小于容器宽度时,隐藏固定列 @@ -1465,7 +1507,7 @@ layui.define(['table'], function (exports) { }; return JSON.parse(str, function (key, value) { if (typeof value === 'string' && - value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) { + value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) { return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")"); } return value; @@ -1503,5 +1545,5 @@ layui.define(['table'], function (exports) { } // 输出 - exports('soulTableSlim', mod); + exports('soulTable', mod); }); diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableChild.js b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableChild.js index e81bf0a..751d09d 100644 --- a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableChild.js +++ b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableChild.js @@ -4,766 +4,766 @@ * @author: yelog * @link: https://github.com/yelog/layui-soul-table * @license: MIT - * @version: v1.6.1 + * @version: v1.9.0 */ layui.define(['table', 'element', 'form', 'laytpl'], function (exports) { - var $ = layui.jquery, - table = layui.table, - laytpl = layui.laytpl, - tableChildren = {}, - HIDE = 'layui-hide', - ELEM_HOVER = 'soul-table-hover'; + var $ = layui.jquery, + table = layui.table, + laytpl = layui.laytpl, + tableChildren = {}, + HIDE = 'layui-hide', + ELEM_HOVER = 'soul-table-hover'; - // 封装方法 - var mod = { - /** - * 渲染入口 - * @param myTable - */ - render: function (myTable) { - var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - tableId = myTable.id, - $tableHead = $tableBox.children('.layui-table-header').children('table'), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $noFixedBody = $tableBox.children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - columns = _this.getCompleteCols(myTable.cols), - childIndex = [], - soulSort = typeof myTable.soulSort === 'undefined' || myTable.soulSort, - i; + // 封装方法 + var mod = { + /** + * 渲染入口 + * @param myTable + */ + render: function (myTable) { + var _this = this, + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + tableId = myTable.id, + $tableHead = $tableBox.children('.layui-table-header').children('table'), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $noFixedBody = $tableBox.children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + columns = _this.getCompleteCols(myTable.cols), + childIndex = [], + soulSort = typeof myTable.soulSort === 'undefined' || myTable.soulSort, + i; - // 修复hover样式 - _this.fixHoverStyle(myTable) - // 获取子表配置信息 - for (i = 0; i < columns.length; i++) { - if (columns[i].children && columns[i].children.length > 0) { - childIndex.push(i); - } - } - if (typeof $table.attr('lay-filter') === 'undefined') { - $table.attr('lay-filter', tableId); - } - // 绑定一下主表事件 - if ($table.parents('.childTr').length === 0) { - // 行单击事件 - if (typeof myTable.rowEvent === 'function') { - table.on('row(' + $table.attr('lay-filter') + ')', function (obj) { - myTable.rowEvent(_this.commonMember.call(this, _this, myTable, obj)); - }) - } - // 行双击事件 - if (typeof myTable.rowDoubleEvent === 'function') { - table.on('rowDouble(' + $table.attr('lay-filter') + ')', function (obj) { - myTable.rowDoubleEvent(_this.commonMember.call(this, _this, myTable, obj)); - }) - } - // 绑定 checkbox 事件 - if (typeof myTable.checkboxEvent === 'function') { - table.on('checkbox(' + $table.attr('lay-filter') + ')', function (obj) { - myTable.checkboxEvent(_this.commonMember.call(this, _this, myTable, obj)); - }) - } - // 绑定 edit 事件 - if (typeof myTable.editEvent === 'function') { - table.on('edit(' + $table.attr('lay-filter') + ')', function (obj) { - myTable.editEvent(_this.commonMember.call(this, _this, myTable, obj)); - }) - } - // 绑定 tool 事件 - if (typeof myTable.toolEvent === 'function') { - table.on('tool(' + $table.attr('lay-filter') + ')', function (obj) { - myTable.toolEvent(_this.commonMember.call(this, _this, myTable, obj)); - }) - } - // 绑定 toolbar 事件 - if (typeof myTable.toolbarEvent === 'function') { - table.on('toolbar(' + $table.attr('lay-filter') + ')', function (obj) { - myTable.toolbarEvent(_this.commonMember.call(this, _this, myTable, obj)); - }) - } - } - - if (childIndex.length > 0) { - for (i = 0; i < childIndex.length; i++) { - (function f() { - var child = columns[childIndex[i]] - , curIndex = childIndex[i] - , icon = child.icon || ['layui-icon layui-icon-right', 'layui-icon layui-icon-down']; - - if (soulSort && !(myTable.url && myTable.page)) { - // 前台排序 - table.on('sort(' + $table.attr('lay-filter') + ')', function () { - _this.render(myTable) - }); - } - - if (child.isChild && typeof child.isChild === 'function') { - $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').each(function () { - if (child.isChild(layui.table.cache[tableId][$(this).parents('tr:eq(0)').data('index')])) { - if (child.field) { - $(this).prepend(''); - } else { - $(this).html(''); - } - } - }) - } else { - if (child.field) { - $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').prepend(''); - } else { - $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').html(''); - } - } - - $tableBody.children('tbody').children('tr').each(function () { - $(this).children('td:eq(' + curIndex + ')').find('.childTable').on('click', function (e) { - layui.stope(e) - var rowIndex = $(this).parents('tr:eq(0)').data('index'), - tableId = myTable.id, - key = $(this).parents('td:eq(0)').data('key'), - $this = $noFixedBody.children('tbody').children('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'), - $fixedThis = $fixedBody.find('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'), - data = table.cache[tableId][rowIndex], - children = child.children, - isTpl = false, - tplContent = '', - tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'), - obj = { - data: data, - tr: tr, - del: function () { - table.cache[tableId][rowIndex] = []; - _this.destroyChildren(rowIndex, myTable, icon) - tr.remove(); - table.resize(tableId); - }, - update: function (fields) { - fields = fields || {}; - layui.each(fields, function (key, value) { - if (key in data) { - var templet, td = tr.children('td[data-field="' + key + '"]'); - data[key] = value; - table.eachCols(tableId, function (i, item2) { - if (item2.field == key && item2.templet) { - templet = item2.templet; - } - }); - td.children('.layui-table-cell').html(function () { - return templet ? function () { - return typeof templet === 'function' - ? templet(data) - : laytpl($(templet).html() || value).render(data) - }() : value; - }()); - td.data('content', value); - } - }); - }, - close: function () { - _this.destroyChildren(rowIndex, myTable, icon) - table.resize(tableId); - } - - }; - if ($this.hasClass(icon[1])) { - if (typeof child.childClose === 'function') { - if (child.childClose(obj) === false) { - return; - } - } - } else { - // 展开事件 - if (typeof child.childOpen === 'function') { - if (child.childOpen(obj) === false) { - return; - } - } - } - - if (typeof children === 'function') { - children = children(data) - } - // 如果是 templet 自定义内容 - if (typeof children === 'string') { - isTpl = true - tplContent = _this.parseTempData(child, child.field ? data[child.field] : null, data) - } - if (child.show === 2) { // 弹窗模式 - - child.layerOption ? (typeof child.layerOption.title === 'function' ? (child.layerOption.title = child.layerOption.title(data)) : null) : null; - layer.open($.extend({ - type: 1, - title: '子表', - maxmin: true, - content: _this.getTables(this, data, child, myTable, children, isTpl, tplContent), - area: '1000px', - offset: '100px', - cancel: function () { - if (typeof child.childClose === 'function') { - if (child.childClose(obj) === false) { - return; - } - } - } - }, child.layerOption || {})); - - if (!isTpl) { - _this.renderTable(this, data, child, myTable, children, icon); - } - - } else { // 展开模式 - - // 开启手风琴模式 - if (!$this.hasClass(icon[1]) && child.collapse) { - $tableBody.children('tbody').children('tr').children('td').find('.childTable').each(function () { - if ($(this).hasClass(icon[1])) { - _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon) - } - }) - } - - // 多个入口时,关闭其他入口 - if (!$this.hasClass(icon[1])) { - $this.parents('tr:eq(0)').children('td').find('.childTable').each(function () { - if ($(this).hasClass(icon[1])) { - $(this).removeClass(icon[1]).addClass(icon[0]) - _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon) - } - }) - } - - if ($this.hasClass(icon[1])) { - $this.removeClass(icon[1]).addClass(icon[0]) - $fixedThis.removeClass(icon[1]).addClass(icon[0]) - } else { - $this.removeClass(icon[0]).addClass(icon[1]) - $fixedThis.removeClass(icon[0]).addClass(icon[1]) - } - var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan"); - - if ($this.hasClass(icon[1])) { - var newTr = []; - newTr.push(''); - newTr.push(_this.getTables(this, data, child, myTable, children, isTpl, tplContent)); - newTr.push(''); - - if (rowspanIndex) { - var index = parseInt($this.parents('tr:eq(0)').data("index")) + parseInt(rowspanIndex) - 1; - $this.parents('table:eq(0)').children().children("[data-index='" + index + "']").after(newTr.join('')); - } else { - $this.parents('tr:eq(0)').after(newTr.join('')); - } - layui.element.init('tab') - if (!isTpl) { - _this.renderTable(this, data, child, myTable, children, icon); - // 阻止事件冒泡 - $this.parents('tr:eq(0)').next().children('td').children('.layui-tab').children('.layui-tab-content').on('click', function (e) { - // 不阻止 tab 切换点击事件 - if (!$(e.target.parentElement).hasClass('layui-tab-title')) { - e.stopPropagation() - } - }).off('dblclick').on('dblclick', function (e) { - e.stopPropagation() - }).on('mouseenter', 'td', function (e) { - e.stopPropagation() - }).on('change', function (e) { - layui.stope(e) - }) - } - if ($fixedBody.length > 0) { - var $tr = $this.parents('tr:eq(0)').next(), - height = $tr.children('td').height(), - $patchDiv = '
'; - $tr.children('td').children('.soul-table-child-wrapper').css({ - position: 'absolute', - top: 0, - width: '100%', - background: 'white', - 'z-index': 200 - }) - $tr.children('td').append($patchDiv); - $fixedBody.find('tr[data-index="' + rowIndex + '"]').each(function () { - $(this).after('' + $patchDiv + '') - }) - table.resize(tableId) - } - if (child.show === 3) { - $this.parents('tr:eq(0)').next().find('.layui-table-view').css({ margin: 0, 'border-width': 0 }); - $this.parents('tr:eq(0)').next().find('.layui-table-header').css('display', 'none'); - } - - } else { - _this.destroyChildren(rowIndex, myTable, icon); - table.resize(tableId) - } - - } - }) - - }) - - if (child.spread && child.show !== 2) { - $tableBody.children('tbody').children('tr').children('td').find('.childTable').trigger('click'); - } - })() - - } - } - }, - /** - * 生成子表内容 - * @param _this - * @param data - * @param child - * @param myTable - * @param children 子表配置 - * @param isTpl 是否是自定义模版 - * @param tplContent 自定义模版内容 - * @returns {string} - */ - getTables: function (_this, data, child, myTable, children, isTpl, tplContent) { - var tables = [], - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - tableId = myTable.id, - rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index'), - $tableHead = $tableBox.children('.layui-table-header').children('table'), - $tableMain = $table.next().children('.layui-table-box').children('.layui-table-body'), - $tableBody = $tableMain.children('table'), - scrollWidth = 0, - i; - if (isTpl) { - tables.push('
') - } else if (child.show === 3) { - //不限制宽度 - tables.push('">') - } else { - if (child.childWidth === 'full') { - //不限制宽度 - tables.push('">') - } else { - // 如果有滚动条 - if ($tableMain.prop('scrollHeight') + (children.length > 0 ? children[0].height : 0) > $tableMain.height()) { - scrollWidth = this.getScrollWidth(); - } - var maxWidth = $tableMain.width() - 1 - scrollWidth; - tables.push('max-width: ' + (maxWidth > $tableHead.width() ? $tableHead.width() : maxWidth) + 'px">') - } - } - if (isTpl) { - tables.push(tplContent) - } else { - if (child.show !== 3 && (typeof child.childTitle === 'undefined' || child.childTitle)) { - tables.push('
    ') - for (i = 0; i < children.length; i++) { - tables.push('
  • ' + (typeof children[i].title === 'function' ? children[i].title(data) : children[i].title) + '
  • '); - } - tables.push('
') - } - if (child.show === 3) { - tables.push('
'); - } else { - tables.push('
'); - } - for (i = 0; i < children.length; i++) { - var childTableId = rowTableId + i; - tables.push('
'); - } - tables.push('
'); - } - tables.push('
'); - return tables.join('') - }, - /** - * 渲染子表 - * @param _this - * @param data 父表当前行数据 - * @param child 子表列 - * @param myTable 父表配置 - * @param children 子表配置 - * @param icon 自定义图标 - */ - renderTable: function (_this, data, child, myTable, children, icon) { - var tables = [] - , _that = this - , tableId = myTable.id - , rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index'); - - if (child.lazy) { - tables.push(renderChildTable(_that, _this, data, child, myTable, 0, children, icon)); - } else { - for (var i = 0; i < children.length; i++) { - tables.push(renderChildTable(_that, _this, data, child, myTable, i, children, icon)); - } - } - tableChildren[rowTableId] = tables; - - - layui.element.on('tab(table-child-tab-' + rowTableId + ')', function (tabData) { - if (child.lazy) { - var isRender = false; // 是否已经渲染 - for (i = 0; i < tableChildren[rowTableId].length; i++) { - if (tableChildren[rowTableId][i].config.id === (rowTableId + tabData.index)) { - isRender = true; - break; - } - } - if (!isRender) { - tableChildren[rowTableId].push(renderChildTable(_that, _this, data, child, myTable, tabData.index, children)) - } - } - - var rowIndex = $(_this).parents('tr:eq(0)').data('index'), - height = $(tabData.elem).height(); - - $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height) - $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-fixed').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height) - table.resize(tableId) - - }); - - - function renderChildTable(_that, _this, data, child, myTable, i, children, icon) { - var param = _that.deepClone(children[i]), thisTableChild, - tableId = myTable.id, - rowIndex = $(_this).parents('tr:eq(0)').data('index'), - childTableId = tableId + rowIndex + i, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')), - tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'), - row = table.cache[tableId][rowIndex], - // 父表当前行对象 - pobj = { - data: row, - tr: tr, - del: function () { - table.cache[tableId][rowIndex] = []; - _that.destroyChildren(rowIndex, myTable, icon) - tr.remove(); - table.resize(tableId); - }, - update: function (fields) { - fields = fields || {}; - layui.each(fields, function (key, value) { - if (key in row) { - var templet, td = tr.children('td[data-field="' + key + '"]'); - row[key] = value; - table.eachCols(tableId, function (i, item2) { - if (item2.field == key && item2.templet) { - templet = item2.templet; - } - }); - td.children('.layui-table-cell').html(function () { - return templet ? function () { - return typeof templet === 'function' - ? templet(row) - : laytpl($(templet).html() || value).render(row) - }() : value; - }()); - td.data('content', value); - } - }); - }, - close: function () { - _that.destroyChildren(rowIndex, myTable, icon) - table.resize(tableId); - } - - }; - param.id = childTableId; - param.elem = '#' + childTableId; - typeof param.where === 'function' && (param.where = param.where(data)); - typeof param.data === 'function' && (param.data = param.data(data)); - typeof param.url === 'function' && (param.url = param.url(data)); - thisTableChild = table.render(param); - if (!child.lazy && i !== 0) { - $('#' + childTableId).parents('.layui-tab-item:eq(0)').removeClass('layui-show'); //解决隐藏时计算表格高度有问题 - } - // 绑定 checkbox 事件 - if (typeof param.checkboxEvent === 'function') { - table.on('checkbox(' + childTableId + ')', function (obj) { - param.checkboxEvent(_that.commonMember.call(this, _that, param, obj), pobj) - }) - } - // 绑定 edit 事件 - if (typeof param.editEvent === 'function') { - table.on('edit(' + childTableId + ')', function (obj) { - param.editEvent(_that.commonMember.call(this, _that, param, obj), pobj) - }) - } - // 绑定 tool 事件 - if (typeof param.toolEvent === 'function') { - table.on('tool(' + childTableId + ')', function (obj) { - param.toolEvent(_that.commonMember.call(this, _that, param, obj), pobj) - }) - } - // 绑定 toolbar 事件 - if (typeof param.toolbarEvent === 'function') { - table.on('toolbar(' + childTableId + ')', function (obj) { - param.toolbarEvent(_that.commonMember.call(this, _that, param, obj), pobj) - }) - } - // 绑定单击行事件 - if (typeof param.rowEvent === 'function') { - table.on('row(' + childTableId + ')', function (obj) { - param.rowEvent(_that.commonMember.call(this, _that, param, obj), pobj) - }) - } - // 绑定双击行事件 - if (typeof param.rowDoubleEvent === 'function') { - table.on('rowDouble(' + childTableId + ')', function (obj) { - param.rowDoubleEvent(_that.commonMember.call(this, _that, param, obj), pobj) - }) - } - return thisTableChild; - } - }, - destroyChildren: function (rowIndex, myTable, icon) { - var tableId = myTable.id, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), - $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), - $tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'), - isTpl = $tr.next().data('tpl'); - - $tr.find('.childTable').removeClass(icon[1]).addClass(icon[0]); - - // 暂时不处理 rowspan 情况 - // var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan"); - // if(rowspanIndex){ - // var index=$this.parents('tr:eq(0)').index()+parseInt(rowspanIndex); - // $this.parents('table:eq(0)').children().children('tr:eq('+index+')').remove() - // }else{ - // $this.parents('tr:eq(0)').next().remove(); - // } - $tr.next().remove() - if (isTpl === 'false') { - var tables = tableChildren[tableId + rowIndex]; - if (layui.tableFilter) { //如果使用了筛选功能,同时清理筛选渲染的数据 - layui.tableFilter.destroy(tables); - } - if (layui.soulTable) { // 清除记忆 - for (var i = 0; i < tableChildren[tableId + rowIndex].length; i++) { - layui.soulTable.clearOriginCols(tableChildren[tableId + rowIndex][i].config.id) - } - } - } - delete tableChildren[tableId + rowIndex] - - }, - cloneJSON: function (obj) { - var JSON_SERIALIZE_FIX = { - PREFIX: "[[JSON_FUN_PREFIX_", - SUFFIX: "_JSON_FUN_SUFFIX]]" - }; - var sobj = JSON.stringify(obj, function (key, value) { - if (typeof value === 'function') { - return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX; - } - return value; - }); - return JSON.parse(sobj, function (key, value) { - if (typeof value === 'string' && - value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) { - return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")"); - } - return value; - }) || {}; - }, - fixHoverStyle: function (myTable) { - var $table = $(myTable.elem) - , $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table') - , - $tableFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').children('table') - , style = $table.next().find('style')[0], - sheet = style.sheet || style.styleSheet || {}; - // 屏蔽掉layui原生 hover 样式 - this.addCSSRule(sheet, '.layui-table-hover', 'background-color: inherit'); - this.addCSSRule(sheet, '.layui-table-hover.soul-table-hover', 'background-color: #F2F2F2'); - $.merge($tableFixed.children('tbody').children('tr'), $tableBody.children('tbody').children('tr')) - .on('mouseenter', function () { - var othis = $(this) - , index = $(this).data('index'); - if (othis.data('off')) return; - $tableFixed.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER); - $tableBody.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER); - }).on('mouseleave', function () { - var othis = $(this) - , index = $(this).data('index'); - if (othis.data('off')) return; - $tableFixed.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER); - $tableBody.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER); - }) - }, - addCSSRule: function (sheet, selector, rules, index) { - if ('insertRule' in sheet) { - sheet.insertRule(selector + '{' + rules + '}', index) - } else if ('addRule' in sheet) { - sheet.addRule(selector, rules, index) - } - }, - // 深度克隆-不丢失方法 - deepClone: function (obj) { - var newObj = Array.isArray(obj) ? [] : {} - if (obj && typeof obj === "object") { - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key]; - } - } - } - return newObj - }, - getCompleteCols: function (origin) { - var cols = this.deepClone(origin); - var i, j, k, cloneCol; - for (i = 0; i < cols.length; i++) { - for (j = 0; j < cols[i].length; j++) { - if (!cols[i][j].exportHandled) { - if (cols[i][j].rowspan > 1) { - cloneCol = this.deepClone(cols[i][j]) - cloneCol.exportHandled = true; - k = i + 1; - while (k < cols.length) { - cols[k].splice(j, 0, cloneCol) - k++ - } - } - if (cols[i][j].colspan > 1) { - cloneCol = this.deepClone(cols[i][j]) - cloneCol.exportHandled = true; - for (k = 1; k < cols[i][j].colspan; k++) { - cols[i].splice(j, 0, cloneCol) - } - j = j + parseInt(cols[i][j].colspan) - 1 - } - } - } - } - return cols[cols.length - 1]; - }, - getScrollWidth: function (elem) { - var width = 0; - if (elem) { - width = elem.offsetWidth - elem.clientWidth; - } else { - elem = document.createElement('div'); - elem.style.width = '100px'; - elem.style.height = '100px'; - elem.style.overflowY = 'scroll'; - - document.body.appendChild(elem); - width = elem.offsetWidth - elem.clientWidth; - document.body.removeChild(elem); - } - return width; - }, - //解析自定义模板数据 - parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本 - var str = item3.children ? function () { - return typeof item3.children === 'function' - ? item3.children(tplData) - : laytpl($(item3.children).html() || String(content)).render(tplData) - }() : content; - return text ? $('
' + str + '
').text() : str; - }, - commonMember: function (_this, myTable, sets) { - var othis = $(this) - , tableId = myTable.id - , $table = $(myTable.elem) - , $tableBox = $table.next().children('.layui-table-box') - , $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table') - , $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody) - , index = othis[0].tagName === 'TR' ? $(this).data('index') : othis.parents('tr:eq(0)').data('index') - , tr = $tableBody.children('tbody').children('tr[data-index="' + index + '"]') - , data = table.cache[tableId] || []; - - - data = data[index] || {}; - - return $.extend(sets, { - tr: tr //行元素 - , oldValue: othis.prev() ? othis.prev().text() : null - , del: function () { //删除行数据 - table.cache[tableId][index] = []; - tr.remove(); - _this.scrollPatch(myTable); - } - , update: function (fields) { //修改行数据 - fields = fields || {}; - layui.each(fields, function (key, value) { - if (key in data) { - var templet, td = tr.children('td[data-field="' + key + '"]'); - data[key] = value; - table.eachCols(tableId, function (i, item2) { - if (item2.field == key && item2.templet) { - templet = item2.templet; - } - }); - td.children('.layui-table-cell').html(_this.parseTempData({ - templet: templet - }, value, data)); - td.data('content', value); - } - }); - } - }); - }, - scrollPatch: function (myTable) { - var $table = $(myTable.elem), - layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'), - layTotal = $table.next().children('.layui-table-total'), - layMain = $table.next().children('.layui-table-box').children('.layui-table-main'), - layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), - layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'), - layMainTable = layMain.children('table'), - scollWidth = layMain.width() - layMain.prop('clientWidth'), - scollHeight = layMain.height() - layMain.prop('clientHeight'), - outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度 - - //添加补丁 - , addPatch = function (elem) { - if (scollWidth && scollHeight) { - elem = elem.eq(0); - if (!elem.find('.layui-table-patch')[0]) { - var patchElem = $('
'); //补丁元素 - patchElem.find('div').css({ - width: scollWidth - }); - elem.find('tr').append(patchElem); - } - } else { - elem.find('.layui-table-patch').remove(); - } - } - - addPatch(layHeader); - addPatch(layTotal); - - //固定列区域高度 - var mainHeight = layMain.height() - , fixHeight = mainHeight - scollHeight; - layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto'); - - //表格宽度小于容器宽度时,隐藏固定列 - layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE); - - //操作栏 - layFixRight.css('right', scollWidth - 1); + // 修复hover样式 + _this.fixHoverStyle(myTable) + // 获取子表配置信息 + for (i = 0; i < columns.length; i++) { + if (columns[i].children && columns[i].children.length > 0) { + childIndex.push(i); } - }; + } + if (typeof $table.attr('lay-filter') === 'undefined') { + $table.attr('lay-filter', tableId); + } + // 绑定一下主表事件 + if ($table.parents('.childTr').length === 0) { + // 行单击事件 + if (typeof myTable.rowEvent === 'function') { + table.on('row(' + $table.attr('lay-filter') + ')', function (obj) { + myTable.rowEvent(_this.commonMember.call(this, _this, myTable, obj)); + }) + } + // 行双击事件 + if (typeof myTable.rowDoubleEvent === 'function') { + table.on('rowDouble(' + $table.attr('lay-filter') + ')', function (obj) { + myTable.rowDoubleEvent(_this.commonMember.call(this, _this, myTable, obj)); + }) + } + // 绑定 checkbox 事件 + if (typeof myTable.checkboxEvent === 'function') { + table.on('checkbox(' + $table.attr('lay-filter') + ')', function (obj) { + myTable.checkboxEvent(_this.commonMember.call(this, _this, myTable, obj)); + }) + } + // 绑定 edit 事件 + if (typeof myTable.editEvent === 'function') { + table.on('edit(' + $table.attr('lay-filter') + ')', function (obj) { + myTable.editEvent(_this.commonMember.call(this, _this, myTable, obj)); + }) + } + // 绑定 tool 事件 + if (typeof myTable.toolEvent === 'function') { + table.on('tool(' + $table.attr('lay-filter') + ')', function (obj) { + myTable.toolEvent(_this.commonMember.call(this, _this, myTable, obj)); + }) + } + // 绑定 toolbar 事件 + if (typeof myTable.toolbarEvent === 'function') { + table.on('toolbar(' + $table.attr('lay-filter') + ')', function (obj) { + myTable.toolbarEvent(_this.commonMember.call(this, _this, myTable, obj)); + }) + } + } - // 输出 - exports('tableChild', mod); + if (childIndex.length > 0) { + for (i = 0; i < childIndex.length; i++) { + (function f() { + var child = columns[childIndex[i]] + , curIndex = childIndex[i] + , icon = child.icon || ['layui-icon layui-icon-right', 'layui-icon layui-icon-down']; + + if (soulSort && !(myTable.url && myTable.page)) { + // 前台排序 + table.on('sort(' + $table.attr('lay-filter') + ')', function () { + _this.render(myTable) + }); + } + + if (child.isChild && typeof child.isChild === 'function') { + $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').each(function () { + if (child.isChild(layui.table.cache[tableId][$(this).parents('tr:eq(0)').data('index')])) { + if (child.field) { + $(this).prepend(''); + } else { + $(this).html(''); + } + } + }) + } else { + if (child.field) { + $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').prepend(''); + } else { + $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').html(''); + } + } + + $tableBody.children('tbody').children('tr').each(function () { + $(this).children('td:eq(' + curIndex + ')').find('.childTable').on('click', function (e) { + layui.stope(e) + var rowIndex = $(this).parents('tr:eq(0)').data('index'), + tableId = myTable.id, + key = $(this).parents('td:eq(0)').data('key'), + $this = $noFixedBody.children('tbody').children('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'), + $fixedThis = $fixedBody.find('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'), + data = table.cache[tableId][rowIndex], + children = child.children, + isTpl = false, + tplContent = '', + tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'), + obj = { + data: data, + tr: tr, + del: function () { + table.cache[tableId][rowIndex] = []; + _this.destroyChildren(rowIndex, myTable, icon) + tr.remove(); + table.resize(tableId); + }, + update: function (fields) { + fields = fields || {}; + layui.each(fields, function (key, value) { + if (key in data) { + var templet, td = tr.children('td[data-field="' + key + '"]'); + data[key] = value; + table.eachCols(tableId, function (i, item2) { + if (item2.field == key && item2.templet) { + templet = item2.templet; + } + }); + td.children('.layui-table-cell').html(function () { + return templet ? function () { + return typeof templet === 'function' + ? templet(data) + : laytpl($(templet).html() || value).render(data) + }() : value; + }()); + td.data('content', value); + } + }); + }, + close: function () { + _this.destroyChildren(rowIndex, myTable, icon) + table.resize(tableId); + } + + }; + if ($this.hasClass(icon[1])) { + if (typeof child.childClose === 'function') { + if (child.childClose(obj) === false) { + return; + } + } + } else { + // 展开事件 + if (typeof child.childOpen === 'function') { + if (child.childOpen(obj) === false) { + return; + } + } + } + + if (typeof children === 'function') { + children = children(data) + } + // 如果是 templet 自定义内容 + if (typeof children === 'string') { + isTpl = true + tplContent = _this.parseTempData(child, child.field ? data[child.field] : null, data) + } + if (child.show === 2) { // 弹窗模式 + + child.layerOption ? (typeof child.layerOption.title === 'function' ? (child.layerOption.title = child.layerOption.title(data)) : null) : null; + layer.open($.extend({ + type: 1, + title: '子表', + maxmin: true, + content: _this.getTables(this, data, child, myTable, children, isTpl, tplContent), + area: '1000px', + offset: '100px', + cancel: function () { + if (typeof child.childClose === 'function') { + if (child.childClose(obj) === false) { + return; + } + } + } + }, child.layerOption || {})); + + if (!isTpl) { + _this.renderTable(this, data, child, myTable, children, icon); + } + + } else { // 展开模式 + + // 开启手风琴模式 + if (!$this.hasClass(icon[1]) && child.collapse) { + $tableBody.children('tbody').children('tr').children('td').find('.childTable').each(function () { + if ($(this).hasClass(icon[1])) { + _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon) + } + }) + } + + // 多个入口时,关闭其他入口 + if (!$this.hasClass(icon[1])) { + $this.parents('tr:eq(0)').children('td').find('.childTable').each(function () { + if ($(this).hasClass(icon[1])) { + $(this).removeClass(icon[1]).addClass(icon[0]) + _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon) + } + }) + } + + if ($this.hasClass(icon[1])) { + $this.removeClass(icon[1]).addClass(icon[0]) + $fixedThis.removeClass(icon[1]).addClass(icon[0]) + } else { + $this.removeClass(icon[0]).addClass(icon[1]) + $fixedThis.removeClass(icon[0]).addClass(icon[1]) + } + var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan"); + + if ($this.hasClass(icon[1])) { + var newTr = []; + newTr.push(''); + newTr.push(_this.getTables(this, data, child, myTable, children, isTpl, tplContent)); + newTr.push(''); + + if (rowspanIndex) { + var index = parseInt($this.parents('tr:eq(0)').data("index")) + parseInt(rowspanIndex) - 1; + $this.parents('table:eq(0)').children().children("[data-index='" + index + "']").after(newTr.join('')); + } else { + $this.parents('tr:eq(0)').after(newTr.join('')); + } + layui.element.init('tab') + if (!isTpl) { + _this.renderTable(this, data, child, myTable, children, icon); + // 阻止事件冒泡 + $this.parents('tr:eq(0)').next().children('td').children('.layui-tab').children('.layui-tab-content').on('click', function (e) { + // 不阻止 tab 切换点击事件 + if (!$(e.target.parentElement).hasClass('layui-tab-title')) { + e.stopPropagation() + } + }).off('dblclick').on('dblclick', function (e) { + e.stopPropagation() + }).on('mouseenter', 'td', function (e) { + e.stopPropagation() + }).on('change', function (e) { + layui.stope(e) + }) + } + if ($fixedBody.length > 0) { + var $tr = $this.parents('tr:eq(0)').next(), + height = $tr.children('td').height(), + $patchDiv = '
'; + $tr.children('td').children('.soul-table-child-wrapper').css({ + position: 'absolute', + top: 0, + width: '100%', + background: 'white', + 'z-index': 200 + }) + $tr.children('td').append($patchDiv); + $fixedBody.find('tr[data-index="' + rowIndex + '"]').each(function () { + $(this).after('' + $patchDiv + '') + }) + table.resize(tableId) + } + if (child.show === 3) { + $this.parents('tr:eq(0)').next().find('.layui-table-view').css({margin: 0, 'border-width': 0}); + $this.parents('tr:eq(0)').next().find('.layui-table-header').css('display', 'none'); + } + + } else { + _this.destroyChildren(rowIndex, myTable, icon); + table.resize(tableId) + } + + } + }) + + }) + + if (child.spread && child.show !== 2) { + $tableBody.children('tbody').children('tr').children('td').find('.childTable').trigger('click'); + } + })() + + } + } + }, + /** + * 生成子表内容 + * @param _this + * @param data + * @param child + * @param myTable + * @param children 子表配置 + * @param isTpl 是否是自定义模版 + * @param tplContent 自定义模版内容 + * @returns {string} + */ + getTables: function (_this, data, child, myTable, children, isTpl, tplContent) { + var tables = [], + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + tableId = myTable.id, + rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index'), + $tableHead = $tableBox.children('.layui-table-header').children('table'), + $tableMain = $table.next().children('.layui-table-box').children('.layui-table-body'), + $tableBody = $tableMain.children('table'), + scrollWidth = 0, + i; + if (isTpl) { + tables.push('
') + } else if (child.show === 3) { + //不限制宽度 + tables.push('">') + } else { + if (child.childWidth === 'full') { + //不限制宽度 + tables.push('">') + } else { + // 如果有滚动条 + if ($tableMain.prop('scrollHeight') + (children.length > 0 ? children[0].height : 0) > $tableMain.height()) { + scrollWidth = this.getScrollWidth(); + } + var maxWidth = $tableMain.width() - 1 - scrollWidth; + tables.push('max-width: ' + (maxWidth > $tableHead.width() ? $tableHead.width() : maxWidth) + 'px">') + } + } + if (isTpl) { + tables.push(tplContent) + } else { + if (child.show !== 3 && (typeof child.childTitle === 'undefined' || child.childTitle)) { + tables.push('
    ') + for (i = 0; i < children.length; i++) { + tables.push('
  • ' + (typeof children[i].title === 'function' ? children[i].title(data) : children[i].title) + '
  • '); + } + tables.push('
') + } + if (child.show === 3) { + tables.push('
'); + } else { + tables.push('
'); + } + for (i = 0; i < children.length; i++) { + var childTableId = rowTableId + i; + tables.push('
'); + } + tables.push('
'); + } + tables.push('
'); + return tables.join('') + }, + /** + * 渲染子表 + * @param _this + * @param data 父表当前行数据 + * @param child 子表列 + * @param myTable 父表配置 + * @param children 子表配置 + * @param icon 自定义图标 + */ + renderTable: function (_this, data, child, myTable, children, icon) { + var tables = [] + , _that = this + , tableId = myTable.id + , rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index'); + + if (child.lazy) { + tables.push(renderChildTable(_that, _this, data, child, myTable, 0, children, icon)); + } else { + for (var i = 0; i < children.length; i++) { + tables.push(renderChildTable(_that, _this, data, child, myTable, i, children, icon)); + } + } + tableChildren[rowTableId] = tables; + + + layui.element.on('tab(table-child-tab-' + rowTableId + ')', function (tabData) { + if (child.lazy) { + var isRender = false; // 是否已经渲染 + for (i = 0; i < tableChildren[rowTableId].length; i++) { + if (tableChildren[rowTableId][i].config.id === (rowTableId + tabData.index)) { + isRender = true; + break; + } + } + if (!isRender) { + tableChildren[rowTableId].push(renderChildTable(_that, _this, data, child, myTable, tabData.index, children)) + } + } + + var rowIndex = $(_this).parents('tr:eq(0)').data('index'), + height = $(tabData.elem).height(); + + $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height) + $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-fixed').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height) + table.resize(tableId) + + }); + + + function renderChildTable(_that, _this, data, child, myTable, i, children, icon) { + var param = _that.deepClone(children[i]), thisTableChild, + tableId = myTable.id, + rowIndex = $(_this).parents('tr:eq(0)').data('index'), + childTableId = tableId + rowIndex + i, + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')), + tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'), + row = table.cache[tableId][rowIndex], + // 父表当前行对象 + pobj = { + data: row, + tr: tr, + del: function () { + table.cache[tableId][rowIndex] = []; + _that.destroyChildren(rowIndex, myTable, icon) + tr.remove(); + table.resize(tableId); + }, + update: function (fields) { + fields = fields || {}; + layui.each(fields, function (key, value) { + if (key in row) { + var templet, td = tr.children('td[data-field="' + key + '"]'); + row[key] = value; + table.eachCols(tableId, function (i, item2) { + if (item2.field == key && item2.templet) { + templet = item2.templet; + } + }); + td.children('.layui-table-cell').html(function () { + return templet ? function () { + return typeof templet === 'function' + ? templet(row) + : laytpl($(templet).html() || value).render(row) + }() : value; + }()); + td.data('content', value); + } + }); + }, + close: function () { + _that.destroyChildren(rowIndex, myTable, icon) + table.resize(tableId); + } + + }; + param.id = childTableId; + param.elem = '#' + childTableId; + typeof param.where === 'function' && (param.where = param.where(data)); + typeof param.data === 'function' && (param.data = param.data(data)); + typeof param.url === 'function' && (param.url = param.url(data)); + thisTableChild = table.render(param); + if (!child.lazy && i !== 0) { + $('#' + childTableId).parents('.layui-tab-item:eq(0)').removeClass('layui-show'); //解决隐藏时计算表格高度有问题 + } + // 绑定 checkbox 事件 + if (typeof param.checkboxEvent === 'function') { + table.on('checkbox(' + childTableId + ')', function (obj) { + param.checkboxEvent(_that.commonMember.call(this, _that, param, obj), pobj) + }) + } + // 绑定 edit 事件 + if (typeof param.editEvent === 'function') { + table.on('edit(' + childTableId + ')', function (obj) { + param.editEvent(_that.commonMember.call(this, _that, param, obj), pobj) + }) + } + // 绑定 tool 事件 + if (typeof param.toolEvent === 'function') { + table.on('tool(' + childTableId + ')', function (obj) { + param.toolEvent(_that.commonMember.call(this, _that, param, obj), pobj) + }) + } + // 绑定 toolbar 事件 + if (typeof param.toolbarEvent === 'function') { + table.on('toolbar(' + childTableId + ')', function (obj) { + param.toolbarEvent(_that.commonMember.call(this, _that, param, obj), pobj) + }) + } + // 绑定单击行事件 + if (typeof param.rowEvent === 'function') { + table.on('row(' + childTableId + ')', function (obj) { + param.rowEvent(_that.commonMember.call(this, _that, param, obj), pobj) + }) + } + // 绑定双击行事件 + if (typeof param.rowDoubleEvent === 'function') { + table.on('rowDouble(' + childTableId + ')', function (obj) { + param.rowDoubleEvent(_that.commonMember.call(this, _that, param, obj), pobj) + }) + } + return thisTableChild; + } + }, + destroyChildren: function (rowIndex, myTable, icon) { + var tableId = myTable.id, + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'), + $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody), + $tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'), + isTpl = $tr.next().data('tpl'); + + $tr.find('.childTable').removeClass(icon[1]).addClass(icon[0]); + + // 暂时不处理 rowspan 情况 + // var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan"); + // if(rowspanIndex){ + // var index=$this.parents('tr:eq(0)').index()+parseInt(rowspanIndex); + // $this.parents('table:eq(0)').children().children('tr:eq('+index+')').remove() + // }else{ + // $this.parents('tr:eq(0)').next().remove(); + // } + $tr.next().remove() + if (isTpl === 'false') { + var tables = tableChildren[tableId + rowIndex]; + if (layui.tableFilter) { //如果使用了筛选功能,同时清理筛选渲染的数据 + layui.tableFilter.destroy(tables); + } + if (layui.soulTable) { // 清除记忆 + for (var i = 0; i < tableChildren[tableId + rowIndex].length; i++) { + layui.soulTable.clearOriginCols(tableChildren[tableId + rowIndex][i].config.id) + } + } + } + delete tableChildren[tableId + rowIndex] + + }, + cloneJSON: function (obj) { + var JSON_SERIALIZE_FIX = { + PREFIX: "[[JSON_FUN_PREFIX_", + SUFFIX: "_JSON_FUN_SUFFIX]]" + }; + var sobj = JSON.stringify(obj, function (key, value) { + if (typeof value === 'function') { + return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX; + } + return value; + }); + return JSON.parse(sobj, function (key, value) { + if (typeof value === 'string' && + value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) { + return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")"); + } + return value; + }) || {}; + }, + fixHoverStyle: function (myTable) { + var $table = $(myTable.elem) + , $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table') + , + $tableFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').children('table') + , style = $table.next().find('style')[0], + sheet = style.sheet || style.styleSheet || {}; + // 屏蔽掉layui原生 hover 样式 + this.addCSSRule(sheet, '.layui-table-hover', 'background-color: inherit'); + this.addCSSRule(sheet, '.layui-table-hover.soul-table-hover', 'background-color: #F2F2F2'); + $.merge($tableFixed.children('tbody').children('tr'), $tableBody.children('tbody').children('tr')) + .on('mouseenter', function () { + var othis = $(this) + , index = $(this).data('index'); + if (othis.data('off')) return; + $tableFixed.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER); + $tableBody.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER); + }).on('mouseleave', function () { + var othis = $(this) + , index = $(this).data('index'); + if (othis.data('off')) return; + $tableFixed.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER); + $tableBody.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER); + }) + }, + addCSSRule: function (sheet, selector, rules, index) { + if ('insertRule' in sheet) { + sheet.insertRule(selector + '{' + rules + '}', index) + } else if ('addRule' in sheet) { + sheet.addRule(selector, rules, index) + } + }, + // 深度克隆-不丢失方法 + deepClone: function (obj) { + var newObj = Array.isArray(obj) ? [] : {} + if (obj && typeof obj === "object") { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key]; + } + } + } + return newObj + }, + getCompleteCols: function (origin) { + var cols = this.deepClone(origin); + var i, j, k, cloneCol; + for (i = 0; i < cols.length; i++) { + for (j = 0; j < cols[i].length; j++) { + if (!cols[i][j].exportHandled) { + if (cols[i][j].rowspan > 1) { + cloneCol = this.deepClone(cols[i][j]) + cloneCol.exportHandled = true; + k = i + 1; + while (k < cols.length) { + cols[k].splice(j, 0, cloneCol) + k++ + } + } + if (cols[i][j].colspan > 1) { + cloneCol = this.deepClone(cols[i][j]) + cloneCol.exportHandled = true; + for (k = 1; k < cols[i][j].colspan; k++) { + cols[i].splice(j, 0, cloneCol) + } + j = j + parseInt(cols[i][j].colspan) - 1 + } + } + } + } + return cols[cols.length - 1]; + }, + getScrollWidth: function (elem) { + var width = 0; + if (elem) { + width = elem.offsetWidth - elem.clientWidth; + } else { + elem = document.createElement('div'); + elem.style.width = '100px'; + elem.style.height = '100px'; + elem.style.overflowY = 'scroll'; + + document.body.appendChild(elem); + width = elem.offsetWidth - elem.clientWidth; + document.body.removeChild(elem); + } + return width; + }, + //解析自定义模板数据 + parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本 + var str = item3.children ? function () { + return typeof item3.children === 'function' + ? item3.children(tplData) + : laytpl($(item3.children).html() || String(content)).render(tplData) + }() : content; + return text ? $('
' + str + '
').text() : str; + }, + commonMember: function (_this, myTable, sets) { + var othis = $(this) + , tableId = myTable.id + , $table = $(myTable.elem) + , $tableBox = $table.next().children('.layui-table-box') + , $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table') + , $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody) + , index = othis[0].tagName === 'TR' ? $(this).data('index') : othis.parents('tr:eq(0)').data('index') + , tr = $tableBody.children('tbody').children('tr[data-index="' + index + '"]') + , data = table.cache[tableId] || []; + + + data = data[index] || {}; + + return $.extend(sets, { + tr: tr //行元素 + , oldValue: othis.prev() ? othis.prev().text() : null + , del: function () { //删除行数据 + table.cache[tableId][index] = []; + tr.remove(); + _this.scrollPatch(myTable); + } + , update: function (fields) { //修改行数据 + fields = fields || {}; + layui.each(fields, function (key, value) { + if (key in data) { + var templet, td = tr.children('td[data-field="' + key + '"]'); + data[key] = value; + table.eachCols(tableId, function (i, item2) { + if (item2.field == key && item2.templet) { + templet = item2.templet; + } + }); + td.children('.layui-table-cell').html(_this.parseTempData({ + templet: templet + }, value, data)); + td.data('content', value); + } + }); + } + }); + }, + scrollPatch: function (myTable) { + var $table = $(myTable.elem), + layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'), + layTotal = $table.next().children('.layui-table-total'), + layMain = $table.next().children('.layui-table-box').children('.layui-table-main'), + layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'), + layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'), + layMainTable = layMain.children('table'), + scollWidth = layMain.width() - layMain.prop('clientWidth'), + scollHeight = layMain.height() - layMain.prop('clientHeight'), + outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度 + + //添加补丁 + , addPatch = function (elem) { + if (scollWidth && scollHeight) { + elem = elem.eq(0); + if (!elem.find('.layui-table-patch')[0]) { + var patchElem = $('
'); //补丁元素 + patchElem.find('div').css({ + width: scollWidth + }); + elem.find('tr').append(patchElem); + } + } else { + elem.find('.layui-table-patch').remove(); + } + } + + addPatch(layHeader); + addPatch(layTotal); + + //固定列区域高度 + var mainHeight = layMain.height() + , fixHeight = mainHeight - scollHeight; + layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto'); + + //表格宽度小于容器宽度时,隐藏固定列 + layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE); + + //操作栏 + layFixRight.css('right', scollWidth - 1); + } + }; + + // 输出 + exports('tableChild', mod); }); diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js index 7c1666d..122f8f5 100644 --- a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js +++ b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js @@ -4,3273 +4,3221 @@ * @author: yelog * @link: https://github.com/yelog/layui-soul-table * @license: MIT - * @version: v1.6.1 + * @version: v1.9.0 */ layui.define(['table', 'form', 'laydate', 'util', 'excel', 'laytpl'], function (exports) { - var $ = layui.jquery, - table = layui.table, - form = layui.form, - laydate = layui.laydate, - laytpl = layui.laytpl, - util = layui.util, - excel = layui.excel, - columnsTimeOut, - dorpListTimeOut, - conditionTimeOut, - bfColumnTimeOut, - bfCond1TimeOut, - isFilterReload = {}, - SOUL_ROW_INDEX = 'SOUL_ROW_INDEX', - cache = {}, - HIDE = 'layui-hide', - maxId = 1, - UNHANDLED_VALUES = [undefined, '', null], - where_cache = {}, - isFilterCache = {}, - table_cache = {}, - conditionChangeItems = { - 'eq': '等于', - 'ne': '≠ 不等于', - 'gt': '> 大于', - 'ge': '≥ 大于等于', - 'lt': '< 小于', - 'le': '≤ 小于等于', - 'contain': '包含', - 'notContain': '不包含', - 'start': '以...开头', - 'end': '以...结尾', - 'null': '为空', - 'notNull': '不为空' - }, - dateTimeItems = { - 'all': '全部', - 'yesterday': '昨天', - 'thisWeek': '本周', - 'lastWeek': '上周', - 'thisMonth': '本月', - 'thisYear': '今年' - }, - defaultFilterItems = ['column', 'data', 'condition', 'editCondition', 'excel'], - itemsMap = { - 'column': 'soul-column', - 'data': 'soul-dropList', - 'condition': 'soul-condition', - 'editCondition': 'soul-edit-condition', - 'excel': 'soul-export', - 'clearCache': 'soul-clear-cache', - }, - modeMapItems = { - 'in': 'data', - 'condition': 'condition', - 'date': 'condition', - }, - revertMode = { - 'data': { - 'mode': 'condition', - 'type': 'eq', - 'value': '', - }, - 'condition': { - 'mode': 'in', - 'values': [], - }, - }; - - // 封装方法 - var mod = { - /** - * 摧毁render数据 - * @param myTables - */ - destroy: function (myTables) { - if (myTables) { - if (Array.isArray(myTables)) { - for (var i = 0; i < myTables.length; i++) { - deleteRender(myTables[i]) - } - } else { - deleteRender(myTables); - } - } - - function deleteRender(myTable) { - if (!myTable) { - return; - } - var tableId = myTable.config.id; - $('#soul-filter-list' + tableId).remove(); - $('#soulCondition' + tableId).remove(); - $('#soulDropList' + tableId).remove(); - - delete isFilterReload[tableId]; - delete where_cache[tableId]; - delete table_cache[tableId]; - } - }, - clearFilter: function (myTable) { - if (typeof myTable === 'string') { - myTable = table_cache[myTable] - } - if (!where_cache[myTable.id] || !where_cache[myTable.id].filterSos || where_cache[myTable.id].filterSos === "[]") { - return; - } - where_cache[myTable.id].filterSos = "[]" - this.soulReload(myTable, true) - if (table_cache[myTable.id].where && table_cache[myTable.id].where.filterSos && table_cache[myTable.id].where.filterSos !== "[]") { - table_cache[myTable.id].where.filterSos = "[]" - } - }, - render: function (myTable) { - var _this = this, - $table = $(myTable.elem), - $tableMain = $table.next().children('.layui-table-box').children('.layui-table-main'), - $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'), - $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'), - $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'), - tableId = myTable.id, - columns = _this.getCompleteCols(myTable.cols), - filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, - needFilter = false, // 是否存在筛选列需要进行初始化 - initFilter = false, // 是否为第一次筛选 - mainExcel = typeof myTable.excel === 'undefined' || ((myTable.excel && (typeof myTable.excel.on === 'undefined' || myTable.excel.on)) ? myTable.excel : false), - i, j; - - for (i = 0; i < columns.length; i++) { - if (columns[i].field && columns[i].filter) { - needFilter = true; - if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.soul-table-filter').length === 0) { - initFilter = true; - if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) { - $tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide() - $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') - } else { - $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') - } - if ($fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) { - $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide() - $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') - } else { - $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') - } - if ($fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) { - $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide() - $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') - } else { - $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') - } - } - } - } - table_cache[myTable.id] = myTable // 缓存table配置 - isFilterCache[myTable.id] = needFilter; - if (!needFilter) { - // 缓存所有数据 - if (myTable.url && !myTable.page) { - // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题 - cache[myTable.id] = layui.table.cache[myTable.id] - } else { - cache[myTable.id] = myTable.data || layui.table.cache[myTable.id] - } - table.on('sort(' + $table.attr('lay-filter') + ')', function (obj) { - - // 同步分页信息 - myTable.limit = cache[myTable.id].limit - - if (myTable.url && myTable.page && !myTable.autoSort) { - // 后台分页 - where_cache[myTable.id] = myTable.where || {} - where_cache[myTable.id].field = obj.field; - where_cache[myTable.id].order = obj.type; - isFilterReload[myTable.id] = false; - myTable.page = $.extend(myTable.page, { - curr: 1 //重新从第 1 页开始 - }); - table.render($.extend(myTable, { - initSort: obj - , where: where_cache[myTable.id] - })); - } else if ((!myTable.url && myTable.page) || myTable.autoSort) { - // 前台分页 - if (obj.type === 'asc') { //升序 - cache[myTable.id] = layui.sort(cache[myTable.id], obj.field) - } else if (obj.type === 'desc') { //降序 - cache[myTable.id] = layui.sort(cache[myTable.id], obj.field, true) - } else { //清除排序 - cache[myTable.id] = layui.sort(cache[myTable.id], myTable.indexName) - } - //排序后及时更新row[SOUL_ROW_INDEX] - cache[myTable.id].forEach(function (item, index) { - item[SOUL_ROW_INDEX] = index - }) - myTable.initSort = obj; - myTable.page = $.extend(myTable.page, { - curr: 1 //重新从第 1 页开始 - }); - _this.soulReload(myTable, false) - } - }); - return; - } //如果没筛选列,直接退出 - - // 渲染底部筛选条件 - if (!(myTable.filter && typeof myTable.filter.bottom !== 'undefined' && !myTable.filter.bottom) && $table.next().children('.soul-bottom-contion').length === 0) { - $table.next().children('.layui-table-box').after('') - var changeHeight = $table.next().children('.layui-table-box').children('.layui-table-body').outerHeight() - $table.next().children('.soul-bottom-contion').outerHeight(); - if (myTable.page && $table.next().children('.layui-table-page').hasClass('layui-hide')) { - changeHeight += $table.next().children('.layui-table-page').outerHeight() - } - $table.next().children('.layui-table-box').children('.layui-table-body').css('height', changeHeight) - var fixHeight = changeHeight - _this.getScrollWidth($tableMain[0]), - layMainTableHeight = $tableMain.children('table').height() - $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').css('height', layMainTableHeight >= fixHeight ? fixHeight : 'auto') - $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', ($table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').width()) + 'px'); - $table.next().children('.soul-bottom-contion').children('.editCondtion').children('a').on('click', function () { - _this.showConditionBoard(myTable); - }) - } - - /** - * 不重载表头数据,重新绑定事件后结束 - */ - if (!initFilter || isFilterReload[myTable.id] || myTable.isSoulFrontFilter) { - isFilterReload[myTable.id] = false - myTable['isSoulFrontFilter'] = false - // 同步选中状态 - if (!myTable.url && myTable.page && myTable.data) { - myTable.data.forEach(function (row) { - cache[myTable.id][row[SOUL_ROW_INDEX]] = row - }) - } - this.bindFilterClick(myTable); - return; - } else { - if (!myTable.url && myTable.page && myTable.data && myTable.data.length > myTable.limit) { - // 前端分页大于一页,修复 index (用于排序恢复时需要通过这个排序) - layui.each(myTable.data, function (index, item) { - item[myTable.indexName] = index; - }) - } - /** - * 缓存所有数据 - */ - if (myTable.url && !myTable.page) { - // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题 - cache[myTable.id] = layui.table.cache[myTable.id] - } else { - cache[myTable.id] = myTable.data || layui.table.cache[myTable.id] - } - // 给表格数据添加位置标志 - cache[myTable.id].forEach(function (item, index) { - item[SOUL_ROW_INDEX] = index - }) - - if (myTable.filter && myTable.filter.clearFilter) { - if (myTable.where && myTable.where.filterSos && JSON.parse(myTable.where.filterSos).length > 0) { - // 重新查询新数据 - myTable.where.filterSos = '[]'; - where_cache[myTable.id] = myTable.where || {} - _this.soulReload(myTable, false); - return; - } else { - where_cache[myTable.id] = myTable.where || {} - } - } else if ((typeof myTable.url !== 'undefined' && !!myTable.url && myTable.page ? typeof myTable.where.filterSos === 'undefined' : true) && where_cache[myTable.id] && JSON.parse(where_cache[myTable.id].filterSos || '[]').length > 0) { - myTable.where['filterSos'] = where_cache[myTable.id].filterSos - where_cache[myTable.id] = myTable.where; - _this.soulReload(myTable, false); - return; - } else { - where_cache[myTable.id] = myTable.where || {} - } - } - - // 第一次渲染时,追加数据 - if ($('#soul-filter-list' + tableId).length === 0) { - - if (typeof myTable.soulSort === 'undefined' || myTable.soulSort) { - if (typeof $table.attr('lay-filter') === 'undefined') { - $table.attr('lay-filter', tableId); - } - table.on('sort(' + $table.attr('lay-filter') + ')', function (obj) { - - // 同步分页信息 - myTable.limit = table_cache[myTable.id].limit - - if (myTable.url && myTable.page) { - // 后台分页 - where_cache[myTable.id].field = obj.field; - where_cache[myTable.id].order = obj.type; - isFilterReload[myTable.id] = true; - myTable.page = $.extend(myTable.page, { - curr: 1 //重新从第 1 页开始 - }); - table.render($.extend(myTable, { - initSort: obj - , where: where_cache[myTable.id] - })); - } else if (!myTable.url && myTable.page) { - // 前台分页 - if (obj.type === 'asc') { //升序 - cache[myTable.id] = layui.sort(cache[myTable.id], obj.field) - } else if (obj.type === 'desc') { //降序 - cache[myTable.id] = layui.sort(cache[myTable.id], obj.field, true) - } else { //清除排序 - cache[myTable.id] = layui.sort(cache[myTable.id], myTable.indexName) - } - //排序后及时更新row[SOUL_ROW_INDEX] - cache[myTable.id].forEach(function (item, index) { - item[SOUL_ROW_INDEX] = index - }) - myTable.initSort = obj; - myTable.page = $.extend(myTable.page, { - curr: 1 //重新从第 1 页开始 - }); - _this.soulReload(myTable, false) - } - }); - } - - var soulFilterList = [], - filterItemsHtml = { - column: '
  • 表格列
  • ', - data: '
  • 筛选数据
  • ', - condition: '
  • 筛选条件
  • ', - editCondition: '
  • 编辑筛选条件
  • ', - excel: '
  • 导出excel
  • ', - clearCache: '
  • 清除缓存
  • ' - }; - soulFilterList.push('
    '); - soulFilterList.push('
    '); - $('body').append(soulFilterList.join('')); - - - // 显示隐藏列 - var liClick = true; - form.on('checkbox(changeColumns' + tableId + ')', function (data) { - liClick = false; - var columnkey = data.value - if (data.elem.checked) { - $table.next().find('[data-key=' + columnkey + ']').removeClass(HIDE); - } else { - $table.next().find('[data-key=' + columnkey + ']').addClass(HIDE); - } - // 同步配置 - for (i = 0; i < myTable.cols.length; i++) { - for (j = 0; j < myTable.cols[i].length; j++) { - if ((myTable.index + '-' + myTable.cols[i][j].key) === columnkey) { - myTable.cols[i][j]['hide'] = !data.elem.checked - } - } - } - if (layui.soulTable) { - layui.soulTable.fixTableRemember(myTable) - } - $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr.childTr').children('td').attr('colspan', $table.next().children('.layui-table-box').children('.layui-table-header').find('thead>tr>th:visible').length) - table.resize(tableId) - }); - $('#soul-columns' + tableId + '>li[data-value]').on('click', function () { - if (!$(this).find(':checkbox').is(':disabled')) { //disabled禁止点击 - if (liClick) { - $(this).find('div.layui-form-checkbox').trigger('click'); - } - liClick = true; - } - }); - - // 全选-反选事件 - $('#soul-dropList' + tableId + ' .check [data-type]').on('click', function () { - - switch ($(this).data('type')) { - case 'all': - $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:not(:checked)').prop('checked', true); - break; - case 'reverse': - $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]').each(function () { - $(this).prop('checked', !$(this).prop('checked')) - }); - break; - case 'none': - $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:checked').prop('checked', false); - break; - } - form.render('checkbox', 'orm'); - _this.updateDropList(myTable, $('#main-list' + tableId).data('field')); - return false; - }); - - // 关键字搜索 - $('#soul-dropList' + tableId + ' .filter-search input').on('input', function () { - var key = $(this).val(); - if (key === '') { - $('#soul-dropList' + tableId + '>ul>li').show(); - } else { - $('#soul-dropList' + tableId + '>ul>li').hide(); - $('#soul-dropList' + tableId + '>ul>li[data-value*="' + key.toLowerCase() + '"]').show(); - } - }) - - // 显示表格列 - $('#main-list' + tableId + ' .soul-column').on('mouseover', function (e) { - _this.hideDropList(myTable); - _this.hideCondition(myTable); - e.stopPropagation(); - if (columnsTimeOut) { - clearTimeout(columnsTimeOut) - } - columns = _this.getCompleteCols(myTable.cols) - for (i = 0; i < columns.length; i++) { - $('#soul-columns' + tableId).find('li[data-value="' + columns[i].field + '"]>input').prop('checked', !columns[i].hide); - } - form.render('checkbox', 'orm'); - $('#soul-columns' + tableId).show(); - var left, animate; - if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-columns' + tableId).width() < document.body.clientWidth) { - left = $(this).parent().offset().left + $(this).parent().width(); - animate = 'fadeInLeft' - } else { - left = $(this).parent().offset().left - $('#soul-columns' + tableId).width(); - animate = 'fadeInRight' - } - $('#soul-columns' + tableId).css({ 'top': $(this).offset().top, 'left': left }) - .removeClass().addClass(animate + ' animated'); - }); - // 显示数据下拉 - $('#main-list' + tableId + ' .soul-dropList').on('mouseover', function (e) { - if ($('#soul-dropList' + tableId).is(':visible') && !$('#soul-dropList' + tableId).hasClass('fadeOutLeft')) { - return false; - } - _this.hideColumns(myTable); - _this.hideCondition(myTable); - e.stopPropagation(); - if (dorpListTimeOut) { - clearTimeout(dorpListTimeOut); - } - $('#soul-dropList' + tableId + '>.filter-search>input').val(''); - $('#soul-dropList' + tableId).show(); - var left, animate, field = $('#main-list' + tableId).data('field'); - if ($('#main-list' + tableId).offset().left + $('#soul-dropList' + tableId).width() + $('#soul-dropList' + tableId).width() < document.body.clientWidth) { - left = $('#main-list' + tableId).offset().left + $('#main-list' + tableId).width(); - animate = 'fadeInLeft'; - } else { - left = $('#main-list' + tableId).offset().left - $('#soul-dropList' + tableId).width(); - animate = 'fadeInRight'; - } - - $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false); - var where = where_cache[myTable.id] || {}, - filterSos = JSON.parse(where.filterSos ? where.filterSos : null), - id = '', prefix = ''; - if (filterSos) { - for (i = 0; i < filterSos.length; i++) { - if (filterSos[i].head && filterSos[i].mode === "in" && filterSos[i].field === field) { - id = filterSos[i].id; - prefix = filterSos[i].prefix; - for (j = 0; j < filterSos[i].values.length; j++) { - $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSos[i].values[j] + '"]').prop('checked', true); - } - break; - } - } - } - $('#soul-dropList' + tableId + '>ul').data({ - head: true, - 'id': id, - prefix: prefix, - refresh: true, - split: $('#main-list' + tableId).data('split') - }).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone()); - - $('#soul-dropList' + tableId).css({ 'top': $(this).offset().top, 'left': left }) - .show().removeClass().addClass(animate + ' animated'); - setTimeout(function () { - $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框 - form.render('checkbox', 'orm'); - }, 1); - - // 监听筛选数据 - var liClick = true; - form.on('checkbox(soulDropList' + tableId + ')', function (data) { - liClick = false; - _this.updateDropList(myTable, field); - }); - - $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () { - if (liClick) { - $(this).find('div.layui-form-checkbox').trigger('click'); - } - liClick = true; - }) - }); - - // 显示筛选条件 - $('#main-list' + tableId + ' .soul-condition').on('mouseover', function (e) { - if ($('#soul-condition' + tableId).is(':visible') && !$('#soul-condition' + tableId).hasClass('fadeOutLeft')) { - return false; - } - _this.hideColumns(myTable); - _this.hideDropList(myTable); - e.stopPropagation(); - if (conditionTimeOut) { - clearTimeout(conditionTimeOut); - } - var documentWidth = document.body.clientWidth; - $('#soul-condition' + tableId).show(); - var left, animate, field = $(this).parent().data('field'); - if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-condition' + tableId).width() < documentWidth) { - left = $(this).parent().offset().left + $(this).parent().width(); - animate = 'fadeInLeft' - } else { - left = $(this).parent().offset().left - $('#soul-condition' + tableId).width(); - animate = 'fadeInRight' - } - - var filterSo, conditionHtml = [], - where = where_cache[myTable.id] || {}, - filterSos = JSON.parse(where.filterSos ? where.filterSos : null); - if (filterSos) { - for (i = 0; i < filterSos.length; i++) { - if (filterSos[i].head && filterSos[i].field === field && (filterSos[i].mode === "date" || filterSos[i].mode === 'group')) { - filterSo = filterSos[i] - break; - } - } - } - - var filterType = $(this).parent().data('type'); - if (_this.startsWith(filterType, 'date')) { - _this.showDate(myTable, field, filterSo, animate, $(this).offset().top, $(this).parent().offset().left + $(this).parent().width(), 'down', true); - } else { - /** - * 筛选条件 - */ - var fieldMap = {}; - for (i = 0; i < columns.length; i++) { - if (columns[i].field) { - fieldMap[columns[i]['field']] = columns[i] - } - } - // 查询条件 - var selectStr = ""; - conditionHtml.push(''); - if (filterSo && filterSo.children && filterSo.children.length > 0) { - for (i = 0; i < filterSo.children.length; i++) { - var id = filterSo.children[i].id, - prefix = filterSo.children[i].prefix, - type = filterSo.children[i].type, - value = filterSo.children[i].value; - conditionHtml.push(''); - if (i === 0) { - conditionHtml.push('') - } else { - conditionHtml.push( - '') - } - conditionHtml.push('') - conditionHtml.push(''); - conditionHtml.push(''); - conditionHtml.push('') - } - } else { - conditionHtml.push('' - + '' - + '' - + '' - + '' - + ''); - } - conditionHtml.push('
    ' + fieldMap[field].title + '' + - '
    ' + - ' ' + - '
    ' + - '
    ' + fieldMap[field].title + '
    ' + selectStr - + '
    ') - - $('#soul-condition' + tableId).data({ head: true, id: filterSo ? filterSo.id || '' : '' }) - .html(conditionHtml.join('')) - .css({ 'top': $(this).offset().top, 'left': left }) - .show().removeClass().addClass(animate + ' animated'); - - $('.condition-table').on('click', function () { - return false; - }) - - // 新增与查询 - $('#soul-condition' + tableId + ' button[data-type]').on('click', function () { - /** - * 新增 - */ - if ($(this).data('type') === 'add') { - var groupId = $('#soul-condition' + tableId).data('id'), - head = $('#soul-condition' + tableId).data('head'), - type = 'eq', - filterSo, - $tr1 = $('#soul-condition' + tableId).find('tr:eq(0)'); - - if (groupId) { - filterSo = { - head: head, - prefix: 'and', - field: field, - mode: 'condition', - type: type, - value: '', - groupId: groupId - } - } else { - filterSo = { - head: head, - prefix: head ? 'and' : 'and', - mode: 'group', - field: field, - children: [{ - id: _this.getDifId(), - prefix: 'and', - field: field, - mode: 'condition', - type: $tr1.find('select').val(), - value: $tr1.find('.value').val() - }, { - id: _this.getDifId(), - prefix: 'and', - field: field, - mode: 'condition', - type: type, - value: '' - }] - } - } - - _this.updateWhere(myTable, filterSo); - if (!groupId) { - $('#soul-condition' + tableId).data('id', filterSo.id); - $tr1.data('id', filterSo.children[0].id); - } - // $tableHead.find('thead>tr>th[data-field="'+field+'"] .soul-table-filter').attr('soul-filter','true'); - var newId = groupId ? filterSo.id : filterSo.children[1].id; - var newTr = '' + - '
    ' + - ' ' + - '
    ' + - '' - + '
    ' + selectStr + '
    ' - + '
    ' - + ''; - - $('#soul-condition' + tableId + ">table>tbody").append(newTr) - $('#soul-condition' + tableId).find('.del:last').on('click', function () { //删除 - delCurrentTr(this) - }); - - // input同步筛选条件 - $('#soul-condition' + tableId + ' input.value:last').on('input', function () { - updateTrWhere($(this).parents('tr:eq(0)')) - }); - } else if ($(this).data('type') === 'search') { - /** - * 查询 - */ - _this.soulReload(myTable); - } - form.render('select', 'orm'); - form.render('checkbox', 'orm'); - return false; - }); - - // input同步筛选条件 - $('#soul-condition' + tableId + ' input.value').on('input', function () { - updateTrWhere($(this).parents('tr:eq(0)')); - }); - - // 当前行改动时,同步where条件 - function updateTrWhere($tr) { - var id = $tr.data('id'), - groupId = $('#soul-condition' + tableId).data('id'), - prefix = $tr.find('input[lay-filter="soul-coondition-switch"]:checked').prop('checked') ? 'and' : 'or', - type = $tr.find('select').val(), - value = $tr.find('.value').val(), - head = $('#soul-condition' + tableId).data('head'); - - if (groupId) { - filterSo = { - id: id, - prefix: prefix, - mode: 'condition', - field: field, - type: type, - value: value, - groupId: groupId - } - } else { - filterSo = { - head: head, - prefix: head ? 'and' : 'and', - mode: 'group', - field: field, - children: [{ - id: _this.getDifId(), - prefix: prefix, - mode: 'condition', - field: field, - type: type, - value: value, - groupId: groupId - }] - } - } - _this.updateWhere(myTable, filterSo) - if (!groupId) { - $('#soul-condition' + tableId).data('id', filterSo.id); - $tr.data('id', filterSo.children[0].id) - } else if (!id) { - $tr.data('id', filterSo.id); - } - } - - // select同步筛选条件 - form.on('select(conditionChange)', function (data) { - if (data.value === 'null' || data.value === 'notNull') { - $(this).parents('tr').find('input.value').hide(); - } else { - $(this).parents('tr').find('input.value').show(); - } - updateTrWhere($(data.elem).parents('tr:eq(0)')); - }) - - // radio同步筛选条件 - form.on('switch(soul-coondition-switch)', function (data) { - updateTrWhere($(this).parents('tr:eq(0)')); - }); - - // 删除当前行 - $('#soul-condition' + tableId + ' .del').on('click', function () { - delCurrentTr(this) - }); - - function delCurrentTr(obj) { - - var id; - - if ($(obj).parents('table:eq(0)').find('tr').length === 1) { - id = $('#soul-condition' + tableId).data('id'); - $('#soul-condition' + tableId).data('id', ''); - $(obj).parents('tr:eq(0)').find('select').val('eq') - $(obj).parents('tr:eq(0)').find('.value').val('').show() - form.render('select', 'orm'); - } else { - id = $(obj).parents('tr:eq(0)').data('id'); - if ($(obj).parents('tr:eq(0)').index() === 0) { - $(obj).parents('table:eq(0)').find('tr:eq(1)>td:eq(0)').html(fieldMap[field].title).addClass('soul-condition-title') - } - $(obj).parents('tr:eq(0)').remove() - } - if (id) { - _this.updateWhere(myTable, { - id: id, - delete: true - }) - } - } - } - form.render('select', 'orm'); - form.render('checkbox', 'orm'); - - }); - - $('#soul-columns' + tableId + ', #soul-dropList' + tableId).on('mouseover', function (e) { - e.stopPropagation(); - }); - $('#main-list' + tableId + ' .soul-edit-condition').on('mouseover', function (e) { - _this.hideColumns(myTable) - _this.hideDropList(myTable) - _this.hideCondition(myTable) - e.stopPropagation(); - }).on('click', function () { - $('#main-list' + tableId).hide(); - _this.showConditionBoard(myTable) - }); - $('#main-list' + tableId + ' .soul-export').on('mouseover', function (e) { - _this.hideColumns(myTable) - _this.hideDropList(myTable) - _this.hideCondition(myTable) - e.stopPropagation(); - }).on('click', function () { - $('#main-list' + tableId).hide(); - _this.export(table_cache[myTable.id]) - }); - - $('#main-list' + tableId + ' .soul-clear-cache').on('mouseover', function (e) { - _this.hideColumns(myTable) - _this.hideDropList(myTable) - _this.hideCondition(myTable) - e.stopPropagation(); - }).on('click', function () { - $('#main-list' + tableId).hide(); - if (layui.soulTable) { - layui.soulTable.clearCache(myTable) - } - layer.msg('已还原!', { icon: 1, time: 1000 }) - }); - - $('#main-list' + tableId).on('mouseover', function (e) { - var curX = e.pageX; - var curY = e.pageY; - var div = $(this); - var y1 = div.offset().top; //div上面两个的点的y值 - var y2 = y1 + div.height();//div下面两个点的y值 - var x1 = div.offset().left; //div左边两个的点的x值 - var x2 = x1 + div.width(); //div右边两个点的x的值 - if (curX <= x1 || curX >= x2 || curY <= y1 || curY >= y2) { - } else { - _this.hideColumns(myTable); - _this.hideDropList(myTable); - _this.hideCondition(myTable); - } - }); - } else { - - types = {}; //存储过滤数据的类型 - // 根据表格列显示 - for (i = 0; i < columns.length; i++) { - if (columns[i].type === 'checkbox' || !columns[i].field) { - continue; - } - //存储过滤数据的类型 - if (columns[i].filter && columns[i].filter.type) { - if (columns[i].filter.field) { - types[columns[i].filter.field] = columns[i].filter.type; - } else { - types[columns[i].field] = columns[i].filter.type; - } - } - } - if (JSON.stringify(types).length !== 2) { - myTable.where['tableFilterType'] = JSON.stringify(types); - } - - } - - // 初始化下拉数据 - if ($('#soulDropList' + tableId).length === 0) { - $('body').append(''); - } - - if ($tableHead.find('.soul-table-filter').length > 0) { - var columnField = [], mainDataSwitch = filterItems.indexOf('data') !== -1; - $tableHead.find('.soul-table-filter').each(function (index, elem) { - if ($(this).data('column') && (mainDataSwitch ? (!$(this).data('items') || $(this).data('items').split(',').indexOf('data') !== -1) : $(this).data('items').split(',').indexOf('data') !== -1)) { - columnField.push($(this).data('column')); - } - }); - if (columnField.length > 0) { - if (typeof myTable.url !== 'undefined' && !!myTable.url && myTable.page) { - var datas = JSON.parse(JSON.stringify(myTable.where)), url = myTable.url; - datas['columns'] = JSON.stringify(columnField); - $.ajax({ - url: url, - data: datas, - dataType: 'json', - method: 'post', - headers: myTable.headers || {}, - contentType: myTable.contentType, - success: function (result) { - - var uls = []; - for (var key in result) { - var list = result[key]; - if (!((list.length === 1 && list[0] === '') || list.length === 0)) { - var ul = []; - ul.push("
      "); - - var columnsConfigs = columns; - for (j = 0; j < columnsConfigs.length; j++) { - if (columnsConfigs[j].field === key) { - if (columnsConfigs[j].filter.split) { - var tempList = [] - for (i = 0; i < list.length; i++) { - var tempList2 = list[i].split(columnsConfigs[j].filter.split) - for (var k = 0; k < tempList2.length; k++) { - if (tempList.indexOf(tempList2[k]) === -1) { - tempList.push(tempList2[k]); - } - } - } - list = tempList; - } - list.sort(function (a, b) { - if (isNaN(a) || isNaN(b)) { - return String(a) >= String(b) - } else { - return Number(a) - Number(b) - } - }) - for (i = 0; i < list.length; i++) { - if (UNHANDLED_VALUES.indexOf(list[i]) === -1) { - var line = {}; - line[key] = list[i]; - ul.push('
    • ') - } - } - break; - } - } - - ul.push("
    "); - uls.push(ul.join('')); - } else { - uls.push("
    • (无数据)
    ") - } - } - $('#soulDropList' + tableId).html(uls.join('')); - }, - error: function () { - // layer.msg('列筛选数据查询失败!', {icon: 2, anim: 6}) - } - }) - } else { - var tableDatas = cache[myTable.id]; - var dropDatas = {}; - for (i = 0; i < tableDatas.length; i++) { - for (j = 0; j < columnField.length; j++) { - var value = typeof tableDatas[i][columnField[j]] === 'undefined' ? '' : tableDatas[i][columnField[j]]; - if (dropDatas[columnField[j]]) { - if (dropDatas[columnField[j]].indexOf(value) === -1) { - dropDatas[columnField[j]].push(value); - } - } else { - dropDatas[columnField[j]] = [value] - } - } - } - - var columnsConfigs = columns; - var uls = []; - for (j = 0; j < columnsConfigs.length; j++) { - var key = columnsConfigs[j].field; - var list = dropDatas[key]; - if (list && !(list.length === 1 && list[0] === '')) { - if (columnsConfigs[j].filter && columnsConfigs[j].filter.split) { - var tempList = [] - for (i = 0; i < list.length; i++) { - var tempList2 = String(list[i]).split(columnsConfigs[j].filter.split); - for (var k = 0; k < tempList2.length; k++) { - if (tempList.indexOf(tempList2[k]) === -1) { - tempList.push(tempList2[k]) - } - } - } - list = tempList; - } - list.sort(function (a, b) { - if (isNaN(a) || isNaN(b)) { - return String(a) >= String(b) - } else { - return Number(a) - Number(b) - } - }) - var ul = []; - ul.push("
      "); - for (i = 0; i < list.length; i++) { - if (UNHANDLED_VALUES.indexOf(list[i]) === -1) { - var line = {}; - line[key] = list[i]; - ul.push('
    • ') - } - } - ul.push("
    "); - uls.push(ul.join('')); - } else { - uls.push("
    • (无数据)
    ") - } - } - $('#soulDropList' + tableId).html(uls.join('')); - } - } else { - _this.bindFilterClick(myTable); - } - } - - this.bindFilterClick(myTable); - }, - showConditionBoard: function (myTable) { - var _this = this, - tableId = myTable.id, - where = where_cache[myTable.id] || {}, - tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {}, - filterSos = where.filterSos ? JSON.parse(where.filterSos) : [], - filterBoard = [], fieldMap = {}, firstColumn, curItems, - filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, - columns = _this.getCompleteCols(myTable.cols), - i; - for (i = 0; i < columns.length; i++) { - if (columns[i].field && columns[i].filter) { - if (!firstColumn) { - firstColumn = columns[i] - } - curItems = columns[i].filter.items || filterItems; - fieldMap[columns[i]['field']] = { - title: columns[i].title, - items: curItems - } - } - } - filterBoard.push('
    ') - filterBoard.push('
    ') - filterBoard.push('') - filterBoard.push('
    ') - filterBoard.push('
      ') - for (i = 0; i < filterSos.length; i++) { - groupHtml(filterSos[i], filterBoard, fieldMap, i === 0, i === (filterSos.length - 1)) - } - filterBoard.push('
    ') - filterBoard.push('
    ') - filterBoard.push('
    ') - var _width = document.body.clientWidth > parseInt('480') ? '480px' : document.body.clientWidth - 10 + 'px' - var _height = document.body.clientHeight > parseInt('480') ? '480px' : document.body.clientHeight - 10 + 'px' - layer.open({ - title: '编辑条件', - type: 1, - offset: 'auto', - area: [_width, _height], - content: filterBoard.join('') - }) - form.render(null, 'soul-edit-out'); - - form.on('checkbox(out_auto)', function (data) { - if (data.elem.checked) { - _this.soulReload(myTable); - } - }) - - function groupHtml(filterSo, filterBoard, fieldMap, isFirst, isLast) { - var id = filterSo.id, - field = filterSo.field, - mode = filterSo.mode, - type = filterSo.type, - isOr = filterSo.prefix === 'or'; - filterBoard.push('
  • '); - filterBoard.push('
    ') - // if (!isFirst) { //第一个隐藏 与或 - filterBoard.push('
    ') - // } - switch (mode) { - case 'in': - filterBoard.push('
    ' + (fieldMap[field].title) + '
    '); - filterBoard.push('
    筛选数据
    '); - filterBoard.push('
    共' + (filterSo.values ? filterSo.values.length : 0) + '条数据
    '); - filterBoard.push('
    '); - break; - case 'date': - filterBoard.push('
    ' + (fieldMap[field].title) + '
    '); - filterBoard.push('
    选择日期
    '); - filterBoard.push('
    ' + (filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type]) + '
    '); - filterBoard.push('
    '); - break; - case 'condition': - filterBoard.push('
    ' + (fieldMap[field].title) + '
    '); - filterBoard.push('
    ' + conditionChangeItems[filterSo.type] + '
    '); - if (type !== 'null' && type !== 'notNull') { - filterBoard.push('
    ' + (typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value) + '
    '); - } - filterBoard.push('
    '); - break; - case 'group': - filterBoard.push('
    分组
    ') - filterBoard.push('') - filterBoard.push('
    '); - filterBoard.push('
      '); - if (filterSo.children) { - for (var i = 0; i < filterSo.children.length; i++) { - groupHtml(filterSo.children[i], filterBoard, fieldMap, i === 0, i === (filterSo.children.length - 1)); - } - } - filterBoard.push('
    '); - break; - } - filterBoard.push('
  • ') - } - - // prefix - form.on('switch(soul-edit-switch)', function (data) { - changePrefix(data) - }) - - // column - $('.soul-edit-out .item-field').on('click', function (e) { - e.stopPropagation(); - showColums(this) - }) - // type - $('.soul-edit-out .item-type').on('click', function (e) { - e.stopPropagation(); - showTypes(this) - }) - // value - $('.soul-edit-out .item-value').on('click', function (e) { - e.stopPropagation(); - showValue(this) - }) - // delete - $('.soul-edit-out .delete-item').on('click', function () { - var id = $(this).parent().data('id'), - refresh = $('.soul-edit-out .out_auto').prop('checked'); - $(this).parent().remove(); - _this.updateWhere(myTable, { - id: id, - delete: true - }) - if (refresh) { - _this.soulReload(myTable); - } - }) - - function changePrefix(data) { - var prefix = data.elem.checked ? 'and' : 'or', - id = $(data.elem).parents('li:eq(0)').data('id'), - refresh = $('.soul-edit-out .out_auto').prop('checked'); - - $(data.elem).parents('li:eq(0)').data('prefix', prefix); - _this.updateWhere(myTable, { - id: id, - prefix: prefix - }) - - if (refresh) { - _this.soulReload(myTable) - } - } - - function showColums(obj) { - _this.hideDropList(myTable); - _this.hideCondition(myTable); - _this.hideColumns(myTable); - _this.hideBfPrefix(myTable) - _this.hideBfType(myTable); - var top = $(obj).offset().top + $(obj).outerHeight(), - left = $(obj).offset().left; - - $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') - $('#soul-bf-column' + tableId) - .data('field', $(obj).parent().data('field')) - .data('id', $(obj).parent().data('id')) - .data('mode', $(obj).parent().data('mode')) - .data('group', $(obj).parents('li:eq(2)').data('id') || '') - .data('refresh', $('.soul-edit-out .out_auto').prop('checked')) - .show() - .css({ top: top, left: left }) - .removeClass().addClass('fadeInUp animated') - .find('li[data-field="' + $(obj).parent().data('field') + '"]') - .addClass('soul-bf-selected') - } - - function showTypes(obj) { - _this.hideDropList(myTable); - _this.hideCondition(myTable); - _this.hideColumns(myTable); - _this.hideBfColumn(myTable); - _this.hideBfPrefix(myTable); - var top = $(obj).offset().top + $(obj).outerHeight(), - left = $(obj).offset().left, - field = $(obj).parent().data('field'); - - $('#soul-bf-type' + tableId + ' li').hide() - if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) { - $('#soul-bf-type' + tableId + ' li[data-mode=date]').show() - } - if (fieldMap[field].items.indexOf('data') !== -1) { - $('#soul-bf-type' + tableId + ' li[data-mode=in]').show() - } - if (fieldMap[field].items.indexOf('condition') !== -1) { - $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show() - } - - $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') - switch ($(obj).parent().data('mode')) { - case 'in': - $('#soul-bf-type' + tableId).find('li[data-mode="in"]') - .addClass('soul-bf-selected') - break; - case 'date': - $('#soul-bf-type' + tableId).find('li[data-mode="date"]') - .addClass('soul-bf-selected') - case 'condition': - $('#soul-bf-type' + tableId).find('li[data-value="' + $(obj).parent().data('type') + '"]') - .addClass('soul-bf-selected') - } - - $('#soul-bf-type' + tableId) - .data('type', $(obj).parent().data('type')) - .data('mode', $(obj).parent().data('mode')) - .data('id', $(obj).parent().data('id')) - .data('group', $(obj).parents('li:eq(2)').data('id') || '') - .data('refresh', $('.soul-edit-out .out_auto').prop('checked')) - .show() - .css({ top: top, left: left }) - .removeClass().addClass('fadeInUp animated') - } - - function showValue(obj) { - _this.hideColumns(myTable); - _this.hideBfType(myTable); - _this.hideBfPrefix(myTable) - _this.hideBfColumn(myTable); - - var top, - left = $(obj).offset().left, - mode = $(obj).parent().data('mode'), - field = $(obj).parent().data('field'), - id = $(obj).parent().data('id'), - head = $(obj).parent().data('head'), - prefix = $(obj).parent().data('prefix'), - value = $(obj).parent().data('value'), - refresh = $('.soul-edit-out .out_auto').prop('checked'), - where = where_cache[myTable.id] || {}, - filterSos = where.filterSos ? JSON.parse(where.filterSos) : []; - - switch (mode) { - case 'in': - _this.hideCondition(myTable); - if (dorpListTimeOut) { - clearTimeout(dorpListTimeOut); - } - $('#soul-dropList' + tableId + '>.filter-search>input').val(''); - $('#soul-dropList' + tableId).show(); - $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false); - var filterSo = _this.getFilterSoById(filterSos, id); - if (filterSo.values) { - for (i = 0; i < filterSo.values.length; i++) { - $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true); - } - } - - $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', refresh).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone()); - form.render('checkbox', 'orm'); - top = $(obj).offset().top + $(obj).outerHeight(); - $('#soul-dropList' + tableId).css({ 'top': top, 'left': left }) - .show().removeClass().addClass('fadeInUp animated'); - setTimeout(function () { - $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框 - }, 1); - - // 监听筛选数据 - var liClick = true; - form.on('checkbox(soulDropList' + tableId + ')', function (data) { - liClick = false; - _this.updateDropList(myTable, field); - }); - - $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () { - if (liClick) { - $(this).find('div.layui-form-checkbox').trigger('click'); - } - liClick = true; - }) - break; - case 'date': - _this.hideDropList(myTable); - if (conditionTimeOut) { - clearTimeout(conditionTimeOut); - } - var filterSo = _this.getFilterSoById(filterSos, id), - top = $(obj).offset().top + $(obj).height(); - - _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "down", refresh); - break; - case 'condition': - $(obj).hide(); - $(obj).after('
    ') - $(obj).next().children().val(value).select().on('keydown', function (e) { - if (e.keyCode === 13) { - $(this).blur(); - } - }).on('blur', function () { - var newValue = $(this).val(); - $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue); - $(obj).show(); - $(this).parent().remove() - if (newValue !== value) { - $(obj).parent().data('value', newValue); - _this.updateWhere(myTable, { - id: id, - value: newValue - }) - if (refresh) { - _this.soulReload(myTable); - } - } - }) - break; - } - - } - - $('.soul-edit-out a[data-type]').on('click', function () { - if ($(this).data('type') === 'search') { - _this.soulReload(myTable); - } else { - addLine(this) - } - }) - - function addLine(obj) { - var refresh = $('.soul-edit-out .out_auto').prop('checked'); - filterBoard = [] - switch ($(obj).data('type')) { - case 'addOne': - var filterSo = { - prefix: 'and', - field: firstColumn.field, - mode: 'condition', - type: 'eq', - value: '' - } - if ($(obj).parent().parent().data('id')) { - $.extend(filterSo, { - groupId: $(obj).parent().parent().data('id') - }) - } - - _this.updateWhere(myTable, filterSo); - - filterBoard.push('
  • '); - filterBoard.push('
    '); - filterBoard.push('
    ') - filterBoard.push('
    ' + fieldMap[filterSo.field].title + '
    '); - filterBoard.push('
    等于
    '); - filterBoard.push('
    请输入...
    '); - filterBoard.push('
    '); - filterBoard.push('
  • '); - break; - case 'addGroup': - var filterSo = { - prefix: 'and', - mode: 'group', - children: [] - } - if ($(obj).parent().parent().data('id')) { - $.extend(filterSo, { - groupId: $(obj).parent().parent().data('id') - }) - } - _this.updateWhere(myTable, filterSo); - - filterBoard.push('
  • '); - filterBoard.push('
    '); - filterBoard.push('
    ') - filterBoard.push('
    分组
    ') - filterBoard.push('') - filterBoard.push('
    '); - filterBoard.push('
      '); - filterBoard.push('
    '); - filterBoard.push('
  • '); - break; - } - if (refresh) { - _this.soulReload(myTable); - } - if ($(obj).parent().parent().children('ul').children('li').length > 0) { - $(obj).parent().parent().children('ul').children('li:last').removeClass('last'); - if ($(obj).parent().parent().children('ul').children('li:last').children('ul.group').length > 0) { - $(obj).parent().parent().children('ul').children('li:last').children('ul.group').addClass('line') - } - } - $(obj).parent().parent().children('ul').append(filterBoard.join('')); - form.render('checkbox', 'soul-edit-out') - if ($(obj).data('type') === 'addGroup') { - $(obj).parent().parent().children('ul').children("li:last").find('a[data-type]').on('click', function () { - addLine(this) - }) - } else { - $(obj).parent().parent().children('ul').children("li:last").find('.item-field').on('click', function (e) { - e.stopPropagation(); - showColums(this); - }) - $(obj).parent().parent().children('ul').children("li:last").find('.item-type').on('click', function (e) { - e.stopPropagation(); - showTypes(this); - }) - $(obj).parent().parent().children('ul').children("li:last").find('.item-value').on('click', function (e) { - e.stopPropagation(); - showValue(this); - }) - } - $(obj).parent().parent().children('ul').children("li:last").children('.delete-item').on('click', function () { - var id = $(this).parent().data('id'), - refresh = $('.soul-edit-out .out_auto').prop('checked'); - $(this).parent().remove(); - _this.updateWhere(myTable, { - id: id, - delete: true - }) - if (refresh) { - _this.soulReload(myTable); - } - }) - } - } - , hideColumns: function (myTable, animate) { - var tableId = myTable.id; - - $('#soul-columns' + tableId).removeClass().addClass('fadeOutLeft animated') - if (columnsTimeOut) { - clearTimeout(columnsTimeOut) - } - if (typeof animate === 'undefined' || animate) { - columnsTimeOut = setTimeout(function (e) { - $('#soul-columns' + tableId).hide(); - }, 500) - } else { - $('[id^=soul-columns]').hide(); - } - - } - , hideDropList: function (myTable, animate) { - var tableId = myTable.id; - $('#soul-dropList' + tableId).removeClass().addClass('fadeOutLeft animated') - if (dorpListTimeOut) { - clearTimeout(dorpListTimeOut); - } - if (typeof animate === 'undefined' || animate) { - dorpListTimeOut = setTimeout(function (e) { - $('#soul-dropList' + tableId).hide(); - }, 500) - } else { - $('[id^=soul-dropList]').hide(); - } - - } - , hideCondition: function (myTable, animate) { - var tableId = myTable.id; - $('#soul-condition' + tableId).removeClass().addClass('fadeOutLeft animated') - if (conditionTimeOut) { - clearTimeout(conditionTimeOut); - } - if (typeof animate === 'undefined' || animate) { - conditionTimeOut = setTimeout(function (e) { - $('#soul-condition' + tableId).hide(); - }, 500) - } else { - $('[id^=soul-condition]').hide(); - } - } - , hideBfPrefix: function (myTable, animate) { - var tableId = myTable.id; - $('#soul-bf-prefix' + tableId).removeClass().addClass('fadeOutDown animated') - if (bfColumnTimeOut) { - clearTimeout(bfColumnTimeOut); - } - if (typeof animate === 'undefined' || animate) { - bfColumnTimeOut = setTimeout(function () { - $('#soul-bf-prefix' + tableId).hide(); - }, 500) - } else { - $('[id=soul-bf-prefix' + tableId + ']').hide(); - } - } - , hideBfColumn: function (myTable, animate) { - var tableId = myTable.id; - $('#soul-bf-column' + tableId).removeClass().addClass('fadeOutDown animated') - if (bfColumnTimeOut) { - clearTimeout(bfColumnTimeOut); - } - if (typeof animate === 'undefined' || animate) { - bfColumnTimeOut = setTimeout(function () { - $('#soul-bf-column' + tableId).hide(); - }, 500) - } else { - $('[id=soul-bf-column' + tableId + ']').hide(); - } - } - , hideBfType: function (myTable, animate) { - var tableId = myTable.id; - $('#soul-bf-type' + tableId).removeClass().addClass('fadeOutDown animated') - if (bfCond1TimeOut) { - clearTimeout(bfCond1TimeOut); - } - if (typeof animate === 'undefined' || animate) { - bfCond1TimeOut = setTimeout(function () { - $('#soul-bf-type' + tableId).hide(); - }, 500) - } else { - $('[id=soul-bf-type' + tableId + ']').hide(); - } - } - , bindFilterClick: function (myTable) { - var _this = this, - $table = $(myTable.elem), - $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'), - $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'), - $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'), - tableId = myTable.id, - filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, - mainListTimeOut; - - // 显示筛选框 - $tableHead.find('.soul-table-filter').off('click').on('click', function (e) { - e.stopPropagation(); - showFilter($(this)) - }); - $fixedLeftTableHead.find('.soul-table-filter').off('click').on('click', function (e) { - e.stopPropagation(); - showFilter($(this)) - }); - $fixedRigthTableHead.find('.soul-table-filter').off('click').on('click', function (e) { - e.stopPropagation(); - showFilter($(this)) - }); - - function showFilter($that) { - var curItems = $that.data('items') ? $that.data('items').split(',') : filterItems - _this.hideColumns(myTable, false); - _this.hideDropList(myTable, false); - _this.hideCondition(myTable, false); - $('[id^=main-list]').hide(); - - $('#main-list' + tableId).data({ 'field': $that.data('column'), 'split': $that.data('split') }); - - $('#soul-columns' + tableId + ' [type=checkbox]').attr('disabled', false); - // if (myTable.cols[0][0].type=='checkbox') { - // $('#soul-columns'+tableId+' [type=checkbox]:eq('+($that.parents('th').data('key').split('-')[2]-1)+')').attr('disabled', true); - // } else { - $('#soul-columns' + tableId + ' li[data-key=' + $that.parents('th').data('key').split('-')[2] + '] [type=checkbox]').attr('disabled', true); - // } - - $('#main-list' + tableId + ' > li').hide() - // 是否显示排序框 - if ($that.hasClass('layui-table-sort')) { - $('#main-list' + tableId + ' .soul-sort').show() - } - for (var i = 0; i < curItems.length; i++) { - $('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).show() - if ($('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).index() !== (i + 2)) { - $('#main-list' + tableId + '>li:eq("' + (i + 2) + '")').before($('#main-list' + tableId + ' .' + itemsMap[curItems[i]])) - - } - } - if (mainListTimeOut) { - clearTimeout(mainListTimeOut) - } - var left, animate; - if ($that.offset().left + $('#main-list' + tableId).outerWidth() < document.body.clientWidth) { - left = $that.offset().left + 10; - animate = 'fadeInLeft'; - } else { - left = $that.offset().left - $('#main-list' + tableId).outerWidth(); - animate = 'fadeInRight'; - } - $('#main-list' + tableId).data('type', myTable.where.tableFilterType ? JSON.parse(myTable.where.tableFilterType)[$that.data('column')] || '' : '').hide().css({ - 'top': $that.offset().top + 10, - 'left': left - }).show().removeClass().addClass(animate + ' animated'); - - // 排序 - $('#main-list' + tableId + ' .soul-sort').on('click', function (e) { - $that.siblings('.layui-table-sort').find('.layui-table-sort-' + $(this).data('value')).trigger('click'); - $('#main-list' + tableId).hide(); - }) - form.render('checkbox', 'orm'); - } - - $(document).on('click', function (e) { - $('#main-list' + tableId).hide(); - _this.hideColumns(myTable, false); - _this.hideDropList(myTable, false); - _this.hideCondition(myTable, false); - _this.hideBfPrefix(myTable, false); - _this.hideBfColumn(myTable, false); - _this.hideBfType(myTable, false); - }); - $('#main-list' + tableId + ',#soul-columns' + tableId + ',#soul-dropList' + tableId + ',#soul-condition' + tableId).on('click', function (e) { - $(this).find('.layui-form-selected').removeClass('layui-form-selected') - e.stopPropagation(); - }); - - //渲染底部筛选条件 - _this.renderBottomCondition(myTable); - - // 表头样式 - var where = where_cache[myTable.id] || {}, - filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'); - - for (var i = 0; i < filterSos.length; i++) { - if (filterSos[i].head) { - var hasFilter = false; - switch (filterSos[i].mode) { - case 'in': - if (filterSos[i].values && filterSos[i].values.length > 0) { - hasFilter = true - } - break; - case 'date': - if (filterSos[i].type !== 'all' && typeof filterSos[i].value !== 'undefined' && filterSos[i].value !== '') { - hasFilter = true - } - break; - case 'group': - if (filterSos[i].children && filterSos[i].children.length > 0) { - hasFilter = true - } - default: - break; - } - $tableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter); - $fixedLeftTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter); - $fixedRigthTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter); - } - } - } - , resize: function (myTable) { - var _this = this, - $table = $(myTable.elem), - $tableBox = $table.next().children('.layui-table-box'), - $tableMain = $tableBox.children('.layui-table-main') - // 减去底部筛选的高度 - if ($table.next().children('.soul-bottom-contion').length > 0) { - $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', $table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').outerWidth()); - - var bodyHeight = $table.next().height() - $table.next().children('.soul-bottom-contion').outerHeight() - if ($table.next().children('.layui-table-tool').length > 0) { - bodyHeight = bodyHeight - $table.next().children('.layui-table-tool').outerHeight(); - } - if ($table.next().children('.layui-table-total').length > 0) { - bodyHeight = bodyHeight - $table.next().children('.layui-table-total').outerHeight(); - } - if ($table.next().children('.layui-table-page').length > 0) { - bodyHeight = bodyHeight - $table.next().children('.layui-table-page').outerHeight(); - } - - bodyHeight = bodyHeight - $table.next().children('.layui-table-box').children('.layui-table-header').outerHeight(); - - $table.next().children('.layui-table-box').children('.layui-table-body').height(bodyHeight) - var fixHeight = bodyHeight - _this.getScrollWidth($tableMain[0])-1, - layMainTableHeight = $tableMain.children('table').height() - $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').height(layMainTableHeight >= fixHeight ? fixHeight : 'auto') - - var scollWidth = $tableMain.width() - $tableMain.prop('clientWidth') //纵向滚动条宽度; - $tableBox.children('.layui-table-fixed-r').css('right', scollWidth - 1); - } - } - /** - * 同步当前 droplist - * @param myTable - * @param field - */ - , updateDropList: function (myTable, field) { - var _this = this, - $table = $(myTable.elem), - tableId = myTable.id, - id = $('#soul-dropList' + tableId + '>ul').data('id'), - $checkedDom = $('#soul-dropList' + tableId + '>ul input[type=checkbox]:checked'), - values = [], - head = $('#soul-dropList' + tableId + '>ul').data('head'), - prefix = $('#soul-dropList' + tableId + '>ul').data('prefix'), - refresh = $('#soul-dropList' + tableId + '>ul').data('refresh'), - split = $('#soul-dropList' + tableId + '>ul').data('split'); - if ($checkedDom.length > 0) { - $checkedDom.each(function () { - values.push($(this).val()) - }) - } - var filterSo = { - id: id, - head: head, - prefix: prefix || 'and', - mode: 'in', - field: field, - split: split, - values: values - }; - _this.updateWhere(myTable, filterSo); - if (!id) { - $('#soul-dropList' + tableId + '>ul').data('id', filterSo.id); - } - - if ($('.soul-edit-out').length > 0) { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]>.item-value').html('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据') - } - - if (refresh) { - _this.soulReload(myTable); - } - } - , getFilterSoById: function (filterSos, id) { - for (var i = 0; i < filterSos.length; i++) { - if (filterSos[i].id === id) { - return filterSos[i] - } else if (filterSos[i].mode === 'group') { - for (var j = 0; j < filterSos[i].children.length; j++) { - var filterSo = this.getFilterSoById(filterSos[i].children, id); - if (filterSo) return filterSo; - } - } - } - return null - } - /** - * 更新 filter 条件 - * @param myTable - * @param filterSo - */ - , updateWhere: function (myTable, filterSo) { - var _this = this, - where = where_cache[myTable.id] || {}, - filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'); - - if (filterSo.id || filterSo.groupId) { - for (var i = 0; i < filterSos.length; i++) { - if (filterSo.delete && filterSos[i].id === filterSo.id) { - filterSos.splice(i, 1); - break; - } - if (updateFilterSo(filterSos[i], filterSo)) { - break; - } - } - } else if (!(filterSo.mode === 'in' && !(filterSo.values && filterSo.values.length > 0))) { - filterSos.push($.extend(filterSo, { - id: _this.getDifId() - })) - } - where['filterSos'] = JSON.stringify(filterSos); - myTable.where = where; - where_cache[myTable.id] = where; - - function updateFilterSo(filterSo, newFilterSo) { - var isMatch = false; - - if (filterSo.id === newFilterSo.id) { - $.extend(filterSo, newFilterSo); - isMatch = true; - } - - // 在分组中新增 - if (!newFilterSo.id && filterSo.id === newFilterSo.groupId) { - filterSo.children.push($.extend(newFilterSo, { - id: _this.getDifId() - })) - } else if (filterSo.mode === 'group') { - for (var i = 0; i < filterSo.children.length; i++) { - if (newFilterSo.delete && filterSo.children[i].id === newFilterSo.id) { - filterSo.children.splice(i, 1); - return true; - } - if (updateFilterSo(filterSo.children[i], newFilterSo)) { - return true; - } - } - - } - - return isMatch; - } - } - /** - * 根据当前条件重载表格 - * @param myTable 需要重载的表格对象 - * @param isr 是否为筛选重载,为 true 时,不进行筛选的初始化动作(包括渲染dom、请求表头数据等) - */ - , soulReload: function (myTable, isr) { - var _this = this, - $table = $(myTable.elem), - scrollLeft = $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft(); - - isFilterReload[myTable.id] = typeof isr === 'undefined' ? true : isr; - if (typeof myTable.url !== 'undefined' && !!myTable.url && myTable.page) { - $table.data('scrollLeft', scrollLeft); - /** - * 后台筛选 - */ - table.reload(myTable.id, { - where: where_cache[myTable.id] || {}, - page: { - curr: 1 //重新从第 1 页开始 - } - }, true) - } else { - /** - * 前端筛选 - */ - var where = where_cache[myTable.id] || {}, - filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'), - tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {}, - loading = layer.load(2); - if (!myTable.page) { - // 修复前端不分页时,layui table bug 导致的只显示10条数据的问题 - myTable.limit = 100000000 - } - if (filterSos.length > 0) { - var newData = []; - layui.each(cache[myTable.id], function (index, item) { - var show = true; - - for (var i = 0; i < filterSos.length; i++) { - show = _this.handleFilterSo(filterSos[i], item, tableFilterTypes, show, i === 0) - } - - if (show) { - newData.push(item) - } - }) - if (myTable.page) { - table.reload(myTable.id, { - data: newData - , initSort: myTable.initSort - , isSoulFrontFilter: true - , page: { - curr: 1 //重新从第 1 页开始 - } - }, true) - } else { - var url = myTable.url; - $table.next().off('click') - var inst = table.reload(myTable.id, { - url: '' - , initSort: myTable.initSort - , isSoulFrontFilter: true - , data: newData - }, true) - inst.config.url = url; - } - myTable.data = newData - - } else { - if (myTable.page) { - table.reload(myTable.id, { - data: cache[myTable.id] - , initSort: myTable.initSort - , isSoulFrontFilter: true - , page: { - curr: 1 //重新从第 1 页开始 - } - }, true) - } else { - table.reload(myTable.id, { - data: cache[myTable.id] - , initSort: myTable.initSort - , isSoulFrontFilter: true - }, true) - } - myTable.data = cache[myTable.id] - } - $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft(scrollLeft); - layer.close(loading) - } - } - , handleFilterSo: function (filterSo, item, tableFilterTypes, show, first) { - var isOr = first ? false : filterSo.prefix === 'or', - field = filterSo.field, - value = filterSo.value, - status = true; - - // 如果有子元素 - if (filterSo.children && filterSo.children.length > 0) { - for (var i = 0; i < filterSo.children.length; i++) { - status = this.handleFilterSo(filterSo.children[i], item, tableFilterTypes, status, i === 0) - } - return isOr ? show || status : show && status; - } - - switch (filterSo.mode) { - case "in": - if (filterSo.values && filterSo.values.length > 0) { - if (filterSo.split) { - var tempList = (item[field] + '').split(filterSo.split); - var tempStatus = false; - for (var i = 0; i < tempList.length; i++) { - if (filterSo.values.indexOf(tempList[i]) !== -1) { - tempStatus = true; - } - } - status = tempStatus; - } else { - status = filterSo.values.indexOf(item[field] + '') !== -1 - } - } else { - return show; - } - break; - case "condition": - if (filterSo.type !== 'null' && filterSo.type !== 'notNull' && (typeof value === 'undefined' || value === '')) { - return show; - } - switch (filterSo.type) { - case "eq": - status = isNaN(item[field]) || isNaN(value) ? item[field] === value : Number(item[field]) === Number(value); - break; - case "ne": - status = isNaN(item[field]) || isNaN(value) ? item[field] !== value : Number(item[field]) !== Number(value); - break; - case "gt": - status = isNaN(item[field]) || isNaN(value) ? item[field] > value : Number(item[field]) > Number(value); - break; - case "ge": - status = isNaN(item[field]) || isNaN(value) ? item[field] >= value : Number(item[field]) >= Number(value); - break; - case "lt": - status = isNaN(item[field]) || isNaN(value) ? item[field] < value : Number(item[field]) < Number(value); - break; - case "le": - status = isNaN(item[field]) || isNaN(value) ? item[field] <= value : Number(item[field]) <= Number(value); - break; - case "contain": - status = (item[field] + '').indexOf(value) !== -1; - break; - case "notContain": - status = (item[field] + '').indexOf(value) === -1; - break; - case "start": - status = (item[field] + '').indexOf(value) === 0; - break; - case "end": - var d = (item[field] + '').length - (value + '').length; - status = d >= 0 && (item[field] + '').lastIndexOf(value) === d; - break; - case "null": - status = typeof item[field] === 'undefined' || item[field] === '' || item[field] === null; - break; - case "notNull": - status = typeof item[field] !== 'undefined' && item[field] !== '' && item[field] !== null; - break; - } - break; - case "date": - var dateVal = new Date(Date.parse(item[field].replace(/-/g, "/"))); - switch (filterSo.type) { - case 'all': - status = true; - break; - case 'yesterday': - status = item[field] && isBetween(dateVal, getToday() - 86400, getToday() - 1); - break; - case 'thisWeek': - status = item[field] && isBetween(dateVal, getFirstDayOfWeek(), getFirstDayOfWeek() + 86400 * 7 - 1); - break; - case 'lastWeek': - status = item[field] && isBetween(dateVal, getFirstDayOfWeek() - 86400 * 7, getFirstDayOfWeek() - 1); - break; - case 'thisMonth': - status = item[field] && isBetween(dateVal, getFirstDayOfMonth(), getCurrentMonthLast()); - break; - case 'thisYear': - status = item[field] && isBetween(dateVal, new Date(new Date().getFullYear(), 1, 1) / 1000, new Date(new Date().getFullYear() + 1, 1, 1) / 1000 - 1); - break; - case 'specific': - var dateFormat = dateVal.getFullYear(); - dateFormat += '-' + (timeAdd0(dateVal.getMonth() + 1)); - dateFormat += '-' + timeAdd0(dateVal.getDate()); - status = item[field] && dateFormat === value - break; - } - break; - } - - // 今天凌晨 - function getToday() { - return new Date().setHours(0, 0, 0, 0) / 1000; - } - - // 本周第一天 - function getFirstDayOfWeek() { - var now = new Date(); - var weekday = now.getDay() || 7; //获取星期几,getDay()返回值是 0(周日) 到 6(周六) 之间的一个整数。0||7为7,即weekday的值为1-7 - return new Date(now.setDate(now.getDate() - weekday + 1)).setHours(0, 0, 0, 0) / 1000;//往前算(weekday-1)天,年份、月份会自动变化 - } - - //获取当月第一天 - function getFirstDayOfMonth() { - return new Date(new Date().setDate(1)).setHours(0, 0, 0, 0) / 1000; - } - - //获取当月最后一天最后一秒 - function getCurrentMonthLast() { - var date = new Date(); - var currentMonth = date.getMonth(); - var nextMonth = ++currentMonth; - var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1); - return nextMonthFirstDay / 1000 - 1; - } - - function isBetween(v, a, b) { - return (v.getTime() / 1000) >= a && (v.getTime() / 1000) <= b; - } - - function timeAdd0(str) { - str += ""; - if (str.length <= 1) { - str = '0' + str; - } - return str - } - - return isOr ? show || status : show && status; - } - , getDifId: function () { - return maxId++; - } - , showDate: function (myTable, field, filterSo, animate, top, left, type, refresh) { - var _this = this, - tableId = myTable.id, - conditionHtml = [], - documentWidth = document.body.clientWidth, - animate; - conditionHtml.push('
    '); - conditionHtml.push('
    '); - for (var key in dateTimeItems) { - conditionHtml.push('
    '); - } - conditionHtml.push('
    '); - conditionHtml.push('
    '); - $('#soul-condition' + tableId).html(conditionHtml.join('')); - var filterDate = util.toDateString(new Date(), 'yyyy-MM-dd'); - if (filterSo) { - $('#soul-condition' + tableId).data({ 'id': filterSo.id, 'head': true }); - $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="' + filterSo.type + '"]').prop('checked', true); - if (filterSo.type === 'specific') { - filterDate = filterSo.value; - $('#soul-condition' + tableId + ' [name^=staticDate]').val(filterDate.replace('~', ' - ')); - $('#soul-condition' + tableId + ' [name^=staticDate]').removeClass("layui-hide"); - } - else { - $('#soul-condition' + tableId + ' [name^=staticDate]').addClass("layui-hide"); - } - } else { - $('#soul-condition' + tableId).data({ 'id': '', 'head': true }); - $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="all"]').prop('checked', true); - } - $('#soul-condition' + tableId + ' .specific_value').val(filterDate); - - //时间范围改造= - laydate.render({ - elem: '#soul-condition' + tableId + ' [name^=staticDate]' - , range: true - , btns: ['confirm'] - , type: 'date' - , done: function (value, date, endDate) { - var StartTime = date.year + "-" + date.month + "-" + date.date; - var EndTime = endDate.year + "-" + endDate.month + "-" + endDate.date; - var timeSE = StartTime + "~" + EndTime; - var id = $('#soul-condition' + tableId).data('id'), - head = $('#soul-condition' + tableId).data('head') - $('#soul-condition' + tableId + ' [name^=staticDate]').val(timeSE); - $('#soul-condition' + tableId + ' [name^=datetime]:checked').prop('checked', false); - $('#soul-condition' + tableId + ' [name^=datetime][value=specific]').prop('checked', true); - var filterSo = { - id: id, - head: head, - prefix: head ? 'and' : 'and', - mode: 'date', - field: field, - type: 'specific', - value: timeSE - } - _this.updateWhere(myTable, filterSo); - if (!id) { - $('#soul-condition' + tableId).data('id', filterSo.id) - } - if ($('.soul-edit-out').length > 0) { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value) - } - if (refresh) { - _this.soulReload(myTable); - } - form.render('radio', 'orm'); - } - }); - - form.on('radio(datetime' + tableId + ')', function (data) { - var id = $('#soul-condition' + tableId).data('id'), - head = $('#soul-condition' + tableId).data('head') - var filterSo = { - id: id, - head: head, - prefix: head ? 'and' : 'and', - mode: 'date', - field: field, - type: data.value, - value: $('#soul-condition' + tableId + ' .specific_value').val() - } - if (data.value == "specific") { - $('#soul-condition' + tableId + ' [name^=staticDate]').removeClass("layui-hide"); - return; - } - _this.updateWhere(myTable, filterSo); - if (!id) { - $('#soul-condition' + tableId).data('id', filterSo.id) - } - if ($('.soul-edit-out').length > 0) { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type] || filterSo.value) - } - if (refresh) { - _this.soulReload(myTable); - } - }); - form.render('radio', 'orm') - if (type === 'down') { - if (left + $('#soul-condition' + tableId).width() < documentWidth) { - animate = 'fadeInLeft' - } else { - left = left - $('#main-list' + tableId).width() - $('#soul-condition' + tableId).width(); - animate = 'fadeInRight' - } - } else { - top = top - $('#soul-condition' + tableId).outerHeight() - 10; - } - $('#soul-condition' + tableId).css({ 'top': top<0?0:top, 'left': left }) - .show().removeClass().addClass(animate + ' animated'); - - } - , bottomConditionHtml: function (bcHtml, filterSo, fieldMap, first) { - var _this = this, - isOr = filterSo.prefix === 'or', - field = filterSo.field; - - if (filterSo.mode === 'group') { - if (filterSo.children && filterSo.children.length > 0) { - bcHtml.push('
    '); - if (!first) { - bcHtml.push('
    ' + (isOr ? '或' : '与') + '
    '); - } - - for (var i = 0; i < filterSo.children.length; i++) { - _this.bottomConditionHtml(bcHtml, filterSo.children[i], fieldMap, i === 0); - } - bcHtml.push(''); - bcHtml.push('
    ') - } - return; - } - bcHtml.push('
    '); - if (!first) { - bcHtml.push('
    ' + (isOr ? '或' : '与') + '
    '); - } - bcHtml.push('
    ' + fieldMap[field].title + '
    '); - bcHtml.push('
    '); - switch (filterSo.mode) { - case 'in': - bcHtml.push('筛选数据'); - break; - case 'condition': - bcHtml.push(conditionChangeItems[filterSo.type]); - break; - case 'date': - bcHtml.push('选择日期'); - break; - default: - bcHtml.push('未知'); - break; - } - bcHtml.push('
    '); - if (filterSo.type !== 'null' && filterSo.type !== 'notNull') { - bcHtml.push('
    '); - switch (filterSo.mode) { - case 'in': - bcHtml.push('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据'); - break; - case 'date': - bcHtml.push(filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type]) - break; - case 'condition': - default: - bcHtml.push(typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value); - break; - } - - bcHtml.push('
    ') - } - bcHtml.push(''); - bcHtml.push('
    ') - } - , renderBottomCondition: function (myTable) { - var _this = this, - where = where_cache[myTable.id] || {}, - filterSos = where.filterSos ? JSON.parse(where.filterSos) : [], - tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {}, - $table = $(myTable.elem), - tableId = myTable.id, - $bottomCondition = $table.next().children('.soul-bottom-contion'), - fieldMap = {}, bcHtml = [], curItems, - filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, - columns = _this.getCompleteCols(myTable.cols); - for (var i = 0; i < columns.length; i++) { - if (columns[i].field && columns[i].filter) { - curItems = columns[i].filter.items || filterItems; - if (curItems.indexOf('data') !== -1 || curItems.indexOf('condition') !== -1) { - fieldMap[columns[i]['field']] = { - title: columns[i].title, - items: curItems - } - } - } - } - - /** - * 一、拼装底部内容 - */ - for (var i = 0; i < filterSos.length; i++) { - _this.bottomConditionHtml(bcHtml, filterSos[i], fieldMap, i === 0); - } - $bottomCondition.children('.condition-items').html(bcHtml.join('')) - - /** - * 二、组装底部弹窗条件 - */ - bcHtml = []; - // 1. prefix - if ($('#soul-bf-prefix' + tableId).length === 0) { - bcHtml.push('') - } - // 2. 列选择 - if ($('#soul-bf-column' + tableId).length === 0) { - bcHtml.push('') - } - - // 3. 条件选择 - if ($('#soul-bf-type' + tableId).length === 0) { - bcHtml.push('') - } - - // 4. 值选择 - if ($('#soul-bf-cond2-dropList' + tableId).length === 0) { - bcHtml.push('') - } - - - $('body').append(bcHtml.join('')) - - /** - * 三、底部弹窗事件 - */ - // 1. prefix弹出事件 - $bottomCondition.find('.item-prefix').off('click').on('click', function (e) { - e.stopPropagation(); - $('#main-list' + tableId).hide(); - _this.hideDropList(myTable); - _this.hideCondition(myTable); - _this.hideColumns(myTable); - _this.hideBfColumn(myTable); - _this.hideBfType(myTable); - var top = $(this).offset().top - $('#soul-bf-prefix' + tableId).outerHeight() - 10, - left = $(this).offset().left; - - $('#soul-bf-prefix' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') - $('#soul-bf-prefix' + tableId) - .data('id', $(this).parent().data('id')) - .data('prefix', $(this).parent().data('prefix')) - .data('refresh', true) - .show() - .css({ top: top, left: left }) - .removeClass().addClass('fadeInUp animated') - .find('li[data-value="' + $(this).parent().data('prefix') + '"]') - .addClass('soul-bf-selected') - - }) - // 2. 弹出列选择 - $bottomCondition.find('.item-field').off('click').on('click', function (e) { - e.stopPropagation(); - $('#main-list' + tableId).hide(); - _this.hideDropList(myTable); - _this.hideCondition(myTable); - _this.hideColumns(myTable); - _this.hideBfPrefix(myTable) - _this.hideBfType(myTable); - var top = $(this).offset().top - $('#soul-bf-column' + tableId).outerHeight() - 10, - left = $(this).offset().left; - - $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') - $('#soul-bf-column' + tableId) - .data('field', $(this).parent().data('field')) - .data('id', $(this).parent().data('id')) - .data('mode', $(this).parent().data('mode')) - .data('group', $(this).parent().parent().data('id') || '') - .data('refresh', true) - .show() - .css({ top: top, left: left }) - .removeClass().addClass('fadeInUp animated') - .find('li[data-field="' + $(this).parent().data('field') + '"]') - .addClass('soul-bf-selected') - }) - - // 3. 弹出方式选择 - $bottomCondition.find('.item-type').on('click', function (e) { - e.stopPropagation(); - $('#main-list' + tableId).hide(); - _this.hideDropList(myTable); - _this.hideCondition(myTable); - _this.hideColumns(myTable); - _this.hideBfColumn(myTable); - _this.hideBfPrefix(myTable); - var field = $(this).parent().data('field') - $('#soul-bf-type' + tableId + ' li').hide() - if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) { - $('#soul-bf-type' + tableId + ' li[data-mode=date]').show() - } - if (fieldMap[field].items.indexOf('data') !== -1) { - $('#soul-bf-type' + tableId + ' li[data-mode=in]').show() - } - if (fieldMap[field].items.indexOf('condition') !== -1) { - $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show() - } - - var top = $(this).offset().top - $('#soul-bf-type' + tableId).outerHeight() - 10, - left = $(this).offset().left; - $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') - switch ($(this).parent().data('mode')) { - case 'in': - $('#soul-bf-type' + tableId).find('li[data-mode="in"]') - .addClass('soul-bf-selected') - break; - case 'date': - $('#soul-bf-type' + tableId).find('li[data-mode="date"]') - .addClass('soul-bf-selected') - case 'condition': - $('#soul-bf-type' + tableId).find('li[data-value="' + $(this).parent().data('type') + '"]') - .addClass('soul-bf-selected') - } - - $('#soul-bf-type' + tableId) - .data('type', $(this).parent().data('type')) - .data('mode', $(this).parent().data('mode')) - .data('id', $(this).parent().data('id')) - .data('group', $(this).parent().parent().data('id') || '') - .data('refresh', true) - .show() - .css({ top: top, left: left }) - .removeClass().addClass('fadeInUp animated') - }) - - // 4. 弹出值选择 - $bottomCondition.find('.item-value').on('click', function (e) { - e.stopPropagation(); - $('#main-list' + tableId).hide(); - _this.hideColumns(myTable); - _this.hideBfType(myTable); - _this.hideBfPrefix(myTable) - _this.hideBfColumn(myTable); - var top, - left = $(this).offset().left, - mode = $(this).parent().data('mode'), - field = $(this).parent().data('field'), - id = $(this).parent().data('id'), - head = $(this).parent().data('head'), - prefix = $(this).parent().data('prefix'); - - switch (mode) { - case 'in': - _this.hideCondition(myTable); - if (dorpListTimeOut) { - clearTimeout(dorpListTimeOut); - } - $('#soul-dropList' + tableId + '>.filter-search>input').val(''); - $('#soul-dropList' + tableId).show(); - $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false); - var filterSo = _this.getFilterSoById(filterSos, id); - for (var i = 0; i < filterSo.values.length; i++) { - $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true); - } - - $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', true).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone()); - form.render('checkbox', 'orm'); - top = $(this).offset().top - $('#soul-dropList' + tableId).outerHeight() - 10; - $('#soul-dropList' + tableId).css({ 'top': top, 'left': left }) - .show().removeClass().addClass('fadeInUp animated'); - setTimeout(function () { - $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框 - }, 1); - - - // 监听筛选数据 - var liClick = true; - form.on('checkbox(soulDropList' + tableId + ')', function (data) { - liClick = false; - _this.updateDropList(myTable, field); - }); - - $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () { - if (liClick) { - $(this).find('div.layui-form-checkbox').trigger('click'); - } - liClick = true; - }) - break; - case 'date': - _this.hideDropList(myTable); - if (conditionTimeOut) { - clearTimeout(conditionTimeOut); - } - var filterSo = _this.getFilterSoById(filterSos, id), - top = $(this).offset().top - 10; - - _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "up", true); - break; - default: - _this.hideDropList(myTable); - if (conditionTimeOut) { - clearTimeout(conditionTimeOut); - } - var obj = this, - value = $(this).parents('.condition-item:eq(0)').data('value'); - $(obj).hide(); - $(obj).after('
    ') - $(obj).next().children().val(value).select().on('keydown', function (e) { - if (e.keyCode === 13) { - $(this).blur(); - } - }).on('blur', function () { - var newValue = $(this).val(); - $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue); - $(obj).show(); - $(this).parent().remove() - if (newValue !== value) { - _this.updateWhere(myTable, { - id: id, - value: newValue - }) - _this.soulReload(myTable); - } - }) - - break; - } - }) - - /** - * 三、选择事件 - */ - // 1. 选择prefix - $('#soul-bf-prefix' + tableId + '>ul>li').off('click').on('click', function () { - var id = $(this).parent().parent().data('id'), - newPrefix = $(this).data('value'), - oldPrefix = $(this).parent().parent().data('prefix'), - refresh = $(this).parent().parent().data('refresh'); - - if (oldPrefix !== newPrefix) { - _this.updateWhere(myTable, { - id: id, - prefix: newPrefix - }); - if (refresh === true) { - _this.soulReload(myTable); - } - } - }) - // 1. 选择列 - $('#soul-bf-column' + tableId + '>ul>li').off('click').on('click', function () { - var oldField = $(this).parent().parent().data('field'), - newField = $(this).data('field'), - mode = $(this).parent().parent().data('mode'), - group = $(this).parent().parent().data('group'), - refresh = $(this).parent().parent().data('refresh'); - - if (oldField !== newField) { - var filterSo = { - id: $(this).parent().parent().data('id'), - field: newField - } - if (fieldMap[newField].items.indexOf(modeMapItems[mode]) === -1) { - $.extend(filterSo, $.extend({}, revertMode[modeMapItems[mode]], - revertMode[modeMapItems[mode]].mode === 'condition' && _this.startsWith(tableFilterTypes[newField], 'date') - ? { - mode: 'date', - type: 'all' - } : {})) - } else { - // 重置values值 - if (mode === 'in') { - $.extend(filterSo, { - values: [] - }) - } else if (mode === 'date' && !(_this.startsWith(tableFilterTypes[newField], 'date'))) { - $.extend(filterSo, { - mode: 'condition', - type: 'eq', - value: '' - }) - } else if (mode !== 'date' && _this.startsWith(tableFilterTypes[newField], 'date')) { - $.extend(filterSo, { - mode: 'date', - type: 'all' - }) - } - } - // 如果是头部条件,选择列是清除 - if (group) { - _this.updateWhere(myTable, { - id: group, - head: false - }) - } - _this.updateWhere(myTable, filterSo); - - if ($('.soul-edit-out').length > 0) { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-field').html(fieldMap[newField].title); - if (filterSo.mode === 'in') { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('筛选数据') - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html('共0条数据') - } else if (mode !== filterSo.mode) { - if (filterSo.mode === 'date') { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('选择日期') - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type]) - } else if (filterSo.mode === 'condition') { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html(conditionChangeItems[filterSo.type]) - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value === '' ? '请输入...' : filterSo.value) - } - } - } - - if (refresh === true) { - _this.soulReload(myTable); - } - } - }) - - // 2. 选择类型 - $('#soul-bf-type' + tableId + '>ul>li').off('click').on('click', function () { - var newType = $(this).data('value') + "" // 引号修复为空(null值)传递问题 - , newMode = $(this).data('mode') - , type = $(this).parent().parent().data('type') - , mode = $(this).parent().parent().data('mode') - , group = $(this).parent().parent().data('group') - , refresh = $(this).parent().parent().data('refresh') - if (type !== newType) { - - var filterSo = { - id: $(this).parent().parent().data('id'), - type: newType, - mode: newMode - } - if (mode !== newMode) { - $.extend(filterSo, { - value: '', - values: [] - }) - } - - // 如果是头部条件,选择列是清除 - if (group && newMode === 'in') { - _this.updateWhere(myTable, { - id: group, - head: false - }) - } - _this.updateWhere(myTable, filterSo) - - if ($('.soul-edit-out').length > 0) { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').show(); - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-type').html(conditionChangeItems[newType] || (newMode === 'in' ? '筛选数据' : '选择日期')); - switch (newMode) { - case 'in': - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('共0条数据'); - break; - case 'date': - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html(dateTimeItems[newType]); - break; - case 'condition': - if (mode !== newMode) { - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('请输入...'); - } - $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value')[newType === 'null' || newType === 'notNull' ? 'hide' : 'show']() - - break; - } - } - - // 是否立即更新 - if (refresh === true) { - _this.soulReload(myTable); - } - } - }) - - /** - * 五、底部筛选条件删除事件 - */ - $bottomCondition.find('.condition-items .condition-item .condition-item-close').on('click', function () { - _this.updateWhere(myTable, { - id: $(this).parents('.condition-item:eq(0)').data('id'), - delete: true - }) - _this.soulReload(myTable); - }) - - } - /** - * 导出 excel 文件 - * @param myTable - * @param curExcel - */ - , export: function (myTable, curExcel) { - if (typeof myTable === 'string') { - myTable = table_cache[myTable] // tableId 转 myTable - } - var loading = layer.msg('文件下载中', { - icon: 16 - , time: -1 - , anim: -1 - , fixed: false - }); - var cols = this.deepClone(myTable.cols) - , style = myTable.elem.next().find('style')[0] - , sheet = style.sheet || style.styleSheet || {} - , rules = sheet.cssRules || sheet.rules; - - layui.each(rules, function (i, item) { - if (item.style.width) { - var keys = item.selectorText.split('-'); - cols[keys[3]][keys[4]]['width'] = parseInt(item.style.width) - } - }) - - var data = JSON.parse(JSON.stringify(myTable.data || cache[myTable.id])), - showField = {}, - widths = {}, - mergeArrays = [], // 合并配置 - heightConfig = {}, - $table = $(myTable.elem), - $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table'), - $tableTotal = myTable.totalRow ? $table.next().children('.layui-table-total').children(":first") : null, - finalExcel = Object.assign({}, myTable.excel, curExcel); - - var filename = finalExcel.filename ? (typeof finalExcel.filename === 'function' ? finalExcel.filename.call(this) : finalExcel.filename) : '表格数据.xlsx', - checked = finalExcel.checked === true, - curPage = finalExcel.curPage === true, - customColumns = finalExcel.columns, - totalRow = finalExcel.totalRow, - type = filename.substring(filename.lastIndexOf('.') + 1, filename.length), - tableStartIndex = finalExcel.add && finalExcel.add.top && Array.isArray(finalExcel.add.top.data) ? finalExcel.add.top.data.length + 1 : 1, //表格内容从哪一行开始 - bottomLength = finalExcel.add && finalExcel.add.bottom && Array.isArray(finalExcel.add.bottom.data) ? finalExcel.add.bottom.data.length : 0,// 底部自定义行数 - i, j, k; - - if (finalExcel.data) { - if (Array.isArray(finalExcel.data)) { - data = finalExcel.data - } else { - console.error('导出指定数据 data 不符合数组格式', finalExcel.data) - layer.close(loading) - return; - } - } else if (checked) { // 获取选中行数据 - // data = table.checkStatus(myTable.id).data; - data = [] - if (cache[myTable.id] && cache[myTable.id].length > 0) { - for (i = 0; i < cache[myTable.id].length; i++) { - if (cache[myTable.id][i][table.config.checkName]) { - data.push(cache[myTable.id][i]) - } - } - } - } else if (curPage) { - data = layui.table.cache[myTable.id] - } else if (myTable.url && myTable.page) { - var ajaxStatus = true; - var searchParam = isFilterCache[myTable.id] ? where_cache[myTable.id] : table_cache[myTable.id].where; - if (myTable.contentType && myTable.contentType.indexOf("application/json") == 0) { //提交 json 格式 - searchParam = JSON.stringify(searchParam); - } - $.ajax({ - url: myTable.url, - data: searchParam, - dataType: 'json', - method: myTable.method || 'post', - async: false, - cache: false, - headers: myTable.headers || {}, - contentType: myTable.contentType, - success: function (res) { - if (typeof myTable.parseData === 'function') { - res = myTable.parseData(res) || res; - } - //检查数据格式是否符合规范 - if (res[myTable.response.statusName] != myTable.response.statusCode) { - layer.msg('返回的数据不符合规范,正确的成功状态码应为:"' + myTable.response.statusName + '": ' + myTable.response.statusCode, { - icon: 2, - anim: 6 - }); - } else { - data = res[myTable.response.dataName] - } - }, - error: function (res) { - layer.msg('请求异常!', { icon: 2, anim: 6 }); - ajaxStatus = false; - } - }) - if (!ajaxStatus) { - return; - } - } else { - var $sortDoom = $table.next().children('.layui-table-box').children('.layui-table-header').find('.layui-table-sort[lay-sort$="sc"]:eq(0)') - if ($sortDoom.length > 0) { - var sortField = $sortDoom.parent().parent().data('field'); - var sortOrder = $sortDoom.attr('lay-sort'); - switch (sortOrder) { - case 'asc': - data = layui.sort(data, sortField); - break; - case 'desc': - data = layui.sort(data, sortField, true); - break; - default: - break; - } - } - } - - // 制定显示列和顺序 - var tempArray, cloneCol, columnsMap = [], curRowUnShowCount; - for (i = 0; i < cols.length; i++) { - curRowUnShowCount = 0; - for (j = 0; j < cols[i].length; j++) { - if (!cols[i][j].exportHandled) { - if (cols[i][j].rowspan > 1) { - if ((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide) { - mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + 1 - curRowUnShowCount) + (i + parseInt(cols[i][j].rowspan) + tableStartIndex - 1)]) - } else { - curRowUnShowCount++; - } - cloneCol = this.deepClone(cols[i][j]) - cloneCol.exportHandled = true; - k = i + 1; - while (k < cols.length) { - cols[k].splice(j, 0, cloneCol) - k++ - } - } - if (cols[i][j].colspan > 1) { - mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + parseInt(cols[i][j].colspan) - curRowUnShowCount) + (i + tableStartIndex)]) - cloneCol = this.deepClone(cols[i][j]) - cloneCol.exportHandled = true; - for (k = 1; k < cols[i][j].colspan; k++) { - cols[i].splice(j, 0, cloneCol) - } - j = j + parseInt(cols[i][j].colspan) - 1 - - } - } else if (!((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide)) { - curRowUnShowCount++; - } - } - } - var columns = cols[cols.length - 1]; // 获取真实列 - - // 处理数据 - for (i = 0; i < data.length; i++) { - for (j = 0; j < columns.length; j++) { - if ((columns[j].field || columns[j].type === 'numbers') && (customColumns && Array.isArray(customColumns) || !columns[j].hide)) { - data[i][columns[j].key] = data[i][columns[j].field || columns[j]['LAY_INDEX']] - } - } - } - - // 处理合计行 - if (totalRow !== false && myTable.totalRow) { - var obj = {}, totalRows = {}; - if (typeof totalRow === 'object' && totalRow.type === 'origin') { - // 通过 dom 解析 - for (i = 0; i < columns.length; i++) { - if (columns[i].field) { - obj[columns[i].key] = $tableTotal.find('[data-field="' + columns[i].field + '"]').text().trim() - } - } - data.push(obj); - } else { - // 通过数据解析 - for (i = 0; i < columns.length; i++) { - if (columns[i].totalRowText) { - obj[columns[i].key] = columns[i].totalRowText - } else if (columns[i].totalRow) { - totalRows[columns[i].key] = 0 - } - } - if (JSON.stringify(totalRows) !== '{}') { - for (i = 0; i < data.length; i++) { - for (var key in totalRows) { - totalRows[key] = (parseFloat(totalRows[key]) + (parseFloat(data[i][key]) || 0)).toFixed(2) - } - } - } - data.push(Object.assign(obj, totalRows)); - } - } - - if (customColumns && Array.isArray(customColumns)) { - // 自定义表头 - var tempCustomColumns = []; - tempArray = {}; - mergeArrays = []; // 重置表头合并列 - columnsMap[0] = {}; - for (i = 0; i < customColumns.length; i++) { - for (j = 0; j < columns.length; j++) { - if (columns[j].field === customColumns[i]) { - columns[j].hide = false - tempCustomColumns.push(columns[j]); - columnsMap[0][columns[j].key] = columns[j]; - tempArray[columns[j].key] = $('
    ' + columns[j].title + '
    ').text() - break; - } - } - } - columns = tempCustomColumns; - data.splice(0, 0, tempArray) - } else { - // 拼接表头数据 - for (i = 0; i < cols.length; i++) { - columnsMap[i] = {} - tempArray = {} - for (j = 0; j < cols[i].length; j++) { - columnsMap[i][cols[cols.length - 1][j].key] = cols[i][j]; - tempArray[cols[cols.length - 1][j].key] = $('
    ' + cols[i][j].title + '
    ').text() - } - data.splice(i, 0, tempArray) - } - } - - //添加自定义内容 - if (finalExcel.add) { - var addTop = finalExcel.add.top, - addBottom = finalExcel.add.bottom, - startPos, endPos, jumpColsNum; - - if (addTop && Array.isArray(addTop.data) && addTop.data.length > 0) { - - for (i = 0; i < addTop.data.length; i++) { - tempArray = {}, jumpColsNum = 0; - for (j = 0; j < (addTop.data[i].length > columns.length ? addTop.data[i].length : columns.length); j++) { - if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) { - tempArray[columns[j] ? columns[j].key : j + ''] = addTop.data[i][j - jumpColsNum] || '' - } else { - jumpColsNum++ - } - } - data.splice(i, 0, tempArray); - } - - if (Array.isArray(addTop.heights) && addTop.heights.length > 0) { - for (i = 0; i < addTop.heights.length; i++) { - heightConfig[i] = addTop.heights[i] - } - } - - if (Array.isArray(addTop.merge) && addTop.merge.length > 0) { - for (i = 0; i < addTop.merge.length; i++) { - if (addTop.merge[i].length === 2) { - startPos = addTop.merge[i][0].split(','); - endPos = addTop.merge[i][1].split(','); - mergeArrays.push([numberToLetter(startPos[1]) + startPos[0], numberToLetter(endPos[1]) + endPos[0]]) - } - - } - } - } - if (addBottom && Array.isArray(addBottom.data) && addBottom.data.length > 0) { - for (i = 0; i < addBottom.data.length; i++) { - tempArray = {}, jumpColsNum = 0; - for (j = 0; j < (addBottom.data[i].length > columns.length ? addBottom.data[i].length : columns.length); j++) { - if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) { - tempArray[columns[j] ? columns[j].key : j + ''] = addBottom.data[i][j - jumpColsNum] || '' - } else { - jumpColsNum++ - } - } - data.push(tempArray); - } - - if (Array.isArray(addBottom.heights) && addBottom.heights.length > 0) { - for (i = 0; i < addBottom.heights.length; i++) { - heightConfig[data.length - addBottom.data.length + i] = addBottom.heights[i] - } - } - - if (Array.isArray(addBottom.merge) && addBottom.merge.length > 0) { - for (i = 0; i < addBottom.merge.length; i++) { - if (addBottom.merge[i].length === 2) { - startPos = addBottom.merge[i][0].split(','); - endPos = addBottom.merge[i][1].split(','); - mergeArrays.push([numberToLetter(startPos[1]) + (data.length - addBottom.data.length + parseInt(startPos[0])), numberToLetter(endPos[1]) + (data.length - addBottom.data.length + parseInt(endPos[0]))]) - } - } - } - } - } - - var index = 0, alignTrans = { 'left': 'left', 'center': 'center', 'right': 'right' }, - borderTypes = ['top', 'bottom', 'left', 'right']; - for (i = 0; i < columns.length; i++) { - if ((columns[i].field || columns[i].type === 'numbers') && !columns[i].hide) { - if (columns[i].width) { - widths[String.fromCharCode(64 + parseInt(++index))] = columns[i].width - } - showField[columns[i].key] = function (field, line, data, curIndex) { - var bgColor = 'ffffff', color = '000000', family = 'Calibri', size = 12, cellType = 's', - bodyIndex = curIndex - (customColumns ? 1 : cols.length) - tableStartIndex + 1, - border = { - top: { - style: 'thin', - color: { indexed: 64 } - }, - bottom: { - style: 'thin', - color: { indexed: 64 } - }, - left: { - style: 'thin', - color: { indexed: 64 } - }, - right: { - style: 'thin', - color: { indexed: 64 } - } - } - if (finalExcel.border) { - for (j = 0; j < borderTypes.length; j++) { - if (finalExcel.border[borderTypes[j]]) { - border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style - border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color - } else if (finalExcel.border['color'] || finalExcel.border['style']) { - border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style - border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color - } - } - } - if (curIndex < tableStartIndex - 1 || curIndex >= data.length - bottomLength) { - return { - v: line[field] || '', - s: {// s 代表样式 - alignment: { - horizontal: 'center', - vertical: 'center' - }, - font: { name: family, sz: size, color: { rgb: color } }, - fill: { - fgColor: { rgb: bgColor, bgColor: { indexed: 64 } } - }, - border: border - }, - t: cellType - } - } else if (bodyIndex < 0) { - // 头部样式 - bgColor = 'C7C7C7'; - if (finalExcel.head) { - bgColor = finalExcel.head.bgColor || bgColor; - color = finalExcel.head.color || color; - family = finalExcel.head.family || family; - size = finalExcel.head.size || size; - } - } else { - // 默认全局字体样式 - if (finalExcel.font) { - bgColor = finalExcel.font.bgColor || bgColor; - color = finalExcel.font.color || color; - family = finalExcel.font.family || family; - size = finalExcel.font.size || size; - } - // 默认全局边框样式 - if (finalExcel.border) { - for (j = 0; j < borderTypes.length; j++) { - if (finalExcel.border[borderTypes[j]]) { - border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style - border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color - } else if (finalExcel.border['color'] || finalExcel.border['style']) { - border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style - border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color - } - } - } - // 列上配置了自定义样式 - if (columnsMap[columnsMap.length - 1][field].excel) { - var colExcel = typeof columnsMap[columnsMap.length - 1][field].excel === 'function' ? columnsMap[columnsMap.length - 1][field].excel.call(this, line, bodyIndex, data.length - cols.length - tableStartIndex + 1 - bottomLength) : columnsMap[columnsMap.length - 1][field].excel - if (colExcel) { - bgColor = colExcel.bgColor || bgColor; - color = colExcel.color || color; - family = colExcel.family || family; - size = colExcel.size || size; - cellType = colExcel.cellType || cellType; - - if (colExcel.border) { - for (j = 0; j < borderTypes.length; j++) { - if (colExcel.border[borderTypes[j]]) { - border[borderTypes[j]].style = colExcel.border[borderTypes[j]].style || border[borderTypes[j]].style - border[borderTypes[j]].color = handleRgb(colExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color - } else if (colExcel.border['color'] || colExcel.border['style']) { - border[borderTypes[j]].style = colExcel.border['style'] || border[borderTypes[j]].style - border[borderTypes[j]].color = handleRgb(colExcel.border['color']) || border[borderTypes[j]].color - } - } - } - } - } - } - - function handleNull(val) { - if (typeof val === 'undefined' || val === null) { - return "" - } - return val; - } - - var value = bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].templet ? - typeof columnsMap[columnsMap.length - 1][field].templet === 'function' ? - $('
    ' + columnsMap[columnsMap.length - 1][field].templet(line) + '
    ').find(':input').length === 0 ? $('
    ' + columnsMap[columnsMap.length - 1][field].templet(line) + '
    ').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-field="' + field + '"]').find(':input').val() || handleNull(line[field]) - : $('
    ' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
    ').find(':input').length === 0 ? $('
    ' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
    ').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-field="' + field + '"]').find(':input').val() || handleNull(line[field]) - : bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].type === 'numbers' ? bodyIndex + 1 : handleNull(line[field]); - return { - v: value,// v 代表单元格的值 - s: {// s 代表样式 - alignment: { - horizontal: columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align ? alignTrans[columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align] : 'top', - vertical: 'center' - }, - font: { name: family, sz: size, color: { rgb: color } }, - fill: { - fgColor: { rgb: bgColor, bgColor: { indexed: 64 } } - }, - border: border - }, - t: UNHANDLED_VALUES.indexOf(value) === -1 ? cellType : 's' - }; - } - } - } - - excel.exportExcel({ - sheet1: excel.filterExportData(data, showField) - }, filename, type, { - extend: { - '!cols': excel.makeColConfig(widths, 80), - '!merges': excel.makeMergeConfig(mergeArrays), - '!rows': excel.makeRowConfig(heightConfig, 16) - } - }); - layer.close(loading); - - // 合成 excel.js 识别的 rgb - function handleRgb(rgb) { - return rgb ? { rgb: rgb } : rgb - } - - function numberToLetter(num) { - var result = []; - while (num) { - var t = num % 26; - if (!t) { - t = 26; - --num; - } - // Polyfill 兼容旧浏览器 - if (!String.fromCodePoint) (function (stringFromCharCode) { - var fromCodePoint = function (_) { - var codeUnits = [], codeLen = 0, result = ""; - for (var index = 0, len = arguments.length; index !== len; ++index) { - var codePoint = +arguments[index]; - // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity` - // The surrounding `!(...)` is required to correctly handle `NaN` cases - // The (codePoint>>>0) === codePoint clause handles decimals and negatives - if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint)) - throw RangeError("Invalid code point: " + codePoint); - if (codePoint <= 0xFFFF) { // BMP code point - codeLen = codeUnits.push(codePoint); - } else { // Astral code point; split in surrogate halves - // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae - codePoint -= 0x10000; - codeLen = codeUnits.push( - (codePoint >> 10) + 0xD800, // highSurrogate - (codePoint % 0x400) + 0xDC00 // lowSurrogate - ); - } - if (codeLen >= 0x3fff) { - result += stringFromCharCode.apply(null, codeUnits); - codeUnits.length = 0; - } - } - return result + stringFromCharCode.apply(null, codeUnits); - }; - try { // IE 8 only supports `Object.defineProperty` on DOM elements - Object.defineProperty(String, "fromCodePoint", { - "value": fromCodePoint, "configurable": true, "writable": true - }); - } catch (e) { - String.fromCodePoint = fromCodePoint; - } - }(String.fromCharCode)); - result.push(String.fromCodePoint(t + 64)); - if (!String.fromCodePoint) (function (stringFromCharCode) { - var fromCodePoint = function (_) { - var codeUnits = [], codeLen = 0, result = ""; - for (var index = 0, len = arguments.length; index !== len; ++index) { - var codePoint = +arguments[index]; - // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity` - // The surrounding `!(...)` is required to correctly handle `NaN` cases - // The (codePoint>>>0) === codePoint clause handles decimals and negatives - if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint)) - throw RangeError("Invalid code point: " + codePoint); - if (codePoint <= 0xFFFF) { // BMP code point - codeLen = codeUnits.push(codePoint); - } else { // Astral code point; split in surrogate halves - // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae - codePoint -= 0x10000; - codeLen = codeUnits.push( - (codePoint >> 10) + 0xD800, // highSurrogate - (codePoint % 0x400) + 0xDC00 // lowSurrogate - ); - } - if (codeLen >= 0x3fff) { - result += stringFromCharCode.apply(null, codeUnits); - codeUnits.length = 0; - } - } - return result + stringFromCharCode.apply(null, codeUnits); - }; - try { // IE 8 only supports `Object.defineProperty` on DOM elements - Object.defineProperty(String, "fromCodePoint", { - "value": fromCodePoint, "configurable": true, "writable": true - }); - } catch (e) { - String.fromCodePoint = fromCodePoint; - } - }(String.fromCharCode)); - num = ~~(num / 26); - } - return result.reverse().join(''); - } - }, - startsWith: function (content, str) { - var reg = new RegExp("^" + str); - return content && reg.test(content); - }, - // 深度克隆-不丢失方法 - deepClone: function (obj) { - var newObj = Array.isArray(obj) ? [] : {} - if (obj && typeof obj === "object") { - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key]; - } - } - } - return newObj - }, - deepStringify: function (obj) { - var JSON_SERIALIZE_FIX = { - PREFIX: "[[JSON_FUN_PREFIX_", - SUFFIX: "_JSON_FUN_SUFFIX]]" - }; - return JSON.stringify(obj, function (key, value) { - if (typeof value === 'function') { - return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX; - } - return value; - }); - }, - /* layui table 中原生的方法 */ - getScrollWidth: function (elem) { - var width = 0; - if (elem) { - width = elem.offsetWidth - elem.clientWidth; - } else { - elem = document.createElement('div'); - elem.style.width = '100px'; - elem.style.height = '100px'; - elem.style.overflowY = 'scroll'; - - document.body.appendChild(elem); - width = elem.offsetWidth - elem.clientWidth; - document.body.removeChild(elem); - } - return width; - } - , getCompleteCols: function (origin) { - var cols = this.deepClone(origin); - var i, j, k, cloneCol; - for (i = 0; i < cols.length; i++) { - for (j = 0; j < cols[i].length; j++) { - if (!cols[i][j].exportHandled) { - if (cols[i][j].rowspan > 1) { - cloneCol = this.deepClone(cols[i][j]) - cloneCol.exportHandled = true; - k = i + 1; - while (k < cols.length) { - cols[k].splice(j, 0, cloneCol) - k++ - } - } - if (cols[i][j].colspan > 1) { - cloneCol = this.deepClone(cols[i][j]) - cloneCol.exportHandled = true; - for (k = 1; k < cols[i][j].colspan; k++) { - cols[i].splice(j, 0, cloneCol) - } - j = j + parseInt(cols[i][j].colspan) - 1 - } - } - } - } - return cols[cols.length - 1]; - } - , parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本 - var str = item3.templet ? function () { - return typeof item3.templet === 'function' - ? item3.templet(tplData) - : laytpl($(item3.templet).html() || String(content)).render(tplData) - }() : content; - return text ? $('
    ' + str + '
    ').text() : str; - } - , cache: cache + var $ = layui.jquery, + table = layui.table, + form = layui.form, + laydate = layui.laydate, + laytpl = layui.laytpl, + util = layui.util, + excel = layui.excel, + columnsTimeOut, + dorpListTimeOut, + conditionTimeOut, + bfColumnTimeOut, + bfCond1TimeOut, + isFilterReload = {}, + SOUL_ROW_INDEX = 'SOUL_ROW_INDEX', + cache = {}, + HIDE = 'layui-hide', + maxId = 1, + UNHANDLED_VALUES = [undefined, '', null], + where_cache = {}, + isFilterCache = {}, + table_cache = {}, + conditionChangeItems = { + 'eq': '等于', + 'ne': '≠ 不等于', + 'gt': '> 大于', + 'ge': '≥ 大于等于', + 'lt': '< 小于', + 'le': '≤ 小于等于', + 'contain': '包含', + 'notContain': '不包含', + 'start': '以...开头', + 'end': '以...结尾', + 'null': '为空', + 'notNull': '不为空' + }, + dateTimeItems = { + 'all': '全部', + 'yesterday': '昨天', + 'thisWeek': '本周', + 'lastWeek': '上周', + 'thisMonth': '本月', + 'thisYear': '今年' + }, + defaultFilterItems = ['column', 'data', 'condition', 'editCondition', 'excel'], + itemsMap = { + 'column': 'soul-column', + 'data': 'soul-dropList', + 'condition': 'soul-condition', + 'editCondition': 'soul-edit-condition', + 'excel': 'soul-export', + 'clearCache': 'soul-clear-cache', + }, + modeMapItems = { + 'in': 'data', + 'condition': 'condition', + 'date': 'condition', + }, + revertMode = { + 'data': { + 'mode': 'condition', + 'type': 'eq', + 'value': '', + }, + 'condition': { + 'mode': 'in', + 'values': [], + }, }; - // 输出 - exports('tableFilter', mod); + // 封装方法 + var mod = { + /** + * 摧毁render数据 + * @param myTables + */ + destroy: function (myTables) { + if (myTables) { + if (Array.isArray(myTables)) { + for (var i = 0; i < myTables.length; i++) { + deleteRender(myTables[i]) + } + } else { + deleteRender(myTables); + } + } + + function deleteRender(myTable) { + if (!myTable) { + return; + } + var tableId = myTable.config.id; + $('#soul-filter-list' + tableId).remove(); + $('#soulCondition' + tableId).remove(); + $('#soulDropList' + tableId).remove(); + + delete isFilterReload[tableId]; + delete where_cache[tableId]; + delete table_cache[tableId]; + } + }, + clearFilter: function (myTable) { + if (typeof myTable === 'string') { + myTable = table_cache[myTable] + } + if (!where_cache[myTable.id] || !where_cache[myTable.id].filterSos || where_cache[myTable.id].filterSos === "[]") { + return; + } + where_cache[myTable.id].filterSos = "[]" + this.soulReload(myTable, true) + if (table_cache[myTable.id].where && table_cache[myTable.id].where.filterSos && table_cache[myTable.id].where.filterSos !== "[]") { + table_cache[myTable.id].where.filterSos = "[]" + } + }, + render: function (myTable) { + var _this = this, + $table = $(myTable.elem), + $tableMain = $table.next().children('.layui-table-box').children('.layui-table-main'), + $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'), + $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'), + $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'), + tableId = myTable.id, + columns = _this.getCompleteCols(myTable.cols), + filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, + needFilter = false, // 是否存在筛选列需要进行初始化 + initFilter = false, // 是否为第一次筛选 + mainExcel = typeof myTable.excel === 'undefined' || ((myTable.excel && (typeof myTable.excel.on === 'undefined' || myTable.excel.on)) ? myTable.excel : false), + i, j; + + for (i = 0; i < columns.length; i++) { + if (columns[i].field && columns[i].filter) { + needFilter = true; + if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.soul-table-filter').length === 0) { + initFilter = true; + if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) { + $tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide() + $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') + } else { + $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') + } + if ($fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) { + $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide() + $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') + } else { + $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') + } + if ($fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) { + $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide() + $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') + } else { + $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('') + } + } + } + } + table_cache[myTable.id] = myTable // 缓存table配置 + isFilterCache[myTable.id] = needFilter; + if (!needFilter) { + // 缓存所有数据 + if (myTable.url && !myTable.page) { + // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题 + cache[myTable.id] = layui.table.cache[myTable.id] + } else { + cache[myTable.id] = myTable.data || layui.table.cache[myTable.id] + } + return; + } //如果没筛选列,直接退出 + + // 渲染底部筛选条件 + if (!(myTable.filter && typeof myTable.filter.bottom !== 'undefined' && !myTable.filter.bottom) && $table.next().children('.soul-bottom-contion').length === 0) { + $table.next().children('.layui-table-box').after('') + var changeHeight = $table.next().children('.layui-table-box').children('.layui-table-body').outerHeight() - $table.next().children('.soul-bottom-contion').outerHeight(); + if (myTable.page && $table.next().children('.layui-table-page').hasClass('layui-hide')) { + changeHeight += $table.next().children('.layui-table-page').outerHeight() + } + $table.next().children('.layui-table-box').children('.layui-table-body').css('height', changeHeight) + var fixHeight = changeHeight - _this.getScrollWidth($tableMain[0]), + layMainTableHeight = $tableMain.children('table').height() + $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').css('height', layMainTableHeight >= fixHeight ? fixHeight : 'auto') + $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', ($table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').width()) + 'px'); + $table.next().children('.soul-bottom-contion').children('.editCondtion').children('a').on('click', function () { + _this.showConditionBoard(myTable); + }) + } + + /** + * 不重载表头数据,重新绑定事件后结束 + */ + if (!initFilter || isFilterReload[myTable.id] || myTable.isSoulFrontFilter) { + isFilterReload[myTable.id] = false + myTable['isSoulFrontFilter'] = false + // 同步选中状态 + if (!myTable.url && myTable.page && myTable.data) { + myTable.data.forEach(function (row) { + for (i = 0; i < cache[myTable.id].length; i++) { + if (cache[myTable.id][i][SOUL_ROW_INDEX] === row[SOUL_ROW_INDEX]) { + cache[myTable.id][i] = row + break; + } + } + }) + } + this.bindFilterClick(myTable); + return; + } else { + if (!myTable.url && myTable.page && myTable.data && myTable.data.length > myTable.limit) { + // 前端分页大于一页,修复 index (用于排序恢复时需要通过这个排序) + layui.each(myTable.data, function (index, item) { + item[myTable.indexName] = index; + }) + } + /** + * 缓存所有数据 + */ + if (myTable.url && !myTable.page) { + // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题 + cache[myTable.id] = layui.table.cache[myTable.id] + } else { + cache[myTable.id] = myTable.data || layui.table.cache[myTable.id] + } + // 给表格数据添加位置标志 + cache[myTable.id].forEach(function (item, index) { + item[SOUL_ROW_INDEX] = index + }) + + if (myTable.filter && myTable.filter.clearFilter) { + if (myTable.where && myTable.where.filterSos && JSON.parse(myTable.where.filterSos).length > 0) { + // 重新查询新数据 + myTable.where.filterSos = '[]'; + where_cache[myTable.id] = myTable.where || {} + _this.soulReload(myTable, false); + return; + } else { + where_cache[myTable.id] = myTable.where || {} + } + } else if ((typeof myTable.url !== 'undefined' && myTable.page ? typeof myTable.where.filterSos === 'undefined' : true) && where_cache[myTable.id] && JSON.parse(where_cache[myTable.id].filterSos || '[]').length > 0) { + myTable.where['filterSos'] = where_cache[myTable.id].filterSos + where_cache[myTable.id] = myTable.where; + _this.soulReload(myTable, false); + return; + } else { + where_cache[myTable.id] = myTable.where || {} + } + } + + // 第一次渲染时,追加数据 + if ($('#soul-filter-list' + tableId).length === 0) { + + if (typeof myTable.soulSort === 'undefined' || myTable.soulSort) { + if (typeof $table.attr('lay-filter') === 'undefined') { + $table.attr('lay-filter', tableId); + } + table.on('sort(' + $table.attr('lay-filter') + ')', function (obj) { + + // 同步分页信息 + myTable.limit = table_cache[myTable.id].limit + + if (myTable.url && myTable.page) { + // 后台分页 + where_cache[myTable.id].field = obj.field; + where_cache[myTable.id].order = obj.type; + isFilterReload[myTable.id] = true; + table.render($.extend(myTable, { + initSort: obj + , where: where_cache[myTable.id] + , page: { + curr: 1 //重新从第 1 页开始 + } + })); + } else if (!myTable.url && myTable.page) { + // 前台分页 + if (obj.type === 'asc') { //升序 + cache[myTable.id] = layui.sort(cache[myTable.id], obj.field) + } else if (obj.type === 'desc') { //降序 + cache[myTable.id] = layui.sort(cache[myTable.id], obj.field, true) + } else { //清除排序 + cache[myTable.id] = layui.sort(cache[myTable.id], myTable.indexName) + } + myTable.initSort = obj; + myTable.page = {curr: 1}; + _this.soulReload(myTable, false) + } + }); + } + + var soulFilterList = [], + filterItemsHtml = { + column: '
  • 表格列
  • ', + data: '
  • 筛选数据
  • ', + condition: '
  • 筛选条件
  • ', + editCondition: '
  • 编辑筛选条件
  • ', + excel: '
  • 导出excel
  • ', + clearCache: '
  • 清除缓存
  • ' + }; + soulFilterList.push('
    '); + soulFilterList.push('
    '); + $('body').append(soulFilterList.join('')); + + + // 显示隐藏列 + var liClick = true; + form.on('checkbox(changeColumns' + tableId + ')', function (data) { + liClick = false; + var columnkey = data.value + if (data.elem.checked) { + $table.next().find('[data-key=' + columnkey + ']').removeClass(HIDE); + } else { + $table.next().find('[data-key=' + columnkey + ']').addClass(HIDE); + } + // 同步配置 + for (i = 0; i < myTable.cols.length; i++) { + for (j = 0; j < myTable.cols[i].length; j++) { + if ((myTable.index + '-' + myTable.cols[i][j].key) === columnkey) { + myTable.cols[i][j]['hide'] = !data.elem.checked + } + } + } + if (layui.soulTable) { + layui.soulTable.fixTableRemember(myTable) + } + $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr.childTr').children('td').attr('colspan', $table.next().children('.layui-table-box').children('.layui-table-header').find('thead>tr>th:visible').length) + table.resize(tableId) + }); + $('#soul-columns' + tableId + '>li[data-value]').on('click', function () { + if (!$(this).find(':checkbox').is(':disabled')) { //disabled禁止点击 + if (liClick) { + $(this).find('div.layui-form-checkbox').trigger('click'); + } + liClick = true; + } + }); + + // 全选-反选事件 + $('#soul-dropList' + tableId + ' .check [data-type]').on('click', function () { + + switch ($(this).data('type')) { + case 'all': + $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:not(:checked)').prop('checked', true); + break; + case 'reverse': + $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]').each(function () { + $(this).prop('checked', !$(this).prop('checked')) + }); + break; + case 'none': + $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:checked').prop('checked', false); + break; + } + form.render('checkbox', 'orm'); + _this.updateDropList(myTable, $('#main-list' + tableId).data('field')); + return false; + }); + + // 关键字搜索 + $('#soul-dropList' + tableId + ' .filter-search input').on('input', function () { + var key = $(this).val(); + if (key === '') { + $('#soul-dropList' + tableId + '>ul>li').show(); + } else { + $('#soul-dropList' + tableId + '>ul>li').hide(); + $('#soul-dropList' + tableId + '>ul>li[data-value*="' + key.toLowerCase() + '"]').show(); + } + }) + + // 显示表格列 + $('#main-list' + tableId + ' .soul-column').on('mouseover', function (e) { + _this.hideDropList(myTable); + _this.hideCondition(myTable); + e.stopPropagation(); + if (columnsTimeOut) { + clearTimeout(columnsTimeOut) + } + columns = _this.getCompleteCols(myTable.cols) + for (i = 0; i < columns.length; i++) { + $('#soul-columns' + tableId).find('li[data-value="' + columns[i].field + '"]>input').prop('checked', !columns[i].hide); + } + form.render('checkbox', 'orm'); + $('#soul-columns' + tableId).show(); + var left, animate; + if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-columns' + tableId).width() < document.body.clientWidth) { + left = $(this).parent().offset().left + $(this).parent().width(); + animate = 'fadeInLeft' + } else { + left = $(this).parent().offset().left - $('#soul-columns' + tableId).width(); + animate = 'fadeInRight' + } + $('#soul-columns' + tableId).css({'top': $(this).offset().top, 'left': left}) + .removeClass().addClass(animate + ' animated'); + }); + // 显示数据下拉 + $('#main-list' + tableId + ' .soul-dropList').on('mouseover', function (e) { + if ($('#soul-dropList' + tableId).is(':visible') && !$('#soul-dropList' + tableId).hasClass('fadeOutLeft')) { + return false; + } + _this.hideColumns(myTable); + _this.hideCondition(myTable); + e.stopPropagation(); + if (dorpListTimeOut) { + clearTimeout(dorpListTimeOut); + } + $('#soul-dropList' + tableId + '>.filter-search>input').val(''); + $('#soul-dropList' + tableId).show(); + var left, animate, field = $('#main-list' + tableId).data('field'); + if ($('#main-list' + tableId).offset().left + $('#soul-dropList' + tableId).width() + $('#soul-dropList' + tableId).width() < document.body.clientWidth) { + left = $('#main-list' + tableId).offset().left + $('#main-list' + tableId).width(); + animate = 'fadeInLeft'; + } else { + left = $('#main-list' + tableId).offset().left - $('#soul-dropList' + tableId).width(); + animate = 'fadeInRight'; + } + + $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false); + var where = where_cache[myTable.id] || {}, + filterSos = JSON.parse(where.filterSos ? where.filterSos : null), + id = '', prefix = ''; + if (filterSos) { + for (i = 0; i < filterSos.length; i++) { + if (filterSos[i].head && filterSos[i].mode === "in" && filterSos[i].field === field) { + id = filterSos[i].id; + prefix = filterSos[i].prefix; + for (j = 0; j < filterSos[i].values.length; j++) { + $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSos[i].values[j] + '"]').prop('checked', true); + } + break; + } + } + } + $('#soul-dropList' + tableId + '>ul').data({ + head: true, + 'id': id, + prefix: prefix, + refresh: true, + split: $('#main-list' + tableId).data('split') + }).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone()); + + $('#soul-dropList' + tableId).css({'top': $(this).offset().top, 'left': left}) + .show().removeClass().addClass(animate + ' animated'); + setTimeout(function () { + $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框 + form.render('checkbox', 'orm'); + }, 1); + + // 监听筛选数据 + var liClick = true; + form.on('checkbox(soulDropList' + tableId + ')', function (data) { + liClick = false; + _this.updateDropList(myTable, field); + }); + + $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () { + if (liClick) { + $(this).find('div.layui-form-checkbox').trigger('click'); + } + liClick = true; + }) + }); + + // 显示筛选条件 + $('#main-list' + tableId + ' .soul-condition').on('mouseover', function (e) { + if ($('#soul-condition' + tableId).is(':visible') && !$('#soul-condition' + tableId).hasClass('fadeOutLeft')) { + return false; + } + _this.hideColumns(myTable); + _this.hideDropList(myTable); + e.stopPropagation(); + if (conditionTimeOut) { + clearTimeout(conditionTimeOut); + } + var documentWidth = document.body.clientWidth; + $('#soul-condition' + tableId).show(); + var left, animate, field = $(this).parent().data('field'); + if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-condition' + tableId).width() < documentWidth) { + left = $(this).parent().offset().left + $(this).parent().width(); + animate = 'fadeInLeft' + } else { + left = $(this).parent().offset().left - $('#soul-condition' + tableId).width(); + animate = 'fadeInRight' + } + + var filterSo, conditionHtml = [], + where = where_cache[myTable.id] || {}, + filterSos = JSON.parse(where.filterSos ? where.filterSos : null); + if (filterSos) { + for (i = 0; i < filterSos.length; i++) { + if (filterSos[i].head && filterSos[i].field === field && (filterSos[i].mode === "date" || filterSos[i].mode === 'group')) { + filterSo = filterSos[i] + break; + } + } + } + + var filterType = $(this).parent().data('type'); + if (_this.startsWith(filterType, 'date')) { + _this.showDate(myTable, field, filterSo, animate, $(this).offset().top, $(this).parent().offset().left + $(this).parent().width(), 'down', true); + } else { + /** + * 筛选条件 + */ + var fieldMap = {}; + for (i = 0; i < columns.length; i++) { + if (columns[i].field) { + fieldMap[columns[i]['field']] = columns[i] + } + } + // 查询条件 + var selectStr = ""; + conditionHtml.push(''); + if (filterSo && filterSo.children && filterSo.children.length > 0) { + for (i = 0; i < filterSo.children.length; i++) { + var id = filterSo.children[i].id, + prefix = filterSo.children[i].prefix, + type = filterSo.children[i].type, + value = filterSo.children[i].value; + conditionHtml.push(''); + if (i === 0) { + conditionHtml.push('') + } else { + conditionHtml.push( + '') + } + conditionHtml.push('') + conditionHtml.push(''); + conditionHtml.push(''); + conditionHtml.push('') + } + } else { + conditionHtml.push('' + + '' + + '' + + '' + + '' + + ''); + } + conditionHtml.push('
    ' + fieldMap[field].title + '' + + '
    ' + + ' ' + + '
    ' + + '
    ' + fieldMap[field].title + '
    ' + selectStr + + '
    ') + + $('#soul-condition' + tableId).data({head: true, id: filterSo ? filterSo.id || '' : ''}) + .html(conditionHtml.join('')) + .css({'top': $(this).offset().top, 'left': left}) + .show().removeClass().addClass(animate + ' animated'); + + $('.condition-table').on('click', function () { + return false; + }) + + // 新增与查询 + $('#soul-condition' + tableId + ' button[data-type]').on('click', function () { + /** + * 新增 + */ + if ($(this).data('type') === 'add') { + var groupId = $('#soul-condition' + tableId).data('id'), + head = $('#soul-condition' + tableId).data('head'), + type = 'eq', + filterSo, + $tr1 = $('#soul-condition' + tableId).find('tr:eq(0)'); + + if (groupId) { + filterSo = { + head: head, + prefix: 'and', + field: field, + mode: 'condition', + type: type, + value: '', + groupId: groupId + } + } else { + filterSo = { + head: head, + prefix: head ? 'and' : 'and', + mode: 'group', + field: field, + children: [{ + id: _this.getDifId(), + prefix: 'and', + field: field, + mode: 'condition', + type: $tr1.find('select').val(), + value: $tr1.find('.value').val() + }, { + id: _this.getDifId(), + prefix: 'and', + field: field, + mode: 'condition', + type: type, + value: '' + }] + } + } + + _this.updateWhere(myTable, filterSo); + if (!groupId) { + $('#soul-condition' + tableId).data('id', filterSo.id); + $tr1.data('id', filterSo.children[0].id); + } + // $tableHead.find('thead>tr>th[data-field="'+field+'"] .soul-table-filter').attr('soul-filter','true'); + var newId = groupId ? filterSo.id : filterSo.children[1].id; + var newTr = '' + + '
    ' + + ' ' + + '
    ' + + '' + + '
    ' + selectStr + '
    ' + + '
    ' + + ''; + + $('#soul-condition' + tableId + ">table>tbody").append(newTr) + $('#soul-condition' + tableId).find('.del:last').on('click', function () { //删除 + delCurrentTr(this) + }); + + // input同步筛选条件 + $('#soul-condition' + tableId + ' input.value:last').on('input', function () { + updateTrWhere($(this).parents('tr:eq(0)')) + }); + } else if ($(this).data('type') === 'search') { + /** + * 查询 + */ + _this.soulReload(myTable); + } + form.render('select', 'orm'); + form.render('checkbox', 'orm'); + return false; + }); + + // input同步筛选条件 + $('#soul-condition' + tableId + ' input.value').on('input', function () { + updateTrWhere($(this).parents('tr:eq(0)')); + }); + + // 当前行改动时,同步where条件 + function updateTrWhere($tr) { + var id = $tr.data('id'), + groupId = $('#soul-condition' + tableId).data('id'), + prefix = $tr.find('input[lay-filter="soul-coondition-switch"]:checked').prop('checked') ? 'and' : 'or', + type = $tr.find('select').val(), + value = $tr.find('.value').val(), + head = $('#soul-condition' + tableId).data('head'); + + if (groupId) { + filterSo = { + id: id, + prefix: prefix, + mode: 'condition', + field: field, + type: type, + value: value, + groupId: groupId + } + } else { + filterSo = { + head: head, + prefix: head ? 'and' : 'and', + mode: 'group', + field: field, + children: [{ + id: _this.getDifId(), + prefix: prefix, + mode: 'condition', + field: field, + type: type, + value: value, + groupId: groupId + }] + } + } + _this.updateWhere(myTable, filterSo) + if (!groupId) { + $('#soul-condition' + tableId).data('id', filterSo.id); + $tr.data('id', filterSo.children[0].id) + } else if (!id) { + $tr.data('id', filterSo.id); + } + } + + // select同步筛选条件 + form.on('select(conditionChange)', function (data) { + if (data.value === 'null' || data.value === 'notNull') { + $(this).parents('tr').find('input.value').hide(); + } else { + $(this).parents('tr').find('input.value').show(); + } + updateTrWhere($(data.elem).parents('tr:eq(0)')); + }) + + // radio同步筛选条件 + form.on('switch(soul-coondition-switch)', function (data) { + updateTrWhere($(this).parents('tr:eq(0)')); + }); + + // 删除当前行 + $('#soul-condition' + tableId + ' .del').on('click', function () { + delCurrentTr(this) + }); + + function delCurrentTr(obj) { + + var id; + + if ($(obj).parents('table:eq(0)').find('tr').length === 1) { + id = $('#soul-condition' + tableId).data('id'); + $('#soul-condition' + tableId).data('id', ''); + $(obj).parents('tr:eq(0)').find('select').val('eq') + $(obj).parents('tr:eq(0)').find('.value').val('').show() + form.render('select', 'orm'); + } else { + id = $(obj).parents('tr:eq(0)').data('id'); + if ($(obj).parents('tr:eq(0)').index() === 0) { + $(obj).parents('table:eq(0)').find('tr:eq(1)>td:eq(0)').html(fieldMap[field].title).addClass('soul-condition-title') + } + $(obj).parents('tr:eq(0)').remove() + } + if (id) { + _this.updateWhere(myTable, { + id: id, + delete: true + }) + } + } + } + form.render('select', 'orm'); + form.render('checkbox', 'orm'); + + }); + + $('#soul-columns' + tableId + ', #soul-dropList' + tableId).on('mouseover', function (e) { + e.stopPropagation(); + }); + $('#main-list' + tableId + ' .soul-edit-condition').on('mouseover', function (e) { + _this.hideColumns(myTable) + _this.hideDropList(myTable) + _this.hideCondition(myTable) + e.stopPropagation(); + }).on('click', function () { + $('#main-list' + tableId).hide(); + _this.showConditionBoard(myTable) + }); + $('#main-list' + tableId + ' .soul-export').on('mouseover', function (e) { + _this.hideColumns(myTable) + _this.hideDropList(myTable) + _this.hideCondition(myTable) + e.stopPropagation(); + }).on('click', function () { + $('#main-list' + tableId).hide(); + _this.export(table_cache[myTable.id]) + }); + + $('#main-list' + tableId + ' .soul-clear-cache').on('mouseover', function (e) { + _this.hideColumns(myTable) + _this.hideDropList(myTable) + _this.hideCondition(myTable) + e.stopPropagation(); + }).on('click', function () { + $('#main-list' + tableId).hide(); + if (layui.soulTable) { + layui.soulTable.clearCache(myTable) + } + layer.msg('已还原!', {icon: 1, time: 1000}) + }); + + $('#main-list' + tableId).on('mouseover', function (e) { + var curX = e.pageX; + var curY = e.pageY; + var div = $(this); + var y1 = div.offset().top; //div上面两个的点的y值 + var y2 = y1 + div.height();//div下面两个点的y值 + var x1 = div.offset().left; //div左边两个的点的x值 + var x2 = x1 + div.width(); //div右边两个点的x的值 + if (curX <= x1 || curX >= x2 || curY <= y1 || curY >= y2) { + } else { + _this.hideColumns(myTable); + _this.hideDropList(myTable); + _this.hideCondition(myTable); + } + }); + } else { + + types = {}; //存储过滤数据的类型 + // 根据表格列显示 + for (i = 0; i < columns.length; i++) { + if (columns[i].type === 'checkbox' || !columns[i].field) { + continue; + } + //存储过滤数据的类型 + if (columns[i].filter && columns[i].filter.type) { + if (columns[i].filter.field) { + types[columns[i].filter.field] = columns[i].filter.type; + } else { + types[columns[i].field] = columns[i].filter.type; + } + } + } + if (JSON.stringify(types).length !== 2) { + myTable.where['tableFilterType'] = JSON.stringify(types); + } + + } + + // 初始化下拉数据 + if ($('#soulDropList' + tableId).length === 0) { + $('body').append(''); + } + + if ($tableHead.find('.soul-table-filter').length > 0) { + var columnField = [], mainDataSwitch = filterItems.indexOf('data') !== -1; + $tableHead.find('.soul-table-filter').each(function (index, elem) { + if ($(this).data('column') && (mainDataSwitch ? (!$(this).data('items') || $(this).data('items').split(',').indexOf('data') !== -1) : $(this).data('items').split(',').indexOf('data') !== -1)) { + columnField.push($(this).data('column')); + } + }); + if (columnField.length > 0) { + if (typeof myTable.url !== 'undefined' && myTable.page) { + var datas = JSON.parse(JSON.stringify(myTable.where)), url = myTable.url; + datas['columns'] = JSON.stringify(columnField); + $.ajax({ + url: url, + data: datas, + dataType: 'json', + method: 'post', + headers: myTable.headers || {}, + contentType: myTable.contentType, + success: function (result) { + + var uls = []; + for (var key in result) { + var list = result[key]; + if (!((list.length === 1 && list[0] === '') || list.length === 0)) { + var ul = []; + ul.push("
      "); + + var columnsConfigs = columns; + for (j = 0; j < columnsConfigs.length; j++) { + if (columnsConfigs[j].field === key) { + if (columnsConfigs[j].filter.split) { + var tempList = [] + for (i = 0; i < list.length; i++) { + var tempList2 = list[i].split(columnsConfigs[j].filter.split) + for (var k = 0; k < tempList2.length; k++) { + if (tempList.indexOf(tempList2[k]) === -1) { + tempList.push(tempList2[k]); + } + } + } + list = tempList; + } + list.sort(function (a, b) { + if (isNaN(a) || isNaN(b)) { + return String(a) >= String(b) + } else { + return Number(a) - Number(b) + } + }) + for (i = 0; i < list.length; i++) { + if (UNHANDLED_VALUES.indexOf(list[i]) === -1) { + var line = {}; + line[key] = list[i]; + ul.push('
    • ') + } + } + break; + } + } + + ul.push("
    "); + uls.push(ul.join('')); + } else { + uls.push("
    • (无数据)
    ") + } + } + $('#soulDropList' + tableId).html(uls.join('')); + }, + error: function () { + // layer.msg('列筛选数据查询失败!', {icon: 2, anim: 6}) + } + }) + } else { + var tableDatas = cache[myTable.id]; + var dropDatas = {}; + for (i = 0; i < tableDatas.length; i++) { + for (j = 0; j < columnField.length; j++) { + var value = typeof tableDatas[i][columnField[j]] === 'undefined' ? '' : tableDatas[i][columnField[j]]; + if (dropDatas[columnField[j]]) { + if (dropDatas[columnField[j]].indexOf(value) === -1) { + dropDatas[columnField[j]].push(value); + } + } else { + dropDatas[columnField[j]] = [value] + } + } + } + + var columnsConfigs = columns; + var uls = []; + for (j = 0; j < columnsConfigs.length; j++) { + var key = columnsConfigs[j].field; + var list = dropDatas[key]; + if (list && !(list.length === 1 && list[0] === '')) { + if (columnsConfigs[j].filter && columnsConfigs[j].filter.split) { + var tempList = [] + for (i = 0; i < list.length; i++) { + var tempList2 = String(list[i]).split(columnsConfigs[j].filter.split); + for (var k = 0; k < tempList2.length; k++) { + if (tempList.indexOf(tempList2[k]) === -1) { + tempList.push(tempList2[k]) + } + } + } + list = tempList; + } + list.sort(function (a, b) { + if (isNaN(a) || isNaN(b)) { + return String(a) >= String(b) + } else { + return Number(a) - Number(b) + } + }) + var ul = []; + ul.push("
      "); + for (i = 0; i < list.length; i++) { + if (UNHANDLED_VALUES.indexOf(list[i]) === -1) { + var line = {}; + line[key] = list[i]; + ul.push('
    • ') + } + } + ul.push("
    "); + uls.push(ul.join('')); + } else { + uls.push("
    • (无数据)
    ") + } + } + $('#soulDropList' + tableId).html(uls.join('')); + } + } else { + _this.bindFilterClick(myTable); + } + } + + this.bindFilterClick(myTable); + }, + showConditionBoard: function (myTable) { + var _this = this, + tableId = myTable.id, + where = where_cache[myTable.id] || {}, + tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {}, + filterSos = where.filterSos ? JSON.parse(where.filterSos) : [], + filterBoard = [], fieldMap = {}, firstColumn, curItems, + filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, + columns = _this.getCompleteCols(myTable.cols), + i; + for (i = 0; i < columns.length; i++) { + if (columns[i].field && columns[i].filter) { + if (!firstColumn) { + firstColumn = columns[i] + } + curItems = columns[i].filter.items || filterItems; + fieldMap[columns[i]['field']] = { + title: columns[i].title, + items: curItems + } + } + } + filterBoard.push('
    ') + filterBoard.push('
    ') + filterBoard.push('') + filterBoard.push('
    ') + filterBoard.push('
      ') + for (i = 0; i < filterSos.length; i++) { + groupHtml(filterSos[i], filterBoard, fieldMap, i === 0, i === (filterSos.length - 1)) + } + filterBoard.push('
    ') + filterBoard.push('
    ') + filterBoard.push('
    ') + var _width = document.body.clientWidth > parseInt('480') ? '480px' : document.body.clientWidth - 10 + 'px' + var _height = document.body.clientHeight > parseInt('480') ? '480px' : document.body.clientHeight - 10 + 'px' + layer.open({ + title: '编辑条件', + type: 1, + offset: 'auto', + area: [_width, _height], + content: filterBoard.join('') + }) + form.render(null, 'soul-edit-out'); + + form.on('checkbox(out_auto)', function (data) { + if (data.elem.checked) { + _this.soulReload(myTable); + } + }) + + function groupHtml(filterSo, filterBoard, fieldMap, isFirst, isLast) { + var id = filterSo.id, + field = filterSo.field, + mode = filterSo.mode, + type = filterSo.type, + isOr = filterSo.prefix === 'or'; + filterBoard.push('
  • '); + filterBoard.push('
    ') + // if (!isFirst) { //第一个隐藏 与或 + filterBoard.push('
    ') + // } + switch (mode) { + case 'in': + filterBoard.push('
    ' + (fieldMap[field].title) + '
    '); + filterBoard.push('
    筛选数据
    '); + filterBoard.push('
    共' + (filterSo.values ? filterSo.values.length : 0) + '条数据
    '); + filterBoard.push('
    '); + break; + case 'date': + filterBoard.push('
    ' + (fieldMap[field].title) + '
    '); + filterBoard.push('
    选择日期
    '); + filterBoard.push('
    ' + (filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type]) + '
    '); + filterBoard.push('
    '); + break; + case 'condition': + filterBoard.push('
    ' + (fieldMap[field].title) + '
    '); + filterBoard.push('
    ' + conditionChangeItems[filterSo.type] + '
    '); + if (type !== 'null' && type !== 'notNull') { + filterBoard.push('
    ' + (typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value) + '
    '); + } + filterBoard.push('
    '); + break; + case 'group': + filterBoard.push('
    分组
    ') + filterBoard.push('') + filterBoard.push('
    '); + filterBoard.push('
      '); + if (filterSo.children) { + for (var i = 0; i < filterSo.children.length; i++) { + groupHtml(filterSo.children[i], filterBoard, fieldMap, i === 0, i === (filterSo.children.length - 1)); + } + } + filterBoard.push('
    '); + break; + } + filterBoard.push('
  • ') + } + + // prefix + form.on('switch(soul-edit-switch)', function (data) { + changePrefix(data) + }) + + // column + $('.soul-edit-out .item-field').on('click', function (e) { + e.stopPropagation(); + showColums(this) + }) + // type + $('.soul-edit-out .item-type').on('click', function (e) { + e.stopPropagation(); + showTypes(this) + }) + // value + $('.soul-edit-out .item-value').on('click', function (e) { + e.stopPropagation(); + showValue(this) + }) + // delete + $('.soul-edit-out .delete-item').on('click', function () { + var id = $(this).parent().data('id'), + refresh = $('.soul-edit-out .out_auto').prop('checked'); + $(this).parent().remove(); + _this.updateWhere(myTable, { + id: id, + delete: true + }) + if (refresh) { + _this.soulReload(myTable); + } + }) + + function changePrefix(data) { + var prefix = data.elem.checked ? 'and' : 'or', + id = $(data.elem).parents('li:eq(0)').data('id'), + refresh = $('.soul-edit-out .out_auto').prop('checked'); + + $(data.elem).parents('li:eq(0)').data('prefix', prefix); + _this.updateWhere(myTable, { + id: id, + prefix: prefix + }) + + if (refresh) { + _this.soulReload(myTable) + } + } + + function showColums(obj) { + _this.hideDropList(myTable); + _this.hideCondition(myTable); + _this.hideColumns(myTable); + _this.hideBfPrefix(myTable) + _this.hideBfType(myTable); + var top = $(obj).offset().top + $(obj).outerHeight(), + left = $(obj).offset().left; + + $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') + $('#soul-bf-column' + tableId) + .data('field', $(obj).parent().data('field')) + .data('id', $(obj).parent().data('id')) + .data('mode', $(obj).parent().data('mode')) + .data('group', $(obj).parents('li:eq(2)').data('id') || '') + .data('refresh', $('.soul-edit-out .out_auto').prop('checked')) + .show() + .css({top: top, left: left}) + .removeClass().addClass('fadeInUp animated') + .find('li[data-field="' + $(obj).parent().data('field') + '"]') + .addClass('soul-bf-selected') + } + + function showTypes(obj) { + _this.hideDropList(myTable); + _this.hideCondition(myTable); + _this.hideColumns(myTable); + _this.hideBfColumn(myTable); + _this.hideBfPrefix(myTable); + var top = $(obj).offset().top + $(obj).outerHeight(), + left = $(obj).offset().left, + field = $(obj).parent().data('field'); + + $('#soul-bf-type' + tableId + ' li').hide() + if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) { + $('#soul-bf-type' + tableId + ' li[data-mode=date]').show() + } + if (fieldMap[field].items.indexOf('data') !== -1) { + $('#soul-bf-type' + tableId + ' li[data-mode=in]').show() + } + if (fieldMap[field].items.indexOf('condition') !== -1) { + $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show() + } + + $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') + switch ($(obj).parent().data('mode')) { + case 'in': + $('#soul-bf-type' + tableId).find('li[data-mode="in"]') + .addClass('soul-bf-selected') + break; + case 'date': + $('#soul-bf-type' + tableId).find('li[data-mode="date"]') + .addClass('soul-bf-selected') + case 'condition': + $('#soul-bf-type' + tableId).find('li[data-value="' + $(obj).parent().data('type') + '"]') + .addClass('soul-bf-selected') + } + + $('#soul-bf-type' + tableId) + .data('type', $(obj).parent().data('type')) + .data('mode', $(obj).parent().data('mode')) + .data('id', $(obj).parent().data('id')) + .data('group', $(obj).parents('li:eq(2)').data('id') || '') + .data('refresh', $('.soul-edit-out .out_auto').prop('checked')) + .show() + .css({top: top, left: left}) + .removeClass().addClass('fadeInUp animated') + } + + function showValue(obj) { + _this.hideColumns(myTable); + _this.hideBfType(myTable); + _this.hideBfPrefix(myTable) + _this.hideBfColumn(myTable); + + var top, + left = $(obj).offset().left, + mode = $(obj).parent().data('mode'), + field = $(obj).parent().data('field'), + id = $(obj).parent().data('id'), + head = $(obj).parent().data('head'), + prefix = $(obj).parent().data('prefix'), + value = $(obj).parent().data('value'), + refresh = $('.soul-edit-out .out_auto').prop('checked'), + where = where_cache[myTable.id] || {}, + filterSos = where.filterSos ? JSON.parse(where.filterSos) : []; + + switch (mode) { + case 'in': + _this.hideCondition(myTable); + if (dorpListTimeOut) { + clearTimeout(dorpListTimeOut); + } + $('#soul-dropList' + tableId + '>.filter-search>input').val(''); + $('#soul-dropList' + tableId).show(); + $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false); + var filterSo = _this.getFilterSoById(filterSos, id); + if (filterSo.values) { + for (i = 0; i < filterSo.values.length; i++) { + $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true); + } + } + + $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', refresh).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone()); + form.render('checkbox', 'orm'); + top = $(obj).offset().top + $(obj).outerHeight(); + $('#soul-dropList' + tableId).css({'top': top, 'left': left}) + .show().removeClass().addClass('fadeInUp animated'); + setTimeout(function () { + $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框 + }, 1); + + // 监听筛选数据 + var liClick = true; + form.on('checkbox(soulDropList' + tableId + ')', function (data) { + liClick = false; + _this.updateDropList(myTable, field); + }); + + $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () { + if (liClick) { + $(this).find('div.layui-form-checkbox').trigger('click'); + } + liClick = true; + }) + break; + case 'date': + _this.hideDropList(myTable); + if (conditionTimeOut) { + clearTimeout(conditionTimeOut); + } + var filterSo = _this.getFilterSoById(filterSos, id), + top = $(obj).offset().top + $(obj).height(); + + _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "down", refresh); + break; + case 'condition': + $(obj).hide(); + $(obj).after('
    ') + $(obj).next().children().val(value).select().on('keydown', function (e) { + if (e.keyCode === 13) { + $(this).blur(); + } + }).on('blur', function () { + var newValue = $(this).val(); + $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue); + $(obj).show(); + $(this).parent().remove() + if (newValue !== value) { + $(obj).parent().data('value', newValue); + _this.updateWhere(myTable, { + id: id, + value: newValue + }) + if (refresh) { + _this.soulReload(myTable); + } + } + }) + break; + } + + } + + $('.soul-edit-out a[data-type]').on('click', function () { + if ($(this).data('type') === 'search') { + _this.soulReload(myTable); + } else { + addLine(this) + } + }) + + function addLine(obj) { + var refresh = $('.soul-edit-out .out_auto').prop('checked'); + filterBoard = [] + switch ($(obj).data('type')) { + case 'addOne': + var filterSo = { + prefix: 'and', + field: firstColumn.field, + mode: 'condition', + type: 'eq', + value: '' + } + if ($(obj).parent().parent().data('id')) { + $.extend(filterSo, { + groupId: $(obj).parent().parent().data('id') + }) + } + + _this.updateWhere(myTable, filterSo); + + filterBoard.push('
  • '); + filterBoard.push('
    '); + filterBoard.push('
    ') + filterBoard.push('
    ' + fieldMap[filterSo.field].title + '
    '); + filterBoard.push('
    等于
    '); + filterBoard.push('
    请输入...
    '); + filterBoard.push('
    '); + filterBoard.push('
  • '); + break; + case 'addGroup': + var filterSo = { + prefix: 'and', + mode: 'group', + children: [] + } + if ($(obj).parent().parent().data('id')) { + $.extend(filterSo, { + groupId: $(obj).parent().parent().data('id') + }) + } + _this.updateWhere(myTable, filterSo); + + filterBoard.push('
  • '); + filterBoard.push('
    '); + filterBoard.push('
    ') + filterBoard.push('
    分组
    ') + filterBoard.push('') + filterBoard.push('
    '); + filterBoard.push('
      '); + filterBoard.push('
    '); + filterBoard.push('
  • '); + break; + } + if (refresh) { + _this.soulReload(myTable); + } + if ($(obj).parent().parent().children('ul').children('li').length > 0) { + $(obj).parent().parent().children('ul').children('li:last').removeClass('last'); + if ($(obj).parent().parent().children('ul').children('li:last').children('ul.group').length > 0) { + $(obj).parent().parent().children('ul').children('li:last').children('ul.group').addClass('line') + } + } + $(obj).parent().parent().children('ul').append(filterBoard.join('')); + form.render('checkbox', 'soul-edit-out') + if ($(obj).data('type') === 'addGroup') { + $(obj).parent().parent().children('ul').children("li:last").find('a[data-type]').on('click', function () { + addLine(this) + }) + } else { + $(obj).parent().parent().children('ul').children("li:last").find('.item-field').on('click', function (e) { + e.stopPropagation(); + showColums(this); + }) + $(obj).parent().parent().children('ul').children("li:last").find('.item-type').on('click', function (e) { + e.stopPropagation(); + showTypes(this); + }) + $(obj).parent().parent().children('ul').children("li:last").find('.item-value').on('click', function (e) { + e.stopPropagation(); + showValue(this); + }) + } + $(obj).parent().parent().children('ul').children("li:last").children('.delete-item').on('click', function () { + var id = $(this).parent().data('id'), + refresh = $('.soul-edit-out .out_auto').prop('checked'); + $(this).parent().remove(); + _this.updateWhere(myTable, { + id: id, + delete: true + }) + if (refresh) { + _this.soulReload(myTable); + } + }) + } + } + , hideColumns: function (myTable, animate) { + var tableId = myTable.id; + + $('#soul-columns' + tableId).removeClass().addClass('fadeOutLeft animated') + if (columnsTimeOut) { + clearTimeout(columnsTimeOut) + } + if (typeof animate === 'undefined' || animate) { + columnsTimeOut = setTimeout(function (e) { + $('#soul-columns' + tableId).hide(); + }, 500) + } else { + $('[id^=soul-columns]').hide(); + } + + } + , hideDropList: function (myTable, animate) { + var tableId = myTable.id; + $('#soul-dropList' + tableId).removeClass().addClass('fadeOutLeft animated') + if (dorpListTimeOut) { + clearTimeout(dorpListTimeOut); + } + if (typeof animate === 'undefined' || animate) { + dorpListTimeOut = setTimeout(function (e) { + $('#soul-dropList' + tableId).hide(); + }, 500) + } else { + $('[id^=soul-dropList]').hide(); + } + + } + , hideCondition: function (myTable, animate) { + var tableId = myTable.id; + $('#soul-condition' + tableId).removeClass().addClass('fadeOutLeft animated') + if (conditionTimeOut) { + clearTimeout(conditionTimeOut); + } + if (typeof animate === 'undefined' || animate) { + conditionTimeOut = setTimeout(function (e) { + $('#soul-condition' + tableId).hide(); + }, 500) + } else { + $('[id^=soul-condition]').hide(); + } + } + , hideBfPrefix: function (myTable, animate) { + var tableId = myTable.id; + $('#soul-bf-prefix' + tableId).removeClass().addClass('fadeOutDown animated') + if (bfColumnTimeOut) { + clearTimeout(bfColumnTimeOut); + } + if (typeof animate === 'undefined' || animate) { + bfColumnTimeOut = setTimeout(function () { + $('#soul-bf-prefix' + tableId).hide(); + }, 500) + } else { + $('[id=soul-bf-prefix' + tableId + ']').hide(); + } + } + , hideBfColumn: function (myTable, animate) { + var tableId = myTable.id; + $('#soul-bf-column' + tableId).removeClass().addClass('fadeOutDown animated') + if (bfColumnTimeOut) { + clearTimeout(bfColumnTimeOut); + } + if (typeof animate === 'undefined' || animate) { + bfColumnTimeOut = setTimeout(function () { + $('#soul-bf-column' + tableId).hide(); + }, 500) + } else { + $('[id=soul-bf-column' + tableId + ']').hide(); + } + } + , hideBfType: function (myTable, animate) { + var tableId = myTable.id; + $('#soul-bf-type' + tableId).removeClass().addClass('fadeOutDown animated') + if (bfCond1TimeOut) { + clearTimeout(bfCond1TimeOut); + } + if (typeof animate === 'undefined' || animate) { + bfCond1TimeOut = setTimeout(function () { + $('#soul-bf-type' + tableId).hide(); + }, 500) + } else { + $('[id=soul-bf-type' + tableId + ']').hide(); + } + } + , bindFilterClick: function (myTable) { + var _this = this, + $table = $(myTable.elem), + $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'), + $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'), + $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'), + tableId = myTable.id, + filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, + mainListTimeOut; + + // 显示筛选框 + $tableHead.find('.soul-table-filter').off('click').on('click', function (e) { + e.stopPropagation(); + showFilter($(this)) + }); + $fixedLeftTableHead.find('.soul-table-filter').off('click').on('click', function (e) { + e.stopPropagation(); + showFilter($(this)) + }); + $fixedRigthTableHead.find('.soul-table-filter').off('click').on('click', function (e) { + e.stopPropagation(); + showFilter($(this)) + }); + + function showFilter($that) { + var curItems = $that.data('items') ? $that.data('items').split(',') : filterItems + _this.hideColumns(myTable, false); + _this.hideDropList(myTable, false); + _this.hideCondition(myTable, false); + $('[id^=main-list]').hide(); + + $('#main-list' + tableId).data({'field': $that.data('column'), 'split': $that.data('split')}); + + $('#soul-columns' + tableId + ' [type=checkbox]').attr('disabled', false); + // if (myTable.cols[0][0].type=='checkbox') { + // $('#soul-columns'+tableId+' [type=checkbox]:eq('+($that.parents('th').data('key').split('-')[2]-1)+')').attr('disabled', true); + // } else { + $('#soul-columns' + tableId + ' li[data-key=' + $that.parents('th').data('key').split('-')[2] + '] [type=checkbox]').attr('disabled', true); + // } + + $('#main-list' + tableId + ' > li').hide() + // 是否显示排序框 + if ($that.hasClass('layui-table-sort')) { + $('#main-list' + tableId + ' .soul-sort').show() + } + for (var i = 0; i < curItems.length; i++) { + $('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).show() + if ($('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).index() !== (i + 2)) { + $('#main-list' + tableId + '>li:eq("' + (i + 2) + '")').before($('#main-list' + tableId + ' .' + itemsMap[curItems[i]])) + + } + } + if (mainListTimeOut) { + clearTimeout(mainListTimeOut) + } + var left, animate; + if ($that.offset().left + $('#main-list' + tableId).outerWidth() < document.body.clientWidth) { + left = $that.offset().left + 10; + animate = 'fadeInLeft'; + } else { + left = $that.offset().left - $('#main-list' + tableId).outerWidth(); + animate = 'fadeInRight'; + } + $('#main-list' + tableId).data('type', myTable.where.tableFilterType ? JSON.parse(myTable.where.tableFilterType)[$that.data('column')] || '' : '').hide().css({ + 'top': $that.offset().top + 10, + 'left': left + }).show().removeClass().addClass(animate + ' animated'); + + // 排序 + $('#main-list' + tableId + ' .soul-sort').on('click', function (e) { + $that.siblings('.layui-table-sort').find('.layui-table-sort-' + $(this).data('value')).trigger('click'); + $('#main-list' + tableId).hide(); + }) + form.render('checkbox', 'orm'); + } + + $(document).on('click', function (e) { + $('#main-list' + tableId).hide(); + _this.hideColumns(myTable, false); + _this.hideDropList(myTable, false); + _this.hideCondition(myTable, false); + _this.hideBfPrefix(myTable, false); + _this.hideBfColumn(myTable, false); + _this.hideBfType(myTable, false); + }); + $('#main-list' + tableId + ',#soul-columns' + tableId + ',#soul-dropList' + tableId + ',#soul-condition' + tableId).on('click', function (e) { + $(this).find('.layui-form-selected').removeClass('layui-form-selected') + e.stopPropagation(); + }); + + //渲染底部筛选条件 + _this.renderBottomCondition(myTable); + + // 表头样式 + var where = where_cache[myTable.id] || {}, + filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'); + + for (var i = 0; i < filterSos.length; i++) { + if (filterSos[i].head) { + var hasFilter = false; + switch (filterSos[i].mode) { + case 'in': + if (filterSos[i].values && filterSos[i].values.length > 0) { + hasFilter = true + } + break; + case 'date': + if (filterSos[i].type !== 'all' && typeof filterSos[i].value !== 'undefined' && filterSos[i].value !== '') { + hasFilter = true + } + break; + case 'group': + if (filterSos[i].children && filterSos[i].children.length > 0) { + hasFilter = true + } + default: + break; + } + $tableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter); + $fixedLeftTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter); + $fixedRigthTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter); + } + } + } + , resize: function (myTable) { + var _this = this, + $table = $(myTable.elem), + $tableBox = $table.next().children('.layui-table-box'), + $tableMain = $tableBox.children('.layui-table-main') + // 减去底部筛选的高度 + if ($table.next().children('.soul-bottom-contion').length > 0) { + $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', $table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').outerWidth()); + + var bodyHeight = $table.next().height() - $table.next().children('.soul-bottom-contion').outerHeight() + if ($table.next().children('.layui-table-tool').length > 0) { + bodyHeight = bodyHeight - $table.next().children('.layui-table-tool').outerHeight(); + } + if ($table.next().children('.layui-table-total').length > 0) { + bodyHeight = bodyHeight - $table.next().children('.layui-table-total').outerHeight(); + } + if ($table.next().children('.layui-table-page').length > 0) { + bodyHeight = bodyHeight - $table.next().children('.layui-table-page').outerHeight(); + } + + bodyHeight = bodyHeight - $table.next().children('.layui-table-box').children('.layui-table-header').outerHeight(); + + $table.next().children('.layui-table-box').children('.layui-table-body').height(bodyHeight) + var fixHeight = bodyHeight - _this.getScrollWidth($tableMain[0]), + layMainTableHeight = $tableMain.children('table').height() + $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').height(layMainTableHeight >= fixHeight ? fixHeight : 'auto') + + var scollWidth = $tableMain.width() - $tableMain.prop('clientWidth') //纵向滚动条宽度; + $tableBox.children('.layui-table-fixed-r').css('right', scollWidth - 1); + } + } + /** + * 同步当前 droplist + * @param myTable + * @param field + */ + , updateDropList: function (myTable, field) { + var _this = this, + $table = $(myTable.elem), + tableId = myTable.id, + id = $('#soul-dropList' + tableId + '>ul').data('id'), + $checkedDom = $('#soul-dropList' + tableId + '>ul input[type=checkbox]:checked'), + values = [], + head = $('#soul-dropList' + tableId + '>ul').data('head'), + prefix = $('#soul-dropList' + tableId + '>ul').data('prefix'), + refresh = $('#soul-dropList' + tableId + '>ul').data('refresh'), + split = $('#soul-dropList' + tableId + '>ul').data('split'); + if ($checkedDom.length > 0) { + $checkedDom.each(function () { + values.push($(this).val()) + }) + } + var filterSo = { + id: id, + head: head, + prefix: prefix || 'and', + mode: 'in', + field: field, + split: split, + values: values + }; + _this.updateWhere(myTable, filterSo); + if (!id) { + $('#soul-dropList' + tableId + '>ul').data('id', filterSo.id); + } + + if ($('.soul-edit-out').length > 0) { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]>.item-value').html('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据') + } + + if (refresh) { + _this.soulReload(myTable); + } + } + , getFilterSoById: function (filterSos, id) { + for (var i = 0; i < filterSos.length; i++) { + if (filterSos[i].id === id) { + return filterSos[i] + } else if (filterSos[i].mode === 'group') { + for (var j = 0; j < filterSos[i].children.length; j++) { + var filterSo = this.getFilterSoById(filterSos[i].children, id); + if (filterSo) return filterSo; + } + } + } + return null + } + /** + * 更新 filter 条件 + * @param myTable + * @param filterSo + */ + , updateWhere: function (myTable, filterSo) { + var _this = this, + where = where_cache[myTable.id] || {}, + filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'); + + if (filterSo.id || filterSo.groupId) { + for (var i = 0; i < filterSos.length; i++) { + if (filterSo.delete && filterSos[i].id === filterSo.id) { + filterSos.splice(i, 1); + break; + } + if (updateFilterSo(filterSos[i], filterSo)) { + break; + } + } + } else if (!(filterSo.mode === 'in' && !(filterSo.values && filterSo.values.length > 0))) { + filterSos.push($.extend(filterSo, { + id: _this.getDifId() + })) + } + where['filterSos'] = JSON.stringify(filterSos); + myTable.where = where; + where_cache[myTable.id] = where; + + function updateFilterSo(filterSo, newFilterSo) { + var isMatch = false; + + if (filterSo.id === newFilterSo.id) { + $.extend(filterSo, newFilterSo); + isMatch = true; + } + + // 在分组中新增 + if (!newFilterSo.id && filterSo.id === newFilterSo.groupId) { + filterSo.children.push($.extend(newFilterSo, { + id: _this.getDifId() + })) + } else if (filterSo.mode === 'group') { + for (var i = 0; i < filterSo.children.length; i++) { + if (newFilterSo.delete && filterSo.children[i].id === newFilterSo.id) { + filterSo.children.splice(i, 1); + return true; + } + if (updateFilterSo(filterSo.children[i], newFilterSo)) { + return true; + } + } + + } + + return isMatch; + } + } + /** + * 根据当前条件重载表格 + * @param myTable 需要重载的表格对象 + * @param isr 是否为筛选重载,为 true 时,不进行筛选的初始化动作(包括渲染dom、请求表头数据等) + */ + , soulReload: function (myTable, isr) { + var _this = this, + $table = $(myTable.elem), + scrollLeft = $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft(); + + isFilterReload[myTable.id] = typeof isr === 'undefined' ? true : isr; + if (typeof myTable.url !== 'undefined' && myTable.page) { + $table.data('scrollLeft', scrollLeft); + /** + * 后台筛选 + */ + table.reload(myTable.id, { + where: where_cache[myTable.id] || {}, + page: { + curr: 1 //重新从第 1 页开始 + } + }, true) + } else { + /** + * 前端筛选 + */ + var where = where_cache[myTable.id] || {}, + filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'), + tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {}, + loading = layer.load(2); + if (!myTable.page) { + // 修复前端不分页时,layui table bug 导致的只显示10条数据的问题 + myTable.limit = 100000000 + } + if (filterSos.length > 0) { + var newData = []; + layui.each(cache[myTable.id], function (index, item) { + var show = true; + + for (var i = 0; i < filterSos.length; i++) { + show = _this.handleFilterSo(filterSos[i], item, tableFilterTypes, show, i === 0) + } + + if (show) { + newData.push(item) + } + }) + if (myTable.page) { + table.reload(myTable.id, { + data: newData + , initSort: myTable.initSort + , isSoulFrontFilter: true + , page: { + curr: 1 //重新从第 1 页开始 + } + }, true) + } else { + var url = myTable.url; + $table.next().off('click') + var inst = table.reload(myTable.id, { + url: '' + , initSort: myTable.initSort + , isSoulFrontFilter: true + , data: newData + }, true) + inst.config.url = url; + } + myTable.data = newData + + } else { + if (myTable.page) { + table.reload(myTable.id, { + data: cache[myTable.id] + , initSort: myTable.initSort + , isSoulFrontFilter: true + , page: { + curr: 1 //重新从第 1 页开始 + } + }, true) + } else { + table.reload(myTable.id, { + data: cache[myTable.id] + , initSort: myTable.initSort + , isSoulFrontFilter: true + }, true) + } + myTable.data = cache[myTable.id] + } + $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft(scrollLeft); + layer.close(loading) + } + } + , handleFilterSo: function (filterSo, item, tableFilterTypes, show, first) { + var isOr = first ? false : filterSo.prefix === 'or', + field = filterSo.field, + value = filterSo.value, + status = true; + + // 如果有子元素 + if (filterSo.children && filterSo.children.length > 0) { + for (var i = 0; i < filterSo.children.length; i++) { + status = this.handleFilterSo(filterSo.children[i], item, tableFilterTypes, status, i === 0) + } + return isOr ? show || status : show && status; + } + + switch (filterSo.mode) { + case "in": + if (filterSo.values && filterSo.values.length > 0) { + if (filterSo.split) { + var tempList = (item[field] + '').split(filterSo.split); + var tempStatus = false; + for (var i = 0; i < tempList.length; i++) { + if (filterSo.values.indexOf(tempList[i]) !== -1) { + tempStatus = true; + } + } + status = tempStatus; + } else { + status = filterSo.values.indexOf(item[field] + '') !== -1 + } + } else { + return show; + } + break; + case "condition": + if (filterSo.type !== 'null' && filterSo.type !== 'notNull' && (typeof value === 'undefined' || value === '')) { + return show; + } + switch (filterSo.type) { + case "eq": + status = isNaN(item[field]) || isNaN(value) ? item[field] === value : Number(item[field]) === Number(value); + break; + case "ne": + status = isNaN(item[field]) || isNaN(value) ? item[field] !== value : Number(item[field]) !== Number(value); + break; + case "gt": + status = isNaN(item[field]) || isNaN(value) ? item[field] > value : Number(item[field]) > Number(value); + break; + case "ge": + status = isNaN(item[field]) || isNaN(value) ? item[field] >= value : Number(item[field]) >= Number(value); + break; + case "lt": + status = isNaN(item[field]) || isNaN(value) ? item[field] < value : Number(item[field]) < Number(value); + break; + case "le": + status = isNaN(item[field]) || isNaN(value) ? item[field] <= value : Number(item[field]) <= Number(value); + break; + case "contain": + status = (item[field] + '').indexOf(value) !== -1; + break; + case "notContain": + status = (item[field] + '').indexOf(value) === -1; + break; + case "start": + status = (item[field] + '').indexOf(value) === 0; + break; + case "end": + var d = (item[field] + '').length - (value + '').length; + status = d >= 0 && (item[field] + '').lastIndexOf(value) === d; + break; + case "null": + status = typeof item[field] === 'undefined' || item[field] === '' || item[field] === null; + break; + case "notNull": + status = typeof item[field] !== 'undefined' && item[field] !== '' && item[field] !== null; + break; + } + break; + case "date": + var dateVal = new Date(Date.parse(item[field].replace(/-/g, "/"))); + switch (filterSo.type) { + case 'all': + status = true; + break; + case 'yesterday': + status = item[field] && isBetween(dateVal, getToday() - 86400, getToday() - 1); + break; + case 'thisWeek': + status = item[field] && isBetween(dateVal, getFirstDayOfWeek(), getFirstDayOfWeek() + 86400 * 7 - 1); + break; + case 'lastWeek': + status = item[field] && isBetween(dateVal, getFirstDayOfWeek() - 86400 * 7, getFirstDayOfWeek() - 1); + break; + case 'thisMonth': + status = item[field] && isBetween(dateVal, getFirstDayOfMonth(), getCurrentMonthLast()); + break; + case 'thisYear': + status = item[field] && isBetween(dateVal, new Date(new Date().getFullYear(), 1, 1) / 1000, new Date(new Date().getFullYear() + 1, 1, 1) / 1000 - 1); + break; + case 'specific': + var dateFormat = dateVal.getFullYear(); + dateFormat += '-' + (timeAdd0(dateVal.getMonth() + 1)); + dateFormat += '-' + timeAdd0(dateVal.getDate()); + status = item[field] && dateFormat === value + break; + } + break; + } + + // 今天凌晨 + function getToday() { + return new Date().setHours(0, 0, 0, 0) / 1000; + } + + // 本周第一天 + function getFirstDayOfWeek() { + var now = new Date(); + var weekday = now.getDay() || 7; //获取星期几,getDay()返回值是 0(周日) 到 6(周六) 之间的一个整数。0||7为7,即weekday的值为1-7 + return new Date(now.setDate(now.getDate() - weekday + 1)).setHours(0, 0, 0, 0) / 1000;//往前算(weekday-1)天,年份、月份会自动变化 + } + + //获取当月第一天 + function getFirstDayOfMonth() { + return new Date(new Date().setDate(1)).setHours(0, 0, 0, 0) / 1000; + } + + //获取当月最后一天最后一秒 + function getCurrentMonthLast() { + var date = new Date(); + var currentMonth = date.getMonth(); + var nextMonth = ++currentMonth; + var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1); + return nextMonthFirstDay / 1000 - 1; + } + + function isBetween(v, a, b) { + return (v.getTime() / 1000) >= a && (v.getTime() / 1000) <= b; + } + + function timeAdd0(str) { + str += ""; + if (str.length <= 1) { + str = '0' + str; + } + return str + } + + return isOr ? show || status : show && status; + } + , getDifId: function () { + return maxId++; + } + , showDate: function (myTable, field, filterSo, animate, top, left, type, refresh) { + var _this = this, + tableId = myTable.id, + conditionHtml = [], + documentWidth = document.body.clientWidth, + animate; + conditionHtml.push('
    '); + conditionHtml.push('
    '); + for (var key in dateTimeItems) { + conditionHtml.push('
    '); + } + conditionHtml.push('
    '); + conditionHtml.push('
    '); + $('#soul-condition' + tableId).html(conditionHtml.join('')); + var filterDate = util.toDateString(new Date(), 'yyyy-MM-dd'); + if (filterSo) { + $('#soul-condition' + tableId).data({'id': filterSo.id, 'head': true}); + $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="' + filterSo.type + '"]').prop('checked', true); + if (filterSo.type === 'specific') { + filterDate = filterSo.value + } + } else { + $('#soul-condition' + tableId).data({'id': '', 'head': true}); + $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="all"]').prop('checked', true); + } + + $('#soul-condition' + tableId + ' .specific_value').val(filterDate); + laydate.render({ + elem: '#soul-condition' + tableId + ' .staticDate' + , position: 'static' + , calendar: true + , btns: ['now'] + , value: filterDate + , done: function (value) { + var id = $('#soul-condition' + tableId).data('id'), + head = $('#soul-condition' + tableId).data('head') + $('#soul-condition' + tableId + ' .specific_value').val(value); + $('#soul-condition' + tableId + ' [name^=datetime]:checked').prop('checked', false); + $('#soul-condition' + tableId + ' [name^=datetime][value=specific]').prop('checked', true); + var filterSo = { + id: id, + head: head, + prefix: head ? 'and' : 'and', + mode: 'date', + field: field, + type: 'specific', + value: value + } + _this.updateWhere(myTable, filterSo); + if (!id) { + $('#soul-condition' + tableId).data('id', filterSo.id) + } + if ($('.soul-edit-out').length > 0) { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value) + } + if (refresh) { + _this.soulReload(myTable); + } + form.render('radio', 'orm'); + } + }); + form.on('radio(datetime' + tableId + ')', function (data) { + var id = $('#soul-condition' + tableId).data('id'), + head = $('#soul-condition' + tableId).data('head') + var filterSo = { + id: id, + head: head, + prefix: head ? 'and' : 'and', + mode: 'date', + field: field, + type: data.value, + value: $('#soul-condition' + tableId + ' .specific_value').val() + } + _this.updateWhere(myTable, filterSo); + if (!id) { + $('#soul-condition' + tableId).data('id', filterSo.id) + } + if ($('.soul-edit-out').length > 0) { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type] || filterSo.value) + } + if (refresh) { + _this.soulReload(myTable); + } + }); + form.render('radio', 'orm') + if (type === 'down') { + if (left + $('#soul-condition' + tableId).width() < documentWidth) { + animate = 'fadeInLeft' + } else { + left = left - $('#main-list' + tableId).width() - $('#soul-condition' + tableId).width(); + animate = 'fadeInRight' + } + } else { + top = top - $('#soul-condition' + tableId).outerHeight() - 10; + } + $('#soul-condition' + tableId).css({'top': top, 'left': left}) + .show().removeClass().addClass(animate + ' animated'); + + } + , bottomConditionHtml: function (bcHtml, filterSo, fieldMap, first) { + var _this = this, + isOr = filterSo.prefix === 'or', + field = filterSo.field; + + if (filterSo.mode === 'group') { + if (filterSo.children && filterSo.children.length > 0) { + bcHtml.push('
    '); + if (!first) { + bcHtml.push('
    ' + (isOr ? '或' : '与') + '
    '); + } + + for (var i = 0; i < filterSo.children.length; i++) { + _this.bottomConditionHtml(bcHtml, filterSo.children[i], fieldMap, i === 0); + } + bcHtml.push(''); + bcHtml.push('
    ') + } + return; + } + bcHtml.push('
    '); + if (!first) { + bcHtml.push('
    ' + (isOr ? '或' : '与') + '
    '); + } + bcHtml.push('
    ' + fieldMap[field].title + '
    '); + bcHtml.push('
    '); + switch (filterSo.mode) { + case 'in': + bcHtml.push('筛选数据'); + break; + case 'condition': + bcHtml.push(conditionChangeItems[filterSo.type]); + break; + case 'date': + bcHtml.push('选择日期'); + break; + default: + bcHtml.push('未知'); + break; + } + bcHtml.push('
    '); + if (filterSo.type !== 'null' && filterSo.type !== 'notNull') { + bcHtml.push('
    '); + switch (filterSo.mode) { + case 'in': + bcHtml.push('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据'); + break; + case 'date': + bcHtml.push(filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type]) + break; + case 'condition': + default: + bcHtml.push(typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value); + break; + } + + bcHtml.push('
    ') + } + bcHtml.push(''); + bcHtml.push('
    ') + } + , renderBottomCondition: function (myTable) { + var _this = this, + where = where_cache[myTable.id] || {}, + filterSos = where.filterSos ? JSON.parse(where.filterSos) : [], + tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {}, + $table = $(myTable.elem), + tableId = myTable.id, + $bottomCondition = $table.next().children('.soul-bottom-contion'), + fieldMap = {}, bcHtml = [], curItems, + filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems, + columns = _this.getCompleteCols(myTable.cols); + for (var i = 0; i < columns.length; i++) { + if (columns[i].field && columns[i].filter) { + curItems = columns[i].filter.items || filterItems; + if (curItems.indexOf('data') !== -1 || curItems.indexOf('condition') !== -1) { + fieldMap[columns[i]['field']] = { + title: columns[i].title, + items: curItems + } + } + } + } + + /** + * 一、拼装底部内容 + */ + for (var i = 0; i < filterSos.length; i++) { + _this.bottomConditionHtml(bcHtml, filterSos[i], fieldMap, i === 0); + } + $bottomCondition.children('.condition-items').html(bcHtml.join('')) + + /** + * 二、组装底部弹窗条件 + */ + bcHtml = []; + // 1. prefix + if ($('#soul-bf-prefix' + tableId).length === 0) { + bcHtml.push('') + } + // 2. 列选择 + if ($('#soul-bf-column' + tableId).length === 0) { + bcHtml.push('') + } + + // 3. 条件选择 + if ($('#soul-bf-type' + tableId).length === 0) { + bcHtml.push('') + } + + // 4. 值选择 + if ($('#soul-bf-cond2-dropList' + tableId).length === 0) { + bcHtml.push('') + } + + + $('body').append(bcHtml.join('')) + + /** + * 三、底部弹窗事件 + */ + // 1. prefix弹出事件 + $bottomCondition.find('.item-prefix').off('click').on('click', function (e) { + e.stopPropagation(); + $('#main-list' + tableId).hide(); + _this.hideDropList(myTable); + _this.hideCondition(myTable); + _this.hideColumns(myTable); + _this.hideBfColumn(myTable); + _this.hideBfType(myTable); + var top = $(this).offset().top - $('#soul-bf-prefix' + tableId).outerHeight() - 10, + left = $(this).offset().left; + + $('#soul-bf-prefix' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') + $('#soul-bf-prefix' + tableId) + .data('id', $(this).parent().data('id')) + .data('prefix', $(this).parent().data('prefix')) + .data('refresh', true) + .show() + .css({top: top, left: left}) + .removeClass().addClass('fadeInUp animated') + .find('li[data-value="' + $(this).parent().data('prefix') + '"]') + .addClass('soul-bf-selected') + + }) + // 2. 弹出列选择 + $bottomCondition.find('.item-field').off('click').on('click', function (e) { + e.stopPropagation(); + $('#main-list' + tableId).hide(); + _this.hideDropList(myTable); + _this.hideCondition(myTable); + _this.hideColumns(myTable); + _this.hideBfPrefix(myTable) + _this.hideBfType(myTable); + var top = $(this).offset().top - $('#soul-bf-column' + tableId).outerHeight() - 10, + left = $(this).offset().left; + + $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') + $('#soul-bf-column' + tableId) + .data('field', $(this).parent().data('field')) + .data('id', $(this).parent().data('id')) + .data('mode', $(this).parent().data('mode')) + .data('group', $(this).parent().parent().data('id') || '') + .data('refresh', true) + .show() + .css({top: top, left: left}) + .removeClass().addClass('fadeInUp animated') + .find('li[data-field="' + $(this).parent().data('field') + '"]') + .addClass('soul-bf-selected') + }) + + // 3. 弹出方式选择 + $bottomCondition.find('.item-type').on('click', function (e) { + e.stopPropagation(); + $('#main-list' + tableId).hide(); + _this.hideDropList(myTable); + _this.hideCondition(myTable); + _this.hideColumns(myTable); + _this.hideBfColumn(myTable); + _this.hideBfPrefix(myTable); + var field = $(this).parent().data('field') + $('#soul-bf-type' + tableId + ' li').hide() + if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) { + $('#soul-bf-type' + tableId + ' li[data-mode=date]').show() + } + if (fieldMap[field].items.indexOf('data') !== -1) { + $('#soul-bf-type' + tableId + ' li[data-mode=in]').show() + } + if (fieldMap[field].items.indexOf('condition') !== -1) { + $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show() + } + + var top = $(this).offset().top - $('#soul-bf-type' + tableId).outerHeight() - 10, + left = $(this).offset().left; + $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected') + switch ($(this).parent().data('mode')) { + case 'in': + $('#soul-bf-type' + tableId).find('li[data-mode="in"]') + .addClass('soul-bf-selected') + break; + case 'date': + $('#soul-bf-type' + tableId).find('li[data-mode="date"]') + .addClass('soul-bf-selected') + case 'condition': + $('#soul-bf-type' + tableId).find('li[data-value="' + $(this).parent().data('type') + '"]') + .addClass('soul-bf-selected') + } + + $('#soul-bf-type' + tableId) + .data('type', $(this).parent().data('type')) + .data('mode', $(this).parent().data('mode')) + .data('id', $(this).parent().data('id')) + .data('group', $(this).parent().parent().data('id') || '') + .data('refresh', true) + .show() + .css({top: top, left: left}) + .removeClass().addClass('fadeInUp animated') + }) + + // 4. 弹出值选择 + $bottomCondition.find('.item-value').on('click', function (e) { + e.stopPropagation(); + $('#main-list' + tableId).hide(); + _this.hideColumns(myTable); + _this.hideBfType(myTable); + _this.hideBfPrefix(myTable) + _this.hideBfColumn(myTable); + var top, + left = $(this).offset().left, + mode = $(this).parent().data('mode'), + field = $(this).parent().data('field'), + id = $(this).parent().data('id'), + head = $(this).parent().data('head'), + prefix = $(this).parent().data('prefix'); + + switch (mode) { + case 'in': + _this.hideCondition(myTable); + if (dorpListTimeOut) { + clearTimeout(dorpListTimeOut); + } + $('#soul-dropList' + tableId + '>.filter-search>input').val(''); + $('#soul-dropList' + tableId).show(); + $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false); + var filterSo = _this.getFilterSoById(filterSos, id); + for (var i = 0; i < filterSo.values.length; i++) { + $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true); + } + + $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', true).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone()); + form.render('checkbox', 'orm'); + top = $(this).offset().top - $('#soul-dropList' + tableId).outerHeight() - 10; + $('#soul-dropList' + tableId).css({'top': top, 'left': left}) + .show().removeClass().addClass('fadeInUp animated'); + setTimeout(function () { + $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框 + }, 1); + + + // 监听筛选数据 + var liClick = true; + form.on('checkbox(soulDropList' + tableId + ')', function (data) { + liClick = false; + _this.updateDropList(myTable, field); + }); + + $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () { + if (liClick) { + $(this).find('div.layui-form-checkbox').trigger('click'); + } + liClick = true; + }) + break; + case 'date': + _this.hideDropList(myTable); + if (conditionTimeOut) { + clearTimeout(conditionTimeOut); + } + var filterSo = _this.getFilterSoById(filterSos, id), + top = $(this).offset().top - 10; + + _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "up", true); + break; + default: + _this.hideDropList(myTable); + if (conditionTimeOut) { + clearTimeout(conditionTimeOut); + } + var obj = this, + value = $(this).parents('.condition-item:eq(0)').data('value'); + $(obj).hide(); + $(obj).after('
    ') + $(obj).next().children().val(value).select().on('keydown', function (e) { + if (e.keyCode === 13) { + $(this).blur(); + } + }).on('blur', function () { + var newValue = $(this).val(); + $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue); + $(obj).show(); + $(this).parent().remove() + if (newValue !== value) { + _this.updateWhere(myTable, { + id: id, + value: newValue + }) + _this.soulReload(myTable); + } + }) + + break; + } + }) + + /** + * 三、选择事件 + */ + // 1. 选择prefix + $('#soul-bf-prefix' + tableId + '>ul>li').off('click').on('click', function () { + var id = $(this).parent().parent().data('id'), + newPrefix = $(this).data('value'), + oldPrefix = $(this).parent().parent().data('prefix'), + refresh = $(this).parent().parent().data('refresh'); + + if (oldPrefix !== newPrefix) { + _this.updateWhere(myTable, { + id: id, + prefix: newPrefix + }); + if (refresh === true) { + _this.soulReload(myTable); + } + } + }) + // 1. 选择列 + $('#soul-bf-column' + tableId + '>ul>li').off('click').on('click', function () { + var oldField = $(this).parent().parent().data('field'), + newField = $(this).data('field'), + mode = $(this).parent().parent().data('mode'), + group = $(this).parent().parent().data('group'), + refresh = $(this).parent().parent().data('refresh'); + + if (oldField !== newField) { + var filterSo = { + id: $(this).parent().parent().data('id'), + field: newField + } + if (fieldMap[newField].items.indexOf(modeMapItems[mode]) === -1) { + $.extend(filterSo, $.extend({}, revertMode[modeMapItems[mode]], + revertMode[modeMapItems[mode]].mode === 'condition' && _this.startsWith(tableFilterTypes[newField], 'date') + ? { + mode: 'date', + type: 'all' + } : {})) + } else { + // 重置values值 + if (mode === 'in') { + $.extend(filterSo, { + values: [] + }) + } else if (mode === 'date' && !(_this.startsWith(tableFilterTypes[newField], 'date'))) { + $.extend(filterSo, { + mode: 'condition', + type: 'eq', + value: '' + }) + } else if (mode !== 'date' && _this.startsWith(tableFilterTypes[newField], 'date')) { + $.extend(filterSo, { + mode: 'date', + type: 'all' + }) + } + } + // 如果是头部条件,选择列是清除 + if (group) { + _this.updateWhere(myTable, { + id: group, + head: false + }) + } + _this.updateWhere(myTable, filterSo); + + if ($('.soul-edit-out').length > 0) { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-field').html(fieldMap[newField].title); + if (filterSo.mode === 'in') { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('筛选数据') + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html('共0条数据') + } else if (mode !== filterSo.mode) { + if (filterSo.mode === 'date') { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('选择日期') + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type]) + } else if (filterSo.mode === 'condition') { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html(conditionChangeItems[filterSo.type]) + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value === '' ? '请输入...' : filterSo.value) + } + } + } + + if (refresh === true) { + _this.soulReload(myTable); + } + } + }) + + // 2. 选择类型 + $('#soul-bf-type' + tableId + '>ul>li').off('click').on('click', function () { + var newType = $(this).data('value') + "" // 引号修复为空(null值)传递问题 + , newMode = $(this).data('mode') + , type = $(this).parent().parent().data('type') + , mode = $(this).parent().parent().data('mode') + , group = $(this).parent().parent().data('group') + , refresh = $(this).parent().parent().data('refresh') + if (type !== newType) { + + var filterSo = { + id: $(this).parent().parent().data('id'), + type: newType, + mode: newMode + } + if (mode !== newMode) { + $.extend(filterSo, { + value: '', + values: [] + }) + } + + // 如果是头部条件,选择列是清除 + if (group && newMode === 'in') { + _this.updateWhere(myTable, { + id: group, + head: false + }) + } + _this.updateWhere(myTable, filterSo) + + if ($('.soul-edit-out').length > 0) { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').show(); + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-type').html(conditionChangeItems[newType] || (newMode === 'in' ? '筛选数据' : '选择日期')); + switch (newMode) { + case 'in': + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('共0条数据'); + break; + case 'date': + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html(dateTimeItems[newType]); + break; + case 'condition': + if (mode !== newMode) { + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('请输入...'); + } + $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value')[newType === 'null' || newType === 'notNull' ? 'hide' : 'show']() + + break; + } + } + + // 是否立即更新 + if (refresh === true) { + _this.soulReload(myTable); + } + } + }) + + /** + * 五、底部筛选条件删除事件 + */ + $bottomCondition.find('.condition-items .condition-item .condition-item-close').on('click', function () { + _this.updateWhere(myTable, { + id: $(this).parents('.condition-item:eq(0)').data('id'), + delete: true + }) + _this.soulReload(myTable); + }) + + } + /** + * 导出 excel 文件 + * @param myTable + * @param curExcel + */ + , export: function (myTable, curExcel) { + if (typeof myTable === 'string') { + myTable = table_cache[myTable] // tableId 转 myTable + } + var loading = layer.msg('文件下载中', { + icon: 16 + , time: -1 + , anim: -1 + , fixed: false + }); + var cols = this.deepClone(myTable.cols) + , style = myTable.elem.next().find('style')[0] + , sheet = style.sheet || style.styleSheet || {} + , rules = sheet.cssRules || sheet.rules; + + layui.each(rules, function (i, item) { + if (item.style.width) { + var keys = item.selectorText.split('-'); + cols[keys[3]][keys[4]]['width'] = parseInt(item.style.width) + } + }) + + var data = JSON.parse(JSON.stringify(myTable.data || cache[myTable.id])), + showField = {}, + widths = {}, + mergeArrays = [], // 合并配置 + heightConfig = {}, + $table = $(myTable.elem), + $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table'), + $tableTotal = myTable.totalRow ? $table.next().children('.layui-table-total').children(":first") : null, + finalExcel = Object.assign({}, myTable.excel, curExcel); + + var filename = finalExcel.filename ? (typeof finalExcel.filename === 'function' ? finalExcel.filename.call(this) : finalExcel.filename) : '表格数据.xlsx', + checked = finalExcel.checked === true, + curPage = finalExcel.curPage === true, + customColumns = finalExcel.columns, + totalRow = finalExcel.totalRow, + type = filename.substring(filename.lastIndexOf('.') + 1, filename.length), + tableStartIndex = finalExcel.add && finalExcel.add.top && Array.isArray(finalExcel.add.top.data) ? finalExcel.add.top.data.length + 1 : 1, //表格内容从哪一行开始 + bottomLength = finalExcel.add && finalExcel.add.bottom && Array.isArray(finalExcel.add.bottom.data) ? finalExcel.add.bottom.data.length : 0,// 底部自定义行数 + i, j, k; + + if (finalExcel.data){ + if(Array.isArray(finalExcel.data)) { + data = finalExcel.data + } else { + console.error('导出指定数据 data 不符合数组格式', finalExcel.data) + layer.close(loading) + return; + } + } else if (checked) { // 获取选中行数据 + // data = table.checkStatus(myTable.id).data; + data = [] + if (cache[myTable.id] && cache[myTable.id].length > 0) { + for (i = 0; i < cache[myTable.id].length; i++) { + if (cache[myTable.id][i][table.config.checkName]) { + data.push(cache[myTable.id][i]) + } + } + } + } else if (curPage) { + data = layui.table.cache[myTable.id] + } else if (myTable.url && myTable.page) { + var ajaxStatus = true; + var searchParam = isFilterCache[myTable.id] ? where_cache[myTable.id] : table_cache[myTable.id].where; + if (myTable.contentType && myTable.contentType.indexOf("application/json") == 0) { //提交 json 格式 + searchParam = JSON.stringify(searchParam); + } + $.ajax({ + url: myTable.url, + data: searchParam, + dataType: 'json', + method: myTable.method || 'post', + async: false, + cache: false, + headers: myTable.headers || {}, + contentType: myTable.contentType, + success: function (res) { + if (typeof myTable.parseData === 'function') { + res = myTable.parseData(res) || res; + } + //检查数据格式是否符合规范 + if (res[myTable.response.statusName] != myTable.response.statusCode) { + layer.msg('返回的数据不符合规范,正确的成功状态码应为:"' + myTable.response.statusName + '": ' + myTable.response.statusCode, { + icon: 2, + anim: 6 + }); + } else { + data = res[myTable.response.dataName] + } + }, + error: function (res) { + layer.msg('请求异常!', {icon: 2, anim: 6}); + ajaxStatus = false; + } + }) + if (!ajaxStatus) { + return; + } + } else { + var $sortDoom = $table.next().children('.layui-table-box').children('.layui-table-header').find('.layui-table-sort[lay-sort$="sc"]:eq(0)') + if ($sortDoom.length > 0) { + var sortField = $sortDoom.parent().parent().data('field'); + var sortOrder = $sortDoom.attr('lay-sort'); + switch (sortOrder) { + case 'asc': + data = layui.sort(data, sortField); + break; + case 'desc': + data = layui.sort(data, sortField, true); + break; + default: + break; + } + } + } + + // 制定显示列和顺序 + var tempArray, cloneCol, columnsMap = [], curRowUnShowCount; + for (i = 0; i < cols.length; i++) { + curRowUnShowCount = 0; + for (j = 0; j < cols[i].length; j++) { + if (!cols[i][j].exportHandled) { + if (cols[i][j].rowspan > 1) { + if ((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide) { + mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + 1 - curRowUnShowCount) + (i + parseInt(cols[i][j].rowspan) + tableStartIndex - 1)]) + } else { + curRowUnShowCount++; + } + cloneCol = this.deepClone(cols[i][j]) + cloneCol.exportHandled = true; + k = i + 1; + while (k < cols.length) { + cols[k].splice(j, 0, cloneCol) + k++ + } + } + if (cols[i][j].colspan > 1) { + mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + parseInt(cols[i][j].colspan) - curRowUnShowCount) + (i + tableStartIndex)]) + cloneCol = this.deepClone(cols[i][j]) + cloneCol.exportHandled = true; + for (k = 1; k < cols[i][j].colspan; k++) { + cols[i].splice(j, 0, cloneCol) + } + j = j + parseInt(cols[i][j].colspan) - 1 + + } + } else if (!((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide)) { + curRowUnShowCount++; + } + } + } + var columns = cols[cols.length - 1]; // 获取真实列 + + // 处理数据 + for (i = 0; i < data.length; i++) { + for (j = 0; j < columns.length; j++) { + if ((columns[j].field || columns[j].type === 'numbers') && (customColumns && Array.isArray(customColumns) || !columns[j].hide)) { + data[i][columns[j].key] = data[i][columns[j].field || columns[j]['LAY_INDEX']] + } + } + } + + // 处理合计行 + if (totalRow !== false && myTable.totalRow) { + var obj = {}, totalRows = {}; + if (typeof totalRow === 'object' && totalRow.type === 'origin') { + // 通过 dom 解析 + for (i = 0; i < columns.length; i++) { + if (columns[i].field) { + obj[columns[i].key] = $tableTotal.find('[data-field="'+columns[i].field+'"]').text().trim() + } + } + data.push(obj); + } else { + // 通过数据解析 + for (i = 0; i < columns.length; i++) { + if (columns[i].totalRowText) { + obj[columns[i].key] = columns[i].totalRowText + } else if (columns[i].totalRow) { + totalRows[columns[i].key] = 0 + } + } + if (JSON.stringify(totalRows) !== '{}') { + for (i = 0; i < data.length; i++) { + for (var key in totalRows) { + totalRows[key] = (parseFloat(totalRows[key]) + (parseFloat(data[i][key]) || 0)).toFixed(2) + } + } + } + data.push(Object.assign(obj, totalRows)); + } + } + + if (customColumns && Array.isArray(customColumns)) { + // 自定义表头 + var tempCustomColumns = []; + tempArray = {}; + mergeArrays = []; // 重置表头合并列 + columnsMap[0] = {}; + for (i = 0; i < customColumns.length; i++) { + for (j = 0; j < columns.length; j++) { + if (columns[j].field === customColumns[i]) { + columns[j].hide = false + tempCustomColumns.push(columns[j]); + columnsMap[0][columns[j].key] = columns[j]; + tempArray[columns[j].key] = $('
    '+columns[j].title+'
    ').text() + break; + } + } + } + columns = tempCustomColumns; + data.splice(0, 0, tempArray) + } else { + // 拼接表头数据 + for (i = 0; i < cols.length; i++) { + columnsMap[i] = {} + tempArray = {} + for (j = 0; j < cols[i].length; j++) { + columnsMap[i][cols[cols.length - 1][j].key] = cols[i][j]; + tempArray[cols[cols.length - 1][j].key] = $('
    '+cols[i][j].title+'
    ').text() + } + data.splice(i, 0, tempArray) + } + } + + //添加自定义内容 + if (finalExcel.add) { + var addTop = finalExcel.add.top, + addBottom = finalExcel.add.bottom, + startPos, endPos, jumpColsNum; + + if (addTop && Array.isArray(addTop.data) && addTop.data.length > 0) { + + for (i = 0; i < addTop.data.length; i++) { + tempArray = {}, jumpColsNum = 0; + for (j = 0; j < (addTop.data[i].length > columns.length ? addTop.data[i].length : columns.length); j++) { + if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) { + tempArray[columns[j] ? columns[j].key : j + ''] = addTop.data[i][j - jumpColsNum] || '' + } else { + jumpColsNum++ + } + } + data.splice(i, 0, tempArray); + } + + if (Array.isArray(addTop.heights) && addTop.heights.length > 0) { + for (i = 0; i < addTop.heights.length; i++) { + heightConfig[i] = addTop.heights[i] + } + } + + if (Array.isArray(addTop.merge) && addTop.merge.length > 0) { + for (i = 0; i < addTop.merge.length; i++) { + if (addTop.merge[i].length === 2) { + startPos = addTop.merge[i][0].split(','); + endPos = addTop.merge[i][1].split(','); + mergeArrays.push([numberToLetter(startPos[1]) + startPos[0], numberToLetter(endPos[1]) + endPos[0]]) + } + + } + } + } + if (addBottom && Array.isArray(addBottom.data) && addBottom.data.length > 0) { + for (i = 0; i < addBottom.data.length; i++) { + tempArray = {}, jumpColsNum = 0; + for (j = 0; j < (addBottom.data[i].length > columns.length ? addBottom.data[i].length : columns.length); j++) { + if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) { + tempArray[columns[j] ? columns[j].key : j + ''] = addBottom.data[i][j - jumpColsNum] || '' + } else { + jumpColsNum++ + } + } + data.push(tempArray); + } + + if (Array.isArray(addBottom.heights) && addBottom.heights.length > 0) { + for (i = 0; i < addBottom.heights.length; i++) { + heightConfig[data.length - addBottom.data.length + i] = addBottom.heights[i] + } + } + + if (Array.isArray(addBottom.merge) && addBottom.merge.length > 0) { + for (i = 0; i < addBottom.merge.length; i++) { + if (addBottom.merge[i].length === 2) { + startPos = addBottom.merge[i][0].split(','); + endPos = addBottom.merge[i][1].split(','); + mergeArrays.push([numberToLetter(startPos[1]) + (data.length - addBottom.data.length + parseInt(startPos[0])), numberToLetter(endPos[1]) + (data.length - addBottom.data.length + parseInt(endPos[0]))]) + } + } + } + } + } + + var index = 0, alignTrans = {'left': 'left', 'center': 'center', 'right': 'right'}, + borderTypes = ['top', 'bottom', 'left', 'right']; + for (i = 0; i < columns.length; i++) { + if ((columns[i].field || columns[i].type === 'numbers') && !columns[i].hide) { + if (columns[i].width) { + widths[String.fromCharCode(64 + parseInt(++index))] = columns[i].width + } + showField[columns[i].key] = function (field, line, data, curIndex) { + var bgColor = 'ffffff', color = '000000', family = 'Calibri', size = 12, cellType = 's', + bodyIndex = curIndex - (customColumns ? 1 : cols.length) - tableStartIndex + 1, + border = { + top: { + style: 'thin', + color: {indexed: 64} + }, + bottom: { + style: 'thin', + color: {indexed: 64} + }, + left: { + style: 'thin', + color: {indexed: 64} + }, + right: { + style: 'thin', + color: {indexed: 64} + } + } + if (finalExcel.border) { + for (j = 0; j < borderTypes.length; j++) { + if (finalExcel.border[borderTypes[j]]) { + border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style + border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color + } else if (finalExcel.border['color'] || finalExcel.border['style']) { + border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style + border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color + } + } + } + if (curIndex < tableStartIndex - 1 || curIndex >= data.length - bottomLength) { + return { + v: line[field] || '', + s: {// s 代表样式 + alignment: { + horizontal: 'center', + vertical: 'center' + }, + font: {name: family, sz: size, color: {rgb: color}}, + fill: { + fgColor: {rgb: bgColor, bgColor: {indexed: 64}} + }, + border: border + }, + t: cellType + } + } else if (bodyIndex < 0) { + // 头部样式 + bgColor = 'C7C7C7'; + if (finalExcel.head) { + bgColor = finalExcel.head.bgColor || bgColor; + color = finalExcel.head.color || color; + family = finalExcel.head.family || family; + size = finalExcel.head.size || size; + } + } else { + // 默认全局字体样式 + if (finalExcel.font) { + bgColor = finalExcel.font.bgColor || bgColor; + color = finalExcel.font.color || color; + family = finalExcel.font.family || family; + size = finalExcel.font.size || size; + } + // 默认全局边框样式 + if (finalExcel.border) { + for (j = 0; j < borderTypes.length; j++) { + if (finalExcel.border[borderTypes[j]]) { + border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style + border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color + } else if (finalExcel.border['color'] || finalExcel.border['style']) { + border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style + border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color + } + } + } + // 列上配置了自定义样式 + if (columnsMap[columnsMap.length - 1][field].excel) { + var colExcel = typeof columnsMap[columnsMap.length - 1][field].excel === 'function' ? columnsMap[columnsMap.length - 1][field].excel.call(this, line, bodyIndex, data.length - cols.length - tableStartIndex + 1 - bottomLength) : columnsMap[columnsMap.length - 1][field].excel + if (colExcel) { + bgColor = colExcel.bgColor || bgColor; + color = colExcel.color || color; + family = colExcel.family || family; + size = colExcel.size || size; + cellType = colExcel.cellType || cellType; + + if (colExcel.border) { + for (j = 0; j < borderTypes.length; j++) { + if (colExcel.border[borderTypes[j]]) { + border[borderTypes[j]].style = colExcel.border[borderTypes[j]].style || border[borderTypes[j]].style + border[borderTypes[j]].color = handleRgb(colExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color + } else if (colExcel.border['color'] || colExcel.border['style']) { + border[borderTypes[j]].style = colExcel.border['style'] || border[borderTypes[j]].style + border[borderTypes[j]].color = handleRgb(colExcel.border['color']) || border[borderTypes[j]].color + } + } + } + } + } + } + + function handleNull(val) { + if (typeof val === 'undefined' || val === null) { + return "" + } + return val; + } + + var value = bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].templet ? + typeof columnsMap[columnsMap.length - 1][field].templet === 'function' ? + $('
    ' + columnsMap[columnsMap.length - 1][field].templet(line) + '
    ').find(':input').length === 0 ? $('
    ' + columnsMap[columnsMap.length - 1][field].templet(line) + '
    ').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-key="' + field + '"]').find(':input').val() || handleNull(line[field]) + : $('
    ' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
    ').find(':input').length === 0 ? $('
    ' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
    ').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-key="' + field + '"]').find(':input').val() || handleNull(line[field]) + : bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].type === 'numbers' ? bodyIndex + 1 : handleNull(line[field]); + return { + v: value,// v 代表单元格的值 + s: {// s 代表样式 + alignment: { + horizontal: columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align ? alignTrans[columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align] : 'top', + vertical: 'center' + }, + font: {name: family, sz: size, color: {rgb: color}}, + fill: { + fgColor: {rgb: bgColor, bgColor: {indexed: 64}} + }, + border: border + }, + t: UNHANDLED_VALUES.indexOf(value) === -1 ? cellType : 's' + }; + } + } + } + + excel.exportExcel({ + sheet1: excel.filterExportData(data, showField) + }, filename, type, { + extend: { + '!cols': excel.makeColConfig(widths, 80), + '!merges': excel.makeMergeConfig(mergeArrays), + '!rows': excel.makeRowConfig(heightConfig, 16) + } + }); + layer.close(loading); + + // 合成 excel.js 识别的 rgb + function handleRgb(rgb) { + return rgb ? {rgb: rgb} : rgb + } + + function numberToLetter(num) { + var result = []; + while (num) { + var t = num % 26; + if (!t) { + t = 26; + --num; + } + // Polyfill 兼容旧浏览器 + if (!String.fromCodePoint) (function (stringFromCharCode) { + var fromCodePoint = function (_) { + var codeUnits = [], codeLen = 0, result = ""; + for (var index = 0, len = arguments.length; index !== len; ++index) { + var codePoint = +arguments[index]; + // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity` + // The surrounding `!(...)` is required to correctly handle `NaN` cases + // The (codePoint>>>0) === codePoint clause handles decimals and negatives + if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint)) + throw RangeError("Invalid code point: " + codePoint); + if (codePoint <= 0xFFFF) { // BMP code point + codeLen = codeUnits.push(codePoint); + } else { // Astral code point; split in surrogate halves + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + codePoint -= 0x10000; + codeLen = codeUnits.push( + (codePoint >> 10) + 0xD800, // highSurrogate + (codePoint % 0x400) + 0xDC00 // lowSurrogate + ); + } + if (codeLen >= 0x3fff) { + result += stringFromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } + } + return result + stringFromCharCode.apply(null, codeUnits); + }; + try { // IE 8 only supports `Object.defineProperty` on DOM elements + Object.defineProperty(String, "fromCodePoint", { + "value": fromCodePoint, "configurable": true, "writable": true + }); + } catch (e) { + String.fromCodePoint = fromCodePoint; + } + }(String.fromCharCode)); + result.push(String.fromCodePoint(t + 64)); + if (!String.fromCodePoint) (function (stringFromCharCode) { + var fromCodePoint = function (_) { + var codeUnits = [], codeLen = 0, result = ""; + for (var index = 0, len = arguments.length; index !== len; ++index) { + var codePoint = +arguments[index]; + // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity` + // The surrounding `!(...)` is required to correctly handle `NaN` cases + // The (codePoint>>>0) === codePoint clause handles decimals and negatives + if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint)) + throw RangeError("Invalid code point: " + codePoint); + if (codePoint <= 0xFFFF) { // BMP code point + codeLen = codeUnits.push(codePoint); + } else { // Astral code point; split in surrogate halves + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + codePoint -= 0x10000; + codeLen = codeUnits.push( + (codePoint >> 10) + 0xD800, // highSurrogate + (codePoint % 0x400) + 0xDC00 // lowSurrogate + ); + } + if (codeLen >= 0x3fff) { + result += stringFromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } + } + return result + stringFromCharCode.apply(null, codeUnits); + }; + try { // IE 8 only supports `Object.defineProperty` on DOM elements + Object.defineProperty(String, "fromCodePoint", { + "value": fromCodePoint, "configurable": true, "writable": true + }); + } catch (e) { + String.fromCodePoint = fromCodePoint; + } + }(String.fromCharCode)); + num = ~~(num / 26); + } + return result.reverse().join(''); + } + }, + startsWith: function (content, str) { + var reg = new RegExp("^" + str); + return content && reg.test(content); + }, + // 深度克隆-不丢失方法 + deepClone: function (obj) { + var newObj = Array.isArray(obj) ? [] : {} + if (obj && typeof obj === "object") { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key]; + } + } + } + return newObj + }, + deepStringify: function (obj) { + var JSON_SERIALIZE_FIX = { + PREFIX: "[[JSON_FUN_PREFIX_", + SUFFIX: "_JSON_FUN_SUFFIX]]" + }; + return JSON.stringify(obj, function (key, value) { + if (typeof value === 'function') { + return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX; + } + return value; + }); + }, + /* layui table 中原生的方法 */ + getScrollWidth: function (elem) { + var width = 0; + if (elem) { + width = elem.offsetWidth - elem.clientWidth; + } else { + elem = document.createElement('div'); + elem.style.width = '100px'; + elem.style.height = '100px'; + elem.style.overflowY = 'scroll'; + + document.body.appendChild(elem); + width = elem.offsetWidth - elem.clientWidth; + document.body.removeChild(elem); + } + return width; + } + , getCompleteCols: function (origin) { + var cols = this.deepClone(origin); + var i, j, k, cloneCol; + for (i = 0; i < cols.length; i++) { + for (j = 0; j < cols[i].length; j++) { + if (!cols[i][j].exportHandled) { + if (cols[i][j].rowspan > 1) { + cloneCol = this.deepClone(cols[i][j]) + cloneCol.exportHandled = true; + k = i + 1; + while (k < cols.length) { + cols[k].splice(j, 0, cloneCol) + k++ + } + } + if (cols[i][j].colspan > 1) { + cloneCol = this.deepClone(cols[i][j]) + cloneCol.exportHandled = true; + for (k = 1; k < cols[i][j].colspan; k++) { + cols[i].splice(j, 0, cloneCol) + } + j = j + parseInt(cols[i][j].colspan) - 1 + } + } + } + } + return cols[cols.length - 1]; + } + , parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本 + var str = item3.templet ? function () { + return typeof item3.templet === 'function' + ? item3.templet(tplData) + : laytpl($(item3.templet).html() || String(content)).render(tplData) + }() : content; + return text ? $('
    ' + str + '
    ').text() : str; + } + , cache: cache + }; + + // 输出 + exports('tableFilter', mod); }); diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js index 44e75ae..fa98da3 100644 --- a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js +++ b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js @@ -4,100 +4,100 @@ * @author: yelog * @link: https://github.com/yelog/layui-soul-table * @license: MIT - * @version: v1.6.1 + * @version: v1.9.0 */ layui.define(['table'], function (exports) { - var $ = layui.jquery; + var $ = layui.jquery; - // 封装方法 - var mod = { - /** - * 渲染入口 - * @param myTable - */ - render: function (myTable) { - var tableBox = $(myTable.elem).next().children('.layui-table-box'), - $main = $(tableBox.children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()), - $fixLeft = $(tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()), - $fixRight = $(tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()), - mergeRecord = {}; + // 封装方法 + var mod = { + /** + * 渲染入口 + * @param myTable + */ + render: function (myTable) { + var tableBox = $(myTable.elem).next().children('.layui-table-box'), + $main = $(tableBox.children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()), + $fixLeft = $(tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()), + $fixRight = $(tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()), + mergeRecord = {}; - layui.each(myTable.cols, function (i1, item1) { - layui.each(item1, function (i2, item2) { - if (item2.merge && item2.field) { - var mergeField = [item2.field]; - if (item2.merge !== true) { - if (typeof item2.merge === 'string') { - mergeField = [item2.merge] - } else { - mergeField = item2.merge - } - } - mergeRecord[myTable.index + '-' + i1 + '-' + i2] = { mergeField: mergeField, rowspan: 1 } - } - }) - }) - - $main.each(function (i) { - - for (var item in mergeRecord) { - if (i === $main.length - 1 || isMaster(i, item)) { - var tdHeight = $(this).children('[data-key="' + item + '"]').outerHeight(), patchHeight = 0; // 获取td高度 - if ($main.eq(i).data('index') === 0) { - patchHeight = 1 - } - $(this).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({ - 'position': 'static', - 'height': tdHeight * mergeRecord[item].rowspan + patchHeight - }).children().css({ - height: 'auto', - 'white-space': 'normal', - 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10 - }); - $fixLeft.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({ - 'position': 'static', - 'height': tdHeight * mergeRecord[item].rowspan + patchHeight - }).children().css({ - height: 'auto', - 'white-space': 'normal', - 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10 - }); - $fixRight.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({ - 'position': 'static', - 'height': tdHeight * mergeRecord[item].rowspan + patchHeight - }).children().css({ - height: 'auto', - 'white-space': 'normal', - 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10 - }); - mergeRecord[item].rowspan = 1; - } else { - $(this).children('[data-key="' + item + '"]').remove(); - $fixLeft.eq(i).children('[data-key="' + item + '"]').remove(); - $fixRight.eq(i).children('[data-key="' + item + '"]').remove(); - mergeRecord[item].rowspan += 1; - } - } - }) - - function isMaster(index, item) { - var mergeField = mergeRecord[item].mergeField; - var dataLength = layui.table.cache[myTable.id].length; - for (var i = 0; i < mergeField.length; i++) { - - if (layui.table.cache[myTable.id][dataLength - 2 - index][mergeField[i]] - !== layui.table.cache[myTable.id][dataLength - 1 - index][mergeField[i]]) { - return true; - } - } - return false; + layui.each(myTable.cols, function (i1, item1) { + layui.each(item1, function (i2, item2) { + if (item2.merge && item2.field) { + var mergeField = [item2.field]; + if (item2.merge !== true) { + if (typeof item2.merge === 'string') { + mergeField = [item2.merge] + } else { + mergeField = item2.merge + } } + mergeRecord[myTable.index + '-' + i1 + '-' + i2] = {mergeField: mergeField, rowspan: 1} + } + }) + }) + $main.each(function (i) { + + for (var item in mergeRecord) { + if (i === $main.length - 1 || isMaster(i, item)) { + var tdHeight = $(this).children('[data-key="' + item + '"]').outerHeight(), patchHeight = 0; // 获取td高度 + if ($main.eq(i).data('index') === 0) { + patchHeight = 1 + } + $(this).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({ + 'position': 'static', + 'height': tdHeight * mergeRecord[item].rowspan + patchHeight + }).children().css({ + height: 'auto', + 'white-space': 'normal', + 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10 + }); + $fixLeft.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({ + 'position': 'static', + 'height': tdHeight * mergeRecord[item].rowspan + patchHeight + }).children().css({ + height: 'auto', + 'white-space': 'normal', + 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10 + }); + $fixRight.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({ + 'position': 'static', + 'height': tdHeight * mergeRecord[item].rowspan + patchHeight + }).children().css({ + height: 'auto', + 'white-space': 'normal', + 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10 + }); + mergeRecord[item].rowspan = 1; + } else { + $(this).children('[data-key="' + item + '"]').remove(); + $fixLeft.eq(i).children('[data-key="' + item + '"]').remove(); + $fixRight.eq(i).children('[data-key="' + item + '"]').remove(); + mergeRecord[item].rowspan += 1; + } } - }; + }) - // 输出 - exports('tableMerge', mod); + function isMaster(index, item) { + var mergeField = mergeRecord[item].mergeField; + var dataLength = layui.table.cache[myTable.id].length; + for (var i = 0; i < mergeField.length; i++) { + + if (layui.table.cache[myTable.id][dataLength - 2 - index][mergeField[i]] + !== layui.table.cache[myTable.id][dataLength - 1 - index][mergeField[i]]) { + return true; + } + } + return false; + } + + } + }; + + // 输出 + exports('tableMerge', mod); }); diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js b/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js index 5948467..920a53c 100644 --- a/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js +++ b/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js @@ -166,14 +166,14 @@ layui.define(['layer', 'table','soulTable'], function (exports) { if (isOpen) { $(this).hide(); var index = $(this).attr('data-index'); - $('div[lay-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').hide(); + $('div[lay-table-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').hide(); if ('dir' == ttype && tOpen == isOpen) { $ti.trigger('click'); } } else { $(this).show(); var index = $(this).attr('data-index'); - $('div[lay-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').show(); + $('div[lay-table-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').show(); if (linkage && 'dir' == ttype && tOpen == isOpen) { $ti.trigger('click'); } diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css b/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css index 7037848..202c082 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css +++ b/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css @@ -19,7 +19,7 @@ pre{white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; w /** 初始化全局标签 **/ body{line-height: 1.6; color: #333; color: rgba(0,0,0,.85); font: 14px Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif;} -hr{height: 0; line-height: 0; margin: 10px 0; padding: 0; border: none!important; border-bottom: 1px solid #eee !important; clear: both; overflow: hidden; background: none;} +hr{height: 0; line-height: 0; margin: 10px 0; padding: 0; border: none; border-bottom: 1px solid #eee; clear: both; overflow: hidden; background: none;} a{color: #333; text-decoration:none;} a:hover{color: #777;} a cite{font-style: normal; *cursor:pointer;} @@ -513,12 +513,37 @@ a cite{font-style: normal; *cursor:pointer;} .layui-col-space32>*{padding: 16px;} -/** 页面元素 **/ -.layui-btn, .layui-input, .layui-textarea, .layui-upload-button, .layui-select{outline: none; -webkit-appearance: none; transition: all .3s; -webkit-transition: all .3s; box-sizing: border-box;} +/* 内边距 */ +.layui-padding-1{padding: 4px !important;} +.layui-padding-2{padding: 8px !important;} +.layui-padding-3{padding: 16px !important;} +.layui-padding-4{padding: 32px !important;} +.layui-padding-5{padding: 48px !important;} -/* 引用 */.layui-elem-quote{margin-bottom: 10px; padding: 15px; line-height: 1.8; border-left: 5px solid #16b777; border-radius: 0 2px 2px 0; background-color: #fafafa;} +/* 外边距 */ +.layui-margin-1{margin: 4px !important;} +.layui-margin-2{margin: 8px !important;} +.layui-margin-3{margin: 16px !important;} +.layui-margin-4{margin: 32px !important;} +.layui-margin-5{margin: 48px !important;} + + +/* + * 页面元素 + */ + +.layui-btn, +.layui-input, +.layui-select, +.layui-textarea, +.layui-upload-button{outline: none; -webkit-appearance: none; transition: all .3s; -webkit-transition: all .3s; box-sizing: border-box;} + +/* 引用 */ +.layui-elem-quote{margin-bottom: 10px; padding: 15px; line-height: 1.8; border-left: 5px solid #16b777; border-radius: 0 2px 2px 0; background-color: #fafafa;} .layui-quote-nm{border-style: solid; border-width: 1px; border-left-width: 5px; background: none;} -/* 字段集合 */.layui-elem-field{margin-bottom: 10px; padding: 0; border-width: 1px; border-style: solid;} + +/* 字段集合 */ +.layui-elem-field{margin-bottom: 10px; padding: 0; border-width: 1px; border-style: solid;} .layui-elem-field legend{margin-left: 20px; padding: 0 10px; font-size: 20px;} .layui-field-title{margin: 16px 0; border-width: 0; border-top-width: 1px;} .layui-field-box{padding: 15px;} @@ -534,10 +559,8 @@ a cite{font-style: normal; *cursor:pointer;} /* - - 面板 - -*/ + * 面板 + */ /* 折叠面板 */ @@ -566,8 +589,8 @@ a cite{font-style: normal; *cursor:pointer;} .layui-panel-window{position: relative; padding: 15px; border-radius: 0; border-top: 5px solid #eee; background-color: #fff;} /* 其它辅助 */ -.layui-auxiliar-moving{position: fixed; left: 0; right: 0; top: 0; bottom: 0; width: 100%; height: 100%; background: none; z-index: 9999999999;} -.layui-scollbar-hide{overflow: hidden !important;} +.layui-auxiliar-moving{position: fixed; left: 0; right: 0; top: 0; bottom: 0; width: 100%; height: 100%; background: none; z-index: 9999999999; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none;} +.layui-scrollbar-hide{overflow: hidden !important;} /* @@ -613,6 +636,15 @@ a cite{font-style: normal; *cursor:pointer;} .layui-border-purple{border-width: 1px; border-style: solid; border-color: #a233c6!important; color: #a233c6!important;} .layui-border-black{border-width: 1px; border-style: solid; border-color: #2f363c!important; color: #2f363c!important;} +/* 分割线边框 */ +hr.layui-border-red, +hr.layui-border-orange, +hr.layui-border-green, +hr.layui-border-cyan, +hr.layui-border-blue, +hr.layui-border-purple, +hr.layui-border-black{border-width: 0 0 1px;} + /* 背景边框 */ .layui-timeline-item:before{background-color: #eee;} @@ -642,9 +674,9 @@ a cite{font-style: normal; *cursor:pointer;} .layui-text a:not(.layui-btn){color: #01AAED;} .layui-text a:not(.layui-btn):hover{text-decoration: underline;} .layui-text blockquote:not(.layui-elem-quote){padding: 5px 15px; border-left: 5px solid #eee;} -.layui-text pre > code:not(.layui-code){padding: 15px; font-family: Courier New,Lucida Console,Consolas; background-color: #fafafa;} +.layui-text pre > code:not(.layui-code){padding: 15px; font-family: "Courier New",Consolas,"Lucida Console";} -/* 字体大小及颜色 */ +/* 字体大小 */ .layui-font-12{font-size: 12px !important;} .layui-font-13{font-size: 13px !important;} .layui-font-14{font-size: 14px !important;} @@ -658,6 +690,7 @@ a cite{font-style: normal; *cursor:pointer;} .layui-font-30{font-size: 30px !important;} .layui-font-32{font-size: 32px !important;} +/* 字体颜色 */ .layui-font-red{color: #ff5722 !important;} /*赤*/ .layui-font-orange{color: #ffb800!important;} /*橙*/ .layui-font-green{color: #16baaa!important;} /*绿*/ @@ -670,10 +703,8 @@ a cite{font-style: normal; *cursor:pointer;} /* - - 按钮 - -*/ + * 按钮 + */ .layui-btn{display: inline-block; vertical-align: middle; height: 38px; line-height: 38px; border: 1px solid transparent; padding: 0 18px; background-color: #16baaa; color: #fff; white-space: nowrap; text-align: center; font-size: 14px; border-radius: 2px; cursor: pointer; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;} .layui-btn:hover{opacity: 0.8; filter:alpha(opacity=80); color: #fff;} @@ -764,8 +795,8 @@ a cite{font-style: normal; *cursor:pointer;} .layui-input-group{position: relative; display: table; box-sizing: border-box;} .layui-input-group>*{display: table-cell; vertical-align: middle; position: relative;} .layui-input-group .layui-input{padding-right: 15px;} -.layui-input-group .layui-input-prefix{width: auto; border-right: 0;} -.layui-input-group .layui-input-suffix{width: auto; border-left: 0;} +.layui-input-group > .layui-input-prefix{width: auto; border-right: 0;} +.layui-input-group > .layui-input-suffix{width: auto; border-left: 0;} .layui-input-group .layui-input-split{white-space: nowrap;} /* 输入框前后缀容器 */ @@ -783,7 +814,9 @@ a cite{font-style: normal; *cursor:pointer;} .layui-input-wrap .layui-input-split{pointer-events: none;} .layui-input-wrap .layui-input:hover + .layui-input-split{border-color: #d2d2d2;} .layui-input-wrap .layui-input:focus + .layui-input-split{border-color: #16b777;} +.layui-input-wrap .layui-input.layui-form-danger:focus + .layui-input-split{border-color: #ff5722;} .layui-input-wrap .layui-input-prefix.layui-input-split{border-width: 0; border-right-width: 1px;} +.layui-input-wrap .layui-input-suffix.layui-input-split{border-width: 0; border-left-width: 1px;} /* 输入框动态点缀 */ .layui-input-affix{line-height: 38px;} @@ -793,15 +826,16 @@ a cite{font-style: normal; *cursor:pointer;} .layui-input-affix .layui-icon:hover{color: rgba(0,0,0,.6);} /* 数字输入框动态点缀 */ -.layui-input-number{width: 24px; padding: 0;} -.layui-input-number .layui-icon{position: absolute; right: 0; width: 100%; height: 50%; line-height: normal; font-size: 12px;} -.layui-input-number .layui-icon:before{position: absolute; left: 50%; top: 50%; margin-top: -6px; margin-left: -6px;} -.layui-input-number .layui-icon:first-child{top: 0; border-bottom: 1px solid #eee;} -.layui-input-number .layui-icon:last-child{bottom: 0;} -.layui-input-number .layui-icon:hover{font-weight: 700;} +.layui-input-wrap .layui-input-number{width: 24px; padding: 0;} +.layui-input-wrap .layui-input-number .layui-icon{position: absolute; right: 0; width: 100%; height: 50%; line-height: normal; font-size: 12px;} +.layui-input-wrap .layui-input-number .layui-icon:before{position: absolute; left: 50%; top: 50%; margin-top: -6px; margin-left: -6px;} +.layui-input-wrap .layui-input-number .layui-icon-up{top: 0; border-bottom: 1px solid #eee;} +.layui-input-wrap .layui-input-number .layui-icon-down{bottom: 0;} +.layui-input-wrap .layui-input-number .layui-icon:hover{font-weight: 700;} .layui-input-wrap .layui-input[type="number"]::-webkit-outer-spin-button, .layui-input-wrap .layui-input[type="number"]::-webkit-inner-spin-button{-webkit-appearance: none !important;} .layui-input-wrap .layui-input[type="number"]{-moz-appearance: textfield;} +.layui-input-wrap .layui-input[type="number"].layui-input-number-out-of-range{color:#ff5722;} @@ -826,6 +860,8 @@ a cite{font-style: normal; *cursor:pointer;} :root .layui-form-selected .layui-edge{margin-top: -9px\0/IE9;} .layui-form-selectup dl{top: auto; bottom: 42px;} .layui-select-none{margin: 5px 0; text-align: center; color: #999;} +.layui-select-panel-wrap {position: absolute; z-index: 99999999;} +.layui-select-panel-wrap dl{position: relative; display: block; top:0;} .layui-select-disabled .layui-disabled{border-color: #eee !important;} .layui-select-disabled .layui-edge{border-top-color: #d2d2d2} @@ -839,11 +875,11 @@ a cite{font-style: normal; *cursor:pointer;} .layui-form-checkbox:hover > div{background-color: #c2c2c2;} .layui-form-checkbox > i{position: absolute; right: 0; top: 0; width: 30px; height: 100%; border: 1px solid #d2d2d2; border-left: none; border-radius: 0 2px 2px 0; color: #fff; color: rgba(255,255,255,0); font-size: 20px; text-align: center; box-sizing: border-box;} .layui-form-checkbox:hover > i{border-color: #c2c2c2; color: #c2c2c2;} -.layui-form-checked, +.layui-form-checked, .layui-form-checked:hover{border-color: #16b777;} -.layui-form-checked > div, +.layui-form-checked > div, .layui-form-checked:hover > div{background-color: #16b777;} -.layui-form-checked > i, +.layui-form-checked > i, .layui-form-checked:hover > i{color: #16b777;} .layui-form-item .layui-form-checkbox{margin-top: 4px;} .layui-form-checkbox.layui-checkbox-disabled > div{background-color: #eee !important;} @@ -870,6 +906,18 @@ a cite{font-style: normal; *cursor:pointer;} .layui-form-onswitch > i{left: 100%; margin-left: -21px; background-color: #fff;} .layui-form-onswitch > div{margin-left: 0; margin-right: 21px; color: #fff!important;} +/* 无样式风格-根据模板自定义样式*/ +.layui-form-checkbox[lay-skin="none"] *, +.layui-form-radio[lay-skin="none"] *{box-sizing: border-box;} +.layui-form-checkbox[lay-skin="none"], +.layui-form-radio[lay-skin="none"] {position: relative; min-height: 20px; margin: 0; padding: 0; height: auto; line-height: normal;} +.layui-form-checkbox[lay-skin="none"]>div, +.layui-form-radio[lay-skin="none"]>div{position: relative; top: 0; left: 0; cursor: pointer; z-index: 10; color: inherit; background-color: inherit;} +.layui-form-checkbox[lay-skin="none"]>i, +.layui-form-radio[lay-skin="none"]>i{display: none;} +.layui-form-checkbox[lay-skin="none"].layui-checkbox-disabled>div, +.layui-form-radio[lay-skin="none"].layui-radio-disabled>div{cursor: not-allowed;} + .layui-checkbox-disabled{border-color: #eee !important;} .layui-checkbox-disabled > div{color: #c2c2c2!important;} .layui-checkbox-disabled > i{border-color: #eee !important;} @@ -980,6 +1028,9 @@ a cite{font-style: normal; *cursor:pointer;} .layui-table-checked{background-color: #dbfbf0;} .layui-table-checked.layui-table-hover, .layui-table-checked.layui-table-click{background-color: #abf8dd;} +.layui-table-disabled-transition *, +.layui-table-disabled-transition *:before, +.layui-table-disabled-transition *:after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important} .layui-table th, @@ -1035,8 +1086,10 @@ a cite{font-style: normal; *cursor:pointer;} .layui-table-view .layui-form-checkbox[lay-skin="primary"] i{width: 18px; height: 18px; line-height: 16px;} .layui-table-view .layui-form-radio{line-height: 0; padding: 0;} .layui-table-view .layui-form-radio>i{margin: 0; font-size: 20px;} -.layui-table-init{position: absolute; left: 0; top: 0; width: 100%; height: 100%; text-align: center; z-index: 199;} -.layui-table-init .layui-icon{position: absolute; left: 50%; top: 50%; margin: -15px 0 0 -15px; font-size: 30px; color: #c2c2c2;} +.layui-table-init{position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: 0; z-index: 199; transition: opacity .1s; user-select: none; opacity: 1;} +.layui-table-init.layui-hide-v{opacity: 0;} +.layui-table-loading-icon{position: absolute; width: 100%\0; left: 50%; left:auto\0; top: 50%; margin-top: -15px\0; transform: translate(-50%, -50%); transform: none\0; text-align: center;} +.layui-table-loading-icon .layui-icon{font-size: 30px; color: #c2c2c2;} .layui-table-header{border-width: 0; border-bottom-width: 1px; overflow: hidden;} .layui-table-header .layui-table{margin-bottom: -1px;} @@ -1071,6 +1124,7 @@ a cite{font-style: normal; *cursor:pointer;} .layui-table-cell{height: 38px; line-height: 28px; padding: 6px 15px; position: relative; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; box-sizing: border-box;} .layui-table-cell .layui-form-checkbox[lay-skin="primary"]{top: -1px; padding: 0;} +.layui-table-cell .layui-form-checkbox[lay-skin="primary"] > div{padding-left: 24px;} .layui-table-cell .layui-table-link{color: #01AAED;} .layui-table-cell .layui-btn{vertical-align: inherit;} .layui-table-cell[align="center"]{-webkit-box-pack: center;} @@ -1130,16 +1184,28 @@ select.layui-table-edit{padding: 0 0 0 10px; border-color: #d2d2d2;} /* 展开溢出的单元格 */ .layui-table-grid .layui-table-cell{overflow: visible;} -.layui-table-grid-down{position: absolute; top: 0; right: 0; width: 26px; height: 100%; padding: 5px 0; border-width: 0; border-left-width: 1px; text-align: center; background-color: #fff; color: #999; cursor: pointer;} -.layui-table-grid-down .layui-icon{position: absolute; top: 50%; left: 50%; margin: -8px 0 0 -8px;} +.layui-table-grid-down{position: absolute; top: 0; right: 0; width: 24px; height: 100%; padding: 5px 0; border-width: 0; border-left-width: 1px; text-align: center; background-color: #fff; color: #999; cursor: pointer;} +.layui-table-grid-down .layui-icon{position: absolute; top: 50%; left: 50%; margin: -8px 0 0 -8px; font-size: 14px;} .layui-table-grid-down:hover{background-color: #fbfbfb;} +/* 单元格多行展开风格 */ +.layui-table-expanded{height: 95px;} +.layui-table-expanded .layui-table-cell, +.layui-table-view .layui-table[lay-size="sm"] .layui-table-expanded .layui-table-cell, +.layui-table-view .layui-table[lay-size="lg"] .layui-table-expanded .layui-table-cell{height: auto; max-height: 94px; white-space: normal; text-overflow: clip;} +.layui-table-cell-c{position: absolute; bottom: -10px; right: 50%; margin-right: -9px; width: 20px; height: 20px; line-height: 18px; cursor: pointer; text-align: center; background-color: #fff; border: 1px solid #eee; border-radius: 50%; z-index: 1000; transition: 0.3s all; font-size: 14px;} +.layui-table-cell-c:hover{border-color: #16b777;} +.layui-table-expanded td:hover .layui-table-cell{overflow: auto;} +.layui-table-main > .layui-table > tbody > tr:last-child > td > .layui-table-cell-c{bottom: 0;} + +/* 单元格 TIPS 展开风格 */ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-shadow: 0 1px 6px rgba(0,0,0,.12);} .layui-table-tips-main{margin: -49px 0 0 -1px; max-height: 150px; padding: 8px 15px; font-size: 14px; overflow-y: scroll; background-color: #fff; color: #5F5F5F;} .layui-table-tips-c{position: absolute; right: -3px; top: -13px; width: 20px; height: 20px; padding: 3px; cursor: pointer; background-color: #5F5F5F; border-radius: 50%; color: #fff;} .layui-table-tips-c:hover{background-color: #777;} .layui-table-tips-c:before{position: relative; right: -2px;} + /** 树表 **/ .layui-table-tree-nodeIcon {max-width: 20px;} .layui-table-tree-nodeIcon > * {width: 100%;} @@ -1166,7 +1232,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh .layui-menu li, .layui-menu-body-title, .layui-menu-body-title a{padding: 5px 15px; color: initial} -.layui-menu li{position: relative; margin: 1px 0; line-height: 26px; color: rgba(0,0,0,.8); font-size: 14px; white-space: nowrap; cursor: pointer; transition: all .3s;} +.layui-menu li{position: relative; margin: 0 0 1px; line-height: 26px; color: rgba(0,0,0,.8); font-size: 14px; white-space: nowrap; cursor: pointer; transition: all .3s;} .layui-menu li:hover{background-color: #f8f8f8; } .layui-menu li.layui-disabled, .layui-menu li.layui-disabled *{background: none !important; color: #d2d2d2 !important; cursor: not-allowed !important;} @@ -1189,6 +1255,8 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh .layui-menu .layui-menu-item-down:hover{cursor: pointer;} .layui-menu .layui-menu-item-up>.layui-menu-body-title{ color: rgba(0,0,0,.8);} .layui-menu .layui-menu-item-up>ul{visibility: hidden; height: 0; overflow: hidden;} +.layui-menu .layui-menu-item-down>.layui-menu-body-title>.layui-icon-down{transform: rotate(180deg);} +.layui-menu .layui-menu-item-up>.layui-menu-body-title>.layui-icon-up{transform: rotate(-180deg);} .layui-menu .layui-menu-item-up>.layui-menu-body-title:hover>.layui-icon, .layui-menu .layui-menu-item-down:hover>.layui-menu-body-title>.layui-icon{color: rgba(0,0,0,1);} .layui-menu .layui-menu-item-down>ul{visibility: visible; height: auto;} @@ -1202,7 +1270,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh .layui-menu-body-title{position: relative; margin: -5px -15px; overflow: hidden; text-overflow: ellipsis;} .layui-menu-body-title a{display: block; margin: -5px -15px; color: rgba(0,0,0,.8);} .layui-menu-body-title a:hover{transition: all .3s;} -.layui-menu-body-title>.layui-icon{position: absolute; right: 15px; top: 50%; margin-top: -6px; line-height: normal; font-size: 14px;} +.layui-menu-body-title>.layui-icon{position: absolute; right: 15px; top: 50%; margin-top: -6px; line-height: normal; font-size: 14px; transition: all .2s; -webkit-transition: all .2s;} .layui-menu-body-title>.layui-icon:hover{transition: all .3s;} .layui-menu-body-title>.layui-icon-right{right: 14px;} .layui-menu-body-panel{display: none; position: absolute; top: -7px; left: 100%; z-index: 1000; margin-left: 13px; padding: 5px 0;} @@ -1271,26 +1339,24 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh .layui-nav-itemed>a{color: #fff !important;} .layui-nav-tree .layui-nav-bar{background-color: #16baaa;} -.layui-nav-tree .layui-nav-child{position: relative; z-index: 0; top: 0; border: none; box-shadow: none;} +.layui-nav-tree .layui-nav-child{position: relative; z-index: 0; top: 0; border: none; background: none; background-color: rgba(0,0,0,.3); box-shadow: none;} .layui-nav-tree .layui-nav-child dd{margin: 0;} .layui-nav-tree .layui-nav-child a{color: #fff; color: rgba(255,255,255,.7);} -.layui-nav-tree .layui-nav-child a:hover, -.layui-nav-tree .layui-nav-child{background: none; color: #fff;} +.layui-nav-tree .layui-nav-child a:hover{background: none; color: #fff;} -.layui-nav-itemed>.layui-nav-child{display: block; background-color: rgba(0,0,0,.3) !important;} +/* 垂直导航 - 展开状态 */ +.layui-nav-itemed>.layui-nav-child, .layui-nav-itemed>.layui-nav-child>.layui-this>.layui-nav-child{display: block;} -/* 侧边 */.layui-nav-side{position: fixed; top: 0; bottom: 0; left: 0; overflow-x: hidden; z-index: 999;} +/* 垂直导航 - 侧边 */ +.layui-nav-side{position: fixed; top: 0; bottom: 0; left: 0; overflow-x: hidden; z-index: 999;} /* 导航浅色背景 */ .layui-nav.layui-bg-gray .layui-nav-item a, -.layui-nav-tree.layui-bg-gray a{color: rgba(0,0,0,.8);} -.layui-nav-tree.layui-bg-gray{padding: 6px 0;} +.layui-nav-tree.layui-bg-gray a{color: #373737; color: rgba(0,0,0,.8);} .layui-nav-tree.layui-bg-gray .layui-nav-itemed>a{color: #000 !important;} .layui-nav.layui-bg-gray .layui-this a{color: #16b777;} -.layui-nav-tree.layui-bg-gray .layui-nav-itemed>.layui-nav-child{padding-left: 11px; background: none!important;} -.layui-nav-tree.layui-bg-gray .layui-nav-item>a{padding-top: 0; padding-bottom: 0;} -.layui-nav-tree.layui-bg-gray .layui-nav-item>a .layui-nav-more{padding: 0;} +.layui-nav-tree.layui-bg-gray .layui-nav-child{padding-left: 11px; background: none;} .layui-nav-tree.layui-bg-gray .layui-this, .layui-nav-tree.layui-bg-gray .layui-this>a, .layui-nav-tree.layui-bg-gray .layui-nav-child dd.layui-this, @@ -1315,7 +1381,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh .layui-tab .layui-tab-title li a{display: block; padding: 0 15px; margin: 0 -15px;} .layui-tab-title .layui-this{color: #000;} -.layui-tab-title .layui-this:after{position: absolute; left:0; top: 0; content: ""; width:100%; height: 41px; border-width: 1px; border-style: solid; border-bottom-color: #fff; border-radius: 2px 2px 0 0; box-sizing: border-box; pointer-events: none;} +.layui-tab-title .layui-this:after{position: absolute; left:0; top: 0; content: ""; width:100%; height: 41px; border-width: 1px; border-bottom-width: 2px; border-style: solid; border-bottom-color: #fff; border-radius: 2px 2px 0 0; box-sizing: border-box; pointer-events: none;} .layui-tab-bar{position: absolute; right: 0; top: 0; z-index: 10; width: 30px; height: 39px; line-height: 39px; border-width: 1px; border-style: solid; border-radius: 2px; text-align: center; background-color: #fff; cursor: pointer;} .layui-tab-bar .layui-icon{position: relative; display: inline-block; top: 3px; transition: all .3s; -webkit-transition: all .3s;} .layui-tab-item{display: none;} @@ -1445,7 +1511,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-util-face ul li:hover{position: relative; z-index: 2; border: 1px solid #eb7350; background: #fff9ec;} /** 代码文本修饰 **/ -.layui-code{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border: 1px solid #eee; border-left-width: 6px; background-color: #fafafa; color: #333; font-family: Courier New,Lucida Console,Consolas; font-size: 12px;} +.layui-code{display: block; position: relative; padding: 15px; line-height: 20px; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333; font-family: "Courier New",Consolas,"Lucida Console"; font-size: 12px;} /** 穿梭框 **/ .layui-transfer-box, @@ -1474,7 +1540,8 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-rate li{margin-top: 0 !important;} .layui-rate li i.layui-icon{ font-size: 20px; color: #ffb800;} .layui-rate li i.layui-icon{margin-right: 5px; transition: all .3s; -webkit-transition: all .3s;} -.layui-rate li i:hover{cursor: pointer; transform: scale(1.12); -webkit-transform: scale(1.12);} +.layui-rate li i:hover, +.layui-rate-hover{cursor: pointer; transform: scale(1.12); -webkit-transform: scale(1.12);} .layui-rate[readonly] li i:hover{cursor: default; transform: scale(1);} /** 颜色选择器 **/ @@ -1491,10 +1558,10 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-colorpicker-main{position: absolute; left: -999999px; top: -999999px; z-index: 77777777; width: 280px; margin: 5px 0; padding: 7px; background: #FFF; border: 1px solid #d2d2d2; border-radius: 2px; box-shadow: 0 2px 4px rgba(0,0,0,.12);} .layui-colorpicker-main-wrapper{height: 180px; position: relative;} -.layui-colorpicker-basis{width: 260px; height: 100%; position: relative;} +.layui-colorpicker-basis{width: 260px; height: 100%; position: relative; overflow: hidden;} .layui-colorpicker-basis-white{width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: linear-gradient(90deg, #FFF, hsla(0,0%,100%,0));} .layui-colorpicker-basis-black{width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: linear-gradient(0deg, #000, transparent);} -.layui-colorpicker-basis-cursor{width: 10px; height: 10px; border: 1px solid #FFF; border-radius: 50%; position: absolute; top: -3px; right: -3px; cursor: pointer;} +.layui-colorpicker-basis-cursor{width: 10px; height: 10px; border: 1px solid #FFF; border-radius: 50%; position: absolute; top: 0%; right: 100%; cursor: pointer; transform: translate(-50%,-50%);} .layui-colorpicker-side{position: absolute; top: 0; right: 0; width: 12px; height: 100%; background: linear-gradient(#F00, #FF0, #0F0, #0FF, #00F, #F0F, #F00);} .layui-colorpicker-side-slider{width: 100%; height: 5px; box-shadow: 0 0 1px #888888; box-sizing: border-box; background: #FFF; border-radius: 1px; border: 1px solid #f0f0f0; cursor: pointer; position: absolute; left: 0;} .layui-colorpicker-main-alpha{display: none; height: 12px; margin-top: 7px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)} @@ -1508,8 +1575,8 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-colorpicker-pre > div{height: 100%; border-radius: 2px;} .layui-colorpicker-main-input{text-align: right; padding-top: 7px;} .layui-colorpicker-main-input .layui-btn-container .layui-btn{margin: 0 0 0 10px;} -.layui-colorpicker-main-input div.layui-inline{float: left; margin-right: 10px; font-size: 14px;} -.layui-colorpicker-main-input input.layui-input{width: 150px; height: 30px; color: #5F5F5F;} +.layui-colorpicker-main-input div.layui-inline{float: left; font-size: 14px;} +.layui-colorpicker-main-input input.layui-input{width: 168px; height: 30px; color: #5F5F5F; padding-left: 5px;} /** 滑块 **/ .layui-slider{height: 4px; background: #eee; border-radius: 3px; position: relative; cursor: pointer;} @@ -1521,7 +1588,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-slider-wrap-btn:hover, .layui-slider-wrap-btn.layui-slider-hover{transform: scale(1.2);} .layui-slider-wrap-btn.layui-disabled:hover{transform: scale(1) !important;} -.layui-slider-tips{position: absolute; top: -42px; z-index: 77777777; white-space:nowrap; display: none; -webkit-transform: translateX(-50%); transform: translateX(-50%); color: #FFF; background: #000; border-radius: 3px; height: 25px; line-height: 25px; padding: 0 10px;} +.layui-slider-tips{position: absolute; top: -42px; z-index: 77777777; white-space:nowrap; -webkit-transform: translateX(-50%); transform: translateX(-50%); color: #FFF; background: #000; border-radius: 3px; height: 25px; line-height: 25px; padding: 0 10px;} .layui-slider-tips:after{content: ""; position: absolute; bottom: -12px; left: 50%; margin-left: -6px; width: 0; height: 0; border-width: 6px; border-style: solid; border-color: #000 transparent transparent transparent;} .layui-slider-input{width: 70px; height: 32px; border: 1px solid #eee; border-radius: 3px; font-size: 16px; line-height: 32px; position: absolute; right: 0; top: -14px; box-sizing: border-box;} .layui-slider-input-btn{position: absolute; top: 0; right: 0; width: 20px; height: 100%; border-left: 1px solid #eee;} @@ -1550,7 +1617,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-tree-pack{display: none; padding-left: 20px; position: relative;} .layui-tree-line .layui-tree-pack{padding-left: 27px;} .layui-tree-line .layui-tree-set .layui-tree-set:after{content: ""; position: absolute; top: 14px; left: -9px; width: 17px; height: 0; border-top: 1px dotted #c0c4cc;} -.layui-tree-entry{position: relative; padding: 3px 0; height: 20px; white-space: nowrap;} +.layui-tree-entry{position: relative; padding: 3px 0; height: 26px; white-space: nowrap;} .layui-tree-entry:hover{background-color: #eee;} .layui-tree-line .layui-tree-entry:hover{background-color: rgba(0,0,0,0);} .layui-tree-line .layui-tree-entry:hover .layui-tree-txt{color: #999; text-decoration: underline; transition: 0.3s;} @@ -1559,7 +1626,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-tree-line .layui-tree-set.layui-tree-setLineShort:before{height: 13px;} .layui-tree-line .layui-tree-set.layui-tree-setHide:before{height: 0;} .layui-tree-iconClick{display: inline-block; vertical-align: middle; position: relative; height: 20px; line-height: 20px; margin: 0 10px; color: #c0c4cc;} -.layui-tree-icon{height: 12px; line-height: 12px; width: 12px; text-align: center; border: 1px solid #c0c4cc;} +.layui-tree-icon{height: 14px; line-height: 12px; width: 14px; text-align: center; border: 1px solid #c0c4cc;} .layui-tree-iconClick .layui-icon{font-size: 18px;} .layui-tree-icon .layui-icon{font-size: 12px; color: #5F5F5F;} .layui-tree-iconArrow{padding: 0 5px;} @@ -1571,7 +1638,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co .layui-tree-btnGroup .layui-icon{display: inline-block; vertical-align: middle; padding: 0 2px; cursor: pointer;} .layui-tree-btnGroup .layui-icon:hover{color: #999; transition: 0.3s;} .layui-tree-entry:hover .layui-tree-btnGroup{visibility: visible;} -.layui-tree-editInput{position: relative; display: inline-block; vertical-align: middle; height: 20px; line-height: 20px; padding: 0 3px; border: none; background-color: rgba(0,0,0,0.05);} +.layui-tree-editInput{position: relative; display: inline-block; vertical-align: middle; height: 20px; line-height: 20px; padding: 0; border: none; background-color: rgba(0,0,0,0.05);} .layui-tree-emptyText{text-align: center; color: #999;} diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css index 348a8e6..cbd36ce 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css +++ b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css @@ -2,59 +2,74 @@ * code */ -/* 加载就绪标志 */ -html #layuicss-skincodecss{display:none; position: absolute; width:1989px;} +html #layuicss-skincodecss{display: none; position: absolute; width: 1989px;} -/* 默认风格 */ -.layui-code-view{display: block; position: relative; margin: 11px 0; padding: 0; border: 1px solid #eee; border-left-width: 6px; background-color: #FAFAFA; color: #333; font-family: Courier New; font-size: 13px;} -.layui-code-title{position: relative; padding: 0 10px; height: 40px; line-height: 40px; border-bottom: 1px solid #eee; font-size: 12px;} -.layui-code-title > .layui-code-about{position: absolute; right: 10px; top: 0; color: #B7B7B7;} -.layui-code-about > a{padding-left: 10px;} -.layui-code-view > .layui-code-ol, -.layui-code-view > .layui-code-ul{max-height: 100%; padding: 0 !important; position: relative; overflow: auto;} -.layui-code-view > .layui-code-ol > li{position: relative; margin-top: 0 !important; margin-left: 45px !important; line-height: 20px; padding: 0 10px !important; border-left: 1px solid #e2e2e2; list-style-type: decimal-leading-zero; *list-style-type: decimal; background-color: #fff;} -.layui-code-view > .layui-code-ol > li:first-child, -.layui-code-view > .layui-code-ul > li:first-child{padding-top: 10px !important;} -.layui-code-view > .layui-code-ol > li:last-child, -.layui-code-view > .layui-code-ul > li:last-child{padding-bottom: 10px !important;} -.layui-code-view > .layui-code-ul > li{position: relative; line-height: 20px; padding: 0 10px !important; list-style-type: none; *list-style-type: none; background-color: #fff;} -.layui-code-view pre{margin: 0;} +/* 字体 */ +.layui-code-wrap{font-size: 13px; font-family: "Courier New",Consolas,"Lucida Console";} + +/* 基础结构 */ +.layui-code-view{display: block; position: relative; padding: 0 !important; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333;} +.layui-code-view pre{margin: 0 !important;} + +.layui-code-header{position: relative; z-index: 3; padding: 0 11px; height: 40px; line-height: 40px; border-bottom: 1px solid #eee; background-color: #fafafa; font-size: 12px;} +.layui-code-header > .layui-code-header-about{position: absolute; right: 11px; top: 0; color: #B7B7B7;} +.layui-code-header-about > a{padding-left: 10px;} + +.layui-code-wrap{position: relative; display: block; z-index: 1; margin: 0 !important; padding: 11px 0 !important; overflow-x: hidden; overflow-y: auto;} +.layui-code-line{position: relative; line-height: 19px; margin: 0 !important;} +.layui-code-line-number{position: absolute; left: 0; top: 0; padding: 0 8px; min-width: 45px; height: 100%; text-align: right; user-select: none; white-space: nowrap; overflow: hidden;} +.layui-code-line-content{padding: 0 11px; word-wrap: break-word; white-space: pre-wrap;} + +.layui-code-ln-mode > .layui-code-wrap > .layui-code-line{padding-left: 45px;} +.layui-code-ln-side{position: absolute; left: 0; top: 0; bottom: 0; z-index: 0; width: 45px; border-right: 1px solid #eee; border-color: rgb(126 122 122 / 15%); background-color: #fafafa; pointer-events: none;} + +/* 不自动换行 */ +.layui-code-nowrap > .layui-code-wrap{overflow: auto;} +.layui-code-nowrap > .layui-code-wrap > .layui-code-line > .layui-code-line-content{white-space: pre; word-wrap: normal;} +.layui-code-nowrap > .layui-code-ln-side{border-right-width: 0 !important; background: none !important;} + +.layui-code-fixbar{position: absolute; top: 8px; right: 11px; padding-right: 45px; z-index: 5;} +.layui-code-fixbar > span{position: absolute; right: 0; top: 0; padding: 0 8px; color: #777; transition: all .3s;} +.layui-code-fixbar > span:hover{color: #16b777;} +.layui-code-copy{display: none; cursor: pointer;} +.layui-code-preview > .layui-code-view > .layui-code-fixbar .layui-code-copy{display: none !important;} +.layui-code-view:hover > .layui-code-fixbar .layui-code-copy{display: block;} +.layui-code-view:hover > .layui-code-fixbar .layui-code-lang-marker{display: none;} + +/* 深色主题 */ +.layui-code-theme-dark, +.layui-code-theme-dark > .layui-code-header{border-color: rgb(126 122 122 / 15%); background-color: #1f1f1f;} +.layui-code-theme-dark{border-width: 1px; color: #ccc;} +.layui-code-theme-dark > .layui-code-ln-side{border-right-color: #2a2a2a; background: none; color: #6e7681;} -/* 深色风格 */ -.layui-code-dark{border: 1px solid #0C0C0C; border-left-color: #3F3F3F; background-color: #0C0C0C; color: #C2BE9E} -.layui-code-dark > .layui-code-title{border-bottom: none;} -.layui-code-dark > .layui-code-ol > li, -.layui-code-dark > .layui-code-ul > li{background-color: #3F3F3F; border-left: none;} -.layui-code-dark > .layui-code-ul > li{margin-left: 6px;} /* 代码预览 */ .layui-code textarea{display: none;} -.layui-code-preview > .layui-code{margin: 0;} +.layui-code-preview > .layui-code, +.layui-code-preview > .layui-code-view{margin: 0;} .layui-code-preview > .layui-tab{position: relative; z-index: 1; margin-bottom: 0;} -.layui-code-preview > .layui-tab > .layui-tab-title{border-bottom: none;} -.layui-code-preview > .layui-code > .layui-code-title{display: none;} +.layui-code-preview > .layui-tab > .layui-tab-title{border-width: 0;} .layui-code-preview .layui-code-item{display: none;} -.layui-code-preview .layui-code-view > .layui-code-ol > li{} +.layui-code-preview .layui-code-view > .layui-code-lines > .layui-code-line{} .layui-code-item-preview{position: relative; padding: 16px;} .layui-code-item-preview > iframe{position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;} /* 工具栏 */ -.layui-code-tools{position: absolute; right: 11px; top: 3px;} +.layui-code-tools{position: absolute; right: 11px; top: 8px; line-height: normal;} .layui-code-tools > i{display: inline-block; margin-left: 6px; padding: 3px; cursor: pointer;} .layui-code-tools > i.layui-icon-file-b{color: #999;} .layui-code-tools > i:hover{color: #16b777;} -/* 复制 */ -.layui-code-copy{position: absolute; right: 6px; top: 6px; cursor: pointer; display: none;} -.layui-code-copy .layui-icon{color: #777; transition: all .3s;} -.layui-code-copy:hover .layui-icon{color: #16b777;} -.layui-code-view:hover > .layui-code-copy{display: block;} -.layui-code-copy-offset{margin-right: 17px;} -.layui-code-preview > .layui-code-view > .layui-code-copy{display: none !important;} - /* 全屏风格 */ .layui-code-full{position: fixed; left: 0; top: 0; z-index: 1111111; width: 100%; height: 100%; background-color: #fff;} .layui-code-full .layui-code-item{width: 100% !important; border-width: 0 !important; border-top-width: 1px !important;} .layui-code-full .layui-code-item, -.layui-code-full .layui-code-ol, -.layui-code-full .layui-code-ul{height: calc(100vh - 51px) !important; box-sizing: border-box;} \ No newline at end of file +.layui-code-full .layui-code-view, +.layui-code-full .layui-code-wrap{height: calc(100vh - 51px) !important; box-sizing: border-box;} +.layui-code-full .layui-code-item-preview{overflow: auto;} + +/* 代码高亮重置 */ +.layui-code-view.layui-code-hl{line-height: 20px !important; border-left-width: 1px;} +.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;} +.layui-code-theme-dark.layui-code-hl, +.layui-code-theme-dark.layui-code-hl > .layui-code-ln-side{border-color: rgb(126 122 122 / 15%);} diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css index 18d163b..155fc5a 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css +++ b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css @@ -61,7 +61,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;} .laydate-day-mark::after{position: absolute; content:''; right: 2px; top: 2px; width: 5px; height: 5px; border-radius: 50%;} .laydate-day-holidays:before{position: absolute; left: 0; top: 0; font-size: 12px; transform: scale(.7);} .laydate-day-holidays:before{content:'\4F11'; color: #FF5722;} -.laydate-day-holidays[type="work"]:before{content:'\73ED'; color: inherit;} +.laydate-day-holidays[type="workdays"]:before{content:'\73ED'; color: inherit;} .layui-laydate .layui-this .laydate-day-holidays:before{color: #fff;} /* 底部结构 */ @@ -85,12 +85,14 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;} .layui-laydate .layui-laydate-list{position: absolute; left: 0; top: 0; width: 100%; height: 100%; padding: 10px; box-sizing: border-box; background-color: #fff;} .layui-laydate .layui-laydate-list>li{position: relative; display: inline-block; width: 33.3%; height: 36px; line-height: 36px; margin: 3px 0; vertical-align: middle; text-align: center; cursor: pointer; list-style: none;} .layui-laydate .laydate-month-list>li{width: 25%; margin: 17px 0;} -.laydate-time-list{} -.layui-laydate .laydate-time-list>li{height: 100%; margin: 0; line-height: normal; cursor: default;} +.laydate-time-list{display: table;} +.layui-laydate .laydate-time-list>li{display: table-cell; height: 100%; margin: 0; line-height: normal; cursor: default;} .layui-laydate .laydate-time-list p{position: relative; top: -4px; margin: 0; line-height: 29px;} .layui-laydate .laydate-time-list ol{height: 181px; overflow: hidden;} .layui-laydate .laydate-time-list>li:hover ol{overflow-y: auto;} .layui-laydate .laydate-time-list ol li{width: 130%; padding-left: 33px; height: 30px; line-height: 30px; text-align: left; cursor: pointer;} +.layui-laydate .laydate-time-list-hide-1 ol li{padding-left: 53px;} +.layui-laydate .laydate-time-list-hide-2 ol li{padding-left: 117px;} /* 提示 */ .layui-laydate-hint{position: absolute; top: 115px; left: 50%; width: 250px; margin-left: -125px; line-height: 20px; padding: 15px; text-align: center; font-size: 12px; color: #FF5722;} @@ -103,6 +105,8 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;} .layui-laydate-range .laydate-main-list-1 .layui-laydate-content{border-left: 1px solid #e2e2e2;} .layui-laydate-range.layui-laydate-linkage .laydate-main-list-0 .laydate-next-m, .layui-laydate-range.layui-laydate-linkage .laydate-main-list-0 .laydate-next-y, .layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .laydate-prev-m, .layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .laydate-prev-y{display: none;} +.layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .layui-laydate-header, +.layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .layui-laydate-content{border-left-style: dashed;} /* 默认简约主题 */ @@ -115,29 +119,30 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;} .layui-laydate-content td{color: #777;} .layui-laydate-content td.laydate-day-now{color: #16b777;} .layui-laydate-content td.laydate-day-now:after{content: ''; position: absolute; width: 100%; height: 30px; left: 0; top: 0; border: 1px solid #16b777; box-sizing: border-box;} -.layui-laydate-linkage .layui-laydate-content td.laydate-selected>div{background-color: #00F7DE;} -.layui-laydate-linkage .laydate-selected:hover>div{background-color: #00F7DE !important;} +.layui-laydate-linkage .layui-laydate-content td.laydate-selected>div{background-color: #cffae9; transition: all .3s;} +.layui-laydate-linkage .laydate-selected:hover>div{background-color: #cffae9 !important;} .layui-laydate-content td:hover:after, .layui-laydate-content td.laydate-selected:after{content: none;} .layui-laydate-content td>div:hover, .layui-laydate-list li:hover, -.layui-laydate-shortcut>li:hover{background-color: #eee; color: #333;} +.layui-laydate-shortcut>li:hover{background-color: #eee; color: #333; transition: all .3s;} .laydate-time-list li ol{margin: 0; padding: 0; border: 1px solid #e2e2e2; border-left-width: 0;} .laydate-time-list li:first-child ol{border-left-width: 1px;} .laydate-time-list>li:hover{background: none;} .layui-laydate-content .laydate-day-prev, .layui-laydate-content .laydate-day-next{color: #d2d2d2;} .layui-laydate-linkage .laydate-selected.laydate-day-prev>div, -.layui-laydate-linkage .laydate-selected.laydate-day-next>div{background-color: #f8f8f8 !important;} +.layui-laydate-linkage .laydate-selected.laydate-day-next>div{background: none !important;} .layui-laydate-footer{border-top: 1px solid #e2e2e2;} .layui-laydate-hint{color: #FF5722;} .laydate-day-mark::after{background-color: #16b777;} .layui-laydate-content td.layui-this .laydate-day-mark::after{display: none;} .layui-laydate-footer span[lay-type="date"]{color: #16b777;} -.layui-laydate .layui-this,.layui-laydate .layui-this>div{background-color: #16baaa !important; color: #fff !important;} +.layui-laydate .layui-this,.layui-laydate .layui-this>div{background-color: #16b777 !important; color: #fff !important;} .layui-laydate .laydate-disabled, .layui-laydate .laydate-disabled:hover{background:none !important; color: #d2d2d2 !important; cursor: not-allowed !important; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;} -.layui-laydate-content td>div{padding: 7px 0;height: 100%;} +.layui-laydate .layui-this.laydate-disabled,.layui-laydate .layui-this.laydate-disabled>div{background-color: #eee !important} +.layui-laydate-content td>div{padding: 7px 0; height: 100%;} /* 墨绿/自定义背景色主题 */ .laydate-theme-molv{border: none;} @@ -150,6 +155,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;} .laydate-theme-molv .layui-laydate-header span:hover{color: #fff;} .laydate-theme-molv .layui-laydate-content{border: 1px solid #e2e2e2; border-top: none; border-bottom: none;} .laydate-theme-molv .laydate-main-list-1 .layui-laydate-content{border-left: none;} +.laydate-theme-molv .layui-this, .laydate-theme-molv .layui-this>div{background-color: #16baaa !important;} .laydate-theme-molv .layui-laydate-footer{border: 1px solid #e2e2e2;} /* 格子主题 */ @@ -183,3 +189,5 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;} .laydate-theme-fullpanel .laydate-time-show .laydate-set-ym span[lay-type="year"], .laydate-theme-fullpanel .laydate-time-show .laydate-set-ym span[lay-type="month"] {display: inline-block !important;} .laydate-theme-fullpanel .laydate-btns-time{display: none;} +.laydate-theme-fullpanel .laydate-time-list-hide-1 ol li{padding-left: 49px;} +.laydate-theme-fullpanel .laydate-time-list-hide-2 ol li{padding-left: 107px;} diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css index 5b45dd7..4ebfdfd 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css +++ b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css @@ -6,14 +6,14 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;} /* common */ .layui-layer-shade, .layui-layer{position:fixed; _position:absolute; pointer-events: auto;} -.layui-layer-shade{top:0; left:0; width:100%; height:100%; _height:expression(document.body.offsetHeight+"px");} +.layui-layer-shade{opacity: 0; transition: opacity .35s cubic-bezier(0.34, 0.69, 0.1, 1); top:0; left:0; width:100%; height:100%; _height:expression(document.body.offsetHeight+"px");} .layui-layer{-webkit-overflow-scrolling: touch;} .layui-layer{top:150px; left: 0; margin:0; padding:0; background-color:#fff; -webkit-background-clip: content; border-radius: 2px; box-shadow: 1px 1px 50px rgba(0,0,0,.3);} .layui-layer-close{position:absolute;} .layui-layer-content{position:relative;} .layui-layer-border{border: 1px solid #B2B2B2; border: 1px solid rgba(0,0,0,.1); box-shadow: 1px 1px 5px rgba(0,0,0,.2);} .layui-layer-setwin span, -.layui-layer-btn a{display:inline-block; *display:inline; *zoom:1; vertical-align:top;} +.layui-layer-btn a{display: inline-block; vertical-align: middle; *display: inline; *zoom:1; } .layui-layer-move{display: none; position: fixed; *position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; cursor: move; opacity: 0; filter:alpha(opacity=0); background-color: #fff; z-index: 2147483647;} .layui-layer-resize{position: absolute; width: 15px; height: 15px; right: 0; bottom: 0; cursor: se-resize;} @@ -120,8 +120,8 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;} /* 标题栏 */ .layui-layer-title{padding: 0 81px 0 16px; height: 50px; line-height: 50px; border-bottom:1px solid #F0F0F0; font-size: 14px; color:#333; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-radius: 2px 2px 0 0;} .layui-layer-setwin{position:absolute; right: 15px; *right:0; top: 16px; font-size:0; line-height: initial;} -.layui-layer-setwin span{position:relative; width: 16px; height: 16px; line-height: 18px; margin-left: 10px; text-align: center; font-size: 16px; cursor: pointer; color: #000; _overflow:hidden;} -.layui-layer-setwin .layui-layer-min:before{content: ''; position: absolute; width: 12px; height: 1px; left: 50%; top: 50%; margin: -0.5px 0 0 -6px; background-color: #2E2D3C; cursor: pointer; _overflow:hidden;} +.layui-layer-setwin span{position:relative; width: 16px; height: 16px; line-height: 18px; margin-left: 10px; text-align: center; font-size: 16px; cursor: pointer; color: #000; _overflow: hidden; box-sizing: border-box;} +.layui-layer-setwin .layui-layer-min:before{content: ''; position: absolute; width: 12px; border-bottom: 1px solid #2E2D3C; left: 50%; top: 50%; margin: -0.5px 0 0 -6px; cursor: pointer; _overflow:hidden;} .layui-layer-setwin .layui-layer-min:hover:before{background-color: #2D93CA} .layui-layer-setwin .layui-layer-max:before, .layui-layer-setwin .layui-layer-max:after{content: ''; position: absolute; left: 50%; top: 50%; z-index: 1; width: 9px; height: 9px; margin: -5px 0 0 -5px; border: 1px solid #2E2D3C;} @@ -133,17 +133,19 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;} .layui-layer-setwin .layui-layer-maxmin:after{z-index: 0; margin: -5px 0 0 -1px;} .layui-layer-setwin .layui-layer-close{cursor: pointer;} .layui-layer-setwin .layui-layer-close:hover{opacity:0.7;} -.layui-layer-setwin .layui-layer-close2{position:absolute; right: -28px; top: -28px; color: #fff; background-color: #787878; padding: 3px; border: 3px solid; width: 18px; height: 18px; font-size: 18px; font-weight: bolder; border-radius: 50%; margin-left: 0; *right:-18px; _display:none;} +.layui-layer-setwin .layui-layer-close2{position:absolute; right: -28px; top: -28px; color: #fff; background-color: #787878; padding: 3px; border: 3px solid; width: 28px; height: 28px; font-size: 16px; font-weight: bolder; border-radius: 50%; margin-left: 0; *right:-18px; _display:none;} .layui-layer-setwin .layui-layer-close2:hover{opacity: unset; background-color: #3888f6;} /* 按钮栏 */ .layui-layer-btn{text-align: right; padding: 0 15px 12px; pointer-events: auto; user-select: none; -webkit-user-select: none;} -.layui-layer-btn a{height: 28px; line-height: 28px; margin: 5px 5px 0; padding: 0 15px; border: 1px solid #dedede; background-color:#fff; color: #333; border-radius: 2px; font-weight:400; cursor:pointer; text-decoration: none;} +.layui-layer-btn a{height: 30px; line-height: 30px; margin: 5px 5px 0; padding: 0 16px; border: 1px solid #dedede; background-color: #fff; color: #333; border-radius: 2px; font-weight: 400; cursor: pointer; text-decoration: none; box-sizing: border-box;} .layui-layer-btn a:hover{opacity: 0.9; text-decoration: none;} .layui-layer-btn a:active{opacity: 0.8;} -.layui-layer-btn .layui-layer-btn0{border-color: #1E9FFF; background-color: #1E9FFF; color:#fff;} +.layui-layer-btn .layui-layer-btn0{border-color: transparent; background-color: #1E9FFF; color:#fff;} .layui-layer-btn-l{text-align: left;} .layui-layer-btn-c{text-align: center;} +.layui-layer-btn-is-loading{opacity:0.5 !important; cursor:not-allowed !important; cursor:wait !important; overflow:hidden; white-space:nowrap; -webkit-user-select: none; -ms-user-select: none;user-select: none;} +.layui-layer-btn-is-loading .layui-layer-btn-loading-icon{margin-right: 8px; font-size: 14px;} /* 定制化 */ .layui-layer-dialog{min-width: 240px;} @@ -204,14 +206,14 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;} .layui-layer-win10{border: 1px solid #aaa; box-shadow: 1px 1px 6px rgba(0,0,0,.3); border-radius: none;} .layui-layer-win10 .layui-layer-title{height: 32px; line-height: 32px; padding-left: 8px; border-bottom: none; font-size: 12px;} .layui-layer-win10 .layui-layer-setwin{right: 0; top: 0;} -.layui-layer-win10 .layui-layer-setwin span{margin-left: 0; padding: 8px;} -.layui-layer-win10.layui-layer-page .layui-layer-setwin span{padding: 8px 11px;} +.layui-layer-win10 .layui-layer-setwin span{margin-left: 0; width: 32px; height: 32px; padding: 8px;} +.layui-layer-win10.layui-layer-page .layui-layer-setwin span{width: 38px;} .layui-layer-win10 .layui-layer-setwin span:hover{background-color: #E5E5E5;} .layui-layer-win10 .layui-layer-setwin span.layui-icon-close:hover{background-color: #E81123; color: #fff;} .layui-layer-win10.layui-layer-dialog .layui-layer-content{padding: 8px 16px 32px; color: #0033BC;} .layui-layer-win10.layui-layer-dialog .layui-layer-padding{padding-top: 18px; padding-left: 58px;} .layui-layer-win10 .layui-layer-btn{padding: 5px 5px 10px; border-top:1px solid #DFDFDF; background-color: #F0F0F0;} -.layui-layer-win10 .layui-layer-btn a{height: 18px; line-height: 18px; background-color: #E1E1E1; border-color: #ADADAD; color: #000; font-size: 12px; transition: all .3s;} +.layui-layer-win10 .layui-layer-btn a{height: 20px; line-height: 18px; background-color: #E1E1E1; border-color: #ADADAD; color: #000; font-size: 12px; transition: all .3s;} .layui-layer-win10 .layui-layer-btn a:hover{border-color: #2A8EDD; background-color: #E5F1FB;} .layui-layer-win10 .layui-layer-btn .layui-layer-btn0{border-color: #0078D7;} @@ -238,21 +240,27 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;} .layui-layer-tabmain .layui-layer-tabli{display:none;} .layui-layer-tabmain .layui-layer-tabli.layui-this{display: block;} -/* photo模式 */ +/* photos */ .layui-layer-photos{background: none; box-shadow: none;} -.layui-layer-photos .layui-layer-content{overflow:hidden; text-align: center;} -.layui-layer-photos .layui-layer-phimg img{position: relative; width:100%; display: inline-block; *display:inline; *zoom:1; vertical-align:top;} -.layui-layer-imgprev, .layui-layer-imgnext{position: fixed; top: 50%; width: 52px; height: 52px; line-height: 52px; margin-top: -26px; cursor: pointer; font-size: 52px; color: #717171;} -.layui-layer-imgprev{left: 32px;} -.layui-layer-imgnext{right: 32px;} -.layui-layer-imgprev:hover, -.layui-layer-imgnext:hover{color: #959595;} -.layui-layer-imgbar{position: fixed; left:0; right: 0; bottom:0; width:100%; height: 40px; line-height: 40px; background-color:#000\9; filter:Alpha(opacity=60); background-color: rgba(2,0,0,.35); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;} -.layui-layer-imgtit{/*position:absolute; left:20px;*/} -.layui-layer-imgtit *{display:inline-block; *display:inline; *zoom:1; vertical-align:top; padding: 0 5px; font-size:12px; color: #fff;} -.layui-layer-imgtit h3{max-width:65%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-weight: 300;} -.layui-layer-imgtit a:hover{color: #fff; text-decoration: underline;} -.layui-layer-imgtit em{font-style: normal;} +.layui-layer-photos .layui-layer-content{overflow: visible; text-align: center;} +.layui-layer-photos .layer-layer-photos-main img{position: relative; width:100%; display: inline-block; *display:inline; *zoom:1; vertical-align:top;} +.layui-layer-photos-prev, +.layui-layer-photos-next{position: fixed; top: 50%; width: 52px; height: 52px; line-height: 52px; margin-top: -26px; cursor: pointer; font-size: 52px; color: #717171;} +.layui-layer-photos-prev{left: 32px;} +.layui-layer-photos-next{right: 32px;} +.layui-layer-photos-prev:hover, +.layui-layer-photos-next:hover{color: #959595;} + +.layui-layer-photos-toolbar{position: fixed; left: 0; right: 0; bottom: 0; width: 100%; height: 52px; line-height: 52px; background-color: #000\9; filter: Alpha(opacity=60); background-color: rgba(0,0,0,.32); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;} +.layui-layer-photos-toolbar > *{display:inline-block; vertical-align: top; padding: 0 16px; font-size: 12px; color: #fff; *display:inline; *zoom: 1;} +.layui-layer-photos-toolbar *{font-size: 12px;} +.layui-layer-photos-header{top: 0; bottom: auto;} +.layui-layer-photos-header > span{cursor: pointer;} +.layui-layer-photos-header > span:hover{background-color: rgba(51,51,51,.32);} +.layui-layer-photos-header .layui-icon{font-size: 18px;} +.layui-layer-photos-footer > h3{max-width: 65%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;} +.layui-layer-photos-footer a:hover{text-decoration: underline;} +.layui-layer-photos-footer em{font-style: normal;} /* 关闭动画 */ @-webkit-keyframes layer-bounceOut { @@ -266,9 +274,3 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;} 0% {-webkit-transform: scale(1); -ms-transform: scale(1);transform: scale(1);} } .layer-anim-close{-webkit-animation-name: layer-bounceOut; animation-name: layer-bounceOut; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration:.2s; animation-duration:.2s;} - -@media screen and (max-width: 1100px) { - .layui-layer-iframe{overflow-y: auto; -webkit-overflow-scrolling: touch;} -} - - diff --git a/HT.Cloud.Web/wwwroot/lib/layui/layui.js b/HT.Cloud.Web/wwwroot/lib/layui/layui.js index 8b783a7..b8da36c 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/layui.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/layui.js @@ -3,7 +3,7 @@ * Classic modular front-end UI library * MIT Licensed */ - + ;!function(win){ "use strict"; @@ -16,9 +16,9 @@ }; var Layui = function(){ - this.v = '2.8.11'; // Layui 版本号 + this.v = '2.9.14'; // Layui 版本号 }; - + // 识别预先可能定义的指定全局对象 var GLOBAL = win.LAYUI_GLOBAL || {}; @@ -36,7 +36,7 @@ } return src || js[last].src; }(); - + return config.dir = GLOBAL.dir || jsPath.substring(0, jsPath.lastIndexOf('/') + 1); }(); @@ -71,7 +71,7 @@ util: 'util', // 工具块 code: 'code', // 代码修饰器 jquery: 'jquery', // DOM 库(第三方) - + all: 'all', 'layui.all': 'layui.all' // 聚合标识(功能性的,非真实模块) }; @@ -96,12 +96,12 @@ }); return this; }; - + type && ( factory = deps, deps = [] ); - + that.use(deps, callback, null, 'define'); return that; }; @@ -115,15 +115,15 @@ apps = function(){ if(typeof apps === 'string'){ return [apps]; - } + } // 当第一个参数为 function 时,则自动加载所有内置模块,且执行的回调即为该 function 参数; else if(typeof apps === 'function'){ callback = apps; return ['all']; - } + } return apps; }(); - + // 如果页面已经存在 jQuery 1.7+ 库且所定义的模块依赖 jQuery,则不加载内部 jquery 模块 if(win.jQuery && jQuery.fn.on){ that.each(apps, function(index, item){ @@ -133,7 +133,7 @@ }); layui.jquery = layui.$ = jQuery; } - + var item = apps[0]; var timeout = 0; @@ -141,7 +141,7 @@ // 静态资源host config.host = config.host || (dir.match(/\/\/([\s\S]+?)\//)||['//'+ location.host +'/'])[0]; - + // 加载完毕 function onScriptLoad(e, url){ var readyRegExp = navigator.platform === 'PLaySTATION 3' ? /^complete$/ : /^(complete|loaded)$/ @@ -156,7 +156,7 @@ }()); } } - + // 回调 function onCallback(){ exports.push(layui[item]); @@ -172,12 +172,12 @@ callback.apply(layui, exports); }() ); } - + // 如果引入了聚合板,内置的模块则不必重复加载 if( apps.length === 0 || (layui['layui.all'] && modules[item]) ){ return onCallback(), that; } - + /* * 获取加载的模块 URL * 如果是内置模块,则按照 dir 参数拼接模块路径 @@ -185,12 +185,12 @@ * 如果路径值是 {/} 开头,则模块路径即为后面紧跟的字符。 * 否则,则按照 base 参数拼接模块路径 */ - - var url = ( modules[item] ? (dir + 'modules/') + + var url = ( modules[item] ? (dir + 'modules/') : (/^\{\/\}/.test(that.modules[item]) ? '' : (config.base || '')) ) + (that.modules[item] || item) + '.js'; url = url.replace(/^\{\/\}/, ''); - + // 如果扩展模块(即:非内置模块)对象已经存在,则不必再加载 if(!config.modules[item] && layui[item]){ config.modules[item] = url; // 并记录起该扩展模块的 url @@ -199,18 +199,18 @@ // 首次加载模块 if(!config.modules[item]){ var node = doc.createElement('script'); - + node.async = true; node.charset = 'utf-8'; node.src = url + function(){ - var version = config.version === true + var version = config.version === true ? (config.v || (new Date()).getTime()) : (config.version||''); return version ? ('?v=' + version) : ''; }(); - + head.appendChild(node); - + if(node.attachEvent && !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && !isOpera){ node.attachEvent('onreadystatechange', function(e){ onScriptLoad(e, url); @@ -220,19 +220,19 @@ onScriptLoad(e, url); }, false); } - + config.modules[item] = url; } else { // 缓存 (function poll() { if(++timeout > config.timeout * 1000 / 4){ return error(item + ' is not a valid module', 'error'); } - (typeof config.modules[item] === 'string' && config.status[item]) - ? onCallback() + (typeof config.modules[item] === 'string' && config.status[item]) + ? onCallback() : setTimeout(poll, 4); }()); } - + return that; }; @@ -264,35 +264,35 @@ var that = this; var head = doc.getElementsByTagName('head')[0]; var link = doc.createElement('link'); - + if(typeof fn === 'string') cssname = fn; - + var app = (cssname || href).replace(/\.|\//g, ''); var id = 'layuicss-'+ app; var STAUTS_NAME = 'creating'; var timeout = 0; - + link.href = href + (config.debug ? '?v='+new Date().getTime() : ''); link.rel = 'stylesheet'; link.id = id; link.media = 'all'; - + if(!doc.getElementById(id)){ head.appendChild(link); } - + if(typeof fn !== 'function') return that; - + // 轮询 css 是否加载完毕 (function poll(status) { var delay = 100; var getLinkElem = doc.getElementById(id); // 获取动态插入的 link 元素 - + // 如果轮询超过指定秒数,则视为请求文件失败或 css 文件不符合规范 if(++timeout > config.timeout * 1000 / delay){ return error(href + ' timeout'); } - + // css 加载就绪 if(parseInt(that.getStyle(getLinkElem, 'width')) === 1989){ // 如果参数来自于初始轮询(即未加载就绪时的),则移除 link 标签状态 @@ -306,7 +306,7 @@ }, delay); } }()); - + // 轮询css是否加载完毕 /* (function poll() { @@ -318,31 +318,31 @@ }() : setTimeout(poll, 100); }()); */ - + return that; }; - + // css 内部加载器 Layui.prototype.addcss = function(firename, fn, cssname){ return layui.link(config.dir + 'css/' + firename, fn, cssname); }; - + // 存储模块的回调 config.callback = {}; - + // 重新执行模块的工厂函数 Layui.prototype.factory = function(modName){ if(layui[modName]){ - return typeof config.callback[modName] === 'function' + return typeof config.callback[modName] === 'function' ? config.callback[modName] : null; } }; // 图片预加载 - Layui.prototype.img = function(url, callback, error) { + Layui.prototype.img = function(url, callback, error) { var img = new Image(); - img.src = url; + img.src = url; if(img.complete){ return callback(img); } @@ -353,7 +353,7 @@ img.onerror = function(e){ img.onerror = null; typeof error === 'function' && error(e); - }; + }; }; // 全局配置 @@ -400,13 +400,13 @@ search: {}, hash: (hash.match(/[^#](#.*$)/) || [])[1] || '' }; - + if(!/^#\//.test(hash)) return data; // 禁止非路由规范 hash = hash.replace(/^#\//, ''); data.href = '/' + hash; hash = hash.replace(/([^#])(#.*$)/, '$1').split('/') || []; - + // 提取 Hash 结构 that.each(hash, function(index, item){ /^\w+=/.test(item) ? function(){ @@ -414,10 +414,10 @@ data.search[item[0]] = item[1]; }() : data.path.push(item); }); - + return data; }; - + // URL 解析 Layui.prototype.url = function(href){ var that = this; @@ -432,18 +432,18 @@ : location.pathname; return pathname.replace(/^\//, '').split('/'); }(), - + // 提取 url 参数 search: function(){ var obj = {}; - var search = (href + var search = (href ? function(){ var str = (href.match(/\?.+/) || [])[0] || ''; return str.replace(/\#.+/, ''); }() : location.search ).replace(/^\?+/, '').split('&'); // 去除 ?,按 & 分割参数 - + // 遍历分割后的参数 that.each(search, function(index, item){ var _index = item.indexOf('=') @@ -455,24 +455,24 @@ } else { return item.substr(0, _index); } - }(); + }(); // 提取 value if(key){ obj[key] = _index > 0 ? item.substr(_index + 1) : null; } }); - + return obj; }(), - + // 提取 Hash hash: that.router(function(){ - return href + return href ? ((href.match(/#.+/) || [])[0] || '/') : location.hash; }()) }; - + return data; }; @@ -480,31 +480,31 @@ Layui.prototype.data = function(table, settings, storage){ table = table || 'layui'; storage = storage || localStorage; - + if(!win.JSON || !win.JSON.parse) return; - + // 如果 settings 为 null,则删除表 if(settings === null){ return delete storage[table]; } - - settings = typeof settings === 'object' - ? settings + + settings = typeof settings === 'object' + ? settings : {key: settings}; - + try { var data = JSON.parse(storage[table]); } catch(e) { var data = {}; } - + if('value' in settings) data[settings.key] = settings.value; if(settings.remove) delete data[settings.key]; storage[table] = JSON.stringify(data); - + return settings.key ? data[settings.key] : data; }; - + // 本地临时存储 Layui.prototype.sessionData = function(table, settings){ return this.data(table, settings, sessionStorage); @@ -520,7 +520,7 @@ label = (agent.match(exp)||[])[1]; return label || false; }; - + // 返回结果集 var result = { os: function(){ // 底层操作系统 @@ -532,7 +532,7 @@ return 'ios'; } else if(/mac/.test(agent)){ return 'mac'; - } + } }(), ie: function(){ // ie 版本 return (!!win.ActiveXObject || "ActiveXObject" in win) ? ( @@ -541,17 +541,17 @@ }(), weixin: getVersion('micromessenger') // 是否微信 }; - + // 任意的 key if(key && !result[key]){ result[key] = getVersion(key); } - + // 移动设备 result.android = /android/.test(agent); result.ios = result.os === 'ios'; result.mobile = (result.android || result.ios); - + return result; }; @@ -561,33 +561,33 @@ error: error }; }; - + // typeof 类型细分 -> string/number/boolean/undefined/null、object/array/function/… Layui.prototype._typeof = Layui.prototype.type = function(operand){ if(operand === null) return String(operand); - + // 细分引用类型 return (typeof operand === 'object' || typeof operand === 'function') ? function(){ var type = Object.prototype.toString.call(operand).match(/\s(.+)\]$/) || []; // 匹配类型字符 var classType = 'Function|Array|Date|RegExp|Object|Error|Symbol'; // 常见类型字符 - + type = type[1] || 'Object'; - + // 除匹配到的类型外,其他对象均返回 object - return new RegExp('\\b('+ classType + ')\\b').test(type) - ? type.toLowerCase() + return new RegExp('\\b('+ classType + ')\\b').test(type) + ? type.toLowerCase() : 'object'; }() : typeof operand; }; - + // 对象是否具备数组结构(此处为兼容 jQuery 对象) Layui.prototype._isArray = Layui.prototype.isArray = function(obj){ var that = this; var len; var type = that.type(obj); - + if(!obj || (typeof obj !== 'object') || obj === win) return false; - + len = 'length' in obj && obj.length; // 兼容 ie return type === 'array' || len === 0 || ( typeof len === 'number' && len > 0 && (len - 1) in obj // 兼容 jQuery 对象 @@ -601,10 +601,10 @@ var callFn = function(key, obj){ // 回调 return fn.call(obj[key], key, obj[key]) }; - + if(typeof fn !== 'function') return that; obj = obj || []; - + // 优先处理数组结构 if(that.isArray(obj)){ for(key = 0; key < obj.length; key++){ @@ -615,7 +615,7 @@ if(callFn(key, obj)) break; } } - + return that; }; @@ -632,12 +632,12 @@ } else if(typeof arr !== 'object'){ // 若 arr 非对象 return [clone]; } - + // 开始排序 clone.sort(function(o1, o2){ var v1 = o1[key]; var v2 = o2[key]; - + /* * 特殊数据 * 若比较的成员均非对象 @@ -679,11 +679,11 @@ return v1 - v2; } } - + /** * 字典序排序 */ - + // 若为非数字比较 if(!isNum[0] && !isNum[1]){ // 字典序比较 @@ -695,7 +695,7 @@ return 0; } } - + // 若为混合比较 if(isNum[0] || !isNum[1]){ // 数字 vs 非数字 return -1; @@ -716,13 +716,13 @@ thisEvent.cancelBubble = true; } }; - + // 字符常理 var EV_REMOVE = 'LAYUI-EVENT-REMOVE'; // 自定义模块事件 Layui.prototype.onevent = function(modName, events, callback){ - if(typeof modName !== 'string' + if(typeof modName !== 'string' || typeof callback !== 'function') return this; return Layui.event(modName, events, null, callback); @@ -739,13 +739,13 @@ var res = item && item.call(that, params); res === false && result === null && (result = false); }; - + // 如果参数传入特定字符,则执行移除事件 if(params === EV_REMOVE){ delete (that.cache.event[eventName] || {})[filterName]; return that; } - + // 添加事件 if(fn){ config.event[eventName] = config.event[eventName] || {}; @@ -760,7 +760,7 @@ } return this; } - + // 执行事件回调 layui.each(config.event[eventName], function(key, item){ // 执行当前模块的全部事件 @@ -768,21 +768,21 @@ layui.each(item, callback); return; } - + // 执行指定事件 key === '' && layui.each(item, callback); (filterName && key === filterName) && layui.each(item, callback); }); - + return result; }; - + // 新增模块事件 Layui.prototype.on = function(events, modName, callback){ var that = this; return that.onevent.call(that, modName, events, callback); } - + // 移除模块事件 Layui.prototype.off = function(events, modName){ var that = this; diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js index bcfa718..2a27c87 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js @@ -5,7 +5,8 @@ layui.define(function(){ var mods = [] - ,builtin = layui.cache.builtin; + var builtin = layui.cache.builtin; + layui.each(builtin, function(modName){ (modName === 'all' || modName === 'layui.all') || mods.push(modName); }); @@ -15,12 +16,12 @@ layui.define(function(){ }(), function(exports){ "use strict"; - var MOD_NAME = 'all' + var MOD_NAME = 'all'; - //外部接口 - ,all = { - config: {} - ,time: function(){ + // 外部接口 + var all = { + config: {}, + time: function(){ var time = new Date().getTime() - layui.cache.startTime; delete layui.cache.startTime; return time; diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js index 765abe9..ee24b77 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js @@ -12,50 +12,61 @@ layui.define(['jquery', 'lay'], function(exports){ var hint = layui.hint(); var device = layui.device(); - //外部接口 + // 外部接口 var carousel = { - config: {} //全局配置项 + config: {}, // 全局配置项 - //设置全局项 - ,set: function(options){ + // 设置全局项 + set: function(options){ var that = this; that.config = $.extend({}, that.config, options); return that; - } + }, - //事件 - ,on: function(events, callback){ + // 事件 + on: function(events, callback){ return layui.onevent.call(this, MOD_NAME, events, callback); } - } + }; - //字符常量 - ,MOD_NAME = 'carousel', ELEM = '.layui-carousel', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled' + // 字符常量 + var MOD_NAME = 'carousel'; + var ELEM = '.layui-carousel'; + var THIS = 'layui-this'; + var SHOW = 'layui-show'; + var HIDE = 'layui-hide'; + var DISABLED = 'layui-disabled' - ,ELEM_ITEM = '>*[carousel-item]>*', ELEM_LEFT = 'layui-carousel-left', ELEM_RIGHT = 'layui-carousel-right', ELEM_PREV = 'layui-carousel-prev', ELEM_NEXT = 'layui-carousel-next', ELEM_ARROW = 'layui-carousel-arrow', ELEM_IND = 'layui-carousel-ind' + var ELEM_ITEM = '>*[carousel-item]>*'; + var ELEM_LEFT = 'layui-carousel-left'; + var ELEM_RIGHT = 'layui-carousel-right'; + var ELEM_PREV = 'layui-carousel-prev'; + var ELEM_NEXT = 'layui-carousel-next'; + var ELEM_ARROW = 'layui-carousel-arrow'; + var ELEM_IND = 'layui-carousel-ind'; - //构造器 - ,Class = function(options){ + // 构造器 + var Class = function(options){ var that = this; that.config = $.extend({}, that.config, carousel.config, options); that.render(); }; - //默认配置 + // 默认配置 Class.prototype.config = { - width: '600px' - ,height: '280px' - ,full: false //是否全屏 - ,arrow: 'hover' //切换箭头默认显示状态:hover/always/none - ,indicator: 'inside' //指示器位置:inside/outside/none - ,autoplay: true //是否自动切换 - ,interval: 3000 //自动切换的时间间隔,不能低于800ms - ,anim: '' //动画类型:default/updown/fade - ,trigger: 'click' //指示器的触发方式:click/hover - ,index: 0 //初始开始的索引 + width: '600px', + height: '280px', + full: false, // 是否全屏 + arrow: 'hover', // 切换箭头默认显示状态:hover/always/none + indicator: 'inside', // 指示器位置:inside/outside/none + autoplay: true, // 是否自动切换 + interval: 3000, // 自动切换的时间间隔,不能低于800ms + anim: '', // 动画类型:default/updown/fade + trigger: 'click', // 指示器的触发方式:click/hover + index: 0 // 初始开始的索引 }; - //轮播渲染 + // 轮播渲染 Class.prototype.render = function(){ var that = this; var options = that.config; @@ -82,35 +93,37 @@ layui.define(['jquery', 'lay'], function(exports){ if(options.index >= that.elemItem.length) options.index = that.elemItem.length - 1; if(options.interval < 800) options.interval = 800; - //是否全屏模式 + // 是否全屏模式 if(options.full){ options.elem.css({ - position: 'fixed' - ,width: '100%' - ,height: '100%' - ,zIndex: 9999 + position: 'fixed', + width: '100%', + height: '100%', + zIndex: 9999 }); } else { options.elem.css({ - width: options.width - ,height: options.height + width: options.width, + height: options.height }); } options.elem.attr('lay-anim', options.anim); - //初始焦点状态 + // 初始焦点状态 that.elemItem.eq(options.index).addClass(THIS); - //指示器等动作 - if(that.elemItem.length <= 1) return; + // 指示器、箭头等动作 that.indicator(); that.arrow(); that.autoplay(); - that.events(); + + if (that.elemItem.length > 1) { + that.events(); + } }; - //重置轮播 + // 重置轮播 Class.prototype.reload = function(options){ var that = this; clearInterval(that.timer); @@ -118,95 +131,101 @@ layui.define(['jquery', 'lay'], function(exports){ that.render(); }; - //获取上一个等待条目的索引 + // 获取上一个等待条目的索引 Class.prototype.prevIndex = function(){ - var that = this - ,options = that.config; - + var that = this; + var options = that.config; var prevIndex = options.index - 1; + if(prevIndex < 0){ prevIndex = that.elemItem.length - 1; } + return prevIndex; }; - //获取下一个等待条目的索引 + // 获取下一个等待条目的索引 Class.prototype.nextIndex = function(){ - var that = this - ,options = that.config; - + var that = this; + var options = that.config; var nextIndex = options.index + 1; + if(nextIndex >= that.elemItem.length){ nextIndex = 0; } + return nextIndex; }; - //索引递增 + // 索引递增 Class.prototype.addIndex = function(num){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; num = num || 1; options.index = options.index + num; - //index不能超过轮播总数量 + // index 不能超过轮播总数量 if(options.index >= that.elemItem.length){ options.index = 0; } }; - //索引递减 + // 索引递减 Class.prototype.subIndex = function(num){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; num = num || 1; options.index = options.index - num; - //index不能超过轮播总数量 + // index 不能超过轮播总数量 if(options.index < 0){ options.index = that.elemItem.length - 1; } }; - //自动轮播 + // 自动轮播 Class.prototype.autoplay = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; + var itemsCount = that.elemItem.length; if(!options.autoplay) return; clearInterval(that.timer); - that.timer = setInterval(function(){ - that.slide(); - }, options.interval); + if (itemsCount > 1) { + that.timer = setInterval(function(){ + that.slide(); + }, options.interval); + } }; - //箭头 + // 箭头 Class.prototype.arrow = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; + var itemsCount = that.elemItem.length; - //模板 + // 模板 var tplArrow = $([ - '' - ,'' + '', + '' ].join('')); - //预设基础属性 + // 预设基础属性 options.elem.attr('lay-arrow', options.arrow); - //避免重复插入 + // 避免重复插入 if(options.elem.find('.'+ELEM_ARROW)[0]){ options.elem.find('.'+ELEM_ARROW).remove(); } - options.elem.append(tplArrow); + itemsCount > 1 ? options.elem.append(tplArrow) : tplArrow.remove(); - //事件 + // 事件 tplArrow.on('click', function(){ - var othis = $(this) - ,type = othis.attr('lay-type') + var othis = $(this); + var type = othis.attr('lay-type') that.slide(type); }); }; @@ -223,30 +242,32 @@ layui.define(['jquery', 'lay'], function(exports){ } } - //指示器 + // 指示器 Class.prototype.indicator = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; + var itemsCount = that.elemItem.length; - //模板 - var tplInd = that.elemInd = $(['
      ' - ,function(){ + // 模板 + var tplInd = that.elemInd = $(['
        ', + function(){ var li = []; layui.each(that.elemItem, function(index){ li.push(''); }); return li.join(''); - }() - ,'
      '].join('')); + }(), + '
    '].join('')); - //预设基础属性 + // 预设基础属性 options.elem.attr('lay-indicator', options.indicator); - //避免重复插入 + // 避免重复插入 if(options.elem.find('.'+ELEM_IND)[0]){ options.elem.find('.'+ELEM_IND).remove(); } - options.elem.append(tplInd); + + itemsCount > 1 ? options.elem.append(tplInd) : tplInd.remove(); if(options.anim === 'updown'){ tplInd.css('margin-top', -(tplInd.height()/2)); @@ -258,17 +279,18 @@ layui.define(['jquery', 'lay'], function(exports){ }); }; - //滑动切换 + // 滑动切换 Class.prototype.slide = function(type, num){ - var that = this - ,elemItem = that.elemItem - ,options = that.config - ,thisIndex = options.index - ,filter = options.elem.attr('lay-filter'); + var that = this; + var elemItem = that.elemItem; + var itemsCount = elemItem.length; + var options = that.config; + var thisIndex = options.index; + var filter = options.elem.attr('lay-filter'); - if(that.haveSlide) return; + if (that.haveSlide || itemsCount <= 1) return; - //滑动方向 + // 滑动方向 if(type === 'sub'){ that.subIndex(num); elemItem.eq(options.index).addClass(ELEM_PREV); @@ -276,7 +298,7 @@ layui.define(['jquery', 'lay'], function(exports){ elemItem.eq(thisIndex).addClass(ELEM_RIGHT); elemItem.eq(options.index).addClass(ELEM_RIGHT); }, 50); - } else { //默认递增滑 + } else { // 默认递增滑 that.addIndex(num); elemItem.eq(options.index).addClass(ELEM_NEXT); setTimeout(function(){ @@ -285,14 +307,14 @@ layui.define(['jquery', 'lay'], function(exports){ }, 50); } - //移除过度类 + // 移除过渡类 setTimeout(function(){ elemItem.removeClass(THIS + ' ' + ELEM_PREV + ' ' + ELEM_NEXT + ' ' + ELEM_LEFT + ' ' + ELEM_RIGHT); elemItem.eq(options.index).addClass(THIS); - that.haveSlide = false; //解锁 - }, 300); + that.haveSlide = false; // 解锁 + }, 350); - //指示器焦点 + // 指示器焦点 that.elemInd.find('li').eq(options.index).addClass(THIS) .siblings().removeClass(THIS); @@ -300,35 +322,50 @@ layui.define(['jquery', 'lay'], function(exports){ // 回调返回的参数 var params = { - index: options.index - ,prevIndex: thisIndex - ,item: elemItem.eq(options.index) + index: options.index, + prevIndex: thisIndex, + item: elemItem.eq(options.index) }; typeof options.change === 'function' && options.change(params); layui.event.call(this, MOD_NAME, 'change('+ filter +')', params); }; - //事件处理 + // 事件处理 Class.prototype.events = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; if(options.elem.data('haveEvents')) return; + - //移入移出容器 - options.elem.on('mouseenter', function(){ + // 移入移出容器 + options.elem.on('mouseenter touchstart', function(){ if (that.config.autoplay === 'always') return; clearInterval(that.timer); - }).on('mouseleave', function(){ + }).on('mouseleave touchend', function(){ if (that.config.autoplay === 'always') return; that.autoplay(); }); + + var touchEl = options.elem; + var isVertical = options.anim === 'updown'; + lay.touchSwipe(touchEl, { + onTouchEnd: function(e, state){ + var duration = Date.now() - state.timeStart; + var distance = isVertical ? state.distanceY : state.distanceX; + var speed = distance / duration; + var shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(distance) > touchEl[isVertical ? 'height' : 'width']() / 3; + if(shouldSwipe){ + that.slide(distance > 0 ? '' : 'sub'); + } + } + }) options.elem.data('haveEvents', true); }; - //核心入口 + // 核心入口 carousel.render = function(options){ return new Class(options); }; diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js index 5efd496..9c8ecd9 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js @@ -1,32 +1,37 @@ /** - * code + * code * Code 预览组件 */ - + layui.define(['lay', 'util', 'element', 'form'], function(exports){ "use strict"; - + var $ = layui.$; var util = layui.util; var element = layui.element; var form = layui.form; var layer = layui.layer; + var hint = layui.hint(); // 常量 var CONST = { ELEM_VIEW: 'layui-code-view', - ELEM_COPY: 'layui-code-copy', ELEM_TAB: 'layui-tab', - ELEM_TITLE: 'layui-code-title', + ELEM_HEADER: 'layui-code-header', ELEM_FULL: 'layui-code-full', ELEM_PREVIEW: 'layui-code-preview', ELEM_ITEM: 'layui-code-item', - ELEM_SHOW: 'layui-show' + ELEM_SHOW: 'layui-show', + ELEM_LINE: 'layui-code-line', + ELEM_LINE_NUM: 'layui-code-line-number', + ELEM_LN_MODE: 'layui-code-ln-mode', + CDDE_DATA_CLASS: 'LayuiCodeDataClass', + LINE_RAW_WIDTH: 45, // 行号初始宽度,需与 css 保持一致 }; // 默认参数项 var config = { - elem: '.layui-code', // 元素选择器 + elem: '', // 元素选择器 about: '', // 代码栏右上角信息 ln: true, // 代码区域是否显示行号 header: false, // 是否显示代码栏头部区域 @@ -35,338 +40,557 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ // 默认文本 text: { code: util.escape(''), - preview: 'Preview' - } + preview: 'Preview', + }, + wordWrap: true, // 是否自动换行 + lang: 'text', // 指定语言类型 + highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki' + langMarker: false, // 代码区域是否显示语言类型标记 }; + // 初始索引 + var codeIndex = layui.code ? (layui.code.index + 10000) : 0; + + // 去除尾部空格 + var trimEnd = function(str){ + return String(str).replace(/\s+$/, ''); + } + // 保留首行缩进 var trim = function(str){ - return $.trim(str).replace(/^\n|\n$/, ''); + return trimEnd(str).replace(/^\n|\n$/, ''); }; - + // export api - exports('code', function(options){ - var opts = options = $.extend(true, {}, config, options); + exports('code', function(options, mode){ + options = $.extend(true, {}, config, options); + + // 返回对象 + var ret = { + config: options, + reload: function(opts) { // 重载 + layui.code(this.updateOptions(opts)); + }, + updateOptions: function(opts) { // 更新属性(选项) + opts = opts || {}; + delete opts.elem; + return $.extend(true, options, opts); + }, + reloadCode: function(opts) { // 仅重载 code + layui.code(this.updateOptions(opts), 'reloadCode'); + } + }; + + // 若 elem 非唯一 + var elem = $(options.elem); + if(elem.length > 1){ + // 是否正向渲染 + layui.each(options.obverse ? elem : elem.get().reverse(), function(){ + layui.code($.extend({}, options, { + elem: this + }), mode); + }); + return ret; + } // 目标元素是否存在 - options.elem = $(options.elem); - if(!options.elem[0]) return; + var othis = options.elem = $(options.elem); + if(!othis[0]) return ret; - // 从内至外渲染 - layui.each(options.elem.get().reverse(), function(index, item){ - var othis = $(item); - - // 合并属性上的参数,并兼容旧版本属性写法 lay-* - var options = $.extend(true, {}, opts, lay.options(item), function(obj){ - var attrs = ['title', 'height', 'encode', 'skin', 'about']; - layui.each(attrs, function(i, attr){ - var value = othis.attr('lay-'+ attr); - if(typeof value === 'string'){ - obj[attr] = value; - } - }) - return obj; - }({})); - - // 最终显示的代码 - var finalCode; - - // 获得初始代码 - var codes = othis.data('code') || function(){ - var arr = []; - var textarea = othis.children('textarea'); - - // 若内容放置在 textarea 中 - textarea.each(function(){ - arr.push(trim(this.value)); - }); - - // 内容直接放置在元素外层 - if(arr.length === 0){ - arr.push(trim(othis.html())); + // 合并属性上的参数,并兼容旧版本属性写法 lay-* + $.extend(true, options, lay.options(othis[0]), function(obj){ + var attrs = ['title', 'height', 'encode', 'skin', 'about']; + layui.each(attrs, function(i, attr){ + var value = othis.attr('lay-'+ attr); + if(typeof value === 'string'){ + obj[attr] = value; } - - return arr; - }(); + }) + return obj; + }({})); - othis.data('code', codes); + // codeRender 需要关闭编码 + // 未使用 codeRender 时若开启了预览,则强制开启编码 + options.encode = (options.encode || options.preview) && !options.codeRender; - // code - var html = finalCode = codes.join(''); + // 获得初始 code + options.code = options.code || function(){ + var arr = []; + var textarea = othis.children('textarea'); - // 外部重新解析 code - if(typeof options.codeParse === 'function'){ - html = finalCode = options.codeParse(html); + // 若内容放置在 textarea 中 + textarea.each(function(){ + arr.push(trim(this.value)); + }); + + // 内容直接放置在元素外层 + if(arr.length === 0){ + arr.push(trim(othis.html())); } - // 工具栏 - var tools = { - copy: { - className: 'file-b', - title: ['复制代码'], - event: function(el, type){ - typeof options.onCopy === 'function' ? options.onCopy(finalCode) : function(){ - try { - navigator.clipboard.writeText(util.unescape(finalCode)).then(function(){ - layer.msg('已复制', { - icon: 1 - }); - }); - } catch(e) { - layer.msg('复制失败', { - icon: 2 - }); - } - }(); - } - } + return arr.join(''); + }(); + + // 创建 code 行结构 + var createCode = function(html) { + // codeRender + if(typeof options.codeRender === 'function') { + html = options.codeRender(String(html), options); + } + + // code 行 + var lines = String(html).split(/\r?\n/g); + + // 包裹 code 行结构 + html = $.map(lines, function(line, num) { + return [ + '
    ', + ( + options.ln ? [ + '
    ', + (util.digit(num + 1) + '.'), + '
    ', + ].join('') : '' + ), + '
    ', + (line || ' '), + '
    ', + '
    ' + ].join(''); + }); + + return { + lines: lines, + html: html }; + }; - // 是否开启预览 - if(options.preview){ - var FILTER_VALUE = 'LAY-CODE-DF-'+ index; - var layout = options.layout || ['code', 'preview']; - var isIframePreview = options.preview === 'iframe'; - - // 追加 Tab 组件 - var elemView = $('
    '); - var elemTabView = $('
    '); - var elemHeaderView = $('
    '); - var elemPreviewView = $('
    '); - var elemToolbar = $('
    '); - var elemViewHas = othis.parent('.' + CONST.ELEM_PREVIEW); - var elemTabHas = othis.prev('.'+ CONST.ELEM_TAB); - var elemPreviewViewHas = othis.next('.' + CONST.ELEM_ITEM +'-preview'); + // 原始 code + var rawCode = options.code; - if(options.id) elemView.attr('id', options.id); - elemView.addClass(options.className); - elemTabView.attr('lay-filter', FILTER_VALUE); + // 最终 code + var finalCode = function(code) { + return typeof options.codeParse === 'function' ? + options.codeParse(code, options) : + code; + }; - // 若开启预览,则强制对 code 进行编码 - options.encode = true; + // 仅重载 code + if (mode === 'reloadCode') { + return othis.children('.layui-code-wrap').html( + createCode(finalCode(rawCode)).html + ), ret; + } - // 标签头 - layui.each(layout, function(i, v){ - var li = $('
  • '); - if(i === 0) li.addClass('layui-this'); - li.html(options.text[v]); - elemHeaderView.append(li); - }); + // 自增索引 + var index = layui.code.index = ++codeIndex; + othis.attr('lay-code-index', index); - // 工具栏 - $.extend(tools, { - 'full': { - className: 'screen-full', - title: ['最大化显示', '还原显示'], - event: function(el, type){ - var elemView = el.closest('.'+ CONST.ELEM_PREVIEW); - var classNameFull = 'layui-icon-'+ this.className; - var classNameRestore = 'layui-icon-screen-restore'; - var title = this.title; - var html = $('html,body'); - var ELEM_SCOLLBAR_HIDE = 'layui-scollbar-hide'; + // 初始化 className + var hasDataClass = CONST.CDDE_DATA_CLASS in othis.data(); + if (hasDataClass) { + othis.attr('class', othis.data(CONST.CDDE_DATA_CLASS) || ''); + } - if(el.hasClass(classNameFull)){ - elemView.addClass(CONST.ELEM_FULL); - el.removeClass(classNameFull).addClass(classNameRestore); - el.attr('title', title[1]); - html.addClass(ELEM_SCOLLBAR_HIDE); - } else { - elemView.removeClass(CONST.ELEM_FULL); - el.removeClass(classNameRestore).addClass(classNameFull); - el.attr('title', title[0]); - html.removeClass(ELEM_SCOLLBAR_HIDE); - } + // 记录初始 className + if (!hasDataClass) { + othis.data(CONST.CDDE_DATA_CLASS, othis.attr('class')); + } + + // 工具栏 + var tools = { + copy: { + className: 'file-b', + title: ['复制代码'], + event: function(obj){ + var code = util.unescape(finalCode(options.code)); + + // 写入剪切板 + lay.clipboard.writeText({ + text: code, + done: function() { + layer.msg('已复制', {icon: 1}); + }, + error: function() { + layer.msg('复制失败', {icon: 2}); } - }, - 'window': { - className: 'release', - title: ['在新窗口预览'], - event: function(el, type){ - util.openWin({ - content: finalCode - }); + }); + + typeof options.onCopy === 'function' && options.onCopy(code); + } + } + }; + + // 移除包裹结构 + var unwrap = (function fn() { + var elemViewHas = othis.parent('.' + CONST.ELEM_PREVIEW); + var elemTabHas = elemViewHas.children('.'+ CONST.ELEM_TAB); + var elemPreviewViewHas = elemViewHas.children('.' + CONST.ELEM_ITEM +'-preview'); + + // 移除旧结构 + elemTabHas.remove(); // 移除 tab + elemPreviewViewHas.remove(); // 移除预览区域 + if (elemViewHas[0]) othis.unwrap(); // 移除外层容器 + + return fn; + })(); + + // 是否开启预览 + if(options.preview){ + var FILTER_VALUE = 'LAY-CODE-DF-'+ index; + var layout = options.layout || ['code', 'preview']; + var isIframePreview = options.preview === 'iframe'; + + // 追加 Tab 组件 + var elemView = $('
    '); + var elemTabView = $('
    '); + var elemHeaderView = $('
    '); + var elemPreviewView = $('
    '); + var elemToolbar = $('
    '); + + + if(options.id) elemView.attr('id', options.id); + elemView.addClass(options.className); + elemTabView.attr('lay-filter', FILTER_VALUE); + + // 标签头 + layui.each(layout, function(i, v){ + var li = $('
  • '); + if(i === 0) li.addClass('layui-this'); + li.html(options.text[v]); + elemHeaderView.append(li); + }); + + // 工具栏 + $.extend(tools, { + 'full': { + className: 'screen-full', + title: ['最大化显示', '还原显示'], + event: function(obj){ + var el = obj.elem; + var elemView = el.closest('.'+ CONST.ELEM_PREVIEW); + var classNameFull = 'layui-icon-'+ this.className; + var classNameRestore = 'layui-icon-screen-restore'; + var title = this.title; + var htmlElem = $('html,body'); + var ELEM_SCROLLBAR_HIDE = 'layui-scrollbar-hide'; + + if(el.hasClass(classNameFull)){ + elemView.addClass(CONST.ELEM_FULL); + el.removeClass(classNameFull).addClass(classNameRestore); + el.attr('title', title[1]); + htmlElem.addClass(ELEM_SCROLLBAR_HIDE); + } else { + elemView.removeClass(CONST.ELEM_FULL); + el.removeClass(classNameRestore).addClass(classNameFull); + el.attr('title', title[0]); + htmlElem.removeClass(ELEM_SCROLLBAR_HIDE); } } - }); - - // copy - if(options.copy){ - if(layui.type(options.tools) === 'array'){ - // 若 copy 未存在于 tools 中,则追加到最前 - if(options.tools.indexOf('copy') === -1){ - options.tools.unshift('copy'); - } - } else { - options.tools = ['copy']; + }, + 'window': { + className: 'release', + title: ['在新窗口预览'], + event: function(obj){ + util.openWin({ + content: finalCode(options.code) + }); } } + }); - // 工具栏事件 - elemToolbar.on('click', '>i', function(){ - var oi = $(this); - var type = oi.data('type'); - typeof tools[type].event === 'function' && tools[type].event(oi, type); - typeof options.toolsEvent === 'function' && options.toolsEvent(oi, type); - }); - layui.each(options.tools, function(i, v){ - var className = (tools[v] && tools[v].className) || v; - var title = tools[v].title || ['']; - elemToolbar.append( - '' - ); - }); + // copy + if(options.copy){ + if(layui.type(options.tools) === 'array'){ + // 若 copy 未存在于 tools 中,则追加到最前 + if(options.tools.indexOf('copy') === -1){ + options.tools.unshift('copy'); + } + } else { + options.tools = ['copy']; + } + } - // 移除旧结构 - if(elemTabHas[0]) elemTabHas.remove(); // 移除 tab - if(elemPreviewViewHas[0]) elemPreviewViewHas.remove(); // 移除预览区域 - if(elemViewHas[0]) othis.unwrap(); // 移除外层容器 + // 工具栏事件 + elemToolbar.on('click', '>i', function(){ + var oi = $(this); + var type = oi.data('type'); + var parameters = { + elem: oi, + type: type, + options: options, // 当前属性选项 + rawCode: options.code, // 原始 code + finalCode: util.unescape(finalCode(options.code)) // 最终 code + }; - elemTabView.append(elemHeaderView); // 追加标签头 - options.tools && elemTabView.append(elemToolbar); // 追加工具栏 - othis.wrap(elemView).addClass(CONST.ELEM_ITEM).before(elemTabView); // 追加标签结构 + // 内部 tools event + tools[type] && typeof tools[type].event === 'function' && tools[type].event(parameters); - - // 追加预览 - if(isIframePreview){ - elemPreviewView.html(''); + // 外部 tools event + typeof options.toolsEvent === 'function' && options.toolsEvent(parameters); + }); + + // 增加工具栏 + if (options.addTools && options.tools) { + options.tools = [].concat(options.tools, options.addTools); + } + + // 渲染工具栏 + layui.each(options.tools, function(i, v){ + var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性 + var tool = viso ? v : ( + tools[v] || { + className: v, + title: [v] + } + ); + + var className = tool.className || tool.type; + var title = tool.title || ['']; + var type = viso ? ( tool.type || className ) : v; + + if (!type) return; + + // 若非内置 tool,则合并到 tools 中 + if (!tools[type]) { + var obj = {}; + obj[type] = tool; + $.extend(tools, obj); } - // 执行预览 - var run = function(thisItemBody){ - var iframe = thisItemBody.children('iframe')[0]; - if(isIframePreview && iframe){ - iframe.srcdoc = finalCode; - } else { - thisItemBody.html(codes.join('')); - } - // 回调的返回参数 - var params = { + elemToolbar.append( + '' + ); + }); + + othis.addClass(CONST.ELEM_ITEM).wrap(elemView); // 包裹外层容器 + elemTabView.append(elemHeaderView); // 追加标签头 + options.tools && elemTabView.append(elemToolbar); // 追加工具栏 + othis.before(elemTabView); // 追加标签结构 + + // 追加预览 + if(isIframePreview){ + elemPreviewView.html(''); + } + + // 执行预览 + var runPreview = function(thisItemBody){ + var iframe = thisItemBody.children('iframe')[0]; + + // 是否 iframe 方式预览 + if(isIframePreview && iframe){ + iframe.srcdoc = finalCode(options.code); + } else { + thisItemBody.html(options.code); + } + + // 当前实例预览完毕后的回调 + setTimeout(function(){ + typeof options.done === 'function' && options.done({ container: thisItemBody, + options: options, render: function(){ form.render(thisItemBody.find('.layui-form')); element.render(); } - }; - // 当前实例预览完毕后的回调 - setTimeout(function(){ - typeof options.done === 'function' && options.done(params); - },3); - }; + }); + },3); + }; - if(layout[0] === 'preview'){ - elemPreviewView.addClass(CONST.ELEM_SHOW); - othis.before(elemPreviewView); - run(elemPreviewView); - } else { - othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView); + if(layout[0] === 'preview'){ + elemPreviewView.addClass(CONST.ELEM_SHOW); + othis.before(elemPreviewView); + runPreview(elemPreviewView); + } else { + othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView); + } + + // 内容项初始化样式 + options.previewStyle = [options.style, options.previewStyle].join(''); + elemPreviewView.attr('style', options.previewStyle); + + // tab change + element.on('tab('+ FILTER_VALUE +')', function(data){ + var $this = $(this); + var thisElem = $(data.elem).closest('.'+ CONST.ELEM_PREVIEW); + var elemItemBody = thisElem.find('.'+ CONST.ELEM_ITEM); + var thisItemBody = elemItemBody.eq(data.index); + + elemItemBody.removeClass(CONST.ELEM_SHOW); + thisItemBody.addClass(CONST.ELEM_SHOW); + + if($this.attr('lay-id') === 'preview'){ + runPreview(thisItemBody); } - // 内容项初始化样式 - options.codeStyle = [options.style, options.codeStyle].join(''); - options.previewStyle = [options.style, options.previewStyle].join(''); - // othis.attr('style', options.codeStyle); - elemPreviewView.attr('style', options.previewStyle); + setCodeLayout(); + }); + } - // tab change - element.on('tab('+ FILTER_VALUE +')', function(data){ - var $this = $(this); - var thisElem = $(data.elem).closest('.'+ CONST.ELEM_PREVIEW); - var elemItemBody = thisElem.find('.'+ CONST.ELEM_ITEM); - var thisItemBody = elemItemBody.eq(data.index); - - elemItemBody.removeClass(CONST.ELEM_SHOW); - thisItemBody.addClass(CONST.ELEM_SHOW); + // 创建 code 容器 + var codeElem = $(''); // 此处的闭合标签是为了兼容 IE8 - if($this.attr('lay-id') === 'preview'){ - run(thisItemBody); - } - }); - } + // 添加主容器 className + othis.addClass(function(arr) { + if (!options.wordWrap) arr.push('layui-code-nowrap'); + return arr.join(' ') + }(['layui-code-view layui-border-box'])); - // 有序或无序列表 - var listTag = options.ln ? 'ol' : 'ul'; - var listElem = $('<'+ listTag +' class="layui-code-'+ listTag +'">'); + // code 主题风格 + var theme = options.theme || options.skin; + if (theme) { + othis.removeClass('layui-code-theme-dark layui-code-theme-light'); + othis.addClass('layui-code-theme-'+ theme); + } - // header - var headerElem = $('
    '); + // 添加高亮必要的 className + if (options.highlighter) { + othis.addClass([ + options.highlighter, + 'language-' + options.lang, + 'layui-code-hl' + ].join(' ')); + } - // 添加组件 clasName - othis.addClass('layui-code-view layui-box'); + // 获取 code 行结构 + var createCodeRst = createCode( + options.encode ? util.escape(finalCode(rawCode)) : rawCode // 是否编码 + ); + var lines = createCodeRst.lines; - // 自定义风格 - if(options.skin){ - if(options.skin === 'notepad') options.skin = 'dark'; - othis.removeClass('layui-code-dark layui-code-light'); - othis.addClass('layui-code-'+ options.skin); - } + // 插入 code + othis.html(codeElem.html(createCodeRst.html)); - - + // 插入行号边栏 + if (options.ln) { + othis.append('
    '); + } - // 转义 HTML 标签 - if(options.encode) html = util.escape(html); // 编码 - html = html.replace(/[\r\t\n]+/g, '
  • '); // 转义换行符 - - // 生成列表 - othis.html(listElem.html('
  • ' + html + '
  • ')); - - // 创建 header - if(options.header && !othis.children('.'+ CONST.ELEM_TITLE)[0]){ - headerElem.html((options.title || options.text.code) + ( - options.about - ? '
    ' + options.about + '
    ' - : '' - )); - othis.prepend(headerElem); - } + // 兼容旧版本 height 属性 + if (options.height) { + codeElem.css('max-height', options.height); + } - // 所有实例渲染完毕后的回调 - if(options.elem.length === index + 1){ - typeof options.allDone === 'function' && options.allDone(); - } + // code 区域样式 + options.codeStyle = [options.style, options.codeStyle].join(''); + if (options.codeStyle) { + codeElem.attr('style', function(i, val) { + return (val || '') + options.codeStyle; + }); + } - // 按行数适配左边距 - (function(autoIncNums){ - if(autoIncNums > 0){ - listElem.css('margin-left', autoIncNums + 'px'); + // 动态设置样式 + var cssRules = [ + { + selector: '>.layui-code-wrap>.layui-code-line{}', + setValue: function(item, value) { + item.style['padding-left'] = value + 'px'; + } + }, + { + selector: '>.layui-code-wrap>.layui-code-line>.layui-code-line-number{}', + setValue: function(item, value) { + item.style.width = value + 'px'; + } + }, + { + selector: '>.layui-code-ln-side{}', + setValue: function(item, value) { + item.style.width = value + 'px'; } - })(Math.floor(listElem.find('li').length/100)); - - // 限制 Code 最大高度 - if(options.height){ // 兼容旧版本 - listElem.css('max-height', options.height); } - // Code 内容区域样式 - listElem.attr('style', options.codeStyle); + ]; - // 是否开启代码复制 - if(options.copy && !options.preview){ - var elemCopy = $(['', - '', - ''].join('')); - var elemCopyHas = othis.children('.'+ CONST.ELEM_COPY); - var isHeight = listElem[0].style.height || listElem[0].style.maxHeight; + // 生成初始 style 元素 + var styleElem = lay.style({ + target: othis[0], + id: 'DF-code-'+ index, + text: $.map($.map(cssRules, function(val){ + return val.selector; + }), function(val, i) { + return ['.layui-code-view[lay-code-index="'+ index + '"]', val].join(' '); + }).join('') + }) - if(isHeight) elemCopy.addClass(CONST.ELEM_COPY + '-offset'); // 偏移 - if(elemCopyHas[0]) elemCopyHas.remove(); // 移除旧的复制元素 - othis.append(elemCopy); + // 动态设置 code 布局 + var setCodeLayout = (function fn() { + if (options.ln) { + var multiLine = Math.floor(lines.length / 100); + var lineElem = codeElem.children('.'+ CONST.ELEM_LINE); + var width = lineElem.last().children('.'+ CONST.ELEM_LINE_NUM).outerWidth(); - // 点击复制 - elemCopy.on('click', function(){ - tools.copy.event(); - }); + othis.addClass(CONST.ELEM_LN_MODE); + + // 若超出 100 行 + if (multiLine && width > CONST.LINE_RAW_WIDTH) { + lay.getStyleRules(styleElem, function(item, i) { + try { + cssRules[i].setValue(item, width); + } catch(e) { } + }); + } } - }); - + return fn; + })(); + + // 创建 code header + if (options.header) { + var headerElem = $('
    '); + headerElem.html(options.title || options.text.code); + othis.prepend(headerElem); + } + + // 创建 code 区域固定条 + var elemFixbar = $('
    '); + + // 若开启复制,且未开启预览,则单独生成复制图标 + if(options.copy && !options.preview){ + var copyElem = $(['', + '', + ''].join('')); + + // 点击复制 + copyElem.on('click', function(){ + tools.copy.event(); + }); + + elemFixbar.append(copyElem); + } + + // 创建 language marker + if (options.langMarker) { + elemFixbar.append('' + options.lang + ''); + } + + // 创建 about 自定义内容 + if (options.about) { + elemFixbar.append(options.about); + } + + // 生成 code fixbar + othis.append(elemFixbar); + + // code 渲染完毕后的回调 + if (!options.preview) { + setTimeout(function(){ + typeof options.done === 'function' && options.done({}); + },3); + } + + // 所有实例渲染完毕后的回调 + if(options.elem.length === index + 1){ + typeof options.allDone === 'function' && options.allDone(); + } + + return ret; }); }); // 若为源码版,则自动加载该组件依赖的 css 文件 if(!layui['layui.all']){ - layui.addcss('modules/code.css?v=3', 'skincodecss'); -} \ No newline at end of file + layui.addcss('modules/code.css?v=6', 'skincodecss'); +} diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js index 514e35b..c67c7ce 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js @@ -214,7 +214,7 @@ layui.define(['jquery', 'lay'], function(exports){ ,'
    '].join('')) //初始化颜色选择框 - var elem = options.elem = $(options.elem); + elem = options.elem = $(options.elem); options.size && elemColorBox.addClass('layui-colorpicker-'+ options.size); //初始化颜色选择框尺寸 // 插入颜色选择框 @@ -434,7 +434,7 @@ layui.define(['jquery', 'lay'], function(exports){ } //回调更改的颜色 - options.change && options.change(that.elemPicker.find('.' + PICKER_INPUT).find('input').val()); + options.change && options.change($.trim(that.elemPicker.find('.' + PICKER_INPUT).find('input').val())); } //拖拽元素 @@ -448,11 +448,16 @@ layui.define(['jquery', 'lay'], function(exports){ elemMove.remove(); }); }; + // 移动端滑动模拟事件中 + // 1. 不触发游标上绑定的事件,以提高性能,使滑动更流畅 + // 2. 游标上的事件需要冒泡到颜色拾取区域,用来模拟拖动游标的效果 + var needTrigger = true; + var needStopPropagation = true; //右侧主色选择 - slider.on('mousedown', function(e){ - var oldtop = this.offsetTop - ,oldy = e.clientY; + slider.on('mousedown', function(e, triggerEvent){ + var oldtop = this.offsetTop; + var oldy = e.clientY === undefined ? triggerEvent.clientY : e.clientY; var move = function(e){ var top = oldtop + (e.clientY - oldy) ,maxh = side[0].offsetHeight; @@ -463,13 +468,12 @@ layui.define(['jquery', 'lay'], function(exports){ change(h, _s, _b, _a); e.preventDefault(); }; - + needStopPropagation && layui.stope(e); createMoveElem(move); - //layui.stope(e); e.preventDefault(); }); - side.on('click', function(e){ + side.on('mousedown', function(e){ var top = e.clientY - $(this).offset().top + $win.scrollTop(); if(top < 0)top = 0; if(top > this.offsetHeight) top = this.offsetHeight; @@ -477,56 +481,57 @@ layui.define(['jquery', 'lay'], function(exports){ _h = h; change(h, _s, _b, _a); e.preventDefault(); + needTrigger && slider.trigger('mousedown', e); }); //中间小圆点颜色选择 - choose.on('mousedown', function(e){ - var oldtop = this.offsetTop - ,oldleft = this.offsetLeft - ,oldy = e.clientY - ,oldx = e.clientX; + choose.on('mousedown', function(e, triggerEvent){ + var oldtop = this.offsetTop; + var oldleft = this.offsetLeft; + var oldy = e.clientY === undefined ? triggerEvent.clientY : e.clientY; + var oldx = e.clientX === undefined ? triggerEvent.clientX : e.clientX; var move = function(e){ var top = oldtop + (e.clientY - oldy) ,left = oldleft + (e.clientX - oldx) - ,maxh = basis[0].offsetHeight - 3 - ,maxw = basis[0].offsetWidth - 3; - if(top < -3)top = -3; + ,maxh = basis[0].offsetHeight + ,maxw = basis[0].offsetWidth; + if(top < 0)top = 0; if(top > maxh)top = maxh; - if(left < -3)left = -3; + if(left < 0)left = 0; if(left > maxw)left = maxw; - var s = (left + 3)/260*100 - ,b = 100 - (top + 3)/180*100; + var s = left/260*100 + ,b = 100 - top/180*100; _b = b; _s = s; change(_h, s, b, _a); e.preventDefault(); }; - layui.stope(e); + needStopPropagation && layui.stope(e); createMoveElem(move); e.preventDefault(); }); basis.on('mousedown', function(e){ - var top = e.clientY - $(this).offset().top - 3 + $win.scrollTop() - ,left = e.clientX - $(this).offset().left - 3 + $win.scrollLeft() - if(top < -3)top = -3; - if(top > this.offsetHeight - 3)top = this.offsetHeight - 3; - if(left < -3)left = -3; - if(left > this.offsetWidth - 3)left = this.offsetWidth - 3; - var s = (left + 3)/260*100 - ,b = 100 - (top + 3)/180*100; + var top = e.clientY - $(this).offset().top + $win.scrollTop() + ,left = e.clientX - $(this).offset().left + $win.scrollLeft() + if(top < 0)top = 0; + if(top > this.offsetHeight)top = this.offsetHeight; + if(left < 0)left = 0; + if(left > this.offsetWidth)left = this.offsetWidth; + var s = left/260*100 + ,b = 100 - top/180*100; _b = b; _s = s; change(_h, s, b, _a); layui.stope(e); e.preventDefault(); - choose.trigger(e, 'mousedown'); + needTrigger && choose.trigger('mousedown', e); }); //底部透明度选择 - alphaslider.on('mousedown', function(e){ - var oldleft = this.offsetLeft - ,oldx = e.clientX; + alphaslider.on('mousedown', function(e, triggerEvent){ + var oldleft = this.offsetLeft; + var oldx = e.clientX === undefined ? triggerEvent.clientX : e.clientX; var move = function(e){ var left = oldleft + (e.clientX - oldx) ,maxw = alphacolor[0].offsetWidth; @@ -538,10 +543,11 @@ layui.define(['jquery', 'lay'], function(exports){ e.preventDefault(); }; + needStopPropagation && layui.stope(e); createMoveElem(move); e.preventDefault(); }); - alphacolor.on('click', function(e){ + alphacolor.on('mousedown', function(e){ var left = e.clientX - $(this).offset().left if(left < 0)left = 0; if(left > this.offsetWidth)left = this.offsetWidth; @@ -549,6 +555,7 @@ layui.define(['jquery', 'lay'], function(exports){ _a = a; change(_h, _s, _b, a); e.preventDefault(); + needTrigger && alphaslider.trigger('mousedown', e); }); //预定义颜色选择 @@ -567,6 +574,41 @@ layui.define(['jquery', 'lay'], function(exports){ change(hsb.h, hsb.s, hsb.b, a); }) }); + + if(!lay.touchEventsSupported()) return; + // 触摸事件模拟 + layui.each([ + {elem: side, eventType: 'mousedown'}, + {elem: alphacolor, eventType: 'mousedown'}, + {elem: basis, eventType: 'mousedown'} + ], function(i, obj){ + lay.touchSwipe(obj.elem, { + onTouchStart: function(){ + needTrigger = false; + needStopPropagation = false; + }, + onTouchMove: function(e){ + touchHandler(e, obj.eventType) + }, + onTouchEnd: function(){ + elemMove.remove(); + needTrigger = true; + needStopPropagation = true; + } + }) + }) + + function touchHandler(event, eventType) { + var pointer = event.touches[0]; + var simulatedEvent = document.createEvent("MouseEvent"); + + simulatedEvent.initMouseEvent(eventType, + true, true, window, 1, + pointer.screenX, pointer.screenY,pointer.clientX, pointer.clientY, + false, false, false, false, 0, null + ); + pointer.target.dispatchEvent(simulatedEvent); + } }; //颜色选择器hsb转换 @@ -576,16 +618,17 @@ layui.define(['jquery', 'lay'], function(exports){ var hex = HSBToHEX({h:h, s:100, b:100}); var color = HSBToHEX({h:h, s:s, b:b}); var sidetop = h/360*180; - var top = 180 - b/100*180 - 3; - var left = s/100*260 - 3; + var top = 180 - b/100*180; + var left = s/100*260; + var basisElem = that.elemPicker.find('.' + PICKER_BASIS)[0]; that.elemPicker.find('.' + PICKER_SIDE_SLIDER).css("top", sidetop); //滑块的top - that.elemPicker.find('.' + PICKER_BASIS)[0].style.background = '#' + hex; //颜色选择器的背景 + basisElem.style.background = '#' + hex; //颜色选择器的背景 //选择器的top left that.elemPicker.find('.' + PICKER_BASIS_CUR).css({ - "top": top - ,"left": left + "top": top / basisElem.offsetHeight * 100 + '%', + "left": left / basisElem.offsetWidth * 100 + '%' }); // if(type === 'change') return; @@ -614,7 +657,7 @@ layui.define(['jquery', 'lay'], function(exports){ //确认 ,confirm: function(othis, change){ - var value = elemPickerInput.val() + var value = $.trim(elemPickerInput.val()) ,colorValue ,hsb; diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js index 3fff835..07831fe 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js @@ -3,11 +3,12 @@ * 下拉菜单组件 */ -layui.define(['jquery', 'laytpl', 'lay'], function(exports){ +layui.define(['jquery', 'laytpl', 'lay', 'util'], function(exports){ "use strict"; var $ = layui.$; var laytpl = layui.laytpl; + var util = layui.util; var hint = layui.hint(); var device = layui.device(); var clickOrMousedown = (device.mobile ? 'touchstart' : 'mousedown'); @@ -15,10 +16,17 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ // 模块名 var MOD_NAME = 'dropdown'; var MOD_INDEX = 'layui_'+ MOD_NAME +'_index'; // 模块索引名 + var MOD_ID = 'lay-' + MOD_NAME + '-id'; // 外部接口 var dropdown = { - config: {}, + config: { + customName: { // 自定义 data 字段名 + id: 'id', + title: 'title', + children: 'child' + } + }, index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0, // 设置全局项 @@ -53,6 +61,9 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ }, close: function () { that.remove() + }, + open: function () { + that.render() } } }; @@ -94,8 +105,9 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ isAllowSpread: true, // 是否允许菜单组展开收缩 isSpreadItem: true, // 是否初始展开子菜单 data: [], // 菜单数据结构 - delay: 300, // 延迟关闭的毫秒数,若 trigger 为 hover 时才生效 - shade: 0 // 遮罩 + delay: [200, 300], // 延时显示或隐藏的毫秒数,若为 number 类型,则表示显示和隐藏的延迟时间相同,trigger 为 hover 时才生效 + shade: 0, // 遮罩 + accordion: false // 手风琴效果,仅菜单组生效。基础菜单需要在容器上追加 'lay-accordion' 属性。 }; // 重载实例 @@ -125,8 +137,8 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ $.extend(options, lay.options(elem[0])); // 若重复执行 render,则视为 reload 处理 - if(!rerender && elem[0] && elem.data(MOD_INDEX)){ - var newThat = thisModule.getThis(elem.data(MOD_INDEX)); + if(!rerender && elem[0] && elem.attr(MOD_ID)){ + var newThat = thisModule.getThis(elem.attr(MOD_ID)); if(!newThat) return; return newThat.reload(options, type); @@ -139,6 +151,11 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ elem.attr('id') || that.index ); + elem.attr(MOD_ID, options.id); + + // 初始化自定义字段名 + options.customName = $.extend({}, dropdown.config.customName, options.customName); + if(options.show || (type === 'reloadData' && that.elemView && $('body').find(that.elemView.get(0)).length)) that.render(rerender, type); //初始即显示或者面板弹出之后执行了刷新数据 that.events(); // 事件 }; @@ -147,6 +164,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ Class.prototype.render = function(rerender, type){ var that = this; var options = that.config; + var customName = options.customName; var elemBody = $('body'); // 默认菜单内容 @@ -155,7 +173,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ if(options.data.length > 0 ){ eachItemView(elemUl, options.data) } else { - elemUl.html('
  • No data
  • '); + elemUl.html('
  • 暂无数据
  • '); } return elemUl; }; @@ -163,9 +181,10 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ // 遍历菜单项 var eachItemView = function(views, data){ // var views = []; + layui.each(data, function(index, item){ // 是否存在子级 - var isChild = item.child && item.child.length > 0; + var isChild = item[customName.children] && item[customName.children].length > 0; var isSpreadItem = ('isSpreadItem' in item) ? item.isSpreadItem : options.isSpreadItem var title = function(title){ var templet = item.templet || options.templet; @@ -175,7 +194,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ : laytpl(templet).render(item); } return title; - }(item.title); + }(util.escape(item[customName.title])); // 初始类型 var type = function(){ @@ -192,7 +211,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ return ''; }(); - if(type !== '-' && (!item.title && !item.id && !isChild)) return; + if(type !== '-' && (!item[customName.title] && !item[customName.id] && !isChild)) return; //列表元素 var viewLi = $(['
    ') - ,elemUl = $('
      '); + var elemPanel = $('
      '); + var elemUl = $('
        '); if(type === 'parent'){ - elemPanel.append(eachItemView(elemUl, item.child)); + elemPanel.append(eachItemView(elemUl, item[customName.children])); viewLi.append(elemPanel); } else { - viewLi.append(eachItemView(elemUl, item.child)); + viewLi.append(eachItemView(elemUl, item[customName.children])); } } @@ -256,7 +275,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ }; // 主模板 - var TPL_MAIN = ['
        ' + var TPL_MAIN = ['
        ' ,'
        '].join(''); // 如果是右键事件,则每次触发事件时,将允许重新渲染 @@ -266,7 +285,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ if(!rerender && options.elem.data(MOD_INDEX +'_opened')) return; // 记录模板对象 - that.elemView = $('.' + STR_ELEM + '[lay-id="' + options.id + '"]'); + that.elemView = $('.' + STR_ELEM + '[' + MOD_ID + '="' + options.id + '"]'); if (type === 'reloadData' && that.elemView.length) { that.elemView.html(options.content || getDefaultView()); } else { @@ -313,7 +332,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ that.elemView.find('.layui-menu li').on('click', function(e){ var othis = $(this); var data = othis.data('item') || {}; - var isChild = data.child && data.child.length > 0; + var isChild = data[customName.children] && data[customName.children].length > 0; var isClickAllScope = options.clickScope === 'all'; // 是否所有父子菜单均触发点击事件 if(data.disabled) return; // 菜单项禁用状态 @@ -331,12 +350,12 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ // 触发菜单组展开收缩 that.elemView.find(STR_GROUP_TITLE).on('click', function(e){ - var othis = $(this) - ,elemGroup = othis.parent() - ,data = elemGroup.data('item') || {} + var othis = $(this); + var elemGroup = othis.parent(); + var data = elemGroup.data('item') || {}; if(data.type === 'group' && options.isAllowSpread){ - thisModule.spread(elemGroup); + thisModule.spread(elemGroup, options.accordion); } }); @@ -364,17 +383,33 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ Class.prototype.remove = function(){ var that = this; var options = that.config; - var elemPrev = thisModule.prevElem; + var prevContentElem = thisModule.prevElem; // 若存在已打开的面板元素,则移除 - if(elemPrev){ - elemPrev.data('prevElem') && ( - elemPrev.data('prevElem').data(MOD_INDEX +'_opened', false) - ); - elemPrev.remove(); + if(prevContentElem){ + var prevId = prevContentElem.attr(MOD_ID); + var prevTriggerElem = prevContentElem.data('prevElem'); + var prevInstance = thisModule.getThis(prevId); + var prevOnClose = prevInstance.config.close; + + prevTriggerElem && prevTriggerElem.data(MOD_INDEX +'_opened', false); + prevContentElem.remove(); + delete thisModule.prevElem; + typeof prevOnClose === 'function' && prevOnClose.call(prevInstance.config, prevTriggerElem); } lay('.' + STR_ELEM_SHADE).remove(); }; + + Class.prototype.normalizedDelay = function(){ + var that = this; + var options = that.config; + var delay = [].concat(options.delay); + + return { + show: delay[0], + hide: delay[1] !== undefined ? delay[1] : delay[0] + } + } // 延迟删除视图 Class.prototype.delayRemove = function(){ @@ -384,7 +419,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ thisModule.timer = setTimeout(function(){ that.remove(); - }, options.delay); + }, that.normalizedDelay().hide); }; // 事件 @@ -397,13 +432,23 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ // 解除上一个事件 if(that.prevElem) that.prevElem.off(options.trigger, that.prevElemCallback); + + // 是否鼠标移入时触发 + var isMouseEnter = options.trigger === 'mouseenter'; // 记录被绑定的元素及回调 that.prevElem = options.elem; that.prevElemCallback = function(e){ clearTimeout(thisModule.timer); that.e = e; - that.render(); + + // 若为鼠标移入事件,则延迟触发 + isMouseEnter ? ( + thisModule.timer = setTimeout(function(){ + that.render(); + }, that.normalizedDelay().show) + ) : that.render(); + e.preventDefault(); }; @@ -411,8 +456,8 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ options.elem.on(options.trigger, that.prevElemCallback); // 如果是鼠标移入事件 - if(options.trigger === 'mouseenter'){ - // 直行鼠标移出事件 + if (isMouseEnter) { + // 执行鼠标移出事件 options.elem.on('mouseleave', function(){ that.delayRemove(); }); @@ -430,16 +475,33 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ }; // 设置菜单组展开和收缩状态 - thisModule.spread = function(othis){ - // 菜单组展开和收缩 + thisModule.spread = function(othis, isAccordion){ + var contentElem = othis.children('ul'); var needSpread = othis.hasClass(STR_ITEM_UP); - var elemIcon = othis.children('.'+ STR_MENU_TITLE).find('.layui-icon-' + (needSpread ? 'down' : 'up')); - if(needSpread){ + var ANIM_MS = 200; + + // 动画执行完成后的操作 + var complete = function() { + $(this).css({'display': ''}); // 剔除临时 style,以适配外部样式的状态重置; + }; + + // 动画是否正在执行 + if (contentElem.is(':animated')) return; + + // 展开 + if (needSpread) { othis.removeClass(STR_ITEM_UP).addClass(STR_ITEM_DOWN); - elemIcon.removeClass('layui-icon-down').addClass('layui-icon-up'); - } else { + contentElem.hide().stop().slideDown(ANIM_MS, complete); + } else { // 收缩 + contentElem.stop().slideUp(ANIM_MS, complete); othis.removeClass(STR_ITEM_DOWN).addClass(STR_ITEM_UP); - elemIcon.removeClass('layui-icon-up').addClass('layui-icon-down'); + } + + // 手风琴 + if (needSpread && isAccordion) { + var groupSibs = othis.siblings('.' + STR_ITEM_DOWN); + groupSibs.children('ul').stop().slideUp(ANIM_MS, complete); + groupSibs.removeClass(STR_ITEM_DOWN).addClass(STR_ITEM_UP); } }; @@ -454,7 +516,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ var that = thisModule.getThis(dropdown.thisId); if(!that) return; - if(!that.elemView[0] || !$('.'+ STR_ELEM)[0]){ + if((that.elemView && !that.elemView[0]) || !$('.'+ STR_ELEM)[0]){ return false; } @@ -523,9 +585,10 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ var othis = $(this); var elemGroup = othis.parents('.'+ STR_ITEM_GROUP +':eq(0)'); var options = lay.options(elemGroup[0]); + var isAccordion = typeof othis.parents('.layui-menu').eq(0).attr('lay-accordion') === 'string'; if(('isAllowSpread' in options) ? options.isAllowSpread : true){ - thisModule.spread(elemGroup); + thisModule.spread(elemGroup, isAccordion); } }); @@ -570,6 +633,15 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){ that.remove(); return thisModule.call(that); }; + + // 打开面板 + dropdown.open = function(id){ + var that = thisModule.getThis(id); + if(!that) return this; + + that.render(); + return thisModule.call(that); + } // 重载实例 dropdown.reload = function(id, options, type){ diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js index e3c210b..ddc9edd 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js @@ -48,7 +48,7 @@ layui.define('jquery', function(exports){ }() +'>'+ (options.title || 'unnaming') +''; barElem[0] ? barElem.before(li) : titElem.append(li); - contElem.append('
        '+ (options.content || '') +'
        '); + contElem.append('
        '+ (options.content || '') +'
        '); // call.hideTabMore(true); // 是否添加即切换 options.change && this.tabChange(filter, options.id); @@ -66,14 +66,21 @@ layui.define('jquery', function(exports){ return this; }; - // 外部 Tab 切换 - Element.prototype.tabChange = function(filter, layid){ + /** + * 外部 Tab 切换 + * @param {string} filter - 标签主容器 lay-filter 值 + * @param {string} layid - 标签头 lay-id 值 + * @param {boolean} force - 是否强制切换 + * @returns {this} + */ + Element.prototype.tabChange = function(filter, layid, force){ var tabElem = $('.layui-tab[lay-filter='+ filter +']'); var titElem = tabElem.children(TITLE); var liElem = titElem.find('>li[lay-id="'+ layid +'"]'); call.tabClick.call(liElem[0], { - liElem: liElem + liElem: liElem, + force: force }); return this; }; @@ -82,7 +89,7 @@ layui.define('jquery', function(exports){ Element.prototype.tab = function(options){ options = options || {}; dom.on('click', options.headerElem, function(e){ - var index = $(this).index(); + var index = $(options.headerElem).index($(this)); call.tabClick.call(this, { index: index, options: options @@ -134,21 +141,46 @@ layui.define('jquery', function(exports){ var isJump = elemA.attr('href') !== 'javascript:;' && elemA.attr('target') === '_blank'; // 是否存在跳转 var unselect = typeof othis.attr('lay-unselect') === 'string'; // 是否禁用选中 var filter = parents.attr('lay-filter'); + var hasId = othis.attr('lay-id'); // 下标 var index = 'index' in obj ? obj.index : othis.parent().children('li').index(othis); + + // 若非强制切换,则根据 tabBeforeChange 事件的返回结果决定是否切换 + if (!obj.force) { + var liThis = othis.siblings('.' + THIS); + var shouldChange = layui.event.call(this, MOD_NAME, 'tabBeforeChange('+ filter +')', { + elem: parents, + from: { + index: othis.parent().children('li').index(liThis), + id: liThis.attr('lay-id') + }, + to: { + index: index, + id: hasId + }, + }); + if(shouldChange === false) return; + } // 执行切换 if(!(isJump || unselect)){ othis.addClass(THIS).siblings().removeClass(THIS); - item.eq(index).addClass(SHOW).siblings().removeClass(SHOW); + if(hasId){ + var contentElem = item.filter('[lay-id="' + hasId + '"]'); + contentElem = contentElem.length ? contentElem : item.eq(index); + contentElem.addClass(SHOW).siblings().removeClass(SHOW); + }else{ + item.eq(index).addClass(SHOW).siblings().removeClass(SHOW); + } } layui.event.call(this, MOD_NAME, 'tab('+ filter +')', { elem: parents, - index: index + index: index, + id: hasId }); } @@ -159,6 +191,14 @@ layui.define('jquery', function(exports){ var tabElem = li.closest('.layui-tab'); var item = tabElem.children('.layui-tab-content').children('.layui-tab-item'); var filter = tabElem.attr('lay-filter'); + var hasId = li.attr('lay-id'); + + var shouldClose = layui.event.call(li[0], MOD_NAME, 'tabBeforeDelete('+ filter +')', { + elem: tabElem, + index: index, + id: hasId + }); + if(shouldClose === false) return; if(li.hasClass(THIS)){ if (li.next()[0] && li.next().is('li')){ @@ -171,14 +211,21 @@ layui.define('jquery', function(exports){ } li.remove(); - item.eq(index).remove(); + if(hasId){ + var contentElem = item.filter('[lay-id="' + hasId + '"]'); + contentElem = contentElem.length ? contentElem : item.eq(index) + contentElem.remove() + }else{ + item.eq(index).remove(); + } setTimeout(function(){ call.tabAuto(); }, 50); layui.event.call(this, MOD_NAME, 'tabDelete('+ filter +')', { elem: tabElem, - index: index + index: index, + id: hasId }); } @@ -202,10 +249,11 @@ layui.define('jquery', function(exports){ } // 开启关闭图标 - if(othis.attr('lay-allowclose')){ + var allowclose = othis.attr('lay-allowclose'); + if(allowclose && allowclose !== 'false'){ title.find('li').each(function(){ var li = $(this); - if(!li.find('.'+CLOSE)[0]){ + if(!li.find('.'+CLOSE)[0] && li.attr('lay-allowclose') !== 'false'){ var close = $(''); close.on('click', call.tabDelete); li.append(close); @@ -272,31 +320,63 @@ layui.define('jquery', function(exports){ ) */ - //点击菜单 - a标签触发 - ,clickThis: function(){ - var othis = $(this) - ,parents = othis.parents(NAV_ELEM) - ,filter = parents.attr('lay-filter') - ,parent = othis.parent() - ,child = othis.siblings('.'+NAV_CHILD) - ,unselect = typeof parent.attr('lay-unselect') === 'string'; //是否禁用选中 + // 点击菜单 - a 标签触发 + ,clickThis: function() { + var othis = $(this); + var parents = othis.closest(NAV_ELEM); + var filter = parents.attr('lay-filter'); + var parent = othis.parent() ; + var child = othis.siblings('.'+ NAV_CHILD); + var unselect = typeof parent.attr('lay-unselect') === 'string'; // 是否禁用选中 - if(!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect){ - if(!child[0]){ - parents.find('.'+THIS).removeClass(THIS); + // 满足点击选中的条件 + if (!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect) { + if (!child[0]) { + parents.find('.'+ THIS).removeClass(THIS); parent.addClass(THIS); } } - //如果是垂直菜单 - if(parents.hasClass(NAV_TREE)){ + // 若为垂直菜单 + if (parents.hasClass(NAV_TREE)) { + var NAV_ITEMED = NAV_ITEM + 'ed'; // 用于标注展开状态 + var needExpand = !parent.hasClass(NAV_ITEMED); // 是否执行展开 + var ANIM_MS = 200; // 动画过渡毫秒数 + + // 动画执行完成后的操作 + var complete = function() { + $(this).css({ + "display": "" // 剔除动画生成的 style display,以适配外部样式的状态重置 + }); + // 避免导航滑块错位 + parents.children('.'+ NAV_BAR).css({ + opacity: 0 + }) + }; + + // 是否正处于动画中的状态 + if (child.is(':animated')) return; + + // 剔除可能存在的 CSS3 动画类 child.removeClass(NAV_ANIM); - - //如果有子菜单,则展开 - if(child[0]){ - parent[child.css('display') === 'none' ? 'addClass': 'removeClass'](NAV_ITEM+'ed'); - if(parents.attr('lay-shrink') === 'all'){ - parent.siblings().removeClass(NAV_ITEM + 'ed'); + + // 若有子菜单,则对其执行展开或收缩 + if (child[0]) { + if (needExpand) { + // 先执行 slideDown 动画,再标注展开状态样式,避免元素 `block` 状态导致动画无效 + child.slideDown(ANIM_MS, complete); + parent.addClass(NAV_ITEMED); + } else { + // 先取消展开状态样式,再将元素临时显示,避免 `none` 状态导致 slideUp 动画无效 + parent.removeClass(NAV_ITEMED); + child.show().slideUp(ANIM_MS, complete); + } + + // 手风琴 --- 收缩兄弟展开项 + if (typeof parents.attr('lay-accordion') === 'string' || parents.attr('lay-shrink') === 'all') { + var parentSibs = parent.siblings('.'+ NAV_ITEMED); + parentSibs.removeClass(NAV_ITEMED); + parentSibs.children('.'+ NAV_CHILD).show().stop().slideUp(ANIM_MS, complete); } } } @@ -304,26 +384,16 @@ layui.define('jquery', function(exports){ layui.event.call(this, MOD_NAME, 'nav('+ filter +')', othis); } - //点击子菜单选中 - /* - ,clickChild: function(){ - var othis = $(this), parents = othis.parents(NAV_ELEM) - ,filter = parents.attr('lay-filter'); - parents.find('.'+THIS).removeClass(THIS); - othis.addClass(THIS); - layui.event.call(this, MOD_NAME, 'nav('+ filter +')', othis); - } - */ - - //折叠面板 + // 折叠面板 ,collapse: function(){ - var othis = $(this), icon = othis.find('.layui-colla-icon') - ,elemCont = othis.siblings('.layui-colla-content') - ,parents = othis.parents('.layui-collapse').eq(0) - ,filter = parents.attr('lay-filter') - ,isNone = elemCont.css('display') === 'none'; + var othis = $(this); + var icon = othis.find('.layui-colla-icon'); + var elemCont = othis.siblings('.layui-colla-content'); + var parents = othis.parents('.layui-collapse').eq(0); + var filter = parents.attr('lay-filter'); + var isNone = elemCont.css('display') === 'none'; - //是否手风琴 + // 是否手风琴 if(typeof parents.attr('lay-accordion') === 'string'){ var show = parents.children('.layui-colla-item').children('.'+SHOW); show.siblings('.layui-colla-title').children('.layui-colla-icon').html(''); @@ -352,56 +422,65 @@ layui.define('jquery', function(exports){ call.tabAuto.call({}); } - //导航菜单 + // 导航菜单 ,nav: function(){ - var TIME = 200, timer = {}, timerMore = {}, timeEnd = {}, NAV_TITLE = 'layui-nav-title' + var TIME = 200; + var timer = {}; + var timerMore = {}; + var timeEnd = {}; + var NAV_TITLE = 'layui-nav-title'; - //滑块跟随 - ,follow = function(bar, nav, index){ - var othis = $(this), child = othis.find('.'+NAV_CHILD); - if(nav.hasClass(NAV_TREE)){ - //无子菜单时跟随 - if(!child[0]){ + // 滑块跟随 + var follow = function(bar, nav, index) { + var othis = $(this); + var child = othis.find('.'+NAV_CHILD); + + // 是否垂直导航菜单 + if (nav.hasClass(NAV_TREE)) { + // 无子菜单时跟随 + if (!child[0]) { var thisA = othis.children('.'+ NAV_TITLE); bar.css({ - top: othis.offset().top - nav.offset().top - ,height: (thisA[0] ? thisA : othis).outerHeight() - ,opacity: 1 + top: othis.offset().top - nav.offset().top, + height: (thisA[0] ? thisA : othis).outerHeight(), + opacity: 1 }); } } else { child.addClass(NAV_ANIM); - //若居中对齐 - if(child.hasClass(NAV_CHILD_C)) child.css({ - left: -(child.outerWidth() - othis.width())/2 - }); - - //滑块定位 - if(child[0]){ //若有子菜单,则滑块消失 - bar.css({ - left: bar.position().left + bar.width()/2 - ,width: 0 - ,opacity: 0 - }); - } else { //bar 跟随 - bar.css({ - left: othis.position().left + parseFloat(othis.css('marginLeft')) - ,top: othis.position().top + othis.height() - bar.height() + // 若居中对齐 + if (child.hasClass(NAV_CHILD_C)) { + child.css({ + left: -(child.outerWidth() - othis.width()) / 2 }); } - //渐显滑块并适配宽度 - timer[index] = setTimeout(function(){ + // 滑块定位 + if (child[0]) { // 若有子菜单,则滑块消失 bar.css({ - width: child[0] ? 0 : othis.width() - ,opacity: child[0] ? 0 : 1 + left: bar.position().left + bar.width() / 2, + width: 0, + opacity: 0 + }); + } else { // bar 跟随 + bar.css({ + left: othis.position().left + parseFloat(othis.css('marginLeft')), + top: othis.position().top + othis.height() - bar.height() + }); + } + + // 渐显滑块并适配宽度 + timer[index] = setTimeout(function() { + bar.css({ + width: child[0] ? 0 : othis.width(), + opacity: child[0] ? 0 : 1 }); }, device.ie && device.ie < 10 ? 0 : TIME); - //显示子菜单 + // 显示子菜单 clearTimeout(timeEnd[index]); - if(child.css('display') === 'block'){ + if (child.css('display') === 'block') { clearTimeout(timerMore[index]); } timerMore[index] = setTimeout(function(){ @@ -411,61 +490,64 @@ layui.define('jquery', function(exports){ } }; - //遍历导航 - $(NAV_ELEM + elemFilter).each(function(index){ - var othis = $(this) - ,bar = $('') - ,itemElem = othis.find('.'+NAV_ITEM); + // 遍历导航 + $(NAV_ELEM + elemFilter).each(function(index) { + var othis = $(this); + var bar = $(''); + var itemElem = othis.find('.'+NAV_ITEM); - //hover 滑动效果 - if(!othis.find('.'+NAV_BAR)[0]){ + // hover 滑动效果 + if (!othis.find('.'+NAV_BAR)[0]) { othis.append(bar); - (othis.hasClass(NAV_TREE) + ( othis.hasClass(NAV_TREE) ? itemElem.find('dd,>.'+ NAV_TITLE) - : itemElem).on('mouseenter', function(){ + : itemElem + ).on('mouseenter', function() { follow.call(this, bar, othis, index); - }).on('mouseleave', function(){ //鼠标移出 - //是否为垂直导航 - if(othis.hasClass(NAV_TREE)){ + }).on('mouseleave', function() { // 鼠标移出 + // 是否为垂直导航 + if (othis.hasClass(NAV_TREE)) { bar.css({ - height: 0 - ,opacity: 0 + height: 0, + opacity: 0 }); } else { - //隐藏子菜单 + // 隐藏子菜单 clearTimeout(timerMore[index]); timerMore[index] = setTimeout(function(){ - othis.find('.'+NAV_CHILD).removeClass(SHOW); - othis.find('.'+NAV_MORE).removeClass(NAV_MORE+'d'); + othis.find('.'+ NAV_CHILD).removeClass(SHOW); + othis.find('.'+ NAV_MORE).removeClass(NAV_MORE +'d'); }, 300); } }); - othis.on('mouseleave', function(){ + + // 鼠标离开当前菜单时 + othis.on('mouseleave', function() { clearTimeout(timer[index]) - timeEnd[index] = setTimeout(function(){ - if(!othis.hasClass(NAV_TREE)){ + timeEnd[index] = setTimeout(function() { + if (!othis.hasClass(NAV_TREE)) { bar.css({ - width: 0 - ,left: bar.position().left + bar.width()/2 - ,opacity: 0 + width: 0, + left: bar.position().left + bar.width() / 2, + opacity: 0 }); } }, TIME); }); } - //展开子菜单 - itemElem.find('a').each(function(){ - var thisA = $(this) - ,parent = thisA.parent() - ,child = thisA.siblings('.'+NAV_CHILD); + // 展开子菜单 + itemElem.find('a').each(function() { + var thisA = $(this); + var parent = thisA.parent(); + var child = thisA.siblings('.'+ NAV_CHILD); - //输出小箭头 - if(child[0] && !thisA.children('.'+NAV_MORE)[0]){ + // 输出小箭头 + if (child[0] && !thisA.children('.'+ NAV_MORE)[0]) { thisA.append(''); } - thisA.off('click', call.clickThis).on('click', call.clickThis); //点击菜单 + thisA.off('click', call.clickThis).on('click', call.clickThis); // 点击菜单 }); }); } diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js index bb4a4bc..6128e27 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js @@ -1,11 +1,11 @@ /** - * flow 流加载组件 + * flow 流加载组件 */ - - + + layui.define('jquery', function(exports){ "use strict"; - + var $ = layui.$, Flow = function(options){} ,ELEM_MORE = 'layui-flow-more' ,ELEM_LOAD = ''; @@ -14,97 +14,118 @@ layui.define('jquery', function(exports){ Flow.prototype.load = function(options){ var that = this, page = 0, lock, isOver, lazyimg, timer; options = options || {}; - + var elem = $(options.elem); if(!elem[0]) return; - var scrollElem = $(options.scrollElem || document); //滚动条所在元素 - var mb = options.mb || 50; //与底部的临界距离 - var isAuto = 'isAuto' in options ? options.isAuto : true; //是否自动滚动加载 - var end = options.end || '没有更多了'; //“末页”显示文案 - + var scrollElem = $(options.scrollElem || document); // 滚动条所在元素 + var threshold = 'mb' in options ? options.mb : 50; // 临界距离 + var isAuto = 'isAuto' in options ? options.isAuto : true; // 否自动滚动加载 + var moreText = options.moreText || "加载更多"; // 手动加载时,加载更多按钮文案 + var end = options.end || '没有更多了'; // “末页”显示文案 + var direction = options.direction || 'bottom'; + var isTop = direction === 'top'; + + // 重复执行时清理旧的事件绑定 + that._cleanup(elem, scrollElem); + //滚动条所在元素是否为document var notDocument = options.scrollElem && options.scrollElem !== document; - + //加载更多 - var ELEM_TEXT = '加载更多' + var ELEM_TEXT = '' + moreText + '' ,more = $(''); - + if(!elem.find('.layui-flow-more')[0]){ - elem.append(more); + elem[isTop ? 'prepend' : 'append'](more); } - + //加载下一个元素 - var next = function(html, over){ + var next = function(html, over){ + var scrollHeightStart = notDocument ? scrollElem.prop('scrollHeight') : document.documentElement.scrollHeight; + var scrollTopStart = scrollElem.scrollTop(); html = $(html); - more.before(html); + more[isTop ? 'after' : 'before'](html); over = over == 0 ? true : null; over ? more.html(end) : more.find('a').html(ELEM_TEXT); isOver = over; lock = null; lazyimg && lazyimg(); + if(isTop){ + var scrollHeightEnd = notDocument ? scrollElem.prop('scrollHeight') : document.documentElement.scrollHeight; + if(page === 1){ + // 首次渲染后滑动到底部 + scrollElem.scrollTop(scrollHeightEnd); + }else if(page > 1){ + var nextElementHeight = scrollHeightEnd - scrollHeightStart; + scrollElem.scrollTop(scrollTopStart + nextElementHeight); + } + } }; - + //触发请求 var done = function(){ lock = true; more.find('a').html(ELEM_LOAD); typeof options.done === 'function' && options.done(++page, next); }; - + done(); - + //不自动滚动加载 - more.find('a').on('click', function(){ + more.find('a').on('click.flow', function(){ var othis = $(this); if(isOver) return; lock || done(); }); - + //如果允许图片懒加载 if(options.isLazyimg){ - var lazyimg = that.lazyimg({ + lazyimg = that.lazyimg({ elem: options.elem + ' img' ,scrollElem: options.scrollElem + ,direction: options.direction }); } - + if(!isAuto) return that; - - scrollElem.on('scroll', function(){ + + scrollElem.on('scroll.flow', function(){ var othis = $(this), top = othis.scrollTop(); - + if(timer) clearTimeout(timer); if(isOver || !elem.width()) return; //如果已经结束,或者元素处于隐藏状态,则不执行滚动加载 - + timer = setTimeout(function(){ //计算滚动所在容器的可视高度 var height = notDocument ? othis.height() : $(window).height(); - + //计算滚动所在容器的实际高度 var scrollHeight = notDocument ? othis.prop('scrollHeight') : document.documentElement.scrollHeight; //临界点 - if(scrollHeight - top - height <= mb){ + if(!isTop ? scrollHeight - top - height <= threshold : top <= threshold){ lock || done(); } }, 100); }); - + return that; }; - + //图片懒加载 Flow.prototype.lazyimg = function(options){ var that = this, index = 0, haveScroll; options = options || {}; - + var scrollElem = $(options.scrollElem || document); //滚动条所在元素 var elem = options.elem || 'img'; - + var direction = options.direction || 'bottom'; + var isTop = direction === 'top'; + //滚动条所在元素是否为document var notDocument = options.scrollElem && options.scrollElem !== document; - + //显示图片 var show = function(item, height){ var start = scrollElem.scrollTop(), end = start + height; @@ -113,13 +134,13 @@ layui.define('jquery', function(exports){ }() : item.offset().top; /* 始终只加载在当前屏范围内的图片 */ - if(elemTop >= start && elemTop <= end){ + if((isTop ? elemTop + item.height() : elemTop) >= start && elemTop <= end){ if(item.attr('lay-src')){ var src = item.attr('lay-src'); layui.img(src, function(){ var next = that.lazyimg.elem.eq(index); item.attr('src', src).removeAttr('lay-src'); - + /* 当前图片加载就绪后,检测下一个图片是否在当前屏 */ next[0] && render(next); index++; @@ -130,7 +151,7 @@ layui.define('jquery', function(exports){ } } }, render = function(othis, scroll){ - + //计算滚动所在容器的可视高度 var height = notDocument ? (scroll||scrollElem).height() : $(window).height(); var start = scrollElem.scrollTop(), end = start + height; @@ -145,32 +166,39 @@ layui.define('jquery', function(exports){ var item = that.lazyimg.elem.eq(i), elemTop = notDocument ? function(){ return item.offset().top - scrollElem.offset().top + start; }() : item.offset().top; - + show(item, height); index = i; - + //如果图片的top坐标,超出了当前屏,则终止后续图片的遍历 if(elemTop > end) break; } } }; - + render(); - + if(!haveScroll){ var timer; - scrollElem.on('scroll', function(){ + scrollElem.on('scroll.lazyimg' , function(){ var othis = $(this); if(timer) clearTimeout(timer) timer = setTimeout(function(){ render(null, othis); }, 50); - }); + }); haveScroll = true; } return render; }; - + + // 重复执行时清理旧的事件绑定,私有方法 + Flow.prototype._cleanup = function(elem, scrollElem){ + scrollElem.off('scroll.flow').off('scroll.lazyimg'); + elem.find('.layui-flow-more').find('a').off('click.flow'); + elem.html(''); + } + //暴露接口 exports('flow', new Flow()); }); diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js index 538d73c..b8a0813 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js @@ -1,1066 +1,1310 @@ /** * form 表单组件 */ - -layui.define(['lay', 'layer', 'util'], function(exports){ - "use strict"; - - var $ = layui.$; - var layer = layui.layer; - var util = layui.util; - var hint = layui.hint(); - var device = layui.device(); - - var MOD_NAME = 'form', ELEM = '.layui-form', THIS = 'layui-this'; - var SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled'; - - var Form = function(){ - this.config = { - // 内置的验证规则 - verify: { - required: [ - /[\S]+/, - '必填项不能为空' - ], - phone: [ - /^1\d{10}$/, - '请输入正确的手机号' - ], - email: [ - /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, - '邮箱格式不正确' - ], - url: [ - /^(#|(http(s?)):\/\/|\/\/)[^\s]+\.[^\s]+$/, - '链接格式不正确' - ], - number: function(value){ - if(isNaN(value)) return '只能填写数字'; - }, - date: [ - /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/, - '日期格式不正确' - ], - identity: [ - /(^\d{15}$)|(^\d{17}(x|X|\d)$)/, - '请输入正确的身份证号' - ], - integer: [/^\d*$/ - , "只能填写整数"], - pass: [ - /^[\S]{6,12}$/ - , '密码必须6到12位,且不能出现空格' - ], - ip: [ - /(^$)|^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/ - , 'IP地址不符合规则' - ] - }, - verIncludeRequired: false, // 验证规则是否包含必填 --- 为兼容旧版的验证机制 - autocomplete: null // 全局 autocomplete 状态。 null 表示不干预 + +layui.define(['lay', 'layer', 'util'], function (exports) { + "use strict"; + + var $ = layui.$; + var layer = layui.layer; + var util = layui.util; + var hint = layui.hint(); + var device = layui.device(); + + var MOD_NAME = 'form'; + var ELEM = '.layui-form'; + var THIS = 'layui-this'; + var SHOW = 'layui-show'; + var HIDE = 'layui-hide'; + var DISABLED = 'layui-disabled'; + var OUT_OF_RANGE = 'layui-input-number-out-of-range'; + + var Form = function () { + this.config = { + // 内置的验证规则 + verify: { + required: function (value) { + if (!/[\S]+/.test(value)) { + return '必填项不能为空'; + } + }, + phone: function (value) { + var EXP = /^1\d{10}$/; + if (value && !EXP.test(value)) { + return '手机号格式不正确'; + } + }, + email: function (value) { + var EXP = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; + if (value && !EXP.test(value)) { + return '邮箱格式不正确'; + } + }, + url: function (value) { + var EXP = /^(#|(http(s?)):\/\/|\/\/)[^\s]+\.[^\s]+$/; + if (value && !EXP.test(value)) { + return '链接格式不正确'; + } + }, + number: function (value) { + if (value && isNaN(value)) { + return '只能填写数字'; + } + }, + date: function (value) { + var EXP = /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/; + if (value && !EXP.test(value)) { + return '日期格式不正确'; + } + }, + identity: function (value) { + var EXP = /(^\d{15}$)|(^\d{17}(x|X|\d)$)/; + if (value && !EXP.test(value)) { + return '身份证号格式不正确'; + } + }, + integer: function (value) { + var EXP = /^\d*$/; + if (value && !EXP.test(value)) { + return '只能填写整数'; + } + } + }, + autocomplete: null // 全局 autocomplete 状态。 null 表示不干预 + }; }; - }; - - // 全局设置 - Form.prototype.set = function(options){ - var that = this; - $.extend(true, that.config, options); - return that; - }; - - // 验证规则设定 - Form.prototype.verify = function(settings){ - var that = this; - $.extend(true, that.config.verify, settings); - return that; - }; - // 获取指定表单对象 - Form.prototype.getFormElem = function(filter){ - return $(ELEM + function(){ - return filter ? ('[lay-filter="' + filter +'"]') : ''; - }()); - }; - - // 表单事件 - Form.prototype.on = function(events, callback){ - return layui.onevent.call(this, MOD_NAME, events, callback); - }; - - // 赋值/取值 - Form.prototype.val = function(filter, object){ - var that = this - ,formElem = that.getFormElem(filter); - - // 遍历 - formElem.each(function(index, item){ - var itemForm = $(this); - - // 赋值 - layui.each(object, function(key, value){ - var itemElem = itemForm.find('[name="'+ key +'"]') - ,type; - - // 如果对应的表单不存在,则不执行 - if(!itemElem[0]) return; - type = itemElem[0].type; - - // 如果为复选框 - if(type === 'checkbox'){ - itemElem[0].checked = value; - } else if(type === 'radio') { // 如果为单选框 - itemElem.each(function(){ - this.checked = this.value == value; - }); - } else { // 其它类型的表单 - itemElem.val(value); - } - }); - }); - - form.render(null, filter); - - // 返回值 - return that.getValue(filter); - }; - - // 取值 - Form.prototype.getValue = function(filter, itemForm){ - itemForm = itemForm || this.getFormElem(filter); - - var nameIndex = {} // 数组 name 索引 - ,field = {} - ,fieldElem = itemForm.find('input,select,textarea') // 获取所有表单域 - - layui.each(fieldElem, function(_, item){ - var othis = $(this) - ,init_name; // 初始 name - - item.name = (item.name || '').replace(/^\s*|\s*&/, ''); - if(!item.name) return; - - // 用于支持数组 name - if(/^.*\[\]$/.test(item.name)){ - var key = item.name.match(/^(.*)\[\]$/g)[0]; - nameIndex[key] = nameIndex[key] | 0; - init_name = item.name.replace(/^(.*)\[\]$/, '$1['+ (nameIndex[key]++) +']'); - } - - if(/^(checkbox|radio)$/.test(item.type) && !item.checked) return; // 复选框和单选框未选中,不记录字段 - field[init_name || item.name] = item.value; - }); - - return field; - }; - - // 表单控件渲染 - Form.prototype.render = function(type, filter){ - var that = this; - var options = that.config; - var elemForm = $(ELEM + function(){ - return filter ? ('[lay-filter="' + filter +'"]') : ''; - }()); - var items = { - // 输入框 - input: function(elem){ - var inputs = elem || elemForm.find('input,textarea'); + // 全局设置 + Form.prototype.set = function (options) { + var that = this; + $.extend(true, that.config, options); + return that; + }; - // 初始化全局的 autocomplete - options.autocomplete && inputs.attr('autocomplete', options.autocomplete); + // 验证规则设定 + Form.prototype.verify = function (settings) { + var that = this; + $.extend(true, that.config.verify, settings); + return that; + }; - // 初始化输入框动态点缀 - elemForm.find('input[lay-affix],textarea[lay-affix]').each(function(){ - var othis = $(this); - var affix = othis.attr('lay-affix'); - var CLASS_WRAP = 'layui-input-wrap'; - var CLASS_SUFFIX = 'layui-input-suffix'; - var CLASS_AFFIX = 'layui-input-affix'; - var disabled = othis.is('[disabled]') || othis.is('[readonly]'); + // 获取指定表单对象 + Form.prototype.getFormElem = function (filter) { + return $(ELEM + function () { + return filter ? ('[lay-filter="' + filter + '"]') : ''; + }()); + }; - // 根据是否空值来显示或隐藏元素 - var showAffix = function(elem, value){ - elem = $(elem); - if(!elem[0]) return; - elem[$.trim(value) ? 'removeClass' : 'addClass'](HIDE); - }; + // 表单事件 + Form.prototype.on = function (events, callback) { + return layui.onevent.call(this, MOD_NAME, events, callback); + }; - // 渲染动态点缀内容 - var renderAffix = function(opts){ - opts = $.extend({}, (affixOptions[affix] || { - value: affix - }), opts, lay.options(othis[0])); - var elemAffix = $('
        '); - var value = layui.isArray(opts.value) ? opts.value : [opts.value]; - var elemIcon = $(function(){ - var arr = []; - layui.each(value, function(i, item){ - arr.push(''); - }); - return arr.join(''); - }()); - - elemAffix.append(elemIcon); // 插入图标元素 + // 赋值/取值 + Form.prototype.val = function (filter, object) { + var that = this + , formElem = that.getFormElem(filter); - // 追加 className - if(opts.split) elemAffix.addClass('layui-input-split'); - if(opts.className) elemAffix.addClass(opts.className); + // 遍历 + formElem.each(function (index, item) { + var itemForm = $(this); - // 移除旧的元素 - var hasElemAffix = othis.next('.'+ CLASS_AFFIX); - if(hasElemAffix[0]) hasElemAffix.remove(); + // 赋值 + layui.each(object, function (key, value) { + var itemElem = itemForm.find('[name="' + key + '"]') + , type; - // 是否在规定的容器中 - if(!othis.parent().hasClass(CLASS_WRAP)){ - othis.wrap('
        '); + // 如果对应的表单不存在,则不执行 + if (!itemElem[0]) return; + type = itemElem[0].type; + + // 如果为复选框 + if (type === 'checkbox') { + itemElem[0].checked = value; + } else if (type === 'radio') { // 如果为单选框 + itemElem.each(function () { + this.checked = this.value == value + ''; + }); + } else { // 其它类型的表单 + itemElem.val(value); + } + }); + }); + + form.render(null, filter); + + // 返回值 + return that.getValue(filter); + }; + + // 取值 + Form.prototype.getValue = function (filter, itemForm) { + itemForm = itemForm || this.getFormElem(filter); + + var nameIndex = {} // 数组 name 索引 + , field = {} + , fieldElem = itemForm.find('input,select,textarea') // 获取所有表单域 + + layui.each(fieldElem, function (_, item) { + var othis = $(this) + , init_name; // 初始 name + + item.name = (item.name || '').replace(/^\s*|\s*&/, ''); + if (!item.name) return; + + // 用于支持数组 name + if (/^.*\[\]$/.test(item.name)) { + var key = item.name.match(/^(.*)\[\]$/g)[0]; + nameIndex[key] = nameIndex[key] | 0; + init_name = item.name.replace(/^(.*)\[\]$/, '$1[' + (nameIndex[key]++) + ']'); } - // 是否已经存在后缀元素 - var hasElemSuffix = othis.next('.'+ CLASS_SUFFIX); - if(hasElemSuffix[0]){ - hasElemAffix = hasElemSuffix.find('.'+ CLASS_AFFIX); - if(hasElemAffix[0]) hasElemAffix.remove(); + if (/^(checkbox|radio)$/.test(item.type) && !item.checked) return; // 复选框和单选框未选中,不记录字段 + field[init_name || item.name] = item.value; + }); - hasElemSuffix.prepend(elemAffix); + return field; + }; - othis.css('padding-right', function(){ - var paddingRight = othis.closest('.layui-input-group')[0] - ? 0 - : hasElemSuffix.outerWidth(); - return paddingRight + elemAffix.outerWidth() - }); - } else { - elemAffix.addClass(CLASS_SUFFIX); - othis.after(elemAffix); - } + // 表单控件渲染 + Form.prototype.render = function (type, filter) { + var that = this; + var options = that.config; + var elemForm = $(ELEM + function () { + return filter ? ('[lay-filter="' + filter + '"]') : ''; + }()); + var items = { + // 输入框 + input: function (elem) { + var inputs = elem || elemForm.find('input,textarea'); - opts.show === 'auto' && showAffix(elemAffix, othis.val()); - - // 输入事件 - othis.on('input propertychange', function(){ - var value = this.value; - opts.show === 'auto' && showAffix(elemAffix, value); - }); - - // 点击动态后缀事件 - elemIcon.on('click', function(){ - var inputFilter = othis.attr('lay-filter'); - if($(this).hasClass(DISABLED)) return; - - typeof opts.click === 'function' && opts.click.call(this, othis, opts); - - // 对外事件 - layui.event.call(this, MOD_NAME, 'input-affix('+ inputFilter +')', { - elem: othis[0], - affix: affix, - options: opts - }); - }); - }; - - // 动态点缀配置项 - var affixOptions = { - eye: { // 密码显隐 - value: 'eye-invisible', - click: function(elem, opts){ // 事件 - var SHOW_NAME = 'LAY_FORM_INPUT_AFFIX_SHOW'; - var isShow = elem.data(SHOW_NAME); - - elem.attr('type', isShow ? 'password' : 'text').data(SHOW_NAME, !isShow); + // 初始化全局的 autocomplete + options.autocomplete && inputs.attr('autocomplete', options.autocomplete); - renderAffix({ - value: isShow ? 'eye-invisible' : 'eye' + var handleInputNumber = function (elem, eventType) { + var that = this; + var rawValue = elem.val(); + var value = Number(rawValue); + var step = Number(elem.attr('step')) || 1; // 加减的数字间隔 + var min = Number(elem.attr('min')); + var max = Number(elem.attr('max')); + var precision = Number(elem.attr('lay-precision')); + var noAction = eventType !== 'click' && rawValue === ''; // 初始渲染和失焦时空值不作处理 + var isInit = eventType === 'init'; + + if (isNaN(value)) return; // 若非数字,则不作处理 + + if (eventType === 'click') { + var isDecrement = !!$(that).index() // 0: icon-up, 1: icon-down + value = isDecrement ? value - step : value + step; + } + + // 获取小数点后位数 + var decimals = function (step) { + var decimals = (step.toString().match(/\.(\d+$)/) || [])[1] || ''; + return decimals.length; + }; + + precision = precision >= 0 ? precision : Math.max(decimals(step), decimals(rawValue)); + + // 赋值 + if (!noAction) { + // 初始渲染时只处理数字精度 + if (!isInit) { + if (value <= min) value = min; + if (value >= max) value = max; + } + // 若 `lay-precision` 为 0, 则表示只保留整数 + if (precision === 0) { + value = parseInt(value); + } else if (precision > 0) { // 小数位精度 + value = value.toFixed(precision); + } + elem.val(value); + } + + // 超出范围的样式 + var outOfRange = value < min || value > max; + elem[outOfRange && !noAction ? 'addClass' : 'removeClass'](OUT_OF_RANGE); + + if (isInit) return; + + // 更新按钮状态 + var controlBtn = { + increment: elem.next().find('.layui-icon-up'), + decrement: elem.next().find('.layui-icon-down') + } + controlBtn.increment[(value >= max && !noAction) ? 'addClass' : 'removeClass'](DISABLED) + controlBtn.decrement[(value <= min && !noAction) ? 'addClass' : 'removeClass'](DISABLED) + } + + // 初始化输入框动态点缀 + elemForm.find('input[lay-affix],textarea[lay-affix]').each(function () { + var othis = $(this); + var affix = othis.attr('lay-affix'); + var CLASS_WRAP = 'layui-input-wrap'; + var CLASS_SUFFIX = 'layui-input-suffix'; + var CLASS_AFFIX = 'layui-input-affix'; + var disabled = othis.is('[disabled]') || othis.is('[readonly]'); + + // 根据是否空值来显示或隐藏元素 + var showAffix = function (elem, value) { + elem = $(elem); + if (!elem[0]) return; + elem[$.trim(value) ? 'removeClass' : 'addClass'](HIDE); + }; + + // 渲染动态点缀内容 + var renderAffix = function (opts) { + opts = $.extend({}, (affixOptions[affix] || { + value: affix + }), opts, lay.options(othis[0])); + var elemAffix = $('
        '); + var value = layui.isArray(opts.value) ? opts.value : [opts.value]; + var elemIcon = $(function () { + var arr = []; + layui.each(value, function (i, item) { + arr.push(''); + }); + return arr.join(''); + }()); + + elemAffix.append(elemIcon); // 插入图标元素 + + // 追加 className + if (opts.split) elemAffix.addClass('layui-input-split'); + if (opts.className) elemAffix.addClass(opts.className); + + // 移除旧的元素 + var hasElemAffix = othis.next('.' + CLASS_AFFIX); + if (hasElemAffix[0]) hasElemAffix.remove(); + + // 是否在规定的容器中 + if (!othis.parent().hasClass(CLASS_WRAP)) { + othis.wrap('
        '); + } + + // 是否已经存在后缀元素 + var hasElemSuffix = othis.next('.' + CLASS_SUFFIX); + if (hasElemSuffix[0]) { + hasElemAffix = hasElemSuffix.find('.' + CLASS_AFFIX); + if (hasElemAffix[0]) hasElemAffix.remove(); + + hasElemSuffix.prepend(elemAffix); + + othis.css('padding-right', function () { + var paddingRight = othis.closest('.layui-input-group')[0] + ? 0 + : hasElemSuffix.outerWidth(); + return paddingRight + elemAffix.outerWidth() + }); + } else { + elemAffix.addClass(CLASS_SUFFIX); + othis.after(elemAffix); + } + + opts.show === 'auto' && showAffix(elemAffix, othis.val()); + + typeof opts.init === 'function' && opts.init.call(this, othis, opts); + + // 输入事件 + othis.on('input propertychange', function () { + var value = this.value; + opts.show === 'auto' && showAffix(elemAffix, value); + }); + + // 失去焦点事件 + othis.on('blur', function () { + typeof opts.blur === 'function' && opts.blur.call(this, othis, opts); + }); + + // 点击动态后缀事件 + elemIcon.on('click', function () { + var inputFilter = othis.attr('lay-filter'); + if ($(this).hasClass(DISABLED)) return; + + typeof opts.click === 'function' && opts.click.call(this, othis, opts); + + // 对外事件 + layui.event.call(this, MOD_NAME, 'input-affix(' + inputFilter + ')', { + elem: othis[0], + affix: affix, + options: opts + }); + }); + }; + + // 动态点缀配置项 + var affixOptions = { + eye: { // 密码显隐 + value: 'eye-invisible', + click: function (elem, opts) { // 事件 + var SHOW_NAME = 'LAY_FORM_INPUT_AFFIX_SHOW'; + var isShow = elem.data(SHOW_NAME); + + elem.attr('type', isShow ? 'password' : 'text').data(SHOW_NAME, !isShow); + + renderAffix({ + value: isShow ? 'eye-invisible' : 'eye' + }); + } + }, + clear: { // 内容清除 + value: 'clear', + click: function (elem) { + elem.val('').focus(); + showAffix($(this).parent(), null); + }, + show: 'auto', // 根据输入框值是否存在来显示或隐藏点缀图标 + disabled: disabled // 跟随输入框禁用状态 + }, + number: { // 数字输入框 + value: ['up', 'down'], + split: true, + className: 'layui-input-number', + disabled: othis.is('[disabled]'), // 跟随输入框禁用状态 + init: function (elem) { + handleInputNumber.call(this, elem, 'init') + }, + click: function (elem) { + handleInputNumber.call(this, elem, 'click') + }, + blur: function (elem) { + handleInputNumber.call(this, elem, 'blur') + }, + } + }; + + renderAffix(); }); - } - }, - clear: { // 内容清除 - value: 'clear', - click: function(elem){ - elem.val('').focus(); - showAffix($(this).parent(), null); - }, - show: 'auto', // 根据输入框值是否存在来显示或隐藏点缀图标 - disabled: disabled // 跟随输入框禁用状态 - }, - number: { // 数字输入框 - value: ['up', 'down'], - split: true, - className: 'layui-input-number', - disabled: othis.is('[disabled]'), // 跟随输入框禁用状态 - click: function(elem){ - var index = $(this).index(); - var value = elem.val(); - var rawValue = value; - var step = Number(elem.attr('step')) || 1; // 加减的数字间隔 - var min = Number(elem.attr('min')); - var max = Number(elem.attr('max')); + } - if(isNaN(value)) return; // 若非数字,则不作处理 + // 下拉选择框 + , select: function (elem) { + var TIPS = '请选择'; + var CLASS = 'layui-form-select'; + var TITLE = 'layui-select-title'; + var NONE = 'layui-select-none'; + var CREATE_OPTION = 'layui-select-create-option'; + var PANEL_WRAP = 'layui-select-panel-wrap' + var PANEL_ELEM_DATA = 'layui-select-panel-elem-data'; + var selects = elem || elemForm.find('select'); - value = Number(value); - value = index ? value - step : value + step; + // 各种事件 + var events = function (reElem, titleElem, disabled, isSearch, isCreatable, isAppendTo) { + var select = $(this); + var title = titleElem; + var input = title.find('input'); + var dl = reElem.find('dl'); + var dds = dl.children('dd'); + var dts = dl.children('dt'); // select 分组dt元素 + var index = this.selectedIndex; // 当前选中的索引 + var initValue = ''; + var removeClickOutsideEvent; - // min max - if(value < min) value = min; - if(value > max) value = max; + if (disabled) return; - // 获取小数点后位数 - var decimals = function(step){ - var decimals = (step.toString().match(/\.(\d+$)/) || [])[1] || ''; - return decimals.length; + /** + * 搜索项 + * @typedef searchOption + * @prop {boolean} [caseSensitive=false] 是否区分大小写 + * @prop {boolean} [fuzzy=false] 是否开启模糊匹配,开启后将会忽略模式出现在字符串中的位置。 + */ + /** @type {searchOption} */ + var laySearch = select.attr('lay-search') === 'cs' ? { caseSensitive: true } : lay.options(select, { attr: 'lay-search' }); + // 目前只支持 body + var appendTarget = select.attr('lay-append-to') || 'body'; + var appendPosition = select.attr('lay-append-position'); + + // #1449 + // IE10 和 11 中,带有占位符的 input 元素获得/失去焦点时,会触发 input 事件 + // 当鼠标按下时,根据 input 元素上的 __ieph 标识忽略 input 事件 + var needPlaceholderPatch = !!(lay.ie && (lay.ie === '10' || lay.ie === '11') && input.attr('placeholder')); + + // 展开下拉 + var showDown = function () { + if (isAppendTo) { + // 如果追加面板元素后出现滚动条,触发元素宽度可能会有变化,所以先追加面板元素 + reElem.appendTo(appendTarget).css({ width: title.width() + 'px' }); + + var updatePosition = function () { + lay.position(title[0], reElem[0], { + position: appendPosition, + allowBottomOut: true, + offset: [0, 5] + }); + } + + updatePosition(); + $(window).on('resize.lay_select_resize', updatePosition); + } + var top = reElem.offset().top + reElem.outerHeight() + 5 - $win.scrollTop(); + var dlHeight = dl.outerHeight(); + var dds = dl.children('dd'); + + index = select[0].selectedIndex; // 获取最新的 selectedIndex + title.parent().addClass(CLASS + 'ed'); + dds.removeClass(HIDE); + dts.removeClass(HIDE); + + // 初始选中样式 + dds.removeClass(THIS); + index >= 0 && dds.eq(index).addClass(THIS); + + // 上下定位识别 + if (top + dlHeight > $win.height() && top >= dlHeight) { + reElem.addClass(CLASS + 'up'); + } + + followScroll(); + + if (needPlaceholderPatch) { + dl.off('mousedown.lay_select_ieph').on('mousedown.lay_select_ieph', function () { + input[0].__ieph = true; + setTimeout(function () { + input[0].__ieph = false; + }, 60) + }); + } + + removeClickOutsideEvent = lay.onClickOutside( + isAppendTo ? reElem[0] : dl[0], + function () { + hideDown(); + initValue && input.val(initValue); + }, + { ignore: title } + ); + }; + + // 隐藏下拉 + var hideDown = function (choose) { + title.parent().removeClass(CLASS + 'ed ' + CLASS + 'up'); + input.blur(); + isCreatable && dl.children('.' + CREATE_OPTION).remove(); + removeClickOutsideEvent && removeClickOutsideEvent(); + if (isAppendTo) { + reElem.detach(); + $(window).off('resize.lay_select_resize'); + } + + if (choose) return; + + notOption(input.val(), function (none) { + var selectedIndex = select[0].selectedIndex; + + // 未查询到相关值 + if (none) { + initValue = $(select[0].options[selectedIndex]).html(); // 重新获得初始选中值 + + // 如果是第一项,且文本值等于 placeholder,则清空初始值 + if (selectedIndex === 0 && initValue === input.attr('placeholder')) { + initValue = ''; + } + + // 如果有选中值,则将输入框纠正为该值。否则清空输入框 + input.val(initValue || ''); + } + }); + }; + + // 定位下拉滚动条 + var followScroll = function () { + var thisDd = dl.children('dd.' + THIS); + + if (!thisDd[0]) return; + + var posTop = thisDd.position().top; + var dlHeight = dl.height(); + var ddHeight = thisDd.height(); + + // 若选中元素在滚动条不可见底部 + if (posTop > dlHeight) { + dl.scrollTop(posTop + dl.scrollTop() - dlHeight + ddHeight - 5); + } + + // 若选择元素在滚动条不可见顶部 + if (posTop < 0) { + dl.scrollTop(posTop + dl.scrollTop() - 5); + } + }; + + // 点击标题区域 + title.on('click', function (e) { + title.parent().hasClass(CLASS + 'ed') ? ( + hideDown() + ) : ( + showDown() + ); + dl.find('.' + NONE).remove(); + }); + + // 点击箭头获取焦点 + title.find('.layui-edge').on('click', function () { + input.focus(); + }); + + // select 中 input 键盘事件 + input.on('keyup', function (e) { // 键盘松开 + var keyCode = e.keyCode; + + // Tab键展开 + if (keyCode === 9) { + showDown(); + } + }).on('keydown', function (e) { // 键盘按下 + var keyCode = e.keyCode; + + // Tab键隐藏 + if (keyCode === 9) { + hideDown(); + } + + // 标注 dd 的选中状态 + var setThisDd = function (prevNext) { + e.preventDefault(); + var allDisplayedElem = dl.children('dd:not(.' + HIDE + ',.' + DISABLED + ')'); + if (!allDisplayedElem.length) return; + var firstIndex = 0; + var lastIndex = allDisplayedElem.length - 1; + var selectedIndex = -1; + + layui.each(allDisplayedElem, function (index, el) { + if ($(el).hasClass(THIS)) { + selectedIndex = index; + return true; + } + }) + + var nextIndex = prevNext === 'prev' + ? (selectedIndex - 1 < firstIndex ? lastIndex : selectedIndex - 1) + : (selectedIndex + 1 > lastIndex ? firstIndex : selectedIndex + 1) + + var selectedElem = allDisplayedElem.eq(nextIndex); + selectedElem.addClass(THIS).siblings().removeClass(THIS); // 标注样式 + followScroll(); // 定位滚动条 + }; + + if (keyCode === 38) setThisDd('prev'); // Up 键 + if (keyCode === 40) setThisDd('next'); // Down 键 + + // Enter 键 + if (keyCode === 13) { + e.preventDefault(); + dl.children('dd.' + THIS).trigger('click'); + } + }).on('paste', function () { + showDown(); + }); + + // 检测值是否不属于 select 项 + var notOption = function (value, callback, origin) { + var num = 0; + var dds = dl.children('dd'); + var hasEquals = false; + var rawValue = value; + var fuzzyMatchRE; + if (!laySearch.caseSensitive) { + value = value.toLowerCase(); + } + if (laySearch.fuzzy) { + fuzzyMatchRE = fuzzyMatchRegExp(value, laySearch.caseSensitive); + } + layui.each(dds, function () { + var othis = $(this); + var text = othis.text(); + var isCreateOption = isCreatable && othis.hasClass(CREATE_OPTION); + + // 需要区分大小写 + if (isCreatable && !isCreateOption && text === rawValue) { + hasEquals = true; + } + + // 是否区分大小写 + if (!laySearch.caseSensitive) { + text = text.toLowerCase(); + } + + // 匹配 + var not = laySearch.fuzzy ? !fuzzyMatchRE.test(text) : text.indexOf(value) === -1; + + if (value === '' || (origin === 'blur') ? value !== text : not) num++; + origin === 'keyup' && othis[(isCreatable ? (not && !isCreateOption) : not) ? 'addClass' : 'removeClass'](HIDE); + }); + // 处理 select 分组元素 + origin === 'keyup' && layui.each(dts, function () { + var othis = $(this); + var thisDds = othis.nextUntil('dt').filter('dd'); // 当前分组下的dd元素 + if (isCreatable) thisDds = thisDds.not('.' + CREATE_OPTION); + var allHide = thisDds.length == thisDds.filter('.' + HIDE).length; // 当前分组下所有dd元素都隐藏了 + othis[allHide ? 'addClass' : 'removeClass'](HIDE); + }); + var none = num === dds.length; + return callback(none, hasEquals), none; + }; + + // 搜索匹配 + var search = function (e) { + var value = this.value, keyCode = e.keyCode; + + if (keyCode === 9 || keyCode === 13 + || keyCode === 37 || keyCode === 38 + || keyCode === 39 || keyCode === 40 + ) { + return false; + } + + if (needPlaceholderPatch && e.target.__ieph) { + e.target.__ieph = false; + return false; + } + + notOption(value, function (none, hasEquals) { + if (isCreatable) { + if (hasEquals) { + dl.children('.' + CREATE_OPTION).remove(); + } else { + var createOptionElem = dl.children('.' + CREATE_OPTION); + if (createOptionElem[0]) { + createOptionElem.attr('lay-value', value).html(util.escape(value)); + } else { + // 临时显示在顶部 + var ddElem = $('
        ').addClass(CREATE_OPTION).attr('lay-value', value).html(util.escape(value)); + var firstOptionELem = dl.children().eq(0); + var hasTips = firstOptionELem.hasClass('layui-select-tips'); + firstOptionELem[hasTips ? 'after' : 'before'](ddElem); + } + } + } else { + if (none) { + dl.find('.' + NONE)[0] || dl.append('

        无匹配项

        '); + } else { + dl.find('.' + NONE).remove(); + } + } + }, 'keyup'); + + // 当搜索值清空时 + if (value === '') { + // 取消选中项 + select.val(''); + dl.find('.' + THIS).removeClass(THIS); + (select[0].options[0] || {}).value || dl.children('dd:eq(0)').addClass(THIS); + dl.find('.' + NONE).remove(); + isCreatable && dl.children('.' + CREATE_OPTION).remove(); + } + + followScroll(); // 定位滚动条 + }; + + if (isSearch) { + input.on('input propertychange', layui.debounce(search, 50)).on('blur', function (e) { + var selectedIndex = select[0].selectedIndex; + + initValue = $(select[0].options[selectedIndex]).text(); // 重新获得初始选中值 + + // 如果是第一项,且文本值等于 placeholder,则清空初始值 + if (selectedIndex === 0 && initValue === input.attr('placeholder')) { + initValue = ''; + } + + setTimeout(function () { + notOption(input.val(), function (none) { + initValue || input.val(''); // none && !initValue + }, 'blur'); + }, 200); + }); + } + + // 选择 + dl.on('click', 'dd', function () { + var othis = $(this), value = othis.attr('lay-value'); + var filter = select.attr('lay-filter'); // 获取过滤器 + + if (othis.hasClass(DISABLED)) return false; + + if (othis.hasClass('layui-select-tips')) { + input.val(''); + } else { + input.val(othis.text()); + othis.addClass(THIS); + } + + // 将新增的 option 元素添加到末尾 + if (isCreatable && othis.hasClass(CREATE_OPTION)) { + dl.append(othis.removeClass(CREATE_OPTION)); + var optionElem = $('
        ' @@ -393,7 +401,22 @@ Class.pt.creat = function(){ var content = config.content; var conType = typeof content === 'object'; var body = $('body'); - + + var setAnim = function(layero){ + // anim 兼容旧版 shift + if(config.shift){ + config.anim = config.shift; + } + + // 为兼容 jQuery3.0 的 css 动画影响元素尺寸计算 + if(doms.anim[config.anim]){ + var animClass = 'layer-anim '+ doms.anim[config.anim]; + layero.addClass(animClass).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){ + $(this).removeClass(animClass); + }); + } + } + // 若 id 对应的弹层已经存在,则不重新创建 if(config.id && $('.'+ doms[0]).find('#'+ config.id)[0]){ return (function(){ @@ -409,12 +432,16 @@ Class.pt.creat = function(){ } else if(options.hideOnClose){ elemShade.show(); layero.show(); + setAnim(layero); + setTimeout(function(){ + elemShade.css({opacity: elemShade.data(SHADE_KEY)}); + }, 10); } })(); } // 是否移除活动元素的焦点 - if(config.removeFocus) { + if(config.removeFocus && document.activeElement) { document.activeElement.blur(); // 将原始的聚焦节点失焦 } @@ -423,11 +450,6 @@ Class.pt.creat = function(){ config.area = config.area === 'auto' ? ['', ''] : [config.area, '']; } - // anim 兼容旧版 shift - if(config.shift){ - config.anim = config.shift; - } - if(layer.ie == 6){ config.fixed = false; } @@ -475,14 +497,16 @@ Class.pt.creat = function(){ that.layero = $('#'+ doms[0] + times); that.shadeo = $('#'+ doms.SHADE + times); - config.scrollbar || doms.html.css('overflow', 'hidden').attr('layer-full', times); + config.scrollbar || ready.setScrollbar(times); }).auto(times); // 遮罩 that.shadeo.css({ 'background-color': config.shade[1] || '#000' ,'opacity': config.shade[0] || config.shade + ,'transition': config.shade[2] || '' }); + that.shadeo.data(SHADE_KEY, config.shade[0] || config.shade); config.type == 2 && layer.ie == 6 && that.layero.find('iframe').attr('src', content[0]); @@ -514,14 +538,7 @@ Class.pt.creat = function(){ layer.close(that.index); }, config.time); that.move().callback(); - - // 为兼容 jQuery3.0 的 css 动画影响元素尺寸计算 - if(doms.anim[config.anim]){ - var animClass = 'layer-anim '+ doms.anim[config.anim]; - that.layero.addClass(animClass).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){ - $(this).removeClass(animClass); - }); - } + setAnim(that.layero); // 记录配置信息 that.layero.data('config', config); @@ -667,13 +684,15 @@ Class.pt.tips = function(){ }; // 辨别 tips 的方位 + // 21 为箭头大小 8*2 + 箭头相对父元素的top偏移 5 goal.where = [function(){ // 上 goal.autoLeft(); goal.tipTop = goal.top - layArea[1] - 10; tipsG.removeClass('layui-layer-TipsB').addClass('layui-layer-TipsT').css('border-right-color', config.tips[1]); }, function(){ // 右 goal.tipLeft = goal.left + goal.width + 10; - goal.tipTop = goal.top; + goal.tipTop = goal.top - (goal.height * 0.75 < 21 ? 21 - goal.height * 0.5 : 0); + goal.tipTop = Math.max(goal.tipTop, 0); tipsG.removeClass('layui-layer-TipsL').addClass('layui-layer-TipsR').css('border-bottom-color', config.tips[1]); }, function(){ // 下 goal.autoLeft(); @@ -681,7 +700,8 @@ Class.pt.tips = function(){ tipsG.removeClass('layui-layer-TipsT').addClass('layui-layer-TipsB').css('border-right-color', config.tips[1]); }, function(){ // 左 goal.tipLeft = goal.left - layArea[0] - 10; - goal.tipTop = goal.top; + goal.tipTop = goal.top - (goal.height * 0.75 < 21 ? 21 - goal.height * 0.5 : 0); + goal.tipTop = Math.max(goal.tipTop, 0); tipsG.removeClass('layui-layer-TipsR').addClass('layui-layer-TipsL').css('border-bottom-color', config.tips[1]); }]; goal.where[guide-1](); @@ -839,6 +859,16 @@ Class.pt.move = function(){ return that; }; +Class.pt.btnLoading = function(btnElem, isLoading){ + if(isLoading){ + var loadingTpl = ''; + if(btnElem.find('.layui-layer-btn-loading-icon')[0]) return; + btnElem.addClass('layui-layer-btn-is-loading').attr({disabled: ''}).prepend(loadingTpl); + }else{ + btnElem.removeClass('layui-layer-btn-is-loading').removeAttr('disabled').find('.layui-layer-btn-loading-icon').remove(); + } +} + Class.pt.callback = function(){ var that = this, layero = that.layero, config = that.config; that.openLayer(); @@ -855,18 +885,42 @@ Class.pt.callback = function(){ // 按钮 layero.find('.'+ doms[6]).children('a').on('click', function(){ - var index = $(this).index(); - if(index === 0){ - if(config.yes){ - config.yes(that.index, layero, that); - } else if(config['btn1']){ - config['btn1'](that.index, layero, that); - } else { + var btnElem = $(this); + var index = btnElem.index(); + if(btnElem.attr('disabled')) return; + + // 若为异步按钮 + if(config.btnAsync){ + var btnCallback = index === 0 ? (config.yes || config['btn1']) : config['btn'+(index+1)]; + that.loading = function(isLoading){ + that.btnLoading(btnElem, isLoading); + } + + if(btnCallback){ + ready.promiseLikeResolve(btnCallback.call(config, that.index, layero, that)) + .then(function(result){ + if(result !== false){ + layer.close(that.index) + } + }, function(reason){ + reason !== undefined && window.console && window.console.error('layer error hint: ' + reason); + }); + }else{ layer.close(that.index); } - } else { - var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero, that); - close === false || layer.close(that.index); + } else { // 普通按钮 + if(index === 0){ + if(config.yes){ + config.yes(that.index, layero, that); + } else if(config['btn1']){ + config['btn1'](that.index, layero, that); + } else { + layer.close(that.index); + } + } else { + var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero, that); + close === false || layer.close(that.index); + } } }); @@ -906,6 +960,7 @@ Class.pt.callback = function(){ }); config.end && (ready.end[that.index] = config.end); + config.beforeEnd && (ready.beforeEnd[that.index] = $.proxy(config.beforeEnd, config, layero, that.index, that)); }; // for ie6 恢复 select @@ -950,27 +1005,47 @@ Class.pt.openLayer = function(){ // 记录宽高坐标,用于还原 ready.record = function(layero){ if(!layero[0]) return window.console && console.error('index error'); + var type = layero.attr('type'); + var contentElem = layero.find('.layui-layer-content'); + var contentRecordHeightElem = type === ready.type[2] ? contentElem.children('iframe') : contentElem; var area = [ - layero[0].style.width || layero.width(), - layero[0].style.height || layero.height(), + layero[0].style.width || ready.getStyle(layero[0], 'width'), + layero[0].style.height || ready.getStyle(layero[0], 'height'), layero.position().top, layero.position().left + parseFloat(layero.css('margin-left')) ]; layero.find('.layui-layer-max').addClass('layui-layer-maxmin'); layero.attr({area: area}); + contentElem.data(RECORD_HEIGHT_KEY, ready.getStyle(contentRecordHeightElem[0], 'height')); }; -ready.rescollbar = function(index){ +// 设置页面滚动条 +ready.setScrollbar = function(index){ + doms.html.css('overflow', 'hidden').attr('layer-full', index); +}; + +// 恢复页面滚动条 +ready.restScrollbar = function(index){ if(doms.html.attr('layer-full') == index){ - if(doms.html[0].style.removeProperty){ - doms.html[0].style.removeProperty('overflow'); - } else { - doms.html[0].style.removeAttribute('overflow'); - } + doms.html[0].style[doms.html[0].style.removeProperty + ? 'removeProperty' + : 'removeAttribute']('overflow'); doms.html.removeAttr('layer-full'); } }; +// 类似 Promise.resolve +ready.promiseLikeResolve = function(value){ + var deferred = $.Deferred(); + + if(value && typeof value.then === 'function'){ + value.then(deferred.resolve, deferred.reject); + }else{ + deferred.resolve(value); + } + return deferred.promise(); +} + /** 内置成员 */ window.layer = layer; @@ -1005,7 +1080,7 @@ layer.iframeSrc = function(index, url){ // 设定层的样式 layer.style = function(index, options, limit){ var layero = $('#'+ doms[0] + index); - var contElem = layero.find('.layui-layer-content'); + var contentElem = layero.find('.layui-layer-content'); var type = layero.attr('type'); var titHeight = layero.find(doms[1]).outerHeight() || 0; var btnHeight = layero.find('.'+doms[6]).outerHeight() || 0; @@ -1033,10 +1108,10 @@ layer.style = function(index, options, limit){ height: (typeof options.height === 'number' ? options.height : layero.height()) - titHeight - btnHeight }); } else { - contElem.css({ + contentElem.css({ height: (typeof options.height === 'number' ? options.height : layero.height()) - titHeight - btnHeight - - parseFloat(contElem.css('padding-top')) - - parseFloat(contElem.css('padding-bottom')) + - parseFloat(contentElem.css('padding-top')) + - parseFloat(contentElem.css('padding-bottom')) }) } }; @@ -1097,7 +1172,7 @@ layer.min = function(index, options){ elemMin.hide(); layero.attr('type') === 'page' && layero.find(doms[4]).hide(); - ready.rescollbar(index); + ready.restScrollbar(index); // 隐藏遮罩 shadeo.hide(); @@ -1107,8 +1182,11 @@ layer.min = function(index, options){ layer.restore = function(index){ var layero = $('#'+ doms[0] + index); var shadeo = $('#'+ doms.SHADE + index); + var contentElem = layero.find('.layui-layer-content'); var area = layero.attr('area').split(','); var type = layero.attr('type'); + var options = layero.data('config') || {}; + var contentRecordHeight = contentElem.data(RECORD_HEIGHT_KEY); layero.removeData('maxminStatus'); // 移除最大最小状态 @@ -1125,7 +1203,16 @@ layer.restore = function(index){ layero.find('.layui-layer-max').removeClass('layui-layer-maxmin'); layero.find('.layui-layer-min').show(); type === 'page' && layero.find(doms[4]).show(); - ready.rescollbar(index); + + // 恢复页面滚动条弹层打开时的状态 + options.scrollbar ? ready.restScrollbar(index) : ready.setScrollbar(index); + + // #1604 + if(contentRecordHeight !== undefined){ + contentElem.removeData(RECORD_HEIGHT_KEY); + var contentRecordHeightElem = type === ready.type[2] ? contentElem.children('iframe') : contentElem; + contentRecordHeightElem.css({height: contentRecordHeight}); + } // 恢复遮罩 shadeo.show(); @@ -1144,7 +1231,7 @@ layer.full = function(index){ ready.record(layero); // 记录当前尺寸、坐标 if(!doms.html.attr('layer-full')){ - doms.html.css('overflow','hidden').attr('layer-full', index); + ready.setScrollbar(index); } setTimeout(function(){ @@ -1168,10 +1255,10 @@ layer.title = function(name, index){ // 关闭 layer 总方法 layer.close = function(index, callback){ var layero = function(){ - var closest = $('.'+ doms[0]).find('#'+ index).closest('.'+ doms[0]); + var closest = $('.'+ doms[0]).children('#'+ index).closest('.'+ doms[0]); return closest[0] ? ( - index = closest.attr('times') - ,closest + index = closest.attr('times'), + closest ) : $('#'+ doms[0] + index) }(); var type = layero.attr('type'); @@ -1180,83 +1267,104 @@ layer.close = function(index, callback){ if(!layero[0]) return; - // 关闭动画 - var closeAnim = ({ - slideDown: 'layer-anim-slide-down-out', - slideLeft: 'layer-anim-slide-left-out', - slideUp: 'layer-anim-slide-up-out', - slideRight: 'layer-anim-slide-right-out' - })[options.anim] || 'layer-anim-close'; - - // 移除主容器 - var remove = function(){ - var WRAP = 'layui-layer-wrap'; - - // 是否关闭时隐藏弹层容器 - if(hideOnClose){ - layero.removeClass('layer-anim '+ closeAnim); - return layero.hide(); - } - - // 是否为页面捕获层 - if(type === ready.type[1] && layero.attr('conType') === 'object'){ - layero.children(':not(.'+ doms[5] +')').remove(); - var wrap = layero.find('.'+WRAP); - for(var i = 0; i < 2; i++){ - wrap.unwrap(); + var executor = function(){ + // 关闭动画 + var closeAnim = ({ + slideDown: 'layer-anim-slide-down-out', + slideLeft: 'layer-anim-slide-left-out', + slideUp: 'layer-anim-slide-up-out', + slideRight: 'layer-anim-slide-right-out' + })[options.anim] || 'layer-anim-close'; + + // 移除主容器 + var remove = function(){ + var WRAP = 'layui-layer-wrap'; + + // 是否关闭时隐藏弹层容器 + if(hideOnClose){ + layero.removeClass('layer-anim '+ closeAnim); + return layero.hide(); } - wrap.css('display', wrap.data('display')).removeClass(WRAP); + + // 是否为页面捕获层 + if(type === ready.type[1] && layero.attr('conType') === 'object'){ + layero.children(':not(.'+ doms[5] +')').remove(); + var wrap = layero.find('.'+WRAP); + for(var i = 0; i < 2; i++){ + wrap.unwrap(); + } + wrap.css('display', wrap.data('display')).removeClass(WRAP); + } else { + // 低版本 IE 回收 iframe + if(type === ready.type[2]){ + try { + var iframe = $('#'+ doms[4] + index)[0]; + iframe.contentWindow.document.write(''); + iframe.contentWindow.close(); + layero.find('.'+doms[5])[0].removeChild(iframe); + } catch(e){} + } + layero[0].innerHTML = ''; + layero.remove(); + } + + typeof ready.end[index] === 'function' && ready.end[index](); + delete ready.end[index]; + typeof callback === 'function' && callback(); + + // 移除 reisze 事件 + if(ready.events.resize[index]){ + win.off('resize', ready.events.resize[index]); + delete ready.events.resize[index]; + } + }; + // 移除遮罩 + var shadeo = $('#'+ doms.SHADE + index); + if((layer.ie && layer.ie < 10) || !options.isOutAnim){ + shadeo[hideOnClose ? 'hide' : 'remove'](); + }else{ + shadeo.css({opacity: 0}); + setTimeout(function(){ + shadeo[hideOnClose ? 'hide' : 'remove'](); + }, 350); + } + + // 是否允许关闭动画 + if(options.isOutAnim){ + layero.addClass('layer-anim '+ closeAnim); + } + + layer.ie == 6 && ready.reselect(); + ready.restScrollbar(index); + + // 记住被关闭层的最小化堆叠坐标 + if(typeof layero.attr('minLeft') === 'string'){ + ready.minStackIndex--; + ready.minStackArr.push(layero.attr('minLeft')); + } + + if((layer.ie && layer.ie < 10) || !options.isOutAnim){ + remove() } else { - // 低版本 IE 回收 iframe - if(type === ready.type[2]){ - try { - var iframe = $('#'+ doms[4] + index)[0]; - iframe.contentWindow.document.write(''); - iframe.contentWindow.close(); - layero.find('.'+doms[5])[0].removeChild(iframe); - } catch(e){} - } - layero[0].innerHTML = ''; - layero.remove(); + setTimeout(function(){ + remove(); + }, 200); } - - typeof ready.end[index] === 'function' && ready.end[index](); - delete ready.end[index]; - typeof callback === 'function' && callback(); - - // 移除 reisze 事件 - if(ready.events.resize[index]){ - win.off('resize', ready.events.resize[index]); - delete ready.events.resize[index]; - } - }; - // 移除遮罩 - var removeShade = (function fn(){ - $('#'+ doms.SHADE + index)[ - hideOnClose ? 'hide' : 'remove' - ](); - })(); - - // 是否允许关闭动画 - if(options.isOutAnim){ - layero.addClass('layer-anim '+ closeAnim); } - - layer.ie == 6 && ready.reselect(); - ready.rescollbar(index); - - // 记住被关闭层的最小化堆叠坐标 - if(typeof layero.attr('minLeft') === 'string'){ - ready.minStackIndex--; - ready.minStackArr.push(layero.attr('minLeft')); - } - - if((layer.ie && layer.ie < 10) || !options.isOutAnim){ - remove() - } else { - setTimeout(function(){ - remove(); - }, 200); + + if(!hideOnClose && typeof ready.beforeEnd[index] === 'function'){ + ready.promiseLikeResolve(ready.beforeEnd[index]()) + .then(function(result){ + if(result !== false){ + delete ready.beforeEnd[index]; + executor(); + } + }, function(reason){ + reason !== undefined && window.console && window.console.error('layer error hint: ' + reason); + }); + }else{ + delete ready.beforeEnd[index]; + executor(); } }; @@ -1277,9 +1385,19 @@ layer.closeAll = function(type, callback){ }; // 根据弹层类型关闭最近打开的层 -layer.closeLast = function(type){ - type = type || 'page'; - layer.close($('.layui-layer-'+ type +':last').attr("times")); +layer.closeLast = function(type, callback){ + var layerIndexList = []; + var isArrayType = $.isArray(type); + $(typeof type === 'string' ? '.layui-layer-' + type : '.layui-layer').each(function(i, el){ + var layero = $(el); + var shouldSkip = (isArrayType && type.indexOf(layero.attr('type')) === -1) || layero.css('display') === 'none'; + if(shouldSkip) return true; + layerIndexList.push(Number(layero.attr('times'))); + }); + if(layerIndexList.length > 0){ + var layerIndexMax = Math.max.apply(null, layerIndexList); + layer.close(layerIndexMax, callback); + } }; @@ -1317,7 +1435,7 @@ layer.prompt = function(options, yes){ return layer.open($.extend({ type: 1, - btn: ['确定','取消'], + btn: ['确定','取消'], content: content, skin: 'layui-layer-prompt' + skin('prompt'), maxWidth: win.width(), @@ -1330,7 +1448,7 @@ layer.prompt = function(options, yes){ yes: function(index){ var value = prompt.val(); if(value.length > (options.maxlength||500)) { - layer.tips('最多输入'+ (options.maxlength || 500) +'个字数', prompt, {tips: 1}); + layer.tips('最多输入'+ (options.maxlength || 500) +'个字符', prompt, {tips: 1}); } else { yes && yes(value, index, prompt); } @@ -1342,9 +1460,9 @@ layer.prompt = function(options, yes){ layer.tab = function(options){ options = options || {}; - var tab = options.tab || {} - ,THIS = 'layui-this' - ,success = options.success; + var tab = options.tab || {}; + var THIS = 'layui-this'; + var success = options.success; delete options.success; @@ -1387,10 +1505,16 @@ layer.tab = function(options){ }, options)); }; -// 相册层 +// 图片层 layer.photos = function(options, loop, key){ var dict = {}; - options = options || {}; + + // 默认属性 + options = $.extend(true, { + toolbar: true, + footer: true + }, options); + if(!options.photos) return; // 若 photos 并非选择器或 jQuery 对象,则为普通 object @@ -1398,11 +1522,10 @@ layer.photos = function(options, loop, key){ var photos = isObject ? options.photos : {}; var data = photos.data || []; var start = photos.start || 0; + var success = options.success; dict.imgIndex = (start|0) + 1; options.img = options.img || 'img'; - - var success = options.success; delete options.success; // 若 options.photos 不是一个对象 @@ -1439,10 +1562,9 @@ layer.photos = function(options, loop, key){ }); // 不直接弹出 - if(!loop) return; - + if (!loop) return; } else if (data.length === 0){ - return layer.msg('没有图片'); + return layer.msg('没有图片'); } // 上一张 @@ -1486,28 +1608,128 @@ layer.photos = function(options, loop, key){ layer.close(dict.index); return layer.photos(options, true, key); } + + dict.isNumber = function (n) { + return typeof n === 'number' && !isNaN(n); + } + + dict.image = {}; + + dict.getTransform = function(opts){ + var transforms = []; + var rotate = opts.rotate; + var scaleX = opts.scaleX; + var scale = opts.scale; + + if (dict.isNumber(rotate) && rotate !== 0) { + transforms.push('rotate(' + rotate + 'deg)'); + } + + if (dict.isNumber(scaleX) && scaleX !== 1) { + transforms.push('scaleX(' + scaleX + ')'); + } + + if (dict.isNumber(scale)) { + transforms.push('scale(' + scale + ')'); + } + + return transforms.length ? transforms.join(' ') : 'none'; + } // 一些动作 - dict.event = function(){ - /* - dict.bigimg.hover(function(){ - dict.imgsee.show(); - }, function(){ - dict.imgsee.hide(); - }); - */ - - dict.bigimg.find('.layui-layer-imgprev').on('click', function(event){ + dict.event = function(layero, index, that){ + // 上一张 + dict.main.find('.layui-layer-photos-prev').on('click', function(event){ event.preventDefault(); dict.imgprev(true); }); - dict.bigimg.find('.layui-layer-imgnext').on('click', function(event){ + // 下一张 + dict.main.find('.layui-layer-photos-next').on('click', function(event){ event.preventDefault(); dict.imgnext(true); }); $(document).on('keyup', dict.keyup); + + // 头部工具栏事件 + layero.off('click').on('click','*[toolbar-event]', function () { + var othis = $(this); + var event = othis.attr('toolbar-event'); + switch (event) { + case 'rotate': + dict.image.rotate = ((dict.image.rotate || 0) + Number(othis.attr('data-option'))) % 360; + dict.imgElem.css({ + transform: dict.getTransform(dict.image) + }); + break; + case 'scalex': + dict.image.scaleX = dict.image.scaleX === -1 ? 1 : -1; + dict.imgElem.css({ + transform: dict.getTransform(dict.image) + }); + break; + case 'zoom': + var ratio = Number(othis.attr('data-option')); + dict.image.scale = (dict.image.scale || 1) + ratio; + // 缩小状态最小值 + if (ratio < 0 && dict.image.scale < 0 - ratio) { + dict.image.scale = 0 - ratio; + } + dict.imgElem.css({ + transform: dict.getTransform(dict.image) + }); + break; + case 'reset': + dict.image.scaleX = 1; + dict.image.scale = 1; + dict.image.rotate = 0; + dict.imgElem.css({ + transform: 'none' + }); + break; + case 'close': + layer.close(index); + break; + } + that.offset(); + that.auto(index); + }); + + // 鼠标滚轮缩放图片事件 + dict.main.on('mousewheel DOMMouseScroll', function(e) { + var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail; + var zoomElem = dict.main.find('[toolbar-event="zoom"]'); + if (delta > 0) { + zoomElem.eq(0).trigger('click'); + } else { + zoomElem.eq(1).trigger('click'); + } + e.preventDefault(); + }); + + // 滑动切换图片事件,仅限 layui 中 + if(window.layui || window.lay){ + var lay = window.layui.lay || window.lay; + var touchEndCallback = function(e, state){ + var duration = Date.now() - state.timeStart; + var speed = state.distanceX / duration; + var threshold = win.width() / 3; + var shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(state.distanceX) > threshold; + if(!shouldSwipe) return; + if(state.direction === 'left'){ + dict.imgnext(true); + }else if(state.direction === 'right'){ + dict.imgprev(true); + } + } + + $.each([that.shadeo, dict.main], function(i, elem){ + lay.touchSwipe(elem, { + onTouchEnd: touchEndCallback + }) + }) + } }; // 图片预加载 @@ -1528,7 +1750,7 @@ layer.photos = function(options, loop, key){ } dict.loadi = layer.load(1, { - shade: 'shade' in options ? false : 0.9, + shade: 'shade' in options ? false : [0.9, undefined, 'unset'], scrollbar: false }); @@ -1559,52 +1781,65 @@ layer.photos = function(options, loop, key){ imgarea[1] = imgarea[1]/wh[1]; } } - + return [imgarea[0]+'px', imgarea[1]+'px']; }(), title: false, - shade: 0.9, + shade: [0.9, undefined, 'unset'], shadeClose: true, closeBtn: false, - move: '.layui-layer-phimg img', + move: '.layer-layer-photos-main img', moveType: 1, scrollbar: false, moveOut: true, anim: 5, isOutAnim: false, skin: 'layui-layer-photos' + skin('photos'), - content: '
        ' - + ''+ alt +'' + content: '
        ' + + ''+ alt +'' + function(){ - var arr = ['
        ']; + var arr = ['
        ']; // 左右箭头翻页 - if(data.length > 1){ - arr.push(['
        ' - ,'' - ,'' - ,'
        '].join('')); + if (data.length > 1) { + arr.push(['
        ', + '', + '', + '
        '].join('')); + } + + // 头部工具栏 + if (options.toolbar) { + arr.push([ + '
        ', + '', + '', + '', + '', + '', + '', + '
        ' + ].join('')); } // 底部栏 - if(!options.hideFooter){ - arr.push(['
        ' - ,'
        ' - ,'

        '+ alt +'

        ' - ,''+ dict.imgIndex +' / '+ data.length +'' - ,'查看原图' - ,'
        ' - ,'
        '].join('')); + if (options.footer) { + arr.push([''].join('')); } arr.push('
        '); return arr.join(''); }() +'
        ', - success: function(layero, index){ - dict.bigimg = layero.find('.layui-layer-phimg'); - dict.imgsee = layero.find('.layui-layer-imgbar'); - dict.event(layero); + success: function(layero, index, that){ + dict.main = layero.find('.layer-layer-photos-main'); + dict.footer = layero.find('.layui-layer-photos-footer'); + dict.imgElem = dict.main.children('img'); + dict.event(layero, index, that); options.tab && options.tab(data[start], layero); typeof success === 'function' && success(layero); }, end: function(){ @@ -1614,9 +1849,9 @@ layer.photos = function(options, loop, key){ }, options)); }, function(){ layer.close(dict.loadi); - layer.msg('当前图片地址异常
        是否继续查看下一张?', { + layer.msg('当前图片地址异常,
        是否继续查看下一张?', { time: 30000, - btn: ['下一张', '不看了'], + btn: ['下一张', '不看了'], yes: function(){ data.length > 1 && dict.imgnext(true,true); } @@ -1628,6 +1863,23 @@ layer.photos = function(options, loop, key){ ready.run = function(_$){ $ = _$; win = $(window); + + // 移动端兼容性处理 + // https://gitee.com/layui/layui/issues/I81WGC + // https://github.com/jquery/jquery/issues/1729 + var agent = navigator.userAgent.toLowerCase(); + var isMobile = /android|iphone|ipod|ipad|ios/.test(agent) + var _win = $(window); + if(isMobile){ + $.each({Height: "height", Width: "width"}, function(propSuffix, funcName){ + var propName = 'inner' + propSuffix; + win[funcName] = function(){ + return propName in window + ? window[propName] + : _win[funcName]() + } + }) + } doms.html = $('html'); layer.open = function(deliver){ var o = new Class(deliver); @@ -1638,7 +1890,7 @@ ready.run = function(_$){ // 加载方式 window.layui && layui.define ? ( layer.ready(), - layui.define('jquery', function(exports){ // layui + layui.define(['jquery','lay'], function(exports){ // layui layer.path = layui.cache.dir; ready.run(layui.$); diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js index c0d44d9..12c7404 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js @@ -5,22 +5,23 @@ layui.define(function(exports){ "use strict"; - var doc = document - ,id = 'getElementById' - ,tag = 'getElementsByTagName' + var doc = document; + var id = 'getElementById'; + var tag = 'getElementsByTagName'; - //字符常量 - ,MOD_NAME = 'laypage', DISABLED = 'layui-disabled' + // 字符常量 + var MOD_NAME = 'laypage'; + var DISABLED = 'layui-disabled'; - //构造器 - ,Class = function(options){ + // 构造器 + var Class = function(options){ var that = this; that.config = options || {}; that.config.index = ++laypage.index; that.render(true); }; - //判断传入的容器类型 + // 判断传入的容器类型 Class.prototype.type = function(){ var config = this.config; if(typeof config.elem === 'object'){ @@ -54,7 +55,7 @@ layui.define(function(exports){ // 默认条数 config.limit = Number(config.limit) || 10; - //总页数 + // 总页数 config.pages = Math.ceil(config.count/config.limit) || 1; // 当前页不能超过总页数 @@ -64,126 +65,147 @@ layui.define(function(exports){ config.curr = 1; } - //连续分页个数不能低于 0 且不能大于总页数 + // 连续分页个数不能低于 0 且不能大于总页数 if(groups < 0){ groups = 1; } else if (groups > config.pages){ groups = config.pages; } - config.prev = 'prev' in config ? config.prev : '上一页'; //上一页文本 - config.next = 'next' in config ? config.next : '下一页'; //下一页文本 + config.prev = 'prev' in config ? config.prev : '上一页'; // 上一页文本 + config.next = 'next' in config ? config.next : '下一页'; // 下一页文本 - //计算当前组 + // 计算当前组 var index = config.pages > groups ? Math.ceil( (config.curr + (groups > 1 ? 1 : 0)) / (groups > 0 ? groups : 1) ) - : 1 + : 1; - //视图片段 - ,views = { - //上一页 + // 视图片段 + var views = { + // 上一页 prev: function(){ return config.prev ? ''+ config.prev +'' : ''; - }() + }(), - //页码 - ,page: function(){ + // 页码 + page: function(){ var pager = []; - //数据量为0时,不输出页码 + // 数据量为0时,不输出页码 if(config.count < 1){ return ''; } - //首页 + // 首页 if(index > 1 && config.first !== false && groups !== 0){ - pager.push(''+ (config.first || 1) +''); + pager.push(''+ (config.first || 1) +''); } - //计算当前页码组的起始页 - var halve = Math.floor((groups-1)/2) //页码数等分 - ,start = index > 1 ? config.curr - halve : 1 - ,end = index > 1 ? (function(){ + // 计算当前页码组的起始页 + var halve = Math.floor((groups-1)/2) // 页码数等分 + var start = index > 1 ? config.curr - halve : 1; + var end = index > 1 ? (function(){ var max = config.curr + (groups - halve - 1); return max > config.pages ? config.pages : max; }()) : groups; - //防止最后一组出现“不规定”的连续页码数 + // 防止最后一组出现“不规定”的连续页码数 if(end - start < groups - 1){ start = end - groups + 1; } - //输出左分割符 + // 输出左分割符 if(config.first !== false && start > 2){ - pager.push('') + pager.push('...') } - //输出连续页码 + // 输出连续页码 for(; start <= end; start++){ if(start === config.curr){ - //当前页 + // 当前页 pager.push(''+ start +''); } else { pager.push(''+ start +''); } } - //输出输出右分隔符 & 末页 + // 输出输出右分隔符 & 末页 if(config.pages > groups && config.pages > end && config.last !== false){ if(end + 1 < config.pages){ - pager.push(''); + pager.push('...'); } if(groups !== 0){ - pager.push(''+ (config.last || config.pages) +''); + pager.push(''+ (config.last || config.pages) +''); } } return pager.join(''); - }() + }(), - //下一页 - ,next: function(){ + // 下一页 + next: function(){ return config.next ? ''+ config.next +'' : ''; - }() + }(), - //数据总数 - ,count: '共 '+ config.count +' 条' + // 数据总数 + count: function(){ + var countText = typeof config.countText === 'object' ? config.countText : ['共 ', ' 条']; + return ''+ countText[0] + config.count + countText[1] +'' + }(), - //每页条数 - ,limit: function(){ - var options = ['']; + var template = function(item) { + var def = item +' 条/页'; + return typeof config.limitTemplet === 'function' + ? (config.limitTemplet(item) || def) + : def; + }; + + // 条目选项列表 layui.each(config.limits, function(index, item){ - options.push( - '' + elemArr.push( + '' ); }); - return options.join('') +''; - }() - - //刷新当前页 - ,refresh: ['' - ,'' - ,''].join('') - //跳页区域 - ,skip: function(){ - return ['到第' - ,'' - ,'页' - ,''].join(''); + return elemArr.join('') +''; + }(), + + // 刷新当前页 + refresh: [ + '', + '', + '' + ].join(''), + + // 跳页区域 + skip: function(){ + var skipText = typeof config.skipText === 'object' ? config.skipText : [ + '到第', + '页', + '确定' + ]; + return [ + ''+ skipText[0], + '', + skipText[1]+ '', + '' + ].join(''); }() }; return ['
        ' - ,function(){ + ) : 'default') +'" id="layui-laypage-'+ config.index +'">', + function(){ var plate = []; layui.each(config.layout, function(index, item){ if(views[item]){ @@ -191,20 +213,21 @@ layui.define(function(exports){ } }); return plate.join(''); - }() - ,'
        '].join(''); + }(), + '
        '].join(''); }; - //跳页的回调 + // 跳页的回调 Class.prototype.jump = function(elem, isskip){ if(!elem) return; - var that = this - ,config = that.config - ,childs = elem.children - ,btn = elem[tag]('button')[0] - ,input = elem[tag]('input')[0] - ,select = elem[tag]('select')[0] - ,skip = function(){ + + var that = this; + var config = that.config; + var childs = elem.children; + var btn = elem[tag]('button')[0]; + var input = elem[tag]('input')[0]; + var select = elem[tag]('select')[0]; + var skip = function(){ var curr = Number(input.value.replace(/\s|\D/g, '')); if(curr){ config.curr = curr; @@ -214,7 +237,7 @@ layui.define(function(exports){ if(isskip) return skip(); - //页码 + // 页码 for(var i = 0, len = childs.length; i < len; i++){ if(childs[i].nodeName.toLowerCase() === 'a'){ laypage.on(childs[i], 'click', function(){ @@ -226,7 +249,7 @@ layui.define(function(exports){ } } - //条数 + // 条数 if(select){ laypage.on(select, 'change', function(){ var value = this.value; @@ -238,7 +261,7 @@ layui.define(function(exports){ }); } - //确定 + // 确定 if(btn){ laypage.on(btn, 'click', function(){ skip(); @@ -246,15 +269,22 @@ layui.define(function(exports){ } }; - //输入页数字控制 + // 输入页数字控制 Class.prototype.skip = function(elem){ if(!elem) return; - var that = this, input = elem[tag]('input')[0]; + + var that = this; + var input = elem[tag]('input')[0]; + if(!input) return; + + // 键盘事件 laypage.on(input, 'keyup', function(e){ - var value = this.value - ,keyCode = e.keyCode; + var value = this.value; + var keyCode = e.keyCode; + if(/^(37|38|39|40)$/.test(keyCode)) return; + if(/\D/.test(value)){ this.value = value.replace(/\D/, ''); } @@ -264,12 +294,12 @@ layui.define(function(exports){ }); }; - //渲染分页 + // 渲染分页 Class.prototype.render = function(load){ - var that = this - ,config = that.config - ,type = that.type() - ,view = that.view(); + var that = this; + var config = that.config; + var type = that.type(); + var view = that.view(); if(type === 2){ config.elem && (config.elem.innerHTML = view); @@ -293,16 +323,16 @@ layui.define(function(exports){ that.skip(elem); }; - //外部接口 + // 外部接口 var laypage = { - //分页渲染 + // 分页渲染 render: function(options){ var o = new Class(options); return o.index; - } - ,index: layui.laypage ? (layui.laypage.index + 10000) : 0 - ,on: function(elem, even, fn){ - elem.attachEvent ? elem.attachEvent('on'+ even, function(e){ //for ie + }, + index: layui.laypage ? (layui.laypage.index + 10000) : 0, + on: function(elem, even, fn){ + elem.attachEvent ? elem.attachEvent('on'+ even, function(e){ // for ie e.target = e.srcElement; fn.call(elem, e); }) : elem.addEventListener(even, fn, false); @@ -311,4 +341,4 @@ layui.define(function(exports){ } exports(MOD_NAME, laypage); -}); \ No newline at end of file +}); diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js index 161262c..0e67d9a 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js @@ -1,4 +1,4 @@ -/** +/** * laytpl 轻量模板引擎 */ @@ -12,11 +12,11 @@ layui.define(function(exports){ }; // 模板工具 - var tool = { + var tool = { escape: function(html){ var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g; if(html === undefined || html === null) return ''; - + html += ''; if(!exp.test(html)) return html; @@ -77,12 +77,12 @@ layui.define(function(exports){ // 模板必须为 string 类型 if(typeof template !== 'string') return template; - + // 正则解析 template = template.replace(/\s+|\r|\t|\n/g, ' ') .replace(inner.exp(options.open +'#'), options.open +'# ') .replace(inner.exp(options.close +'}'), '} '+ options.close).replace(/\\/g, '\\\\') - + // 不匹配指定区域的内容 .replace(inner.exp(options.open + '!(.+?)!' + options.close), function(str){ str = str.replace(inner.exp('^'+ options.open + '!'), '') @@ -92,13 +92,13 @@ layui.define(function(exports){ }); return str }) - + // 匹配 JS 语法 .replace(/(?="|')/g, '\\').replace(that.tagExp(), function(str){ str = str.replace(jss, '').replace(jsse, ''); return '";' + str.replace(/\\(.)/g, '$1') + ';view+="'; }) - + // 匹配普通输出语句 .replace(that.tagExp(1), function(str){ var start = '"+laytpl.escape('; @@ -114,10 +114,14 @@ layui.define(function(exports){ } return start + str.replace(/\\(.)/g, '$1') + ')+"'; }); - + template = '"use strict";var view = "' + template + '";return view;'; try { + /** + * 请注意: 开发者在使用模板语法时,需确保模板中的 JS 语句不来自于页面用户输入。 + * 即模板中的 JS 语句必须在页面开发者自身的可控范围内,否则请避免使用该模板解析。 + */ that.cache = template = new Function('d, laytpl', template); return template(data, tool); } catch(e) { @@ -132,7 +136,7 @@ layui.define(function(exports){ var that = this; var result = that.cache ? that.cache(data, tool) : that.parse(that.template, data); - + // 返回渲染结果 typeof callback === 'function' && callback(result); return result; @@ -152,7 +156,7 @@ layui.define(function(exports){ }; laytpl.v = '2.0.0'; - + // export exports('laytpl', laytpl); -}); \ No newline at end of file +}); diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js index 23d7faf..842a808 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js @@ -10,42 +10,47 @@ layui.define(['jquery', 'lay'],function(exports){ // 外部接口 var rate = { - config: {} - ,index: layui.rate ? (layui.rate.index + 10000) : 0 + config: {}, + index: layui.rate ? (layui.rate.index + 10000) : 0, //设置全局项 - ,set: function(options){ + set: function(options){ var that = this; that.config = $.extend({}, that.config, options); return that; - } - + }, + //事件 - ,on: function(events, callback){ + on: function(events, callback){ return layui.onevent.call(this, MOD_NAME, events, callback); } } // 操作当前实例 - ,thisRate = function(){ - var that = this - ,options = that.config; - + var thisRate = function () { + var that = this; + var options = that.config; + return { - setvalue: function(value){ + setvalue: function (value) { that.setvalue.call(that, value); - } - ,config: options + }, + config: options } - } + }; //字符常量 - ,MOD_NAME = 'rate',ELEM_VIEW = 'layui-rate', ICON_RATE = 'layui-icon-rate', ICON_RATE_SOLID = 'layui-icon-rate-solid', ICON_RATE_HALF = 'layui-icon-rate-half' - - ,ICON_SOLID_HALF = 'layui-icon-rate-solid layui-icon-rate-half', ICON_SOLID_RATE = 'layui-icon-rate-solid layui-icon-rate', ICON_HALF_RATE = 'layui-icon-rate layui-icon-rate-half' + var MOD_NAME = 'rate'; + var ELEM_VIEW = 'layui-rate'; + var ICON_RATE = 'layui-icon-rate'; + var ICON_RATE_SOLID = 'layui-icon-rate-solid'; + var ICON_RATE_HALF = 'layui-icon-rate-half'; + var ICON_SOLID_HALF = 'layui-icon-rate-solid layui-icon-rate-half'; + var ICON_SOLID_RATE = 'layui-icon-rate-solid layui-icon-rate'; + var ICON_HALF_RATE = 'layui-icon-rate layui-icon-rate-half'; //构造器 - ,Class = function(options){ + var Class = function (options) { var that = this; that.index = ++rate.index; that.config = $.extend({}, that.config, rate.config, options); @@ -54,19 +59,19 @@ layui.define(['jquery', 'lay'],function(exports){ //默认配置 Class.prototype.config = { - length: 5 //初始长度 - ,text: false //是否显示评分等级 - ,readonly: false //是否只读 - ,half: false //是否可以半星 - ,value: 0 //星星选中个数 - ,theme: '' + length: 5, //初始长度 + text: false, //是否显示评分等级 + readonly: false, //是否只读 + half: false, //是否可以半星 + value: 0, //星星选中个数 + theme: '' //主题颜色 }; //评分渲染 Class.prototype.render = function(){ var that = this; var options = that.config; - + // 若 elem 非唯一,则拆分为多个实例 var elem = $(options.elem); if(elem.length > 1){ @@ -83,9 +88,9 @@ layui.define(['jquery', 'lay'],function(exports){ // 自定义主题 var style = options.theme ? ('style="color: '+ options.theme + ';"') : ''; - + options.elem = $(options.elem); - + //最大值不能大于总长度 if(options.value > options.length){ options.value = options.length; @@ -114,14 +119,14 @@ layui.define(['jquery', 'lay'],function(exports){ temp += '' + (options.text ? (''+ options.value + '星') : '') + ''; //开始插入替代元素 - var othis = options.elem - ,hasRender = othis.next('.' + ELEM_VIEW); - + var othis = options.elem; + var hasRender = othis.next('.' + ELEM_VIEW); + //生成替代元素 hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender that.elemTemp = $(temp); - + options.span = that.elemTemp.next('span'); options.setText && options.setText(options.value); @@ -131,14 +136,14 @@ layui.define(['jquery', 'lay'],function(exports){ othis.addClass("layui-inline"); //如果不是只读,那么进行触控事件 - if(!options.readonly) that.action(); + if(!options.readonly) that.action(); }; //评分重置 Class.prototype.setvalue = function(value){ - var that = this - ,options = that.config ; + var that = this; + var options = that.config; options.value = value ; that.render(); @@ -146,14 +151,15 @@ layui.define(['jquery', 'lay'],function(exports){ //li触控事件 Class.prototype.action = function(){ - var that = this - ,options = that.config - ,_ul = that.elemTemp - ,wide = _ul.find("i").width(); + var that = this; + var options = that.config; + var _ul = that.elemTemp; + var wide = _ul.find("i").width(); + var liElems = _ul.children("li"); - _ul.children("li").each(function(index){ - var ind = index + 1 - ,othis = $(this); + liElems.each(function(index){ + var ind = index + 1; + var othis = $(this); //点击 othis.on('click', function(e){ @@ -175,7 +181,7 @@ layui.define(['jquery', 'lay'],function(exports){ //移入 othis.on('mousemove', function(e){ - _ul.find("i").each(function(){ + _ul.find("i").each(function(){ $(this).addClass(ICON_RATE).removeClass(ICON_SOLID_HALF) }); _ul.find("i:lt(" + ind + ")").each(function(){ @@ -187,7 +193,7 @@ layui.define(['jquery', 'lay'],function(exports){ if(x <= wide / 2){ othis.children("i").addClass(ICON_RATE_HALF).removeClass(ICON_RATE_SOLID) } - } + } }) //移出 @@ -201,18 +207,68 @@ layui.define(['jquery', 'lay'],function(exports){ //如果设置可选半星,根据分数判断是否有半星 if(options.half){ if(parseInt(options.value) !== options.value){ - _ul.children("li:eq(" + Math.floor(options.value) + ")").children("i").addClass(ICON_RATE_HALF).removeClass(ICON_SOLID_RATE) + _ul.children("li:eq(" + Math.floor(options.value) + ")").children("i").addClass(ICON_RATE_HALF).removeClass(ICON_SOLID_RATE) } - } + } }) }) + + lay.touchSwipe(_ul, { + onTouchMove: function(e, state){ + if(Date.now() - state.timeStart <= 200) return; + var pageX = e.touches[0].pageX; + var rateElemWidth = _ul.width(); + var itemElemWidth = rateElemWidth / options.length; // 单颗星的宽度 + var offsetX = pageX - _ul.offset().left; + var num = offsetX / itemElemWidth; // 原始值 + var remainder = num % 1; + var integer = num - remainder; + + // 最终值 + var score = remainder <= 0.5 && options.half ? integer + 0.5 : Math.ceil(num); + if(score > options.length) score = options.length; + if(score < 0) score = 0; + + liElems.each(function(index){ + var iconElem = $(this).children('i'); + var isActiveIcon = (Math.ceil(score) - index === 1); + var needSelect = Math.ceil(score) > index; + var shouldHalfIcon = (score - index === 0.5); + + if(needSelect){ + // 设置选中样式 + iconElem.addClass(ICON_RATE_SOLID).removeClass(ICON_HALF_RATE); + if(options.half && shouldHalfIcon){ + iconElem.addClass(ICON_RATE_HALF).removeClass(ICON_RATE_SOLID); + } + }else{ + // 恢复初始样式 + iconElem.addClass(ICON_RATE).removeClass(ICON_SOLID_HALF); + } + + // 设置缩放样式 + iconElem.toggleClass('layui-rate-hover', isActiveIcon); + }); + + // 更新最终值 + options.value = score; + if(options.text) _ul.next("span").text(options.value + "星"); + options.setText && options.setText(options.value); + }, + onTouchEnd: function(e, state){ + if(Date.now() - state.timeStart <= 200) return; + _ul.find('i').removeClass('layui-rate-hover'); + options.choose && options.choose(options.value); + options.setText && options.setText(options.value); + } + }); }; - + //事件处理 - Class.prototype.events = function(){ - var that = this - ,options = that.config; + Class.prototype.events = function () { + var that = this; + //var options = that.config; }; //核心入口 @@ -220,6 +276,6 @@ layui.define(['jquery', 'lay'],function(exports){ var inst = new Class(options); return thisRate.call(inst); }; - + exports(MOD_NAME, rate); -}) \ No newline at end of file +}) diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js index c0f3e35..745c52b 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js @@ -10,26 +10,26 @@ layui.define(['jquery', 'lay'], function(exports){ // 外部接口 var slider = { - config: {} - ,index: layui.slider ? (layui.slider.index + 10000) : 0 + config: {}, + index: layui.slider ? (layui.slider.index + 10000) : 0, // 设置全局项 - ,set: function(options){ + set: function(options){ var that = this; that.config = $.extend({}, that.config, options); return that; - } - + }, + // 事件 - ,on: function(events, callback){ + on: function(events, callback){ return layui.onevent.call(this, MOD_NAME, events, callback); } }; - + // 操作当前实例 var thisSlider = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; return { setValue: function(value, index){ // 设置值 @@ -37,8 +37,8 @@ layui.define(['jquery', 'lay'], function(exports){ value = value < options.min ? options.min : value; options.value = value; return that.slide('set', value, index || 0); - } - ,config: options + }, + config: options } }; @@ -65,20 +65,32 @@ layui.define(['jquery', 'lay'], function(exports){ // 默认配置 Class.prototype.config = { - type: 'default' //滑块类型,垂直:vertical - ,min: 0 //最小值 - ,max: 100 //最大值,默认100 - ,value: 0 //初始值,默认为0 - ,step: 1 //间隔值 - ,showstep: false //间隔点开启 - ,tips: true //文字提示,开启 - ,input: false //输入框,关闭 - ,range: false //范围选择,与输入框不能同时开启,默认关闭 - ,height: 200 //配合 type:"vertical" 使用,默认200px - ,disabled: false //滑块禁用,默认关闭 - ,theme: '#16baaa' //主题颜色 + type: 'default', //滑块类型,垂直:vertical + min: 0, //最小值 + max: 100, //最大值,默认100 + value: 0, //初始值,默认为0 + step: 1, //间隔值 + showstep: false, //间隔点开启 + tips: true, //文字提示,开启 + tipsAlways: false, //文字提示,始终开启 + input: false, //输入框,关闭 + range: false, //范围选择,与输入框不能同时开启,默认关闭 + height: 200, //配合 type:"vertical" 使用,默认200px + disabled: false, //滑块禁用,默认关闭 + theme: '#16baaa' //主题颜色 }; + // 数值精度 + Class.prototype.precision = function(){ + var that = this; + var options = that.config; + var precisions = $.map([options.min, options.max, options.step], function(v, i){ + var decimalArr = String(v).split('.'); + return decimalArr[1] ? decimalArr[1].length : 0; + }) + return Math.max.apply(null, precisions); + } + //滑块渲染 Class.prototype.render = function(){ var that = this; @@ -97,28 +109,28 @@ layui.define(['jquery', 'lay'], function(exports){ // 合并 lay-options 属性上的配置信息 $.extend(options, lay.options(elem[0])); - - //间隔值不能小于 1 - if(options.step < 1) options.step = 1; - + + //间隔值不能小于等于 0 + if(options.step <= 0) options.step = 1; + //最大值不能小于最小值 if(options.max < options.min) options.max = options.min + options.step; - - + + //判断是否开启双滑块 if(options.range){ options.value = typeof(options.value) == 'object' ? options.value : [options.min, options.value]; var minValue = Math.min(options.value[0], options.value[1]) ,maxValue = Math.max(options.value[0], options.value[1]); - options.value[0] = minValue > options.min ? minValue : options.min; - options.value[1] = maxValue > options.min ? maxValue : options.min; - options.value[0] = options.value[0] > options.max ? options.max : options.value[0]; - options.value[1] = options.value[1] > options.max ? options.max : options.value[1]; - - var scaleFir = Math.floor((options.value[0] - options.min) / (options.max - options.min) * 100) - ,scaleSec = Math.floor((options.value[1] - options.min) / (options.max - options.min) * 100) - ,scale = scaleSec - scaleFir + '%'; + options.value[0] = Math.max(minValue,options.min); + options.value[1] = Math.max(maxValue,options.min); + options.value[0] = Math.min(options.value[0],options.max); + options.value[1] = Math.min(options.value[1],options.max); + + var scaleFir = (options.value[0] - options.min) / (options.max - options.min) * 100; + var scaleSec = (options.value[1] - options.min) / (options.max - options.min) * 100; + var scale = scaleSec - scaleFir + '%'; scaleFir = scaleFir + '%'; scaleSec = scaleSec + '%'; } else { @@ -126,44 +138,44 @@ layui.define(['jquery', 'lay'], function(exports){ if(typeof options.value == 'object'){ options.value = Math.min.apply(null, options.value); } - + //初始值不能小于最小值且不能大于最大值 if(options.value < options.min) options.value = options.min; if(options.value > options.max) options.value = options.max; - var scale = Math.floor((options.value - options.min) / (options.max - options.min) * 100) + '%'; - }; - + var scale = (options.value - options.min) / (options.max - options.min) * 100 + '%'; + } + //如果禁用,颜色为统一的灰色 var theme = options.disabled ? '#c2c2c2' : options.theme; //滑块 - var temp = '
        '+ (options.tips ? '
        ' : '') + + var temp = '
        '+ (options.tips ? '
        ' : '') + '
        ' + '
        '+ (options.range ? '
        ' : '') +'
        '; - var othis = $(options.elem) - ,hasRender = othis.next('.' + ELEM_VIEW); + var othis = $(options.elem); + var hasRender = othis.next('.' + ELEM_VIEW); //生成替代元素 - hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender + hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender that.elemTemp = $(temp); //把数据缓存到滑块上 if(options.range){ that.elemTemp.find('.' + SLIDER_WRAP).eq(0).data('value', options.value[0]); - that.elemTemp.find('.' + SLIDER_WRAP).eq(1).data('value', options.value[1]); + that.elemTemp.find('.' + SLIDER_WRAP).eq(1).data('value', options.value[1]); }else{ that.elemTemp.find('.' + SLIDER_WRAP).data('value', options.value); - }; - + } + //插入替代元素 - othis.html(that.elemTemp); + othis.html(that.elemTemp); //垂直滑块 if(options.type === 'vertical'){ that.elemTemp.height(options.height + 'px'); - }; + } //显示间断点 if(options.showstep){ @@ -173,9 +185,9 @@ layui.define(['jquery', 'lay'], function(exports){ if(step < 100){ item += '
        ' } - }; + } that.elemTemp.append(item); - }; + } //插入输入框 if(options.input && !options.range){ @@ -191,7 +203,7 @@ layui.define(['jquery', 'lay'], function(exports){ } else { that.elemTemp.css("margin-right", elemInput.outerWidth() + 15); } - }; + } //给未禁止的滑块滑动事件 if(!options.disabled){ @@ -199,70 +211,107 @@ layui.define(['jquery', 'lay'], function(exports){ }else{ that.elemTemp.addClass(DISABLED); that.elemTemp.find('.' + SLIDER_WRAP_BTN).addClass(DISABLED); - }; + } - //划过滑块显示数值 - var timer; - that.elemTemp.find('.' + SLIDER_WRAP_BTN).on('mouseover', function(){ - var sliderWidth = options.type === 'vertical' ? options.height : that.elemTemp[0].offsetWidth - ,sliderWrap = that.elemTemp.find('.' + SLIDER_WRAP) - ,tipsLeft = options.type === 'vertical' ? (sliderWidth - $(this).parent()[0].offsetTop - sliderWrap.height()) : $(this).parent()[0].offsetLeft - ,left = tipsLeft / sliderWidth * 100 - ,value = $(this).parent().data('value') - ,tipsTxt = options.setTips ? options.setTips(value) : value; + /** + * @description 设置提示文本内容 + * @param {Element} sliderWrapBtnElem 提示文本节点元素 + */ + function setSliderTipsTxt(sliderWrapBtnElem) { + var value = sliderWrapBtnElem.parent().data('value'); + var tipsTxt = options.setTips ? options.setTips(value) : value; that.elemTemp.find('.' + SLIDER_TIPS).html(tipsTxt); + } - clearTimeout(timer); - timer = setTimeout(function(){ - if(options.type === 'vertical'){ - that.elemTemp.find('.' + SLIDER_TIPS).css({ - "bottom": left + '%', - "margin-bottom": "20px", - "display": "inline-block" - }); - } else { - that.elemTemp.find('.' + SLIDER_TIPS).css({ - "left": left + '%', - "display": "inline-block" - }); - }; - }, 300); - }).on('mouseout', function(){ - clearTimeout(timer); - that.elemTemp.find('.' + SLIDER_TIPS).css("display", "none"); - }); + /** + * @description 计算提示文本元素的 position left + * @param {Element} sliderWrapBtnElem 提示文本节点元素 + */ + function calcSliderTipsLeft(sliderWrapBtnElem){ + var sliderWidth = options.type === 'vertical' ? options.height : that.elemTemp[0].offsetWidth; + var sliderWrap = that.elemTemp.find('.' + SLIDER_WRAP); + var tipsLeft = options.type === 'vertical' ? (sliderWidth - sliderWrapBtnElem.parent()[0].offsetTop - sliderWrap.height()) : sliderWrapBtnElem.parent()[0].offsetLeft; + var left = tipsLeft / sliderWidth * 100; + return left + } + + /** + * @description 设置提示文本元素的 position left + * @param {number} left 要设置的 left 的大小 + */ + function setSliderTipsLeft(left) { + if(options.type === 'vertical'){ + that.elemTemp.find('.' + SLIDER_TIPS).css({ + "bottom": left + '%', + "margin-bottom": "20px", + "display": "inline-block" + }); + } else { + that.elemTemp.find('.' + SLIDER_TIPS).css({ + "left": left + '%', + "display": "inline-block" + }); + } + } + + //判断是否要始终显示提示文本 + if(options.tips){ + if(options.tipsAlways){ + var sliderWrapBtnElem = that.elemTemp.find('.' + SLIDER_WRAP_BTN); + setSliderTipsTxt(sliderWrapBtnElem) + var left = calcSliderTipsLeft(sliderWrapBtnElem); + setSliderTipsLeft(left) + }else{ + //划过滑块显示数值 + var timer; + that.elemTemp.find('.' + SLIDER_WRAP_BTN).on('mouseover', function(){ + setSliderTipsTxt($(this)) + var left = calcSliderTipsLeft($(this)); + clearTimeout(timer); + timer = setTimeout(function(){ + setSliderTipsLeft(left) + }, 300); + }).on('mouseout', function(){ + clearTimeout(timer); + if(!options.tipsAlways){ + that.elemTemp.find('.' + SLIDER_TIPS).css("display", "none"); + } + }); + } + } }; //滑块滑动 Class.prototype.slide = function(setValue, value, i){ - var that = this - ,options = that.config - ,sliderAct = that.elemTemp - ,sliderWidth = function(){ + var that = this; + var options = that.config; + var sliderAct = that.elemTemp; + var sliderWidth = function(){ return options.type === 'vertical' ? options.height : sliderAct[0].offsetWidth - } - ,sliderWrap = sliderAct.find('.' + SLIDER_WRAP) - ,sliderTxt = sliderAct.next('.' + SLIDER_INPUT) - ,inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val() - ,step = 100 / ((options.max - options.min) / Math.ceil(options.step)) - ,change = function(offsetValue, index, from){ + }; + var sliderWrap = sliderAct.find('.' + SLIDER_WRAP); + var sliderTxt = sliderAct.next('.' + SLIDER_INPUT); + var inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(); + var step = 100 / ((options.max - options.min) / options.step); + var precision = that.precision(); + var change = function(offsetValue, index, from){ if(Math.ceil(offsetValue) * step > 100){ offsetValue = Math.ceil(offsetValue) * step }else{ offsetValue = Math.round(offsetValue) * step - }; + } offsetValue = offsetValue > 100 ? 100: offsetValue; offsetValue = offsetValue < 0 ? 0: offsetValue; sliderWrap.eq(index).css((options.type === 'vertical' ?'bottom':'left'), offsetValue + '%'); - var firLeft = valueTo(sliderWrap[0].offsetLeft) - ,secLeft = options.range ? valueTo(sliderWrap[1].offsetLeft) : 0; + var firLeft = valueTo(sliderWrap[0].offsetLeft); + var secLeft = options.range ? valueTo(sliderWrap[1].offsetLeft) : 0; if(options.type === 'vertical'){ sliderAct.find('.' + SLIDER_TIPS).css({"bottom":offsetValue + '%', "margin-bottom":"20px"}); firLeft = valueTo(sliderWidth() - sliderWrap[0].offsetTop - sliderWrap.height()); secLeft = options.range ? valueTo(sliderWidth() - sliderWrap[1].offsetTop - sliderWrap.height()) : 0; }else{ sliderAct.find('.' + SLIDER_TIPS).css("left",offsetValue + '%'); - }; + } firLeft = firLeft > 100 ? 100: firLeft; secLeft = secLeft > 100 ? 100: secLeft; var minLeft = Math.min(firLeft, secLeft) @@ -271,18 +320,19 @@ layui.define(['jquery', 'lay'], function(exports){ sliderAct.find('.' + SLIDER_BAR).css({"height":wrapWidth + '%', "bottom":minLeft + '%'}); }else{ sliderAct.find('.' + SLIDER_BAR).css({"width":wrapWidth + '%', "left":minLeft + '%'}); - }; - var selfValue = options.min + Math.round((options.max - options.min) * offsetValue / 100); + } + var selfValue = options.min + (options.max - options.min) * offsetValue / 100; + selfValue = Number(parseFloat(selfValue).toFixed(precision)); inputValue = selfValue; sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(inputValue); sliderWrap.eq(index).data('value', selfValue); sliderAct.find('.' + SLIDER_TIPS).html(options.setTips ? options.setTips(selfValue) : selfValue); - + //如果开启范围选择,则返回数组值 if(options.range){ var arrValue = [ - sliderWrap.eq(0).data('value') - ,sliderWrap.eq(1).data('value') + sliderWrap.eq(0).data('value'), + sliderWrap.eq(1).data('value') ]; if(arrValue[0] > arrValue[1]) arrValue.reverse(); //如果前面的圆点超过了后面的圆点值,则调换顺序 } @@ -292,47 +342,70 @@ layui.define(['jquery', 'lay'], function(exports){ // 值完成选中的事件 if(from === 'done') options.done && options.done(that.value); - } - ,valueTo = function(value){ - var oldLeft = value / sliderWidth() * 100 / step - ,left = Math.round(oldLeft) * step; + }; + var valueTo = function(value){ + var oldLeft = value / sliderWidth() * 100 / step; + var left = Math.round(oldLeft) * step; if(value == sliderWidth()){ left = Math.ceil(oldLeft) * step; - }; + } return left; - } - + }; + //拖拽元素 - ,elemMove = $(['
        sliderWidth())left = sliderWidth(); @@ -342,23 +415,27 @@ layui.define(['jquery', 'lay'], function(exports){ sliderAct.find('.' + SLIDER_TIPS).show(); e.preventDefault(); }; - - var up = function(){ + + var up = function(delay){ othis.removeClass(ELEM_HOVER); - sliderAct.find('.' + SLIDER_TIPS).hide(); + if(!options.tipsAlways){ + setTimeout(function(){ + sliderAct.find('.' + SLIDER_TIPS).hide(); + }, delay); + } }; - - createMoveElem(move, up) + + createMoveElem(othis, move, up) }); }); - + // 点击滑块 sliderAct.on('click', function(e){ var main = $('.' + SLIDER_WRAP_BTN); var othis = $(this); if(!main.is(event.target) && main.has(event.target).length === 0 && main.length){ var index; - var offset = options.type === 'vertical' + var offset = options.type === 'vertical' ? (sliderWidth() - e.clientY + othis.offset().top - $(window).scrollTop()) :(e.clientX - othis.offset().left - $(window).scrollLeft()); @@ -373,30 +450,30 @@ layui.define(['jquery', 'lay'], function(exports){ } } else { index = 0; - }; + } change(reaLeft, index, 'done'); e.preventDefault(); } }); - + //点击加减输入框 sliderTxt.children('.' + SLIDER_INPUT_BTN).children('i').each(function(index){ $(this).on('click', function(){ inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(); if(index == 1){ //减 - inputValue = inputValue - options.step < options.min - ? options.min + inputValue = inputValue - options.step < options.min + ? options.min : Number(inputValue) - options.step; }else{ - inputValue = Number(inputValue) + options.step > options.max - ? options.max + inputValue = Number(inputValue) + options.step > options.max + ? options.max : Number(inputValue) + options.step; - }; + } var inputScale = (inputValue - options.min) / (options.max - options.min) * 100 / step; change(inputScale, 0, 'done'); }); }); - + //获取输入框值 var getInputValue = function(){ var realValue = this.value; @@ -412,20 +489,20 @@ layui.define(['jquery', 'lay'], function(exports){ e.preventDefault(); getInputValue.call(this); } - }).on('change', getInputValue); + }).on('change', getInputValue); }; //事件处理 Class.prototype.events = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; }; //核心入口 slider.render = function(options){ - var inst = new Class(options); + var inst = new Class(options); return thisSlider.call(inst); }; - + exports(MOD_NAME, slider); -}) \ No newline at end of file +}) diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js index 72da9c1..6ba70f6 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js @@ -77,6 +77,16 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ return config || null; }; + // lay 函数可以处理 Selector,HTMLElement,JQuery 类型 + // 无效的 CSS 选择器字符串,会抛出 SyntaxError 异常,此时直接返回 laytpl 模板字符串 + var resolveTplStr = function(templet){ + try{ + return lay(templet).html(); + }catch(err){ + return templet; + } + } + // 解析自定义模板数据 var parseTempData = function(obj){ obj = obj || {}; @@ -97,9 +107,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ if(templet){ content = typeof templet === 'function' ? templet.call(item3, obj.tplData, obj.obj) - : laytpl($(templet).html() || String(content)).render($.extend({ - LAY_COL: item3 - }, obj.tplData)); + : laytpl(resolveTplStr(templet) || String(content)).render($.extend({ + LAY_COL: item3 + }, obj.tplData)); } // 是否只返回文本 @@ -108,6 +118,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 字符 var MOD_NAME = 'table'; + var MOD_ID = 'lay-' + MOD_NAME + '-id'; var ELEM = '.layui-table'; var THIS = 'layui-this'; var SHOW = 'layui-show'; @@ -136,6 +147,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var ELEM_GROUP = 'laytable-cell-group'; var ELEM_COL_SPECIAL = 'layui-table-col-special'; var ELEM_TOOL_PANEL = 'layui-table-tool-panel'; + var ELEM_EXPAND = 'layui-table-expanded'; + var DISABLED_TRANSITION = 'layui-table-disabled-transition'; var DATA_MOVE_NAME = 'LAY_TABLE_MOVE_DICT'; @@ -162,7 +175,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ return ''; }() ,'{{# var isSort = !(item2.colGroup) && item2.sort; }}' - ,'' + ,'' ,'
        ' ,'{{# if(d.data.loading){ }}' - ,'
        ' - ,'' + ,'
        ' + ,'
        ' + ,'{{# if(typeof d.data.loading === "string"){ }}' + ,'{{- d.data.loading}}' + ,'{{# } else{ }}' + ,'' + ,'{{# } }}' + ,'
        ' ,'
        ' ,'{{# } }}' @@ -257,29 +276,6 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ ,'
        ' ,'
        ' ,'
        ' - - ,'' ].join(''); var _WIN = $(window); @@ -328,18 +324,18 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ //请求参数的自定义格式 options.request = $.extend({ - pageName: 'page' - ,limitName: 'limit' + pageName: 'page', + limitName: 'limit' }, options.request) // 响应数据的自定义格式 options.response = $.extend({ - statusName: 'code' //规定数据状态的字段名称 - ,statusCode: 0 //规定成功的状态码 - ,msgName: 'msg' //规定状态信息的字段名称 - ,dataName: 'data' //规定数据总数的字段名称 - ,totalRowName: 'totalRow' //规定数据统计的字段名称 - ,countName: 'count' + statusName: 'code', //规定数据状态的字段名称 + statusCode: 0, //规定成功的状态码 + msgName: 'msg', //规定状态信息的字段名称 + dataName: 'data', //规定数据总数的字段名称 + totalRowName: 'totalRow', //规定数据统计的字段名称 + countName: 'count' }, options.response); //如果 page 传入 laypage 对象 @@ -370,27 +366,31 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ options.index = that.index; that.key = options.id || options.index; - //初始化一些其他参数 + // 初始化一些其他参数 that.setInit(); - //高度铺满:full-差距值 - if(options.height && /^full-\d+$/.test(options.height)){ + // 高度铺满:full-差距值 + if(options.height && /^full-.+$/.test(options.height)){ that.fullHeightGap = options.height.split('-')[1]; - options.height = _WIN.height() - that.fullHeightGap; - } else if (options.height && /^#\w+\S*-\d+$/.test(options.height)) { + options.height = _WIN.height() - (parseFloat(that.fullHeightGap) || 0); + } else if (options.height && /^#\w+\S*-.+$/.test(options.height)) { var parentDiv = options.height.split("-"); that.parentHeightGap = parentDiv.pop(); that.parentDiv = parentDiv.join("-"); - options.height = $(that.parentDiv).height() - that.parentHeightGap; + options.height = $(that.parentDiv).height() - (parseFloat(that.parentHeightGap) || 0); + } else if (typeof options.height === "function"){ + that.customHeightFunc = options.height; + options.height = that.customHeightFunc(); } - //开始插入替代元素 - var othis = options.elem - ,hasRender = othis.next('.' + ELEM_VIEW) + // 开始插入替代元素 + var othis = options.elem; + var hasRender = othis.next('.' + ELEM_VIEW); - //主容器 - ,reElem = that.elem = $('
        '); + // 主容器 + var reElem = that.elem = $('
        '); + // 添加 className reElem.addClass(function(){ var arr = [ ELEM_VIEW, @@ -400,28 +400,37 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ ]; if(options.className) arr.push(options.className); return arr.join(' '); - }()).attr({ - 'lay-filter': 'LAY-TABLE-FORM-DF-'+ that.index - ,'lay-id': options.id - ,'style': function(){ - var arr = []; - if(options.width) arr.push('width:'+ options.width + 'px;'); - // if(options.height) arr.push('height:'+ options.height + 'px;'); - return arr.join('') - }() - }).html(laytpl(TPL_MAIN, { + }()).attr(function(){ + var obj = { + 'lay-filter': 'LAY-TABLE-FORM-DF-'+ that.index, + 'style': function(){ + var arr = []; + if(options.width) arr.push('width:'+ options.width + 'px;'); + // if(options.height) arr.push('height:'+ options.height + 'px;'); + return arr.join('') + }() + } + obj[MOD_ID] = options.id; + return obj; + }()).html(laytpl(TPL_MAIN, { open: '{{', // 标签符前缀 close: '}}' // 标签符后缀 }).render({ - data: options - ,index: that.index //索引 + data: options, + index: that.index //索引 })); - //生成替代元素 - hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender + // 初始化样式 + that.renderStyle(); + + // 生成替代元素 + if(hasRender[0]){ + that.resizeObserver && that.resizeObserver.unobserve(that.elem[0]); + hasRender.remove(); // 如果已经渲染,则 Rerender + } othis.after(reElem); - //各级容器 + // 各级容器 that.layTool = reElem.find(ELEM_TOOL); that.layBox = reElem.find(ELEM_BOX); that.layHeader = reElem.find(ELEM_HEADER); @@ -442,23 +451,22 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 让表格平铺 that.fullSize(); - - that.pullData(that.page); //请求数据 - that.events(); //事件 + that.pullData(that.page); // 请求数据 + that.events(); // 事件 }; - //根据列类型,定制化参数 + // 根据列类型,定制化参数 Class.prototype.initOpts = function(item){ var that = this - ,options = that.config - ,initWidth = { - checkbox: 50 - ,radio: 50 - ,space: 30 - ,numbers: 60 + var options = that.config; + var initWidth = { + checkbox: 50, + radio: 50, + space: 30, + numbers: 60 }; - //让 type 参数兼容旧版本 + // 让 type 参数兼容旧版本 if(item.checkbox) item.type = "checkbox"; if(item.space) item.type = "space"; if(!item.type) item.type = "normal"; @@ -471,8 +479,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ //初始化一些参数 Class.prototype.setInit = function(type){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; options.clientWidth = options.width || function(){ //获取容器宽度 //如果父元素宽度为0(一般为隐藏元素),则继续查找上层元素,直到找到真实宽度为止 @@ -553,10 +561,70 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }; - // 初始工具栏 + // 初始化样式 + Class.prototype.renderStyle = function() { + var that = this; + var options = that.config; + var index = that.index; + var text = []; + + // 单元格宽度 + layui.each(options.cols, function(i1, item1) { + layui.each(item1, function(i2, item2) { + var key = [index, i1, i2].join('-'); + var val = ['width: ', (item2.width || options.cellMinWidth), 'px'].join(''); + text.push('.laytable-cell-'+ key +'{'+ val +'}'); + }); + }); + + // 自定义行样式 + (function (lineStyle) { + if (!lineStyle) return; + var trClassName = '.layui-table-view-'+ index +' .layui-table-body .layui-table tr'; + var rules = lineStyle.split(';'); + var cellMaxHeight = 'none'; + + // 计算单元格最大高度 + layui.each(rules, function(i, rule) { + rule = rule.split(':'); + if (rule[0] === 'height') { + var val = parseFloat(rule[1]); + if (!isNaN(val)) cellMaxHeight = (val - 1) + 'px'; + return true; + } + }); + + // 多行相关样式 + layui.each([ + '{'+ lineStyle +'}', + '.layui-table-cell{height: auto; max-height: '+ cellMaxHeight +'; white-space: normal; text-overflow: clip;}', + '> td:hover > .layui-table-cell{overflow: auto;}' + ].concat( + device.ie ? [ + '.layui-table-edit{height: '+ cellMaxHeight +';}', + 'td[data-edit]:hover:after{height: '+ cellMaxHeight +';}' + ] : [] + ), function(i, val) { + val && text.push(trClassName + ' ' + val); + }); + })(options.lineStyle); + + // 自定义 css 属性 + if (options.css) text.push(options.css); + + // 生成 style + lay.style({ + target: that.elem[0], + text: text.join(''), + id: 'DF-table-'+ index + }); + }; + + // 初始头部工具栏 Class.prototype.renderToolbar = function(){ - var that = this - var options = that.config + var that = this; + var options = that.config; + var filter = options.elem.attr('lay-filter'); // 添加工具栏左侧模板 var leftDefaultTemp = [ @@ -575,36 +643,164 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ ); } - // 添加工具栏右侧面板 - var layout = { + // 头部工具栏右上角默认工具 + var defaultConfig = { filter: { title: '筛选列', layEvent: 'LAYTABLE_COLS', - icon: 'layui-icon-cols' + icon: 'layui-icon-cols', + onClick: function(obj) { + var options = obj.config; + var openPanel = obj.openPanel; + + openPanel({ + list: function(){ + var lis = []; + that.eachCols(function(i, item){ + if(item.field && item.type == 'normal'){ + lis.push('
      • '); + } + }); + return lis.join(''); + }(), + done: function() { + form.on('checkbox(LAY_TABLE_TOOL_COLS)', function(obj){ + var othis = $(obj.elem); + var checked = this.checked; + var key = othis.data('key'); + var col = that.col(key); + var hide = col.hide; + var parentKey = othis.data('parentkey'); + + if(!col.key) return; + + // 同步勾选列的 hide 值和隐藏样式 + col.hide = !checked; + that.elem.find('*[data-key="'+ key +'"]')[ + checked ? 'removeClass' : 'addClass' + ](HIDE); + + // 根据列的显示隐藏,同步多级表头的父级相关属性值 + if(hide != col.hide){ + that.setParentCol(!checked, parentKey); + } + + // 重新适配尺寸 + that.resize(); + + // 列筛选(显示或隐藏)后的事件 + layui.event.call(this, MOD_NAME, 'colToggled('+ filter +')', { + col: col, + config: options + }); + }); + } + }); + } }, exports: { title: '导出', layEvent: 'LAYTABLE_EXPORT', - icon: 'layui-icon-export' + icon: 'layui-icon-export', + onClick: function(obj) { // 自带导出 + var data = obj.data; + var options = obj.config; + var openPanel = obj.openPanel; + var elem = obj.elem; + + if (!data.length) return layer.tips('当前表格无数据', elem, {tips: 3}); + if(device.ie){ + layer.tips('导出功能不支持 IE,请用 Chrome 等高级浏览器导出', elem, { + tips: 3 + }); + } else { + openPanel({ + list: function(){ + return [ + '
      • 导出 CSV 文件
      • ' + ].join('') + }(), + done: function(panel, list){ + list.on('click', function(){ + var type = $(this).data('type') + table.exportFile.call(that, options.id, null, type); + }); + } + }); + } + } }, print: { title: '打印', layEvent: 'LAYTABLE_PRINT', - icon: 'layui-icon-print' - } - }, iconElem = []; + icon: 'layui-icon-print', + onClick: function(obj) { + var data = obj.data; + var options = obj.config; + var elem = obj.elem; - if(typeof options.defaultToolbar === 'object'){ - layui.each(options.defaultToolbar, function(i, item){ - var thisItem = typeof item === 'string' ? layout[item] : item; - if(thisItem){ - iconElem.push('
        ' - +'' - +'
        '); + if (!data.length) return layer.tips('当前表格无数据', elem, {tips: 3}); + var printWin = window.open('about:blank', '_blank'); + var style = [''].join('') + var html = $(that.layHeader.html()); // 输出表头 + + html.append(that.layMain.find('table').html()); // 输出表体 + html.append(that.layTotal.find('table').html()) // 输出合计行 + + html.find('th.layui-table-patch').remove(); // 移除补丁 + // 移除表头特殊列 + html.find('thead>tr>th.'+ ELEM_COL_SPECIAL).filter(function(i, thElem){ + return !$(thElem).children('.'+ ELEM_GROUP).length; // 父级表头除外 + }).remove(); + html.find('tbody>tr>td.'+ ELEM_COL_SPECIAL).remove(); // 移除表体特殊列 + + printWin.document.write(style + html.prop('outerHTML')); + printWin.document.close(); + + if(layui.device('edg').edg){ + printWin.onafterprint = printWin.close; + printWin.print(); + }else{ + printWin.print(); + printWin.close(); + } } + } + }; + + // 若开启 defaultToolbar + if (typeof options.defaultToolbar === 'object') { + var iconElem = []; + options.defaultToolbar = $.map(options.defaultToolbar, function(item, i) { + var itemIsName = typeof item === 'string'; + var thisItem = itemIsName ? defaultConfig[item] : item; + if (thisItem) { + // 根据 name 匹配默认工具并合并 + if (thisItem.name && defaultConfig[thisItem.name]) { + thisItem = $.extend({}, defaultConfig[thisItem.name], thisItem); + } + // 初始化默认工具 name + if (!thisItem.name && itemIsName) { + thisItem.name = item; + } + // 图标列表 + iconElem.push( + '
        ' + +'' + +'
        ' + ); + } + return thisItem; }); + that.layTool.find('.layui-table-tool-self').html(iconElem.join('')); } - that.layTool.find('.layui-table-tool-self').html(iconElem.join('')); }; // 分页栏 @@ -784,7 +980,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 给未分配宽的列平均分配宽 if(item3.width === 0){ - that.getCssRule(item3.key, function(item){ + that.cssRules(item3.key, function(item){ item.style.width = Math.floor(function(){ if(autoWidth < minWidth) return minWidth; if(autoWidth > maxWidth) return maxWidth; @@ -795,7 +991,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 给设定百分比的列分配列宽 else if(/\d+%$/.test(item3.width)){ - that.getCssRule(item3.key, function(item){ + that.cssRules(item3.key, function(item){ var width = Math.floor((parseFloat(item3.width) / 100) * cntrWidth); width < minWidth && (width = minWidth); width > maxWidth && (width = maxWidth); @@ -805,7 +1001,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 给拥有普通 width 值的列分配最新列宽 else { - that.getCssRule(item3.key, function(item){ + that.cssRules(item3.key, function(item){ item.style.width = item3.width + 'px'; }); } @@ -828,7 +1024,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var th = getEndTh(); var key = th.data('key'); - that.getCssRule(key, function(item){ + that.cssRules(key, function(item){ var width = item.style.width || th.outerWidth(); item.style.width = (parseFloat(width) + patchNums) + 'px'; @@ -850,33 +1046,17 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ that.layMain.find('table').width('auto'); } - that.loading(!0); }; // 重置表格尺寸/结构 Class.prototype.resize = function(){ var that = this; - //soultable - //--- - var scrollTop = 0; - if (!!that.config.id) { - scrollTop = that.layMain[0].scrollTop; - } - //--- + + if (!that.layMain) return; + that.fullSize(); // 让表格铺满 that.setColsWidth(); // 自适应列宽 - that.scrollPatch(); // 滚动条补丁 - //soultable - //--- - if (layui.tableFilter) { - layui.tableFilter.resize(that.config); - if (!!that.config.id) { - that.layMain[0].scrollTop = scrollTop; - //同步更新滚动 - that.layFixed.find(ELEM_BODY).scrollTop(scrollTop); - } - } - //--- + that.scrollPatch(); // 滚动条补丁 }; // 表格重载 @@ -930,6 +1110,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ that.syncCheckAll(); that.renderForm(); that.setColsWidth(); + that.loading(false); }; // 初始页码 @@ -944,6 +1125,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ options.HAS_SET_COLS_PATCH = true; var request = options.request; var response = options.response; + var res; var sort = function(){ if(typeof options.initSort === 'object'){ that.sort({ @@ -955,6 +1137,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }; var done = function(res, origin){ that.setColsWidth(); + that.loading(false); typeof options.done === 'function' && options.done( res, curr, res[response.countName], origin ); @@ -969,7 +1152,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ that.startTime = new Date().getTime(); // 渲染开始时间 if (opts.renderData) { // 将 cache 信息重新渲染 - var res = {}; + res = {}; res[response.dataName] = table.cache[that.key]; res[response.countName] = options.url ? (layui.type(options.page) === 'object' ? options.page.count : res[response.dataName].length) : options.data.length; @@ -983,7 +1166,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ curr: curr, count: res[response.countName], type: opts.type, - }), sort(), done(res, 'renderData'); + sort: true + }), done(res, 'renderData'); } else if(options.url){ // Ajax请求 var params = {}; // 当 page 开启,默认自动传递 page、limit 参数 @@ -998,7 +1182,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ data = JSON.stringify(data); } - that.loading(); + that.loading(true); $.ajax({ type: options.method || 'get', @@ -1008,6 +1192,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ dataType: options.dataType || 'json', jsonpCallback: options.jsonpCallback, headers: options.headers || {}, + complete: typeof options.complete === 'function' ? options.complete : undefined, success: function(res){ // 若有数据解析的回调,则获得其返回的数据 if(typeof options.parseData === 'function'){ @@ -1031,7 +1216,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 耗时(接口请求+视图渲染) options.time = (new Date().getTime() - that.startTime) + ' ms'; } - done(res); + done(res, opts.type); }, error: function(e, msg){ that.errorView('请求异常,错误提示:'+ msg); @@ -1039,7 +1224,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ } }); } else if(layui.type(options.data) === 'array'){ //已知数据 - var res = {}; + res = {}; var startLimit = curr*options.limit - options.limit; var newData = options.data.concat(); @@ -1061,7 +1246,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ type: opts.type }), sort(); - done(res); + done(res, opts.type); } }; @@ -1092,8 +1277,10 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ curr = curr || 1 layui.each(data, function(i1, item1){ - var tds = [], tds_fixed = [], tds_fixed_r = [] - ,numbers = i1 + options.limit*(curr - 1) + 1; // 序号 + var tds = []; + var tds_fixed = []; + var tds_fixed_r = []; + var numbers = i1 + options.limit*(curr - 1) + 1; // 序号 // 数组值是否为 object,如果不是,则自动转为 object if(typeof item1 !== 'object'){ @@ -1123,34 +1310,31 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // td 内容 var td = ['' - ,'
        ' + +'>' + function(){ var tplData = $.extend(true, { LAY_COL: item3 @@ -1158,7 +1342,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var checkName = table.config.checkName; var disabledName = table.config.disabledName; - //渲染不同风格的列 + // 渲染不同风格的列 switch(item3.type){ case 'checkbox': // 复选 return ''; - break; + //break; case 'radio': // 单选 return ''; - break; + //break; case 'numbers': return numbers; - break; - }; + //break; + } //解析工具列模板 if(item3.toolbar){ @@ -1328,15 +1512,15 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ //同步分页状态 if(options.page){ options.page = $.extend({ - elem: 'layui-table-page' + options.index - ,count: count - ,limit: options.limit - ,limits: options.limits || [10,20,30,40,50,60,70,80,90] - ,groups: 3 - ,layout: ['prev', 'page', 'next', 'skip', 'count', 'limit'] - ,prev: '' - ,next: '' - ,jump: function(obj, first){ + elem: 'layui-table-page' + options.index, + count: count, + limit: options.limit, + limits: options.limits || [10,20,30,40,50,60,70,80,90], + groups: 3, + layout: ['prev', 'page', 'next', 'skip', 'count', 'limit'], + prev: '', + next: '', + jump: function(obj, first){ if(!first){ //分页本身并非需要做以下更新,下面参数的同步,主要是因为其它处理统一用到了它们 //而并非用的是 options.page 中的参数(以确保分页未开启的情况仍能正常使用) @@ -1413,9 +1597,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 获取自动计算的合并内容 var getContent = item3.totalRow ? (parseTempData.call(that, { - item3: item3 - ,content: thisTotalNum - ,tplData: tplData + item3: item3, + content: thisTotalNum, + tplData: tplData }) || text) : text; // 如果直接传入了合计行数据,则不输出自动计算的结果 @@ -1434,21 +1618,21 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var attr = []; if(item3.minWidth) attr.push('data-minwidth="'+ item3.minWidth +'"'); // 单元格最小宽度 if(item3.maxWidth) attr.push('data-maxwidth="'+ item3.maxWidth +'"'); // 单元格最小宽度 + if(item3.style) attr.push('style="'+ item3.style +'"'); // 自定义单元格样式 return attr.join(' '); }() +' class="'+ function(){ // 追加样式 var classNames = []; if(item3.hide) classNames.push(HIDE); // 插入隐藏列样式 if(!item3.field) classNames.push(ELEM_COL_SPECIAL); // 插入特殊列样式 return classNames.join(' '); - }() +'">' - ,'
        ', + '
        ' + function(){ var totalRow = item3.totalRow || options.totalRow; @@ -1462,8 +1646,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }, item3)); } return content; - }() - ,'
        '].join(''); + }(), + '
        '].join(''); tds.push(td); }); @@ -1474,8 +1658,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ //找到对应的列元素 Class.prototype.getColElem = function(parent, key){ - var that = this - ,options = that.config; + var that = this; + //var options = that.config; return parent.eq(0).find('.laytable-cell-'+ key + ':eq(0)'); }; @@ -1487,6 +1671,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ form.render(type, filter); }; + // 定向渲染表单 + Class.prototype.renderFormByElem = function(elem){ + layui.each(['input', 'select'], function(i, formType){ + form.render(elem.find(formType)); + }) + }; + // 同步全选按钮状态 Class.prototype.syncCheckAll = function(){ var that = this; @@ -1510,26 +1701,49 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ checked: checkStatus.isAll, indeterminate: !checkStatus.isAll && checkStatus.data.length // 半选 }); - form.render(checkAllElem); }; // 标记当前活动行背景色 - Class.prototype.setRowActive = function(index, className){ + Class.prototype.setRowActive = function(index, className, removeClass){ var that = this; var options = that.config; var tr = that.layBody.find('tr[data-index="'+ index +'"]'); className = className || 'layui-table-click'; - tr.addClass(className) - .siblings('tr').removeClass(className); + + if(removeClass) return tr.removeClass(className); + + tr.addClass(className); + tr.siblings('tr').removeClass(className); }; // 设置行选中状态 Class.prototype.setRowChecked = function(opts){ var that = this; var options = that.config; - var tr = that.layBody.find('tr'+ ( - opts.index === 'all' ? '' : '[data-index="'+ opts.index +'"]' - )); + var isCheckAll = opts.index === 'all'; // 是否操作全部 + var isCheckMult = layui.type(opts.index) === 'array'; // 是否操作多个 + var needDisableTransition= isCheckAll || isCheckMult; // 减少回流 + + if(needDisableTransition){ + that.layBox.addClass(DISABLED_TRANSITION); + } + + if(isCheckMult){ + var makeMap = {} + layui.each(opts.index, function(i,v){ + makeMap[v] = true; + }) + opts.index = makeMap; + } + + // 匹配行元素 + var selector = (isCheckAll || isCheckMult) ? 'tr' : 'tr[data-index="'+ opts.index +'"]'; + var tr = function(tr) { + return isCheckAll ? tr : tr.filter(isCheckMult ? function() { + var dataIndex = $(this).data('index'); + return opts.index[dataIndex]; + } : '[data-index="'+ opts.index +'"]'); + }(that.layBody.find(selector)); // 默认属性 opts = $.extend({ @@ -1539,36 +1753,84 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 同步数据选中属性值 var thisData = table.cache[that.key]; var existChecked = 'checked' in opts; + + // 若为单选框,则单向选中;若为复选框,则切换选中。 var getChecked = function(value){ - // 若为单选框,则单向选中;若为复选框,则切换选中。 return opts.type === 'radio' ? true : (existChecked ? opts.checked : !value) }; - // 设置数据选中属性 + var ignoreTrIndex = {}; + // 设置选中状态 layui.each(thisData, function(i, item){ - if(layui.type(item) === 'array') return; // 空项 - if(Number(opts.index) === i || opts.index === 'all'){ + // 绕过空项和禁用项 + if(layui.type(item) === 'array' || item[options.disabledName]){ + ignoreTrIndex[i] = true; + return; + } + + // 匹配条件 + var matched = isCheckAll || ( + isCheckMult ? opts.index[i] : Number(opts.index) === i + ); + + // 设置匹配项的选中值 + if(matched){ + // 标记数据选中状态 var checked = item[options.checkName] = getChecked(item[options.checkName]); - tr[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 标记当前选中行背景色 - // 若为 radio 类型,则取消其他行选中背景色 - if(opts.type === 'radio'){ - tr.siblings().removeClass(ELEM_CHECKED); + + // 标记当前行背景色 + // 此处只更新 radio 和 单个 checkbox + if(!isCheckAll && !isCheckMult){ + var currTr = tr.filter('[data-index="'+ i +'"]'); + currTr[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); + + // 若为 radio 类型,则取消其他行选中背景色 + if(opts.type === 'radio'){ + currTr.siblings().removeClass(ELEM_CHECKED); + } } } else if(opts.type === 'radio') { delete item[options.checkName]; } }); + if(isCheckAll){ + tr.each(function(i){ + var index = this.getAttribute('data-index'); + if(!ignoreTrIndex[index]){ + var el = $(this); + el.toggleClass(ELEM_CHECKED, !!getChecked(thisData[index][options.checkName])) + } + }); + }else if(isCheckMult){ + tr.each(function(i){ + var index = this.getAttribute('data-index'); + if(opts.index[index] && !ignoreTrIndex[index]){ + var el = $(this); + el.toggleClass(ELEM_CHECKED, !!getChecked(thisData[index][options.checkName])) + } + }); + } + // 若存在复选框或单选框,则标注选中状态样式 var checkedElem = tr.find('input[lay-type="'+ ({ radio: 'layTableRadio', checkbox: 'layTableCheckbox' - }[opts.type] || 'checkbox') +'"]'); + }[opts.type] || 'checkbox') +'"]:not(:disabled)'); + var checkedSameElem = checkedElem.last(); + var fixRElem = checkedSameElem.closest(ELEM_FIXR); - checkedElem.prop('checked', getChecked(checkedElem.last().prop('checked'))); + ( opts.type === 'radio' && fixRElem.hasClass(HIDE) + ? checkedElem.first() + : checkedElem ).prop('checked', getChecked(checkedSameElem.prop('checked'))); that.syncCheckAll(); - that.renderForm(opts.type); + + if(needDisableTransition){ + setTimeout(function(){ + that.layBox.removeClass(DISABLED_TRANSITION); + },100) + } }; // 数据排序 @@ -1586,8 +1848,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ if(typeof opts.field === 'string'){ field = opts.field; that.layHeader.find('th').each(function(i, item){ - var othis = $(this) - ,_field = othis.data('field'); + var othis = $(this); + var _field = othis.data('field'); if(_field === opts.field){ opts.field = othis; field = _field; @@ -1597,8 +1859,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ } try { - var field = field || opts.field.data('field') - ,key = opts.field.data('key'); + field = field || opts.field.data('field'); + var key = opts.field.data('key'); // 如果欲执行的排序已在状态中,则不执行渲染 if(that.sortKey && !opts.pull){ @@ -1617,8 +1879,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 记录排序索引和类型 that.sortKey = { - field: field - ,sort: opts.type + field: field, + sort: opts.type }; // 默认为前端自动排序。如果否,则需自主排序(通常为服务端处理好排序) @@ -1648,8 +1910,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 排序是否来自于点击表头事件触发 if(opts.fromEvent){ options.initSort = { - field: field - ,type: opts.type + field: field, + type: opts.type }; layui.event.call(opts.field, MOD_NAME, 'sort('+ filter +')', $.extend({ config: options @@ -1658,52 +1920,47 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }; // 请求 loading - Class.prototype.loading = function(hide){ + Class.prototype.loading = function(show){ var that = this; var options = that.config; + if(options.loading){ - if(hide){ - that.layInit && that.layInit.remove(); - delete that.layInit; - that.layBox.find(ELEM_INIT).remove(); - } else { - that.layInit = $(['
        ' - ,'' - ,'
        '].join('')); - that.layBox.append(that.layInit); - } + that.layBox.find(ELEM_INIT).toggleClass(HIDE_V, !show); } }; - // 获取 cssRule - Class.prototype.getCssRule = function(key, callback){ + // 获取对应单元格的 cssRules + Class.prototype.cssRules = function(key, callback){ var that = this; - var style = that.elem.find('style')[0]; - var sheet = style.sheet || style.styleSheet || {}; - var rules = sheet.cssRules || sheet.rules; + var style = that.elem.children('style')[0]; - layui.each(rules, function(i, item){ - if(item.selectorText === ('.laytable-cell-'+ key)){ - return callback(item), true; + lay.getStyleRules(style, function(item){ + if (item.selectorText === ('.laytable-cell-'+ key)) { + callback(item); + return true; } }); }; - //让表格铺满 + // 让表格铺满 Class.prototype.fullSize = function(){ - var that = this - ,options = that.config - ,height = options.height - ,bodyHeight; + var that = this; + var options = that.config; + var height = options.height; + var bodyHeight; + var MIN_HEIGHT = 135; if(that.fullHeightGap){ height = _WIN.height() - that.fullHeightGap; - if(height < 135) height = 135; + if(height < MIN_HEIGHT) height = MIN_HEIGHT; // that.elem.css('height', height); } else if (that.parentDiv && that.parentHeightGap) { height = $(that.parentDiv).height() - that.parentHeightGap; - if (height < 135) height = 135; + if(height < MIN_HEIGHT) height = MIN_HEIGHT; // that.elem.css("height", height); + } else if (that.customHeightFunc) { + height = that.customHeightFunc(); + if(height < MIN_HEIGHT) height = MIN_HEIGHT; } // 如果多级表头,则填补表头高度 @@ -1752,7 +2009,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ //获取滚动条宽度 Class.prototype.getScrollWidth = function(elem){ - var width = 0; + var width; if(elem){ width = elem.offsetWidth - elem.clientWidth; } else { @@ -1772,19 +2029,19 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ Class.prototype.scrollPatch = function(){ var that = this; var layMainTable = that.layMain.children('table'); - var scollWidth = that.layMain.width() - that.layMain.prop('clientWidth'); // 纵向滚动条宽度 - var scollHeight = that.layMain.height() - that.layMain.prop('clientHeight'); // 横向滚动条高度 + var scrollWidth = that.layMain.width() - that.layMain.prop('clientWidth'); // 纵向滚动条宽度 + var scrollHeight = that.layMain.height() - that.layMain.prop('clientHeight'); // 横向滚动条高度 var getScrollWidth = that.getScrollWidth(that.layMain[0]); // 获取主容器滚动条宽度,如果有的话 var outWidth = layMainTable.outerWidth() - that.layMain.width(); // 表格内容器的超出宽度 // 添加补丁 var addPatch = function(elem){ - if(scollWidth && scollHeight){ + if(scrollWidth && scrollHeight){ elem = elem.eq(0); if(!elem.find('.layui-table-patch')[0]){ var patchElem = $('
        '); // 补丁元素 patchElem.find('div').css({ - width: scollWidth + width: scrollWidth }); elem.find('tr').append(patchElem); } @@ -1798,7 +2055,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 固定列区域高度 var mainHeight = that.layMain.height(); - var fixHeight = mainHeight - scollHeight; + var fixHeight = mainHeight - scrollHeight; that.layFixed.find(ELEM_BODY).css( 'height', @@ -1813,9 +2070,76 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ ](HIDE); // 操作栏 - that.layFixRight.css('right', scollWidth - 1); + that.layFixRight.css('right', scrollWidth - 1); }; + /** + * @typedef updateRowOptions + * @prop {number} index - 行索引 + * @prop {Object.} data - 行数据 + * @prop {boolean | ((field, index) => boolean)} [related] - 更新其他包含自定义模板且可能有所关联的列视图 + */ + /** + * 更新指定行 + * @param {updateRowOptions | updateRowOptions[]} opts + * @param {(field: string, value: any) => void} [callback] - 更新每个字段时的回调函数 + */ + Class.prototype.updateRow = function(opts, callback){ + var that = this; + var ELEM_CELL = '.layui-table-cell'; + var opts = layui.type(opts) === 'array' ? opts : [opts]; + var dataCache = table.cache[that.key] || []; + + var update = function(opt){ + var index = opt.index; + var row = opt.data; + var related = opt.related; + + var data = dataCache[index] || {}; + var tr = that.layBody.find('tr[data-index="' + index + '"]'); + + // 更新缓存中的数据 + layui.each(row, function (key, value) { + data[key] = value; + callback && callback(key, value); + }); + + // 更新单元格 + that.eachCols(function (i, item3) { + var field = String(item3.field || i); + var shouldUpdate = field in row || ((typeof related === 'function' ? related(field, i) : related) && (item3.templet || item3.toolbar)); + if(shouldUpdate){ + var td = tr.children('td[data-field="' + field + '"]'); + var cell = td.children(ELEM_CELL); + var content = data[item3.field]; + cell.html(parseTempData.call(that, { + item3: item3, + content: content, + tplData: $.extend({ + LAY_COL: item3, + }, data) + })); + td.data("content", content); + that.renderFormByElem(cell); + } + }); + } + + layui.each(opts, function(i, opt){ + update(opt); + }); + }; + + /** + * 更新指定行 + * @param {string} id - table ID + * @param {updateRowOptions | updateRowOptions[]} options + */ + table.updateRow = function (id, options){ + var that = getThisTable(id); + return that.updateRow(options); + } + // 事件处理 Class.prototype.events = function(){ var that = this; @@ -1832,7 +2156,10 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ that.layTool.on('click', '*[lay-event]', function(e){ var othis = $(this); var events = othis.attr('lay-event'); - var openPanel = function(sets){ + var data = table.cache[options.id]; + + // 弹出工具下拉面板 + var openPanel = function(sets) { var list = $(sets.list); var panel = $('
          '); @@ -1858,112 +2185,23 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ _DOC.trigger('table.tool.panel.remove'); layer.close(that.tipsIndex); - switch(events){ - case 'LAYTABLE_COLS': // 筛选列 - openPanel({ - list: function(){ - var lis = []; - that.eachCols(function(i, item){ - if(item.field && item.type == 'normal'){ - lis.push('
        • '); - } - }); - return lis.join(''); - }() - ,done: function(){ - form.on('checkbox(LAY_TABLE_TOOL_COLS)', function(obj){ - var othis = $(obj.elem); - var checked = this.checked; - var key = othis.data('key'); - var col = that.col(key); - var hide = col.hide; - var parentKey = othis.data('parentkey'); - - if(!col.key) return; - - // 同步勾选列的 hide 值和隐藏样式 - col.hide = !checked; - that.elem.find('*[data-key="'+ key +'"]')[ - checked ? 'removeClass' : 'addClass' - ](HIDE); - - // 根据列的显示隐藏,同步多级表头的父级相关属性值 - if(hide != col.hide){ - that.setParentCol(!checked, parentKey); - } - - // 重新适配尺寸 - that.resize(); - - // 列筛选(显示或隐藏)后的事件 - layui.event.call(this, MOD_NAME, 'colToggled('+ filter +')', { - col: col, - config: options - }); - }); - } + // 头部工具栏右侧图标 + layui.each(options.defaultToolbar, function(index, item) { + if (item.layEvent === events) { + typeof item.onClick === 'function' && item.onClick({ + data: data, + config: options, + openPanel: openPanel, + elem: othis }); - break; - case 'LAYTABLE_EXPORT': // 导出 - if(device.ie){ - layer.tips('导出功能不支持 IE,请用 Chrome 等高级浏览器导出', this, { - tips: 3 - }) - } else { - openPanel({ - list: function(){ - return [ - '
        • 导出 csv 格式文件
        • ', - '
        • 导出 xls 格式文件
        • ' - ].join('') - }() - ,done: function(panel, list){ - list.on('click', function(){ - var type = $(this).data('type') - table.exportFile.call(that, options.id, null, type); - }); - } - }); - } - break; - case 'LAYTABLE_PRINT': // 打印 - var printWin = window.open('about:blank', '_blank'); - var style = [''].join('') - var html = $(that.layHeader.html()); // 输出表头 - - html.append(that.layMain.find('table').html()); // 输出表体 - html.append(that.layTotal.find('table').html()) // 输出合计行 - - html.find('th.layui-table-patch').remove(); // 移除补丁 - // 移除表头特殊列 - html.find('thead>tr>th.'+ ELEM_COL_SPECIAL).filter(function(i, thElem){ - return !$(thElem).children('.'+ ELEM_GROUP).length; // 父级表头除外 - }).remove(); - html.find('tbody>tr>td.'+ ELEM_COL_SPECIAL).remove(); // 移除表体特殊列 - - printWin.document.write(style + html.prop('outerHTML')); - printWin.document.close(); - - if(layui.device('edg').edg){ - printWin.onafterprint = printWin.close; - printWin.print(); - }else{ - printWin.print(); - printWin.close(); - } - break; - } + return true; + } + }); + // table toolbar 事件 layui.event.call(this, MOD_NAME, 'toolbar('+ filter +')', $.extend({ - event: events - ,config: options + event: events, + config: options },{})); }); @@ -1988,16 +2226,16 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var events = othis.attr('lay-event'); layui.event.call(this, MOD_NAME, 'pagebar('+ filter +')', $.extend({ - event: events - ,config: options + event: events, + config: options },{})); }); // 拖拽调整宽度 th.on('mousemove', function(e){ - var othis = $(this) - ,oLeft = othis.offset().left - ,pLeft = e.clientX - oLeft; + var othis = $(this); + var oLeft = othis.offset().left; + var pLeft = e.clientX - oLeft; if(othis.data('unresize') || thisTable.eventMoveElem){ return; } @@ -2006,6 +2244,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }).on('mouseleave', function(){ var othis = $(this); if(thisTable.eventMoveElem) return; + dict.allowResize = false; _BODY.css('cursor', ''); }).on('mousedown', function(e){ var othis = $(this); @@ -2014,7 +2253,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ e.preventDefault(); dict.offset = [e.clientX, e.clientY]; //记录初始坐标 - that.getCssRule(key, function(item){ + that.cssRules(key, function(item){ var width = item.style.width || othis.outerWidth(); dict.rule = item; dict.ruleWidth = parseFloat(width); @@ -2039,7 +2278,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ if(dict.rule){ var setWidth = dict.ruleWidth + e.clientX - dict.offset[0]; - var id = thisTable.eventMoveElem.closest('.' + ELEM_VIEW).attr('lay-id'); + var id = thisTable.eventMoveElem.closest('.' + ELEM_VIEW).attr(MOD_ID); var thatTable = getThisTable(id); if(!thatTable) return; @@ -2055,7 +2294,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }).on('mouseup', function(e){ if(thisTable.eventMoveElem){ var th = thisTable.eventMoveElem; // 当前触发拖拽的 th 元素 - var id = th.closest('.' + ELEM_VIEW).attr('lay-id'); + var id = th.closest('.' + ELEM_VIEW).attr(MOD_ID); var thatTable = getThisTable(id); if(!thatTable) return; @@ -2074,7 +2313,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ delete thisTable.eventMoveElem; // 列拖拽宽度后的事件 - thatTable.getCssRule(key, function(item){ + thatTable.cssRules(key, function(item){ col.width = parseFloat(item.style.width); layui.event.call(th[0], MOD_NAME, 'colResized('+ filter +')', { col: col, @@ -2114,9 +2353,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ fromEvent: true }); }).find(ELEM_SORT+' .layui-edge ').on('click', function(e){ - var othis = $(this) - ,index = othis.index() - ,field = othis.parents('th').eq(0).data('field') + var othis = $(this); + var index = othis.index(); + var field = othis.parents('th').eq(0).data('field'); layui.stope(e); if(index === 0){ that.sort({ @@ -2156,43 +2395,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }, update: function(fields, related){ // 修改行数据 fields = fields || {}; - layui.each(fields, function(key, value){ - var td = tr.children('td[data-field="'+ key +'"]'); - var cell = td.children(ELEM_CELL); // 获取当前修改的列 - - // 更新缓存中的数据 - data[key] = obj.data[key] = value; - - // 更新相应列视图 - that.eachCols(function(i, item3){ - if(item3.field == key){ - cell.html(parseTempData.call(that, { - item3: item3 - ,content: value - ,tplData: $.extend({ - LAY_COL: item3 - }, data) - })); - td.data('content', value); - } - // 更新其他包含自定义模板且可能有所关联的列视图 - else if(related && (item3.templet || item3.toolbar)){ - var thisTd = tr.children('td[data-field="'+ (item3.field || i) +'"]'); - var content = data[item3.field]; - - thisTd.children(ELEM_CELL).html(parseTempData.call(that, { - item3: item3 - ,content: content - ,tplData: $.extend({ - LAY_COL: item3 - }, data) - })); - thisTd.data('content', content); - } - }); + that.updateRow({ + index: index, + data: fields, + related: related + }, function(key, value){ + obj.data[key] = value; }); - - that.renderForm(); }, // 设置行选中状态 setRowChecked: function(opts){ @@ -2288,26 +2497,39 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ if(othis.data('off')) return; // 不触发事件 that.layBody.find('tr:eq('+ index +')').removeClass(ELEM_HOVER) }).on('click', 'tr', function(e){ // 单击行 - // 不支持行单击事件的元素 - var UNROW = '.layui-form-checkbox,.layui-form-switch,.layui-form-radio,[lay-unrow]'; - if( $(e.target).is(UNROW) || $(e.target).closest(UNROW)[0]){ - return; - }; - setRowEvent.call(this, 'row'); - }).on('dblclick', 'tr', function(){ // 双击行 - setRowEvent.call(this, 'rowDouble'); + setRowEvent.call(this, 'row', e); + }).on('dblclick', 'tr', function(e){ // 双击行 + setRowEvent.call(this, 'rowDouble', e); }).on('contextmenu', 'tr', function(e){ // 菜单 if (!options.defaultContextmenu) e.preventDefault(); - setRowEvent.call(this, 'rowContextmenu'); + setRowEvent.call(this, 'rowContextmenu', e); }); // 创建行单击、双击、菜单事件 - var setRowEvent = function(eventType){ + var setRowEvent = function(eventType, e){ var othis = $(this); - if(othis.data('off')) return; //不触发事件 - layui.event.call(this, + if(othis.data('off')) return; // 不触发事件 + + // 不触发「行单/双击事件」的子元素 + if (eventType !== 'rowContextmenu') { + var UNROW = [ + '.layui-form-checkbox', + '.layui-form-switch', + '.layui-form-radio', + '[lay-unrow]' + ].join(','); + + if($(e.target).is(UNROW) || $(e.target).closest(UNROW)[0]){ + return; + } + } + + layui.event.call( + this, MOD_NAME, eventType + '('+ filter +')', - commonMember.call(othis.children('td')[0]) + commonMember.call(othis.children('td')[0], { + e: e + }) ); }; @@ -2339,8 +2561,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ } return inputElem; }()); - - input[0].value = othis.data('content') || data[field] || elemCell.text(); + input[0].value = function(val) { + return (val === undefined || val === null) ? '' : val; + }(othis.data('content') || data[field]); othis.find('.'+ELEM_EDIT)[0] || othis.append(input); input.focus(); e && layui.stope(e); @@ -2391,7 +2614,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 表格主体单元格触发编辑的事件 that.layBody.on(options.editTrigger, 'td', function(e){ - renderGridEdit(this, e) + renderGridEdit(this, e); }).on('mouseenter', 'td', function(){ showGridExpandIcon.call(this) }).on('mouseleave', 'td', function(){ @@ -2413,51 +2636,106 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var othis = $(this); var elemCell = othis.children(ELEM_CELL); - if(othis.data('off')) return; //不触发事件 + if(othis.data('off')) return; // 不触发事件 + if(othis.parent().hasClass(ELEM_EXPAND)) return; // 是否已为展开状态 if(hide){ othis.find('.layui-table-grid-down').remove(); } else if(( - elemCell.prop('scrollWidth') > elemCell.outerWidth() || + elemCell.prop('scrollWidth') > elemCell.prop('clientWidth') || elemCell.find("br").length > 0 ) && !options.lineStyle){ if(elemCell.find('.'+ ELEM_GRID_DOWN)[0]) return; othis.append('
          '); } }; - // 单元格内容展开 - var gridExpand = function(e){ + // 展开单元格内容 + var gridExpand = function(e, expandedMode){ var othis = $(this); var td = othis.parent(); + var key = td.data('key'); + var col = that.col(key); + var index = td.parent().data('index'); var elemCell = td.children(ELEM_CELL); + var ELEM_CELL_C = 'layui-table-cell-c'; + var elemCellClose = $(''); - that.tipsIndex = layer.tips([ - '
          ', + elemCell.html(), + '
          ', + '' + ].join(''), elemCell[0], { + tips: [3, ''], + time: -1, + anim: -1, + maxWidth: (device.ios || device.android) ? 300 : that.elem.width()/2, + isOutAnim: false, + skin: 'layui-table-tips', + success: function(layero, index){ + layero.find('.layui-table-tips-c').on('click', function(){ + layer.close(index); + }); } - if(options.size === 'lg'){ - return 'padding: 14px 15px;'; - } - return ''; - }() +'">', - elemCell.html(), - '
          ', - '' - ].join(''), elemCell[0], { - tips: [3, ''], - time: -1, - anim: -1, - maxWidth: (device.ios || device.android) ? 300 : that.elem.width()/2, - isOutAnim: false, - skin: 'layui-table-tips', - success: function(layero, index){ - layero.find('.layui-table-tips-c').on('click', function(){ - layer.close(index); + }); + } else { // 多行展开风格 + // 恢复其他已经展开的单元格 + that.elem.find('.'+ ELEM_CELL_C).trigger('click'); + + // 设置当前单元格展开宽度 + that.cssRules(key, function(item){ + var width = item.style.width; + var expandedWidth = col.expandedWidth || options.cellExpandedWidth; + + // 展开后的宽度不能小于当前宽度 + if(expandedWidth < parseFloat(width)) expandedWidth = parseFloat(width); + + elemCellClose.data('cell-width', width); + item.style.width = expandedWidth + 'px'; + + setTimeout(function(){ + that.scrollPatch(); // 滚动条补丁 }); - } - }); + }); + // 设置当前单元格展开样式 + that.setRowActive(index, ELEM_EXPAND); + + // 插入关闭按钮 + if(!elemCell.next('.'+ ELEM_CELL_C)[0]){ + elemCell.after(elemCellClose); + } + + // 关闭展开状态 + elemCellClose.on('click', function(){ + var $this = $(this); + that.setRowActive(index, [ELEM_EXPAND, ELEM_HOVER].join(' '), true); // 移除单元格展开样式 + that.cssRules(key, function(item){ + item.style.width = $this.data('cell-width'); // 恢复单元格展开前的宽度 + setTimeout(function(){ + that.resize(); // 滚动条补丁 + }); + }); + $this.remove(); + // 重置单元格滚动条位置 + elemCell.scrollTop(0); + elemCell.scrollLeft(0); + }); + } + + othis.remove(); layui.stope(e); }; @@ -2467,7 +2745,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ }); // 表格合计栏单元格展开事件 that.layTotal.on('click', '.'+ ELEM_GRID_DOWN, function(e){ - gridExpand.call(this, e); + gridExpand.call(this, e, 'tips'); // 强制采用 tips 风格 }); // 行工具条操作事件 @@ -2514,20 +2792,41 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ layer.close(that.tipsIndex); }); - // 适应 - _WIN.on('resize', function(){ - that.resize(); + // 固定列滚轮事件 - 临时兼容方案 + that.layFixed.find(ELEM_BODY).on('mousewheel DOMMouseScroll', function(e) { + var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail; + var scrollTop = that.layMain.scrollTop(); + var step = 30; + + e.preventDefault(); + that.layMain.scrollTop(scrollTop + (delta > 0 ? -step : step)); }); + + if(window.ResizeObserver){ + if(!that.resizeObserver){ + that.resizeObserver = new ResizeObserver(function(){ + table.resize(that.key); + }); + } + that.resizeObserver.observe(that.elem[0]); + } }; - //一次性事件 - ;(function(){ - //全局点击 + // 全局事件 + (function(){ + // 自适应尺寸 + _WIN.on('resize', function(){ + layui.each(thisTable.that, function(){ + this.resize(); + }); + }); + + // 全局点击 _DOC.on('click', function(){ _DOC.trigger('table.remove.tool.panel'); }); - //工具面板移除事件 + // 工具面板移除事件 _DOC.on('table.remove.tool.panel', function(){ $('.' + ELEM_TOOL_PANEL).remove(); }); @@ -2578,8 +2877,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var row = $.extend({ title: th.text() - ,colspan: parseInt(th.attr('colspan')) || 0 //列单元格 - ,rowspan: parseInt(th.attr('rowspan')) || 0 //行单元格 + ,colspan: parseInt(th.attr('colspan')) || 1 //列单元格 + ,rowspan: parseInt(th.attr('rowspan')) || 1 //行单元格 }, itemData); options.cols[i].push(row); @@ -2648,8 +2947,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 遍历表头 table.eachCols = function(id, callback, cols){ - var config = thisTable.config[id] || {} - ,arrs = [], index = 0; + var config = thisTable.config[id] || {}; + var arrs = [], index = 0; cols = $.extend(true, [], cols || config.cols); @@ -2683,7 +2982,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ //计算全选个数 layui.each(data, function(i, item){ - if(layui.type(item) === 'array'){ + if(layui.type(item) === 'array' || item[table.config.disabledName]){ invalidNum++; // 无效数据,或已删除的 return; } @@ -2709,12 +3008,12 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 获取表格当前页的所有行数据 table.getData = function(id){ - var arr = [] - ,data = table.cache[id] || []; + var arr = []; + var data = table.cache[id] || []; layui.each(data, function(i, item){ if(layui.type(item) === 'array'){ return; - }; + } arr.push(table.clearCacheKey(item)); }); return arr; @@ -2749,13 +3048,28 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var thatTable = thisTable.that[id]; var config = thisTable.config[id] || {}; var textType = ({ - csv: 'text/csv' - ,xls: 'application/vnd.ms-excel' + csv: 'text/csv', + xls: 'application/vnd.ms-excel' })[type]; var alink = document.createElement("a"); if(device.ie) return hint.error('IE_NOT_SUPPORT_EXPORTS'); + // 处理 treeTable 数据 + var isTreeTable = config.tree && config.tree.view; + if (isTreeTable) { + try { + data = $.extend(true, [], table.cache[id]); + data = (function fn(data) { + return data.reduce(function (acc, obj){ + var children = obj.children || []; + delete obj.children; + return acc.concat(obj, fn(children)); + }, []); + })(Array.from(data)); + } catch (e) {} + } + alink.href = 'data:'+ textType +';charset=utf-8,\ufeff'+ encodeURIComponent(function(){ var dataTitle = []; var dataMain = []; @@ -2775,8 +3089,11 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ } else { table.eachCols(id, function(i3, item3){ if(item3.ignoreExport === false || item3.field && item3.type == 'normal'){ - // 不导出隐藏列 - if(item3.hide || item3.ignoreExport){ + // 不导出隐藏列,除非设置 ignoreExport 强制导出 + if ( + (item3.hide && item3.ignoreExport !== false) || + item3.ignoreExport === true // 忽略导出 + ) { if(i1 == 0) fieldsIsHide[item3.field] = true; // 记录隐藏列 return; } @@ -2788,12 +3105,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 解析内容 content = parseTempData.call(thatTable, { - item3: item3 - ,content: content - ,tplData: item1 - ,text: 'text' - ,obj: { + item3: item3, + content: content, + tplData: item1, + text: 'text', + obj: { td: function(field){ + if (isTreeTable) i1 = item1['LAY_DATA_INDEX']; // 兼容 treeTable 索引 var td = thatTable.layBody.find('tr[data-index="'+ i1 +'"]>td'); return td.filter('[data-field="'+ field +'"]'); } @@ -2807,6 +3125,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ // 插入内容 vals.push(content); + }else if(item3.field && item3.type !== 'normal'){ + // https://gitee.com/layui/layui/issues/I8PHCR + if(i1 == 0) fieldsIsHide[item3.field] = true; } }); } @@ -2901,7 +3222,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ var dataParams = new RegExp('^('+ [ 'elem', 'id', 'cols', 'width', 'height', 'maxHeight', 'toolbar', 'defaultToolbar', - 'className', 'css', 'totalRow', 'pagebar' + 'className', 'css', 'pagebar' ].join('|') + ')$'); // 过滤与数据无关的参数 @@ -2937,5 +3258,3 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){ exports(MOD_NAME, table); }); - - diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js index aa1adcd..200eb28 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js @@ -56,7 +56,7 @@ layui.define(['laytpl', 'form'], function(exports){ var getThisModuleConfig = function(id){ var config = thisModule.config[id]; if(!config) hint.error('The ID option was not found in the '+ MOD_NAME +' instance'); - return; config || null; + return config || null; }; // 字符常量 @@ -73,39 +73,39 @@ layui.define(['laytpl', 'form'], function(exports){ // 穿梭框模板 var TPL_BOX = function(obj){ obj = obj || {}; - return ['
          ' - ,'
          ' - ,'' - ,'
          ' - ,'{{# if(d.data.showSearch){ }}' - ,'' - ,'{{# } }}' - ,'
            ' - ,'
            '].join(''); + return ['
            ', + '
            ', + '', + '
            ', + '{{# if(d.data.showSearch){ }}', + '', + '{{# } }}', + '
              ', + '
              '].join(''); }; // 主模板 - var TPL_MAIN = ['
              ' - ,TPL_BOX({ - index: 0 - ,checkAllName: 'layTransferLeftCheckAll' - }) - ,'
              ' - ,'' - ,'' - ,'
              ' - ,TPL_BOX({ - index: 1 - ,checkAllName: 'layTransferRightCheckAll' - }) - ,'
              '].join(''); + var TPL_MAIN = ['
              ', + TPL_BOX({ + index: 0, + checkAllName: 'layTransferLeftCheckAll' + }), + '
              ', + '', + '', + '
              ', + TPL_BOX({ + index: 1, + checkAllName: 'layTransferRightCheckAll' + }), + '
              '].join(''); // 构造器 var Class = function(options){ @@ -115,7 +115,7 @@ layui.define(['laytpl', 'form'], function(exports){ that.render(); }; - //默认配置 + // 默认配置 Class.prototype.config = { title: ['列表一', '列表二'], width: 200, @@ -130,31 +130,31 @@ layui.define(['laytpl', 'form'], function(exports){ } }; - //重载实例 + // 重载实例 Class.prototype.reload = function(options){ var that = this; that.config = $.extend({}, that.config, options); that.render(); }; - //渲染 + // 渲染 Class.prototype.render = function(){ var that = this; var options = that.config; - //解析模板 + // 解析模板 var thisElem = that.elem = $(laytpl(TPL_MAIN, { open: '{{', // 标签符前缀 close: '}}' // 标签符后缀 }).render({ - data: options - ,index: that.index //索引 + data: options, + index: that.index // 索引 })); var othis = options.elem = $(options.elem); if(!othis[0]) return; - //初始化属性 + // 初始化属性 options.data = options.data || []; options.value = options.value || []; @@ -164,20 +164,20 @@ layui.define(['laytpl', 'form'], function(exports){ ); that.key = options.id; - //插入组件结构 + // 插入组件结构 othis.html(that.elem); - //各级容器 + // 各级容器 that.layBox = that.elem.find('.'+ ELEM_BOX) that.layHeader = that.elem.find('.'+ ELEM_HEADER) that.laySearch = that.elem.find('.'+ ELEM_SEARCH) that.layData = thisElem.find('.'+ ELEM_DATA); that.layBtn = thisElem.find('.'+ ELEM_ACTIVE + ' .layui-btn'); - //初始化尺寸 + // 初始化尺寸 that.layBox.css({ - width: options.width - ,height: options.height + width: options.width, + height: options.height }); that.layData.css({ height: function(){ @@ -189,8 +189,8 @@ layui.define(['laytpl', 'form'], function(exports){ }() }); - that.renderData(); //渲染数据 - that.events(); //事件 + that.renderData(); // 渲染数据 + that.events(); // 事件 }; // 渲染数据 @@ -233,27 +233,28 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderCheckBtn(); }; - //渲染表单 + // 渲染表单 Class.prototype.renderForm = function(type){ form.render(type, 'LAY-transfer-'+ this.index); }; - //同步复选框和按钮状态 + // 同步复选框和按钮状态 Class.prototype.renderCheckBtn = function(obj){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; obj = obj || {}; that.layBox.each(function(_index){ - var othis = $(this) - ,thisDataElem = othis.find('.'+ ELEM_DATA) - ,allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]') - ,listElemCheckbox = thisDataElem.find('input[type="checkbox"]'); + var othis = $(this); + var thisDataElem = othis.find('.'+ ELEM_DATA); + var allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]'); + var listElemCheckbox = thisDataElem.find('input[type="checkbox"]'); - //同步复选框和按钮状态 - var nums = 0 - ,haveChecked = false; + // 同步复选框和按钮状态 + var nums = 0; + var haveChecked = false; + listElemCheckbox.each(function(){ var isHide = $(this).data('hide'); if(this.checked || this.disabled || isHide){ @@ -264,10 +265,10 @@ layui.define(['laytpl', 'form'], function(exports){ } }); - allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); //全选复选框状态 - that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); //对应的按钮状态 + allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); // 全选复选框状态 + that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); // 对应的按钮状态 - //无数据视图 + // 无数据视图 if(!obj.stopNone){ var isNone = thisDataElem.children('li:not(.'+ HIDE +')').length that.noneView(thisDataElem, isNone ? '' : options.text.none); @@ -277,7 +278,7 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderForm('checkbox'); }; - //无数据视图 + // 无数据视图 Class.prototype.noneView = function(thisDataElem, text){ var createNoneElem = $('

              '+ (text || '') +'

              '); if(thisDataElem.find('.'+ NONE)[0]){ @@ -286,11 +287,12 @@ layui.define(['laytpl', 'form'], function(exports){ text.replace(/\s/g, '') && thisDataElem.append(createNoneElem); }; - //同步 value 属性值 + // 同步 value 属性值 Class.prototype.setValue = function(){ - var that = this - ,options = that.config - ,arr = []; + var that = this; + var options = that.config; + var arr = []; + that.layBox.eq(1).find('.'+ ELEM_DATA +' input[type="checkbox"]').each(function(){ var isHide = $(this).data('hide'); isHide || arr.push(this.value); @@ -300,14 +302,14 @@ layui.define(['laytpl', 'form'], function(exports){ return that; }; - //解析数据 + // 解析数据 Class.prototype.parseData = function(callback){ - var that = this - ,options = that.config - ,newData = []; + var that = this; + var options = that.config; + var newData = []; layui.each(options.data, function(index, item){ - //解析格式 + // 解析格式 item = (typeof options.parseData === 'function' ? options.parseData(item) : item) || item; @@ -326,11 +328,11 @@ layui.define(['laytpl', 'form'], function(exports){ return that; }; - //获得右侧面板数据 + // 获得右侧面板数据 Class.prototype.getData = function(value){ - var that = this - ,options = that.config - ,selectedData = []; + var that = this; + var options = that.config; + var selectedData = []; that.setValue(); @@ -345,30 +347,30 @@ layui.define(['laytpl', 'form'], function(exports){ return selectedData; }; - //执行穿梭 + // 执行穿梭 Class.prototype.transfer = function (_index, elem) { - var that = this - ,options = that.config - ,thisBoxElem = that.layBox.eq(_index) - ,arr = [] + var that = this; + var options = that.config; + var thisBoxElem = that.layBox.eq(_index); + var arr = []; if (!elem) { - //通过按钮触发找到选中的进行移动 + // 通过按钮触发找到选中的进行移动 thisBoxElem.each(function(_index){ - var othis = $(this) - ,thisDataElem = othis.find('.'+ ELEM_DATA); + var othis = $(this); + var thisDataElem = othis.find('.'+ ELEM_DATA); thisDataElem.children('li').each(function(){ - var thisList = $(this) - ,thisElemCheckbox = thisList.find('input[type="checkbox"]') - ,isHide = thisElemCheckbox.data('hide'); + var thisList = $(this); + var thisElemCheckbox = thisList.find('input[type="checkbox"]'); + var isHide = thisElemCheckbox.data('hide'); if(thisElemCheckbox[0].checked && !isHide){ thisElemCheckbox[0].checked = false; thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone()); thisList.remove(); - //记录当前穿梭的数据 + // 记录当前穿梭的数据 arr.push(thisElemCheckbox[0].value); } @@ -376,15 +378,15 @@ layui.define(['laytpl', 'form'], function(exports){ }); }); } else { - //双击单条记录移动 - var thisList = elem - ,thisElemCheckbox = thisList.find('input[type="checkbox"]') + // 双击单条记录移动 + var thisList = elem; + var thisElemCheckbox = thisList.find('input[type="checkbox"]'); thisElemCheckbox[0].checked = false; thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone()); thisList.remove(); - //记录当前穿梭的数据 + // 记录当前穿梭的数据 arr.push(thisElemCheckbox[0].value); that.setValue(); @@ -392,28 +394,28 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderCheckBtn(); - //穿梭时,如果另外一个框正在搜索,则触发匹配 + // 穿梭时,如果另外一个框正在搜索,则触发匹配 var siblingInput = thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_SEARCH +' input') siblingInput.val() === '' || siblingInput.trigger('keyup'); - //穿梭时的回调 + // 穿梭时的回调 options.onchange && options.onchange(that.getData(arr), _index); } - //事件 + // 事件 Class.prototype.events = function(){ - var that = this - ,options = that.config; + var that = this; + var options = that.config; - //左右复选框 + // 左右复选框 that.elem.on('click', 'input[lay-filter="layTransferCheckbox"]+', function(){ - var thisElemCheckbox = $(this).prev() - ,checked = thisElemCheckbox[0].checked - ,thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA); + var thisElemCheckbox = $(this).prev(); + var checked = thisElemCheckbox[0].checked; + var thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA); if(thisElemCheckbox[0].disabled) return; - //判断是否全选 + // 判断是否全选 if(thisElemCheckbox.attr('lay-type') === 'all'){ thisDataElem.find('input[type="checkbox"]').each(function(){ if(this.disabled) return; @@ -428,26 +430,36 @@ layui.define(['laytpl', 'form'], function(exports){ // 双击穿梭 that.elem.on('dblclick', '.' + ELEM_DATA + '>li', function(event){ - var elemThis = $(this) - ,thisElemCheckbox = elemThis.children('input[type="checkbox"]') - ,thisDataElem = elemThis.parent() - ,thisBoxElem = thisDataElem.parent() + var elemThis = $(this); + var thisElemCheckbox = elemThis.children('input[type="checkbox"]'); + var thisDataElem = elemThis.parent(); + var thisBoxElem = thisDataElem.parent(); + var index = thisBoxElem.data('index'); if(thisElemCheckbox[0].disabled) return; - that.transfer(thisBoxElem.data('index'), elemThis); + // 根据 dblclick 回调函数返回值决定是否执行穿梭 --- 2.9.3+ + var ret = typeof options.dblclick === 'function' ? options.dblclick({ + elem: elemThis, + data: that.getData([thisElemCheckbox[0].value])[0], + index: index + }) : null; + + if(ret === false) return; + + that.transfer(index, elemThis); }) // 穿梭按钮事件 that.layBtn.on('click', function(){ - var othis = $(this) - ,_index = othis.data('index') - if(othis.hasClass(DISABLED)) return; + var othis = $(this); + var _index = othis.data('index'); + if(othis.hasClass(DISABLED)) return; that.transfer(_index); }); - //搜索 + // 搜索 that.laySearch.find('input').on('keyup', function(){ var value = this.value; var thisDataElem = $(this).parents('.'+ ELEM_SEARCH).eq(0).siblings('.'+ ELEM_DATA); @@ -472,17 +484,17 @@ layui.define(['laytpl', 'form'], function(exports){ that.renderCheckBtn(); - //无匹配数据视图 + // 无匹配数据视图 var isNone = thisListElem.length === thisDataElem.children('li.'+ HIDE).length; that.noneView(thisDataElem, isNone ? options.text.searchNone : ''); }); }; - //记录所有实例 - thisModule.that = {}; //记录所有实例对象 - thisModule.config = {}; //记录所有实例配置项 + // 记录所有实例 + thisModule.that = {}; // 记录所有实例对象 + thisModule.config = {}; // 记录所有实例配置项 - //重载实例 + // 重载实例 transfer.reload = function(id, options){ var that = thisModule.that[id]; that.reload(options); @@ -490,13 +502,13 @@ layui.define(['laytpl', 'form'], function(exports){ return thisModule.call(that); }; - //获得选中的数据(右侧面板) + // 获得选中的数据(右侧面板) transfer.getData = function(id){ var that = thisModule.that[id]; return that.getData(); }; - //核心入口 + // 核心入口 transfer.render = function(options){ var inst = new Class(options); return thisModule.call(inst); diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js index 4fc94a4..1397d97 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js @@ -2,19 +2,26 @@ * tree 树组件 */ -layui.define('form', function(exports){ +layui.define(['form','util'], function(exports){ "use strict"; var $ = layui.$; var form = layui.form; var layer = layui.layer; + var util = layui.util; // 模块名 var MOD_NAME = 'tree'; // 外部接口 var tree = { - config: {}, + config: { + customName: { // 自定义 data 字段名 + id: 'id', + title: 'title', + children: 'children' + } + }, index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0, // 设置全局项 @@ -122,10 +129,13 @@ layui.define('form', function(exports){ Class.prototype.render = function(){ var that = this; var options = that.config; + + // 初始化自定义字段名 + options.customName = $.extend({}, tree.config.customName, options.customName); that.checkids = []; - var temp = $('
              '); + var temp = $('
              '); that.tree(temp); var othis = options.elem = $(options.elem); @@ -178,13 +188,14 @@ layui.define('form', function(exports){ Class.prototype.tree = function(elem, children){ var that = this; var options = that.config; + var customName = options.customName; var data = children || options.data; // 遍历数据 layui.each(data, function(index, item){ - var hasChild = item.children && item.children.length > 0; + var hasChild = item[customName.children] && item[customName.children].length > 0; var packDiv = $('
              '); - var entryDiv = $(['
              ' + var entryDiv = $(['
              ' ,'
              ' ,'
              ' // 箭头 @@ -202,15 +213,15 @@ layui.define('form', function(exports){ // 复选框 ,function(){ - return options.showCheckbox ? '' : ''; + return options.showCheckbox ? '' : ''; }() // 节点 ,function(){ if(options.isJump && item.href){ - return ''+ (item.title || item.label || options.text.defaultNodeName) +''; + return ''+ (item[customName.title] || item.label || options.text.defaultNodeName) +''; }else{ - return ''+ (item.title || item.label || options.text.defaultNodeName) +''; + return ''+ (item[customName.title] || item.label || options.text.defaultNodeName) +''; } }() ,'
              ' @@ -241,7 +252,7 @@ layui.define('form', function(exports){ // 如果有子节点,则递归继续生成树 if(hasChild){ entryDiv.append(packDiv); - that.tree(packDiv, item.children); + that.tree(packDiv, item[customName.children]); }; elem.append(entryDiv); @@ -261,7 +272,7 @@ layui.define('form', function(exports){ // 选择框 if(options.showCheckbox){ - item.checked && that.checkids.push(item.id); + item.checked && that.checkids.push(item[customName.id]); that.checkClick(entryDiv, item); } @@ -296,10 +307,12 @@ layui.define('form', function(exports){ elem.removeClass(ELEM_SPREAD); packCont.slideUp(200); iconClick.removeClass(ICON_SUB).addClass(ICON_ADD); + that.updateFieldValue(item, 'spread', false); }else{ elem.addClass(ELEM_SPREAD); packCont.slideDown(200); iconClick.addClass(ICON_SUB).removeClass(ICON_ADD); + that.updateFieldValue(item, 'spread', true); // 是否手风琴 if(options.accordion){ @@ -328,7 +341,7 @@ layui.define('form', function(exports){ // 获取选中状态 if(elemCheckbox[0]){ - item['checked'] = elemCheckbox.prop('checked'); + that.updateFieldValue(item, 'checked', elemCheckbox.prop('checked')); } // 点击产生的回调 @@ -339,22 +352,29 @@ layui.define('form', function(exports){ }); }); }; + + // 更新数据源 checked,spread 字段值 + Class.prototype.updateFieldValue = function(obj, field, value){ + if(field in obj) obj[field] = value; + }; // 计算复选框选中状态 Class.prototype.setCheckbox = function(elem, item, elemCheckbox){ var that = this; var options = that.config; + var customName = options.customName; var checked = elemCheckbox.prop('checked'); if(elemCheckbox.prop('disabled')) return; // 同步子节点选中状态 - if(typeof item.children === 'object' || elem.find('.'+ELEM_PACK)[0]){ + if(typeof item[customName.children] === 'object' || elem.find('.'+ELEM_PACK)[0]){ var elemCheckboxs = elem.find('.'+ ELEM_PACK).find('input[same="layuiTreeCheck"]'); elemCheckboxs.each(function(index){ if(this.disabled) return; // 不可点击则跳过 - if(item.children[index]) item.children[index]['checked'] = checked; - this.checked = checked; + var children = item[customName.children][index]; + if(children) that.updateFieldValue(children, 'checked', checked); + that.updateFieldValue(this, 'checked', checked); }); }; @@ -410,7 +430,7 @@ layui.define('form', function(exports){ if(elemCheckbox.prop('disabled')) return; that.setCheckbox(elem, item, elemCheckbox); - item.checked = checked; + that.updateFieldValue(item, 'checked', checked); // 复选框点击产生的回调 options.oncheck && options.oncheck({ @@ -425,6 +445,7 @@ layui.define('form', function(exports){ Class.prototype.operate = function(elem, item){ var that = this; var options = that.config; + var customName = options.customName; var entry = elem.children('.'+ ELEM_ENTRY); var elemMain = entry.children('.'+ ELEM_MAIN); @@ -458,8 +479,8 @@ layui.define('form', function(exports){ var key = options.operate && options.operate(returnObj); var obj = {}; - obj.title = options.text.defaultNodeName; - obj.id = key; + obj[customName.title] = options.text.defaultNodeName; + obj[customName.id] = key; that.tree(elem.children('.'+ELEM_PACK), [obj]); // 放在新增后面,因为要对元素进行操作 @@ -527,16 +548,16 @@ layui.define('form', function(exports){ // 添加输入框,覆盖在文字上方 elemMain.append(''); // 获取焦点 - elemMain.children('.layui-tree-editInput').val(text).focus(); + elemMain.children('.layui-tree-editInput').val(util.unescape(text)).focus(); // 嵌入文字移除输入框 var getVal = function(input){ - var textNew = input.val().trim(); + var textNew = util.escape(input.val().trim()); textNew = textNew ? textNew : options.text.defaultNodeName; input.remove(); elemMain.children('.'+ ELEM_TEXT).html(textNew); // 同步数据 - returnObj.data.title = textNew; + returnObj.data[customName.title] = textNew; // 节点修改的回调 options.operate && options.operate(returnObj); @@ -555,7 +576,7 @@ layui.define('form', function(exports){ // 删除 } else { - layer.confirm('确认删除该节点 "'+ (item.title || '') +'" 吗?', function(index){ + layer.confirm('确认删除该节点 "'+ (item[customName.title] || '') +'" 吗?', function(index){ options.operate && options.operate(returnObj); // 节点删除的回调 returnObj.status = 'remove'; // 标注节点删除 @@ -742,6 +763,7 @@ layui.define('form', function(exports){ Class.prototype.getChecked = function(){ var that = this; var options = that.config; + var customName = options.customName; var checkId = []; var checkData = []; @@ -754,16 +776,17 @@ layui.define('form', function(exports){ var eachNodes = function(data, checkNode){ layui.each(data, function(index, item){ layui.each(checkId, function(index2, item2){ - if(item.id == item2){ - item['checked'] = true; + if(item[customName.id] == item2){ + that.updateFieldValue(item, 'checked', true); + var cloneItem = $.extend({}, item); - delete cloneItem.children; + delete cloneItem[customName.children]; checkNode.push(cloneItem); - if(item.children){ - cloneItem.children = []; - eachNodes(item.children, cloneItem.children); + if(item[customName.children]){ + cloneItem[customName.children] = []; + eachNodes(item[customName.children], cloneItem[customName.children]); } return true } @@ -839,4 +862,4 @@ layui.define('form', function(exports){ }; exports(MOD_NAME, tree); -}) \ No newline at end of file +}) diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js index 265833c..7f16eac 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js @@ -47,7 +47,11 @@ layui.define(['table'], function (exports) { } } - // 获取当前实例 + /** + * 获取当前实例 + * @param {string} id 表格id + * @returns {Class} + */ var getThisTable = function (id) { var that = thisTreeTable.that[id]; if (!that) hint.error(id ? ('The treeTable instance with ID \'' + id + '\' not found') : 'ID argument required'); @@ -56,6 +60,7 @@ layui.define(['table'], function (exports) { // 字符 var MOD_NAME = 'treeTable'; + var MOD_ID = 'lay-table-id'; var HIDE = 'layui-hide'; var ELEM_VIEW = '.layui-table-view'; @@ -78,8 +83,14 @@ layui.define(['table'], function (exports) { var LAY_EXPAND = 'LAY_EXPAND'; var LAY_HAS_EXPANDED = 'LAY_HAS_EXPANDED'; var LAY_ASYNC_STATUS = 'LAY_ASYNC_STATUS'; + var LAY_CASCADE = ['all', 'parent', 'children', 'none']; + var HTML_TAG_RE = /<[^>]+?>/; + var ICON_PROPS = ['flexIconClose', 'flexIconOpen', 'iconClose', 'iconOpen', 'iconLeaf', 'icon'] - // 构造器 + /** + * 构造器 + * @class + */ var Class = function (options) { var that = this; that.index = ++treeTable.index; @@ -92,9 +103,9 @@ layui.define(['table'], function (exports) { var updateCache = function (id, childrenKey, data) { var tableCache = table.cache[id]; layui.each(data || tableCache, function (index, item) { - var itemDataIndex = item[LAY_DATA_INDEX]; + var itemDataIndex = item[LAY_DATA_INDEX] || ''; if (itemDataIndex.indexOf('-') !== -1) { - tableCache[itemDataIndex] = item + tableCache[itemDataIndex] = item; } item[childrenKey] && updateCache(id, childrenKey, item[childrenKey]); }) @@ -126,6 +137,14 @@ layui.define(['table'], function (exports) { var parseData = options.parseData; var done = options.done; + // treeTable重载数据时,会先加载显示顶层节点,然后根据重载数据前的子节点展开状态,展开相应的子节点, + // 那么如果重载数据前有滚动条滚动在某个位子,重新加载时顶层节点如果比较少,只显示顶层节点时没有滚动条的情况下, + // 自动展开子节点后,滚动条就会显示在顶部,无法保持在重载数据之前的位置。 + // 处理保持滚动条的问题,重载数据前记录滚动条的位置 + if(reload === 'reloadData' && thatOptionsTemp.scrollPos === 'fixed'){ + that.scrollTopCache = that.config.elem.next().find(ELEM_BODY).scrollTop(); + } + if (thatOptionsTemp.url) { // 异步加载的时候需要处理parseData进行转换 if (!reload || (reload && parseData && !parseData.mod)) { @@ -157,19 +176,25 @@ layui.define(['table'], function (exports) { options.parseData.mod = true } } else { - options.data = options.data || []; - // 处理 isSimpleData - if (treeOptions.data.isSimpleData) { - options.data = that.flatToTree(options.data); + if(options.data !== undefined){ + options.data = options.data || []; + // 处理 isSimpleData + if (treeOptions.data.isSimpleData) { + options.data = that.flatToTree(options.data); + } + that.initData(options.data); } - that.initData(options.data); } if (!reload || (reload && done && !done.mod)) { options.done = function () { var args = arguments; var doneThat = this; - var isRenderData = args[3]; // 是否是 renderData + // undefined: 初始 render 或 reload,两者本质没有区别可以不做区分 + // 'reloadData': 重载数据 + // 'renderData': 重新渲染数据 + var renderType = args[3]; + var isRenderData = renderType === 'renderData'; if (!isRenderData) { delete that.isExpandAll; } @@ -189,20 +214,41 @@ layui.define(['table'], function (exports) { indeterminate: !checkStatus.isAll && checkStatus.data.length }) } + if (!isRenderData && thatOptionsTemp.autoSort && thatOptionsTemp.initSort && thatOptionsTemp.initSort.type) { + treeTable.sort(id); + } that.renderTreeTable(tableView); + // 恢复滚动条位置 + if(renderType === 'reloadData' && doneThat.scrollPos === 'fixed'){ + tableView.find(ELEM_BODY).scrollTop(that.scrollTopCache); + } + if (layui.type(done) === 'function') { return done.apply(doneThat, args); } } options.done.mod = true; } + + // 处理图标 + if(options && options.tree && options.tree.view){ + layui.each(ICON_PROPS, function(i, iconProp){ + if(options.tree.view[iconProp] !== undefined){ + options.tree.view[iconProp] = that.normalizedIcon(options.tree.view[iconProp]); + } + }) + } } Class.prototype.init = function () { var that = this; var options = that.config; + var cascade = options.tree.data.cascade; + if (LAY_CASCADE.indexOf(cascade) === -1) { + options.tree.data.cascade = 'all'; // 超出范围的都重置为全联动 + } // 先初始一个空的表格以便拿到对应的表格实例信息 var tableIns = table.render($.extend({}, options, { @@ -243,7 +289,8 @@ layui.define(['table'], function (exports) { }, data: { isSimpleData: false, // 是否简单数据模式 - rootPid: null // 根节点的父 ID 值 + rootPid: null, // 根节点的父 ID 值 + cascade: 'all' // 级联方式 默认全部级联:all 可选 级联父 parent 级联子 children }, async: { enable: false, // 是否开启异步加载模式,只有开启的时候其他参数才起作用 @@ -261,6 +308,12 @@ layui.define(['table'], function (exports) { }, }; + Class.prototype.normalizedIcon = function(iconStr){ + return iconStr + ? HTML_TAG_RE.test(iconStr) ? iconStr : '' + : '' + } + Class.prototype.getOptions = function () { var that = this; if (that.tableIns) { @@ -274,27 +327,40 @@ layui.define(['table'], function (exports) { idKey = idKey || 'id'; pIdKey = pIdKey || 'parentId'; childrenKey = childrenKey || 'children'; - // 创建一个空的 nodes 对象,用于保存所有的节点 - var nodes = {}; - // 遍历所有节点,将其加入 nodes 对象中 + // 创建一个空的 map 对象,用于保存所有的节点 + var map = {}; + var rootNodes = []; + var idTemp = ''; - layui.each(flatArr, function (index, item) { - idTemp = idKey + item[idKey]; - nodes[idTemp] = $.extend({}, item); - nodes[idTemp][childrenKey] = []; - }) - // 遍历所有节点,将其父子关系加入 nodes 对象 var pidTemp = ''; - layui.each(nodes, function (index, item) { + layui.each(flatArr, function(index, item){ + idTemp = idKey + item[idKey]; pidTemp = idKey + item[pIdKey]; - if (pidTemp && nodes[pidTemp]) { - nodes[pidTemp][childrenKey].push(item); + + // 将节点存入 map 对象 + if(!map[idTemp]){ + map[idTemp] = {}; + map[idTemp][childrenKey] = []; } - }) - // 返回顶层节点 - return Object.values(nodes).filter(function (item) { - return rootPid ? item[pIdKey] === rootPid : !item[pIdKey]; - }) + + // 合并节点 + var tempObj = {}; + tempObj[childrenKey] = map[idTemp][childrenKey]; + map[idTemp] = $.extend({}, item, tempObj); + + var isRootNode = (rootPid ? map[idTemp][pIdKey] === rootPid : !map[idTemp][pIdKey]); + if(isRootNode){ + rootNodes.push(map[idTemp]); + }else{ + if(!map[pidTemp]){ + map[pidTemp] = {}; + map[pidTemp][childrenKey] = []; + } + map[pidTemp][childrenKey].push(map[idTemp]); + } + }); + + return rootNodes; } Class.prototype.flatToTree = function (tableData) { @@ -321,7 +387,6 @@ layui.define(['table'], function (exports) { layui.each(tableData, function (i1, item1) { var dataIndex = (parentIndex ? parentIndex + '-' : '') + i1; var dataNew = $.extend({}, item1); - dataNew[childrenKey] = null; dataNew[pIdKey] = item1[pIdKey] || parentId; flat.push(dataNew); flat = flat.concat(that.treeToFlat(item1[childrenKey], item1[customName.id], dataIndex)); @@ -341,16 +406,14 @@ layui.define(['table'], function (exports) { var tableId = options.id; var customName = treeOptions.customName; - var treeNode = { + // 带上一些常用的方法 + return { data: data, dataIndex: data[LAY_DATA_INDEX], getParentNode: function () { return that.getNodeByIndex(data[LAY_PARENT_INDEX]) }, - } - // 带上一些常用的方法 - - return treeNode; + }; } // 通过 index 返回节点信息 @@ -415,45 +478,48 @@ layui.define(['table'], function (exports) { return; } - // 用index + // 用 index return that.getNodeByIndex(dataIndex); } - // 通过index获取节点数据 + // 通过 index 获取节点数据 Class.prototype.getNodeDataByIndex = function (index, clone, newValue) { var that = this; var options = that.getOptions(); var treeOptions = options.tree; var tableId = options.id; + var tableCache = table.cache[tableId]; - var dataCache = table.cache[tableId][index]; + // 获取当前行中的数据 + var dataCache = tableCache[index]; + + // 若非删除操作,则返回合并后的数据 if (newValue !== 'delete' && dataCache) { $.extend(dataCache, newValue); return clone ? $.extend({}, dataCache) : dataCache; } - var tableData = that.getTableData(); - index += ''; - var indexArr = index.split('-'); + // 删除操作 + var dataRet = tableCache; + var indexArr = String(index).split('-'); - var dataRet = tableData; - var tableCache = (options.url || indexArr.length > 1) ? null : table.cache[tableId]; // 只有在删除根节点的时候才需要处理 + // if (options.url || indexArr.length > 1) tableCache = null // 只有在删除根节点的时候才需要处理 + + // 根据 index 进行数据处理 for (var i = 0, childrenKey = treeOptions.customName.children; i < indexArr.length; i++) { if (newValue && i === indexArr.length - 1) { - if (newValue === 'delete') { - // 删除 - if (tableCache) { - // 同步cache + if (newValue === 'delete') { // 删除并返回当前数据 + // 同步 cache --- 此段代码注释缘由:data 属性模式造成数据重复执行 splice (@Gitee: #I7Z0A/I82E2S) + /*if (tableCache) { layui.each(tableCache, function (i1, item1) { if (item1[LAY_DATA_INDEX] === index) { tableCache.splice(i1, 1); return true; } }) - } + }*/ return (i ? dataRet[childrenKey] : dataRet).splice(indexArr[i], 1)[0]; - } else { - // 更新值 + } else { // 更新值 $.extend((i ? dataRet[childrenKey] : dataRet)[indexArr[i]], newValue); } } @@ -492,15 +558,19 @@ layui.define(['table'], function (exports) { var isParentKey = customName.isParent; var childrenKey = customName.children; - layui.each(data, function (i1, item1) { - if (!(isParentKey in item1)) { - item1[isParentKey] = !!(item1[childrenKey] && item1[childrenKey].length); - } - item1[LAY_DATA_INDEX_HISTORY] = item1[LAY_DATA_INDEX]; - item1[LAY_PARENT_INDEX] = parentIndex = parentIndex || ''; - var dataIndex = item1[LAY_DATA_INDEX] = (parentIndex ? parentIndex + '-' : '') + i1; - that.initData(item1[childrenKey] || [], dataIndex); - }); + var update = function(data, parentIndex){ + layui.each(data, function (i1, item1) { + if (!(isParentKey in item1)) { + item1[isParentKey] = !!(item1[childrenKey] && item1[childrenKey].length); + } + item1[LAY_DATA_INDEX_HISTORY] = item1[LAY_DATA_INDEX]; + item1[LAY_PARENT_INDEX] = parentIndex = parentIndex || ''; + var dataIndex = item1[LAY_DATA_INDEX] = (parentIndex ? parentIndex + '-' : '') + i1; + update(item1[childrenKey] || [], dataIndex); + }); + } + + update(data, parentIndex); updateCache(tableId, childrenKey, data); @@ -523,7 +593,7 @@ layui.define(['table'], function (exports) { // treeNode // 需要展开的节点 var trElem = treeNode.trElem; var tableViewElem = treeNode.tableViewElem || trElem.closest(ELEM_VIEW); - var tableId = treeNode.tableId || tableViewElem.attr('lay-id'); + var tableId = treeNode.tableId || tableViewElem.attr(MOD_ID); var options = treeNode.options || table.getOptions(tableId); var dataIndex = treeNode.dataIndex || trElem.attr('lay-data-index'); // 可能出现多层 var treeTableThat = getThisTable(tableId); @@ -552,14 +622,12 @@ layui.define(['table'], function (exports) { // 找到表格中的同类节点(需要找到lay-data-index一致的所有行) var trsElem = tableViewElem.find('tr[lay-data-index="' + dataIndex + '"]'); - // 处理折叠按钮图标 var flexIconElem = trsElem.find('.layui-table-tree-flexIcon'); - flexIconElem.html(trExpand ? treeOptions.view.flexIconOpen : treeOptions.view.flexIconClose) - trData[isParentKey] && flexIconElem.css('visibility', 'visible'); - // 处理节点图标 - treeOptions.view.showIcon && trsElem - .find('.layui-table-tree-nodeIcon:not(.layui-table-tree-iconCustom,.layui-table-tree-iconLeaf)') - .html(trExpand ? treeOptions.view.iconOpen : treeOptions.view.iconClose); + treeTableThat.updateNodeIcon({ + scopeEl: trsElem, + isExpand: trExpand, + isParent: trData[isParentKey] + }); trData[LAY_EXPAND] = trExpand; var trDataId = trData[customName.id]; trDataId !== undefined && (treeTableThat.status.expand[trDataId] = trExpand); @@ -572,6 +640,7 @@ layui.define(['table'], function (exports) { if (trExpand) { // 展开 if (trExpanded) { // 已经展开过 + if (!childNodes.length) return ;//异步如果子节点没有数据情况下双点行展开所有已展开的节点问题解决 trsElem.nextAll(childNodes.map(function (value, index, array) { return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]' }).join(',')).removeClass(HIDE); @@ -598,7 +667,7 @@ layui.define(['table'], function (exports) { options: options, }, true); } - }) + }); } else { var asyncSetting = treeOptions.async || {}; var asyncUrl = asyncSetting.url || options.url; @@ -701,17 +770,19 @@ layui.define(['table'], function (exports) { 'data-index': childItem[LAY_DATA_INDEX], 'lay-data-index': childItem[LAY_DATA_INDEX], 'data-level': dataLevelNew - }) + }).data('index', childItem[LAY_DATA_INDEX]); + str2Obj.trs_fixed.eq(childIndex).attr({ 'data-index': childItem[LAY_DATA_INDEX], 'lay-data-index': childItem[LAY_DATA_INDEX], 'data-level': dataLevelNew - }) + }).data('index', childItem[LAY_DATA_INDEX]); + str2Obj.trs_fixed_r.eq(childIndex).attr({ 'data-index': childItem[LAY_DATA_INDEX], 'lay-data-index': childItem[LAY_DATA_INDEX], 'data-level': dataLevelNew - }) + }).data('index', childItem[LAY_DATA_INDEX]); }) tableViewElem.find(ELEM_MAIN).find('tbody tr[lay-data-index="' + dataIndex + '"]').after(str2Obj.trs); @@ -896,7 +967,7 @@ layui.define(['table'], function (exports) { d[idKey] !== undefined && (that.status.expand[d[idKey]] = true); } }); - if (options.initSort && options.initSort.type && (!options.url || options.autoSort)) { + if (options.initSort && options.initSort.type && options.autoSort) { return treeTable.sort(id); } var trAll = table.getTrHtml(id, tableDataFlat); @@ -914,9 +985,9 @@ layui.define(['table'], function (exports) { 'lay-data-index': dataItem[LAY_DATA_INDEX], 'data-level': dataLevel }; - trAllObj.trs.eq(dataIndex).attr(props) - trAllObj.trs_fixed.eq(dataIndex).attr(props) - trAllObj.trs_fixed_r.eq(dataIndex).attr(props) + trAllObj.trs.eq(dataIndex).attr(props).data('index', dataItem[LAY_DATA_INDEX]); + trAllObj.trs_fixed.eq(dataIndex).attr(props).data('index', dataItem[LAY_DATA_INDEX]); + trAllObj.trs_fixed_r.eq(dataIndex).attr(props).data('index', dataItem[LAY_DATA_INDEX]); }) layui.each(['main', 'fixed-l', 'fixed-r'], function (i, item) { tableView.find('.layui-table-' + item + ' tbody').html(trAllObj[['trs', 'trs_fixed', 'trs_fixed_r'][i]]); @@ -927,6 +998,43 @@ layui.define(['table'], function (exports) { treeTable.resize(id); } + /** + * @typedef updateNodeIconOptions + * @prop {JQuery} scopeEl - tr 元素 + * @prop {boolean} isExpand - 是否是展开图标 + * @prop {boolean} isParent - 是否是父节点图标 + */ + /** + * 更新节点图标 + * @param {updateNodeIconOptions} opts + */ + Class.prototype.updateNodeIcon = function(opts){ + var that = this; + var options = that.getOptions(); + var treeOptions = options.tree || {}; + var scopeEl = opts.scopeEl; + var isExpand = opts.isExpand; + var isParent = opts.isParent; + + // 处理折叠按钮图标 + var flexIconElem = scopeEl.find('.layui-table-tree-flexIcon'); + + flexIconElem + .css('visibility', isParent || treeOptions.view.showFlexIconIfNotParent ? 'visible' : 'hidden') + .html(isExpand ? treeOptions.view.flexIconOpen : treeOptions.view.flexIconClose); + // 处理节点图标 + if(treeOptions.view.showIcon){ + var nodeIconElem = scopeEl.find('.layui-table-tree-nodeIcon:not(.layui-table-tree-iconCustom)'); + var nodeIcon = isParent + ? (isExpand ? treeOptions.view.iconOpen : treeOptions.view.iconClose) + : treeOptions.view.iconLeaf; + + nodeIconElem + .toggleClass('layui-table-tree-iconLeaf', !isParent) + .html(nodeIcon); + } + } + Class.prototype.renderTreeTable = function (tableView, level, sonSign) { var that = this; var options = that.getOptions(); @@ -995,7 +1103,7 @@ layui.define(['table'], function (exports) { ((trData[customName.icon] || treeOptionsView.icon) ? ' layui-table-tree-iconCustom' : '') + (trData[isParentKey] ? '' : ' layui-table-tree-iconLeaf') + '">' + - (trData[customName.icon] || treeOptionsView.icon || + (that.normalizedIcon(trData[customName.icon]) || treeOptionsView.icon || (trData[isParentKey] ? (trData[LAY_EXPAND] ? treeOptionsView.iconOpen : treeOptionsView.iconClose) : treeOptionsView.iconLeaf) || @@ -1023,10 +1131,14 @@ layui.define(['table'], function (exports) { trDefaultExpand.find('.layui-table-tree-flexIcon').html(treeOptionsView.flexIconOpen); expandNode({trElem: trDefaultExpand.first()}, true); }); + // #1463 expandNode 中已经展开过的节点不会重新渲染 + debounceFn('renderTreeTable2-' + tableId, function () { + form.render($('.layui-table-tree[' + MOD_ID + '="' + tableId + '"]')); + }, 0)(); } else { debounceFn('renderTreeTable-' + tableId, function () { options.hasNumberCol && formatNumber(that); - form.render($('.layui-table-tree[lay-id="' + tableId + '"]')); + form.render($('.layui-table-tree[' + MOD_ID + '="' + tableId + '"]')); }, 0)(); } } @@ -1040,6 +1152,7 @@ layui.define(['table'], function (exports) { var trFixedL = tableViewElem.find('.layui-table-fixed-l tbody tr'); var trFixedR = tableViewElem.find('.layui-table-fixed-r tbody tr'); layui.each(that.treeToFlat(table.cache[options.id]), function (i1, item1) { + if (item1['LAY_HIDE']) return; var itemData = that.getNodeDataByIndex(item1[LAY_DATA_INDEX]); itemData['LAY_NUM'] = ++num; trMain.eq(i1).find('.laytable-cell-numbers').html(num); @@ -1085,7 +1198,7 @@ layui.define(['table'], function (exports) { return treeTable.reload.apply(null, args); }; - var updateStatus = function (data, statusObj, childrenKey) { + var updateStatus = function (data, statusObj, childrenKey, notCascade) { var dataUpdated = []; layui.each(data, function (i1, item1) { if (layui.type(statusObj) === 'function') { @@ -1094,24 +1207,25 @@ layui.define(['table'], function (exports) { $.extend(item1, statusObj); } dataUpdated.push($.extend({}, item1)); - dataUpdated = dataUpdated.concat(updateStatus(item1[childrenKey], statusObj, childrenKey)); + notCascade || (dataUpdated = dataUpdated.concat(updateStatus(item1[childrenKey], statusObj, childrenKey, notCascade))); }); return dataUpdated; } - Class.prototype.updateStatus = function (data, statusObj) { + Class.prototype.updateStatus = function (data, statusObj, notCascade) { var that = this; var options = that.getOptions(); var treeOptions = options.tree; data = data || table.cache[options.id]; - return updateStatus(data, statusObj, treeOptions.customName.children); + return updateStatus(data, statusObj, treeOptions.customName.children, notCascade); } Class.prototype.getTableData = function () { var that = this; var options = that.getOptions(); - return options.url ? table.cache[options.id] : options.data; + // return options.url ? table.cache[options.id] : options.data; + return table.cache[options.id]; } treeTable.updateStatus = function (id, statusObj, data) { @@ -1132,8 +1246,32 @@ layui.define(['table'], function (exports) { if(!that) return; var options = that.getOptions(); - if (!options.url || options.autoSort) { - that.initData(); + var treeOptions = options.tree; + + var tableData = treeTable.getData(id); + var customName = treeOptions.customName; + var childrenKey = customName.children; + + // 只和同级节点排序 + var sort = function(data, field, type){ + layui.sort(data, field, type, true); + layui.each(data, function(rowIndex, trData){ + sort(trData[childrenKey] || [], field, type); + }) + } + + if (options.autoSort) { + var initSort = options.initSort; + if (initSort.type) { + sort(tableData, initSort.field, initSort.type === 'desc'); + } else { + // 恢复默认 + sort(tableData, table.config.indexName, null); + } + // 更新缓存中数据的顺序 + table.cache[id] = tableData; + // 重新初始化缓存数据 + that.initData(tableData); treeTable.renderData(id); } } @@ -1198,47 +1336,90 @@ layui.define(['table'], function (exports) { 'data-index': trIndex, 'lay-data-index': index, 'data-level': trLevel - })); + }).data('index', trIndex)); }); that.renderTreeTable(tableView.find('tr[lay-data-index="' + index + '"]'), trLevel); } // 删除数据 - treeTable.removeNode = function (id, node) { + // _keepParent 暂时为私有参数,仅供内部使用 + treeTable.removeNode = function (id, node, _keepParent) { var that = getThisTable(id); if(!that) return; var options = that.getOptions(); var treeOptions = options.tree; + var isParentKey = treeOptions.customName.isParent; + var childrenKey = treeOptions.customName.children; var tableView = options.elem.next(); var delNode; var indexArr = []; + var tableCache = table.cache[id]; delNode = that.getNodeDataByIndex(layui.type(node) === 'string' ? node : node[LAY_DATA_INDEX], false, 'delete'); var nodeP = that.getNodeDataByIndex(delNode[LAY_PARENT_INDEX]); that.updateCheckStatus(nodeP); var delNodesFlat = that.treeToFlat([delNode], delNode[treeOptions.customName.pid], delNode[LAY_PARENT_INDEX]); - layui.each(delNodesFlat, function (i2, item2) { - indexArr.push('tr[lay-data-index="' + item2[LAY_DATA_INDEX] + '"]'); + layui.each(delNodesFlat, function (i2, delNode) { + var delNodeDataIndex = delNode[LAY_DATA_INDEX]; + indexArr.push('tr[lay-data-index="' + delNodeDataIndex + '"]'); + // 删除临时 key + if(delNodeDataIndex.indexOf('-') !== -1){ + delete tableCache[delNodeDataIndex]; + } }) tableView.find(indexArr.join(',')).remove(); // 删除行 + + var deleteCacheKey = function(){ + for (var key in tableCache) { + // 根节点 getNodeDataByIndex 内部已处理 + if(key.indexOf('-') !== -1){ + // L93 updateCache() 中,cacheKey 取自 rowData 中的 LAY_DATA_INDEX, + // 两者不同说明当前 cacheKey 引用的 rowData 已被更新 + if(key !== tableCache[key][LAY_DATA_INDEX]){ + delete tableCache[key] + } + } + } + } + // 重新整理数据 var tableData = that.initData(); + deleteCacheKey(); // index发生变化需要更新页面tr中对应的lay-data-index 新增和删除都要注意数据结构变动之后的index问题 layui.each(that.treeToFlat(tableData), function (i3, item3) { if (item3[LAY_DATA_INDEX_HISTORY] && item3[LAY_DATA_INDEX_HISTORY] !== item3[LAY_DATA_INDEX]) { tableView.find('tr[lay-data-index="' + item3[LAY_DATA_INDEX_HISTORY] + '"]').attr({ 'data-index': item3[LAY_DATA_INDEX], 'lay-data-index': item3[LAY_DATA_INDEX], - }); + }).data('index', item3[LAY_DATA_INDEX]); // item3[LAY_DATA_INDEX_HISTORY] = item3[LAY_DATA_INDEX] } }); // 重新更新顶层节点的data-index; - layui.each(table.cache[id], function (i4, item4) { - tableView.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]').attr('data-index', i4); + layui.each(tableCache, function (i4, item4) { + tableView.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]') + .attr('data-index', i4) + .data('index', i4); }) options.hasNumberCol && formatNumber(that); + // 更新父节点状态 + if(nodeP){ + var trEl = tableView.find('tr[lay-data-index="' + nodeP[LAY_DATA_INDEX] + '"]'); + + if(!_keepParent){ + nodeP[isParentKey] = !!(nodeP[childrenKey] && nodeP[childrenKey].length); + } + + that.updateNodeIcon({ + scopeEl: trEl, + isExpand: nodeP[LAY_EXPAND], + isParent: nodeP[isParentKey], + }); + } + + // 重新适配尺寸 + treeTable.resize(id); } /** @@ -1258,6 +1439,7 @@ layui.define(['table'], function (exports) { var options = that.getOptions(); var treeOptions = options.tree; var tableViewElem = options.elem.next(); + var checkName = table.config.checkName; opts = opts || {}; @@ -1273,6 +1455,13 @@ layui.define(['table'], function (exports) { // 添加数据 newNodes = $.extend(true, [], (layui.isArray(newNodes) ? newNodes : [newNodes])); + // 若未传入 LAY_CHECKED 属性,则继承父节点的 checked 状态 + layui.each(newNodes, function(i, item){ + if(!(checkName in item) && parentNode){ + item[checkName] = parentNode[checkName]; + } + }) + var tableData = that.getTableData(), dataAfter; if (!parentNode) { // 添加到根节点 @@ -1309,9 +1498,9 @@ layui.define(['table'], function (exports) { 'lay-data-index': newNodeItem[LAY_DATA_INDEX], 'data-level': '0' }; - newNodesHtmlObj.trs.eq(newNodeIndex).attr(attrs) - newNodesHtmlObj.trs_fixed.eq(newNodeIndex).attr(attrs) - newNodesHtmlObj.trs_fixed_r.eq(newNodeIndex).attr(attrs) + newNodesHtmlObj.trs.eq(newNodeIndex).attr(attrs).data('index', newNodeItem[LAY_DATA_INDEX]); + newNodesHtmlObj.trs_fixed.eq(newNodeIndex).attr(attrs).data('index', newNodeItem[LAY_DATA_INDEX]); + newNodesHtmlObj.trs_fixed_r.eq(newNodeIndex).attr(attrs).data('index', newNodeItem[LAY_DATA_INDEX]); }) var trIndexPrev = parseInt(newNodes[0][LAY_DATA_INDEX]) - 1; var tableViewElemMAIN = tableViewElem.find(ELEM_MAIN); @@ -1319,9 +1508,16 @@ layui.define(['table'], function (exports) { var tableViewElemFIXR = tableViewElem.find(ELEM_FIXR); if (trIndexPrev === -1) { // 插入到开头 - tableViewElemMAIN.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs); - tableViewElemFIXL.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed); - tableViewElemFIXR.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed_r); + var hasTr = tableViewElemMAIN.find('tr[data-level="0"][data-index="0"]')[0]; + if(hasTr){ + tableViewElemMAIN.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs); + tableViewElemFIXL.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed); + tableViewElemFIXR.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed_r); + }else{ + tableViewElemMAIN.find('tbody').prepend(newNodesHtmlObj.trs); + tableViewElemFIXL.find('tbody').prepend(newNodesHtmlObj.trs_fixed); + tableViewElemFIXR.find('tbody').prepend(newNodesHtmlObj.trs_fixed_r); + } } else { if (index === -1) { // 追加到最后 @@ -1339,7 +1535,9 @@ layui.define(['table'], function (exports) { // 重新更新顶层节点的data-index; layui.each(table.cache[id], function (i4, item4) { - tableViewElem.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]').attr('data-index', i4); + tableViewElem.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]') + .attr('data-index', i4) + .data('index', i4); }) that.renderTreeTable(tableViewElem.find(newNodes.map(function (value, index, array) { @@ -1375,11 +1573,21 @@ layui.define(['table'], function (exports) { expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + parentIndex + '"]')}, true) } that.updateCheckStatus(parentNode); + // 更新父节点图标状态 + if(parentNode){ + var trEl = tableViewElem.find('tr[lay-data-index="' + parentNode[LAY_DATA_INDEX] + '"]'); + that.updateNodeIcon({ + scopeEl: trEl, + isExpand: parentNode[LAY_EXPAND], + isParent: parentNode[isParentKey], + }); + } treeTable.resize(id); if (focus) { // 滚动到第一个新增的节点 tableViewElem.find(ELEM_MAIN).find('tr[lay-data-index="' + newNodes[0][LAY_DATA_INDEX] + '"]').get(0).scrollIntoViewIfNeeded(); } + return newNodes; } @@ -1387,6 +1595,8 @@ layui.define(['table'], function (exports) { treeTable.checkStatus = function (id, includeHalfCheck) { var that = getThisTable(id); if (!that) return; + var options = that.getOptions(); + var treeOptions = options.tree; var checkName = table.config.checkName; // 需要区分单双选 @@ -1396,7 +1606,7 @@ layui.define(['table'], function (exports) { }); var isAll = true; - layui.each(table.cache[id], function (i1, item1) { + layui.each(treeOptions.data.cascade === 'all' ? table.cache[id] : treeTable.getData(id, true), function (i1, item1) { if (!item1[checkName]) { isAll = false; return true; @@ -1498,25 +1708,49 @@ layui.define(['table'], function (exports) { } }) + // 设置或取消行选中样式 + Class.prototype.setRowCheckedClass = function(tr, checked){ + var that = this; + var options = that.getOptions(); + + var index = tr.data('index'); + var tableViewElem = options.elem.next(); + + tr[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 主体行 + + // 右侧固定行 + tr.each(function(){ + var index = $(this).data('index'); + var trFixedR = tableViewElem.find('.layui-table-fixed-r tbody tr[data-index="'+ index +'"]'); + trFixedR[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); + }); + }; + // 更新表格的复选框状态 Class.prototype.updateCheckStatus = function (dataP, checked) { var that = this; var options = that.getOptions(); + if (!options.hasChecboxCol) { + return false; // 如果没有复选列则不需要更新状态 + } var treeOptions = options.tree; var tableId = options.id; var tableView = options.elem.next(); var checkName = table.config.checkName; + var cascade = treeOptions.data.cascade; + var isCascadeParent = cascade === 'all' || cascade === 'parent'; + // 如有必要更新父节点们的状态 - if (dataP) { + if (isCascadeParent && dataP) { var trsP = that.updateParentCheckStatus(dataP, layui.type(checked) === 'boolean' ? checked : null); layui.each(trsP, function (indexP, itemP) { var checkboxElem = tableView.find('tr[lay-data-index="' + itemP[LAY_DATA_INDEX] + '"] input[name="layTableCheckbox"]:not(:disabled)'); var checked = itemP[checkName]; - // 标记父节点行背景色 - checkboxElem.closest('tr')[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); + // 标记父节点行背景色 + that.setRowCheckedClass(checkboxElem.closest('tr'), checked); // 设置原始复选框 checked 属性值并渲染 form.render(checkboxElem.prop({ @@ -1529,14 +1763,27 @@ layui.define(['table'], function (exports) { // 更新全选的状态 var isAll = true; var isIndeterminate = false; - layui.each(table.cache[tableId], function (i1, item1) { - if (item1[checkName] || item1[LAY_CHECKBOX_HALF]) { - isIndeterminate = true; - } - if (!item1[checkName]) { - isAll = false; - } - }) + var data = treeOptions.data.cascade === 'all' ? table.cache[tableId] : treeTable.getData(tableId, true); + data = data.filter(function (item) { + return !item[options.disabledName]; + }); + + if(data.length > 0){ + layui.each(data, function (i1, item1) { + if (item1[checkName] || item1[LAY_CHECKBOX_HALF]) { + isIndeterminate = true; + } + if (!item1[checkName]) { + isAll = false; + } + if (isIndeterminate && !isAll) { + return true; + } + }) + }else{ + isAll = false; + } + isIndeterminate = isIndeterminate && !isAll; form.render(tableView.find('input[name="layTableCheckbox"][lay-filter="layTableAllChoose"]').prop({ 'checked': isAll, @@ -1601,6 +1848,7 @@ layui.define(['table'], function (exports) { var checkNode = function (trElem, checked, callbackFlag) { var that = this; var options = that.getOptions(); + var treeOptions = options.tree; var tableId = options.id; var tableView = options.elem.next(); var inputElem = (trElem.length ? trElem : tableView).find('.laytable-cell-radio, .laytable-cell-checkbox').children('input').last(); @@ -1649,20 +1897,22 @@ layui.define(['table'], function (exports) { if (d[checkName]) { var radioElem = tableView.find('tr[lay-data-index="' + d[LAY_DATA_INDEX] + '"] input[type="radio"][lay-type="layTableRadio"]'); d[checkName] = false; - radioElem.closest('tr').removeClass(ELEM_CHECKED); // 取消当前选中行背景色 + + // 取消当前选中行背景色 + that.setRowCheckedClass(radioElem.closest('tr'), false); form.render(radioElem.prop('checked', false)); } }); // 取消其他的选中状态 trData[checkName] = checked; - trElem[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 标记当前选中行背景色 - trElem.siblings().removeClass(ELEM_CHECKED); // 取消其他行背景色 + + that.setRowCheckedClass(trElem, checked); // 标记当前选中行背景色 + that.setRowCheckedClass(trElem.siblings(), false); // 取消其他行背景色 + form.render(trElem.find('input[type="radio"][lay-type="layTableRadio"]').prop('checked', checked)); } else { - var isParentKey = options.tree.customName.isParent; // 切换只能用到单条,全选到这一步的时候应该是一个确定的状态 checked = layui.type(checked) === 'boolean' ? checked : !trData[checkName]; // 状态切换,如果遇到不可操作的节点待处理 todo // 全选或者是一个父节点,将子节点的状态同步为当前节点的状态 - // if (!trData || trData[isParentKey]) { // 处理不可操作的信息 var checkedStatusFn = function (d) { if (!d[table.config.disabledName]) { // 节点不可操作的不处理 @@ -1671,14 +1921,16 @@ layui.define(['table'], function (exports) { } } - var trs = that.updateStatus(trData ? [trData] : table.cache[tableId], checkedStatusFn); + var trs = that.updateStatus(trData ? [trData] : table.cache[tableId], checkedStatusFn, trData && ['parent', 'none'].indexOf(treeOptions.data.cascade) !== -1); var checkboxElem = tableView.find(trs.map(function (value) { return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"] input[name="layTableCheckbox"]:not(:disabled)'; }).join(',')); - checkboxElem.closest('tr')[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 标记当前选中行背景色 + + that.setRowCheckedClass(checkboxElem.closest('tr'), checked); // 标记当前选中行背景色 form.render(checkboxElem.prop({checked: checked, indeterminate: false})); - // } + var trDataP; + // 更新父节点以及更上层节点的状态 if (trData && trData[LAY_PARENT_INDEX]) { // 找到父节点,然后判断父节点的子节点是否全部选中 @@ -1732,14 +1984,30 @@ layui.define(['table'], function (exports) { // 目前只能处理当前页的数据 return; } + + var collectNeedExpandNodeIndex = function(index){ + needExpandIndex.push(index); + var trElem = tableView.find('tr[lay-data-index="' + index + '"]'); + if (!trElem.length) { + var nodeData = that.getNodeDataByIndex(index); + var parentIndex = nodeData[LAY_PARENT_INDEX]; + parentIndex && collectNeedExpandNodeIndex(parentIndex); + } + } + // 判断是否展开过 var trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]'); if (!trElem.length) { + var parentIndex = nodeData[LAY_PARENT_INDEX]; + var needExpandIndex = []; + collectNeedExpandNodeIndex(parentIndex); // 如果还没有展开没有渲染的要先渲染出来 - treeTable.expandNode(id, { - index: nodeData[LAY_PARENT_INDEX], - expandFlag: true - }); + layui.each(needExpandIndex.reverse(),function(index, nodeIndex){ + treeTable.expandNode(id, { + index: nodeIndex, + expandFlag: true + }); + }) trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]'); } checkNode.call(that, trElem, checked, callbackFlag); @@ -1797,7 +2065,7 @@ layui.define(['table'], function (exports) { dataP[LAY_EXPAND] = false; dataP[LAY_ASYNC_STATUS] = false; layui.each(that.treeToFlat(dataP[treeOptions.customName.children]).reverse(), function (i1, item1) { - treeTable.removeNode(id, item1[LAY_DATA_INDEX]); + treeTable.removeNode(id, item1[LAY_DATA_INDEX], true); }) // 重新展开 treeTable.expandNode(id, { @@ -1855,7 +2123,7 @@ layui.define(['table'], function (exports) { // 重载 treeTable.reload = function (id, options, deep, type) { - deep = deep !== false; // 默认采用深拷贝 + // deep = deep !== false; // 默认采用深拷贝 var that = getThisTable(id); if (!that) return; that.reload(options, deep, type); diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js index 93520c9..9989981 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js @@ -3,16 +3,22 @@ * 上传组件 */ -layui.define(['lay','layer'], function(exports){ +layui.define(['lay', 'layer'], function(exports){ "use strict"; var $ = layui.$; + var lay = layui.lay; var layer = layui.layer; var device = layui.device(); + // 模块名 + var MOD_NAME = 'upload'; + var MOD_INDEX = 'layui_'+ MOD_NAME +'_index'; // 模块索引名 + // 外部接口 var upload = { config: {}, // 全局配置项 + index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0, // 索引 // 设置全局项 set: function(options){ var that = this; @@ -26,8 +32,13 @@ layui.define(['lay','layer'], function(exports){ }; // 操作当前实例 - var thisUpload = function(){ + var thisModule = function(){ var that = this; + var options = that.config; + var id = options.id; + + thisModule.that[id] = that; // 记录当前实例对象 + return { upload: function(files){ that.upload.call(that, files); @@ -40,7 +51,6 @@ layui.define(['lay','layer'], function(exports){ }; // 字符常量 - var MOD_NAME = 'upload'; var ELEM = 'layui-upload'; var THIS = 'layui-this'; var SHOW = 'layui-show'; @@ -52,10 +62,12 @@ layui.define(['lay','layer'], function(exports){ var ELEM_IFRAME = 'layui-upload-iframe'; var ELEM_CHOOSE = 'layui-upload-choose'; var ELEM_DRAG = 'layui-upload-drag'; + var UPLOADING = 'UPLOADING'; // 构造器 var Class = function(options){ var that = this; + that.index = ++upload.index; that.config = $.extend({}, that.config, upload.config, options); that.render(); }; @@ -85,15 +97,51 @@ layui.define(['lay','layer'], function(exports){ "limit-size": null // 限制 size 属性的提示 --- function } }; + + // 重载实例 + Class.prototype.reload = function(options){ + var that = this; + that.config = $.extend({}, that.config, options); + that.render(true); + }; // 初始渲染 - Class.prototype.render = function(options){ + Class.prototype.render = function(rerender){ var that = this; var options = that.config; + // 若 elem 非唯一 + var elem = $(options.elem); + if (elem.length > 1) { + layui.each(elem, function() { + upload.render($.extend({}, options, { + elem: this + })); + }); + return that; + } + + // 合并 lay-options 属性上的配置信息 + $.extend(options, lay.options(elem[0], { + attr: elem.attr('lay-data') ? 'lay-data' : null // 兼容旧版的 lay-data 属性 + })); + + // 若重复执行 render,则视为 reload 处理 + if (!rerender && elem[0] && elem.data(MOD_INDEX)) { + var newThat = thisModule.getThis(elem.data(MOD_INDEX)); + if(!newThat) return; + + return newThat.reload(options); + } + options.elem = $(options.elem); options.bindAction = $(options.bindAction); + // 初始化 id 属性 - 优先取 options > 元素 id > 自增索引 + options.id = 'id' in options ? options.id : ( + elem.attr('id') || that.index + ); + that.file(); that.events(); }; @@ -218,30 +266,56 @@ layui.define(['lay','layer'], function(exports){ var request = function(sets){ var formData = new FormData(); + // 恢复文件状态 + var resetFileState = function(file) { + if (sets.unified) { + layui.each(items, function(index, file){ + delete file[UPLOADING]; + }); + } else { + delete file[UPLOADING]; + } + }; + // 追加额外的参数 layui.each(options.data, function(key, value){ - value = typeof value === 'function' ? value() : value; + value = typeof value === 'function' + ? sets.unified ? value() : value(sets.index, sets.file) + : value; formData.append(key, value); }); - // 添加 file 到表单域 - sets.unified ? layui.each(items, function(index, file){ - formData.append(options.field, file); - }) : formData.append(options.field, sets.file); + /* + * 添加 file 到表单域 + */ + + // 是否统一上传 + if (sets.unified) { + layui.each(items, function(index, file){ + if (file[UPLOADING]) return; + file[UPLOADING] = true; // 上传中的标记 + formData.append(options.field, file); + }); + } else { // 逐一上传 + if (sets.file[UPLOADING]) return; + formData.append(options.field, sets.file); + sets.file[UPLOADING] = true; // 上传中的标记 + } // ajax 参数 var opts = { url: options.url, type: 'post', // 统一采用 post 上传 data: formData, + dataType: options.dataType || 'json', contentType: false, processData: false, - dataType: 'json', headers: options.headers || {}, success: function(res){ // 成功回调 options.unified ? (successful += that.fileLength) : successful++; done(sets.index, res); - allDone(); + allDone(sets.index); + resetFileState(sets.file); }, error: function(e){ // 异常回调 options.unified ? (failed += that.fileLength) : failed++; @@ -249,10 +323,12 @@ layui.define(['lay','layer'], function(exports){ 'Upload failed, please try again.', 'status: '+ (e.status || '') +' - '+ (e.statusText || 'error') ].join('
              ')); - error(sets.index); - allDone(); + error(sets.index, e.responseText); + allDone(sets.index); + resetFileState(sets.file); } }; + // 进度条 if(typeof options.progress === 'function'){ opts.xhr = function(){ @@ -310,21 +386,41 @@ layui.define(['lay','layer'], function(exports){ } }, 30); }; - + + // 强制返回的数据格式 + var forceConvert = function(src) { + if(options.force === 'json'){ + if(typeof src !== 'object'){ + try { + return { + status: "CONVERTED", + data: JSON.parse(src) + }; + } catch(e){ + that.msg(text['data-format-error']); + return { + status: "FORMAT_ERROR", + data: {} + }; + } + } + } + return { status: "DO_NOTHING", data: {} } + } + // 统一回调 var done = function(index, res){ that.elemFile.next('.'+ ELEM_CHOOSE).remove(); elemFile.value = ''; - if(options.force === 'json'){ - if(typeof res !== 'object'){ - try { - res = JSON.parse(res); - } catch(e){ - res = {}; - return that.msg(text['data-format-error']); - } - } + var convert = forceConvert(res); + + switch(convert.status) { + case "CONVERTED": + res = convert.data; + break; + case "FORMAT_ERROR": + return; } typeof options.done === 'function' && options.done(res, index || 0, function(files){ @@ -333,13 +429,24 @@ layui.define(['lay','layer'], function(exports){ }; // 统一网络异常回调 - var error = function(index){ + var error = function(index, res){ if(options.auto){ elemFile.value = ''; } + + var convert = forceConvert(res); + + switch(convert.status) { + case "CONVERTED": + res = convert.data; + break; + case "FORMAT_ERROR": + return; + } + typeof options.error === 'function' && options.error(index || 0, function(files){ that.upload(files); - }); + }, res); }; var check; @@ -377,20 +484,42 @@ layui.define(['lay','layer'], function(exports){ var newFile = new File([file], filename); that.files = that.files || {}; that.files[index] = newFile; + }, + // 获取本次选取的文件 + getChooseFiles: function(){ + return that.chooseFiles; } }; // 提交上传 - var send = function(){ - // 上传前的回调 - 如果回调函数明确返回 false,则停止上传 - if(options.before && (options.before(args) === false)) return; - - // IE 兼容处理 - if(device.ie){ - return device.ie > 9 ? ajaxSend() : iframeSend(); + var send = function(){ + var ready = function(){ + // IE 兼容处理 + if(device.ie){ + return device.ie > 9 ? ajaxSend() : iframeSend(); + } + ajaxSend(); + } + // 上传前的回调 - 如果回调函数明确返回 false 或 Promise.reject,则停止上传 + if(typeof options.before === 'function'){ + upload.util.promiseLikeResolve(options.before(args)) + .then(function(result){ + if(result !== false){ + ready(); + } else { + if(options.auto){ + elemFile.value = ''; + } + } + }, function(error){ + if(options.auto){ + elemFile.value = ''; + } + error !== undefined && layui.hint().error(error); + }) + }else{ + ready(); } - - ajaxSend(); }; // 文件类型名称 @@ -406,7 +535,8 @@ layui.define(['lay','layer'], function(exports){ ? ((elemFile.value.match(/[^\/\\]+\..+/g)||[]) || '') : value; - if(value.length === 0) return; + // 若文件域值为空 + if (value.length === 0) return; // 根据文件类型校验 switch(options.accept){ @@ -433,7 +563,7 @@ layui.define(['lay','layer'], function(exports){ break; default: // 图片文件 layui.each(value, function(i, item){ - if(!RegExp('.\\.('+ (exts || 'jpg|png|gif|bmp|jpeg|svg') +')$', 'i').test(escape(item))){ + if(!RegExp('.\\.('+ (exts || 'jpg|png|gif|bmp|jpeg|svg|webp') +')$', 'i').test(escape(item))){ return check = true; } }); @@ -493,24 +623,6 @@ layui.define(['lay','layer'], function(exports){ send(); }; - //重置方法 - Class.prototype.reload = function(options){ - options = options || {}; - delete options.elem; - delete options.bindAction; - - var that = this; - var options = that.config = $.extend({}, that.config, upload.config, options); - var next = options.elem.next(); - - //更新文件域相关属性 - next.attr({ - name: options.name, - accept: options.acceptMime, - multiple: options.multiple - }); - }; - //事件处理 Class.prototype.events = function(){ var that = this; @@ -541,23 +653,70 @@ layui.define(['lay','layer'], function(exports){ elemFile.after(''+ value +''); }; - // 合并 lay-options/lay-data 属性配置项 - var extendAttrs = function(){ - var othis = $(this); - var data = othis.attr('lay-data') || othis.attr('lay-options'); // 优先兼容旧版本 + /** + * 判断文件是否加入排队 + * @param {File} file + * @return {boolean} + */ + var checkFile = function (file) { + var result = true; + layui.each(that.files, function (index, item) { + result = !(item.name === file.name); + if(!result) return true; + }); + return result; + } - if(data){ - that.config = $.extend({}, options, lay.options(this, { - attr: othis.attr('lay-data') ? 'lay-data' : null - })); + /** + * 扩展文件信息 + * @template {File | FileList} T + * @param {T} obj + * @return {T} + */ + var extendInfo = function (obj) { + + var extInfo = function (file) { + //文件扩展名 + file.ext = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase(); + // 文件大小 + file.sizes = upload.util.parseSize(file.size); + // 可以继续扩展 } - }; + + //FileList对象 + if (obj instanceof FileList) { + layui.each(obj, function (index, item) { + extInfo(item); + }); + } else { + extInfo(obj); + } + + return obj; + } + + /** + * 检查获取文件 + * @param {FileList} files + * @return {Array|FileList} + */ + var getFiles = function (files) { + files = files || []; + if (!files.length) return []; + if (!that.files) return extendInfo(files); + var result = []; + layui.each(files, function (index, item) { + if (checkFile(item)) { + result.push(extendInfo(item)); + } + }); + return result; + } // 点击上传容器 options.elem.off('upload.start').on('upload.start', function(){ var othis = $(this); - extendAttrs.call(this); that.config.item = othis; that.elemFile[0].click(); }); @@ -574,10 +733,9 @@ layui.define(['lay','layer'], function(exports){ }) .off('upload.drop').on('upload.drop', function(e, param){ var othis = $(this); - var files = param.originalEvent.dataTransfer.files || []; + var files = getFiles(param.originalEvent.dataTransfer.files); othis.removeAttr('lay-over'); - extendAttrs.call(this); setChooseFile(files); options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传 @@ -585,11 +743,13 @@ layui.define(['lay','layer'], function(exports){ } // 文件选择 - that.elemFile.off('upload.change').on('upload.change', function(){ - var files = this.files || []; + that.elemFile.on('change', function(){ + var files = getFiles(this.files); + + if(files.length === 0) return; - extendAttrs.call(this); setChooseFile(files); + options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传 }); @@ -597,19 +757,19 @@ layui.define(['lay','layer'], function(exports){ options.bindAction.off('upload.action').on('upload.action', function(){ that.upload(); }); - + + // 防止事件重复绑定 - if(options.elem.data('haveEvents')) return; - - that.elemFile.on('change', function(){ - $(this).trigger('upload.change'); - }); - + if(options.elem.data(MOD_INDEX)) return; + + + // 目标元素 click 事件 options.elem.on('click', function(){ if(that.isFile()) return; $(this).trigger('upload.start'); }); + // 目标元素 drop 事件 if(options.drag){ options.elem.on('dragover', function(e){ e.preventDefault(); @@ -622,17 +782,67 @@ layui.define(['lay','layer'], function(exports){ }); } + // 手动上传时触发上传的元素 click 事件 options.bindAction.on('click', function(){ $(this).trigger('upload.action'); }); - options.elem.data('haveEvents', true); + // 绑定元素索引 + options.elem.data(MOD_INDEX, options.id); + }; + + /** + * 上传组件辅助方法 + */ + upload.util = { + /** + * 文件大小处理 + * @param {number | string} size -文件大小 + * @param {number} [precision] - 数值精度 + * @return {string} + */ + parseSize: function (size, precision) { + precision = precision || 2; + if (null == size || !size) { + return '0'; + } + var unitArr = ["Bytes", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"]; + var index; + var formatSize = typeof size === 'string' ? parseFloat(size) : size; + index = Math.floor(Math.log(formatSize) / Math.log(1024)); + size = formatSize / Math.pow(1024, index); + size = size % 1 === 0 ? size : parseFloat(size.toFixed(precision));//保留的小数位数 + return size + unitArr[index]; + }, + /** + * 将给定的值转换为一个 JQueryDeferred 对象 + */ + promiseLikeResolve:function(value){ + var deferred = $.Deferred(); + + if(value && typeof value.then === 'function'){ + value.then(deferred.resolve, deferred.reject); + }else{ + deferred.resolve(value); + } + return deferred.promise(); + } + } + + // 记录所有实例 + thisModule.that = {}; // 记录所有实例对象 + + // 获取当前实例对象 + thisModule.getThis = function(id){ + var that = thisModule.that[id]; + if(!that) hint.error(id ? (MOD_NAME +' instance with ID \''+ id +'\' not found') : 'ID argument required'); + return that; }; // 核心入口 upload.render = function(options){ var inst = new Class(options); - return thisUpload.call(inst); + return thisModule.call(inst); }; exports(MOD_NAME, upload); diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js index d992f12..cc628ee 100644 --- a/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js +++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js @@ -1,13 +1,13 @@ /** - * util 工具组件 + * util 工具组件 */ layui.define('jquery', function(exports){ "use strict"; - + var $ = layui.$; var hint = layui.hint(); - + // 外部接口 var util = { // 固定块 @@ -19,7 +19,7 @@ layui.define('jquery', function(exports){ options = $.extend(true, { target: 'body', // fixbar 的插入目标选择器 bars: [], // bar 信息 - default: true, // 是否显示默认 bar + "default": true, // 是否显示默认 bar margin: 160, // 出现 top bar 的滚动条高度临界值 duration: 320 // top bar 等动画时长(毫秒) }, options); @@ -28,12 +28,12 @@ layui.define('jquery', function(exports){ var $target = $(options.target); // 滚动条所在元素对象 - var $scroll = options.scroll - ? $(options.scroll) + var $scroll = options.scroll + ? $(options.scroll) : $(options.target === 'body' ? $doc : $target) // 是否提供默认图标 - if(options.default){ + if(options['default']){ // 兼容旧版本的一些属性 if(options.bar1){ options.bars.push({ @@ -72,8 +72,8 @@ layui.define('jquery', function(exports){ var type = $(this).attr('lay-type'); if(type === 'top'){ ( - options.target === 'body' - ? $('html,body') + options.target === 'body' + ? $('html,body') : $scroll ).animate({ scrollTop : 0 @@ -130,9 +130,9 @@ layui.define('jquery', function(exports){ timer = setTimeout(function(){ setTopBar(); }, 100); - }); + }); }, - + // 倒计时 countdown: function(options){ var that = this; @@ -198,27 +198,27 @@ layui.define('jquery', function(exports){ if(countTime <= 0){ clearTimeout(inst.timer); typeof options.done === 'function' && options.done(result, inst); - }; + } return fn; })(); - + return inst; }, - + // 某个时间在当前时间的多久前 timeAgo: function(time, onlyDate){ var that = this; var arr = [[], []]; var stamp = new Date().getTime() - new Date(time).getTime(); - + // 返回具体日期 if(stamp > 1000*60*60*24*31){ stamp = new Date(time); arr[0][0] = that.digit(stamp.getFullYear(), 4); arr[0][1] = that.digit(stamp.getMonth() + 1); arr[0][2] = that.digit(stamp.getDate()); - + // 是否输出时间 if(!onlyDate){ arr[1][0] = that.digit(stamp.getHours()); @@ -227,7 +227,7 @@ layui.define('jquery', function(exports){ } return arr[0].join('-') + ' ' + arr[1].join(':'); } - + // 30 天以内,返回「多久前」 if(stamp >= 1000*60*60*24){ return ((stamp/1000/60/60/24)|0) + ' 天前'; @@ -241,7 +241,7 @@ layui.define('jquery', function(exports){ return '刚刚'; } }, - + // 数字前置补零 digit: function(num, length){ var str = ''; @@ -252,39 +252,75 @@ layui.define('jquery', function(exports){ } return num < Math.pow(10, length) ? str + (num|0) : num; }, - + // 转化为日期格式字符 - toDateString: function(time, format){ - //若 null 或空字符,则返回空字符 + toDateString: function(time, format, options){ + // 若 null 或空字符,则返回空字符 if(time === null || time === '') return ''; - - var that = this - ,date = new Date(function(){ + + // 引用自 dayjs + // https://github.com/iamkun/dayjs/blob/v1.11.9/src/constant.js#L30 + var REGEX_FORMAT = /\[([^\]]+)]|y{1,4}|M{1,2}|d{1,2}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|SSS/g; + var that = this; + var date = new Date(function(){ if(!time) return; return isNaN(time) ? time : (typeof time === 'string' ? parseInt(time) : time) }() || new Date()) - ,ymd = [ - that.digit(date.getFullYear(), 4) - ,that.digit(date.getMonth() + 1) - ,that.digit(date.getDate()) - ] - ,hms = [ - that.digit(date.getHours()) - ,that.digit(date.getMinutes()) - ,that.digit(date.getSeconds()) - ]; - - if(!date.getDate()) return hint.error('Invalid Msec for "util.toDateString(Msec)"'), ''; - + + if(!date.getDate()) return hint.error('Invalid millisecond for "util.toDateString(millisecond)"'), ''; + + var years = date.getFullYear(); + var month = date.getMonth(); + var days = date.getDate(); + var hours = date.getHours(); + var minutes = date.getMinutes(); + var seconds = date.getSeconds(); + var milliseconds = date.getMilliseconds(); + + var defaultMeridiem = function(hours, minutes){ + var hm = hours * 100 + minutes; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1100) { + return '上午'; + } else if (hm < 1300) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } + return '晚上'; + }; + + var meridiem = (options && options.customMeridiem) || defaultMeridiem; + + var matches = { + yy: function(){return String(years).slice(-2);}, + yyyy: function(){return that.digit(years, 4);}, + M: function(){return String(month + 1);}, + MM: function(){return that.digit(month + 1);}, + d: function(){return String(days);}, + dd: function(){return that.digit(days);}, + H: function(){return String(hours);}, + HH: function(){return that.digit(hours);}, + h: function(){return String(hours % 12 || 12);}, + hh: function(){return that.digit(hours % 12 || 12);}, + A: function(){return meridiem(hours, minutes);}, + m: function(){return String(minutes);}, + mm: function(){return that.digit(minutes);}, + s: function(){return String(seconds);}, + ss: function(){return that.digit(seconds);}, + SSS: function(){return that.digit(milliseconds, 3);} + } + format = format || 'yyyy-MM-dd HH:mm:ss'; - return format.replace(/yyyy/g, ymd[0]) - .replace(/MM/g, ymd[1]) - .replace(/dd/g, ymd[2]) - .replace(/HH/g, hms[0]) - .replace(/mm/g, hms[1]) - .replace(/ss/g, hms[2]); + + return format.replace(REGEX_FORMAT, function(match, $1) { + return $1 || (matches[match] && matches[match]()) || match; + }); }, - + // 转义 html escape: function(html){ var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g; @@ -297,7 +333,7 @@ layui.define('jquery', function(exports){ .replace(//g, '>') .replace(/'/g, ''').replace(/"/g, '"'); }, - + // 还原转义的 html unescape: function(html){ if(html === undefined || html === null) html = ''; @@ -318,68 +354,102 @@ layui.define('jquery', function(exports){ win.document.write(options.content || ''); win.document.close(); }, - + // 让指定的元素保持在可视区域 toVisibleArea: function(options){ options = $.extend({ - margin: 160 //触发动作的边界值 - ,duration: 200 //动画持续毫秒数 - ,type: 'y' //触发方向,x 水平、y 垂直 + margin: 160, // 触发动作的边界值 + duration: 200, // 动画持续毫秒数 + type: 'y' // 触发方向,x 水平、y 垂直 }, options); - + if(!options.scrollElem[0] || !options.thisElem[0]) return; - - var scrollElem = options.scrollElem //滚动元素 - ,thisElem = options.thisElem //目标元素 - ,vertical = options.type === 'y' //是否垂直方向 - ,SCROLL_NAME = vertical ? 'scrollTop' : 'scrollLeft' //滚动方法 - ,OFFSET_NAME = vertical ? 'top' : 'left' //坐标方式 - ,scrollValue = scrollElem[SCROLL_NAME]() //当前滚动距离 - ,size = scrollElem[vertical ? 'height' : 'width']() //滚动元素的尺寸 - ,scrollOffet = scrollElem.offset()[OFFSET_NAME] //滚动元素所处位置 - ,thisOffset = thisElem.offset()[OFFSET_NAME] - scrollOffet //目标元素当前的所在位置 - ,obj = {}; - - //边界满足条件 + + var scrollElem = options.scrollElem // 滚动元素 + var thisElem = options.thisElem // 目标元素 + var vertical = options.type === 'y' // 是否垂直方向 + var SCROLL_NAME = vertical ? 'scrollTop' : 'scrollLeft' // 滚动方法 + var OFFSET_NAME = vertical ? 'top' : 'left' // 坐标方式 + var scrollValue = scrollElem[SCROLL_NAME]() // 当前滚动距离 + var size = scrollElem[vertical ? 'height' : 'width']() // 滚动元素的尺寸 + var scrollOffset = scrollElem.offset()[OFFSET_NAME] // 滚动元素所处位置 + var thisOffset = thisElem.offset()[OFFSET_NAME] - scrollOffset // 目标元素当前的所在位置 + var obj = {}; + + // 边界满足条件 if(thisOffset > size - options.margin || thisOffset < options.margin){ obj[SCROLL_NAME] = thisOffset - size/2 + scrollValue scrollElem.animate(obj, options.duration); } }, - - //批量事件 - event: function(attr, obj, eventType){ - var _body = $('body'); - eventType = eventType || 'click'; - - //记录事件回调集合 - obj = util.event[attr] = $.extend(true, util.event[attr], obj) || {}; - - //清除委托事件 - util.event.UTIL_EVENT_CALLBACK = util.event.UTIL_EVENT_CALLBACK || {}; - _body.off(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr]) - - //绑定委托事件 - util.event.UTIL_EVENT_CALLBACK[attr] = function(){ - var othis = $(this) - ,key = othis.attr(attr); - (typeof obj[key] === 'function') && obj[key].call(this, othis); - }; - //清除旧事件,绑定新事件 - _body.on(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr]); - - return obj; + /** + * 批量事件 + * @param {string} [attr="lay-on"] - 触发事件的元素属性名 + * @param {Object.} events - 事件集合 + * @param {Object} [options] - 参数的更多选项 + * @param {(string|HTMLElement|JQuery)} [options.elem="body"] - 触发事件的委托元素 + * @param {string} [options.trigger="click"] - 事件触发的方式 + * @returns {Object} 返回当前 events 参数设置的事件集合 + */ + on: function(attr, events, options) { + // 若参数一为 object 类型,则为事件集,且省略 attr + if (typeof attr === 'object') { + options = events || {}; + events = attr; + attr = options.attr || 'lay-on'; // 默认属性名 + } + + // 更多选项 + options = $.extend({ + elem: 'body', + trigger: 'click' + }, typeof options === 'object' ? options : { + trigger: options // 兼容旧版 + }); + + var elem = options.elem = $(options.elem); + var attrSelector = '['+ attr +']'; + var DATANAME = 'UTIL_ON_DATA'; // 缓存在委托元素上的 data-* 属性名 + + if (!elem[0]) return; // 若委托元素不存在 + + // 初始化 data 默认值,以委托元素为存储单元 + if (!elem.data(DATANAME)) { + elem.data(DATANAME, { + events: {}, + callbacks: {} + }); + } + + // 读取 data 缓存 + var dataCache = elem.data(DATANAME); + var callbacks = dataCache.callbacks; + + // 根据 attr 记录事件集合 + events = dataCache.events[attr] = $.extend(true, dataCache.events[attr], events); + + // 清除事件委托,避免重复绑定 + elem.off(options.trigger, attrSelector, callbacks[attr]); + + // 绑定事件委托 + elem.on( + options.trigger, + attrSelector, + callbacks[attr] = function(e) { + var othis = $(this); + var key = othis.attr(attr); + typeof events[key] === 'function' && events[key].call(this, othis, e); + } + ); + + return events; } }; - util.on = util.event; - - // DOM 尺寸变化,该创意来自:http://benalman.com/projects/jquery-resize-plugin/ - /* - !function(a,b,c){"$:nomunge";function l(){f=b[g](function(){d.each(function(){var b=a(this),c=b.width(),d=b.height(),e=a.data(this,i);(c!==e.w||d!==e.h)&&b.trigger(h,[e.w=c,e.h=d])}),l()},e[j])}var f,d=a([]),e=a.resize=a.extend(a.resize,{}),g="setTimeout",h="resize",i=h+"-special-event",j="delay",k="throttleWindow";e[j]=250,e[k]=!0,a.event.special[h]={setup:function(){if(!e[k]&&this[g])return!1;var b=a(this);d=d.add(b),a.data(this,i,{w:b.width(),h:b.height()}),1===d.length&&l()},teardown:function(){if(!e[k]&&this[g])return!1;var b=a(this);d=d.not(b),b.removeData(i),d.length||clearTimeout(f)},add:function(b){function f(b,e,f){var g=a(this),h=a.data(this,i)||{};h.w=e!==c?e:g.width(),h.h=f!==c?f:g.height(),d.apply(this,arguments)}if(!e[k]&&this[g])return!1;var d;return a.isFunction(b)?(d=b,f):(d=b.handler,b.handler=f,void 0)}}}($,window); - */ - + // 兼容旧版 + util.event = util.on; + // 输出接口 exports('util', util); -}); \ No newline at end of file +});