├── MultipleFileUpload.sln └── MultipleFileUpload ├── App_Start └── RouteConfig.cs ├── Content ├── Site.css ├── bootstrap.css └── bootstrap.min.css ├── Controllers └── SupportController.cs ├── Global.asax ├── Global.asax.cs ├── Models ├── FileDetail.cs ├── Support.cs └── SupportContext.cs ├── MultipleFileUpload.csproj ├── MultipleFileUpload.csproj.user ├── Properties └── AssemblyInfo.cs ├── Scripts ├── bootstrap.js ├── bootstrap.min.js ├── jquery-1.10.2.intellisense.js ├── jquery-1.10.2.js ├── jquery-1.10.2.min.js ├── jquery-1.10.2.min.map ├── jquery.validate-vsdoc.js ├── jquery.validate.js ├── jquery.validate.min.js ├── jquery.validate.unobtrusive.js ├── jquery.validate.unobtrusive.min.js └── modernizr-2.6.2.js ├── Views ├── Shared │ └── _Layout.cshtml ├── Support │ ├── Create.cshtml │ ├── Delete.cshtml │ ├── Edit.cshtml │ └── Index.cshtml ├── _ViewStart.cshtml └── web.config ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf └── glyphicons-halflings-regular.woff └── packages.config /MultipleFileUpload.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultipleFileUpload", "MultipleFileUpload\MultipleFileUpload.csproj", "{8A722A58-4212-43BF-81D4-A43796F35180}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {8A722A58-4212-43BF-81D4-A43796F35180}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {8A722A58-4212-43BF-81D4-A43796F35180}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {8A722A58-4212-43BF-81D4-A43796F35180}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {8A722A58-4212-43BF-81D4-A43796F35180}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /MultipleFileUpload/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace MultipleFileUpload 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Support", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MultipleFileUpload/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: .85em; 3 | font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif; 4 | color: #232323; 5 | background-color: #fff; 6 | padding:1em 5em; 7 | } 8 | 9 | header, footer, nav, section { 10 | display: block; 11 | } 12 | 13 | input, textarea 14 | { 15 | border:1px solid #aaa; 16 | } 17 | 18 | p 19 | { 20 | margin:10px 0px; 21 | } 22 | 23 | /* Styles for basic forms 24 | -----------------------------------------------------------*/ 25 | fieldset { 26 | border: 1px solid #ddd; 27 | padding: 0 1.4em 1.4em 1.4em; 28 | margin: 0 0 1.5em 0; 29 | } 30 | 31 | legend { 32 | font-size: 1.2em; 33 | font-weight: bold; 34 | } 35 | 36 | textarea { 37 | min-height: 75px; 38 | } 39 | 40 | .editor-label { 41 | margin: 1em 0 0 0; 42 | } 43 | 44 | .editor-field { 45 | margin: 0.5em 0 0 0; 46 | } 47 | 48 | .editor-field textarea 49 | { 50 | width:40%; 51 | } 52 | 53 | 54 | /* styles for validation helpers */ 55 | .field-validation-error { 56 | color: #b94a48; 57 | } 58 | 59 | .field-validation-valid { 60 | display: none; 61 | } 62 | 63 | input.input-validation-error { 64 | border: 1px solid #b94a48; 65 | } 66 | 67 | input[type="checkbox"].input-validation-error { 68 | border: 0 none; 69 | } 70 | 71 | .validation-summary-errors { 72 | color: #b94a48; 73 | } 74 | 75 | .validation-summary-valid { 76 | display: none; 77 | } 78 | 79 | /* Custom css */ 80 | footer 81 | { 82 | margin-top:2em; 83 | padding-top:1em; 84 | border-top:solid 1px #808080; 85 | 86 | } 87 | 88 | table.gridtable { 89 | font-family: verdana,arial,sans-serif; 90 | font-size:0.9em; 91 | color:#333333; 92 | border-width: 1px; 93 | border-color: #666666; 94 | border-collapse: collapse; 95 | } 96 | table.gridtable th { 97 | border-width: 1px; 98 | padding: 8px; 99 | border-style: solid; 100 | border-color: #666666; 101 | background-color: #dedede; 102 | } 103 | table.gridtable td { 104 | border-width: 1px; 105 | padding: 8px; 106 | border-style: solid; 107 | border-color: #666666; 108 | background-color: #ffffff; 109 | } 110 | 111 | ul.attachment 112 | { 113 | width:40%; 114 | padding:0px; 115 | 116 | } 117 | 118 | ul.attachment li 119 | { 120 | margin:1em; 121 | padding:1em; 122 | border:solid 1px #808080; 123 | background-color:#dddddd; 124 | font-size:0.9em; 125 | list-style-type:none; 126 | } 127 | 128 | ul.attachment li a 129 | { 130 | font-weight:bold; 131 | } 132 | ul.attachment li a.title 133 | { 134 | 135 | } 136 | ul.attachment li a.deleteItem 137 | { 138 | text-align:right; 139 | float:right; 140 | color:#808080; 141 | } -------------------------------------------------------------------------------- /MultipleFileUpload/Controllers/SupportController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Web; 8 | using System.Web.Mvc; 9 | using MultipleFileUpload.Models; 10 | 11 | namespace MultipleFileUpload.Controllers 12 | { 13 | public class SupportController : Controller 14 | { 15 | private SupportContext db = new SupportContext(); 16 | 17 | // 18 | // GET: /Support/ 19 | 20 | public ActionResult Index() 21 | { 22 | return View(db.Supports.ToList()); 23 | } 24 | 25 | // 26 | // GET: /Support/Create 27 | 28 | public ActionResult Create() 29 | { 30 | return View(); 31 | } 32 | 33 | 34 | 35 | [HttpPost] 36 | [ValidateAntiForgeryToken] 37 | public ActionResult Create(Support support) 38 | { 39 | if (ModelState.IsValid) 40 | { 41 | List fileDetails = new List(); 42 | for (int i = 0; i < Request.Files.Count; i++) 43 | { 44 | var file = Request.Files[i]; 45 | 46 | if (file != null && file.ContentLength > 0) 47 | { 48 | var fileName = Path.GetFileName(file.FileName); 49 | FileDetail fileDetail = new FileDetail() 50 | { 51 | FileName = fileName, 52 | Extension = Path.GetExtension(fileName), 53 | Id = Guid.NewGuid() 54 | }; 55 | fileDetails.Add(fileDetail); 56 | 57 | var path = Path.Combine(Server.MapPath("~/App_Data/Upload/"), fileDetail.Id + fileDetail.Extension); 58 | file.SaveAs(path); 59 | } 60 | } 61 | 62 | support.FileDetails = fileDetails; 63 | db.Supports.Add(support); 64 | db.SaveChanges(); 65 | return RedirectToAction("Index"); 66 | } 67 | 68 | return View(support); 69 | } 70 | 71 | // 72 | // GET: /Support/Edit/5 73 | 74 | public ActionResult Edit(int? id) 75 | { 76 | if (id == null) 77 | { 78 | return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 79 | } 80 | Support support = db.Supports.Include(s => s.FileDetails).SingleOrDefault(x => x.SupportId == id); 81 | if (support == null) 82 | { 83 | return HttpNotFound(); 84 | } 85 | return View(support); 86 | } 87 | 88 | 89 | public FileResult Download(String p, String d) 90 | { 91 | return File(Path.Combine(Server.MapPath("~/App_Data/Upload/"), p), System.Net.Mime.MediaTypeNames.Application.Octet, d); 92 | } 93 | 94 | 95 | 96 | // 97 | // POST: /Support/Edit/5 98 | 99 | [HttpPost] 100 | [ValidateAntiForgeryToken] 101 | public ActionResult Edit(Support support) 102 | { 103 | if (ModelState.IsValid) 104 | { 105 | 106 | //New Files 107 | for (int i = 0; i < Request.Files.Count; i++) 108 | { 109 | var file = Request.Files[i]; 110 | 111 | if (file != null && file.ContentLength > 0) 112 | { 113 | var fileName = Path.GetFileName(file.FileName); 114 | FileDetail fileDetail = new FileDetail() 115 | { 116 | FileName = fileName, 117 | Extension = Path.GetExtension(fileName), 118 | Id = Guid.NewGuid(), 119 | SupportId = support.SupportId 120 | }; 121 | var path = Path.Combine(Server.MapPath("~/App_Data/Upload/"), fileDetail.Id + fileDetail.Extension); 122 | file.SaveAs(path); 123 | 124 | db.Entry(fileDetail).State = EntityState.Added; 125 | } 126 | } 127 | 128 | db.Entry(support).State = EntityState.Modified; 129 | db.SaveChanges(); 130 | return RedirectToAction("Index"); 131 | } 132 | return View(support); 133 | } 134 | 135 | 136 | 137 | [HttpPost] 138 | public JsonResult DeleteFile(string id) 139 | { 140 | if (String.IsNullOrEmpty(id)) 141 | { 142 | Response.StatusCode = (int)HttpStatusCode.BadRequest; 143 | return Json(new { Result = "Error" }); 144 | } 145 | try 146 | { 147 | Guid guid = new Guid(id); 148 | FileDetail fileDetail = db.FileDetails.Find(guid); 149 | if (fileDetail == null) 150 | { 151 | Response.StatusCode = (int)HttpStatusCode.NotFound; 152 | return Json(new { Result = "Error" }); 153 | } 154 | 155 | //Remove from database 156 | db.FileDetails.Remove(fileDetail); 157 | db.SaveChanges(); 158 | 159 | //Delete file from the file system 160 | var path = Path.Combine(Server.MapPath("~/App_Data/Upload/"), fileDetail.Id + fileDetail.Extension); 161 | if (System.IO.File.Exists(path)) 162 | { 163 | System.IO.File.Delete(path); 164 | } 165 | return Json(new { Result = "OK" }); 166 | } 167 | catch (Exception ex) 168 | { 169 | return Json(new { Result = "ERROR", Message = ex.Message }); 170 | } 171 | } 172 | 173 | 174 | 175 | 176 | 177 | // 178 | // POST: /Support/Delete/5 179 | 180 | [HttpPost] 181 | public JsonResult Delete(int id) 182 | { 183 | try 184 | { 185 | Support support = db.Supports.Find(id); 186 | if (support == null) 187 | { 188 | Response.StatusCode = (int)HttpStatusCode.NotFound; 189 | return Json(new { Result = "Error" }); 190 | } 191 | 192 | //delete files from the file system 193 | 194 | foreach (var item in support.FileDetails){ 195 | String path = Path.Combine(Server.MapPath("~/App_Data/Upload/"), item.Id + item.Extension); 196 | if (System.IO.File.Exists(path)) 197 | { 198 | System.IO.File.Delete(path); 199 | } 200 | } 201 | 202 | db.Supports.Remove(support); 203 | db.SaveChanges(); 204 | return Json(new { Result = "OK" }); 205 | } 206 | catch (Exception ex) 207 | { 208 | return Json(new { Result = "ERROR", Message = ex.Message }); 209 | } 210 | } 211 | 212 | protected override void Dispose(bool disposing) 213 | { 214 | db.Dispose(); 215 | base.Dispose(disposing); 216 | } 217 | } 218 | } -------------------------------------------------------------------------------- /MultipleFileUpload/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MultipleFileUpload.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /MultipleFileUpload/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.Mvc; 7 | using System.Web.Routing; 8 | using MultipleFileUpload.Models; 9 | 10 | namespace MultipleFileUpload 11 | { 12 | public class MvcApplication : System.Web.HttpApplication 13 | { 14 | protected void Application_Start() 15 | { 16 | AreaRegistration.RegisterAllAreas(); 17 | RouteConfig.RegisterRoutes(RouteTable.Routes); 18 | Database.SetInitializer(null); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MultipleFileUpload/Models/FileDetail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace MultipleFileUpload.Models 7 | { 8 | public class FileDetail 9 | { 10 | public Guid Id { get; set; } 11 | public string FileName { get; set; } 12 | public string Extension { get; set; } 13 | public int SupportId { get; set; } 14 | public virtual Support Support { get; set; } 15 | 16 | } 17 | } -------------------------------------------------------------------------------- /MultipleFileUpload/Models/Support.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Web; 6 | 7 | namespace MultipleFileUpload.Models 8 | { 9 | public class Support 10 | { 11 | public int SupportId { get; set; } 12 | 13 | [Required(ErrorMessage = "Please Enter Your Name")] 14 | [Display(Name = "Name")] 15 | [MaxLength(100)] 16 | public string Name { get; set; } 17 | 18 | [Required(ErrorMessage = "Please Enter Summary")] 19 | [Display(Name = "Summary")] 20 | [MaxLength(500)] 21 | public string Summary { get; set; } 22 | 23 | public virtual ICollection FileDetails { get; set; } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /MultipleFileUpload/Models/SupportContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Web; 6 | 7 | namespace MultipleFileUpload.Models 8 | { 9 | public class SupportContext : DbContext 10 | { 11 | public SupportContext() 12 | : base("name=DefaultConnection") 13 | { 14 | } 15 | public DbSet Supports { get; set; } 16 | public DbSet FileDetails { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /MultipleFileUpload/MultipleFileUpload.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {8A722A58-4212-43BF-81D4-A43796F35180} 11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | MultipleFileUpload 15 | MultipleFileUpload 16 | v4.5 17 | true 18 | 19 | 20 | 21 | 22 | ..\packages\WebGrease.1.5.2\lib 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | pdbonly 35 | true 36 | bin\ 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | 43 | ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll 44 | 45 | 46 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll 47 | 48 | 49 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll 50 | 51 | 52 | 53 | ..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | ..\packages\WebGrease.1.5.2\lib\WebGrease.dll 79 | 80 | 81 | 82 | 83 | True 84 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 85 | 86 | 87 | ..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll 88 | 89 | 90 | ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.dll 91 | 92 | 93 | ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.Deployment.dll 94 | 95 | 96 | ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.Razor.dll 97 | 98 | 99 | ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Helpers.dll 100 | 101 | 102 | ..\packages\Microsoft.AspNet.Mvc.5.0.0\lib\net45\System.Web.Mvc.dll 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | Designer 127 | 128 | 129 | 130 | 131 | 132 | 133 | Global.asax 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | Web.config 152 | 153 | 154 | Web.config 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 10.0 165 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | True 175 | True 176 | 0 177 | / 178 | http://localhost:51320/ 179 | False 180 | False 181 | 182 | 183 | False 184 | 185 | 186 | 187 | 188 | 195 | -------------------------------------------------------------------------------- /MultipleFileUpload/MultipleFileUpload.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | False 6 | False 7 | 8 | False 9 | ShowAllFiles 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | CurrentPage 18 | True 19 | False 20 | False 21 | False 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | False 31 | True 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /MultipleFileUpload/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MultipleFileUpload")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MultipleFileUpload")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cd256a9d-d6cb-4d75-a1c2-559c1b57d5c1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /MultipleFileUpload/Scripts/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | 16 | /** 17 | * bootstrap.js v3.0.0 by @fat and @mdo 18 | * Copyright 2013 Twitter Inc. 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | */ 21 | if(!jQuery)throw new Error("Bootstrap requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]}}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(window.jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d)};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.is("input")?"val":"html",e=c.data();a+="Text",e.resetText||c.data("resetText",c[d]()),c[d](e[a]||this.options[a]),setTimeout(function(){"loadingText"==a?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.closest('[data-toggle="buttons"]');if(a.length){var b=this.$element.find("input").prop("checked",!this.$element.hasClass("active")).trigger("change");"radio"===b.prop("type")&&a.find(".active").removeClass("active")}this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition.end&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}this.sliding=!0,f&&this.pause();var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});if(!e.hasClass("active")){if(this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(j),j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)}).emulateTransitionEnd(600)}else{if(this.$element.trigger(j),j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return f&&this.cycle(),this}};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?(this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350),void 0):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(window.jQuery),+function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(''}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"html":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(window.jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(c).is("body")?a(window):a(c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#\w/.test(e)&&a(e);return f&&f.length&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parents(".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.attr("data-target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top()),"function"==typeof h&&(h=f.bottom());var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;this.affixed!==i&&(this.unpin&&this.$element.css("top",""),this.affixed=i,this.unpin="bottom"==i?e.top-d:null,this.$element.removeClass(b.RESET).addClass("affix"+(i?"-"+i:"")),"bottom"==i&&this.$element.offset({top:document.body.offsetHeight-h-this.$element.height()}))}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(window.jQuery); -------------------------------------------------------------------------------- /MultipleFileUpload/Scripts/jquery.validate-vsdoc.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | * This file has been commented to support Visual Studio Intellisense. 17 | * You should not use this file at runtime inside the browser--it is only 18 | * intended to be used only for design-time IntelliSense. Please use the 19 | * standard jQuery library for all production use. 20 | * 21 | * Comment version: 1.11.1 22 | */ 23 | 24 | /* 25 | * Note: While Microsoft is not the author of this file, Microsoft is 26 | * offering you a license subject to the terms of the Microsoft Software 27 | * License Terms for Microsoft ASP.NET Model View Controller 3. 28 | * Microsoft reserves all other rights. The notices below are provided 29 | * for informational purposes only and are not the license terms under 30 | * which Microsoft distributed this file. 31 | * 32 | * jQuery Validation Plugin - v1.11.1 - 2/4/2013 33 | * https://github.com/jzaefferer/jquery-validation 34 | * Copyright (c) 2013 Jörn Zaefferer; Licensed MIT 35 | * 36 | */ 37 | 38 | (function($) { 39 | 40 | $.extend($.fn, { 41 | // http://docs.jquery.com/Plugins/Validation/validate 42 | validate: function( options ) { 43 | /// 44 | /// Validates the selected form. This method sets up event handlers for submit, focus, 45 | /// keyup, blur and click to trigger validation of the entire form or individual 46 | /// elements. Each one can be disabled, see the onxxx options (onsubmit, onfocusout, 47 | /// onkeyup, onclick). focusInvalid focuses elements when submitting a invalid form. 48 | /// 49 | /// 50 | /// A set of key/value pairs that configure the validate. All options are optional. 51 | /// 52 | 53 | // if nothing is selected, return nothing; can't chain anyway 54 | if (!this.length) { 55 | options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" ); 56 | return; 57 | } 58 | 59 | // check if a validator for this form was already created 60 | var validator = $.data(this[0], 'validator'); 61 | if ( validator ) { 62 | return validator; 63 | } 64 | 65 | validator = new $.validator( options, this[0] ); 66 | $.data(this[0], 'validator', validator); 67 | 68 | if ( validator.settings.onsubmit ) { 69 | 70 | // allow suppresing validation by adding a cancel class to the submit button 71 | this.find("input, button").filter(".cancel").click(function() { 72 | validator.cancelSubmit = true; 73 | }); 74 | 75 | // when a submitHandler is used, capture the submitting button 76 | if (validator.settings.submitHandler) { 77 | this.find("input, button").filter(":submit").click(function() { 78 | validator.submitButton = this; 79 | }); 80 | } 81 | 82 | // validate the form on submit 83 | this.submit( function( event ) { 84 | if ( validator.settings.debug ) 85 | // prevent form submit to be able to see console output 86 | event.preventDefault(); 87 | 88 | function handle() { 89 | if ( validator.settings.submitHandler ) { 90 | if (validator.submitButton) { 91 | // insert a hidden input as a replacement for the missing submit button 92 | var hidden = $("").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); 93 | } 94 | validator.settings.submitHandler.call( validator, validator.currentForm ); 95 | if (validator.submitButton) { 96 | // and clean up afterwards; thanks to no-block-scope, hidden can be referenced 97 | hidden.remove(); 98 | } 99 | return false; 100 | } 101 | return true; 102 | } 103 | 104 | // prevent submit for invalid forms or custom submit handlers 105 | if ( validator.cancelSubmit ) { 106 | validator.cancelSubmit = false; 107 | return handle(); 108 | } 109 | if ( validator.form() ) { 110 | if ( validator.pendingRequest ) { 111 | validator.formSubmitted = true; 112 | return false; 113 | } 114 | return handle(); 115 | } else { 116 | validator.focusInvalid(); 117 | return false; 118 | } 119 | }); 120 | } 121 | 122 | return validator; 123 | }, 124 | // http://docs.jquery.com/Plugins/Validation/valid 125 | valid: function() { 126 | /// 127 | /// Checks if the selected form is valid or if all selected elements are valid. 128 | /// validate() needs to be called on the form before checking it using this method. 129 | /// 130 | /// 131 | 132 | if ( $(this[0]).is('form')) { 133 | return this.validate().form(); 134 | } else { 135 | var valid = true; 136 | var validator = $(this[0].form).validate(); 137 | this.each(function() { 138 | valid &= validator.element(this); 139 | }); 140 | return valid; 141 | } 142 | }, 143 | // attributes: space seperated list of attributes to retrieve and remove 144 | removeAttrs: function(attributes) { 145 | /// 146 | /// Remove the specified attributes from the first matched element and return them. 147 | /// 148 | /// 149 | /// A space-seperated list of attribute names to remove. 150 | /// 151 | 152 | var result = {}, 153 | $element = this; 154 | $.each(attributes.split(/\s/), function(index, value) { 155 | result[value] = $element.attr(value); 156 | $element.removeAttr(value); 157 | }); 158 | return result; 159 | }, 160 | // http://docs.jquery.com/Plugins/Validation/rules 161 | rules: function(command, argument) { 162 | /// 163 | /// Return the validations rules for the first selected element. 164 | /// 165 | /// 166 | /// Can be either "add" or "remove". 167 | /// 168 | /// 169 | /// A list of rules to add or remove. 170 | /// 171 | 172 | var element = this[0]; 173 | 174 | if (command) { 175 | var settings = $.data(element.form, 'validator').settings; 176 | var staticRules = settings.rules; 177 | var existingRules = $.validator.staticRules(element); 178 | switch(command) { 179 | case "add": 180 | $.extend(existingRules, $.validator.normalizeRule(argument)); 181 | staticRules[element.name] = existingRules; 182 | if (argument.messages) 183 | settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); 184 | break; 185 | case "remove": 186 | if (!argument) { 187 | delete staticRules[element.name]; 188 | return existingRules; 189 | } 190 | var filtered = {}; 191 | $.each(argument.split(/\s/), function(index, method) { 192 | filtered[method] = existingRules[method]; 193 | delete existingRules[method]; 194 | }); 195 | return filtered; 196 | } 197 | } 198 | 199 | var data = $.validator.normalizeRules( 200 | $.extend( 201 | {}, 202 | $.validator.metadataRules(element), 203 | $.validator.classRules(element), 204 | $.validator.attributeRules(element), 205 | $.validator.staticRules(element) 206 | ), element); 207 | 208 | // make sure required is at front 209 | if (data.required) { 210 | var param = data.required; 211 | delete data.required; 212 | data = $.extend({required: param}, data); 213 | } 214 | 215 | return data; 216 | } 217 | }); 218 | 219 | // Custom selectors 220 | $.extend($.expr[":"], { 221 | // http://docs.jquery.com/Plugins/Validation/blank 222 | blank: function(a) {return !$.trim("" + a.value);}, 223 | // http://docs.jquery.com/Plugins/Validation/filled 224 | filled: function(a) {return !!$.trim("" + a.value);}, 225 | // http://docs.jquery.com/Plugins/Validation/unchecked 226 | unchecked: function(a) {return !a.checked;} 227 | }); 228 | 229 | // constructor for validator 230 | $.validator = function( options, form ) { 231 | this.settings = $.extend( true, {}, $.validator.defaults, options ); 232 | this.currentForm = form; 233 | this.init(); 234 | }; 235 | 236 | $.validator.format = function(source, params) { 237 | /// 238 | /// Replaces {n} placeholders with arguments. 239 | /// One or more arguments can be passed, in addition to the string template itself, to insert 240 | /// into the string. 241 | /// 242 | /// 243 | /// The string to format. 244 | /// 245 | /// 246 | /// The first argument to insert, or an array of Strings to insert 247 | /// 248 | /// 249 | 250 | if ( arguments.length == 1 ) 251 | return function() { 252 | var args = $.makeArray(arguments); 253 | args.unshift(source); 254 | return $.validator.format.apply( this, args ); 255 | }; 256 | if ( arguments.length > 2 && params.constructor != Array ) { 257 | params = $.makeArray(arguments).slice(1); 258 | } 259 | if ( params.constructor != Array ) { 260 | params = [ params ]; 261 | } 262 | $.each(params, function(i, n) { 263 | source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n); 264 | }); 265 | return source; 266 | }; 267 | 268 | $.extend($.validator, { 269 | 270 | defaults: { 271 | messages: {}, 272 | groups: {}, 273 | rules: {}, 274 | errorClass: "error", 275 | validClass: "valid", 276 | errorElement: "label", 277 | focusInvalid: true, 278 | errorContainer: $( [] ), 279 | errorLabelContainer: $( [] ), 280 | onsubmit: true, 281 | ignore: [], 282 | ignoreTitle: false, 283 | onfocusin: function(element) { 284 | this.lastActive = element; 285 | 286 | // hide error label and remove error class on focus if enabled 287 | if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { 288 | this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); 289 | this.addWrapper(this.errorsFor(element)).hide(); 290 | } 291 | }, 292 | onfocusout: function(element) { 293 | if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { 294 | this.element(element); 295 | } 296 | }, 297 | onkeyup: function(element) { 298 | if ( element.name in this.submitted || element == this.lastElement ) { 299 | this.element(element); 300 | } 301 | }, 302 | onclick: function(element) { 303 | // click on selects, radiobuttons and checkboxes 304 | if ( element.name in this.submitted ) 305 | this.element(element); 306 | // or option elements, check parent select in that case 307 | else if (element.parentNode.name in this.submitted) 308 | this.element(element.parentNode); 309 | }, 310 | highlight: function( element, errorClass, validClass ) { 311 | $(element).addClass(errorClass).removeClass(validClass); 312 | }, 313 | unhighlight: function( element, errorClass, validClass ) { 314 | $(element).removeClass(errorClass).addClass(validClass); 315 | } 316 | }, 317 | 318 | // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults 319 | setDefaults: function(settings) { 320 | /// 321 | /// Modify default settings for validation. 322 | /// Accepts everything that Plugins/Validation/validate accepts. 323 | /// 324 | /// 325 | /// Options to set as default. 326 | /// 327 | 328 | $.extend( $.validator.defaults, settings ); 329 | }, 330 | 331 | messages: { 332 | required: "This field is required.", 333 | remote: "Please fix this field.", 334 | email: "Please enter a valid email address.", 335 | url: "Please enter a valid URL.", 336 | date: "Please enter a valid date.", 337 | dateISO: "Please enter a valid date (ISO).", 338 | number: "Please enter a valid number.", 339 | digits: "Please enter only digits.", 340 | creditcard: "Please enter a valid credit card number.", 341 | equalTo: "Please enter the same value again.", 342 | accept: "Please enter a value with a valid extension.", 343 | maxlength: $.validator.format("Please enter no more than {0} characters."), 344 | minlength: $.validator.format("Please enter at least {0} characters."), 345 | rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), 346 | range: $.validator.format("Please enter a value between {0} and {1}."), 347 | max: $.validator.format("Please enter a value less than or equal to {0}."), 348 | min: $.validator.format("Please enter a value greater than or equal to {0}.") 349 | }, 350 | 351 | autoCreateRanges: false, 352 | 353 | prototype: { 354 | 355 | init: function() { 356 | this.labelContainer = $(this.settings.errorLabelContainer); 357 | this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); 358 | this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); 359 | this.submitted = {}; 360 | this.valueCache = {}; 361 | this.pendingRequest = 0; 362 | this.pending = {}; 363 | this.invalid = {}; 364 | this.reset(); 365 | 366 | var groups = (this.groups = {}); 367 | $.each(this.settings.groups, function(key, value) { 368 | $.each(value.split(/\s/), function(index, name) { 369 | groups[name] = key; 370 | }); 371 | }); 372 | var rules = this.settings.rules; 373 | $.each(rules, function(key, value) { 374 | rules[key] = $.validator.normalizeRule(value); 375 | }); 376 | 377 | function delegate(event) { 378 | var validator = $.data(this[0].form, "validator"), 379 | eventType = "on" + event.type.replace(/^validate/, ""); 380 | validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] ); 381 | } 382 | $(this.currentForm) 383 | .validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate) 384 | .validateDelegate(":radio, :checkbox, select, option", "click", delegate); 385 | 386 | if (this.settings.invalidHandler) 387 | $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); 388 | }, 389 | 390 | // http://docs.jquery.com/Plugins/Validation/Validator/form 391 | form: function() { 392 | /// 393 | /// Validates the form, returns true if it is valid, false otherwise. 394 | /// This behaves as a normal submit event, but returns the result. 395 | /// 396 | /// 397 | 398 | this.checkForm(); 399 | $.extend(this.submitted, this.errorMap); 400 | this.invalid = $.extend({}, this.errorMap); 401 | if (!this.valid()) 402 | $(this.currentForm).triggerHandler("invalid-form", [this]); 403 | this.showErrors(); 404 | return this.valid(); 405 | }, 406 | 407 | checkForm: function() { 408 | this.prepareForm(); 409 | for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { 410 | this.check( elements[i] ); 411 | } 412 | return this.valid(); 413 | }, 414 | 415 | // http://docs.jquery.com/Plugins/Validation/Validator/element 416 | element: function( element ) { 417 | /// 418 | /// Validates a single element, returns true if it is valid, false otherwise. 419 | /// This behaves as validation on blur or keyup, but returns the result. 420 | /// 421 | /// 422 | /// An element to validate, must be inside the validated form. 423 | /// 424 | /// 425 | 426 | element = this.clean( element ); 427 | this.lastElement = element; 428 | this.prepareElement( element ); 429 | this.currentElements = $(element); 430 | var result = this.check( element ); 431 | if ( result ) { 432 | delete this.invalid[element.name]; 433 | } else { 434 | this.invalid[element.name] = true; 435 | } 436 | if ( !this.numberOfInvalids() ) { 437 | // Hide error containers on last error 438 | this.toHide = this.toHide.add( this.containers ); 439 | } 440 | this.showErrors(); 441 | return result; 442 | }, 443 | 444 | // http://docs.jquery.com/Plugins/Validation/Validator/showErrors 445 | showErrors: function(errors) { 446 | /// 447 | /// Show the specified messages. 448 | /// Keys have to refer to the names of elements, values are displayed for those elements, using the configured error placement. 449 | /// 450 | /// 451 | /// One or more key/value pairs of input names and messages. 452 | /// 453 | 454 | if(errors) { 455 | // add items to error list and map 456 | $.extend( this.errorMap, errors ); 457 | this.errorList = []; 458 | for ( var name in errors ) { 459 | this.errorList.push({ 460 | message: errors[name], 461 | element: this.findByName(name)[0] 462 | }); 463 | } 464 | // remove items from success list 465 | this.successList = $.grep( this.successList, function(element) { 466 | return !(element.name in errors); 467 | }); 468 | } 469 | this.settings.showErrors 470 | ? this.settings.showErrors.call( this, this.errorMap, this.errorList ) 471 | : this.defaultShowErrors(); 472 | }, 473 | 474 | // http://docs.jquery.com/Plugins/Validation/Validator/resetForm 475 | resetForm: function() { 476 | /// 477 | /// Resets the controlled form. 478 | /// Resets input fields to their original value (requires form plugin), removes classes 479 | /// indicating invalid elements and hides error messages. 480 | /// 481 | 482 | if ( $.fn.resetForm ) 483 | $( this.currentForm ).resetForm(); 484 | this.submitted = {}; 485 | this.prepareForm(); 486 | this.hideErrors(); 487 | this.elements().removeClass( this.settings.errorClass ); 488 | }, 489 | 490 | numberOfInvalids: function() { 491 | /// 492 | /// Returns the number of invalid fields. 493 | /// This depends on the internal validator state. It covers all fields only after 494 | /// validating the complete form (on submit or via $("form").valid()). After validating 495 | /// a single element, only that element is counted. Most useful in combination with the 496 | /// invalidHandler-option. 497 | /// 498 | /// 499 | 500 | return this.objectLength(this.invalid); 501 | }, 502 | 503 | objectLength: function( obj ) { 504 | var count = 0; 505 | for ( var i in obj ) 506 | count++; 507 | return count; 508 | }, 509 | 510 | hideErrors: function() { 511 | this.addWrapper( this.toHide ).hide(); 512 | }, 513 | 514 | valid: function() { 515 | return this.size() == 0; 516 | }, 517 | 518 | size: function() { 519 | return this.errorList.length; 520 | }, 521 | 522 | focusInvalid: function() { 523 | if( this.settings.focusInvalid ) { 524 | try { 525 | $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) 526 | .filter(":visible") 527 | .focus() 528 | // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 529 | .trigger("focusin"); 530 | } catch(e) { 531 | // ignore IE throwing errors when focusing hidden elements 532 | } 533 | } 534 | }, 535 | 536 | findLastActive: function() { 537 | var lastActive = this.lastActive; 538 | return lastActive && $.grep(this.errorList, function(n) { 539 | return n.element.name == lastActive.name; 540 | }).length == 1 && lastActive; 541 | }, 542 | 543 | elements: function() { 544 | var validator = this, 545 | rulesCache = {}; 546 | 547 | // select all valid inputs inside the form (no submit or reset buttons) 548 | // workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved 549 | return $([]).add(this.currentForm.elements) 550 | .filter(":input") 551 | .not(":submit, :reset, :image, [disabled]") 552 | .not( this.settings.ignore ) 553 | .filter(function() { 554 | !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this); 555 | 556 | // select only the first element for each name, and only those with rules specified 557 | if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) 558 | return false; 559 | 560 | rulesCache[this.name] = true; 561 | return true; 562 | }); 563 | }, 564 | 565 | clean: function( selector ) { 566 | return $( selector )[0]; 567 | }, 568 | 569 | errors: function() { 570 | return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext ); 571 | }, 572 | 573 | reset: function() { 574 | this.successList = []; 575 | this.errorList = []; 576 | this.errorMap = {}; 577 | this.toShow = $([]); 578 | this.toHide = $([]); 579 | this.currentElements = $([]); 580 | }, 581 | 582 | prepareForm: function() { 583 | this.reset(); 584 | this.toHide = this.errors().add( this.containers ); 585 | }, 586 | 587 | prepareElement: function( element ) { 588 | this.reset(); 589 | this.toHide = this.errorsFor(element); 590 | }, 591 | 592 | check: function( element ) { 593 | element = this.clean( element ); 594 | 595 | // if radio/checkbox, validate first element in group instead 596 | if (this.checkable(element)) { 597 | element = this.findByName(element.name).not(this.settings.ignore)[0]; 598 | } 599 | 600 | var rules = $(element).rules(); 601 | var dependencyMismatch = false; 602 | for (var method in rules) { 603 | var rule = { method: method, parameters: rules[method] }; 604 | try { 605 | var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters ); 606 | 607 | // if a method indicates that the field is optional and therefore valid, 608 | // don't mark it as valid when there are no other rules 609 | if ( result == "dependency-mismatch" ) { 610 | dependencyMismatch = true; 611 | continue; 612 | } 613 | dependencyMismatch = false; 614 | 615 | if ( result == "pending" ) { 616 | this.toHide = this.toHide.not( this.errorsFor(element) ); 617 | return; 618 | } 619 | 620 | if( !result ) { 621 | this.formatAndAdd( element, rule ); 622 | return false; 623 | } 624 | } catch(e) { 625 | this.settings.debug && window.console && console.log("exception occured when checking element " + element.id 626 | + ", check the '" + rule.method + "' method", e); 627 | throw e; 628 | } 629 | } 630 | if (dependencyMismatch) 631 | return; 632 | if ( this.objectLength(rules) ) 633 | this.successList.push(element); 634 | return true; 635 | }, 636 | 637 | // return the custom message for the given element and validation method 638 | // specified in the element's "messages" metadata 639 | customMetaMessage: function(element, method) { 640 | if (!$.metadata) 641 | return; 642 | 643 | var meta = this.settings.meta 644 | ? $(element).metadata()[this.settings.meta] 645 | : $(element).metadata(); 646 | 647 | return meta && meta.messages && meta.messages[method]; 648 | }, 649 | 650 | // return the custom message for the given element name and validation method 651 | customMessage: function( name, method ) { 652 | var m = this.settings.messages[name]; 653 | return m && (m.constructor == String 654 | ? m 655 | : m[method]); 656 | }, 657 | 658 | // return the first defined argument, allowing empty strings 659 | findDefined: function() { 660 | for(var i = 0; i < arguments.length; i++) { 661 | if (arguments[i] !== undefined) 662 | return arguments[i]; 663 | } 664 | return undefined; 665 | }, 666 | 667 | defaultMessage: function( element, method) { 668 | return this.findDefined( 669 | this.customMessage( element.name, method ), 670 | this.customMetaMessage( element, method ), 671 | // title is never undefined, so handle empty string as undefined 672 | !this.settings.ignoreTitle && element.title || undefined, 673 | $.validator.messages[method], 674 | "Warning: No message defined for " + element.name + "" 675 | ); 676 | }, 677 | 678 | formatAndAdd: function( element, rule ) { 679 | var message = this.defaultMessage( element, rule.method ), 680 | theregex = /\$?\{(\d+)\}/g; 681 | if ( typeof message == "function" ) { 682 | message = message.call(this, rule.parameters, element); 683 | } else if (theregex.test(message)) { 684 | message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters); 685 | } 686 | this.errorList.push({ 687 | message: message, 688 | element: element 689 | }); 690 | 691 | this.errorMap[element.name] = message; 692 | this.submitted[element.name] = message; 693 | }, 694 | 695 | addWrapper: function(toToggle) { 696 | if ( this.settings.wrapper ) 697 | toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 698 | return toToggle; 699 | }, 700 | 701 | defaultShowErrors: function() { 702 | for ( var i = 0; this.errorList[i]; i++ ) { 703 | var error = this.errorList[i]; 704 | this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); 705 | this.showLabel( error.element, error.message ); 706 | } 707 | if( this.errorList.length ) { 708 | this.toShow = this.toShow.add( this.containers ); 709 | } 710 | if (this.settings.success) { 711 | for ( var i = 0; this.successList[i]; i++ ) { 712 | this.showLabel( this.successList[i] ); 713 | } 714 | } 715 | if (this.settings.unhighlight) { 716 | for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) { 717 | this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass ); 718 | } 719 | } 720 | this.toHide = this.toHide.not( this.toShow ); 721 | this.hideErrors(); 722 | this.addWrapper( this.toShow ).show(); 723 | }, 724 | 725 | validElements: function() { 726 | return this.currentElements.not(this.invalidElements()); 727 | }, 728 | 729 | invalidElements: function() { 730 | return $(this.errorList).map(function() { 731 | return this.element; 732 | }); 733 | }, 734 | 735 | showLabel: function(element, message) { 736 | var label = this.errorsFor( element ); 737 | if ( label.length ) { 738 | // refresh error/success class 739 | label.removeClass().addClass( this.settings.errorClass ); 740 | 741 | // check if we have a generated label, replace the message then 742 | label.attr("generated") && label.html(message); 743 | } else { 744 | // create label 745 | label = $("<" + this.settings.errorElement + "/>") 746 | .attr({"for": this.idOrName(element), generated: true}) 747 | .addClass(this.settings.errorClass) 748 | .html(message || ""); 749 | if ( this.settings.wrapper ) { 750 | // make sure the element is visible, even in IE 751 | // actually showing the wrapped element is handled elsewhere 752 | label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); 753 | } 754 | if ( !this.labelContainer.append(label).length ) 755 | this.settings.errorPlacement 756 | ? this.settings.errorPlacement(label, $(element) ) 757 | : label.insertAfter(element); 758 | } 759 | if ( !message && this.settings.success ) { 760 | label.text(""); 761 | typeof this.settings.success == "string" 762 | ? label.addClass( this.settings.success ) 763 | : this.settings.success( label ); 764 | } 765 | this.toShow = this.toShow.add(label); 766 | }, 767 | 768 | errorsFor: function(element) { 769 | var name = this.idOrName(element); 770 | return this.errors().filter(function() { 771 | return $(this).attr('for') == name; 772 | }); 773 | }, 774 | 775 | idOrName: function(element) { 776 | return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); 777 | }, 778 | 779 | checkable: function( element ) { 780 | return /radio|checkbox/i.test(element.type); 781 | }, 782 | 783 | findByName: function( name ) { 784 | // select by name and filter by form for performance over form.find("[name=...]") 785 | var form = this.currentForm; 786 | return $(document.getElementsByName(name)).map(function(index, element) { 787 | return element.form == form && element.name == name && element || null; 788 | }); 789 | }, 790 | 791 | getLength: function(value, element) { 792 | switch( element.nodeName.toLowerCase() ) { 793 | case 'select': 794 | return $("option:selected", element).length; 795 | case 'input': 796 | if( this.checkable( element) ) 797 | return this.findByName(element.name).filter(':checked').length; 798 | } 799 | return value.length; 800 | }, 801 | 802 | depend: function(param, element) { 803 | return this.dependTypes[typeof param] 804 | ? this.dependTypes[typeof param](param, element) 805 | : true; 806 | }, 807 | 808 | dependTypes: { 809 | "boolean": function(param, element) { 810 | return param; 811 | }, 812 | "string": function(param, element) { 813 | return !!$(param, element.form).length; 814 | }, 815 | "function": function(param, element) { 816 | return param(element); 817 | } 818 | }, 819 | 820 | optional: function(element) { 821 | return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch"; 822 | }, 823 | 824 | startRequest: function(element) { 825 | if (!this.pending[element.name]) { 826 | this.pendingRequest++; 827 | this.pending[element.name] = true; 828 | } 829 | }, 830 | 831 | stopRequest: function(element, valid) { 832 | this.pendingRequest--; 833 | // sometimes synchronization fails, make sure pendingRequest is never < 0 834 | if (this.pendingRequest < 0) 835 | this.pendingRequest = 0; 836 | delete this.pending[element.name]; 837 | if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) { 838 | $(this.currentForm).submit(); 839 | this.formSubmitted = false; 840 | } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) { 841 | $(this.currentForm).triggerHandler("invalid-form", [this]); 842 | this.formSubmitted = false; 843 | } 844 | }, 845 | 846 | previousValue: function(element) { 847 | return $.data(element, "previousValue") || $.data(element, "previousValue", { 848 | old: null, 849 | valid: true, 850 | message: this.defaultMessage( element, "remote" ) 851 | }); 852 | } 853 | 854 | }, 855 | 856 | classRuleSettings: { 857 | required: {required: true}, 858 | email: {email: true}, 859 | url: {url: true}, 860 | date: {date: true}, 861 | dateISO: {dateISO: true}, 862 | dateDE: {dateDE: true}, 863 | number: {number: true}, 864 | numberDE: {numberDE: true}, 865 | digits: {digits: true}, 866 | creditcard: {creditcard: true} 867 | }, 868 | 869 | addClassRules: function(className, rules) { 870 | /// 871 | /// Add a compound class method - useful to refactor common combinations of rules into a single 872 | /// class. 873 | /// 874 | /// 875 | /// The name of the class rule to add 876 | /// 877 | /// 878 | /// The compound rules 879 | /// 880 | 881 | className.constructor == String ? 882 | this.classRuleSettings[className] = rules : 883 | $.extend(this.classRuleSettings, className); 884 | }, 885 | 886 | classRules: function(element) { 887 | var rules = {}; 888 | var classes = $(element).attr('class'); 889 | classes && $.each(classes.split(' '), function() { 890 | if (this in $.validator.classRuleSettings) { 891 | $.extend(rules, $.validator.classRuleSettings[this]); 892 | } 893 | }); 894 | return rules; 895 | }, 896 | 897 | attributeRules: function(element) { 898 | var rules = {}; 899 | var $element = $(element); 900 | 901 | for (var method in $.validator.methods) { 902 | var value = $element.attr(method); 903 | if (value) { 904 | rules[method] = value; 905 | } 906 | } 907 | 908 | // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs 909 | if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { 910 | delete rules.maxlength; 911 | } 912 | 913 | return rules; 914 | }, 915 | 916 | metadataRules: function(element) { 917 | if (!$.metadata) return {}; 918 | 919 | var meta = $.data(element.form, 'validator').settings.meta; 920 | return meta ? 921 | $(element).metadata()[meta] : 922 | $(element).metadata(); 923 | }, 924 | 925 | staticRules: function(element) { 926 | var rules = {}; 927 | var validator = $.data(element.form, 'validator'); 928 | if (validator.settings.rules) { 929 | rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; 930 | } 931 | return rules; 932 | }, 933 | 934 | normalizeRules: function(rules, element) { 935 | // handle dependency check 936 | $.each(rules, function(prop, val) { 937 | // ignore rule when param is explicitly false, eg. required:false 938 | if (val === false) { 939 | delete rules[prop]; 940 | return; 941 | } 942 | if (val.param || val.depends) { 943 | var keepRule = true; 944 | switch (typeof val.depends) { 945 | case "string": 946 | keepRule = !!$(val.depends, element.form).length; 947 | break; 948 | case "function": 949 | keepRule = val.depends.call(element, element); 950 | break; 951 | } 952 | if (keepRule) { 953 | rules[prop] = val.param !== undefined ? val.param : true; 954 | } else { 955 | delete rules[prop]; 956 | } 957 | } 958 | }); 959 | 960 | // evaluate parameters 961 | $.each(rules, function(rule, parameter) { 962 | rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; 963 | }); 964 | 965 | // clean number parameters 966 | $.each(['minlength', 'maxlength', 'min', 'max'], function() { 967 | if (rules[this]) { 968 | rules[this] = Number(rules[this]); 969 | } 970 | }); 971 | $.each(['rangelength', 'range'], function() { 972 | if (rules[this]) { 973 | rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; 974 | } 975 | }); 976 | 977 | if ($.validator.autoCreateRanges) { 978 | // auto-create ranges 979 | if (rules.min && rules.max) { 980 | rules.range = [rules.min, rules.max]; 981 | delete rules.min; 982 | delete rules.max; 983 | } 984 | if (rules.minlength && rules.maxlength) { 985 | rules.rangelength = [rules.minlength, rules.maxlength]; 986 | delete rules.minlength; 987 | delete rules.maxlength; 988 | } 989 | } 990 | 991 | // To support custom messages in metadata ignore rule methods titled "messages" 992 | if (rules.messages) { 993 | delete rules.messages; 994 | } 995 | 996 | return rules; 997 | }, 998 | 999 | // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 1000 | normalizeRule: function(data) { 1001 | if( typeof data == "string" ) { 1002 | var transformed = {}; 1003 | $.each(data.split(/\s/), function() { 1004 | transformed[this] = true; 1005 | }); 1006 | data = transformed; 1007 | } 1008 | return data; 1009 | }, 1010 | 1011 | // http://docs.jquery.com/Plugins/Validation/Validator/addMethod 1012 | addMethod: function(name, method, message) { 1013 | /// 1014 | /// Add a custom validation method. It must consist of a name (must be a legal javascript 1015 | /// identifier), a javascript based function and a default string message. 1016 | /// 1017 | /// 1018 | /// The name of the method, used to identify and referencing it, must be a valid javascript 1019 | /// identifier 1020 | /// 1021 | /// 1022 | /// The actual method implementation, returning true if an element is valid 1023 | /// 1024 | /// 1025 | /// (Optional) The default message to display for this method. Can be a function created by 1026 | /// jQuery.validator.format(value). When undefined, an already existing message is used 1027 | /// (handy for localization), otherwise the field-specific messages have to be defined. 1028 | /// 1029 | 1030 | $.validator.methods[name] = method; 1031 | $.validator.messages[name] = message != undefined ? message : $.validator.messages[name]; 1032 | if (method.length < 3) { 1033 | $.validator.addClassRules(name, $.validator.normalizeRule(name)); 1034 | } 1035 | }, 1036 | 1037 | methods: { 1038 | 1039 | // http://docs.jquery.com/Plugins/Validation/Methods/required 1040 | required: function(value, element, param) { 1041 | // check if dependency is met 1042 | if ( !this.depend(param, element) ) 1043 | return "dependency-mismatch"; 1044 | switch( element.nodeName.toLowerCase() ) { 1045 | case 'select': 1046 | // could be an array for select-multiple or a string, both are fine this way 1047 | var val = $(element).val(); 1048 | return val && val.length > 0; 1049 | case 'input': 1050 | if ( this.checkable(element) ) 1051 | return this.getLength(value, element) > 0; 1052 | default: 1053 | return $.trim(value).length > 0; 1054 | } 1055 | }, 1056 | 1057 | // http://docs.jquery.com/Plugins/Validation/Methods/remote 1058 | remote: function(value, element, param) { 1059 | if ( this.optional(element) ) 1060 | return "dependency-mismatch"; 1061 | 1062 | var previous = this.previousValue(element); 1063 | if (!this.settings.messages[element.name] ) 1064 | this.settings.messages[element.name] = {}; 1065 | previous.originalMessage = this.settings.messages[element.name].remote; 1066 | this.settings.messages[element.name].remote = previous.message; 1067 | 1068 | param = typeof param == "string" && {url:param} || param; 1069 | 1070 | if ( this.pending[element.name] ) { 1071 | return "pending"; 1072 | } 1073 | if ( previous.old === value ) { 1074 | return previous.valid; 1075 | } 1076 | 1077 | previous.old = value; 1078 | var validator = this; 1079 | this.startRequest(element); 1080 | var data = {}; 1081 | data[element.name] = value; 1082 | $.ajax($.extend(true, { 1083 | url: param, 1084 | mode: "abort", 1085 | port: "validate" + element.name, 1086 | dataType: "json", 1087 | data: data, 1088 | success: function(response) { 1089 | validator.settings.messages[element.name].remote = previous.originalMessage; 1090 | var valid = response === true; 1091 | if ( valid ) { 1092 | var submitted = validator.formSubmitted; 1093 | validator.prepareElement(element); 1094 | validator.formSubmitted = submitted; 1095 | validator.successList.push(element); 1096 | validator.showErrors(); 1097 | } else { 1098 | var errors = {}; 1099 | var message = response || validator.defaultMessage(element, "remote"); 1100 | errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; 1101 | validator.showErrors(errors); 1102 | } 1103 | previous.valid = valid; 1104 | validator.stopRequest(element, valid); 1105 | } 1106 | }, param)); 1107 | return "pending"; 1108 | }, 1109 | 1110 | // http://docs.jquery.com/Plugins/Validation/Methods/minlength 1111 | minlength: function(value, element, param) { 1112 | return this.optional(element) || this.getLength($.trim(value), element) >= param; 1113 | }, 1114 | 1115 | // http://docs.jquery.com/Plugins/Validation/Methods/maxlength 1116 | maxlength: function(value, element, param) { 1117 | return this.optional(element) || this.getLength($.trim(value), element) <= param; 1118 | }, 1119 | 1120 | // http://docs.jquery.com/Plugins/Validation/Methods/rangelength 1121 | rangelength: function(value, element, param) { 1122 | var length = this.getLength($.trim(value), element); 1123 | return this.optional(element) || ( length >= param[0] && length <= param[1] ); 1124 | }, 1125 | 1126 | // http://docs.jquery.com/Plugins/Validation/Methods/min 1127 | min: function( value, element, param ) { 1128 | return this.optional(element) || value >= param; 1129 | }, 1130 | 1131 | // http://docs.jquery.com/Plugins/Validation/Methods/max 1132 | max: function( value, element, param ) { 1133 | return this.optional(element) || value <= param; 1134 | }, 1135 | 1136 | // http://docs.jquery.com/Plugins/Validation/Methods/range 1137 | range: function( value, element, param ) { 1138 | return this.optional(element) || ( value >= param[0] && value <= param[1] ); 1139 | }, 1140 | 1141 | // http://docs.jquery.com/Plugins/Validation/Methods/email 1142 | email: function(value, element) { 1143 | // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ 1144 | return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value); 1145 | }, 1146 | 1147 | // http://docs.jquery.com/Plugins/Validation/Methods/url 1148 | url: function(value, element) { 1149 | // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ 1150 | return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); 1151 | }, 1152 | 1153 | // http://docs.jquery.com/Plugins/Validation/Methods/date 1154 | date: function(value, element) { 1155 | return this.optional(element) || !/Invalid|NaN/.test(new Date(value)); 1156 | }, 1157 | 1158 | // http://docs.jquery.com/Plugins/Validation/Methods/dateISO 1159 | dateISO: function(value, element) { 1160 | return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value); 1161 | }, 1162 | 1163 | // http://docs.jquery.com/Plugins/Validation/Methods/number 1164 | number: function(value, element) { 1165 | return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value); 1166 | }, 1167 | 1168 | // http://docs.jquery.com/Plugins/Validation/Methods/digits 1169 | digits: function(value, element) { 1170 | return this.optional(element) || /^\d+$/.test(value); 1171 | }, 1172 | 1173 | // http://docs.jquery.com/Plugins/Validation/Methods/creditcard 1174 | // based on http://en.wikipedia.org/wiki/Luhn 1175 | creditcard: function(value, element) { 1176 | if ( this.optional(element) ) 1177 | return "dependency-mismatch"; 1178 | // accept only digits and dashes 1179 | if (/[^0-9-]+/.test(value)) 1180 | return false; 1181 | var nCheck = 0, 1182 | nDigit = 0, 1183 | bEven = false; 1184 | 1185 | value = value.replace(/\D/g, ""); 1186 | 1187 | for (var n = value.length - 1; n >= 0; n--) { 1188 | var cDigit = value.charAt(n); 1189 | var nDigit = parseInt(cDigit, 10); 1190 | if (bEven) { 1191 | if ((nDigit *= 2) > 9) 1192 | nDigit -= 9; 1193 | } 1194 | nCheck += nDigit; 1195 | bEven = !bEven; 1196 | } 1197 | 1198 | return (nCheck % 10) == 0; 1199 | }, 1200 | 1201 | // http://docs.jquery.com/Plugins/Validation/Methods/accept 1202 | accept: function(value, element, param) { 1203 | param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif"; 1204 | return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); 1205 | }, 1206 | 1207 | // http://docs.jquery.com/Plugins/Validation/Methods/equalTo 1208 | equalTo: function(value, element, param) { 1209 | // bind to the blur event of the target in order to revalidate whenever the target field is updated 1210 | // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 1211 | var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { 1212 | $(element).valid(); 1213 | }); 1214 | return value == target.val(); 1215 | } 1216 | 1217 | } 1218 | 1219 | }); 1220 | 1221 | // deprecated, use $.validator.format instead 1222 | $.format = $.validator.format; 1223 | 1224 | })(jQuery); 1225 | 1226 | // ajax mode: abort 1227 | // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 1228 | // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 1229 | ;(function($) { 1230 | var pendingRequests = {}; 1231 | // Use a prefilter if available (1.5+) 1232 | if ( $.ajaxPrefilter ) { 1233 | $.ajaxPrefilter(function(settings, _, xhr) { 1234 | var port = settings.port; 1235 | if (settings.mode == "abort") { 1236 | if ( pendingRequests[port] ) { 1237 | pendingRequests[port].abort(); 1238 | } pendingRequests[port] = xhr; 1239 | } 1240 | }); 1241 | } else { 1242 | // Proxy ajax 1243 | var ajax = $.ajax; 1244 | $.ajax = function(settings) { 1245 | var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 1246 | port = ( "port" in settings ? settings : $.ajaxSettings ).port; 1247 | if (mode == "abort") { 1248 | if ( pendingRequests[port] ) { 1249 | pendingRequests[port].abort(); 1250 | } 1251 | 1252 | return (pendingRequests[port] = ajax.apply(this, arguments)); 1253 | } 1254 | return ajax.apply(this, arguments); 1255 | }; 1256 | } 1257 | })(jQuery); 1258 | 1259 | // provides cross-browser focusin and focusout events 1260 | // IE has native support, in other browsers, use event caputuring (neither bubbles) 1261 | 1262 | // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation 1263 | // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target 1264 | ;(function($) { 1265 | // only implement if not provided by jQuery core (since 1.4) 1266 | // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs 1267 | if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) { 1268 | $.each({ 1269 | focus: 'focusin', 1270 | blur: 'focusout' 1271 | }, function( original, fix ){ 1272 | $.event.special[fix] = { 1273 | setup:function() { 1274 | this.addEventListener( original, handler, true ); 1275 | }, 1276 | teardown:function() { 1277 | this.removeEventListener( original, handler, true ); 1278 | }, 1279 | handler: function(e) { 1280 | arguments[0] = $.event.fix(e); 1281 | arguments[0].type = fix; 1282 | return $.event.handle.apply(this, arguments); 1283 | } 1284 | }; 1285 | function handler(e) { 1286 | e = $.event.fix(e); 1287 | e.type = fix; 1288 | return $.event.handle.call(this, e); 1289 | } 1290 | }); 1291 | }; 1292 | $.extend($.fn, { 1293 | validateDelegate: function(delegate, type, handler) { 1294 | return this.bind(type, function(event) { 1295 | var target = $(event.target); 1296 | if (target.is(delegate)) { 1297 | return handler.apply(target, arguments); 1298 | } 1299 | }); 1300 | } 1301 | }); 1302 | })(jQuery); 1303 | -------------------------------------------------------------------------------- /MultipleFileUpload/Scripts/jquery.validate.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! 16 | * jQuery Validation Plugin 1.11.1 17 | * 18 | * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ 19 | * http://docs.jquery.com/Plugins/Validation 20 | * 21 | * Copyright 2013 Jörn Zaefferer 22 | * Released under the MIT license: 23 | * http://www.opensource.org/licenses/mit-license.php 24 | */ 25 | 26 | (function($) { 27 | 28 | $.extend($.fn, { 29 | // http://docs.jquery.com/Plugins/Validation/validate 30 | validate: function( options ) { 31 | 32 | // if nothing is selected, return nothing; can't chain anyway 33 | if ( !this.length ) { 34 | if ( options && options.debug && window.console ) { 35 | console.warn( "Nothing selected, can't validate, returning nothing." ); 36 | } 37 | return; 38 | } 39 | 40 | // check if a validator for this form was already created 41 | var validator = $.data( this[0], "validator" ); 42 | if ( validator ) { 43 | return validator; 44 | } 45 | 46 | // Add novalidate tag if HTML5. 47 | this.attr( "novalidate", "novalidate" ); 48 | 49 | validator = new $.validator( options, this[0] ); 50 | $.data( this[0], "validator", validator ); 51 | 52 | if ( validator.settings.onsubmit ) { 53 | 54 | this.validateDelegate( ":submit", "click", function( event ) { 55 | if ( validator.settings.submitHandler ) { 56 | validator.submitButton = event.target; 57 | } 58 | // allow suppressing validation by adding a cancel class to the submit button 59 | if ( $(event.target).hasClass("cancel") ) { 60 | validator.cancelSubmit = true; 61 | } 62 | 63 | // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 64 | if ( $(event.target).attr("formnovalidate") !== undefined ) { 65 | validator.cancelSubmit = true; 66 | } 67 | }); 68 | 69 | // validate the form on submit 70 | this.submit( function( event ) { 71 | if ( validator.settings.debug ) { 72 | // prevent form submit to be able to see console output 73 | event.preventDefault(); 74 | } 75 | function handle() { 76 | var hidden; 77 | if ( validator.settings.submitHandler ) { 78 | if ( validator.submitButton ) { 79 | // insert a hidden input as a replacement for the missing submit button 80 | hidden = $("").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm); 81 | } 82 | validator.settings.submitHandler.call( validator, validator.currentForm, event ); 83 | if ( validator.submitButton ) { 84 | // and clean up afterwards; thanks to no-block-scope, hidden can be referenced 85 | hidden.remove(); 86 | } 87 | return false; 88 | } 89 | return true; 90 | } 91 | 92 | // prevent submit for invalid forms or custom submit handlers 93 | if ( validator.cancelSubmit ) { 94 | validator.cancelSubmit = false; 95 | return handle(); 96 | } 97 | if ( validator.form() ) { 98 | if ( validator.pendingRequest ) { 99 | validator.formSubmitted = true; 100 | return false; 101 | } 102 | return handle(); 103 | } else { 104 | validator.focusInvalid(); 105 | return false; 106 | } 107 | }); 108 | } 109 | 110 | return validator; 111 | }, 112 | // http://docs.jquery.com/Plugins/Validation/valid 113 | valid: function() { 114 | if ( $(this[0]).is("form")) { 115 | return this.validate().form(); 116 | } else { 117 | var valid = true; 118 | var validator = $(this[0].form).validate(); 119 | this.each(function() { 120 | valid = valid && validator.element(this); 121 | }); 122 | return valid; 123 | } 124 | }, 125 | // attributes: space seperated list of attributes to retrieve and remove 126 | removeAttrs: function( attributes ) { 127 | var result = {}, 128 | $element = this; 129 | $.each(attributes.split(/\s/), function( index, value ) { 130 | result[value] = $element.attr(value); 131 | $element.removeAttr(value); 132 | }); 133 | return result; 134 | }, 135 | // http://docs.jquery.com/Plugins/Validation/rules 136 | rules: function( command, argument ) { 137 | var element = this[0]; 138 | 139 | if ( command ) { 140 | var settings = $.data(element.form, "validator").settings; 141 | var staticRules = settings.rules; 142 | var existingRules = $.validator.staticRules(element); 143 | switch(command) { 144 | case "add": 145 | $.extend(existingRules, $.validator.normalizeRule(argument)); 146 | // remove messages from rules, but allow them to be set separetely 147 | delete existingRules.messages; 148 | staticRules[element.name] = existingRules; 149 | if ( argument.messages ) { 150 | settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); 151 | } 152 | break; 153 | case "remove": 154 | if ( !argument ) { 155 | delete staticRules[element.name]; 156 | return existingRules; 157 | } 158 | var filtered = {}; 159 | $.each(argument.split(/\s/), function( index, method ) { 160 | filtered[method] = existingRules[method]; 161 | delete existingRules[method]; 162 | }); 163 | return filtered; 164 | } 165 | } 166 | 167 | var data = $.validator.normalizeRules( 168 | $.extend( 169 | {}, 170 | $.validator.classRules(element), 171 | $.validator.attributeRules(element), 172 | $.validator.dataRules(element), 173 | $.validator.staticRules(element) 174 | ), element); 175 | 176 | // make sure required is at front 177 | if ( data.required ) { 178 | var param = data.required; 179 | delete data.required; 180 | data = $.extend({required: param}, data); 181 | } 182 | 183 | return data; 184 | } 185 | }); 186 | 187 | // Custom selectors 188 | $.extend($.expr[":"], { 189 | // http://docs.jquery.com/Plugins/Validation/blank 190 | blank: function( a ) { return !$.trim("" + $(a).val()); }, 191 | // http://docs.jquery.com/Plugins/Validation/filled 192 | filled: function( a ) { return !!$.trim("" + $(a).val()); }, 193 | // http://docs.jquery.com/Plugins/Validation/unchecked 194 | unchecked: function( a ) { return !$(a).prop("checked"); } 195 | }); 196 | 197 | // constructor for validator 198 | $.validator = function( options, form ) { 199 | this.settings = $.extend( true, {}, $.validator.defaults, options ); 200 | this.currentForm = form; 201 | this.init(); 202 | }; 203 | 204 | $.validator.format = function( source, params ) { 205 | if ( arguments.length === 1 ) { 206 | return function() { 207 | var args = $.makeArray(arguments); 208 | args.unshift(source); 209 | return $.validator.format.apply( this, args ); 210 | }; 211 | } 212 | if ( arguments.length > 2 && params.constructor !== Array ) { 213 | params = $.makeArray(arguments).slice(1); 214 | } 215 | if ( params.constructor !== Array ) { 216 | params = [ params ]; 217 | } 218 | $.each(params, function( i, n ) { 219 | source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() { 220 | return n; 221 | }); 222 | }); 223 | return source; 224 | }; 225 | 226 | $.extend($.validator, { 227 | 228 | defaults: { 229 | messages: {}, 230 | groups: {}, 231 | rules: {}, 232 | errorClass: "error", 233 | validClass: "valid", 234 | errorElement: "label", 235 | focusInvalid: true, 236 | errorContainer: $([]), 237 | errorLabelContainer: $([]), 238 | onsubmit: true, 239 | ignore: ":hidden", 240 | ignoreTitle: false, 241 | onfocusin: function( element, event ) { 242 | this.lastActive = element; 243 | 244 | // hide error label and remove error class on focus if enabled 245 | if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { 246 | if ( this.settings.unhighlight ) { 247 | this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); 248 | } 249 | this.addWrapper(this.errorsFor(element)).hide(); 250 | } 251 | }, 252 | onfocusout: function( element, event ) { 253 | if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { 254 | this.element(element); 255 | } 256 | }, 257 | onkeyup: function( element, event ) { 258 | if ( event.which === 9 && this.elementValue(element) === "" ) { 259 | return; 260 | } else if ( element.name in this.submitted || element === this.lastElement ) { 261 | this.element(element); 262 | } 263 | }, 264 | onclick: function( element, event ) { 265 | // click on selects, radiobuttons and checkboxes 266 | if ( element.name in this.submitted ) { 267 | this.element(element); 268 | } 269 | // or option elements, check parent select in that case 270 | else if ( element.parentNode.name in this.submitted ) { 271 | this.element(element.parentNode); 272 | } 273 | }, 274 | highlight: function( element, errorClass, validClass ) { 275 | if ( element.type === "radio" ) { 276 | this.findByName(element.name).addClass(errorClass).removeClass(validClass); 277 | } else { 278 | $(element).addClass(errorClass).removeClass(validClass); 279 | } 280 | }, 281 | unhighlight: function( element, errorClass, validClass ) { 282 | if ( element.type === "radio" ) { 283 | this.findByName(element.name).removeClass(errorClass).addClass(validClass); 284 | } else { 285 | $(element).removeClass(errorClass).addClass(validClass); 286 | } 287 | } 288 | }, 289 | 290 | // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults 291 | setDefaults: function( settings ) { 292 | $.extend( $.validator.defaults, settings ); 293 | }, 294 | 295 | messages: { 296 | required: "This field is required.", 297 | remote: "Please fix this field.", 298 | email: "Please enter a valid email address.", 299 | url: "Please enter a valid URL.", 300 | date: "Please enter a valid date.", 301 | dateISO: "Please enter a valid date (ISO).", 302 | number: "Please enter a valid number.", 303 | digits: "Please enter only digits.", 304 | creditcard: "Please enter a valid credit card number.", 305 | equalTo: "Please enter the same value again.", 306 | maxlength: $.validator.format("Please enter no more than {0} characters."), 307 | minlength: $.validator.format("Please enter at least {0} characters."), 308 | rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), 309 | range: $.validator.format("Please enter a value between {0} and {1}."), 310 | max: $.validator.format("Please enter a value less than or equal to {0}."), 311 | min: $.validator.format("Please enter a value greater than or equal to {0}.") 312 | }, 313 | 314 | autoCreateRanges: false, 315 | 316 | prototype: { 317 | 318 | init: function() { 319 | this.labelContainer = $(this.settings.errorLabelContainer); 320 | this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); 321 | this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); 322 | this.submitted = {}; 323 | this.valueCache = {}; 324 | this.pendingRequest = 0; 325 | this.pending = {}; 326 | this.invalid = {}; 327 | this.reset(); 328 | 329 | var groups = (this.groups = {}); 330 | $.each(this.settings.groups, function( key, value ) { 331 | if ( typeof value === "string" ) { 332 | value = value.split(/\s/); 333 | } 334 | $.each(value, function( index, name ) { 335 | groups[name] = key; 336 | }); 337 | }); 338 | var rules = this.settings.rules; 339 | $.each(rules, function( key, value ) { 340 | rules[key] = $.validator.normalizeRule(value); 341 | }); 342 | 343 | function delegate(event) { 344 | var validator = $.data(this[0].form, "validator"), 345 | eventType = "on" + event.type.replace(/^validate/, ""); 346 | if ( validator.settings[eventType] ) { 347 | validator.settings[eventType].call(validator, this[0], event); 348 | } 349 | } 350 | $(this.currentForm) 351 | .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " + 352 | "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + 353 | "[type='email'], [type='datetime'], [type='date'], [type='month'], " + 354 | "[type='week'], [type='time'], [type='datetime-local'], " + 355 | "[type='range'], [type='color'] ", 356 | "focusin focusout keyup", delegate) 357 | .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); 358 | 359 | if ( this.settings.invalidHandler ) { 360 | $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); 361 | } 362 | }, 363 | 364 | // http://docs.jquery.com/Plugins/Validation/Validator/form 365 | form: function() { 366 | this.checkForm(); 367 | $.extend(this.submitted, this.errorMap); 368 | this.invalid = $.extend({}, this.errorMap); 369 | if ( !this.valid() ) { 370 | $(this.currentForm).triggerHandler("invalid-form", [this]); 371 | } 372 | this.showErrors(); 373 | return this.valid(); 374 | }, 375 | 376 | checkForm: function() { 377 | this.prepareForm(); 378 | for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { 379 | this.check( elements[i] ); 380 | } 381 | return this.valid(); 382 | }, 383 | 384 | // http://docs.jquery.com/Plugins/Validation/Validator/element 385 | element: function( element ) { 386 | element = this.validationTargetFor( this.clean( element ) ); 387 | this.lastElement = element; 388 | this.prepareElement( element ); 389 | this.currentElements = $(element); 390 | var result = this.check( element ) !== false; 391 | if ( result ) { 392 | delete this.invalid[element.name]; 393 | } else { 394 | this.invalid[element.name] = true; 395 | } 396 | if ( !this.numberOfInvalids() ) { 397 | // Hide error containers on last error 398 | this.toHide = this.toHide.add( this.containers ); 399 | } 400 | this.showErrors(); 401 | return result; 402 | }, 403 | 404 | // http://docs.jquery.com/Plugins/Validation/Validator/showErrors 405 | showErrors: function( errors ) { 406 | if ( errors ) { 407 | // add items to error list and map 408 | $.extend( this.errorMap, errors ); 409 | this.errorList = []; 410 | for ( var name in errors ) { 411 | this.errorList.push({ 412 | message: errors[name], 413 | element: this.findByName(name)[0] 414 | }); 415 | } 416 | // remove items from success list 417 | this.successList = $.grep( this.successList, function( element ) { 418 | return !(element.name in errors); 419 | }); 420 | } 421 | if ( this.settings.showErrors ) { 422 | this.settings.showErrors.call( this, this.errorMap, this.errorList ); 423 | } else { 424 | this.defaultShowErrors(); 425 | } 426 | }, 427 | 428 | // http://docs.jquery.com/Plugins/Validation/Validator/resetForm 429 | resetForm: function() { 430 | if ( $.fn.resetForm ) { 431 | $(this.currentForm).resetForm(); 432 | } 433 | this.submitted = {}; 434 | this.lastElement = null; 435 | this.prepareForm(); 436 | this.hideErrors(); 437 | this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" ); 438 | }, 439 | 440 | numberOfInvalids: function() { 441 | return this.objectLength(this.invalid); 442 | }, 443 | 444 | objectLength: function( obj ) { 445 | var count = 0; 446 | for ( var i in obj ) { 447 | count++; 448 | } 449 | return count; 450 | }, 451 | 452 | hideErrors: function() { 453 | this.addWrapper( this.toHide ).hide(); 454 | }, 455 | 456 | valid: function() { 457 | return this.size() === 0; 458 | }, 459 | 460 | size: function() { 461 | return this.errorList.length; 462 | }, 463 | 464 | focusInvalid: function() { 465 | if ( this.settings.focusInvalid ) { 466 | try { 467 | $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) 468 | .filter(":visible") 469 | .focus() 470 | // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 471 | .trigger("focusin"); 472 | } catch(e) { 473 | // ignore IE throwing errors when focusing hidden elements 474 | } 475 | } 476 | }, 477 | 478 | findLastActive: function() { 479 | var lastActive = this.lastActive; 480 | return lastActive && $.grep(this.errorList, function( n ) { 481 | return n.element.name === lastActive.name; 482 | }).length === 1 && lastActive; 483 | }, 484 | 485 | elements: function() { 486 | var validator = this, 487 | rulesCache = {}; 488 | 489 | // select all valid inputs inside the form (no submit or reset buttons) 490 | return $(this.currentForm) 491 | .find("input, select, textarea") 492 | .not(":submit, :reset, :image, [disabled]") 493 | .not( this.settings.ignore ) 494 | .filter(function() { 495 | if ( !this.name && validator.settings.debug && window.console ) { 496 | console.error( "%o has no name assigned", this); 497 | } 498 | 499 | // select only the first element for each name, and only those with rules specified 500 | if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) { 501 | return false; 502 | } 503 | 504 | rulesCache[this.name] = true; 505 | return true; 506 | }); 507 | }, 508 | 509 | clean: function( selector ) { 510 | return $(selector)[0]; 511 | }, 512 | 513 | errors: function() { 514 | var errorClass = this.settings.errorClass.replace(" ", "."); 515 | return $(this.settings.errorElement + "." + errorClass, this.errorContext); 516 | }, 517 | 518 | reset: function() { 519 | this.successList = []; 520 | this.errorList = []; 521 | this.errorMap = {}; 522 | this.toShow = $([]); 523 | this.toHide = $([]); 524 | this.currentElements = $([]); 525 | }, 526 | 527 | prepareForm: function() { 528 | this.reset(); 529 | this.toHide = this.errors().add( this.containers ); 530 | }, 531 | 532 | prepareElement: function( element ) { 533 | this.reset(); 534 | this.toHide = this.errorsFor(element); 535 | }, 536 | 537 | elementValue: function( element ) { 538 | var type = $(element).attr("type"), 539 | val = $(element).val(); 540 | 541 | if ( type === "radio" || type === "checkbox" ) { 542 | return $("input[name='" + $(element).attr("name") + "']:checked").val(); 543 | } 544 | 545 | if ( typeof val === "string" ) { 546 | return val.replace(/\r/g, ""); 547 | } 548 | return val; 549 | }, 550 | 551 | check: function( element ) { 552 | element = this.validationTargetFor( this.clean( element ) ); 553 | 554 | var rules = $(element).rules(); 555 | var dependencyMismatch = false; 556 | var val = this.elementValue(element); 557 | var result; 558 | 559 | for (var method in rules ) { 560 | var rule = { method: method, parameters: rules[method] }; 561 | try { 562 | 563 | result = $.validator.methods[method].call( this, val, element, rule.parameters ); 564 | 565 | // if a method indicates that the field is optional and therefore valid, 566 | // don't mark it as valid when there are no other rules 567 | if ( result === "dependency-mismatch" ) { 568 | dependencyMismatch = true; 569 | continue; 570 | } 571 | dependencyMismatch = false; 572 | 573 | if ( result === "pending" ) { 574 | this.toHide = this.toHide.not( this.errorsFor(element) ); 575 | return; 576 | } 577 | 578 | if ( !result ) { 579 | this.formatAndAdd( element, rule ); 580 | return false; 581 | } 582 | } catch(e) { 583 | if ( this.settings.debug && window.console ) { 584 | console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); 585 | } 586 | throw e; 587 | } 588 | } 589 | if ( dependencyMismatch ) { 590 | return; 591 | } 592 | if ( this.objectLength(rules) ) { 593 | this.successList.push(element); 594 | } 595 | return true; 596 | }, 597 | 598 | // return the custom message for the given element and validation method 599 | // specified in the element's HTML5 data attribute 600 | customDataMessage: function( element, method ) { 601 | return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase())); 602 | }, 603 | 604 | // return the custom message for the given element name and validation method 605 | customMessage: function( name, method ) { 606 | var m = this.settings.messages[name]; 607 | return m && (m.constructor === String ? m : m[method]); 608 | }, 609 | 610 | // return the first defined argument, allowing empty strings 611 | findDefined: function() { 612 | for(var i = 0; i < arguments.length; i++) { 613 | if ( arguments[i] !== undefined ) { 614 | return arguments[i]; 615 | } 616 | } 617 | return undefined; 618 | }, 619 | 620 | defaultMessage: function( element, method ) { 621 | return this.findDefined( 622 | this.customMessage( element.name, method ), 623 | this.customDataMessage( element, method ), 624 | // title is never undefined, so handle empty string as undefined 625 | !this.settings.ignoreTitle && element.title || undefined, 626 | $.validator.messages[method], 627 | "Warning: No message defined for " + element.name + "" 628 | ); 629 | }, 630 | 631 | formatAndAdd: function( element, rule ) { 632 | var message = this.defaultMessage( element, rule.method ), 633 | theregex = /\$?\{(\d+)\}/g; 634 | if ( typeof message === "function" ) { 635 | message = message.call(this, rule.parameters, element); 636 | } else if (theregex.test(message)) { 637 | message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); 638 | } 639 | this.errorList.push({ 640 | message: message, 641 | element: element 642 | }); 643 | 644 | this.errorMap[element.name] = message; 645 | this.submitted[element.name] = message; 646 | }, 647 | 648 | addWrapper: function( toToggle ) { 649 | if ( this.settings.wrapper ) { 650 | toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 651 | } 652 | return toToggle; 653 | }, 654 | 655 | defaultShowErrors: function() { 656 | var i, elements; 657 | for ( i = 0; this.errorList[i]; i++ ) { 658 | var error = this.errorList[i]; 659 | if ( this.settings.highlight ) { 660 | this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); 661 | } 662 | this.showLabel( error.element, error.message ); 663 | } 664 | if ( this.errorList.length ) { 665 | this.toShow = this.toShow.add( this.containers ); 666 | } 667 | if ( this.settings.success ) { 668 | for ( i = 0; this.successList[i]; i++ ) { 669 | this.showLabel( this.successList[i] ); 670 | } 671 | } 672 | if ( this.settings.unhighlight ) { 673 | for ( i = 0, elements = this.validElements(); elements[i]; i++ ) { 674 | this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass ); 675 | } 676 | } 677 | this.toHide = this.toHide.not( this.toShow ); 678 | this.hideErrors(); 679 | this.addWrapper( this.toShow ).show(); 680 | }, 681 | 682 | validElements: function() { 683 | return this.currentElements.not(this.invalidElements()); 684 | }, 685 | 686 | invalidElements: function() { 687 | return $(this.errorList).map(function() { 688 | return this.element; 689 | }); 690 | }, 691 | 692 | showLabel: function( element, message ) { 693 | var label = this.errorsFor( element ); 694 | if ( label.length ) { 695 | // refresh error/success class 696 | label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); 697 | // replace message on existing label 698 | label.html(message); 699 | } else { 700 | // create label 701 | label = $("<" + this.settings.errorElement + ">") 702 | .attr("for", this.idOrName(element)) 703 | .addClass(this.settings.errorClass) 704 | .html(message || ""); 705 | if ( this.settings.wrapper ) { 706 | // make sure the element is visible, even in IE 707 | // actually showing the wrapped element is handled elsewhere 708 | label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); 709 | } 710 | if ( !this.labelContainer.append(label).length ) { 711 | if ( this.settings.errorPlacement ) { 712 | this.settings.errorPlacement(label, $(element) ); 713 | } else { 714 | label.insertAfter(element); 715 | } 716 | } 717 | } 718 | if ( !message && this.settings.success ) { 719 | label.text(""); 720 | if ( typeof this.settings.success === "string" ) { 721 | label.addClass( this.settings.success ); 722 | } else { 723 | this.settings.success( label, element ); 724 | } 725 | } 726 | this.toShow = this.toShow.add(label); 727 | }, 728 | 729 | errorsFor: function( element ) { 730 | var name = this.idOrName(element); 731 | return this.errors().filter(function() { 732 | return $(this).attr("for") === name; 733 | }); 734 | }, 735 | 736 | idOrName: function( element ) { 737 | return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); 738 | }, 739 | 740 | validationTargetFor: function( element ) { 741 | // if radio/checkbox, validate first element in group instead 742 | if ( this.checkable(element) ) { 743 | element = this.findByName( element.name ).not(this.settings.ignore)[0]; 744 | } 745 | return element; 746 | }, 747 | 748 | checkable: function( element ) { 749 | return (/radio|checkbox/i).test(element.type); 750 | }, 751 | 752 | findByName: function( name ) { 753 | return $(this.currentForm).find("[name='" + name + "']"); 754 | }, 755 | 756 | getLength: function( value, element ) { 757 | switch( element.nodeName.toLowerCase() ) { 758 | case "select": 759 | return $("option:selected", element).length; 760 | case "input": 761 | if ( this.checkable( element) ) { 762 | return this.findByName(element.name).filter(":checked").length; 763 | } 764 | } 765 | return value.length; 766 | }, 767 | 768 | depend: function( param, element ) { 769 | return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; 770 | }, 771 | 772 | dependTypes: { 773 | "boolean": function( param, element ) { 774 | return param; 775 | }, 776 | "string": function( param, element ) { 777 | return !!$(param, element.form).length; 778 | }, 779 | "function": function( param, element ) { 780 | return param(element); 781 | } 782 | }, 783 | 784 | optional: function( element ) { 785 | var val = this.elementValue(element); 786 | return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; 787 | }, 788 | 789 | startRequest: function( element ) { 790 | if ( !this.pending[element.name] ) { 791 | this.pendingRequest++; 792 | this.pending[element.name] = true; 793 | } 794 | }, 795 | 796 | stopRequest: function( element, valid ) { 797 | this.pendingRequest--; 798 | // sometimes synchronization fails, make sure pendingRequest is never < 0 799 | if ( this.pendingRequest < 0 ) { 800 | this.pendingRequest = 0; 801 | } 802 | delete this.pending[element.name]; 803 | if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { 804 | $(this.currentForm).submit(); 805 | this.formSubmitted = false; 806 | } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { 807 | $(this.currentForm).triggerHandler("invalid-form", [this]); 808 | this.formSubmitted = false; 809 | } 810 | }, 811 | 812 | previousValue: function( element ) { 813 | return $.data(element, "previousValue") || $.data(element, "previousValue", { 814 | old: null, 815 | valid: true, 816 | message: this.defaultMessage( element, "remote" ) 817 | }); 818 | } 819 | 820 | }, 821 | 822 | classRuleSettings: { 823 | required: {required: true}, 824 | email: {email: true}, 825 | url: {url: true}, 826 | date: {date: true}, 827 | dateISO: {dateISO: true}, 828 | number: {number: true}, 829 | digits: {digits: true}, 830 | creditcard: {creditcard: true} 831 | }, 832 | 833 | addClassRules: function( className, rules ) { 834 | if ( className.constructor === String ) { 835 | this.classRuleSettings[className] = rules; 836 | } else { 837 | $.extend(this.classRuleSettings, className); 838 | } 839 | }, 840 | 841 | classRules: function( element ) { 842 | var rules = {}; 843 | var classes = $(element).attr("class"); 844 | if ( classes ) { 845 | $.each(classes.split(" "), function() { 846 | if ( this in $.validator.classRuleSettings ) { 847 | $.extend(rules, $.validator.classRuleSettings[this]); 848 | } 849 | }); 850 | } 851 | return rules; 852 | }, 853 | 854 | attributeRules: function( element ) { 855 | var rules = {}; 856 | var $element = $(element); 857 | var type = $element[0].getAttribute("type"); 858 | 859 | for (var method in $.validator.methods) { 860 | var value; 861 | 862 | // support for in both html5 and older browsers 863 | if ( method === "required" ) { 864 | value = $element.get(0).getAttribute(method); 865 | // Some browsers return an empty string for the required attribute 866 | // and non-HTML5 browsers might have required="" markup 867 | if ( value === "" ) { 868 | value = true; 869 | } 870 | // force non-HTML5 browsers to return bool 871 | value = !!value; 872 | } else { 873 | value = $element.attr(method); 874 | } 875 | 876 | // convert the value to a number for number inputs, and for text for backwards compability 877 | // allows type="date" and others to be compared as strings 878 | if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { 879 | value = Number(value); 880 | } 881 | 882 | if ( value ) { 883 | rules[method] = value; 884 | } else if ( type === method && type !== 'range' ) { 885 | // exception: the jquery validate 'range' method 886 | // does not test for the html5 'range' type 887 | rules[method] = true; 888 | } 889 | } 890 | 891 | // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs 892 | if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) { 893 | delete rules.maxlength; 894 | } 895 | 896 | return rules; 897 | }, 898 | 899 | dataRules: function( element ) { 900 | var method, value, 901 | rules = {}, $element = $(element); 902 | for (method in $.validator.methods) { 903 | value = $element.data("rule-" + method.toLowerCase()); 904 | if ( value !== undefined ) { 905 | rules[method] = value; 906 | } 907 | } 908 | return rules; 909 | }, 910 | 911 | staticRules: function( element ) { 912 | var rules = {}; 913 | var validator = $.data(element.form, "validator"); 914 | if ( validator.settings.rules ) { 915 | rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; 916 | } 917 | return rules; 918 | }, 919 | 920 | normalizeRules: function( rules, element ) { 921 | // handle dependency check 922 | $.each(rules, function( prop, val ) { 923 | // ignore rule when param is explicitly false, eg. required:false 924 | if ( val === false ) { 925 | delete rules[prop]; 926 | return; 927 | } 928 | if ( val.param || val.depends ) { 929 | var keepRule = true; 930 | switch (typeof val.depends) { 931 | case "string": 932 | keepRule = !!$(val.depends, element.form).length; 933 | break; 934 | case "function": 935 | keepRule = val.depends.call(element, element); 936 | break; 937 | } 938 | if ( keepRule ) { 939 | rules[prop] = val.param !== undefined ? val.param : true; 940 | } else { 941 | delete rules[prop]; 942 | } 943 | } 944 | }); 945 | 946 | // evaluate parameters 947 | $.each(rules, function( rule, parameter ) { 948 | rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; 949 | }); 950 | 951 | // clean number parameters 952 | $.each(['minlength', 'maxlength'], function() { 953 | if ( rules[this] ) { 954 | rules[this] = Number(rules[this]); 955 | } 956 | }); 957 | $.each(['rangelength', 'range'], function() { 958 | var parts; 959 | if ( rules[this] ) { 960 | if ( $.isArray(rules[this]) ) { 961 | rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; 962 | } else if ( typeof rules[this] === "string" ) { 963 | parts = rules[this].split(/[\s,]+/); 964 | rules[this] = [Number(parts[0]), Number(parts[1])]; 965 | } 966 | } 967 | }); 968 | 969 | if ( $.validator.autoCreateRanges ) { 970 | // auto-create ranges 971 | if ( rules.min && rules.max ) { 972 | rules.range = [rules.min, rules.max]; 973 | delete rules.min; 974 | delete rules.max; 975 | } 976 | if ( rules.minlength && rules.maxlength ) { 977 | rules.rangelength = [rules.minlength, rules.maxlength]; 978 | delete rules.minlength; 979 | delete rules.maxlength; 980 | } 981 | } 982 | 983 | return rules; 984 | }, 985 | 986 | // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 987 | normalizeRule: function( data ) { 988 | if ( typeof data === "string" ) { 989 | var transformed = {}; 990 | $.each(data.split(/\s/), function() { 991 | transformed[this] = true; 992 | }); 993 | data = transformed; 994 | } 995 | return data; 996 | }, 997 | 998 | // http://docs.jquery.com/Plugins/Validation/Validator/addMethod 999 | addMethod: function( name, method, message ) { 1000 | $.validator.methods[name] = method; 1001 | $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; 1002 | if ( method.length < 3 ) { 1003 | $.validator.addClassRules(name, $.validator.normalizeRule(name)); 1004 | } 1005 | }, 1006 | 1007 | methods: { 1008 | 1009 | // http://docs.jquery.com/Plugins/Validation/Methods/required 1010 | required: function( value, element, param ) { 1011 | // check if dependency is met 1012 | if ( !this.depend(param, element) ) { 1013 | return "dependency-mismatch"; 1014 | } 1015 | if ( element.nodeName.toLowerCase() === "select" ) { 1016 | // could be an array for select-multiple or a string, both are fine this way 1017 | var val = $(element).val(); 1018 | return val && val.length > 0; 1019 | } 1020 | if ( this.checkable(element) ) { 1021 | return this.getLength(value, element) > 0; 1022 | } 1023 | return $.trim(value).length > 0; 1024 | }, 1025 | 1026 | // http://docs.jquery.com/Plugins/Validation/Methods/email 1027 | email: function( value, element ) { 1028 | // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ 1029 | return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); 1030 | }, 1031 | 1032 | // http://docs.jquery.com/Plugins/Validation/Methods/url 1033 | url: function( value, element ) { 1034 | // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ 1035 | return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); 1036 | }, 1037 | 1038 | // http://docs.jquery.com/Plugins/Validation/Methods/date 1039 | date: function( value, element ) { 1040 | return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); 1041 | }, 1042 | 1043 | // http://docs.jquery.com/Plugins/Validation/Methods/dateISO 1044 | dateISO: function( value, element ) { 1045 | return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); 1046 | }, 1047 | 1048 | // http://docs.jquery.com/Plugins/Validation/Methods/number 1049 | number: function( value, element ) { 1050 | return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); 1051 | }, 1052 | 1053 | // http://docs.jquery.com/Plugins/Validation/Methods/digits 1054 | digits: function( value, element ) { 1055 | return this.optional(element) || /^\d+$/.test(value); 1056 | }, 1057 | 1058 | // http://docs.jquery.com/Plugins/Validation/Methods/creditcard 1059 | // based on http://en.wikipedia.org/wiki/Luhn 1060 | creditcard: function( value, element ) { 1061 | if ( this.optional(element) ) { 1062 | return "dependency-mismatch"; 1063 | } 1064 | // accept only spaces, digits and dashes 1065 | if ( /[^0-9 \-]+/.test(value) ) { 1066 | return false; 1067 | } 1068 | var nCheck = 0, 1069 | nDigit = 0, 1070 | bEven = false; 1071 | 1072 | value = value.replace(/\D/g, ""); 1073 | 1074 | for (var n = value.length - 1; n >= 0; n--) { 1075 | var cDigit = value.charAt(n); 1076 | nDigit = parseInt(cDigit, 10); 1077 | if ( bEven ) { 1078 | if ( (nDigit *= 2) > 9 ) { 1079 | nDigit -= 9; 1080 | } 1081 | } 1082 | nCheck += nDigit; 1083 | bEven = !bEven; 1084 | } 1085 | 1086 | return (nCheck % 10) === 0; 1087 | }, 1088 | 1089 | // http://docs.jquery.com/Plugins/Validation/Methods/minlength 1090 | minlength: function( value, element, param ) { 1091 | var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); 1092 | return this.optional(element) || length >= param; 1093 | }, 1094 | 1095 | // http://docs.jquery.com/Plugins/Validation/Methods/maxlength 1096 | maxlength: function( value, element, param ) { 1097 | var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); 1098 | return this.optional(element) || length <= param; 1099 | }, 1100 | 1101 | // http://docs.jquery.com/Plugins/Validation/Methods/rangelength 1102 | rangelength: function( value, element, param ) { 1103 | var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); 1104 | return this.optional(element) || ( length >= param[0] && length <= param[1] ); 1105 | }, 1106 | 1107 | // http://docs.jquery.com/Plugins/Validation/Methods/min 1108 | min: function( value, element, param ) { 1109 | return this.optional(element) || value >= param; 1110 | }, 1111 | 1112 | // http://docs.jquery.com/Plugins/Validation/Methods/max 1113 | max: function( value, element, param ) { 1114 | return this.optional(element) || value <= param; 1115 | }, 1116 | 1117 | // http://docs.jquery.com/Plugins/Validation/Methods/range 1118 | range: function( value, element, param ) { 1119 | return this.optional(element) || ( value >= param[0] && value <= param[1] ); 1120 | }, 1121 | 1122 | // http://docs.jquery.com/Plugins/Validation/Methods/equalTo 1123 | equalTo: function( value, element, param ) { 1124 | // bind to the blur event of the target in order to revalidate whenever the target field is updated 1125 | // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 1126 | var target = $(param); 1127 | if ( this.settings.onfocusout ) { 1128 | target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { 1129 | $(element).valid(); 1130 | }); 1131 | } 1132 | return value === target.val(); 1133 | }, 1134 | 1135 | // http://docs.jquery.com/Plugins/Validation/Methods/remote 1136 | remote: function( value, element, param ) { 1137 | if ( this.optional(element) ) { 1138 | return "dependency-mismatch"; 1139 | } 1140 | 1141 | var previous = this.previousValue(element); 1142 | if (!this.settings.messages[element.name] ) { 1143 | this.settings.messages[element.name] = {}; 1144 | } 1145 | previous.originalMessage = this.settings.messages[element.name].remote; 1146 | this.settings.messages[element.name].remote = previous.message; 1147 | 1148 | param = typeof param === "string" && {url:param} || param; 1149 | 1150 | if ( previous.old === value ) { 1151 | return previous.valid; 1152 | } 1153 | 1154 | previous.old = value; 1155 | var validator = this; 1156 | this.startRequest(element); 1157 | var data = {}; 1158 | data[element.name] = value; 1159 | $.ajax($.extend(true, { 1160 | url: param, 1161 | mode: "abort", 1162 | port: "validate" + element.name, 1163 | dataType: "json", 1164 | data: data, 1165 | success: function( response ) { 1166 | validator.settings.messages[element.name].remote = previous.originalMessage; 1167 | var valid = response === true || response === "true"; 1168 | if ( valid ) { 1169 | var submitted = validator.formSubmitted; 1170 | validator.prepareElement(element); 1171 | validator.formSubmitted = submitted; 1172 | validator.successList.push(element); 1173 | delete validator.invalid[element.name]; 1174 | validator.showErrors(); 1175 | } else { 1176 | var errors = {}; 1177 | var message = response || validator.defaultMessage( element, "remote" ); 1178 | errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; 1179 | validator.invalid[element.name] = true; 1180 | validator.showErrors(errors); 1181 | } 1182 | previous.valid = valid; 1183 | validator.stopRequest(element, valid); 1184 | } 1185 | }, param)); 1186 | return "pending"; 1187 | } 1188 | 1189 | } 1190 | 1191 | }); 1192 | 1193 | // deprecated, use $.validator.format instead 1194 | $.format = $.validator.format; 1195 | 1196 | }(jQuery)); 1197 | 1198 | // ajax mode: abort 1199 | // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 1200 | // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 1201 | (function($) { 1202 | var pendingRequests = {}; 1203 | // Use a prefilter if available (1.5+) 1204 | if ( $.ajaxPrefilter ) { 1205 | $.ajaxPrefilter(function( settings, _, xhr ) { 1206 | var port = settings.port; 1207 | if ( settings.mode === "abort" ) { 1208 | if ( pendingRequests[port] ) { 1209 | pendingRequests[port].abort(); 1210 | } 1211 | pendingRequests[port] = xhr; 1212 | } 1213 | }); 1214 | } else { 1215 | // Proxy ajax 1216 | var ajax = $.ajax; 1217 | $.ajax = function( settings ) { 1218 | var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 1219 | port = ( "port" in settings ? settings : $.ajaxSettings ).port; 1220 | if ( mode === "abort" ) { 1221 | if ( pendingRequests[port] ) { 1222 | pendingRequests[port].abort(); 1223 | } 1224 | pendingRequests[port] = ajax.apply(this, arguments); 1225 | return pendingRequests[port]; 1226 | } 1227 | return ajax.apply(this, arguments); 1228 | }; 1229 | } 1230 | }(jQuery)); 1231 | 1232 | // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation 1233 | // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target 1234 | (function($) { 1235 | $.extend($.fn, { 1236 | validateDelegate: function( delegate, type, handler ) { 1237 | return this.bind(type, function( event ) { 1238 | var target = $(event.target); 1239 | if ( target.is(delegate) ) { 1240 | return handler.apply(target, arguments); 1241 | } 1242 | }); 1243 | } 1244 | }); 1245 | }(jQuery)); 1246 | -------------------------------------------------------------------------------- /MultipleFileUpload/Scripts/jquery.validate.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! jQuery Validation Plugin - v1.11.1 - 3/22/2013\n* https://github.com/jzaefferer/jquery-validation 16 | * Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */(function(t){t.extend(t.fn,{validate:function(e){if(!this.length)return e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."),void 0;var i=t.data(this[0],"validator");return i?i:(this.attr("novalidate","novalidate"),i=new t.validator(e,this[0]),t.data(this[0],"validator",i),i.settings.onsubmit&&(this.validateDelegate(":submit","click",function(e){i.settings.submitHandler&&(i.submitButton=e.target),t(e.target).hasClass("cancel")&&(i.cancelSubmit=!0),void 0!==t(e.target).attr("formnovalidate")&&(i.cancelSubmit=!0)}),this.submit(function(e){function s(){var s;return i.settings.submitHandler?(i.submitButton&&(s=t("").attr("name",i.submitButton.name).val(t(i.submitButton).val()).appendTo(i.currentForm)),i.settings.submitHandler.call(i,i.currentForm,e),i.submitButton&&s.remove(),!1):!0}return i.settings.debug&&e.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,s()):i.form()?i.pendingRequest?(i.formSubmitted=!0,!1):s():(i.focusInvalid(),!1)})),i)},valid:function(){if(t(this[0]).is("form"))return this.validate().form();var e=!0,i=t(this[0].form).validate();return this.each(function(){e=e&&i.element(this)}),e},removeAttrs:function(e){var i={},s=this;return t.each(e.split(/\s/),function(t,e){i[e]=s.attr(e),s.removeAttr(e)}),i},rules:function(e,i){var s=this[0];if(e){var r=t.data(s.form,"validator").settings,n=r.rules,a=t.validator.staticRules(s);switch(e){case"add":t.extend(a,t.validator.normalizeRule(i)),delete a.messages,n[s.name]=a,i.messages&&(r.messages[s.name]=t.extend(r.messages[s.name],i.messages));break;case"remove":if(!i)return delete n[s.name],a;var u={};return t.each(i.split(/\s/),function(t,e){u[e]=a[e],delete a[e]}),u}}var o=t.validator.normalizeRules(t.extend({},t.validator.classRules(s),t.validator.attributeRules(s),t.validator.dataRules(s),t.validator.staticRules(s)),s);if(o.required){var l=o.required;delete o.required,o=t.extend({required:l},o)}return o}}),t.extend(t.expr[":"],{blank:function(e){return!t.trim(""+t(e).val())},filled:function(e){return!!t.trim(""+t(e).val())},unchecked:function(e){return!t(e).prop("checked")}}),t.validator=function(e,i){this.settings=t.extend(!0,{},t.validator.defaults,e),this.currentForm=i,this.init()},t.validator.format=function(e,i){return 1===arguments.length?function(){var i=t.makeArray(arguments);return i.unshift(e),t.validator.format.apply(this,i)}:(arguments.length>2&&i.constructor!==Array&&(i=t.makeArray(arguments).slice(1)),i.constructor!==Array&&(i=[i]),t.each(i,function(t,i){e=e.replace(RegExp("\\{"+t+"\\}","g"),function(){return i})}),e)},t.extend(t.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:t([]),errorLabelContainer:t([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(t){this.lastActive=t,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,t,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(t)).hide())},onfocusout:function(t){this.checkable(t)||!(t.name in this.submitted)&&this.optional(t)||this.element(t)},onkeyup:function(t,e){(9!==e.which||""!==this.elementValue(t))&&(t.name in this.submitted||t===this.lastElement)&&this.element(t)},onclick:function(t){t.name in this.submitted?this.element(t):t.parentNode.name in this.submitted&&this.element(t.parentNode)},highlight:function(e,i,s){"radio"===e.type?this.findByName(e.name).addClass(i).removeClass(s):t(e).addClass(i).removeClass(s)},unhighlight:function(e,i,s){"radio"===e.type?this.findByName(e.name).removeClass(i).addClass(s):t(e).removeClass(i).addClass(s)}},setDefaults:function(e){t.extend(t.validator.defaults,e)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:t.validator.format("Please enter no more than {0} characters."),minlength:t.validator.format("Please enter at least {0} characters."),rangelength:t.validator.format("Please enter a value between {0} and {1} characters long."),range:t.validator.format("Please enter a value between {0} and {1}."),max:t.validator.format("Please enter a value less than or equal to {0}."),min:t.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function e(e){var i=t.data(this[0].form,"validator"),s="on"+e.type.replace(/^validate/,"");i.settings[s]&&i.settings[s].call(i,this[0],e)}this.labelContainer=t(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||t(this.currentForm),this.containers=t(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var i=this.groups={};t.each(this.settings.groups,function(e,s){"string"==typeof s&&(s=s.split(/\s/)),t.each(s,function(t,s){i[s]=e})});var s=this.settings.rules;t.each(s,function(e,i){s[e]=t.validator.normalizeRule(i)}),t(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",e).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",e),this.settings.invalidHandler&&t(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),t.extend(this.submitted,this.errorMap),this.invalid=t.extend({},this.errorMap),this.valid()||t(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var t=0,e=this.currentElements=this.elements();e[t];t++)this.check(e[t]);return this.valid()},element:function(e){e=this.validationTargetFor(this.clean(e)),this.lastElement=e,this.prepareElement(e),this.currentElements=t(e);var i=this.check(e)!==!1;return i?delete this.invalid[e.name]:this.invalid[e.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),i},showErrors:function(e){if(e){t.extend(this.errorMap,e),this.errorList=[];for(var i in e)this.errorList.push({message:e[i],element:this.findByName(i)[0]});this.successList=t.grep(this.successList,function(t){return!(t.name in e)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){t.fn.resetForm&&t(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(t){var e=0;for(var i in t)e++;return e},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{t(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(e){}},findLastActive:function(){var e=this.lastActive;return e&&1===t.grep(this.errorList,function(t){return t.element.name===e.name}).length&&e},elements:function(){var e=this,i={};return t(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&e.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in i||!e.objectLength(t(this).rules())?!1:(i[this.name]=!0,!0)})},clean:function(e){return t(e)[0]},errors:function(){var e=this.settings.errorClass.replace(" ",".");return t(this.settings.errorElement+"."+e,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=t([]),this.toHide=t([]),this.currentElements=t([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(t){this.reset(),this.toHide=this.errorsFor(t)},elementValue:function(e){var i=t(e).attr("type"),s=t(e).val();return"radio"===i||"checkbox"===i?t("input[name='"+t(e).attr("name")+"']:checked").val():"string"==typeof s?s.replace(/\r/g,""):s},check:function(e){e=this.validationTargetFor(this.clean(e));var i,s=t(e).rules(),r=!1,n=this.elementValue(e);for(var a in s){var u={method:a,parameters:s[a]};try{if(i=t.validator.methods[a].call(this,n,e,u.parameters),"dependency-mismatch"===i){r=!0;continue}if(r=!1,"pending"===i)return this.toHide=this.toHide.not(this.errorsFor(e)),void 0;if(!i)return this.formatAndAdd(e,u),!1}catch(o){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+e.id+", check the '"+u.method+"' method.",o),o}}return r?void 0:(this.objectLength(s)&&this.successList.push(e),!0)},customDataMessage:function(e,i){return t(e).data("msg-"+i.toLowerCase())||e.attributes&&t(e).attr("data-msg-"+i.toLowerCase())},customMessage:function(t,e){var i=this.settings.messages[t];return i&&(i.constructor===String?i:i[e])},findDefined:function(){for(var t=0;arguments.length>t;t++)if(void 0!==arguments[t])return arguments[t];return void 0},defaultMessage:function(e,i){return this.findDefined(this.customMessage(e.name,i),this.customDataMessage(e,i),!this.settings.ignoreTitle&&e.title||void 0,t.validator.messages[i],"Warning: No message defined for "+e.name+"")},formatAndAdd:function(e,i){var s=this.defaultMessage(e,i.method),r=/\$?\{(\d+)\}/g;"function"==typeof s?s=s.call(this,i.parameters,e):r.test(s)&&(s=t.validator.format(s.replace(r,"{$1}"),i.parameters)),this.errorList.push({message:s,element:e}),this.errorMap[e.name]=s,this.submitted[e.name]=s},addWrapper:function(t){return this.settings.wrapper&&(t=t.add(t.parent(this.settings.wrapper))),t},defaultShowErrors:function(){var t,e;for(t=0;this.errorList[t];t++){var i=this.errorList[t];this.settings.highlight&&this.settings.highlight.call(this,i.element,this.settings.errorClass,this.settings.validClass),this.showLabel(i.element,i.message)}if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(t=0;this.successList[t];t++)this.showLabel(this.successList[t]);if(this.settings.unhighlight)for(t=0,e=this.validElements();e[t];t++)this.settings.unhighlight.call(this,e[t],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return t(this.errorList).map(function(){return this.element})},showLabel:function(e,i){var s=this.errorsFor(e);s.length?(s.removeClass(this.settings.validClass).addClass(this.settings.errorClass),s.html(i)):(s=t("<"+this.settings.errorElement+">").attr("for",this.idOrName(e)).addClass(this.settings.errorClass).html(i||""),this.settings.wrapper&&(s=s.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.append(s).length||(this.settings.errorPlacement?this.settings.errorPlacement(s,t(e)):s.insertAfter(e))),!i&&this.settings.success&&(s.text(""),"string"==typeof this.settings.success?s.addClass(this.settings.success):this.settings.success(s,e)),this.toShow=this.toShow.add(s)},errorsFor:function(e){var i=this.idOrName(e);return this.errors().filter(function(){return t(this).attr("for")===i})},idOrName:function(t){return this.groups[t.name]||(this.checkable(t)?t.name:t.id||t.name)},validationTargetFor:function(t){return this.checkable(t)&&(t=this.findByName(t.name).not(this.settings.ignore)[0]),t},checkable:function(t){return/radio|checkbox/i.test(t.type)},findByName:function(e){return t(this.currentForm).find("[name='"+e+"']")},getLength:function(e,i){switch(i.nodeName.toLowerCase()){case"select":return t("option:selected",i).length;case"input":if(this.checkable(i))return this.findByName(i.name).filter(":checked").length}return e.length},depend:function(t,e){return this.dependTypes[typeof t]?this.dependTypes[typeof t](t,e):!0},dependTypes:{"boolean":function(t){return t},string:function(e,i){return!!t(e,i.form).length},"function":function(t,e){return t(e)}},optional:function(e){var i=this.elementValue(e);return!t.validator.methods.required.call(this,i,e)&&"dependency-mismatch"},startRequest:function(t){this.pending[t.name]||(this.pendingRequest++,this.pending[t.name]=!0)},stopRequest:function(e,i){this.pendingRequest--,0>this.pendingRequest&&(this.pendingRequest=0),delete this.pending[e.name],i&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(t(this.currentForm).submit(),this.formSubmitted=!1):!i&&0===this.pendingRequest&&this.formSubmitted&&(t(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e){return t.data(e,"previousValue")||t.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(e,i){e.constructor===String?this.classRuleSettings[e]=i:t.extend(this.classRuleSettings,e)},classRules:function(e){var i={},s=t(e).attr("class");return s&&t.each(s.split(" "),function(){this in t.validator.classRuleSettings&&t.extend(i,t.validator.classRuleSettings[this])}),i},attributeRules:function(e){var i={},s=t(e),r=s[0].getAttribute("type");for(var n in t.validator.methods){var a;"required"===n?(a=s.get(0).getAttribute(n),""===a&&(a=!0),a=!!a):a=s.attr(n),/min|max/.test(n)&&(null===r||/number|range|text/.test(r))&&(a=Number(a)),a?i[n]=a:r===n&&"range"!==r&&(i[n]=!0)}return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var i,s,r={},n=t(e);for(i in t.validator.methods)s=n.data("rule-"+i.toLowerCase()),void 0!==s&&(r[i]=s);return r},staticRules:function(e){var i={},s=t.data(e.form,"validator");return s.settings.rules&&(i=t.validator.normalizeRule(s.settings.rules[e.name])||{}),i},normalizeRules:function(e,i){return t.each(e,function(s,r){if(r===!1)return delete e[s],void 0;if(r.param||r.depends){var n=!0;switch(typeof r.depends){case"string":n=!!t(r.depends,i.form).length;break;case"function":n=r.depends.call(i,i)}n?e[s]=void 0!==r.param?r.param:!0:delete e[s]}}),t.each(e,function(s,r){e[s]=t.isFunction(r)?r(i):r}),t.each(["minlength","maxlength"],function(){e[this]&&(e[this]=Number(e[this]))}),t.each(["rangelength","range"],function(){var i;e[this]&&(t.isArray(e[this])?e[this]=[Number(e[this][0]),Number(e[this][1])]:"string"==typeof e[this]&&(i=e[this].split(/[\s,]+/),e[this]=[Number(i[0]),Number(i[1])]))}),t.validator.autoCreateRanges&&(e.min&&e.max&&(e.range=[e.min,e.max],delete e.min,delete e.max),e.minlength&&e.maxlength&&(e.rangelength=[e.minlength,e.maxlength],delete e.minlength,delete e.maxlength)),e},normalizeRule:function(e){if("string"==typeof e){var i={};t.each(e.split(/\s/),function(){i[this]=!0}),e=i}return e},addMethod:function(e,i,s){t.validator.methods[e]=i,t.validator.messages[e]=void 0!==s?s:t.validator.messages[e],3>i.length&&t.validator.addClassRules(e,t.validator.normalizeRule(e))},methods:{required:function(e,i,s){if(!this.depend(s,i))return"dependency-mismatch";if("select"===i.nodeName.toLowerCase()){var r=t(i).val();return r&&r.length>0}return this.checkable(i)?this.getLength(e,i)>0:t.trim(e).length>0},email:function(t,e){return this.optional(e)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(t)},url:function(t,e){return this.optional(e)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(t)},date:function(t,e){return this.optional(e)||!/Invalid|NaN/.test(""+new Date(t))},dateISO:function(t,e){return this.optional(e)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(t)},number:function(t,e){return this.optional(e)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(t)},digits:function(t,e){return this.optional(e)||/^\d+$/.test(t)},creditcard:function(t,e){if(this.optional(e))return"dependency-mismatch";if(/[^0-9 \-]+/.test(t))return!1;var i=0,s=0,r=!1;t=t.replace(/\D/g,"");for(var n=t.length-1;n>=0;n--){var a=t.charAt(n);s=parseInt(a,10),r&&(s*=2)>9&&(s-=9),i+=s,r=!r}return 0===i%10},minlength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||r>=s},maxlength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||s>=r},rangelength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||r>=s[0]&&s[1]>=r},min:function(t,e,i){return this.optional(e)||t>=i},max:function(t,e,i){return this.optional(e)||i>=t},range:function(t,e,i){return this.optional(e)||t>=i[0]&&i[1]>=t},equalTo:function(e,i,s){var r=t(s);return this.settings.onfocusout&&r.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){t(i).valid()}),e===r.val()},remote:function(e,i,s){if(this.optional(i))return"dependency-mismatch";var r=this.previousValue(i);if(this.settings.messages[i.name]||(this.settings.messages[i.name]={}),r.originalMessage=this.settings.messages[i.name].remote,this.settings.messages[i.name].remote=r.message,s="string"==typeof s&&{url:s}||s,r.old===e)return r.valid;r.old=e;var n=this;this.startRequest(i);var a={};return a[i.name]=e,t.ajax(t.extend(!0,{url:s,mode:"abort",port:"validate"+i.name,dataType:"json",data:a,success:function(s){n.settings.messages[i.name].remote=r.originalMessage;var a=s===!0||"true"===s;if(a){var u=n.formSubmitted;n.prepareElement(i),n.formSubmitted=u,n.successList.push(i),delete n.invalid[i.name],n.showErrors()}else{var o={},l=s||n.defaultMessage(i,"remote");o[i.name]=r.message=t.isFunction(l)?l(e):l,n.invalid[i.name]=!0,n.showErrors(o)}r.valid=a,n.stopRequest(i,a)}},s)),"pending"}}}),t.format=t.validator.format})(jQuery),function(t){var e={};if(t.ajaxPrefilter)t.ajaxPrefilter(function(t,i,s){var r=t.port;"abort"===t.mode&&(e[r]&&e[r].abort(),e[r]=s)});else{var i=t.ajax;t.ajax=function(s){var r=("mode"in s?s:t.ajaxSettings).mode,n=("port"in s?s:t.ajaxSettings).port;return"abort"===r?(e[n]&&e[n].abort(),e[n]=i.apply(this,arguments),e[n]):i.apply(this,arguments)}}}(jQuery),function(t){t.extend(t.fn,{validateDelegate:function(e,i,s){return this.bind(i,function(i){var r=t(i.target);return r.is(e)?s.apply(r,arguments):void 0})}})}(jQuery); -------------------------------------------------------------------------------- /MultipleFileUpload/Scripts/jquery.validate.unobtrusive.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ 20 | /*global document: false, jQuery: false */ 21 | (function ($) { 22 | var $jQval = $.validator, 23 | adapters, 24 | data_validation = "unobtrusiveValidation"; 25 | function setValidationValues(options, ruleName, value) { 26 | options.rules[ruleName] = value; 27 | if (options.message) { 28 | options.messages[ruleName] = options.message; 29 | } 30 | } 31 | function splitAndTrim(value) { 32 | return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); 33 | } 34 | function escapeAttributeValue(value) { 35 | // As mentioned on http://api.jquery.com/category/selectors/ 36 | return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); 37 | } 38 | function getModelPrefix(fieldName) { 39 | return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); 40 | } 41 | function appendModelPrefix(value, prefix) { 42 | if (value.indexOf("*.") === 0) { 43 | value = value.replace("*.", prefix); 44 | } 45 | return value; 46 | } 47 | function onError(error, inputElement) { // 'this' is the form element 48 | var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), 49 | replaceAttrValue = container.attr("data-valmsg-replace"), 50 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; 51 | container.removeClass("field-validation-valid").addClass("field-validation-error"); 52 | error.data("unobtrusiveContainer", container); 53 | if (replace) { 54 | container.empty(); 55 | error.removeClass("input-validation-error").appendTo(container); 56 | } 57 | else { 58 | error.hide(); 59 | } 60 | } 61 | function onErrors(event, validator) { // 'this' is the form element 62 | var container = $(this).find("[data-valmsg-summary=true]"), 63 | list = container.find("ul"); 64 | if (list && list.length && validator.errorList.length) { 65 | list.empty(); 66 | container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 67 | $.each(validator.errorList, function () { 68 | $("
  • ").html(this.message).appendTo(list); 69 | }); 70 | } 71 | } 72 | function onSuccess(error) { // 'this' is the form element 73 | var container = error.data("unobtrusiveContainer"), 74 | replaceAttrValue = container.attr("data-valmsg-replace"), 75 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; 76 | if (container) { 77 | container.addClass("field-validation-valid").removeClass("field-validation-error"); 78 | error.removeData("unobtrusiveContainer"); 79 | if (replace) { 80 | container.empty(); 81 | } 82 | } 83 | } 84 | function onReset(event) { // 'this' is the form element 85 | var $form = $(this); 86 | $form.data("validator").resetForm(); 87 | $form.find(".validation-summary-errors") 88 | .addClass("validation-summary-valid") 89 | .removeClass("validation-summary-errors"); 90 | $form.find(".field-validation-error") 91 | .addClass("field-validation-valid") 92 | .removeClass("field-validation-error") 93 | .removeData("unobtrusiveContainer") 94 | .find(">*") // If we were using valmsg-replace, get the underlying error 95 | .removeData("unobtrusiveContainer"); 96 | } 97 | function validationInfo(form) { 98 | var $form = $(form), 99 | result = $form.data(data_validation), 100 | onResetProxy = $.proxy(onReset, form); 101 | if (!result) { 102 | result = { 103 | options: { // options structure passed to jQuery Validate's validate() method 104 | errorClass: "input-validation-error", 105 | errorElement: "span", 106 | errorPlacement: $.proxy(onError, form), 107 | invalidHandler: $.proxy(onErrors, form), 108 | messages: {}, 109 | rules: {}, 110 | success: $.proxy(onSuccess, form) 111 | }, 112 | attachValidation: function () { 113 | $form 114 | .unbind("reset." + data_validation, onResetProxy) 115 | .bind("reset." + data_validation, onResetProxy) 116 | .validate(this.options); 117 | }, 118 | validate: function () { // a validation function that is called by unobtrusive Ajax 119 | $form.validate(); 120 | return $form.valid(); 121 | } 122 | }; 123 | $form.data(data_validation, result); 124 | } 125 | return result; 126 | } 127 | $jQval.unobtrusive = { 128 | adapters: [], 129 | parseElement: function (element, skipAttach) { 130 | /// 131 | /// Parses a single HTML element for unobtrusive validation attributes. 132 | /// 133 | /// The HTML element to be parsed. 134 | /// [Optional] true to skip attaching the 135 | /// validation to the form. If parsing just this single element, you should specify true. 136 | /// If parsing several elements, you should specify false, and manually attach the validation 137 | /// to the form when you are finished. The default is false. 138 | var $element = $(element), 139 | form = $element.parents("form")[0], 140 | valInfo, rules, messages; 141 | if (!form) { // Cannot do client-side validation without a form 142 | return; 143 | } 144 | valInfo = validationInfo(form); 145 | valInfo.options.rules[element.name] = rules = {}; 146 | valInfo.options.messages[element.name] = messages = {}; 147 | $.each(this.adapters, function () { 148 | var prefix = "data-val-" + this.name, 149 | message = $element.attr(prefix), 150 | paramValues = {}; 151 | if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy) 152 | prefix += "-"; 153 | $.each(this.params, function () { 154 | paramValues[this] = $element.attr(prefix + this); 155 | }); 156 | this.adapt({ 157 | element: element, 158 | form: form, 159 | message: message, 160 | params: paramValues, 161 | rules: rules, 162 | messages: messages 163 | }); 164 | } 165 | }); 166 | $.extend(rules, { "__dummy__": true }); 167 | if (!skipAttach) { 168 | valInfo.attachValidation(); 169 | } 170 | }, 171 | parse: function (selector) { 172 | /// 173 | /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 174 | /// with the [data-val=true] attribute value and enables validation according to the data-val-* 175 | /// attribute values. 176 | /// 177 | /// Any valid jQuery selector. 178 | var $forms = $(selector) 179 | .parents("form") 180 | .andSelf() 181 | .add($(selector).find("form")) 182 | .filter("form"); 183 | // :input is a psuedoselector provided by jQuery which selects input and input-like elements 184 | // combining :input with other selectors significantly decreases performance. 185 | $(selector).find(":input").filter("[data-val=true]").each(function () { 186 | $jQval.unobtrusive.parseElement(this, true); 187 | }); 188 | $forms.each(function () { 189 | var info = validationInfo(this); 190 | if (info) { 191 | info.attachValidation(); 192 | } 193 | }); 194 | } 195 | }; 196 | adapters = $jQval.unobtrusive.adapters; 197 | adapters.add = function (adapterName, params, fn) { 198 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation. 199 | /// The name of the adapter to be added. This matches the name used 200 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 201 | /// [Optional] An array of parameter names (strings) that will 202 | /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and 203 | /// mmmm is the parameter name). 204 | /// The function to call, which adapts the values from the HTML 205 | /// attributes into jQuery Validate rules and/or messages. 206 | /// 207 | if (!fn) { // Called with no params, just a function 208 | fn = params; 209 | params = []; 210 | } 211 | this.push({ name: adapterName, params: params, adapt: fn }); 212 | return this; 213 | }; 214 | adapters.addBool = function (adapterName, ruleName) { 215 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 216 | /// the jQuery Validate validation rule has no parameter values. 217 | /// The name of the adapter to be added. This matches the name used 218 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 219 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 220 | /// of adapterName will be used instead. 221 | /// 222 | return this.add(adapterName, function (options) { 223 | setValidationValues(options, ruleName || adapterName, true); 224 | }); 225 | }; 226 | adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { 227 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 228 | /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and 229 | /// one for min-and-max). The HTML parameters are expected to be named -min and -max. 230 | /// The name of the adapter to be added. This matches the name used 231 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 232 | /// The name of the jQuery Validate rule to be used when you only 233 | /// have a minimum value. 234 | /// The name of the jQuery Validate rule to be used when you only 235 | /// have a maximum value. 236 | /// The name of the jQuery Validate rule to be used when you 237 | /// have both a minimum and maximum value. 238 | /// [Optional] The name of the HTML attribute that 239 | /// contains the minimum value. The default is "min". 240 | /// [Optional] The name of the HTML attribute that 241 | /// contains the maximum value. The default is "max". 242 | /// 243 | return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { 244 | var min = options.params.min, 245 | max = options.params.max; 246 | if (min && max) { 247 | setValidationValues(options, minMaxRuleName, [min, max]); 248 | } 249 | else if (min) { 250 | setValidationValues(options, minRuleName, min); 251 | } 252 | else if (max) { 253 | setValidationValues(options, maxRuleName, max); 254 | } 255 | }); 256 | }; 257 | adapters.addSingleVal = function (adapterName, attribute, ruleName) { 258 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 259 | /// the jQuery Validate validation rule has a single value. 260 | /// The name of the adapter to be added. This matches the name used 261 | /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name). 262 | /// [Optional] The name of the HTML attribute that contains the value. 263 | /// The default is "val". 264 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 265 | /// of adapterName will be used instead. 266 | /// 267 | return this.add(adapterName, [attribute || "val"], function (options) { 268 | setValidationValues(options, ruleName || adapterName, options.params[attribute]); 269 | }); 270 | }; 271 | $jQval.addMethod("__dummy__", function (value, element, params) { 272 | return true; 273 | }); 274 | $jQval.addMethod("regex", function (value, element, params) { 275 | var match; 276 | if (this.optional(element)) { 277 | return true; 278 | } 279 | match = new RegExp(params).exec(value); 280 | return (match && (match.index === 0) && (match[0].length === value.length)); 281 | }); 282 | $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { 283 | var match; 284 | if (nonalphamin) { 285 | match = value.match(/\W/g); 286 | match = match && match.length >= nonalphamin; 287 | } 288 | return match; 289 | }); 290 | if ($jQval.methods.extension) { 291 | adapters.addSingleVal("accept", "mimtype"); 292 | adapters.addSingleVal("extension", "extension"); 293 | } else { 294 | // for backward compatibility, when the 'extension' validation method does not exist, such as with versions 295 | // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for 296 | // validating the extension, and ignore mime-type validations as they are not supported. 297 | adapters.addSingleVal("extension", "extension", "accept"); 298 | } 299 | adapters.addSingleVal("regex", "pattern"); 300 | adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); 301 | adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); 302 | adapters.add("equalto", ["other"], function (options) { 303 | var prefix = getModelPrefix(options.element.name), 304 | other = options.params.other, 305 | fullOtherName = appendModelPrefix(other, prefix), 306 | element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; 307 | setValidationValues(options, "equalTo", element); 308 | }); 309 | adapters.add("required", function (options) { 310 | // jQuery Validate equates "required" with "mandatory" for checkbox elements 311 | if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { 312 | setValidationValues(options, "required", true); 313 | } 314 | }); 315 | adapters.add("remote", ["url", "type", "additionalfields"], function (options) { 316 | var value = { 317 | url: options.params.url, 318 | type: options.params.type || "GET", 319 | data: {} 320 | }, 321 | prefix = getModelPrefix(options.element.name); 322 | $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { 323 | var paramName = appendModelPrefix(fieldName, prefix); 324 | value.data[paramName] = function () { 325 | return $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']").val(); 326 | }; 327 | }); 328 | setValidationValues(options, "remote", value); 329 | }); 330 | adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { 331 | if (options.params.min) { 332 | setValidationValues(options, "minlength", options.params.min); 333 | } 334 | if (options.params.nonalphamin) { 335 | setValidationValues(options, "nonalphamin", options.params.nonalphamin); 336 | } 337 | if (options.params.regex) { 338 | setValidationValues(options, "regex", options.params.regex); 339 | } 340 | }); 341 | $(function () { 342 | $jQval.unobtrusive.parse(document); 343 | }); 344 | }(jQuery)); 345 | -------------------------------------------------------------------------------- /MultipleFileUpload/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("
  • ").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this);b.data("validator").resetForm();b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(c){var b=a(c),d=b.data(e),f=a.proxy(n,c);if(!d){d={options:{errorClass:"input-validation-error",errorElement:"span",errorPlacement:a.proxy(m,c),invalidHandler:a.proxy(l,c),messages:{},rules:{},success:a.proxy(k,c)},attachValidation:function(){b.unbind("reset."+e,f).bind("reset."+e,f).validate(this.options)},validate:function(){b.validate();return b.valid()}};b.data(e,d)}return d}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(b){var c=a(b).parents("form").andSelf().add(a(b).find("form")).filter("form");a(b).find(":input").filter("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});c.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){return a(b.form).find(":input").filter("[name='"+f(c)+"']").val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery); 20 | -------------------------------------------------------------------------------- /MultipleFileUpload/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title 7 | 8 | 9 | 10 | 11 | 12 | @RenderBody() 13 | 14 | 17 | 18 | 19 | 20 | 21 | @RenderSection("scripts", required: false) 22 | 23 | 24 | -------------------------------------------------------------------------------- /MultipleFileUpload/Views/Support/Create.cshtml: -------------------------------------------------------------------------------- 1 | @model MultipleFileUpload.Models.Support 2 | 3 | @{ 4 | ViewBag.Title = "Create"; 5 | } 6 | 7 | 8 | 9 | @using (Html.BeginForm("Create", "Support", null, FormMethod.Post, new { enctype = "multipart/form-data" })) 10 | { 11 | @Html.AntiForgeryToken() 12 | @Html.ValidationSummary(true) 13 | 14 |
    15 | Create Support Request 16 | 17 |
    18 | @Html.LabelFor(model => model.Name) 19 |
    20 |
    21 | @Html.EditorFor(model => model.Name) 22 | @Html.ValidationMessageFor(model => model.Name) 23 |
    24 | 25 |
    26 | @Html.LabelFor(model => model.Summary) 27 |
    28 |
    29 | @Html.TextAreaFor(model => model.Summary) 30 | @Html.ValidationMessageFor(model => model.Summary) 31 |
    32 |
    33 | 34 |
    35 |
    36 | 37 |
    38 |

    39 | 40 |

    41 |
    42 | } 43 | 44 |
    45 | @Html.ActionLink("Back to List", "Index") 46 |
    47 | 48 | @section Scripts { 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /MultipleFileUpload/Views/Support/Delete.cshtml: -------------------------------------------------------------------------------- 1 | @model MultipleFileUpload.Models.Support 2 | 3 | @{ 4 | ViewBag.Title = "Delete"; 5 | } 6 | 7 |

    Delete

    8 | 9 |

    Are you sure you want to delete this?

    10 |
    11 | Support 12 | 13 |
    14 | @Html.DisplayNameFor(model => model.Name) 15 |
    16 |
    17 | @Html.DisplayFor(model => model.Name) 18 |
    19 | 20 |
    21 | @Html.DisplayNameFor(model => model.Summary) 22 |
    23 |
    24 | @Html.DisplayFor(model => model.Summary) 25 |
    26 |
    27 | @using (Html.BeginForm()) { 28 | @Html.AntiForgeryToken() 29 |

    30 | | 31 | @Html.ActionLink("Back to List", "Index") 32 |

    33 | } 34 | -------------------------------------------------------------------------------- /MultipleFileUpload/Views/Support/Edit.cshtml: -------------------------------------------------------------------------------- 1 | @model MultipleFileUpload.Models.Support 2 | 3 | @{ 4 | ViewBag.Title = "Edit"; 5 | } 6 | 7 | 8 | 9 | @using (Html.BeginForm("Edit", "Support", null, FormMethod.Post, new { enctype = "multipart/form-data" })) 10 | { 11 | @Html.AntiForgeryToken() 12 | @Html.ValidationSummary(true) 13 | 14 |
    15 | Edit Support Request 16 | 17 | @Html.HiddenFor(model => model.SupportId) 18 | 19 |
    20 | @Html.LabelFor(model => model.Name) 21 |
    22 |
    23 | @Html.EditorFor(model => model.Name) 24 | @Html.ValidationMessageFor(model => model.Name) 25 |
    26 | 27 |
    28 | @Html.LabelFor(model => model.Summary) 29 |
    30 |
    31 | @Html.TextAreaFor(model => model.Summary) 32 | @Html.ValidationMessageFor(model => model.Summary) 33 |
    34 |
    35 | 36 |
    37 |
    38 | 39 | 40 |
      41 | @foreach (var item in Model.FileDetails) 42 | { 43 |
    • 44 | @item.FileName 45 | X 46 |
    • 47 | } 48 |
    49 |
    50 |

    51 | 52 |

    53 |
    54 | } 55 | 56 |
    57 | @Html.ActionLink("Back to List", "Index") 58 |
    59 | 60 | @section Scripts { 61 | 62 | 63 | 64 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /MultipleFileUpload/Views/Support/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IEnumerable 2 | 3 | @{ 4 | ViewBag.Title = "Index"; 5 | } 6 | 7 |

    Index

    8 | 9 |

    10 | @Html.ActionLink("Create New", "Create") 11 |

    12 | 13 | 14 | 17 | 20 | 21 | 22 | 23 | 24 | @foreach (var item in Model) { 25 | 26 | 29 | 32 | 39 | 43 | 44 | } 45 | 46 |
    15 | @Html.DisplayNameFor(model => model.Name) 16 | 18 | @Html.DisplayNameFor(model => model.Summary) 19 | Total Files
    27 | @Html.DisplayFor(modelItem => item.Name) 28 | 30 | @Html.DisplayFor(modelItem => item.Summary) 31 | @if (item.FileDetails.Count() == 0) { 33 | No File 34 | } 35 | else{ 36 | @item.FileDetails.Count() File(s) 37 | } 38 | 40 | @Html.ActionLink("Edit", "Edit", new { id=item.SupportId }) | 41 | Delete 42 |
    47 | 48 | @section Scripts { 49 | 50 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /MultipleFileUpload/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /MultipleFileUpload/Views/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
    7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /MultipleFileUpload/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /MultipleFileUpload/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /MultipleFileUpload/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 |
    10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /MultipleFileUpload/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techbrij/file-upload-crud-asp-net-mvc/df0a7ced438d889ac56b4806f32c7caaccb4736f/MultipleFileUpload/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /MultipleFileUpload/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techbrij/file-upload-crud-asp-net-mvc/df0a7ced438d889ac56b4806f32c7caaccb4736f/MultipleFileUpload/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /MultipleFileUpload/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techbrij/file-upload-crud-asp-net-mvc/df0a7ced438d889ac56b4806f32c7caaccb4736f/MultipleFileUpload/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /MultipleFileUpload/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | --------------------------------------------------------------------------------