xuwei преди 3 години
родител
ревизия
d11910d264
променени са 100 файла, в които са добавени 3042 реда и са изтрити 3 реда
  1. 1 0
      .gitignore
  2. 41 0
      HEGII.ss.mes.web.sln
  3. 0 3
      README.md
  4. 34 0
      wwwroot/App_Code/dk.upload.cs
  5. 17 0
      wwwroot/App_Data/PublishProfiles/三水厂172.18.32.32.pubxml
  6. 54 0
      wwwroot/Global.asax
  7. BIN
      wwwroot/Img/accept.png
  8. BIN
      wwwroot/Img/bullet_tick.png
  9. BIN
      wwwroot/Img/chart.png
  10. BIN
      wwwroot/Img/clock.png
  11. BIN
      wwwroot/Img/detail.png
  12. BIN
      wwwroot/Img/dongke.png
  13. BIN
      wwwroot/Img/dongke_logo.jpg
  14. BIN
      wwwroot/Img/email.png
  15. BIN
      wwwroot/Img/email_delete.png
  16. BIN
      wwwroot/Img/email_error.png
  17. BIN
      wwwroot/Img/email_open.png
  18. BIN
      wwwroot/Img/email_stop.png
  19. BIN
      wwwroot/Img/excel.png
  20. BIN
      wwwroot/Img/exclamation.png
  21. BIN
      wwwroot/Img/file_blank.png
  22. BIN
      wwwroot/Img/file_line.png
  23. BIN
      wwwroot/Img/folder_close.png
  24. BIN
      wwwroot/Img/folder_open.png
  25. BIN
      wwwroot/Img/grid.png
  26. BIN
      wwwroot/Img/hegii.png
  27. BIN
      wwwroot/Img/hegii_logo.png
  28. BIN
      wwwroot/Img/lightbulb.png
  29. BIN
      wwwroot/Img/lightbulb_off.png
  30. BIN
      wwwroot/Img/logo.png
  31. BIN
      wwwroot/Img/logo16.png
  32. BIN
      wwwroot/Img/logo2.png
  33. BIN
      wwwroot/Img/logo3.png
  34. BIN
      wwwroot/Img/mail.png
  35. BIN
      wwwroot/Img/mailbox.png
  36. BIN
      wwwroot/Img/mailbox_close.png
  37. BIN
      wwwroot/Img/mailbox_open.png
  38. BIN
      wwwroot/Img/new.png
  39. BIN
      wwwroot/Img/new_blue.png
  40. BIN
      wwwroot/Img/new_red.png
  41. BIN
      wwwroot/Img/package_stop.png
  42. BIN
      wwwroot/Img/page.png
  43. BIN
      wwwroot/Img/page_delete.png
  44. BIN
      wwwroot/Img/page_green.png
  45. BIN
      wwwroot/Img/page_red.png
  46. BIN
      wwwroot/Img/plan.png
  47. BIN
      wwwroot/Img/stop_blue.png
  48. BIN
      wwwroot/Img/stop_green.png
  49. BIN
      wwwroot/Img/stop_red.png
  50. BIN
      wwwroot/Img/tab_blue.png
  51. BIN
      wwwroot/Img/tab_green.png
  52. BIN
      wwwroot/Img/tab_red.png
  53. BIN
      wwwroot/Img/table.png
  54. BIN
      wwwroot/Img/tag_blue.png
  55. BIN
      wwwroot/Img/tag_green.png
  56. BIN
      wwwroot/Img/tag_orange.png
  57. BIN
      wwwroot/Img/tag_pink.png
  58. BIN
      wwwroot/Img/tag_purple.png
  59. BIN
      wwwroot/Img/tag_red.png
  60. BIN
      wwwroot/Img/tag_yellow.png
  61. BIN
      wwwroot/Img/tick.png
  62. BIN
      wwwroot/Img/time.png
  63. BIN
      wwwroot/Img/time_green.png
  64. BIN
      wwwroot/Img/time_red.png
  65. BIN
      wwwroot/Img/top_bg.png
  66. BIN
      wwwroot/Img/vcard.png
  67. BIN
      wwwroot/Img/vcard_delete.png
  68. BIN
      wwwroot/Img/word.png
  69. 172 0
      wwwroot/Plugins/animation/001/JavaScript.js
  70. 2 0
      wwwroot/Plugins/animation/001/animation.js
  71. 73 0
      wwwroot/Plugins/animation/001/style.css
  72. 191 0
      wwwroot/Plugins/animation/002/JavaScript.js
  73. 56 0
      wwwroot/Plugins/animation/002/Style.css
  74. 6 0
      wwwroot/Plugins/animation/002/animation.js
  75. 12 0
      wwwroot/Plugins/animation/003/JavaScript.js
  76. 11 0
      wwwroot/Plugins/animation/003/Style.css
  77. 2 0
      wwwroot/Plugins/animation/003/animation.js
  78. 125 0
      wwwroot/Plugins/animation/004/JavaScript.js
  79. 20 0
      wwwroot/Plugins/animation/004/Style.css
  80. 4 0
      wwwroot/Plugins/animation/004/animation.js
  81. 6 0
      wwwroot/Plugins/chartjs/chart.min.js
  82. 147 0
      wwwroot/Plugins/chartjs/utils.js
  83. 683 0
      wwwroot/Plugins/easyui/changelog.txt
  84. 216 0
      wwwroot/Plugins/easyui/datagrid-export.js
  85. 1139 0
      wwwroot/Plugins/easyui/datagrid-filter.js
  86. 18 0
      wwwroot/Plugins/easyui/demo-mobile/accordion/_content.html
  87. 1 0
      wwwroot/Plugins/easyui/demo-mobile/accordion/basic.html
  88. 1 0
      wwwroot/Plugins/easyui/demo-mobile/accordion/header.html
  89. 1 0
      wwwroot/Plugins/easyui/demo-mobile/animation/basic.html
  90. 1 0
      wwwroot/Plugins/easyui/demo-mobile/animation/fade.html
  91. 1 0
      wwwroot/Plugins/easyui/demo-mobile/animation/pop.html
  92. 1 0
      wwwroot/Plugins/easyui/demo-mobile/animation/slide.html
  93. 1 0
      wwwroot/Plugins/easyui/demo-mobile/badge/basic.html
  94. 1 0
      wwwroot/Plugins/easyui/demo-mobile/badge/button.html
  95. 1 0
      wwwroot/Plugins/easyui/demo-mobile/badge/list.html
  96. 0 0
      wwwroot/Plugins/easyui/demo-mobile/badge/tabs.html
  97. 1 0
      wwwroot/Plugins/easyui/demo-mobile/button/basic.html
  98. 0 0
      wwwroot/Plugins/easyui/demo-mobile/button/group.html
  99. 1 0
      wwwroot/Plugins/easyui/demo-mobile/button/style.html
  100. 1 0
      wwwroot/Plugins/easyui/demo-mobile/button/switch.html

+ 1 - 0
.gitignore

@@ -108,3 +108,4 @@ _UpgradeReport_Files/
 Backup*/
 UpgradeLog*.XML
 
+/.vs

+ 41 - 0
HEGII.ss.mes.web.sln

@@ -0,0 +1,41 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32929.386
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "wwwroot", "wwwroot\", "{DB74DD9E-F84B-4372-A298-41376272D607}"
+	ProjectSection(WebsiteProperties) = preProject
+		TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
+		Debug.AspNetCompiler.VirtualPath = "/localhost_62172"
+		Debug.AspNetCompiler.PhysicalPath = "wwwroot\"
+		Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62172\"
+		Debug.AspNetCompiler.Updateable = "true"
+		Debug.AspNetCompiler.ForceOverwrite = "true"
+		Debug.AspNetCompiler.FixedNames = "false"
+		Debug.AspNetCompiler.Debug = "True"
+		Release.AspNetCompiler.VirtualPath = "/localhost_62172"
+		Release.AspNetCompiler.PhysicalPath = "wwwroot\"
+		Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62172\"
+		Release.AspNetCompiler.Updateable = "true"
+		Release.AspNetCompiler.ForceOverwrite = "true"
+		Release.AspNetCompiler.FixedNames = "false"
+		Release.AspNetCompiler.Debug = "False"
+		VWDPort = "62172"
+		SlnRelativePath = "wwwroot\"
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{DB74DD9E-F84B-4372-A298-41376272D607}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DB74DD9E-F84B-4372-A298-41376272D607}.Debug|Any CPU.Build.0 = Debug|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {9CA3E13F-6ECD-4AFF-BB80-B7C099FAE7B3}
+	EndGlobalSection
+EndGlobal

+ 0 - 3
README.md

@@ -1,3 +0,0 @@
-# HEGIIss.mes.web
-
-恒洁三水厂WEB工程

+ 34 - 0
wwwroot/App_Code/dk.upload.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Web;
+using System.Web.SessionState;
+using System.Data;
+using System.Collections;
+using Curtain.DataAccess;
+using DK.XuWei.WebMes;
+using Newtonsoft.Json.Linq;
+
+/// <summary>
+/// dk 用户 通用方法
+/// xuwei 2020-11-30
+/// </summary>
+public static partial class dk
+{
+    public static class upload
+    {
+        public static string uploadPath = "/main/upload/";
+
+        public static string uploadFile(string saveFileName, int fileIndex = 0)
+        {
+            //上传文件
+            string filePath = uploadPath + DateTime.Now.ToString("yyyy-MM-dd");
+            System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(filePath));
+            string fileName = filePath + "/" + saveFileName;
+            fileName += System.IO.Path.GetExtension(HttpContext.Current.Request.Files[fileIndex].FileName);
+            string diskFileName = HttpContext.Current.Server.MapPath(fileName);
+            if (System.IO.File.Exists(diskFileName)) System.IO.File.Delete(diskFileName);
+            HttpContext.Current.Request.Files[0].SaveAs(diskFileName);
+            return fileName;
+        }
+    }
+
+}

+ 17 - 0
wwwroot/App_Data/PublishProfiles/三水厂172.18.32.32.pubxml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121. 
+-->
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <DeleteExistingFiles>False</DeleteExistingFiles>
+    <ExcludeApp_Data>False</ExcludeApp_Data>
+    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
+    <LastUsedPlatform>Any CPU</LastUsedPlatform>
+    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
+    <PublishProvider>FileSystem</PublishProvider>
+    <PublishUrl>\\172.18.32.32\d$\dongke\IBOSS.PRD\DK.MES.WEB.9000</PublishUrl>
+    <WebPublishMethod>FileSystem</WebPublishMethod>
+    <SiteUrlToLaunchAfterPublish />
+  </PropertyGroup>
+</Project>

+ 54 - 0
wwwroot/Global.asax

@@ -0,0 +1,54 @@
+<%@ Application Language="C#" %>
+<%@ Import Namespace="Curtain.DataAccess" %>
+<%@ Import Namespace="Curtain.Log" %>
+<%@ Import Namespace="DK.XuWei.WebMes" %>
+
+<script runat="server">
+
+    void Application_Start(object sender, EventArgs e)
+    {
+        // 在应用程序启动时运行的代码
+        string connStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
+        DataAccess.DefaultParameterType = SQLParameterType.CDA;
+        DataAccess.DefaultDataBaseType = Curtain.DataAccess.DataBaseType.Oracle;
+        DataAccess.DefaultConnectionString = connStr;
+    }
+
+    void Application_End(object sender, EventArgs e)
+    {
+        //  在应用程序关闭时运行的代码
+
+    }
+
+    void Application_Error(object sender, EventArgs e)
+    {
+        // 在出现未处理的错误时运行的代码
+        Exception error = Server.GetLastError().GetBaseException();
+        if (error != null)
+        {
+            //记录日志
+            Logger.Error(error);
+            //输出错误信息
+            //2022-11-15 冯林勇 出现错误不弹出日志 
+            //HttpContext.Current.Response.Write(new JsonResult(JsonStatus.otherError).ToJson());
+            //2022-11-15 冯林勇 出现错误不弹出日志 
+        }
+        Server.ClearError();
+    }
+
+    void Session_Start(object sender, EventArgs e)
+    {
+        // 在新会话启动时运行的代码
+
+    }
+
+    void Session_End(object sender, EventArgs e)
+    {
+        // 在会话结束时运行的代码。 
+        // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
+        // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
+        // 或 SQLServer,则不引发该事件。
+
+    }
+
+</script>

BIN
wwwroot/Img/accept.png


BIN
wwwroot/Img/bullet_tick.png


BIN
wwwroot/Img/chart.png


BIN
wwwroot/Img/clock.png


BIN
wwwroot/Img/detail.png


BIN
wwwroot/Img/dongke.png


BIN
wwwroot/Img/dongke_logo.jpg


BIN
wwwroot/Img/email.png


BIN
wwwroot/Img/email_delete.png


BIN
wwwroot/Img/email_error.png


BIN
wwwroot/Img/email_open.png


BIN
wwwroot/Img/email_stop.png


BIN
wwwroot/Img/excel.png


BIN
wwwroot/Img/exclamation.png


BIN
wwwroot/Img/file_blank.png


BIN
wwwroot/Img/file_line.png


BIN
wwwroot/Img/folder_close.png


BIN
wwwroot/Img/folder_open.png


BIN
wwwroot/Img/grid.png


BIN
wwwroot/Img/hegii.png


BIN
wwwroot/Img/hegii_logo.png


BIN
wwwroot/Img/lightbulb.png


BIN
wwwroot/Img/lightbulb_off.png


BIN
wwwroot/Img/logo.png


BIN
wwwroot/Img/logo16.png


BIN
wwwroot/Img/logo2.png


BIN
wwwroot/Img/logo3.png


BIN
wwwroot/Img/mail.png


BIN
wwwroot/Img/mailbox.png


BIN
wwwroot/Img/mailbox_close.png


BIN
wwwroot/Img/mailbox_open.png


BIN
wwwroot/Img/new.png


BIN
wwwroot/Img/new_blue.png


BIN
wwwroot/Img/new_red.png


BIN
wwwroot/Img/package_stop.png


BIN
wwwroot/Img/page.png


BIN
wwwroot/Img/page_delete.png


BIN
wwwroot/Img/page_green.png


BIN
wwwroot/Img/page_red.png


BIN
wwwroot/Img/plan.png


BIN
wwwroot/Img/stop_blue.png


BIN
wwwroot/Img/stop_green.png


BIN
wwwroot/Img/stop_red.png


BIN
wwwroot/Img/tab_blue.png


BIN
wwwroot/Img/tab_green.png


BIN
wwwroot/Img/tab_red.png


BIN
wwwroot/Img/table.png


BIN
wwwroot/Img/tag_blue.png


BIN
wwwroot/Img/tag_green.png


BIN
wwwroot/Img/tag_orange.png


BIN
wwwroot/Img/tag_pink.png


BIN
wwwroot/Img/tag_purple.png


BIN
wwwroot/Img/tag_red.png


BIN
wwwroot/Img/tag_yellow.png


BIN
wwwroot/Img/tick.png


BIN
wwwroot/Img/time.png


BIN
wwwroot/Img/time_green.png


BIN
wwwroot/Img/time_red.png


BIN
wwwroot/Img/top_bg.png


BIN
wwwroot/Img/vcard.png


BIN
wwwroot/Img/vcard_delete.png


BIN
wwwroot/Img/word.png


+ 172 - 0
wwwroot/Plugins/animation/001/JavaScript.js

@@ -0,0 +1,172 @@
+
+let max_particles = 100;
+let particles = [];
+let frequency = 100;
+let init_num = max_particles;
+let max_time = frequency * max_particles;
+let time_to_recreate = false;
+
+// Enable repopolate
+setTimeout(function () {
+    time_to_recreate = true;
+}.bind(this), max_time)
+
+// Popolate particles
+popolate(max_particles);
+
+var tela = document.createElement('canvas');
+tela.width = $(window).width();
+tela.height = $(window).height();
+$("body").append(tela);
+
+var canvas = tela.getContext('2d');
+
+class Particle {
+    constructor(canvas, options) {
+        let colors = ["#feea00", "#a9df85", "#5dc0ad", "#ff9a00", "#fa3f20"]
+        let types = ["full", "fill", "empty"]
+        this.random = Math.random()
+        this.canvas = canvas;
+        this.progress = 0;
+
+        this.x = ($(window).width() / 2) + (Math.random() * 200 - Math.random() * 200)
+        this.y = ($(window).height() / 2) + (Math.random() * 200 - Math.random() * 200)
+        this.w = $(window).width()
+        this.h = $(window).height()
+        this.radius = 1 + (8 * this.random)
+        this.type = types[this.randomIntFromInterval(0, types.length - 1)];
+        this.color = colors[this.randomIntFromInterval(0, colors.length - 1)];
+        this.a = 0
+        this.s = (this.radius + (Math.random() * 1)) / 10;
+        //this.s = 12 //Math.random() * 1;
+    }
+
+    getCoordinates() {
+        return {
+            x: this.x,
+            y: this.y
+        }
+    }
+
+    randomIntFromInterval(min, max) {
+        return Math.floor(Math.random() * (max - min + 1) + min);
+    }
+
+    render() {
+        // Create arc
+        let lineWidth = 0.2 + (2.8 * this.random);
+        let color = this.color;
+        switch (this.type) {
+            case "full":
+                this.createArcFill(this.radius, color)
+                this.createArcEmpty(this.radius + lineWidth, lineWidth / 2, color)
+                break;
+            case "fill":
+                this.createArcFill(this.radius, color)
+                break;
+            case "empty":
+                this.createArcEmpty(this.radius, lineWidth, color)
+                break;
+        }
+    }
+
+    createArcFill(radius, color) {
+        this.canvas.beginPath();
+        this.canvas.arc(this.x, this.y, radius, 0, 2 * Math.PI);
+        this.canvas.fillStyle = color;
+        this.canvas.fill();
+        this.canvas.closePath();
+    }
+
+    createArcEmpty(radius, lineWidth, color) {
+        this.canvas.beginPath();
+        this.canvas.arc(this.x, this.y, radius, 0, 2 * Math.PI);
+        this.canvas.lineWidth = lineWidth;
+        this.canvas.strokeStyle = color;
+        this.canvas.stroke();
+        this.canvas.closePath();
+    }
+
+    move() {
+
+        this.x += Math.cos(this.a) * this.s;
+        this.y += Math.sin(this.a) * this.s;
+        this.a += Math.random() * 0.4 - 0.2;
+
+        if (this.x < 0 || this.x > this.w - this.radius) {
+            return false
+        }
+
+        if (this.y < 0 || this.y > this.h - this.radius) {
+            return false
+        }
+        this.render()
+        return true
+    }
+
+    calculateDistance(v1, v2) {
+        let x = Math.abs(v1.x - v2.x);
+        let y = Math.abs(v1.y - v2.y);
+        return Math.sqrt((x * x) + (y * y));
+    }
+}
+
+/*
+ * Function to clear layer canvas
+ * @num:number number of particles
+ */
+function popolate(num) {
+    for (var i = 0; i < num; i++) {
+        setTimeout(
+            function (x) {
+                return function () {
+                    // Add particle
+                    particles.push(new Particle(canvas))
+                };
+            }(i)
+            , frequency * i);
+    }
+    return particles.length
+}
+
+function clear() {
+    // canvas.globalAlpha=0.04;
+    canvas.fillStyle = '#111111';
+    canvas.fillRect(0, 0, tela.width, tela.height);
+    // canvas.globalAlpha=1;
+}
+
+function connection() {
+    let old_element = null
+    $.each(particles, function (i, element) {
+        if (i > 0) {
+            let box1 = old_element.getCoordinates()
+            let box2 = element.getCoordinates()
+            canvas.beginPath();
+            canvas.moveTo(box1.x, box1.y);
+            canvas.lineTo(box2.x, box2.y);
+            canvas.lineWidth = 0.45;
+            canvas.strokeStyle = "#3f47ff";
+            canvas.stroke();
+            canvas.closePath();
+        }
+
+        old_element = element
+    })
+}
+
+/*
+ * Function to update particles in canvas
+ */
+function update() {
+    clear();
+    connection()
+    particles = particles.filter(function (p) { return p.move() })
+    // Recreate particles
+    if (time_to_recreate) {
+        if (particles.length < init_num) { popolate(1); }
+    }
+    requestAnimationFrame(update.bind(this))
+}
+
+update();

+ 2 - 0
wwwroot/Plugins/animation/001/animation.js

@@ -0,0 +1,2 @@
+document.write('<link href="/plugins/animation/001/style.css" rel="stylesheet" />');
+document.write('<script src="/plugins/animation/001/JavaScript.js"></script>');

+ 73 - 0
wwwroot/Plugins/animation/001/style.css

@@ -0,0 +1,73 @@
+
+.more-pens {
+    position: fixed;
+    left: 20px;
+    bottom: 20px;
+    z-index: 10;
+    font-family: "Montserrat";
+    font-size: 12px;
+}
+
+a.white-mode, a.white-mode:link, a.white-mode:visited, a.white-mode:active {
+    font-family: "Montserrat";
+    font-size: 12px;
+    text-decoration: none;
+    background: #212121;
+    padding: 4px 8px;
+    color: #f7f7f7;
+}
+
+    a.white-mode:hover, a.white-mode:link:hover, a.white-mode:visited:hover, a.white-mode:active:hover {
+        background: #edf3f8;
+        color: #212121;
+    }
+
+body {
+    margin: 0;
+    padding: 0;
+    overflow: hidden;
+    width: 100%;
+    height: 100%;
+    background: #000000;
+}
+
+.title {
+    z-index: 10;
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translateX(-50%) translateY(-50%);
+    font-family: "Montserrat";
+    text-align: center;
+    width: 100%;
+}
+
+    .title h1 {
+        position: relative;
+        color: #EEEEEE;
+        font-weight: 600;
+        font-size: 60px;
+        padding: 0;
+        margin: 0;
+        line-height: 1;
+        text-shadow: 0 0 30px #000155;
+    }
+
+        .title h1 span {
+            font-weight: 600;
+            padding: 0;
+            margin: 0;
+            color: #BBB;
+        }
+
+    .title h3 {
+        font-weight: 200;
+        font-size: 20px;
+        padding: 0;
+        margin: 0;
+        line-height: 1;
+        color: #EEEEEE;
+        letter-spacing: 2px;
+        text-shadow: 0 0 30px #000155;
+    }
+

+ 191 - 0
wwwroot/Plugins/animation/002/JavaScript.js

@@ -0,0 +1,191 @@
+
+// min and max radius, radius threshold and percentage of filled circles
+var radMin = 5,
+    radMax = 125,
+    filledCircle = 60, //percentage of filled circles
+    concentricCircle = 30, //percentage of concentric circles
+    radThreshold = 25; //IFF special, over this radius concentric, otherwise filled
+
+//min and max speed to move
+var speedMin = 0.3,
+    speedMax = 2.5;
+
+//max reachable opacity for every circle and blur effect
+var maxOpacity = 0.6;
+
+//default palette choice
+var colors = ['52,168,83', '117,95,147', '199,108,23', '194,62,55', '0,172,212', '120,120,120'],
+    bgColors = ['52,168,83', '117,95,147', '199,108,23', '194,62,55', '0,172,212', '120,120,120'],
+    circleBorder = 10,
+    backgroundLine = bgColors[0];
+var backgroundMlt = 0.85;
+
+//min distance for links
+var linkDist = Math.min(canvas.width, canvas.height) / 2.4,
+    lineBorder = 2.5;
+
+//most importantly: number of overall circles and arrays containing them
+var maxCircles = 12,
+    points = [],
+    pointsBack = [];
+
+//populating the screen
+for (var i = 0; i < maxCircles * 2; i++) points.push(new Circle());
+for (var i = 0; i < maxCircles; i++) pointsBack.push(new Circle(true));
+
+//experimental vars
+var circleExp = 1,
+    circleExpMax = 1.003,
+    circleExpMin = 0.997,
+    circleExpSp = 0.00004,
+    circlePulse = false;
+
+//circle class
+function Circle(background) {
+    //if background, it has different rules
+    this.background = (background || false);
+    this.x = randRange(-canvas.width / 2, canvas.width / 2);
+    this.y = randRange(-canvas.height / 2, canvas.height / 2);
+    this.radius = background ? hyperRange(radMin, radMax) * backgroundMlt : hyperRange(radMin, radMax);
+    this.filled = this.radius < radThreshold ? (randint(0, 100) > filledCircle ? false : 'full') : (randint(0, 100) > concentricCircle ? false : 'concentric');
+    this.color = background ? bgColors[randint(0, bgColors.length - 1)] : colors[randint(0, colors.length - 1)];
+    this.borderColor = background ? bgColors[randint(0, bgColors.length - 1)] : colors[randint(0, colors.length - 1)];
+    this.opacity = 0.05;
+    this.speed = (background ? randRange(speedMin, speedMax) / backgroundMlt : randRange(speedMin, speedMax)); // * (radMin / this.radius);
+    this.speedAngle = Math.random() * 2 * Math.PI;
+    this.speedx = Math.cos(this.speedAngle) * this.speed;
+    this.speedy = Math.sin(this.speedAngle) * this.speed;
+    var spacex = Math.abs((this.x - (this.speedx < 0 ? -1 : 1) * (canvas.width / 2 + this.radius)) / this.speedx),
+        spacey = Math.abs((this.y - (this.speedy < 0 ? -1 : 1) * (canvas.height / 2 + this.radius)) / this.speedy);
+    this.ttl = Math.min(spacex, spacey);
+};
+
+Circle.prototype.init = function () {
+    Circle.call(this, this.background);
+}
+
+//support functions
+//generate random int a<=x<=b
+function randint(a, b) {
+    return Math.floor(Math.random() * (b - a + 1) + a);
+}
+//generate random float
+function randRange(a, b) {
+    return Math.random() * (b - a) + a;
+}
+//generate random float more likely to be close to a
+function hyperRange(a, b) {
+    return Math.random() * Math.random() * Math.random() * (b - a) + a;
+}
+
+//rendering function
+function drawCircle(ctx, circle) {
+    //circle.radius *= circleExp;
+    var radius = circle.background ? circle.radius *= circleExp : circle.radius /= circleExp;
+    ctx.beginPath();
+    ctx.arc(circle.x, circle.y, radius * circleExp, 0, 2 * Math.PI, false);
+    ctx.lineWidth = Math.max(1, circleBorder * (radMin - circle.radius) / (radMin - radMax));
+    ctx.strokeStyle = ['rgba(', circle.borderColor, ',', circle.opacity, ')'].join('');
+    if (circle.filled == 'full') {
+        ctx.fillStyle = ['rgba(', circle.borderColor, ',', circle.background ? circle.opacity * 0.8 : circle.opacity, ')'].join('');
+        ctx.fill();
+        ctx.lineWidth = 0;
+        ctx.strokeStyle = ['rgba(', circle.borderColor, ',', 0, ')'].join('');
+    }
+    ctx.stroke();
+    if (circle.filled == 'concentric') {
+        ctx.beginPath();
+        ctx.arc(circle.x, circle.y, radius / 2, 0, 2 * Math.PI, false);
+        ctx.lineWidth = Math.max(1, circleBorder * (radMin - circle.radius) / (radMin - radMax));
+        ctx.strokeStyle = ['rgba(', circle.color, ',', circle.opacity, ')'].join('');
+        ctx.stroke();
+    }
+    circle.x += circle.speedx;
+    circle.y += circle.speedy;
+    if (circle.opacity < (circle.background ? maxOpacity : 1)) circle.opacity += 0.01;
+    circle.ttl--;
+}
+
+//initializing function
+function init() {
+    window.requestAnimationFrame(draw);
+}
+
+//rendering function
+function draw() {
+
+    if (circlePulse) {
+        if (circleExp < circleExpMin || circleExp > circleExpMax) circleExpSp *= -1;
+        circleExp += circleExpSp;
+    }
+    var ctxfr = document.getElementById('canvas').getContext('2d');
+    var ctxbg = document.getElementById('canvasbg').getContext('2d');
+
+    ctxfr.globalCompositeOperation = 'destination-over';
+    ctxfr.clearRect(0, 0, canvas.width, canvas.height); // clear canvas
+    ctxbg.globalCompositeOperation = 'destination-over';
+    ctxbg.clearRect(0, 0, canvas.width, canvas.height); // clear canvas
+
+    ctxfr.save();
+    ctxfr.translate(canvas.width / 2, canvas.height / 2);
+    ctxbg.save();
+    ctxbg.translate(canvas.width / 2, canvas.height / 2);
+
+    //function to render each single circle, its connections and to manage its out of boundaries replacement
+    function renderPoints(ctx, arr) {
+        for (var i = 0; i < arr.length; i++) {
+            var circle = arr[i];
+            //checking if out of boundaries
+            if (circle.ttl < 0) { }
+            var xEscape = canvas.width / 2 + circle.radius,
+                yEscape = canvas.height / 2 + circle.radius;
+            if (circle.ttl < -20) arr[i].init(arr[i].background);
+            //if (Math.abs(circle.y) > yEscape || Math.abs(circle.x) > xEscape) arr[i].init(arr[i].background);
+            drawCircle(ctx, circle);
+        }
+        for (var i = 0; i < arr.length - 1; i++) {
+            for (var j = i + 1; j < arr.length; j++) {
+                var deltax = arr[i].x - arr[j].x;
+                var deltay = arr[i].y - arr[j].y;
+                var dist = Math.pow(Math.pow(deltax, 2) + Math.pow(deltay, 2), 0.5);
+                //if the circles are overlapping, no laser connecting them
+                if (dist <= arr[i].radius + arr[j].radius) continue;
+                //otherwise we connect them only if the dist is < linkDist
+                if (dist < linkDist) {
+                    var xi = (arr[i].x < arr[j].x ? 1 : -1) * Math.abs(arr[i].radius * deltax / dist);
+                    var yi = (arr[i].y < arr[j].y ? 1 : -1) * Math.abs(arr[i].radius * deltay / dist);
+                    var xj = (arr[i].x < arr[j].x ? -1 : 1) * Math.abs(arr[j].radius * deltax / dist);
+                    var yj = (arr[i].y < arr[j].y ? -1 : 1) * Math.abs(arr[j].radius * deltay / dist);
+                    ctx.beginPath();
+                    ctx.moveTo(arr[i].x + xi, arr[i].y + yi);
+                    ctx.lineTo(arr[j].x + xj, arr[j].y + yj);
+                    var samecolor = arr[i].color == arr[j].color;
+                    ctx.strokeStyle = ["rgba(", arr[i].borderColor, ",", Math.min(arr[i].opacity, arr[j].opacity) * ((linkDist - dist) / linkDist), ")"].join("");
+                    ctx.lineWidth = (arr[i].background ? lineBorder * backgroundMlt : lineBorder) * ((linkDist - dist) / linkDist); //*((linkDist-dist)/linkDist);
+                    ctx.stroke();
+                }
+            }
+        }
+    }
+
+    var startTime = Date.now();
+    renderPoints(ctxfr, points);
+    renderPoints(ctxbg, pointsBack);
+    deltaT = Date.now() - startTime;
+
+    ctxfr.restore();
+    ctxbg.restore();
+
+    window.requestAnimationFrame(draw);
+}
+
+$(function () {
+    init();
+});
+
+
+/*Credits and aknowledgements:
+Original Idea and Design by Luca Luzzatti
+
+Optimizing tips from Benjamin K?stner
+General tips from Salvatore Previti*/

+ 56 - 0
wwwroot/Plugins/animation/002/Style.css

@@ -0,0 +1,56 @@
+html,
+body {
+    overflow: hidden;
+    height: 100%;
+    width: 100%;
+    background: #262b2e
+}
+
+#wrapper {
+    height: 100%;
+    width: 100%;
+    text-align: center;
+    display: table;
+    position: absolute;
+}
+
+#title {
+    display: table-cell;
+    vertical-align: middle;
+    z-index: 999;
+}
+
+    #title h2 {
+        color: #fff;
+        font-size: 45px;
+        font-family: "museo-slab";
+    }
+
+    #title h3 {
+        color: #fff;
+        font-size: 25px;
+        font-family: "museo-sans";
+        font-weight: 300
+    }
+
+
+#wrapper canvas {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+}
+
+#canvas {
+    z-index: 1;
+}
+
+#canvasbg {
+    z-index: -10;
+    -webkit-filter: blur(3px);
+    -moz-filter: blur(3px);
+    -o-filter: blur(3px);
+    filter: blur(3px);
+    opacity: 0.6;
+}
+

+ 6 - 0
wwwroot/Plugins/animation/002/animation.js

@@ -0,0 +1,6 @@
+document.write('<link href="/plugins/animation/002/style.css" rel="stylesheet" />');
+document.write('<div id="wrapper">');
+document.write('<canvas id="canvas" width="1950" height="1024"></canvas>');
+document.write('<canvas id="canvasbg" width="1950" height="1024"></canvas>');
+document.write('</div>');
+document.write('<script src="/plugins/animation/002/JavaScript.js"></script>');

Файловите разлики са ограничени, защото са твърде много
+ 12 - 0
wwwroot/Plugins/animation/003/JavaScript.js


+ 11 - 0
wwwroot/Plugins/animation/003/Style.css

@@ -0,0 +1,11 @@
+html {
+    background: #000;
+}
+
+canvas {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+}

+ 2 - 0
wwwroot/Plugins/animation/003/animation.js

@@ -0,0 +1,2 @@
+document.write('<link href="/plugins/animation/003/style.css" rel="stylesheet" />');
+document.write('<script src="/plugins/animation/003/JavaScript.js"></script>');

+ 125 - 0
wwwroot/Plugins/animation/004/JavaScript.js

@@ -0,0 +1,125 @@
+
+var c1 = document.getElementById('c1'),
+    ctx1 = c1.getContext('2d'),
+    c2 = document.getElementById('c2'),
+    ctx2 = c2.getContext('2d'),
+    twopi = Math.PI * 2,
+    parts = [],
+    sizeBase,
+    cw,
+    opt,
+    hue,
+    count;
+
+function rand(min, max) {
+    return Math.random() * (max - min) + min;
+}
+
+function hsla(h, s, l, a) {
+    return 'hsla(' + h + ',' + s + '%,' + l + '%,' + a + ')';
+}
+
+function create() {
+    sizeBase = cw + ch;
+    count = Math.floor(sizeBase * 0.3),
+        hue = rand(0, 360),
+        opt = {
+            radiusMin: 1,
+            radiusMax: sizeBase * 0.04,
+            blurMin: 10,
+            blurMax: sizeBase * 0.04,
+            hueMin: hue,
+            hueMax: hue + 100,
+            saturationMin: 10,
+            saturationMax: 70,
+            lightnessMin: 20,
+            lightnessMax: 50,
+            alphaMin: 0.1,
+            alphaMax: 0.5
+        }
+    ctx1.clearRect(0, 0, cw, ch);
+    ctx1.globalCompositeOperation = 'lighter';
+    while (count--) {
+        var radius = rand(opt.radiusMin, opt.radiusMax),
+            blur = rand(opt.blurMin, opt.blurMax),
+            x = rand(0, cw),
+            y = rand(0, ch),
+            hue = rand(opt.hueMin, opt.hueMax),
+            saturation = rand(opt.saturationMin, opt.saturationMax),
+            lightness = rand(opt.lightnessMin, opt.lightnessMax),
+            alpha = rand(opt.alphaMin, opt.alphaMax);
+
+        ctx1.shadowColor = hsla(hue, saturation, lightness, alpha);
+        ctx1.shadowBlur = blur;
+        ctx1.beginPath();
+        ctx1.arc(x, y, radius, 0, twopi);
+        ctx1.closePath();
+        ctx1.fill();
+    }
+
+    parts.length = 0;
+    for (var i = 0; i < Math.floor((cw + ch) * 0.03); i++) {
+        parts.push({
+            radius: rand(1, sizeBase * 0.03),
+            x: rand(0, cw),
+            y: rand(0, ch),
+            angle: rand(0, twopi),
+            vel: rand(0.1, 0.5),
+            tick: rand(0, 10000)
+        });
+    }
+}
+
+function init() {
+    resize();
+    create();
+    loop();
+}
+
+function loop() {
+    requestAnimationFrame(loop);
+
+    ctx2.clearRect(0, 0, cw, ch);
+    ctx2.globalCompositeOperation = 'source-over';
+    ctx2.shadowBlur = 0;
+    ctx2.drawImage(c1, 0, 0);
+    ctx2.globalCompositeOperation = 'lighter';
+
+    var i = parts.length;
+    ctx2.shadowBlur = 15;
+    ctx2.shadowColor = '#fff';
+    while (i--) {
+        var part = parts[i];
+
+        part.x += Math.cos(part.angle) * part.vel;
+        part.y += Math.sin(part.angle) * part.vel;
+        part.angle += rand(-0.05, 0.05);
+
+        ctx2.beginPath();
+        ctx2.arc(part.x, part.y, part.radius, 0, twopi);
+        ctx2.fillStyle = hsla(0, 0, 100, 0.075 + Math.cos(part.tick * 0.02) * 0.05);
+        ctx2.fill();
+
+        if (part.x - part.radius > cw) { part.x = -part.radius }
+        if (part.x + part.radius < 0) { part.x = cw + part.radius }
+        if (part.y - part.radius > ch) { part.y = -part.radius }
+        if (part.y + part.radius < 0) { part.y = ch + part.radius }
+
+        part.tick++;
+    }
+}
+
+function resize() {
+    cw = c1.width = c2.width = window.innerWidth,
+        ch = c1.height = c2.height = window.innerHeight;
+    create();
+}
+
+function click() {
+    create()
+}
+
+window.addEventListener('resize', resize);
+window.addEventListener('click', click);
+
+init();

+ 20 - 0
wwwroot/Plugins/animation/004/Style.css

@@ -0,0 +1,20 @@
+body {
+    background: #000;
+    overflow: hidden;
+}
+
+canvas {
+    bottom: 0;
+    left: 0;
+    position: absolute;
+    right: 0;
+    top: 0;
+}
+
+#c1 {
+    opacity: 0;
+}
+
+#c2 {
+    background: #000;
+}

+ 4 - 0
wwwroot/Plugins/animation/004/animation.js

@@ -0,0 +1,4 @@
+document.write('<link href="/plugins/animation/004/style.css" rel="stylesheet" />');
+document.write('<canvas id="c1"></canvas>');
+document.write('<canvas id="c2"></canvas>');
+document.write('<script src="/plugins/animation/004/JavaScript.js"></script>');

Файловите разлики са ограничени, защото са твърде много
+ 6 - 0
wwwroot/Plugins/chartjs/chart.min.js


+ 147 - 0
wwwroot/Plugins/chartjs/utils.js

@@ -0,0 +1,147 @@
+'use strict';
+
+window.chartColors = {
+	red: 'rgb(255, 99, 132)',
+	orange: 'rgb(255, 159, 64)',
+	yellow: 'rgb(255, 205, 86)',
+	green: 'rgb(75, 192, 192)',
+	blue: 'rgb(54, 162, 235)',
+	purple: 'rgb(153, 102, 255)',
+	grey: 'rgb(201, 203, 207)'
+};
+
+(function(global) {
+	var MONTHS = [
+		'January',
+		'February',
+		'March',
+		'April',
+		'May',
+		'June',
+		'July',
+		'August',
+		'September',
+		'October',
+		'November',
+		'December'
+	];
+
+	var COLORS = [
+		'#4dc9f6',
+		'#f67019',
+		'#f53794',
+		'#537bc4',
+		'#acc236',
+		'#166a8f',
+		'#00a950',
+		'#58595b',
+		'#8549ba'
+	];
+
+	var Samples = global.Samples || (global.Samples = {});
+	var Color = global.Color;
+
+	Samples.utils = {
+		// Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
+		srand: function(seed) {
+			this._seed = seed;
+		},
+
+		rand: function(min, max) {
+			var seed = this._seed;
+			min = min === undefined ? 0 : min;
+			max = max === undefined ? 1 : max;
+			this._seed = (seed * 9301 + 49297) % 233280;
+			return min + (this._seed / 233280) * (max - min);
+		},
+
+		numbers: function(config) {
+			var cfg = config || {};
+			var min = cfg.min || 0;
+			var max = cfg.max || 1;
+			var from = cfg.from || [];
+			var count = cfg.count || 8;
+			var decimals = cfg.decimals || 8;
+			var continuity = cfg.continuity || 1;
+			var dfactor = Math.pow(10, decimals) || 0;
+			var data = [];
+			var i, value;
+
+			for (i = 0; i < count; ++i) {
+				value = (from[i] || 0) + this.rand(min, max);
+				if (this.rand() <= continuity) {
+					data.push(Math.round(dfactor * value) / dfactor);
+				} else {
+					data.push(null);
+				}
+			}
+
+			return data;
+		},
+
+		labels: function(config) {
+			var cfg = config || {};
+			var min = cfg.min || 0;
+			var max = cfg.max || 100;
+			var count = cfg.count || 8;
+			var step = (max - min) / count;
+			var decimals = cfg.decimals || 8;
+			var dfactor = Math.pow(10, decimals) || 0;
+			var prefix = cfg.prefix || '';
+			var values = [];
+			var i;
+
+			for (i = min; i < max; i += step) {
+				values.push(prefix + Math.round(dfactor * i) / dfactor);
+			}
+
+			return values;
+		},
+
+		months: function(config) {
+			var cfg = config || {};
+			var count = cfg.count || 12;
+			var section = cfg.section;
+			var values = [];
+			var i, value;
+
+			for (i = 0; i < count; ++i) {
+				value = MONTHS[Math.ceil(i) % 12];
+				values.push(value.substring(0, section));
+			}
+
+			return values;
+		},
+
+		color: function(index) {
+			return COLORS[index % COLORS.length];
+		},
+
+		transparentize: function(color, opacity) {
+			var alpha = opacity === undefined ? 0.5 : 1 - opacity;
+			return Color(color).alpha(alpha).rgbString();
+		}
+	};
+
+	// DEPRECATED
+	window.randomScalingFactor = function() {
+		return Math.round(Samples.utils.rand(-100, 100));
+	};
+
+	// INITIALIZATION
+
+	Samples.utils.srand(Date.now());
+
+	// Google Analytics
+	/* eslint-disable */
+	if (document.location.hostname.match(/^(www\.)?chartjs\.org$/)) {
+		(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+		(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+		m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+		})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+		ga('create', 'UA-28909194-3', 'auto');
+		ga('send', 'pageview');
+	}
+	/* eslint-enable */
+
+}(this));

+ 683 - 0
wwwroot/Plugins/easyui/changelog.txt

@@ -0,0 +1,683 @@
+Version 1.9.x
+-------------
+* Improvement
+ * datagrid: The 'sorter' function on the column accepts the entire row as the sorting parameters.
+ * datebox: Add 'getDate' and 'setDate' methods.
+ * pagination: Add 'onBeforeSelectPage' event.
+
+Version 1.9.0
+-------------
+* Bug
+ * datagrid: Slow scrolling with mousewheel on frozen columns. fixed.
+ * datagrid: The 'rowStyler' function is called on empty row. fixed.
+ * linkbutton: Calling 'disable' method still can submit the form. fixed.
+ * combotree: The 'onBeforeSelect' event fires twice while selecting a node. fixed.
+ * combotreegrid: The 'onSelect' event fires twice while selecting a row. fixed.
+* Improvement
+ * checkbox: Add 'readonly' property.
+ * radiobutton: Add 'readonly' property.
+ * Compatible with jQuery 3.x.
+* New Plugins
+ * timepicker: Allow the user to choose time on a clock.
+
+Version 1.8.0
+-------------
+* Bug
+ * treegrid: The 'pageNumber' can't be initialized with the specified value. fixed.
+ * checkbox: The disabled checkbox has no disabled label. fixed.
+* Improvement
+ * switchbutton: Add the 'label','labelAlign','labelPosition','labelWidth' properties.
+ * switchbutton: Accept 'tabindex' attribute to get focus when the user press TAB key.
+ * form: The 'onChange' event is available for all the form component.
+ * calendar: The 'Date' property is available to support the hijri date.
+ * textbox: The floating label is available.
+
+Version 1.7.0
+-------------
+* Bug
+ * sidemenu: The tooltip has a wrong position when the 'floatMenuPosition' is set to 'left'. fixed.
+ * datagrid: The horizontal scrollbar has a wrong state when the 'showHeader' is set to true. fixed.
+ * combo: The initialized value will trigger the form's 'onChange' event when the 'multiple' is set to true. fixed.
+ * panel: The horizontal panel doesn't work normally when 'noheader' property is set to true. fixed.
+ * pagination: The extended buttons may lose in IE when rebuild the component. fixed.
+* Improvement
+ * tree: Add 'findBy' method to find a node by any fields.
+ * tree: The 'find' method is enhanced to find a node easily.
+ * combo: Add 'panelValign' property.
+ * datagrid: The sorting parameters will be ignored when the 'remoteSort' is set to false.
+ * timespinner: Add 'hour12' property to display in 12 hour format.
+
+Version 1.6.0
+-------------
+* Bug
+ * maskedbox: The component does not accept numeric keypad. fixed.
+ * combogrid: When selecting multiple records, the datagrid will scroll to the last checked record. fixed.
+* Improvement
+ * Compatible with jQuery 3.x.
+ * tabs: The 'toolPosition' property can accept 'top' and 'bottom' values.
+ * textbox: The textbox label has the animating feature when focus or blur on it.
+ * tooltip: Add 'valign' property.
+ * tree: The node class can be initialized by setting the 'nodeCls' in the data.
+* New Plugins
+ * sidemenu: The sidemenu is created from accordion and tree plugins. It builds a collapsible menu with some categories.
+ * radiobutton: This plugin provides a round interface to select one option from a number of options.
+ * checkbox: This plugin allows a user to select a value from a small set of options.
+
+Version 1.5.5
+-------------
+* Bug
+ * tabs: The selecting history has wrong order when the title contains complex elements. fixed.
+ * combo: The drop-down panel may not be hidden if a bigger 'delay' value is set. fixed.
+ * layout: The expanding panel does not collapse when move mouse quickly away from it. fixed.
+ * tagbox: The tagbox and the label don't stay in the same line. fixed.
+* Improvement
+ * combo: The 'blur' event handler is attached to the 'inputEvents' property.
+ * numberbox: The 'cloneFrom' method is available.
+ * slider: The 'step' property can be set with a floating number.
+ * menu: The 'findItem' method allows the user to find menu item by any parameters.
+ * menubutton: Add 'showEvent' and 'hideEvent' properties.
+* New Plugins
+ * maskedbox: The maskedbox enforces its structure as the user types.
+
+Version 1.5.4
+-------------
+* Bug
+ * combotreegrid: The 'onChange' event does not fire when entering values on the inputing box. fixed.
+ * combobox: Clicking on the drop-down panel will jump to the bottom of body on win10 IE11. fixed.
+ * datebox: Clicking on the 'Today' button doesn't trigger the 'onSelect' event. fixed.
+ * propertygrid: The 'getChanges' method doesn't work after editing the only one row. fixed.
+* Improvement
+ * combo: Add the 'panelEvents' property.
+ * combo: Attach the default 'mousedown' event handler.
+ * combobox: The 'setValues' method can be called to initialize the displaying text.
+ * combotreegrid: Press ENTER key to select the highlighted rows.
+ * panel: Improve the resizing performance.
+ * filebox: The 'files' method allows the user to get the selected file list.
+ * searchbox: Improvent the 'selectName' method.
+
+Version 1.5.3
+-------------
+* Bug
+ * combobox: The 'iconCls' property can not be parsed from the <option> markup. fixed.
+ * combobox: Clicking scrollbar will cause the drop-down panel to be hidden in IE. fixed.
+ * pagination: The pagination height will shrink when the 'displayMsg' property is set to false. fixed.
+ * tabs: The tab panel takes a wrong 'data' parameter in the 'onLoad' event. fixed.
+* Improvement
+ * draggable: Add 'onEndDrag' event.
+ * resizable: Retrieve more than one resizing directions with different edges.
+ * datagrid: Add 'resizeEdge' property.
+ * datagrid: Avoid the memory leaks.
+ * combo: The 'originalValue' property value is corrected in multiple mode.
+ * form: Add the tagbox to the form fields.
+ * tagbox: Add the 'reset' method.
+ * progress: Increase the response time to open and close the progress message window.
+ 
+Version 1.5.2
+-------------
+* Bug
+ * form: The initialized value of the inputing box will disappear after calling the 'reset' method. fixed.
+ * textbox: Calling the 'destroy' method does not clean the field label. fixed.
+ * datagrid: Calling the 'selectRow' method on an unexisting row causes undesired record set. fixed.
+* Improvement
+ * datagrid: The ctrl selection is supported on Mac keyboards.
+ * datagrid: The 'scrollOnSelect' property is available for the user to determine whether to scroll to the specified row when selecting it.
+ * combotree: Add the 'textField' property.
+ * combotreegrid: Add the 'textField' property.
+ * pagination: Add 'showPageInfo' property.
+ * panel: Add 'halign' and 'titleDirection' properties to allow the user to align the panel header to left or right side.
+ * accordion: Add 'halign' property to build the horizontal accordion.
+ * tagbox: The 'required' propery can be applied to validate whether the value is empty.
+
+Version 1.5.1
+-------------
+* Bug
+ * datagrid: The selecting and checking flags will lose after calling 'updateRow' method. fixed.
+ * tabs: The trip tools have a wrong position when calling 'update' method. fixed.
+ * window: When the height is set to 'auto', it will disappear after moving the window. fixed.
+ * messager: When display the progress message window and then close it immediately, an exception occurs. fixed.
+ * form: The 'clear' method does not clear the selected drop-down items of the combobox. fixed.
+* Improvement
+ * textbox: The 'cls' property is available to add a custom style to textbox.
+ * numberbox: Allow the user to format currency in Italian.
+ * combo: Add 'multivalue' property that allows the user to determine how to submit the multiple values.
+ * combobox: Add 'reversed' property.
+ * combobox: Add 'onClick' event.
+ * combogrid: Add 'reversed' property.
+ * treegrid: Enable multiple selection with the shift key.
+* New Plugins
+ * tagbox: Allows the user to add tags to a form field.
+
+Version 1.5
+-------------
+* Bug
+ * combobox: The 'onSelect' event does not fire when load data that contains the selected item. fixed.
+ * datagrid: The 'updateRow' method sometimes does not work properly when the field is set to a blank value. fixed.
+* Improvement
+ * A label can be associated to any form fields.
+ * combobox: Enhance the 'select' and 'unselect' rules on the drop-down items.
+ * combobox: Add 'limitToList' property to limit the inputed values to the listed items.
+ * combogrid: Allow the user to clone the component quickly.
+ * form: Add the 'dirty' property that allows the user to submit the only changed fields.
+ * form: Add 'resetDirty' method.
+ * datagrid: Allow the user to display a message when there are no records to be shown.
+ * textbox: Add 'label','labelWidth','labelPosition' and 'labelAlign' properties.
+ * spinner: Add 'spinAlign' property.
+ * calendar: Allow the user to display week number of the year.
+ * window: Add 'constrain' property.
+* New Plugins
+ * passwordbox: The plugin that allows the user to input passwords with nice feedback.
+ * combotreegrid: Combines combobox with drop-down treegrid component.
+
+Version 1.4.5
+-------------
+* Bug
+ * datagrid: The 'getChanges' method does not return the updated rows after calling 'updateRow' method. fixed.
+ * treegrid: The 'onLoadSuccess' event fires when append or insert a row. fixed.
+ * tree: The 'onLoadSuccess' event fires when append or insert a node. fixed.
+* Improvement
+ * window: The displaying style can be customized.
+ * window: The 'border' property allows the user to set different border style.
+ * navpanel: The 'href' property is enabled to load content from remote server.
+ * combotree: The 'setValue' and 'setValues' methods accept the paremter values in 'id' and 'text' pairs
+ * combobox: Add 'showItemIcon' property.
+ * combobox: Set 'groupPosition' property to 'sticky' to stick the item group to the top of drop-down panel.
+ * messager: Pressing ENTER key on input box will trigger click event of the first button.
+ * validatebox: Add 'editable',disabled' and 'readonly' properties.
+ * validatebox: Add 'enable','disable','readonly' methods.
+ * validatebox: Allow the user to determine how to display the error message.
+ * filebox: Add 'accept' and 'multiple' properties.
+ * form: Add 'iframe' property and 'onProgress' event.
+ * treegrid: Add cascade checkbox selection.
+ * treegrid: Add 'getCheckedNodes','checkNode' and 'uncheckNode' methods.
+
+Version 1.4.4
+-------------
+* Bug
+ * filebox: The 'clear' and 'reset' methods do not work properly in IE9. fixed.
+ * messager: After calling $.messager.progress() with no arguments, the $.messager.progress('close') does not work properly. fixed.
+ * timespinner: The value does not display properly in IE8 while clicking the spin buttons. fixed.
+ * window: The window does not display when calling 'options' method in 'onMove' event. fixed.
+ * treegrid: The 'getLevel' method does not accept the parameter value of 0. fixed.
+* Improvement
+ * layout: The 'collapsedContent','expandMode' and 'hideExpandTool' properties are supported in region panel.
+ * layout: The 'hideCollapsedContent' property can be set to display the vertical title bar on collapsed panel.
+ * layout: Add 'onCollapse','onExpand','onAdd','onRemove' events.
+ * datagrid: Display the 'up-down' icon on the sortable columns.
+ * datagrid: Add 'gotoPage' method.
+ * propertygrid: Add 'groups' method that allows to get all the data groups.
+ * messager: Auto scroll feature is supported when displaying long messages.
+ * tabs: The 'disabled' property is supported when defining a disabled tab panel.
+ * tabs: The percentange size is supported now.
+
+Version 1.4.3
+-------------
+* Bug
+ * textbox: The 'setText' method does not accept value 0. fixed.
+ * timespinner: When running in IE11, the error occurs when clicking on the empty textbox. fixed.
+ * tabs: The 'update' method can not update only the panel body. fixed.
+* Improvement
+ * combobox: Improve the performance of displaying the drop-down panel.
+ * combogrid: Remember the displaying text when the drop-down datagrid go to other pages.
+ * combogrid: The 'setValue' and 'setValues' methods accept a key-value object.
+ * window: The inline window's mask can auto-stretch its size to fill parent container.
+ * tabs: The 'showTool' and 'hideTool' methods are available for users to show or hide the tools.
+ * layout: Allow the user to override the 'cls','headerCls' and 'bodyCls' property values.
+* New Plugins
+ * switchbutton: The switch button with two states:'on' and 'off'.
+
+Version 1.4.2
+-------------
+* Bug
+ * treegrid: The column will restore its size to original size after recreating the treegrid. fixed.
+* Improvement
+ * draggable: Add 'delay' property that allows the user to delay the drag operation.
+ * tree: Add 'filter' property and 'doFilter' method.
+ * tabs: The 'add' method allows the user to insert a tab panel at a specified index.
+ * tabs: The user can determine what tab panel can be selected.
+ * tabs: Add 'justified' and 'narrow' properties.
+ * layout: Add 'unsplit' and 'split' methods.
+ * messager: Keyboard navigation features are supported now.
+ * form: Add 'onChange' event.
+ * combobox: Add 'queryParams' property.
+ * slider: Add 'range' property.
+ * menu: Add 'itemHeight','inline','noline' properties.
+ * panel: The 'header' property allows the user to customize the panel header.
+ * menubutton: Add 'hasDownArrow' property.
+* New Plugins
+ * datalist: The plugin to render items in a list.
+ * navpanel: The root component for the mobile page.
+ * mobile: The plugin to provide the mobile page stack management and navigation.
+
+Version 1.4.1
+-------------
+* Bug
+ * combogrid: The combogrid has different height than other combo components. fixed.
+ * datagrid: The row element loses some class style value after calling 'updateRow' method. fixed.
+ * menubutton: Calling 'enable' method on a disabled button can not work well. fixed.
+ * form: The filebox components in the form do not work correctly after calling 'clear' method. fixed.
+* Improvement
+ * tabs: The 'update' method accepts 'type' option that allows the user to update the header,body,or both.
+ * panel: Add 'openAnimation','openDuration','closeAnimation' and 'closeDuration' properties to set the animation for opening or closing a panel.
+ * panel: Add 'footer' property that allows the user to add a footer bar to the bottom of panel.
+ * datagrid: Calling 'endEdit' method will accept the editing value correctly.
+ * datagrid: Add 'onBeforeSelect','onBeforeCheck','onBeforeUnselect','onBeforeUncheck' events.
+ * propertygrid: The user can edit a row by calling 'beginEdit' method.
+ * datebox: Add 'cloneFrom' method to create the datebox component quickly.
+ * datetimebox: Add 'cloneFrom' method to create the datetimebox component quickly.
+
+Version 1.4
+-------------
+* Bug
+ * menu: The menu should not has a correct height when removed a menu item. fixed.
+ * datagrid: The 'fitColumns' method does not work normally when the datarid width is too small. fixed.
+* Improvement
+ * The fluid/percentange size is supported now for all easyui components.
+ * menu: Add 'showItem', 'hideItem' and 'resize' methods.
+ * menu: Auto resize the height upon the window size.
+ * menu: Add 'duration' property that allows the user to define duration time in milliseconds to hide menu.
+ * validatebox: Add 'onBeforeValidate' and 'onValidate' events.
+ * combo: Extended from textbox now.
+ * combo: Add 'panelMinWidth','panelMaxWidth','panelMinHeight' and 'panelMaxHeight' properties.
+ * searchbox: Extended from textbox now.
+ * tree: The 'getRoot' method will return the top parent node of a specified node if pass a 'nodeEl' parameter.
+ * tree: Add 'queryParams' property.
+ * datetimebox: Add 'spinnerWidth' property.
+ * panel: Add 'doLayout' method to cause the panel to lay out its components.
+ * panel: Add 'clear' method to clear the panel's content.
+ * datagrid: The user is allowed to assign percent width to columns.
+ * form: Add 'ajax','novalidate' and 'queryParams' properties.
+ * linkbutton: Add 'resize' method.
+* New Plugins
+ * textbox: A enhanced input field that allows users build their form easily.
+ * datetimespinner: A date and time spinner that allows to pick a specific day.
+ * filebox: The filebox component represents a file field of the forms.
+
+Version 1.3.6
+-------------
+* Bug
+ * treegrid: The 'getChecked' method can not return correct checked rows. fixed.
+ * tree: The checkbox does not display properly on async tree when 'onlyLeafCheck' property is true. fixed.
+* Improvement
+ * treegrid: All the selecting and checking methods are extended from datagrid component.
+ * linkbutton: The icon alignment is fully supported, possible values are: 'top','bottom','left','right'.
+ * linkbutton: Add 'size' property, possible values are: 'small','large'.
+ * linkbutton: Add 'onClick' event.
+ * menubutton: Add 'menuAlign' property that allows the user set top level menu alignment.
+ * combo: Add 'panelAlign' property, possible values are: 'left','right'.
+ * calendar: The 'formatter','styler' and 'validator' options are available to custom the calendar dates.
+ * calendar: Add 'onChange' event.
+ * panel: Add 'method','queryParams' and 'loader' options.
+ * panel: Add 'onLoadError' event.
+ * datagrid: Add 'onBeginEdit' event that fires when a row goes into edit mode.
+ * datagrid: Add 'onEndEdit' event that fires when finishing editing but before destroying editors.
+ * datagrid: Add 'sort' method and 'onBeforeSortColumn' event.
+ * datagrid: The 'combogrid' editor has been integrated into datagrid.
+ * datagrid: Add 'ctrlSelect' property that only allows multi-selection when ctrl+click is used.
+ * slider: Add 'converter' option that allows users determine how to convert a value to the slider position or the slider position to the value.
+ * searchbox: Add 'disabled' property.
+ * searchbox: Add 'disable','enable','clear','reset' methods.
+ * spinner: Add 'readonly' property, 'readonly' method and 'onChange' event.
+
+Version 1.3.5
+-------------
+* Bug
+ * searchbox: The 'searcher' function can not offer 'name' parameter value correctly. fixed.
+ * combo: The 'isValid' method can not return boolean value. fixed.
+ * combo: Clicking combo will trigger the 'onHidePanel' event of other combo components that have hidden drop-down panels. fixed.
+ * combogrid: Some methods can not inherit from combo. fixed.
+* Improvement
+ * datagrid: Improve performance on checking rows.
+ * menu: Allows to append a menu separator.
+ * menu: Add 'hideOnUnhover' property to indicate if the menu should be hidden when mouse exits it.
+ * slider: Add 'clear' and 'reset' methods.
+ * tabs: Add 'unselect' method that will trigger 'onUnselect' event.
+ * tabs: Add 'selected' property to specify what tab panel will be opened.
+ * tabs: The 'collapsible' property of tab panel is supported to determine if the tab panel can be collapsed.
+ * tabs: Add 'showHeader' property, 'showHeader' and 'hideHeader' methods.
+ * combobox: The 'disabled' property can be used to disable some items.
+ * tree: Improve loading performance.
+ * pagination: The 'layout' property can be used to customize the pagination layout.
+ * accordion: Add 'unselect' method that will trigger 'onUnselect' event.
+ * accordion: Add 'selected' and 'multiple' properties.
+ * accordion: Add 'getSelections' method.
+ * datebox: Add 'sharedCalendar' property that allows multiple datebox components share one calendar component.
+
+Version 1.3.4
+-------------
+* Bug
+ * combobox: The onLoadSuccess event fires when parsing empty local data. fixed.
+ * form: Calling 'reset' method can not reset datebox field. fixed.
+* Improvement
+ * mobile: The context menu and double click features are supported on mobile devices.
+ * combobox: The 'groupField' and 'groupFormatter' options are available to display items in groups.
+ * tree: When append or insert nodes, the 'data' parameter accepts one or more nodes data.
+ * tree: The 'getChecked' method accepts a single 'state' or an array of 'state'.
+ * tree: Add 'scrollTo' method.
+ * datagrid: The 'multiSort' property is added to support multiple column sorting.
+ * datagrid: The 'rowStyler' and column 'styler' can return CSS class name or inline styles.
+ * treegrid: Add 'load' method to load data and navigate to the first page.
+ * tabs: Add 'tabWidth' and 'tabHeight' properties.
+ * validatebox: The 'novalidate' property is available to indicate whether to perform the validation.
+ * validatebox: Add 'enableValidation' and 'disableValidation' methods.
+ * form: Add 'enableValidation' and 'disableValidation' methods.
+ * slider: Add 'onComplete' event.
+ * pagination: The 'buttons' property accepts the existing element.
+
+Version 1.3.3
+-------------
+* Bug
+ * datagrid: Some style features are not supported by column styler function. fixed.
+ * datagrid: IE 31 stylesheet limit. fixed.
+ * treegrid: Some style features are not supported by column styler function. fixed.
+ * menu: The auto width of menu item displays incorrect in ie6. fixed.
+ * combo: The 'onHidePanel' event can not fire when clicked outside the combo area. fixed. 
+* Improvement
+ * datagrid: Add 'scrollTo' and 'highlightRow' methods.
+ * treegrid: Enable treegrid to parse data from <tbody> element.
+ * combo: Add 'selectOnNavigation' and 'readonly' options.
+ * combobox: Add 'loadFilter' option to allow users to change data format before loading into combobox.
+ * tree: Add 'onBeforeDrop' callback event.
+ * validatebox: Dependent on tooltip plugin now, add 'deltaX' property.
+ * numberbox: The 'filter' options can be used to determine if the key pressed was accepted.
+ * linkbutton: The group button is available.
+ * layout: The 'minWidth','maxWidth','minHeight','maxHeight' and 'collapsible' properties are available for region panel.
+* New Plugins
+ * tooltip: Display a popup message when moving mouse over an element.
+ 
+Version 1.3.2
+-------------
+* Bug
+ * datagrid: The loading message window can not be centered when changing the width of datagrid. fixed.
+ * treegrid: The 'mergeCells' method can not work normally. fixed.
+ * propertygrid: Calling 'endEdit' method to stop editing a row will cause errors. fixed.
+ * tree: Can not load empty data when 'lines' property set to true. fixed.
+* Improvement
+ * RTL feature is supported now.
+ * tabs: Add 'scrollBy' method to scroll the tab header by the specified amount of pixels
+ * tabs: Add 'toolPosition' property to set tab tools to left or right.
+ * tabs: Add 'tabPosition' property to define the tab position, possible values are: 'top','bottom','left','right'.
+ * datagrid: Add a column level property 'order' that allows users to define different default sort order per column.
+ * datagrid: Add a column level property 'halign' that allows users to define how to align the column header.
+ * datagrid: Add 'resizeHandle' property to define the resizing column position, by grabbing the left or right edge of the column.
+ * datagrid: Add 'freezeRow' method to freeze some rows that will always be displayed at the top when the datagrid is scrolled down.
+ * datagrid: Add 'clearChecked' method to clear all checked records.
+ * datagrid: Add 'data' property to initialize the datagrid data.
+ * linkbutton: Add 'iconAlgin' property to define the icon position, supported values are: 'left','right'.
+ * menu: Add 'minWidth' property.
+ * menu: The menu width can be automatically calculated.
+ * tree: New events are available including 'onBeforeDrag','onStartDrag','onDragEnter','onDragOver','onDragLeave',etc.
+ * combo: Add 'height' property to allow users to define the height of combo.
+ * combo: Add 'reset' method.
+ * numberbox: Add 'reset' method.
+ * spinner: Add 'reset' method.
+ * spinner: Add 'height' property to allow users to define the height of spinner.
+ * searchbox: Add 'height' property to allow users to define the height of searchbox.
+ * form: Add 'reset' method.
+ * validatebox: Add 'delay' property to delay validating from the last inputting value.
+ * validatebox: Add 'tipPosition' property to define the tip position, supported values are: 'left','right'.
+ * validatebox: Multiple validate rules on a field is supported now.
+ * slider: Add 'reversed' property to determine if the min value and max value will switch their positions.
+ * progressbar: Add 'height' property to allow users to define the height of progressbar.
+
+Version 1.3.1
+-------------
+* Bug
+ * datagrid: Setting the 'pageNumber' property is not valid. fixed.
+ * datagrid: The id attribute of rows isn't adjusted properly while calling 'insertRow' or 'deleteRow' method.
+ * dialog: When load content from 'href', the script will run twice. fixed.
+ * propertygrid: The editors that extended from combo can not accept its changed value. fixed.
+* Improvement
+ * droppable: Add 'disabled' property.
+ * droppable: Add 'options','enable' and 'disable' methods.
+ * tabs: The tab panel tools can be changed by calling 'update' method.
+ * messager: When show a message window, the user can define the window position by applying 'style' property.
+ * window: Prevent script on window body from running twice.
+ * window: Add 'hcenter','vcenter' and 'center' methods.
+ * tree: Add 'onBeforeCheck' callback event.
+ * tree: Extend the 'getChecked' method to allow users to get 'checked','unchecked' or 'indeterminate' nodes.
+ * treegrid: Add 'update' method to update a specified node.
+ * treegrid: Add 'insert' method to insert a new node.
+ * treegrid: Add 'pop' method to remove a node and get the removed node data.
+
+Version 1.3
+-----------
+* Bug
+ * combogrid: When set to 'remote' query mode, the 'queryParams' parameters can't be sent to server. fixed.
+ * combotree: The tree nodes on drop-down panel can not be unchecked while calling 'clear' method. fixed.
+ * datetimebox: Setting 'showSeconds' property to false cannot hide seconds info. fixed.
+ * datagrid: Calling 'mergeCells' method can't auto resize the merged cell while header is hidden. fixed.
+ * dialog: Set cache to false and load data via ajax, the content cannot be refreshed. fixed.
+* Improvement
+ * The HTML5 'data-options' attribute is available for components to declare all custom options, including properties and events.
+ * More detailed documentation is available.
+ * panel: Prevent script on panel body from running twice.
+ * accordion: Add 'getPanelIndex' method.
+ * accordion: The tools can be added on panel header.
+ * datetimebox: Add 'timeSeparator' option that allows users to define the time separator.
+ * pagination: Add 'refresh' and 'select' methods.
+ * datagrid: Auto resize the column width to fit the contents when the column width is not defined.
+ * datagrid: Double click on the right border of columns to auto resize the columns to the contents in the columns.
+ * datagrid: Add 'autoSizeColumn' method that allows users to adjust the column width to fit the contents.
+ * datagrid: Add 'getChecked' method to get all rows where the checkbox has been checked.
+ * datagrid: Add 'selectOnCheck' and 'checkOnSelect' properties and some checking methods to enhance the row selections.
+ * datagrid: Add 'pagePosition' property to allow users to display pager bar at either top,bottom or both places of the grid.
+ * datagrid: The buffer view and virtual scroll view are supported to display large amounts of records without pagination.
+ * tabs: Add 'disableTab' and 'enableTab' methods to allow users to disable or enable a tab panel.
+
+Version 1.2.6
+-------------
+* Bug
+ * tabs: Call 'add' method with 'selected:false' option, the added tab panel is always selected. fixed.
+ * treegrid: The 'onSelect' and 'onUnselect' events can't be triggered. fixed.
+ * treegrid: Cannot display zero value field. fixed. 
+* Improvement
+ * propertygrid: Add 'expandGroup' and 'collapseGroup' methods.
+ * layout: Allow users to create collapsed layout panels by assigning 'collapsed' property to true.
+ * layout: Add 'add' and 'remove' methods that allow users to dynamically add or remove region panel.
+ * layout: Additional tool icons can be added on region panel header.
+ * calendar: Add 'firstDay' option that allow users to set first day of week. Sunday is 0, Monday is 1, ...
+ * tree: Add 'lines' option, true to display tree lines. 
+ * tree: Add 'loadFilter' option that allow users to change data format before loading into the tree.
+ * tree: Add 'loader' option that allow users to define how to load data from remote server.
+ * treegrid: Add 'onClickCell' and 'onDblClickCell' callback function options.
+ * datagrid: Add 'autoRowHeight' property that allow users to determine if set the row height based on the contents of that row.
+ * datagrid: Improve performance to load large data set.
+ * datagrid: Add 'loader' option that allow users to define how to load data from remote server.
+ * treegrid: Add 'loader' option that allow users to define how to load data from remote server.
+ * combobox: Add 'onBeforeLoad' callback event function.
+ * combobox: Add 'loader' option that allow users to define how to load data from remote server.
+ * Add support for other loading mode such as dwr,xml,etc.
+* New Plugins
+ * slider: Allows the user to choose a numeric value from a finite range.
+
+Version 1.2.5
+-------------
+* Bug
+ * tabs: When add a new tab panel with href property, the content page is loaded twice. fixed.
+ * form: Failed to call 'load' method to load form input with complex name. fixed.
+ * draggable: End drag in ie9, the cursor cannot be restored. fixed.
+* Improvement
+ * panel: The tools can be defined via html markup.
+ * tabs: Call 'close' method to close specified tab panel, users can pass tab title or index of tab panel. Other methods such 'select','getTab' and 'exists' are similar to 'close' method.
+ * tabs: Add 'getTabIndex' method.
+ * tabs: Users can define mini tools on tabs.
+ * tree: The mouse must move a specified distance to begin drag and drop operation.
+ * resizable: Add 'options','enable' and 'disable' methods.
+ * numberbox: Allow users to change number format.
+ * datagrid: The subgrid is supported now.
+ * searchbox: Add 'selectName' method to select searching type name.
+
+Version 1.2.4
+-------------
+* Bug
+ * menu: The menu position is wrong when scroll bar appears. fixed.
+ * accordion: Cannot display the default selected panel in jQuery 1.6.2. fixed.
+ * tabs: Cannot display the default selected tab panel in jQuery 1.6.2. fixed.
+* Improvement
+ * menu: Allow users to disable or enable menu item.
+ * combo: Add 'delay' property to set the delay time to do searching from the last key input event.
+ * treegrid: The 'getEditors' and 'getEditor' methods are supported now.
+ * treegrid: The 'loadFilter' option is supported now.
+ * messager: Add 'progress' method to display a message box with a progress bar.
+ * panel: Add 'extractor' option to allow users to extract panel content from ajax response.
+* New Plugins
+ * searchbox: Allow users to type words into box and do searching operation.
+ * progressbar: To display the progress of a task.
+ 
+Version 1.2.3
+-------------
+* Bug
+ * window: Cannot resize the window with iframe content. fixed.
+ * tree: The node will be removed when dragging to its child. fixed.
+ * combogrid: The onChange event fires multiple times. fixed.
+ * accordion: Cannot add batch new panels when animate property is set to true. fixed.
+* Improvement
+ * treegrid: The footer row and row styler features are supported now.
+ * treegrid: Add 'getLevel','reloadFooter','getFooterRows' methods.
+ * treegrid: Support root nodes pagination and editable features.
+ * datagrid: Add 'getFooterRows','reloadFooter','insertRow' methods and improve editing performance.
+ * datagrid: Add 'loadFilter' option that allow users to change original source data to standard data format.
+ * draggable: Add 'onBeforeDrag' callback event function.
+ * validatebox: Add 'remote' validation type.
+ * combobox: Add 'method' option.
+* New Plugins
+ * propertygrid: Allow users to edit property value in datagrid. 
+
+Version 1.2.2
+-------------
+* Bug
+ * datagrid: Apply fitColumns cannot work fine while set checkbox column. fixed.
+ * datagrid: The validateRow method cannot return boolean type value. fixed.
+ * numberbox: Cannot fix value in chrome when min or max property isn't defined. fixed.
+* Improvement
+ * menu: Add some crud methods.
+ * combo: Add hasDownArrow property to determine whether to display the down arrow button.
+ * tree: Supports inline editing.
+ * calendar: Add some useful methods such as 'resize', 'moveTo' etc.
+ * timespinner: Add some useful methods.
+ * datebox: Refactoring based on combo and calendar plugin now.
+ * datagrid: Allow users to change row style in some conditions.
+ * datagrid: Users can use the footer row to display summary information.
+* New Plugins
+ * datetimebox: Combines datebox with timespinner component.
+  
+Version 1.2.1
+-------------
+* Bug
+ * easyloader: Some dependencies cannot be loaded by their order. fixed.
+ * tree: The checkbox is setted incorrectly when removing a node. fixed.
+ * dialog: The dialog layout incorrectly when 'closed' property is setted to true. fixed.
+* Improvement
+ * parser: Add onComplete callback function that can indicate whether the parse action is complete.
+ * menu: Add onClick callback function and some other methods.
+ * tree: Add some useful methods.
+ * tree: Drag and Drop feature is supported now.
+ * tree: Add onContextMenu callback function.
+ * tabs: Add onContextMenu callback function.
+ * tabs: Add 'tools' property that can create buttons on right bar.
+ * datagrid: Add onHeaderContextMenu and onRowContextMenu callback functions.
+ * datagrid: Custom view is supported.
+ * treegrid: Add onContextMenu callback function and append,remove methods.
+  
+Version 1.2
+-------------
+* Improvement
+ * tree: Add cascadeCheck,onlyLeafCheck properties and select event.
+ * combobox: Enable multiple selection.
+ * combotree: Enable multiple selection.
+ * tabs: Remember the trace of selection, when current tab panel is closed, the previous selected tab will be selected.
+ * datagrid: Extend from panel, so many properties defined in panel can be used for datagrid.
+* New Plugins
+ * treegrid: Represent tabular data in hierarchical view, combines tree view and datagrid.
+ * combo: The basic component that allow user to extend their combo component such as combobox,combotree,etc.
+ * combogrid: Combines combobox with drop-down datagrid component.
+ * spinner: The basic plugin to create numberspinner,timespinner,etc.
+ * numberspinner: The numberbox that allow user to change value by clicking up and down spin buttons.
+ * timespinner: The time selector that allow user to quickly inc/dec a time.
+ 
+Version 1.1.2
+-------------
+* Bug
+ * messager: When call show method in layout, the message window will be blocked. fixed.
+* Improvement
+ * datagrid: Add validateRow method, remember the current editing row status when do editing action.
+ * datagrid: Add the ability to create merged cells.
+ * form: Add callback functions when loading data.
+ * panel,window,dialog: Add maximize,minimize,restore,collapse,expand methods.
+ * panel,tabs,accordion: The lazy loading feature is supported.
+ * tabs: Add getSelected,update,getTab methods.
+ * accordion: Add crud methods.
+ * linkbutton: Accept an id option to set the id attribute.
+ * tree: Enhance tree node operation.
+ 
+Version 1.1.1
+-------------
+* Bug
+ * form: Cannot clear the value of combobox and combotree component. fixed.
+* Improvement
+ * tree: Add some useful methods such as 'getRoot','getChildren','update',etc.
+ * datagrid: Add editable feature, improve performance while loading data.
+ * datebox: Add destroy method.
+ * combobox: Add destroy and clear method.
+ * combotree: Add destroy and clear method.
+ 
+Version 1.1
+-------------
+* Bug
+ * messager: When call show method with timeout property setted, an error occurs while clicking the close button. fixed.
+ * combobox: The editable property of combobox plugin is invalid. fixed.
+ * window: The proxy box will not be removed when dragging or resizing exceed browser border in ie. fixed.
+* Improvement
+ * menu: The menu item can use <a> markup to display a different page.
+ * tree: The tree node can use <a> markup to act as a tree menu.
+ * pagination: Add some event on refresh button and page list.
+ * datagrid: Add a 'param' parameter for reload method, with which users can pass query parameter when reload data.
+ * numberbox: Add required validation support, the usage is same as validatebox plugin.
+ * combobox: Add required validation support.
+ * combotree: Add required validation support.
+ * layout: Add some method that can get a region panel and attach event handlers.
+* New Plugins
+ * droppable: A droppable plugin that supports drag drop operation.
+ * calendar: A calendar plugin that can either be embedded within a page or popup.
+ * datebox: Combines a textbox with a calendar that let users to select date.
+ * easyloader: A JavaScript loader that allows you to load plugin and their dependencies into your page.
+ 
+Version 1.0.5
+* Bug
+ * panel: The fit property of panel performs incorrectly. fixed.
+* Improvement
+ * menu: Add a href attribute for menu item, with which user can display a different page in the current browser window.
+ * form: Add a validate method to do validation for validatebox component.
+ * dialog: The dialog can read collapsible,minimizable,maximizable and resizable attribute from markup.
+* New Plugins
+ * validatebox: A validation plugin that checks to make sure the user's input value is valid. 
+ 
+Version 1.0.4
+-------------
+* Bug
+ * panel: When panel is invisible, it is abnormal when resized. fixed.
+ * panel: Memory leak in method 'destroy'. fixed.
+ * messager: Memory leak when messager box is closed. fixed.
+ * dialog: No onLoad event occurs when loading remote data. fixed.
+* Improvement
+ * panel: Add method 'setTitle'.
+ * window: Add method 'setTitle'.
+ * dialog: Add method 'setTitle'.
+ * combotree: Add method 'getValue'.
+ * combobox: Add method 'getValue'.
+ * form: The 'load' method can load data and fill combobox and combotree field correctly.
+ 
+Version 1.0.3
+-------------
+* Bug
+ * menu: When menu is show in a DIV container, it will be cropped. fixed.
+ * layout: If you collpase a region panel and then expand it immediately, the region panel will not show normally. fixed.
+ * accordion: If no panel selected then the first one will become selected and the first panel's body height will not set correctly. fixed.
+* Improvement
+ * tree: Add some methods to support CRUD operation.
+ * datagrid: Toolbar can accept a new property named 'disabled' to disable the specified tool button.
+* New Plugins
+ * combobox: Combines a textbox with a list of options that users are able to choose from.
+ * combotree: Combines combobox with drop-down tree component.
+ * numberbox: Make input element can only enter number char.
+ * dialog: rewrite the dialog plugin, dialog can contains toolbar and buttons.

+ 216 - 0
wwwroot/Plugins/easyui/datagrid-export.js

@@ -0,0 +1,216 @@
+/**
+ * DataGrid Export for jQuery EasyUI
+ * version: 1.0.2
+ */
+ 
+(function($){
+    function getRows(target){
+        var state = $(target).data('datagrid');
+        if (state.filterSource){
+            return state.filterSource.rows;
+        } else {
+            return state.data.rows;
+        }
+    }
+    function getFooterRows(target){
+        var state = $(target).data('datagrid');
+        return state.data.footer || [];
+    }
+    function toHtml(target, rows, footer, caption){
+        rows = rows || getRows(target);
+        rows = rows.concat(footer||getFooterRows(target));
+        var dg = $(target);
+        var data = ['<table border="1" rull="all" style="border-collapse:collapse">'];
+        var fields = dg.datagrid('getColumnFields',true).concat(dg.datagrid('getColumnFields',false));
+        var trStyle = 'height:32px';
+        var tdStyle0 = 'vertical-align:middle;padding:0 4px';
+        if (caption){
+            data.push('<caption>'+caption+'</caption>');
+        }
+        data.push('<tr style="'+trStyle+'">');
+        for(var i=0; i<fields.length; i++){
+            var col = dg.datagrid('getColumnOption', fields[i]);
+            var tdStyle = tdStyle0 + ';width:'+col.boxWidth+'px;';
+            tdStyle += ';text-align:'+(col.halign||col.align||'');
+            data.push('<td style="'+tdStyle+'">'+col.title+'</td>');
+        }
+        data.push('</tr>');
+        $.map(rows, function(row){
+            data.push('<tr style="'+trStyle+'">');
+            for(var i=0; i<fields.length; i++){
+                var field = fields[i];
+                var col   = dg.datagrid('getColumnOption', field);
+                var value = row[field];
+                if (value == undefined){
+                    value = '';
+                }
+                var tdStyle = tdStyle0;
+                tdStyle += ';text-align:'+(col.align||'');
+                data.push(
+                    '<td style="'+tdStyle+'">'+value+'</td>'
+                );
+            }
+            data.push('</tr>');
+        });
+        data.push('</table>');
+        return data.join('');
+    }
+
+    function toArray(target, rows, footer){
+        rows = rows || getRows(target);
+        rows = rows.concat(footer||getFooterRows(target));
+        var dg = $(target);
+        var fields = dg.datagrid('getColumnFields',true).concat(dg.datagrid('getColumnFields',false));
+        var data = [];
+        var r = [];
+        for(var i=0; i<fields.length; i++){
+            var col = dg.datagrid('getColumnOption', fields[i]);
+            r.push(col.title);
+        }
+        data.push(r);
+        $.map(rows, function(row){
+            var r = [];
+            for(var i=0; i<fields.length; i++){
+                r.push(row[fields[i]]);
+            }
+            data.push(r);
+        });
+        return data;
+    }
+
+    function print(target, param){
+        var title = null;
+        var rows = null;
+        var footer = null;
+        var caption = null;
+        if (typeof param == 'string'){
+            title = param;
+        } else {
+            title = param['title'];
+            rows = param['rows'];
+            footer = param['footer'];
+            caption = param['caption'];
+        }
+        var newWindow = window.open('', '', 'width=800, height=500');
+        var document = newWindow.document.open();
+        var content = 
+            '<!doctype html>' +
+            '<html>' +
+            '<head>' +
+            '<meta charset="utf-8">' +
+            '<title>'+title+'</title>' +
+            '</head>' +
+            '<body>' + toHtml(target, rows, footer, caption) + '</body>' +
+            '</html>';
+        document.write(content);
+        document.close();
+        newWindow.print();
+    }
+
+    function b64toBlob(data){
+        var sliceSize = 512;
+        var chars = atob(data);
+        var byteArrays = [];
+        for(var offset=0; offset<chars.length; offset+=sliceSize){
+            var slice = chars.slice(offset, offset+sliceSize);
+            var byteNumbers = new Array(slice.length);
+            for(var i=0; i<slice.length; i++){
+                byteNumbers[i] = slice.charCodeAt(i);
+            }
+            var byteArray = new Uint8Array(byteNumbers);
+            byteArrays.push(byteArray);
+        }
+        return new Blob(byteArrays, {
+            type: ''
+        });
+    }
+
+    function toExcel(target, param){
+        var filename = null;
+        var rows = null;
+        var footer = null;
+        var caption = null;
+        var worksheet = 'Worksheet';
+        if (typeof param == 'string'){
+            filename = param;
+        } else {
+            filename = param['filename'];
+            rows = param['rows'];
+            footer = param['footer'];
+            caption = param['caption'];
+            worksheet = param['worksheet'] || 'Worksheet';
+        }
+        var dg = $(target);
+        var uri = 'data:application/vnd.ms-excel;base64,'
+        , template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body>{table}</body></html>'
+        , base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) }
+        , format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }
+
+        var table = toHtml(target, rows, footer, caption);
+        var ctx = { worksheet: worksheet, table: table };
+        var data = base64(format(template, ctx));
+        if (window.navigator.msSaveBlob){
+            var blob = b64toBlob(data);
+            window.navigator.msSaveBlob(blob, filename);
+        } else {
+            var alink = $('<a style="display:none"></a>').appendTo('body');
+            alink[0].href = uri + data;
+            alink[0].download = filename;
+            alink[0].click();
+            alink.remove();
+        }
+    }
+
+    function toCsv(target, param){
+        var filename = null;
+        var rows = null;
+        var footer = null;
+        if (typeof param == 'string'){
+            filename = param;
+        } else {
+            filename = param['filename'];
+            rows = param['rows'];
+            footer = param['footer'];
+        }
+        var arrayData = toArray(target, rows, footer);
+        var csv = $.map(arrayData, function(row){
+            return row.join(',');
+        }).join("\r\n");
+        var data = window.btoa(unescape(encodeURIComponent(csv)));
+        if (window.navigator.msSaveBlob){
+            var blob = b64toBlob(data);
+            window.navigator.msSaveBlob(blob, filename);
+        } else {
+            var uri = 'data:text/csv;charset=utf-8;base64,';
+            var alink = $('<a style="display:none"></a>').appendTo('body');
+            alink[0].href = uri + data;
+            alink[0].download = filename;
+            alink[0].click();
+            alink.remove();
+        }
+    }
+
+    $.extend($.fn.datagrid.methods, {
+        toHtml: function(jq, rows){
+            return toHtml(jq[0], rows);
+        },
+        toArray: function(jq, rows){
+            return toArray(jq[0], rows);
+        },
+        toExcel: function(jq, param){
+            return jq.each(function(){
+                toExcel(this, param);
+            });
+        },
+        toCsv: function(jq, param){
+            return jq.each(function(){
+                toCsv(this, param);
+            });
+        },
+        print: function(jq, param){
+            return jq.each(function(){
+                print(this, param);
+            });
+        }
+    });
+})(jQuery);

+ 1139 - 0
wwwroot/Plugins/easyui/datagrid-filter.js

@@ -0,0 +1,1139 @@
+/**
+ * DataGrid Filter for jQuery EasyUI
+ * version: 1.0.2
+ */
+
+(function($){
+	function getPluginName(target){
+		if ($(target).data('treegrid')){
+			return 'treegrid';
+		} else {
+			return 'datagrid';
+		}
+	}
+
+	var autoSizeColumn1 = $.fn.datagrid.methods.autoSizeColumn;
+	var loadDataMethod1 = $.fn.datagrid.methods.loadData;
+	var appendMethod1 = $.fn.datagrid.methods.appendRow;
+	var deleteMethod1 = $.fn.datagrid.methods.deleteRow;
+	$.extend($.fn.datagrid.methods, {
+		autoSizeColumn: function(jq, field){
+			return jq.each(function(){
+				var fc = $(this).datagrid('getPanel').find('.datagrid-header .datagrid-filter-c');
+				// fc.hide();
+				fc.css({
+					width:'1px',
+					height:0
+				});
+				autoSizeColumn1.call($.fn.datagrid.methods, $(this), field);
+				// fc.show();
+				fc.css({
+					width:'',
+					height:''
+				});
+				resizeFilter(this, field);
+			});
+		},
+		loadData: function(jq, data){
+			jq.each(function(){
+				$.data(this, 'datagrid').filterSource = null;
+			});
+			return loadDataMethod1.call($.fn.datagrid.methods, jq, data);
+		},
+		appendRow: function(jq, row){
+			var result = appendMethod1.call($.fn.datagrid.methods, jq, row);
+			jq.each(function(){
+				var state = $(this).data('datagrid');
+				if (state.filterSource){
+					state.filterSource.total++;
+					if (state.filterSource.rows != state.data.rows){
+						state.filterSource.rows.push(row);
+					}
+				}
+			});
+			return result;
+		},
+		deleteRow: function(jq, index){
+			jq.each(function(){
+				var state = $(this).data('datagrid');
+				var opts = state.options;
+				if (state.filterSource && opts.idField){
+					if (state.filterSource.rows == state.data.rows){
+						state.filterSource.total--;
+					} else {
+						for(var i=0; i<state.filterSource.rows.length; i++){
+							var row = state.filterSource.rows[i];
+							if (row[opts.idField] == state.data.rows[index][opts.idField]){
+								state.filterSource.rows.splice(i,1);
+								state.filterSource.total--;
+								break;
+							}
+						}
+					}
+				}
+			});
+			return deleteMethod1.call($.fn.datagrid.methods, jq, index);		
+		}
+	});
+
+	var loadDataMethod2 = $.fn.treegrid.methods.loadData;
+	var appendMethod2 = $.fn.treegrid.methods.append;
+	var insertMethod2 = $.fn.treegrid.methods.insert;
+	var removeMethod2 = $.fn.treegrid.methods.remove;
+	$.extend($.fn.treegrid.methods, {
+		loadData: function(jq, data){
+			jq.each(function(){
+				$.data(this, 'treegrid').filterSource = null;
+			});
+			return loadDataMethod2.call($.fn.treegrid.methods, jq, data);
+		},
+		append: function(jq, param){
+			return jq.each(function(){
+				var state = $(this).data('treegrid');
+				var opts = state.options;
+				if (opts.oldLoadFilter){
+					var rows = translateTreeData(this, param.data, param.parent);
+					state.filterSource.total += rows.length;
+					state.filterSource.rows = state.filterSource.rows.concat(rows);
+					$(this).treegrid('loadData', state.filterSource)
+				} else {
+					appendMethod2($(this), param);
+				}
+			});
+		},
+		insert: function(jq, param){
+			return jq.each(function(){
+				var state = $(this).data('treegrid');
+				var opts = state.options;
+				if (opts.oldLoadFilter){
+					var ref = param.before || param.after;
+					var index = getNodeIndex(param.before || param.after);
+					var pid = index>=0 ? state.filterSource.rows[index]._parentId : null;
+					var rows = translateTreeData(this, [param.data], pid);
+					var newRows = state.filterSource.rows.splice(0, index>=0 ? (param.before ? index : index+1) : (state.filterSource.rows.length));
+					newRows = newRows.concat(rows);
+					newRows = newRows.concat(state.filterSource.rows);
+					state.filterSource.total += rows.length;
+					state.filterSource.rows = newRows;
+					$(this).treegrid('loadData', state.filterSource);
+
+					function getNodeIndex(id){
+						var rows = state.filterSource.rows;
+						for(var i=0; i<rows.length; i++){
+							if (rows[i][opts.idField] == id){
+								return i;
+							}
+						}
+						return -1;
+					}
+				} else {
+					insertMethod2($(this), param);
+				}
+			});
+		},
+		remove: function(jq, id){
+			jq.each(function(){
+				var state = $(this).data('treegrid');
+				if (state.filterSource){
+					var opts = state.options;
+					var rows = state.filterSource.rows;
+					for(var i=0; i<rows.length; i++){
+						if (rows[i][opts.idField] == id){
+							rows.splice(i, 1);
+							state.filterSource.total--;
+							break;
+						}
+					}
+				}
+			});
+			return removeMethod2(jq, id);
+		}
+	});
+
+	var extendedOptions = {
+		filterMenuIconCls: 'icon-ok',
+		filterBtnIconCls: 'icon-filter',
+		filterBtnPosition: 'right',
+		filterPosition: 'bottom',
+		remoteFilter: false,
+		clientPaging: true,
+		showFilterBar: true,
+		filterDelay: 400,
+		filterRules: [],
+		// specify whether the filtered records need to match ALL or ANY of the applied filters
+		filterMatchingType: 'all',	// possible values: 'all','any'
+		filterIncludingChild: false,
+		// filterCache: {},
+		filterMatcher: function(data){
+			var name = getPluginName(this);
+			var dg = $(this);
+			var state = $.data(this, name);
+			var opts = state.options;
+			if (opts.filterRules.length){
+				var rows = [];
+				if (name == 'treegrid'){
+					var rr = {};
+					$.map(data.rows, function(row){
+						if (isMatch(row, row[opts.idField])){
+							rr[row[opts.idField]] = row;
+							var prow = getRow(data.rows, row._parentId);
+							while(prow){
+								rr[prow[opts.idField]] = prow;
+								prow = getRow(data.rows, prow._parentId);
+							}
+							if (opts.filterIncludingChild){
+								var cc = getAllChildRows(data.rows, row[opts.idField]);
+								$.map(cc, function(row){
+									rr[row[opts.idField]] = row;
+								});
+							}
+						}
+					});
+					for(var id in rr){
+						rows.push(rr[id]);
+					}
+				} else {
+					for(var i=0; i<data.rows.length; i++){
+						var row = data.rows[i];
+						if (isMatch(row, i)){
+							rows.push(row);
+						}
+					}
+				}
+				data = {
+					total: data.total - (data.rows.length - rows.length),
+					rows: rows
+				};
+			}
+			return data;
+			
+			function isMatch(row, index){
+				if (opts.val == $.fn.combogrid.defaults.val){
+					opts.val = extendedOptions.val;
+				}
+				var rules = opts.filterRules;
+				if (!rules.length){return true;}
+				for(var i=0; i<rules.length; i++){
+					var rule = rules[i];
+
+					// var source = row[rule.field];
+					// var col = dg.datagrid('getColumnOption', rule.field);
+					// if (col && col.formatter){
+					// 	source = col.formatter(row[rule.field], row, index);
+					// }
+					
+					var col = dg.datagrid('getColumnOption', rule.field);
+					var formattedValue = (col && col.formatter) ? col.formatter(row[rule.field], row, index) : undefined;
+					var source = opts.val.call(dg[0], row, rule.field, formattedValue);
+
+					if (source == undefined){
+						source = '';
+					}
+					var op = opts.operators[rule.op];
+					var matched = op.isMatch(source, rule.value);
+					if (opts.filterMatchingType == 'any'){
+						if (matched){return true;}
+					} else {
+						if (!matched){return false;}
+					}
+				}
+				return opts.filterMatchingType == 'all';
+			}
+			function getRow(rows, id){
+				for(var i=0; i<rows.length; i++){
+					var row = rows[i];
+					if (row[opts.idField] == id){
+						return row;
+					}
+				}
+				return null;
+			}
+			function getAllChildRows(rows, id){
+				var cc = getChildRows(rows, id);
+				var stack = $.extend(true, [], cc);
+				while(stack.length){
+					var row = stack.shift();
+					var c2 = getChildRows(rows, row[opts.idField]);
+					cc = cc.concat(c2);
+					stack = stack.concat(c2);
+				}
+				return cc;
+			}
+			function getChildRows(rows, id){
+				var cc = [];
+				for(var i=0; i<rows.length; i++){
+					var row = rows[i];
+					if (row._parentId == id){
+						cc.push(row);
+					}
+				}
+				return cc;
+			}
+		},
+		defaultFilterType: 'text',
+		defaultFilterOperator: 'contains',
+		defaultFilterOptions: {
+			onInit: function(target){
+				var name = getPluginName(target);
+				var opts = $(target)[name]('options');
+				var filterOpts = this.filterOptions;
+				var field = $(this).attr('name');
+				var input = $(this);
+				if (input.data('textbox')){
+					input = input.textbox('textbox');
+				}
+				input.off('.filter').on('keydown.filter', function(e){
+					var t = $(this);
+					if (this.timer){
+						clearTimeout(this.timer);
+					}
+					if (e.keyCode == 13){
+						_doFilter();
+					} else if (opts.filterDelay){
+						this.timer = setTimeout(function(){
+							_doFilter();
+						}, opts.filterDelay);
+					}
+				});
+				function _doFilter(){
+					var rule = $(target)[name]('getFilterRule', field);
+					var value = input.val();
+					if (filterOpts.options.prompt && filterOpts.options.prompt==value){
+						value = '';
+					}
+					if (value != ''){
+						if ((rule && rule.value!=value) || !rule){
+							var op = rule ? rule.op : (filterOpts ? filterOpts.defaultFilterOperator||opts.defaultFilterOperator : opts.defaultFilterOperator);
+							$(target)[name]('addFilterRule', {
+								field: field,
+								// op: opts.defaultFilterOperator,
+								op: op,
+								value: value
+							});
+							$(target)[name]('doFilter');
+						}
+					} else {
+						if (rule){
+							$(target)[name]('removeFilterRule', field);
+							$(target)[name]('doFilter');
+						}
+					}
+				}
+			}
+		},
+		filterStringify: function(data){
+			return JSON.stringify(data);
+		},
+		// the function to retrieve the field value of a row to match the filter rule
+		val: function(row, field, formattedValue){
+			return formattedValue || row[field];
+		},
+		onClickMenu: function(item,button){}
+	};
+	$.extend($.fn.datagrid.defaults, extendedOptions);
+	$.extend($.fn.treegrid.defaults, extendedOptions);
+	
+	// filter types
+	$.fn.datagrid.defaults.filters = $.extend({}, $.fn.datagrid.defaults.editors, {
+		label: {
+			init: function(container, options){
+				return $('<span></span>').appendTo(container);
+			},
+			getValue: function(target){
+				return $(target).html();
+			},
+			setValue: function(target, value){
+				$(target).html(value);
+			},
+			resize: function(target, width){
+				$(target)._outerWidth(width)._outerHeight(22);
+			}
+		}
+	});
+	$.fn.treegrid.defaults.filters = $.fn.datagrid.defaults.filters;
+	
+	// filter operators
+	$.fn.datagrid.defaults.operators = {
+		nofilter: {
+			text: 'No Filter'
+		},
+		contains: {
+			text: 'Contains',
+			isMatch: function(source, value){
+				source = String(source);
+				value = String(value);
+				return source.toLowerCase().indexOf(value.toLowerCase()) >= 0;
+			}
+		},
+		equal: {
+			text: 'Equal',
+			isMatch: function(source, value){
+				return source == value;
+			}
+		},
+		notequal: {
+			text: 'Not Equal',
+			isMatch: function(source, value){
+				return source != value;
+			}
+		},
+		beginwith: {
+			text: 'Begin With',
+			isMatch: function(source, value){
+				source = String(source);
+				value = String(value);
+				return source.toLowerCase().indexOf(value.toLowerCase()) == 0;
+			}
+		},
+		endwith: {
+			text: 'End With',
+			isMatch: function(source, value){
+				source = String(source);
+				value = String(value);
+				return source.toLowerCase().indexOf(value.toLowerCase(), source.length - value.length) !== -1;
+			}
+		},
+		less: {
+			text: 'Less',
+			isMatch: function(source, value){
+				return source < value;
+			}
+		},
+		lessorequal: {
+			text: 'Less Or Equal',
+			isMatch: function(source, value){
+				return source <= value;
+			}
+		},
+		greater: {
+			text: 'Greater',
+			isMatch: function(source, value){
+				return source > value;
+			}
+		},
+		greaterorequal: {
+			text: 'Greater Or Equal',
+			isMatch: function(source, value){
+				return source >= value;
+			}
+		}
+	};
+	$.fn.treegrid.defaults.operators = $.fn.datagrid.defaults.operators;
+	
+	function resizeFilter(target, field){
+		var toFixColumnSize = false;
+		var dg = $(target);
+		var header = dg.datagrid('getPanel').find('div.datagrid-header');
+		var tr = header.find('.datagrid-header-row:not(.datagrid-filter-row)');
+		var ff = field ? header.find('.datagrid-filter[name="'+field+'"]') : header.find('.datagrid-filter');
+		ff.each(function(){
+			var name = $(this).attr('name');
+			var col = dg.datagrid('getColumnOption', name);
+			var cc = $(this).closest('div.datagrid-filter-c');
+			var btn = cc.find('a.datagrid-filter-btn');
+			var cell = tr.find('td[field="'+name+'"] .datagrid-cell');
+			var cellWidth = cell._outerWidth();
+			if (cellWidth != _getContentWidth(cc)){
+				this.filter.resize(this, cellWidth - btn._outerWidth());
+			}
+			if (cc.width() > col.boxWidth+col.deltaWidth-1){
+				col.boxWidth = cc.width() - col.deltaWidth + 1;
+				col.width = col.boxWidth + col.deltaWidth;
+				toFixColumnSize = true;
+			}
+		});
+		if (toFixColumnSize){
+			$(target).datagrid('fixColumnSize');			
+		}
+
+		function _getContentWidth(cc){
+			var w = 0;
+			$(cc).children(':visible').each(function(){
+				w += $(this)._outerWidth();
+			});
+			return w;
+		}
+	}
+	
+	function getFilterComponent(target, field){
+		var header = $(target).datagrid('getPanel').find('div.datagrid-header');
+		return header.find('tr.datagrid-filter-row td[field="'+field+'"] .datagrid-filter');
+	}
+	
+	/**
+	 * get filter rule index, return -1 if not found.
+	 */
+	function getRuleIndex(target, field){
+		var name = getPluginName(target);
+		var rules = $(target)[name]('options').filterRules;
+		for(var i=0; i<rules.length; i++){
+			if (rules[i].field == field){
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	function getFilterRule(target, field){
+		var name = getPluginName(target);
+		var rules = $(target)[name]('options').filterRules;
+		var index = getRuleIndex(target, field);
+		if (index >= 0){
+			return rules[index];
+		} else {
+			return null;
+		}
+	}
+	
+	function addFilterRule(target, param){
+		var name = getPluginName(target);
+		var opts = $(target)[name]('options');
+		var rules = opts.filterRules;
+
+		if (param.op == 'nofilter'){
+			removeFilterRule(target, param.field);
+		} else {
+			var index = getRuleIndex(target, param.field);
+			if (index >= 0){
+				$.extend(rules[index], param);
+			} else {
+				rules.push(param);
+			}
+		}
+
+		var input = getFilterComponent(target, param.field);
+		if (input.length){
+			if (param.op != 'nofilter'){
+				var value = input.val();
+				if (input.data('textbox')){
+					value = input.textbox('getText');
+				}
+				if (value != param.value){
+					input[0].filter.setValue(input, param.value);					
+				}
+			}
+			var menu = input[0].menu;
+			if (menu){
+				menu.find('.'+opts.filterMenuIconCls).removeClass(opts.filterMenuIconCls);
+				var item = menu.menu('findItem', opts.operators[param.op]['text']);
+				menu.menu('setIcon', {
+					target: item.target,
+					iconCls: opts.filterMenuIconCls
+				});
+			}
+		}
+	}
+	
+	function removeFilterRule(target, field){
+		var name = getPluginName(target);
+		var dg = $(target);
+		var opts = dg[name]('options');
+		if (field){
+			var index = getRuleIndex(target, field);
+			if (index >= 0){
+				opts.filterRules.splice(index, 1);
+			}
+			_clear([field]);
+		} else {
+			opts.filterRules = [];
+			var fields = dg.datagrid('getColumnFields',true).concat(dg.datagrid('getColumnFields'));
+			_clear(fields);
+		}
+		
+		function _clear(fields){
+			for(var i=0; i<fields.length; i++){
+				var input = getFilterComponent(target, fields[i]);
+				if (input.length){
+					input[0].filter.setValue(input, '');
+					var menu = input[0].menu;
+					if (menu){
+						menu.find('.'+opts.filterMenuIconCls).removeClass(opts.filterMenuIconCls);
+					}
+				}
+			}
+		}
+	}
+	
+	function doFilter(target){
+		var name = getPluginName(target);
+		var state = $.data(target, name);
+		var opts = state.options;
+		if (opts.remoteFilter){
+			$(target)[name]('load');
+		} else {
+			if (opts.view.type == 'scrollview' && state.data.firstRows && state.data.firstRows.length){
+				state.data.rows = state.data.firstRows;
+			}
+			$(target)[name]('getPager').pagination('refresh', {pageNumber:1});
+			$(target)[name]('options').pageNumber = 1;
+			$(target)[name]('loadData', state.filterSource || state.data);
+		}
+	}
+	
+	function translateTreeData(target, children, pid){
+		var opts = $(target).treegrid('options');
+		if (!children || !children.length){return []}
+		var rows = [];
+		$.map(children, function(item){
+			item._parentId = pid;
+			rows.push(item);
+			rows = rows.concat(translateTreeData(target, item.children, item[opts.idField]));
+		});
+		$.map(rows, function(row){
+			row.children = undefined;
+		});
+		return rows;
+	}
+
+	function myLoadFilter(data, parentId){
+		var target = this;
+		var name = getPluginName(target);
+		var state = $.data(target, name);
+		var opts = state.options;
+
+		if (name == 'datagrid' && $.isArray(data)){
+			data = {
+				total: data.length,
+				rows: data
+			};
+		} else if (name == 'treegrid' && $.isArray(data)){
+			var rows = translateTreeData(target, data, parentId);
+			data = {
+				total: rows.length,
+				rows: rows
+			}
+		}
+		if (!opts.remoteFilter || opts.clientPaging){
+			if (!state.filterSource){
+				state.filterSource = data;
+			} else {
+				if (!opts.isSorting) {
+					if (name == 'datagrid'){
+						state.filterSource = data;
+					} else {
+						state.filterSource.total += data.length;
+						state.filterSource.rows = state.filterSource.rows.concat(data.rows);
+						if (parentId){
+							return opts.filterMatcher.call(target, data);
+						}
+					}
+				} else {
+					opts.isSorting = undefined;
+				}
+			}
+			if (!opts.remoteSort && opts.sortName){
+				var names = opts.sortName.split(',');
+				var orders = opts.sortOrder.split(',');
+				var dg = $(target);
+				state.filterSource.rows.sort(function(r1,r2){
+					var r = 0;
+					for(var i=0; i<names.length; i++){
+						var sn = names[i];
+						var so = orders[i];
+						var col = dg.datagrid('getColumnOption', sn);
+						var sortFunc = col.sorter || function(a,b){
+							return a==b ? 0 : (a>b?1:-1);
+						};
+						r = sortFunc(r1[sn], r2[sn]) * (so=='asc'?1:-1);
+						if (r != 0){
+							return r;
+						}
+					}
+					return r;
+				});
+			}
+			data = opts.filterMatcher.call(target, {
+				total: state.filterSource.total,
+				rows: state.filterSource.rows,
+				footer: state.filterSource.footer||[]
+			});
+			data.filterRows = data.rows;
+		}
+		if (opts.pagination && opts.clientPaging){
+			var dg = $(target);
+			var pager = dg[name]('getPager');
+			pager.pagination({
+				onSelectPage:function(pageNum, pageSize){
+					opts.pageNumber = pageNum;
+					opts.pageSize = pageSize;
+					pager.pagination('refresh',{
+						pageNumber:pageNum,
+						pageSize:pageSize
+					});
+					// dg[name]('loadData', state.filterSource);
+					if (opts.clientPaging){
+						dg[name]('loadData', state.filterSource);
+					} else {
+						dg[name]('reload');
+					}
+				},
+				onBeforeRefresh:function(){
+					dg[name]('reload');
+					return false;
+				}
+			});
+			if (name == 'datagrid'){
+				var pd = getPageData(data.rows);
+				opts.pageNumber = pd.pageNumber;
+				data.rows = pd.rows;
+			} else {
+				var topRows = [];
+				var childRows = [];
+				$.map(data.rows, function(row){
+					row._parentId ? childRows.push(row) : topRows.push(row);
+				});
+				data.total = topRows.length;
+				var pd = getPageData(topRows);
+				opts.pageNumber = pd.pageNumber;
+				data.rows = pd.rows.concat(childRows);
+			}
+		}
+		$.map(data.rows, function(row){
+			row.children = undefined;
+		});
+		return data;
+
+		function getPageData(dataRows){
+			var rows = [];
+			var page = opts.pageNumber;
+			while(page > 0){
+				var start = (page-1)*parseInt(opts.pageSize);
+				var end = start + parseInt(opts.pageSize);
+				rows = dataRows.slice(start, end);
+				if (rows.length){
+					break;
+				}
+				page--;
+			}
+			return {
+				pageNumber: page>0?page:1,
+				rows: rows
+			};
+		}
+	}
+	
+	function init(target, filters){
+		filters = filters || [];
+		var name = getPluginName(target);
+		var state = $.data(target, name);
+		var opts = state.options;
+		if (!opts.filterRules.length){
+			opts.filterRules = [];
+		}
+		opts.filterCache = opts.filterCache || {};
+		var dgOpts = $.data(target, 'datagrid').options;
+		
+		var onResize = dgOpts.onResize;
+		dgOpts.onResize = function(width,height){
+			resizeFilter(target);
+			onResize.call(this, width, height);
+		}
+		var onBeforeSortColumn = dgOpts.onBeforeSortColumn;
+		dgOpts.onBeforeSortColumn = function(sort, order){
+			var result = onBeforeSortColumn.call(this, sort, order);
+			if (result != false){
+				opts.isSorting = true;				
+			}
+			return result;
+		};
+
+		var onResizeColumn = opts.onResizeColumn;
+		opts.onResizeColumn = function(field,width){
+			var fc = $(this).datagrid('getPanel').find('.datagrid-header .datagrid-filter-c');
+			var focusOne = fc.find('.datagrid-filter:focus');
+			// fc.hide();
+			fc.css({
+				width:'1px',
+				height:0
+			});
+			$(target).datagrid('fitColumns');
+			if (opts.fitColumns){
+				resizeFilter(target);
+			} else {
+				resizeFilter(target, field);
+			}
+			// fc.show();
+			fc.css({
+				width:'',
+				height:''
+			});
+			focusOne.blur().focus();
+			onResizeColumn.call(target, field, width);
+		};
+		var onBeforeLoad = opts.onBeforeLoad;
+		opts.onBeforeLoad = function(param1, param2){
+			if (param1){
+				param1.filterRules = opts.filterStringify(opts.filterRules);
+			}
+			if (param2){
+				param2.filterRules = opts.filterStringify(opts.filterRules);
+			}
+			var result = onBeforeLoad.call(this, param1, param2);
+			if (result != false && opts.url){
+				if (name == 'datagrid'){
+					state.filterSource = null;
+				} else if (name == 'treegrid' && state.filterSource){
+					if (param1){
+						var id = param1[opts.idField];	// the id of the expanding row
+						var rows = state.filterSource.rows || [];
+						for(var i=0; i<rows.length; i++){
+							if (id == rows[i]._parentId){	// the expanding row has children
+								return false;
+							}
+						}
+					} else {
+						state.filterSource = null;
+					}
+				}
+			}
+			return result;
+		};
+		if ((opts.view.type == 'detailview' || opts.view.type == 'scrollview') && opts.frozenColumns && opts.frozenColumns.length) {
+			var onBeforeRender = opts.view.onBeforeRender;
+			opts.view.onBeforeRender = function(target){
+				onBeforeRender.call(opts.view, target)
+				if (!opts.detailviewFilterInited){
+					opts.detailviewFilterInited = true;
+					var fields = $(target).datagrid('getColumnFields', true);
+					if (opts.rownumbers){
+						fields.unshift('_');
+					}
+					var tr = $(target).data('datagrid').dc.header1.find('.datagrid-filter-row');
+					if (tr.length < fields.length){
+						var index = $.inArray('_expander', fields);
+						if (index >= 0){
+							var td = tr.children().eq(index);
+							if (td.length){
+								$('<td class="_expander"></td>').insertBefore(td);
+							} else {
+								$('<td class="_expander"></td>').appendTo(tr);
+							}
+						}
+					}
+					
+				}
+			}
+		}
+
+		// opts.loadFilter = myLoadFilter;
+		opts.loadFilter = function(data, parentId){
+			var d = opts.oldLoadFilter.call(this, data, parentId);
+			return myLoadFilter.call(this, d, parentId);
+		};
+		state.dc.view2.children('.datagrid-header').off('.filter').on('focusin.filter', function(e){
+			var header = $(this);
+			setTimeout(function(){
+				state.dc.body2._scrollLeft(header._scrollLeft());
+			},0);
+		});
+		
+		initCss();
+		createFilter(true);
+		createFilter();
+		if (opts.fitColumns){
+			setTimeout(function(){
+				resizeFilter(target);
+			}, 0);
+		}
+
+		$.map(opts.filterRules, function(rule){
+			addFilterRule(target, rule);
+		});
+		
+		function initCss(){
+			if (!$('#datagrid-filter-style').length){
+				$('head').append(
+					'<style id="datagrid-filter-style">' +
+					'a.datagrid-filter-btn{display:inline-block;width:22px;height:100%;margin:0;vertical-align:middle;cursor:pointer;opacity:0.6;filter:alpha(opacity=60);}' +
+					'a:hover.datagrid-filter-btn{opacity:1;filter:alpha(opacity=100);}' +
+					'.datagrid-filter-row .textbox,.datagrid-filter-row .textbox .textbox-text{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;}' +
+					'.datagrid-filter-row input{margin:0;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;}' +
+					'.datagrid-filter-c{overflow:hidden}' +
+					'.datagrid-filter-cache{position:absolute;width:10px;height:10px;left:-99999px;}' +
+					'</style>'
+				);
+			}
+		}
+		
+		/**
+		 * create filter component
+		 */
+		function createFilter(frozen){
+			var dc = state.dc;
+			var fields = $(target).datagrid('getColumnFields', frozen);
+			if (frozen && opts.rownumbers){
+				fields.unshift('_');
+			}
+			var table = (frozen?dc.header1:dc.header2).find('table.datagrid-htable');
+			
+			// clear the old filter component
+			table.find('.datagrid-filter').each(function(){
+				if (this.filter.destroy){
+					this.filter.destroy(this);
+				}
+				if (this.menu){
+					$(this.menu).menu('destroy');
+				}
+			});
+			table.find('tr.datagrid-filter-row').remove();
+			
+			var tr = $('<tr class="datagrid-header-row datagrid-filter-row"></tr>');
+			if (opts.filterPosition == 'bottom'){
+				tr.appendTo(table.find('tbody'));
+			} else {
+				tr.prependTo(table.find('tbody'));
+			}
+			if (!opts.showFilterBar){
+				tr.hide();
+			}
+			
+			for(var i=0; i<fields.length; i++){
+				var field = fields[i];
+				var col = $(target).datagrid('getColumnOption', field);
+				var td = $('<td></td>').attr('field', field).appendTo(tr);
+				if (col && col.hidden){
+					td.hide();
+				}
+				if (field == '_'){
+					continue;
+				}
+				if (col && (col.checkbox || col.expander)){
+					continue;
+				}
+
+				var fopts = getFilter(field);
+				if (fopts){
+					$(target)[name]('destroyFilter', field);	// destroy the old filter component
+				} else {
+					fopts = $.extend({}, {
+						field: field,
+						type: opts.defaultFilterType,
+						options: opts.defaultFilterOptions
+					});
+				}
+
+				var div = opts.filterCache[field];
+				if (!div){
+					div = $('<div class="datagrid-filter-c"></div>').appendTo(td);
+					var filter = opts.filters[fopts.type];
+					var input = filter.init(div, $.extend({height:opts.editorHeight},fopts.options||{}));
+					input.addClass('datagrid-filter').attr('name', field);
+					input[0].filter = filter;
+					input[0].filterOptions = fopts;
+					input[0].menu = createFilterButton(div, fopts.op);
+					if (fopts.op && fopts.op.length){
+						if (fopts.options && fopts.options.onInit){
+							fopts.options.onInit.call(input[0], target);
+						} else if (fopts.defaultFilterOperator){
+							opts.defaultFilterOptions.onInit.call(input[0], target);
+						}
+					} else {
+						opts.defaultFilterOptions.onInit.call(input[0], target);
+					}
+					// if (fopts.options){
+					// 	if (fopts.options.onInit){
+					// 		fopts.options.onInit.call(input[0], target);
+					// 	}
+					// } else {
+					// 	opts.defaultFilterOptions.onInit.call(input[0], target);
+					// }
+					opts.filterCache[field] = div;
+					resizeFilter(target, field);
+				} else {
+					div.appendTo(td);
+				}
+			}
+		}
+		
+		function createFilterButton(container, operators){
+			if (!operators){return null;}
+			
+			var btn = $('<a class="datagrid-filter-btn">&nbsp;</a>').addClass(opts.filterBtnIconCls);
+			btn.css('height',opts.editorHeight);
+			if (opts.filterBtnPosition == 'right'){
+				btn.appendTo(container);
+			} else {
+				btn.prependTo(container);
+			}
+
+			var menu = $('<div></div>').appendTo('body');
+			$.map(['nofilter'].concat(operators), function(item){
+				var op = opts.operators[item];
+				if (op){
+					$('<div></div>').attr('name', item).html(op.text).appendTo(menu);
+				}
+			});
+			menu.menu({
+				alignTo:btn,
+				onClick:function(item){
+					var btn = $(this).menu('options').alignTo;
+					var td = btn.closest('td[field]');
+					var field = td.attr('field');
+					var input = td.find('.datagrid-filter');
+					var value = input[0].filter.getValue(input);
+					
+					if (opts.onClickMenu.call(target, item, btn, field) == false){
+						return;
+					}
+					
+					addFilterRule(target, {
+						field: field,
+						op: item.name,
+						value: value
+					});
+					
+					doFilter(target);
+				}
+			});
+
+			btn[0].menu = menu;
+			btn.on('click', {menu:menu}, function(e){
+				$(this.menu).menu('show');
+				return false;
+			});
+			return menu;
+		}
+		
+		function getFilter(field){
+			for(var i=0; i<filters.length; i++){
+				var filter = filters[i];
+				if (filter.field == field){
+					return filter;
+				}
+			}
+			return null;
+		}
+	}
+	
+	$.extend($.fn.datagrid.methods, {
+		isFilterEnabled: function(jq){
+			var name = getPluginName(jq[0]);
+			var opts = $.data(jq[0], name).options;
+			if (opts.oldLoadFilter){
+				return true;
+			} else {
+				return false;
+			}
+		},
+		enableFilter: function(jq, filters){
+			return jq.each(function(){
+				var name = getPluginName(this);
+				var opts = $.data(this, name).options;
+				if (opts.oldLoadFilter){
+					if (filters){
+						$(this)[name]('disableFilter');
+					} else {
+						return;
+					}
+				}
+				opts.oldLoadFilter = opts.loadFilter;
+				init(this, filters);
+				$(this)[name]('resize');
+				if (opts.filterRules.length){
+					if (opts.remoteFilter){
+						doFilter(this);
+					} else if (opts.data){
+						doFilter(this);
+					}
+				}
+			});
+		},
+		disableFilter: function(jq){
+			return jq.each(function(){
+				var name = getPluginName(this);
+				var state = $.data(this, name);
+				var opts = state.options;
+				if (!opts.oldLoadFilter){
+					return;
+				}
+				var dc = $(this).data('datagrid').dc;
+				var div = dc.view.children('.datagrid-filter-cache');
+				if (!div.length){
+					div = $('<div class="datagrid-filter-cache"></div>').appendTo(dc.view);
+				}
+				for(var field in opts.filterCache){
+					$(opts.filterCache[field]).appendTo(div);
+				}
+				var data = state.data;
+				if (state.filterSource){
+					data = state.filterSource;
+					$.map(data.rows, function(row){
+						row.children = undefined;
+					});
+				}
+				dc.header1.add(dc.header2).find('tr.datagrid-filter-row').remove();
+				opts.loadFilter = opts.oldLoadFilter || undefined;
+				opts.oldLoadFilter = null;
+				$(this)[name]('resize');
+				$(this)[name]('loadData', data);
+
+				// $(this)[name]({
+				// 	data: data,
+				// 	loadFilter: (opts.oldLoadFilter||undefined),
+				// 	oldLoadFilter: null
+				// });
+			});
+		},
+		destroyFilter: function(jq, field){
+			return jq.each(function(){
+				var name = getPluginName(this);
+				var state = $.data(this, name);
+				var opts = state.options;
+				if (field){
+					_destroy(field);
+				} else {
+					for(var f in opts.filterCache){
+						_destroy(f);
+					}
+					$(this).datagrid('getPanel').find('.datagrid-header .datagrid-filter-row').remove();
+					$(this).data('datagrid').dc.view.children('.datagrid-filter-cache').remove();
+					opts.filterCache = {};
+					$(this)[name]('resize');
+					$(this)[name]('disableFilter');
+				}
+
+				function _destroy(field){
+					var c = $(opts.filterCache[field]);
+					var input = c.find('.datagrid-filter');
+					if (input.length){
+						var filter = input[0].filter;
+						if (filter.destroy){
+							filter.destroy(input[0]);
+						}
+					}
+					c.find('.datagrid-filter-btn').each(function(){
+						$(this.menu).menu('destroy');
+					});
+					c.remove();
+					opts.filterCache[field] = undefined;
+				}
+			});
+		},
+		getFilterRule: function(jq, field){
+			return getFilterRule(jq[0], field);
+		},
+		addFilterRule: function(jq, param){
+			return jq.each(function(){
+				addFilterRule(this, param);
+			});
+		},
+		removeFilterRule: function(jq, field){
+			return jq.each(function(){
+				removeFilterRule(this, field);
+			});
+		},
+		doFilter: function(jq){
+			return jq.each(function(){
+				doFilter(this);
+			});
+		},
+		getFilterComponent: function(jq, field){
+			return getFilterComponent(jq[0], field);
+		},
+		resizeFilter: function(jq, field){
+			return jq.each(function(){
+				resizeFilter(this, field);
+			});
+		}
+	});
+})(jQuery);

+ 18 - 0
wwwroot/Plugins/easyui/demo-mobile/accordion/_content.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="UTF-8">
+	<title>AJAX Content</title>
+</head>
+<body>
+	<p style="font-size:14px">Here is the content loaded via AJAX.</p>
+	<ul>
+		<li>easyui is a collection of user-interface plugin based on jQuery.</li>
+		<li>easyui provides essential functionality for building modern, interactive, javascript applications.</li>
+		<li>using easyui you don't need to write many javascript code, you usually defines user-interface by writing some HTML markup.</li>
+		<li>complete framework for HTML5 web page.</li>
+		<li>easyui save your time and scales while developing your products.</li>
+		<li>easyui is very easy but powerful.</li>
+	</ul>
+</body>
+</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/accordion/basic.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Basic Accordion - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Basic Accordion</span>
			</div>
		</header>
		<div class="easyui-accordion" fit="true" border="false">
			<div title="List">
				<ul class="m-list">
					<li>WLAN</li>
					<li>Memory</li>
					<li>Screen</li>
					<li>More...</li>
				</ul>
			</div>
			<div title="Ajax" href="_content.html" style="padding:10px"></div>
		</div>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/accordion/header.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Custom Accordion Header - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Custom Accordion Header</span>
			</div>
		</header>
		<div class="easyui-accordion" data-options="fit:true,border:false,selected:-1">
			<div>
				<header>
					<div class="hh-inner">
						<span>List</span>
						<span class="m-badge" style="float:right">26/51</span>
					</div>
				</header>
				<ul class="m-list">
					<li>WLAN</li>
					<li>Memory</li>
					<li>Screen</li>
					<li>More...</li>
				</ul>
			</div>
			<div href="_content.html" style="padding:10px">
				<header>
					<div class="hh-inner">
						<span>Ajax</span>
						<span style="float:right">
							<span style="color:#999;margin-right:5px">Loading via ajax</span>
							<span class="m-badge">23</span>
						</span>
					</div>
				</header>
			</div>
		</div>
	</div>
	<style scoped>
		.hh-inner{
			position: relative;
			line-height: 20px;
			background: #fff;
			font-weight: bold;
			margin: -5px;
			padding: 5px;
		}
	</style>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/animation/basic.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Basic Animation - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Basic Animation</span>
			</div>
		</header>
		<ul class="m-list">
			<li><a href="#p2">Goto Panel2</a></li>
		</ul>
	</div>
	<div id="p2" class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<div class="m-left">
					<a href="#" class="easyui-linkbutton m-back" data-options="plain:true,outline:true,back:true">Back</a>
				</div>
				<div class="m-title">Panel2</div>
			</div>
		</header>
		<ul class="m-list">
			<li><a href="#p3">Goto Panel3</a></li>
		</ul>
	</div>
	<div id="p3" class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<div class="m-left">
					<a href="#" class="easyui-linkbutton m-back" data-options="plain:true,outline:true,back:true">Back</a>
				</div>
				<div class="m-title">Panel3</div>
			</div>
		</header>
		<div style="padding:20px 10px">
			<p>Panel3 Content.</p>
		</div>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/animation/fade.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Fade Animation - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Fade Animation</span>
			</div>
		</header>
		<ul class="m-list">
			<li><a href="#p2" data-options="animation:'fade',direction:''">Fade</a></li>
		</ul>
	</div>
	<div id="p2" class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<div class="m-left">
					<a href="#" class="easyui-linkbutton m-back" data-options="plain:true,outline:true,back:true">Back</a>
				</div>
				<div class="m-title">Panel2</div>
			</div>
		</header>
		<div style="padding:10px">
			<p>Panel2 Content.</p>
		</div>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/animation/pop.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Pop Animation - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Pop Animation</span>
			</div>
		</header>
		<ul class="m-list">
			<li><a href="#p2" data-options="animation:'pop',direction:''">Pop</a></li>
		</ul>
	</div>
	<div id="p2" class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<div class="m-left">
					<a href="#" class="easyui-linkbutton m-back" data-options="plain:true,outline:true,back:true">Back</a>
				</div>
				<div class="m-title">Panel2</div>
			</div>
		</header>
		<div style="padding:10px">
			<p>Panel2 Content.</p>
		</div>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/animation/slide.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Slide Animation - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Slide Animation</span>
			</div>
		</header>
		<ul class="m-list">
			<li><a href="#p2" data-options="animation:'slide',direction:'left'">Slide Left</a></li>
			<li><a href="#p2" data-options="animation:'slide',direction:'right'">Slide Right</a></li>
			<li><a href="#p2" data-options="animation:'slide',direction:'up'">Slide Up</a></li>
			<li><a href="#p2" data-options="animation:'slide',direction:'down'">Slide Down</a></li>
		</ul>
	</div>
	<div id="p2" class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<div class="m-left">
					<a href="#" class="easyui-linkbutton m-back" data-options="plain:true,outline:true,back:true">Back</a>
				</div>
				<div class="m-title">Panel2</div>
			</div>
		</header>
		<div style="padding:10px">
			<p>Panel2 Content.</p>
		</div>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/badge/basic.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Basic Badge - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Basic Badge</span>
			</div>
		</header>
		<div style="padding:20px 40px">
			<a href="#" class="easyui-linkbutton">
				Button<span class="m-badge">2</span>
			</a>
		</div>
		<div style="padding:20px 40px">
			<a href="#" class="easyui-linkbutton" iconCls="icon-ok">
				Button<span class="m-badge">3</span>
			</a>
		</div>
		<div style="padding:20px 40px">
			<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-large-picture',iconAlign:'top',size:'large'">
				LargeButton<span class="m-badge">4</span>
			</a>
			<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-large-shapes',iconAlign:'top',size:'large'" style="margin-left:20px">
				LargeButton<span class="m-badge">5</span>
			</a>
		</div>
		<div style="padding:20px 40px">
			<a href="#" class="easyui-linkbutton m-badge" data-badge="22" style="width:100px;height:40px">Badge Attr</a>
			<a href="#" class="easyui-linkbutton m-badge" data-badge="23" style="width:100px;height:40px;margin-left:20px">Badge Attr</a>
		</div>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/badge/button.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Button Badge - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Button Badge</span>
			</div>
		</header>
		<footer>
            <div class="m-buttongroup m-buttongroup-justified" style="width:100%">
                <a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-large-picture',size:'large',iconAlign:'top',plain:true">Picture</a>
                <a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-large-clipart',size:'large',iconAlign:'top',plain:true">Clip Art</a>
                <a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-large-shapes',size:'large',iconAlign:'top',plain:true">Shapes<span class="m-badge">23</span></a>
                <a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-large-smartart',size:'large',iconAlign:'top',plain:true">SmartArt</a>
            </div>
		</footer>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/badge/list.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>List Badge - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/color.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">List Badge</span>
			</div>
		</header>
		<ul class="m-list">
			<li>Large
				<div class="m-right"><span class="m-badge" style="margin-top:10px">234</span></div>
			</li>
			<li>Spotted Adult Female
				<div class="m-right"><span class="m-badge" style="margin-top:10px">215</span></div>
			</li>
			<li>Venomless
				<div class="m-right"><span class="m-badge c1" style="margin-top:10px">12</span></div>
			</li>
			<li>Rattleless
				<div class="m-right"><span class="m-badge c2" style="margin-top:10px">6</span></div>
			</li>
			<li>Green Adult</li>
			<li>Tailless</li>
			<li>With tail</li>
			<li>Adult Female</li>
		</ul>
	</div>
</body>	
</html>

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
wwwroot/Plugins/easyui/demo-mobile/badge/tabs.html


+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/button/basic.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Basic LinkButton - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script> 
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script> 
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Login to System</span>
			</div>
		</header>
		<div style="margin:20px auto;width:100px;height:100px;border-radius:100px;overflow:hidden">
			<img src="../images/login1.jpg" style="margin:0;width:100%;height:100%;">
		</div>
		<div style="padding:0 20px">
			<div style="margin-bottom:10px">
				<input class="easyui-textbox" data-options="prompt:'Type username',iconCls:'icon-man'" style="width:100%;height:38px">
			</div>
			<div>
				<input class="easyui-passwordbox" data-options="prompt:'Type password'" style="width:100%;height:38px">
			</div>
			<div style="text-align:center;margin-top:30px">
				<a href="#" class="easyui-linkbutton" style="width:100%;height:40px"><span style="font-size:16px">Login</span></a>
			</div>
			<div style="text-align:center;margin-top:30px">
				<a href="#" class="easyui-linkbutton" plain="true" outline="true" style="width:100px;height:35px"><span style="font-size:16px">Register</span></a> 
			</div>
		</div>
	</div>
</body>	
</html>

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
wwwroot/Plugins/easyui/demo-mobile/button/group.html


+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/button/style.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Button Style - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/color.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script>
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script>
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Button Style</span>
			</div>
		</header>
		<div style="padding:20px">
			<p>Style</p>
			<a href="#" class="easyui-linkbutton" style="width:80px">Normal</a>
			<a href="#" class="easyui-linkbutton" plain="true" outline="true" style="width:80px">Outline</a>
			<a href="#" class="easyui-linkbutton" disabled style="width:80px">Disabled</a>

			<p>Colors<p>
			<p><a href="#" class="easyui-linkbutton c1" style="width:100%">Button1</a></p>
			<p><a href="#" class="easyui-linkbutton c2" style="width:100%">Button2</a></p>
			<p><a href="#" class="easyui-linkbutton c3" style="width:100%">Button3</a></p>
			<p><a href="#" class="easyui-linkbutton c4" style="width:100%">Button4</a></p>
			<p><a href="#" class="easyui-linkbutton c5" style="width:100%">Button5</a></p>
			<p><a href="#" class="easyui-linkbutton c6" style="width:100%">Button6</a></p>
		</div>
	</div>
</body>	
</html>

+ 1 - 0
wwwroot/Plugins/easyui/demo-mobile/button/switch.html

@@ -0,0 +1 @@
+<!doctype html>
<html>
<head>
    <meta charset="UTF-8">  
	<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Switch Button - jQuery EasyUI Mobile Demo</title>  
    <link rel="stylesheet" type="text/css" href="../../themes/metro/easyui.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/mobile.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/color.css">  
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">  
    <script type="text/javascript" src="../../jquery.min.js"></script>  
    <script type="text/javascript" src="../../jquery.easyui.min.js"></script>
    <script type="text/javascript" src="../../jquery.easyui.mobile.js"></script>
</head>
<body>
	<div class="easyui-navpanel">
		<header>
			<div class="m-toolbar">
				<span class="m-title">Switch Button</span>
			</div>
		</header>
		<ul class="m-list">
			<li>
				<span>Network</span>
				<div class="m-right"><input class="easyui-switchbutton" checked></div>
			</li>
			<li>
				<span>Bluetooth</span>
				<div class="m-right"><input class="easyui-switchbutton" checked></div>
			</li>
			<li>
				<span>Sent mail</span>
				<div class="m-right"><input class="easyui-switchbutton" data-options="checked:false"></div>
			</li>
			<li>
				<a href="javascript:void(0)">Storage...</a>
			</li>
			<li>
				<a href="javascript:void(0)">More...</a>
			</li>
		</ul>
	</div>
</body>	
</html>

Някои файлове не бяха показани, защото твърде много файлове са промени