├── .gitignore ├── AddItemsDynamically.sln ├── AddItemsDynamically ├── AddItemsDynamically.csproj ├── Controllers │ ├── HomeController.cs │ ├── OrderItemsController.cs │ └── OrdersController.cs ├── Data │ └── ApplicationDbContext.cs ├── Media │ ├── AddButonAndJavScript.png │ ├── AddItemsToList.gif │ ├── AddOrderItemMethod.png │ ├── CreateMethod.png │ ├── FormIdAndSerialize.png │ ├── OrderItemTemplate.png │ ├── OrderModel.png │ ├── PartialView.png │ ├── SimpleOrderCreate.png │ ├── SimpleOrderItemCreate.png │ └── UsingEditorInCreate.png ├── Migrations │ ├── 20190926092520_init.Designer.cs │ ├── 20190926092520_init.cs │ ├── 20190926093730_orderName-added.Designer.cs │ ├── 20190926093730_orderName-added.cs │ └── ApplicationDbContextModelSnapshot.cs ├── Models │ ├── ErrorViewModel.cs │ ├── Order.cs │ └── OrderItem.cs ├── Program.cs ├── Startup.cs ├── Views │ ├── Home │ │ ├── About.cshtml │ │ ├── Contact.cshtml │ │ ├── Index.cshtml │ │ └── Privacy.cshtml │ ├── OrderItems │ │ ├── Create.cshtml │ │ ├── Delete.cshtml │ │ ├── Details.cshtml │ │ ├── Edit.cshtml │ │ └── Index.cshtml │ ├── Orders │ │ ├── Create.cshtml │ │ ├── Delete.cshtml │ │ ├── Details.cshtml │ │ ├── Edit.cshtml │ │ ├── Index.cshtml │ │ └── OrderItems.cshtml │ ├── Shared │ │ ├── EditorTemplates │ │ │ └── OrderItem.cshtml │ │ ├── Error.cshtml │ │ ├── _CookieConsentPartial.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ ├── site.css │ └── site.min.css │ ├── favicon.ico │ ├── images │ ├── banner1.svg │ ├── banner2.svg │ └── banner3.svg │ ├── js │ ├── site.js │ └── site.min.js │ └── lib │ ├── bootstrap │ ├── .bower.json │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-theme.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ └── npm.js │ ├── jquery-validation-unobtrusive │ ├── .bower.json │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── .bower.json │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── .bower.json │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /AddItemsDynamically.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.852 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddItemsDynamically", "AddItemsDynamically\AddItemsDynamically.csproj", "{D142E788-DA2C-403F-AB6B-987FD3C97358}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D142E788-DA2C-403F-AB6B-987FD3C97358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D142E788-DA2C-403F-AB6B-987FD3C97358}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D142E788-DA2C-403F-AB6B-987FD3C97358}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D142E788-DA2C-403F-AB6B-987FD3C97358}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {CF1E03AC-A75B-4863-BAAB-5C541CBEA311} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /AddItemsDynamically/AddItemsDynamically.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | $(IncludeRazorContentInPack) 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /AddItemsDynamically/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using AddItemsDynamically.Models; 8 | 9 | namespace AddItemsDynamically.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | public IActionResult Index() 14 | { 15 | return View(); 16 | } 17 | 18 | public IActionResult About() 19 | { 20 | ViewData["Message"] = "Your application description page."; 21 | 22 | return View(); 23 | } 24 | 25 | public IActionResult Contact() 26 | { 27 | ViewData["Message"] = "Your contact page."; 28 | 29 | return View(); 30 | } 31 | 32 | public IActionResult Privacy() 33 | { 34 | return View(); 35 | } 36 | 37 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 38 | public IActionResult Error() 39 | { 40 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /AddItemsDynamically/Controllers/OrderItemsController.cs: -------------------------------------------------------------------------------- 1 | using AddItemsDynamically.Data; 2 | using AddItemsDynamically.Models; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.EntityFrameworkCore; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace AddItemsDynamically.Controllers 9 | { 10 | public class OrderItemsController : Controller 11 | { 12 | private readonly ApplicationDbContext _context; 13 | 14 | public OrderItemsController(ApplicationDbContext context) 15 | { 16 | _context = context; 17 | } 18 | 19 | // GET: OrderItems 20 | public async Task Index() 21 | { 22 | return View(await _context.OrderItem.ToListAsync()); 23 | } 24 | 25 | // GET: OrderItems/Details/5 26 | public async Task Details(int? id) 27 | { 28 | if (id == null) 29 | { 30 | return NotFound(); 31 | } 32 | 33 | var orderItem = await _context.OrderItem 34 | .FirstOrDefaultAsync(m => m.Id == id); 35 | if (orderItem == null) 36 | { 37 | return NotFound(); 38 | } 39 | 40 | return View(orderItem); 41 | } 42 | 43 | // GET: OrderItems/Create 44 | public IActionResult Create() 45 | { 46 | return View(); 47 | } 48 | 49 | // POST: OrderItems/Create 50 | // To protect from overposting attacks, please enable the specific properties you want to bind to, for 51 | // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 52 | [HttpPost] 53 | [ValidateAntiForgeryToken] 54 | public async Task Create([Bind("Id,ProductName,Quantity")] OrderItem orderItem) 55 | { 56 | if (ModelState.IsValid) 57 | { 58 | _context.Add(orderItem); 59 | await _context.SaveChangesAsync(); 60 | return RedirectToAction(nameof(Index)); 61 | } 62 | return View(orderItem); 63 | } 64 | 65 | // GET: OrderItems/Edit/5 66 | public async Task Edit(int? id) 67 | { 68 | if (id == null) 69 | { 70 | return NotFound(); 71 | } 72 | 73 | var orderItem = await _context.OrderItem.FindAsync(id); 74 | if (orderItem == null) 75 | { 76 | return NotFound(); 77 | } 78 | return View(orderItem); 79 | } 80 | 81 | // POST: OrderItems/Edit/5 82 | // To protect from overposting attacks, please enable the specific properties you want to bind to, for 83 | // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 84 | [HttpPost] 85 | [ValidateAntiForgeryToken] 86 | public async Task Edit(int id, [Bind("Id,ProductName,Quantity")] OrderItem orderItem) 87 | { 88 | if (id != orderItem.Id) 89 | { 90 | return NotFound(); 91 | } 92 | 93 | if (ModelState.IsValid) 94 | { 95 | try 96 | { 97 | _context.Update(orderItem); 98 | await _context.SaveChangesAsync(); 99 | } 100 | catch (DbUpdateConcurrencyException) 101 | { 102 | if (!OrderItemExists(orderItem.Id)) 103 | { 104 | return NotFound(); 105 | } 106 | else 107 | { 108 | throw; 109 | } 110 | } 111 | return RedirectToAction(nameof(Index)); 112 | } 113 | return View(orderItem); 114 | } 115 | 116 | // GET: OrderItems/Delete/5 117 | public async Task Delete(int? id) 118 | { 119 | if (id == null) 120 | { 121 | return NotFound(); 122 | } 123 | 124 | var orderItem = await _context.OrderItem 125 | .FirstOrDefaultAsync(m => m.Id == id); 126 | if (orderItem == null) 127 | { 128 | return NotFound(); 129 | } 130 | 131 | return View(orderItem); 132 | } 133 | 134 | // POST: OrderItems/Delete/5 135 | [HttpPost, ActionName("Delete")] 136 | [ValidateAntiForgeryToken] 137 | public async Task DeleteConfirmed(int id) 138 | { 139 | var orderItem = await _context.OrderItem.FindAsync(id); 140 | _context.OrderItem.Remove(orderItem); 141 | await _context.SaveChangesAsync(); 142 | return RedirectToAction(nameof(Index)); 143 | } 144 | 145 | private bool OrderItemExists(int id) 146 | { 147 | return _context.OrderItem.Any(e => e.Id == id); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /AddItemsDynamically/Controllers/OrdersController.cs: -------------------------------------------------------------------------------- 1 | using AddItemsDynamically.Data; 2 | using AddItemsDynamically.Models; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.EntityFrameworkCore; 5 | using System; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace AddItemsDynamically.Controllers 10 | { 11 | public class OrdersController : Controller 12 | { 13 | private readonly ApplicationDbContext _context; 14 | 15 | public OrdersController(ApplicationDbContext context) 16 | { 17 | _context = context; 18 | } 19 | 20 | // GET: Orders 21 | public async Task Index() 22 | { 23 | return View(await _context.Order.Include(t=>t.Items).ToListAsync()); 24 | } 25 | 26 | // GET: Orders/Details/5 27 | public async Task Details(int? id) 28 | { 29 | if (id == null) 30 | { 31 | return NotFound(); 32 | } 33 | 34 | var order = await _context.Order.Include(t => t.Items) 35 | .FirstOrDefaultAsync(m => m.Id == id); 36 | if (order == null) 37 | { 38 | return NotFound(); 39 | } 40 | 41 | return View(order); 42 | } 43 | 44 | // GET: Orders/Create 45 | public IActionResult Create() 46 | { 47 | var model = new Order(); 48 | model.Items.Add(new OrderItem()); 49 | return View(model); 50 | } 51 | 52 | // POST: Orders/Create 53 | // To protect from overposting attacks, please enable the specific properties you want to bind to, for 54 | // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 55 | [HttpPost] 56 | [ValidateAntiForgeryToken] 57 | public async Task Create([Bind("Name,IsUrgent,Items")] Order order) 58 | { 59 | if (ModelState.IsValid) 60 | { 61 | order.Created = DateTime.UtcNow; 62 | _context.Add(order); 63 | await _context.SaveChangesAsync(); 64 | return RedirectToAction(nameof(Index)); 65 | } 66 | return View(order); 67 | } 68 | 69 | [HttpPost] 70 | [ValidateAntiForgeryToken] 71 | public async Task AddOrderItem([Bind("Items")] Order order) 72 | { 73 | order.Items.Add(new OrderItem()); 74 | return PartialView("OrderItems", order); 75 | } 76 | 77 | // GET: Orders/Edit/5 78 | public async Task Edit(int? id) 79 | { 80 | if (id == null) 81 | { 82 | return NotFound(); 83 | } 84 | 85 | var order = await _context.Order.FindAsync(id); 86 | if (order == null) 87 | { 88 | return NotFound(); 89 | } 90 | return View(order); 91 | } 92 | 93 | // POST: Orders/Edit/5 94 | // To protect from overposting attacks, please enable the specific properties you want to bind to, for 95 | // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 96 | [HttpPost] 97 | [ValidateAntiForgeryToken] 98 | public async Task Edit(int id, [Bind("Id,Name,IsUrgent,Created")] Order order) 99 | { 100 | if (id != order.Id) 101 | { 102 | return NotFound(); 103 | } 104 | 105 | if (ModelState.IsValid) 106 | { 107 | try 108 | { 109 | _context.Update(order); 110 | await _context.SaveChangesAsync(); 111 | } 112 | catch (DbUpdateConcurrencyException) 113 | { 114 | if (!OrderExists(order.Id)) 115 | { 116 | return NotFound(); 117 | } 118 | else 119 | { 120 | throw; 121 | } 122 | } 123 | return RedirectToAction(nameof(Index)); 124 | } 125 | return View(order); 126 | } 127 | 128 | // GET: Orders/Delete/5 129 | public async Task Delete(int? id) 130 | { 131 | if (id == null) 132 | { 133 | return NotFound(); 134 | } 135 | 136 | var order = await _context.Order.Include(t => t.Items) 137 | .FirstOrDefaultAsync(m => m.Id == id); 138 | if (order == null) 139 | { 140 | return NotFound(); 141 | } 142 | 143 | return View(order); 144 | } 145 | 146 | // POST: Orders/Delete/5 147 | [HttpPost, ActionName("Delete")] 148 | [ValidateAntiForgeryToken] 149 | public async Task DeleteConfirmed(int id) 150 | { 151 | var order = await _context.Order.Include(t => t.Items).FirstOrDefaultAsync(t=>t.Id == id); 152 | _context.Order.Remove(order); 153 | await _context.SaveChangesAsync(); 154 | return RedirectToAction(nameof(Index)); 155 | } 156 | 157 | private bool OrderExists(int id) 158 | { 159 | return _context.Order.Any(e => e.Id == id); 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /AddItemsDynamically/Data/ApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using AddItemsDynamically.Models; 2 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace AddItemsDynamically.Data 6 | { 7 | public class ApplicationDbContext : IdentityDbContext 8 | { 9 | public ApplicationDbContext(DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | protected override void OnModelCreating(ModelBuilder builder) 15 | { 16 | base.OnModelCreating(builder); 17 | builder.Entity().Property(t => t.Id).ValueGeneratedOnAdd(); 18 | builder.Entity().Property(t => t.Id).ValueGeneratedOnAdd(); 19 | } 20 | 21 | public DbSet Order { get; set; } 22 | public DbSet OrderItem { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /AddItemsDynamically/Media/AddButonAndJavScript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/AddButonAndJavScript.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/AddItemsToList.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/AddItemsToList.gif -------------------------------------------------------------------------------- /AddItemsDynamically/Media/AddOrderItemMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/AddOrderItemMethod.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/CreateMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/CreateMethod.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/FormIdAndSerialize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/FormIdAndSerialize.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/OrderItemTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/OrderItemTemplate.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/OrderModel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/OrderModel.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/PartialView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/PartialView.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/SimpleOrderCreate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/SimpleOrderCreate.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/SimpleOrderItemCreate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/SimpleOrderItemCreate.png -------------------------------------------------------------------------------- /AddItemsDynamically/Media/UsingEditorInCreate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/Media/UsingEditorInCreate.png -------------------------------------------------------------------------------- /AddItemsDynamically/Migrations/20190926092520_init.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using AddItemsDynamically.Data; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Migrations; 8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 9 | 10 | namespace AddItemsDynamically.Migrations 11 | { 12 | [DbContext(typeof(ApplicationDbContext))] 13 | [Migration("20190926092520_init")] 14 | partial class init 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "2.1.11-servicing-32099") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("AddItemsDynamically.Models.Order", b => 25 | { 26 | b.Property("Id") 27 | .ValueGeneratedOnAdd() 28 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 29 | 30 | b.Property("Created"); 31 | 32 | b.HasKey("Id"); 33 | 34 | b.ToTable("Order"); 35 | }); 36 | 37 | modelBuilder.Entity("AddItemsDynamically.Models.OrderItem", b => 38 | { 39 | b.Property("Id") 40 | .ValueGeneratedOnAdd() 41 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 42 | 43 | b.Property("OrderId"); 44 | 45 | b.Property("ProductName"); 46 | 47 | b.Property("Quantity"); 48 | 49 | b.HasKey("Id"); 50 | 51 | b.HasIndex("OrderId"); 52 | 53 | b.ToTable("OrderItem"); 54 | }); 55 | 56 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 57 | { 58 | b.Property("Id") 59 | .ValueGeneratedOnAdd(); 60 | 61 | b.Property("ConcurrencyStamp") 62 | .IsConcurrencyToken(); 63 | 64 | b.Property("Name") 65 | .HasMaxLength(256); 66 | 67 | b.Property("NormalizedName") 68 | .HasMaxLength(256); 69 | 70 | b.HasKey("Id"); 71 | 72 | b.HasIndex("NormalizedName") 73 | .IsUnique() 74 | .HasName("RoleNameIndex") 75 | .HasFilter("[NormalizedName] IS NOT NULL"); 76 | 77 | b.ToTable("AspNetRoles"); 78 | }); 79 | 80 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 81 | { 82 | b.Property("Id") 83 | .ValueGeneratedOnAdd() 84 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 85 | 86 | b.Property("ClaimType"); 87 | 88 | b.Property("ClaimValue"); 89 | 90 | b.Property("RoleId") 91 | .IsRequired(); 92 | 93 | b.HasKey("Id"); 94 | 95 | b.HasIndex("RoleId"); 96 | 97 | b.ToTable("AspNetRoleClaims"); 98 | }); 99 | 100 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => 101 | { 102 | b.Property("Id") 103 | .ValueGeneratedOnAdd(); 104 | 105 | b.Property("AccessFailedCount"); 106 | 107 | b.Property("ConcurrencyStamp") 108 | .IsConcurrencyToken(); 109 | 110 | b.Property("Email") 111 | .HasMaxLength(256); 112 | 113 | b.Property("EmailConfirmed"); 114 | 115 | b.Property("LockoutEnabled"); 116 | 117 | b.Property("LockoutEnd"); 118 | 119 | b.Property("NormalizedEmail") 120 | .HasMaxLength(256); 121 | 122 | b.Property("NormalizedUserName") 123 | .HasMaxLength(256); 124 | 125 | b.Property("PasswordHash"); 126 | 127 | b.Property("PhoneNumber"); 128 | 129 | b.Property("PhoneNumberConfirmed"); 130 | 131 | b.Property("SecurityStamp"); 132 | 133 | b.Property("TwoFactorEnabled"); 134 | 135 | b.Property("UserName") 136 | .HasMaxLength(256); 137 | 138 | b.HasKey("Id"); 139 | 140 | b.HasIndex("NormalizedEmail") 141 | .HasName("EmailIndex"); 142 | 143 | b.HasIndex("NormalizedUserName") 144 | .IsUnique() 145 | .HasName("UserNameIndex") 146 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 147 | 148 | b.ToTable("AspNetUsers"); 149 | }); 150 | 151 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 152 | { 153 | b.Property("Id") 154 | .ValueGeneratedOnAdd() 155 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 156 | 157 | b.Property("ClaimType"); 158 | 159 | b.Property("ClaimValue"); 160 | 161 | b.Property("UserId") 162 | .IsRequired(); 163 | 164 | b.HasKey("Id"); 165 | 166 | b.HasIndex("UserId"); 167 | 168 | b.ToTable("AspNetUserClaims"); 169 | }); 170 | 171 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 172 | { 173 | b.Property("LoginProvider"); 174 | 175 | b.Property("ProviderKey"); 176 | 177 | b.Property("ProviderDisplayName"); 178 | 179 | b.Property("UserId") 180 | .IsRequired(); 181 | 182 | b.HasKey("LoginProvider", "ProviderKey"); 183 | 184 | b.HasIndex("UserId"); 185 | 186 | b.ToTable("AspNetUserLogins"); 187 | }); 188 | 189 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 190 | { 191 | b.Property("UserId"); 192 | 193 | b.Property("RoleId"); 194 | 195 | b.HasKey("UserId", "RoleId"); 196 | 197 | b.HasIndex("RoleId"); 198 | 199 | b.ToTable("AspNetUserRoles"); 200 | }); 201 | 202 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 203 | { 204 | b.Property("UserId"); 205 | 206 | b.Property("LoginProvider"); 207 | 208 | b.Property("Name"); 209 | 210 | b.Property("Value"); 211 | 212 | b.HasKey("UserId", "LoginProvider", "Name"); 213 | 214 | b.ToTable("AspNetUserTokens"); 215 | }); 216 | 217 | modelBuilder.Entity("AddItemsDynamically.Models.OrderItem", b => 218 | { 219 | b.HasOne("AddItemsDynamically.Models.Order") 220 | .WithMany("Items") 221 | .HasForeignKey("OrderId"); 222 | }); 223 | 224 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 225 | { 226 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 227 | .WithMany() 228 | .HasForeignKey("RoleId") 229 | .OnDelete(DeleteBehavior.Cascade); 230 | }); 231 | 232 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 233 | { 234 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 235 | .WithMany() 236 | .HasForeignKey("UserId") 237 | .OnDelete(DeleteBehavior.Cascade); 238 | }); 239 | 240 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 241 | { 242 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 243 | .WithMany() 244 | .HasForeignKey("UserId") 245 | .OnDelete(DeleteBehavior.Cascade); 246 | }); 247 | 248 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 249 | { 250 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 251 | .WithMany() 252 | .HasForeignKey("RoleId") 253 | .OnDelete(DeleteBehavior.Cascade); 254 | 255 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 256 | .WithMany() 257 | .HasForeignKey("UserId") 258 | .OnDelete(DeleteBehavior.Cascade); 259 | }); 260 | 261 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 262 | { 263 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 264 | .WithMany() 265 | .HasForeignKey("UserId") 266 | .OnDelete(DeleteBehavior.Cascade); 267 | }); 268 | #pragma warning restore 612, 618 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /AddItemsDynamically/Migrations/20190926092520_init.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Metadata; 3 | using Microsoft.EntityFrameworkCore.Migrations; 4 | 5 | namespace AddItemsDynamically.Migrations 6 | { 7 | public partial class init : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | migrationBuilder.CreateTable( 12 | name: "AspNetRoles", 13 | columns: table => new 14 | { 15 | Id = table.Column(nullable: false), 16 | Name = table.Column(maxLength: 256, nullable: true), 17 | NormalizedName = table.Column(maxLength: 256, nullable: true), 18 | ConcurrencyStamp = table.Column(nullable: true) 19 | }, 20 | constraints: table => 21 | { 22 | table.PrimaryKey("PK_AspNetRoles", x => x.Id); 23 | }); 24 | 25 | migrationBuilder.CreateTable( 26 | name: "AspNetUsers", 27 | columns: table => new 28 | { 29 | Id = table.Column(nullable: false), 30 | UserName = table.Column(maxLength: 256, nullable: true), 31 | NormalizedUserName = table.Column(maxLength: 256, nullable: true), 32 | Email = table.Column(maxLength: 256, nullable: true), 33 | NormalizedEmail = table.Column(maxLength: 256, nullable: true), 34 | EmailConfirmed = table.Column(nullable: false), 35 | PasswordHash = table.Column(nullable: true), 36 | SecurityStamp = table.Column(nullable: true), 37 | ConcurrencyStamp = table.Column(nullable: true), 38 | PhoneNumber = table.Column(nullable: true), 39 | PhoneNumberConfirmed = table.Column(nullable: false), 40 | TwoFactorEnabled = table.Column(nullable: false), 41 | LockoutEnd = table.Column(nullable: true), 42 | LockoutEnabled = table.Column(nullable: false), 43 | AccessFailedCount = table.Column(nullable: false) 44 | }, 45 | constraints: table => 46 | { 47 | table.PrimaryKey("PK_AspNetUsers", x => x.Id); 48 | }); 49 | 50 | migrationBuilder.CreateTable( 51 | name: "Order", 52 | columns: table => new 53 | { 54 | Id = table.Column(nullable: false) 55 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 56 | Created = table.Column(nullable: false) 57 | }, 58 | constraints: table => 59 | { 60 | table.PrimaryKey("PK_Order", x => x.Id); 61 | }); 62 | 63 | migrationBuilder.CreateTable( 64 | name: "AspNetRoleClaims", 65 | columns: table => new 66 | { 67 | Id = table.Column(nullable: false) 68 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 69 | RoleId = table.Column(nullable: false), 70 | ClaimType = table.Column(nullable: true), 71 | ClaimValue = table.Column(nullable: true) 72 | }, 73 | constraints: table => 74 | { 75 | table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); 76 | table.ForeignKey( 77 | name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", 78 | column: x => x.RoleId, 79 | principalTable: "AspNetRoles", 80 | principalColumn: "Id", 81 | onDelete: ReferentialAction.Cascade); 82 | }); 83 | 84 | migrationBuilder.CreateTable( 85 | name: "AspNetUserClaims", 86 | columns: table => new 87 | { 88 | Id = table.Column(nullable: false) 89 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 90 | UserId = table.Column(nullable: false), 91 | ClaimType = table.Column(nullable: true), 92 | ClaimValue = table.Column(nullable: true) 93 | }, 94 | constraints: table => 95 | { 96 | table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); 97 | table.ForeignKey( 98 | name: "FK_AspNetUserClaims_AspNetUsers_UserId", 99 | column: x => x.UserId, 100 | principalTable: "AspNetUsers", 101 | principalColumn: "Id", 102 | onDelete: ReferentialAction.Cascade); 103 | }); 104 | 105 | migrationBuilder.CreateTable( 106 | name: "AspNetUserLogins", 107 | columns: table => new 108 | { 109 | LoginProvider = table.Column(nullable: false), 110 | ProviderKey = table.Column(nullable: false), 111 | ProviderDisplayName = table.Column(nullable: true), 112 | UserId = table.Column(nullable: false) 113 | }, 114 | constraints: table => 115 | { 116 | table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); 117 | table.ForeignKey( 118 | name: "FK_AspNetUserLogins_AspNetUsers_UserId", 119 | column: x => x.UserId, 120 | principalTable: "AspNetUsers", 121 | principalColumn: "Id", 122 | onDelete: ReferentialAction.Cascade); 123 | }); 124 | 125 | migrationBuilder.CreateTable( 126 | name: "AspNetUserRoles", 127 | columns: table => new 128 | { 129 | UserId = table.Column(nullable: false), 130 | RoleId = table.Column(nullable: false) 131 | }, 132 | constraints: table => 133 | { 134 | table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); 135 | table.ForeignKey( 136 | name: "FK_AspNetUserRoles_AspNetRoles_RoleId", 137 | column: x => x.RoleId, 138 | principalTable: "AspNetRoles", 139 | principalColumn: "Id", 140 | onDelete: ReferentialAction.Cascade); 141 | table.ForeignKey( 142 | name: "FK_AspNetUserRoles_AspNetUsers_UserId", 143 | column: x => x.UserId, 144 | principalTable: "AspNetUsers", 145 | principalColumn: "Id", 146 | onDelete: ReferentialAction.Cascade); 147 | }); 148 | 149 | migrationBuilder.CreateTable( 150 | name: "AspNetUserTokens", 151 | columns: table => new 152 | { 153 | UserId = table.Column(nullable: false), 154 | LoginProvider = table.Column(nullable: false), 155 | Name = table.Column(nullable: false), 156 | Value = table.Column(nullable: true) 157 | }, 158 | constraints: table => 159 | { 160 | table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); 161 | table.ForeignKey( 162 | name: "FK_AspNetUserTokens_AspNetUsers_UserId", 163 | column: x => x.UserId, 164 | principalTable: "AspNetUsers", 165 | principalColumn: "Id", 166 | onDelete: ReferentialAction.Cascade); 167 | }); 168 | 169 | migrationBuilder.CreateTable( 170 | name: "OrderItem", 171 | columns: table => new 172 | { 173 | Id = table.Column(nullable: false) 174 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 175 | ProductName = table.Column(nullable: true), 176 | Quantity = table.Column(nullable: false), 177 | OrderId = table.Column(nullable: true) 178 | }, 179 | constraints: table => 180 | { 181 | table.PrimaryKey("PK_OrderItem", x => x.Id); 182 | table.ForeignKey( 183 | name: "FK_OrderItem_Order_OrderId", 184 | column: x => x.OrderId, 185 | principalTable: "Order", 186 | principalColumn: "Id", 187 | onDelete: ReferentialAction.Restrict); 188 | }); 189 | 190 | migrationBuilder.CreateIndex( 191 | name: "IX_AspNetRoleClaims_RoleId", 192 | table: "AspNetRoleClaims", 193 | column: "RoleId"); 194 | 195 | migrationBuilder.CreateIndex( 196 | name: "RoleNameIndex", 197 | table: "AspNetRoles", 198 | column: "NormalizedName", 199 | unique: true, 200 | filter: "[NormalizedName] IS NOT NULL"); 201 | 202 | migrationBuilder.CreateIndex( 203 | name: "IX_AspNetUserClaims_UserId", 204 | table: "AspNetUserClaims", 205 | column: "UserId"); 206 | 207 | migrationBuilder.CreateIndex( 208 | name: "IX_AspNetUserLogins_UserId", 209 | table: "AspNetUserLogins", 210 | column: "UserId"); 211 | 212 | migrationBuilder.CreateIndex( 213 | name: "IX_AspNetUserRoles_RoleId", 214 | table: "AspNetUserRoles", 215 | column: "RoleId"); 216 | 217 | migrationBuilder.CreateIndex( 218 | name: "EmailIndex", 219 | table: "AspNetUsers", 220 | column: "NormalizedEmail"); 221 | 222 | migrationBuilder.CreateIndex( 223 | name: "UserNameIndex", 224 | table: "AspNetUsers", 225 | column: "NormalizedUserName", 226 | unique: true, 227 | filter: "[NormalizedUserName] IS NOT NULL"); 228 | 229 | migrationBuilder.CreateIndex( 230 | name: "IX_OrderItem_OrderId", 231 | table: "OrderItem", 232 | column: "OrderId"); 233 | } 234 | 235 | protected override void Down(MigrationBuilder migrationBuilder) 236 | { 237 | migrationBuilder.DropTable( 238 | name: "AspNetRoleClaims"); 239 | 240 | migrationBuilder.DropTable( 241 | name: "AspNetUserClaims"); 242 | 243 | migrationBuilder.DropTable( 244 | name: "AspNetUserLogins"); 245 | 246 | migrationBuilder.DropTable( 247 | name: "AspNetUserRoles"); 248 | 249 | migrationBuilder.DropTable( 250 | name: "AspNetUserTokens"); 251 | 252 | migrationBuilder.DropTable( 253 | name: "OrderItem"); 254 | 255 | migrationBuilder.DropTable( 256 | name: "AspNetRoles"); 257 | 258 | migrationBuilder.DropTable( 259 | name: "AspNetUsers"); 260 | 261 | migrationBuilder.DropTable( 262 | name: "Order"); 263 | } 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /AddItemsDynamically/Migrations/20190926093730_orderName-added.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using AddItemsDynamically.Data; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Migrations; 8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 9 | 10 | namespace AddItemsDynamically.Migrations 11 | { 12 | [DbContext(typeof(ApplicationDbContext))] 13 | [Migration("20190926093730_orderName-added")] 14 | partial class orderNameadded 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "2.1.11-servicing-32099") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("AddItemsDynamically.Models.Order", b => 25 | { 26 | b.Property("Id") 27 | .ValueGeneratedOnAdd() 28 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 29 | 30 | b.Property("Created"); 31 | 32 | b.Property("IsUrgent"); 33 | 34 | b.Property("Name"); 35 | 36 | b.HasKey("Id"); 37 | 38 | b.ToTable("Order"); 39 | }); 40 | 41 | modelBuilder.Entity("AddItemsDynamically.Models.OrderItem", b => 42 | { 43 | b.Property("Id") 44 | .ValueGeneratedOnAdd() 45 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 46 | 47 | b.Property("OrderId"); 48 | 49 | b.Property("ProductName"); 50 | 51 | b.Property("Quantity"); 52 | 53 | b.HasKey("Id"); 54 | 55 | b.HasIndex("OrderId"); 56 | 57 | b.ToTable("OrderItem"); 58 | }); 59 | 60 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 61 | { 62 | b.Property("Id") 63 | .ValueGeneratedOnAdd(); 64 | 65 | b.Property("ConcurrencyStamp") 66 | .IsConcurrencyToken(); 67 | 68 | b.Property("Name") 69 | .HasMaxLength(256); 70 | 71 | b.Property("NormalizedName") 72 | .HasMaxLength(256); 73 | 74 | b.HasKey("Id"); 75 | 76 | b.HasIndex("NormalizedName") 77 | .IsUnique() 78 | .HasName("RoleNameIndex") 79 | .HasFilter("[NormalizedName] IS NOT NULL"); 80 | 81 | b.ToTable("AspNetRoles"); 82 | }); 83 | 84 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 85 | { 86 | b.Property("Id") 87 | .ValueGeneratedOnAdd() 88 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 89 | 90 | b.Property("ClaimType"); 91 | 92 | b.Property("ClaimValue"); 93 | 94 | b.Property("RoleId") 95 | .IsRequired(); 96 | 97 | b.HasKey("Id"); 98 | 99 | b.HasIndex("RoleId"); 100 | 101 | b.ToTable("AspNetRoleClaims"); 102 | }); 103 | 104 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => 105 | { 106 | b.Property("Id") 107 | .ValueGeneratedOnAdd(); 108 | 109 | b.Property("AccessFailedCount"); 110 | 111 | b.Property("ConcurrencyStamp") 112 | .IsConcurrencyToken(); 113 | 114 | b.Property("Email") 115 | .HasMaxLength(256); 116 | 117 | b.Property("EmailConfirmed"); 118 | 119 | b.Property("LockoutEnabled"); 120 | 121 | b.Property("LockoutEnd"); 122 | 123 | b.Property("NormalizedEmail") 124 | .HasMaxLength(256); 125 | 126 | b.Property("NormalizedUserName") 127 | .HasMaxLength(256); 128 | 129 | b.Property("PasswordHash"); 130 | 131 | b.Property("PhoneNumber"); 132 | 133 | b.Property("PhoneNumberConfirmed"); 134 | 135 | b.Property("SecurityStamp"); 136 | 137 | b.Property("TwoFactorEnabled"); 138 | 139 | b.Property("UserName") 140 | .HasMaxLength(256); 141 | 142 | b.HasKey("Id"); 143 | 144 | b.HasIndex("NormalizedEmail") 145 | .HasName("EmailIndex"); 146 | 147 | b.HasIndex("NormalizedUserName") 148 | .IsUnique() 149 | .HasName("UserNameIndex") 150 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 151 | 152 | b.ToTable("AspNetUsers"); 153 | }); 154 | 155 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 156 | { 157 | b.Property("Id") 158 | .ValueGeneratedOnAdd() 159 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 160 | 161 | b.Property("ClaimType"); 162 | 163 | b.Property("ClaimValue"); 164 | 165 | b.Property("UserId") 166 | .IsRequired(); 167 | 168 | b.HasKey("Id"); 169 | 170 | b.HasIndex("UserId"); 171 | 172 | b.ToTable("AspNetUserClaims"); 173 | }); 174 | 175 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 176 | { 177 | b.Property("LoginProvider"); 178 | 179 | b.Property("ProviderKey"); 180 | 181 | b.Property("ProviderDisplayName"); 182 | 183 | b.Property("UserId") 184 | .IsRequired(); 185 | 186 | b.HasKey("LoginProvider", "ProviderKey"); 187 | 188 | b.HasIndex("UserId"); 189 | 190 | b.ToTable("AspNetUserLogins"); 191 | }); 192 | 193 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 194 | { 195 | b.Property("UserId"); 196 | 197 | b.Property("RoleId"); 198 | 199 | b.HasKey("UserId", "RoleId"); 200 | 201 | b.HasIndex("RoleId"); 202 | 203 | b.ToTable("AspNetUserRoles"); 204 | }); 205 | 206 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 207 | { 208 | b.Property("UserId"); 209 | 210 | b.Property("LoginProvider"); 211 | 212 | b.Property("Name"); 213 | 214 | b.Property("Value"); 215 | 216 | b.HasKey("UserId", "LoginProvider", "Name"); 217 | 218 | b.ToTable("AspNetUserTokens"); 219 | }); 220 | 221 | modelBuilder.Entity("AddItemsDynamically.Models.OrderItem", b => 222 | { 223 | b.HasOne("AddItemsDynamically.Models.Order") 224 | .WithMany("Items") 225 | .HasForeignKey("OrderId"); 226 | }); 227 | 228 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 229 | { 230 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 231 | .WithMany() 232 | .HasForeignKey("RoleId") 233 | .OnDelete(DeleteBehavior.Cascade); 234 | }); 235 | 236 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 237 | { 238 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 239 | .WithMany() 240 | .HasForeignKey("UserId") 241 | .OnDelete(DeleteBehavior.Cascade); 242 | }); 243 | 244 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 245 | { 246 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 247 | .WithMany() 248 | .HasForeignKey("UserId") 249 | .OnDelete(DeleteBehavior.Cascade); 250 | }); 251 | 252 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 253 | { 254 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 255 | .WithMany() 256 | .HasForeignKey("RoleId") 257 | .OnDelete(DeleteBehavior.Cascade); 258 | 259 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 260 | .WithMany() 261 | .HasForeignKey("UserId") 262 | .OnDelete(DeleteBehavior.Cascade); 263 | }); 264 | 265 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 266 | { 267 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 268 | .WithMany() 269 | .HasForeignKey("UserId") 270 | .OnDelete(DeleteBehavior.Cascade); 271 | }); 272 | #pragma warning restore 612, 618 273 | } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /AddItemsDynamically/Migrations/20190926093730_orderName-added.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace AddItemsDynamically.Migrations 4 | { 5 | public partial class orderNameadded : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "IsUrgent", 11 | table: "Order", 12 | nullable: false, 13 | defaultValue: false); 14 | 15 | migrationBuilder.AddColumn( 16 | name: "Name", 17 | table: "Order", 18 | nullable: true); 19 | } 20 | 21 | protected override void Down(MigrationBuilder migrationBuilder) 22 | { 23 | migrationBuilder.DropColumn( 24 | name: "IsUrgent", 25 | table: "Order"); 26 | 27 | migrationBuilder.DropColumn( 28 | name: "Name", 29 | table: "Order"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /AddItemsDynamically/Migrations/ApplicationDbContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using AddItemsDynamically.Data; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | 9 | namespace AddItemsDynamically.Migrations 10 | { 11 | [DbContext(typeof(ApplicationDbContext))] 12 | partial class ApplicationDbContextModelSnapshot : ModelSnapshot 13 | { 14 | protected override void BuildModel(ModelBuilder modelBuilder) 15 | { 16 | #pragma warning disable 612, 618 17 | modelBuilder 18 | .HasAnnotation("ProductVersion", "2.1.11-servicing-32099") 19 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 21 | 22 | modelBuilder.Entity("AddItemsDynamically.Models.Order", b => 23 | { 24 | b.Property("Id") 25 | .ValueGeneratedOnAdd() 26 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 27 | 28 | b.Property("Created"); 29 | 30 | b.Property("IsUrgent"); 31 | 32 | b.Property("Name"); 33 | 34 | b.HasKey("Id"); 35 | 36 | b.ToTable("Order"); 37 | }); 38 | 39 | modelBuilder.Entity("AddItemsDynamically.Models.OrderItem", b => 40 | { 41 | b.Property("Id") 42 | .ValueGeneratedOnAdd() 43 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 44 | 45 | b.Property("OrderId"); 46 | 47 | b.Property("ProductName"); 48 | 49 | b.Property("Quantity"); 50 | 51 | b.HasKey("Id"); 52 | 53 | b.HasIndex("OrderId"); 54 | 55 | b.ToTable("OrderItem"); 56 | }); 57 | 58 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 59 | { 60 | b.Property("Id") 61 | .ValueGeneratedOnAdd(); 62 | 63 | b.Property("ConcurrencyStamp") 64 | .IsConcurrencyToken(); 65 | 66 | b.Property("Name") 67 | .HasMaxLength(256); 68 | 69 | b.Property("NormalizedName") 70 | .HasMaxLength(256); 71 | 72 | b.HasKey("Id"); 73 | 74 | b.HasIndex("NormalizedName") 75 | .IsUnique() 76 | .HasName("RoleNameIndex") 77 | .HasFilter("[NormalizedName] IS NOT NULL"); 78 | 79 | b.ToTable("AspNetRoles"); 80 | }); 81 | 82 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 83 | { 84 | b.Property("Id") 85 | .ValueGeneratedOnAdd() 86 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 87 | 88 | b.Property("ClaimType"); 89 | 90 | b.Property("ClaimValue"); 91 | 92 | b.Property("RoleId") 93 | .IsRequired(); 94 | 95 | b.HasKey("Id"); 96 | 97 | b.HasIndex("RoleId"); 98 | 99 | b.ToTable("AspNetRoleClaims"); 100 | }); 101 | 102 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => 103 | { 104 | b.Property("Id") 105 | .ValueGeneratedOnAdd(); 106 | 107 | b.Property("AccessFailedCount"); 108 | 109 | b.Property("ConcurrencyStamp") 110 | .IsConcurrencyToken(); 111 | 112 | b.Property("Email") 113 | .HasMaxLength(256); 114 | 115 | b.Property("EmailConfirmed"); 116 | 117 | b.Property("LockoutEnabled"); 118 | 119 | b.Property("LockoutEnd"); 120 | 121 | b.Property("NormalizedEmail") 122 | .HasMaxLength(256); 123 | 124 | b.Property("NormalizedUserName") 125 | .HasMaxLength(256); 126 | 127 | b.Property("PasswordHash"); 128 | 129 | b.Property("PhoneNumber"); 130 | 131 | b.Property("PhoneNumberConfirmed"); 132 | 133 | b.Property("SecurityStamp"); 134 | 135 | b.Property("TwoFactorEnabled"); 136 | 137 | b.Property("UserName") 138 | .HasMaxLength(256); 139 | 140 | b.HasKey("Id"); 141 | 142 | b.HasIndex("NormalizedEmail") 143 | .HasName("EmailIndex"); 144 | 145 | b.HasIndex("NormalizedUserName") 146 | .IsUnique() 147 | .HasName("UserNameIndex") 148 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 149 | 150 | b.ToTable("AspNetUsers"); 151 | }); 152 | 153 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 154 | { 155 | b.Property("Id") 156 | .ValueGeneratedOnAdd() 157 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 158 | 159 | b.Property("ClaimType"); 160 | 161 | b.Property("ClaimValue"); 162 | 163 | b.Property("UserId") 164 | .IsRequired(); 165 | 166 | b.HasKey("Id"); 167 | 168 | b.HasIndex("UserId"); 169 | 170 | b.ToTable("AspNetUserClaims"); 171 | }); 172 | 173 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 174 | { 175 | b.Property("LoginProvider"); 176 | 177 | b.Property("ProviderKey"); 178 | 179 | b.Property("ProviderDisplayName"); 180 | 181 | b.Property("UserId") 182 | .IsRequired(); 183 | 184 | b.HasKey("LoginProvider", "ProviderKey"); 185 | 186 | b.HasIndex("UserId"); 187 | 188 | b.ToTable("AspNetUserLogins"); 189 | }); 190 | 191 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 192 | { 193 | b.Property("UserId"); 194 | 195 | b.Property("RoleId"); 196 | 197 | b.HasKey("UserId", "RoleId"); 198 | 199 | b.HasIndex("RoleId"); 200 | 201 | b.ToTable("AspNetUserRoles"); 202 | }); 203 | 204 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 205 | { 206 | b.Property("UserId"); 207 | 208 | b.Property("LoginProvider"); 209 | 210 | b.Property("Name"); 211 | 212 | b.Property("Value"); 213 | 214 | b.HasKey("UserId", "LoginProvider", "Name"); 215 | 216 | b.ToTable("AspNetUserTokens"); 217 | }); 218 | 219 | modelBuilder.Entity("AddItemsDynamically.Models.OrderItem", b => 220 | { 221 | b.HasOne("AddItemsDynamically.Models.Order") 222 | .WithMany("Items") 223 | .HasForeignKey("OrderId"); 224 | }); 225 | 226 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 227 | { 228 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 229 | .WithMany() 230 | .HasForeignKey("RoleId") 231 | .OnDelete(DeleteBehavior.Cascade); 232 | }); 233 | 234 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 235 | { 236 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 237 | .WithMany() 238 | .HasForeignKey("UserId") 239 | .OnDelete(DeleteBehavior.Cascade); 240 | }); 241 | 242 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 243 | { 244 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 245 | .WithMany() 246 | .HasForeignKey("UserId") 247 | .OnDelete(DeleteBehavior.Cascade); 248 | }); 249 | 250 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 251 | { 252 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 253 | .WithMany() 254 | .HasForeignKey("RoleId") 255 | .OnDelete(DeleteBehavior.Cascade); 256 | 257 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 258 | .WithMany() 259 | .HasForeignKey("UserId") 260 | .OnDelete(DeleteBehavior.Cascade); 261 | }); 262 | 263 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 264 | { 265 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 266 | .WithMany() 267 | .HasForeignKey("UserId") 268 | .OnDelete(DeleteBehavior.Cascade); 269 | }); 270 | #pragma warning restore 612, 618 271 | } 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /AddItemsDynamically/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AddItemsDynamically.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } -------------------------------------------------------------------------------- /AddItemsDynamically/Models/Order.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace AddItemsDynamically.Models 5 | { 6 | public class Order 7 | { 8 | public int Id { get; set; } 9 | public string Name { get; set; } 10 | public bool IsUrgent { get; set; } 11 | public List Items { get; set; } 12 | public DateTime Created { get; set; } 13 | 14 | //This should be in ViewModel 15 | public int NumberOfItems 16 | { 17 | get => Items.Count; 18 | } 19 | 20 | public Order() 21 | { 22 | Items = new List(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /AddItemsDynamically/Models/OrderItem.cs: -------------------------------------------------------------------------------- 1 | namespace AddItemsDynamically.Models 2 | { 3 | public class OrderItem 4 | { 5 | public int Id { get; set; } 6 | public string ProductName { get; set; } 7 | public int Quantity { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /AddItemsDynamically/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace AddItemsDynamically 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /AddItemsDynamically/Startup.cs: -------------------------------------------------------------------------------- 1 | using AddItemsDynamically.Data; 2 | using Microsoft.AspNetCore.Builder; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.AspNetCore.Http; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.EntityFrameworkCore; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace AddItemsDynamically 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.Configure(options => 25 | { 26 | // This lambda determines whether user consent for non-essential cookies is needed for a given request. 27 | options.CheckConsentNeeded = context => true; 28 | options.MinimumSameSitePolicy = SameSiteMode.None; 29 | }); 30 | 31 | services.AddDbContext(options => 32 | options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 33 | 34 | 35 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 36 | } 37 | 38 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 39 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 40 | { 41 | if (env.IsDevelopment()) 42 | { 43 | app.UseDeveloperExceptionPage(); 44 | } 45 | else 46 | { 47 | app.UseExceptionHandler("/Home/Error"); 48 | app.UseHsts(); 49 | } 50 | 51 | app.UseHttpsRedirection(); 52 | app.UseStaticFiles(); 53 | app.UseCookiePolicy(); 54 | 55 | app.UseMvc(routes => 56 | { 57 | routes.MapRoute( 58 | name: "default", 59 | template: "{controller=Home}/{action=Index}/{id?}"); 60 | }); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "About"; 3 | } 4 |

@ViewData["Title"]

5 |

@ViewData["Message"]

6 | 7 |

Use this area to provide additional information.

8 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Contact"; 3 | } 4 |

@ViewData["Title"]

5 |

@ViewData["Message"]

6 | 7 |
8 | One Microsoft Way
9 | Redmond, WA 98052-6399
10 | P: 11 | 425.555.0100 12 |
13 | 14 |
15 | Support: Support@example.com
16 | Marketing: Marketing@example.com 17 |
18 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 | 55 | 56 | 95 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

@ViewData["Title"]

5 | 6 |

Use this page to detail your site's privacy policy.

7 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/OrderItems/Create.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.OrderItem 2 | 3 | @{ 4 | ViewData["Title"] = "Create"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Create

9 | 10 |

OrderItem

11 |
12 |
13 |
14 |
15 |
16 |
17 | 18 | 19 | 20 |
21 |
22 | 23 | 24 | 25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 |
34 | Back to List 35 |
36 | 37 | @section Scripts { 38 | @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} 39 | } 40 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/OrderItems/Delete.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.OrderItem 2 | 3 | @{ 4 | ViewData["Title"] = "Delete"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Delete

9 | 10 |

Are you sure you want to delete this?

11 |
12 |

OrderItem

13 |
14 |
15 |
16 | @Html.DisplayNameFor(model => model.ProductName) 17 |
18 |
19 | @Html.DisplayFor(model => model.ProductName) 20 |
21 |
22 | @Html.DisplayNameFor(model => model.Quantity) 23 |
24 |
25 | @Html.DisplayFor(model => model.Quantity) 26 |
27 |
28 | 29 |
30 | 31 | | 32 | Back to List 33 |
34 |
35 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/OrderItems/Details.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.OrderItem 2 | 3 | @{ 4 | ViewData["Title"] = "Details"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Details

9 | 10 |
11 |

OrderItem

12 |
13 |
14 |
15 | @Html.DisplayNameFor(model => model.ProductName) 16 |
17 |
18 | @Html.DisplayFor(model => model.ProductName) 19 |
20 |
21 | @Html.DisplayNameFor(model => model.Quantity) 22 |
23 |
24 | @Html.DisplayFor(model => model.Quantity) 25 |
26 |
27 |
28 |
29 | Edit | 30 | Back to List 31 |
32 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/OrderItems/Edit.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.OrderItem 2 | 3 | @{ 4 | ViewData["Title"] = "Edit"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Edit

9 | 10 |

OrderItem

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 | Back to List 36 |
37 | 38 | @section Scripts { 39 | @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} 40 | } 41 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/OrderItems/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IEnumerable 2 | 3 | @{ 4 | ViewData["Title"] = "Index"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Index

9 | 10 |

11 | Create New 12 |

13 | 14 | 15 | 16 | 19 | 22 | 23 | 24 | 25 | 26 | @foreach (var item in Model) { 27 | 28 | 31 | 34 | 39 | 40 | } 41 | 42 |
17 | @Html.DisplayNameFor(model => model.ProductName) 18 | 20 | @Html.DisplayNameFor(model => model.Quantity) 21 |
29 | @Html.DisplayFor(modelItem => item.ProductName) 30 | 32 | @Html.DisplayFor(modelItem => item.Quantity) 33 | 35 | Edit | 36 | Details | 37 | Delete 38 |
43 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Orders/Create.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.Order 2 | 3 | @{ 4 | ViewData["Title"] = "Create"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Create

9 | 10 |

Order

11 |
12 |
13 |
14 |
15 |
16 |
17 | 18 | 19 | 20 |
21 |
22 |
23 | 26 |
27 |
28 |
29 | @Html.EditorFor(model => model.Items) 30 |
31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 |
40 |
41 |
42 | 43 |
44 | Back to List 45 |
46 | 47 | @section Scripts { 48 | @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} 49 | 63 | } 64 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Orders/Delete.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.Order 2 | 3 | @{ 4 | ViewData["Title"] = "Delete"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Delete

9 | 10 |

Are you sure you want to delete this?

11 |
12 |

Order

13 |
14 |
15 |
16 | @Html.DisplayNameFor(model => model.Name) 17 |
18 |
19 | @Html.DisplayFor(model => model.Name) 20 |
21 |
22 | @Html.DisplayNameFor(model => model.IsUrgent) 23 |
24 |
25 | @Html.DisplayFor(model => model.IsUrgent) 26 |
27 |
28 | @Html.DisplayNameFor(model => model.Created) 29 |
30 |
31 | @Html.DisplayFor(model => model.Created) 32 |
33 |
34 | 35 |
36 | 37 | | 38 | Back to List 39 |
40 |
41 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Orders/Details.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.Order 2 | 3 | @{ 4 | ViewData["Title"] = "Details"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Details

9 | 10 |
11 |

Order

12 |
13 |
14 |
15 | @Html.DisplayNameFor(model => model.Name) 16 |
17 |
18 | @Html.DisplayFor(model => model.Name) 19 |
20 |
21 | @Html.DisplayNameFor(model => model.NumberOfItems) 22 |
23 |
24 | @Html.DisplayFor(model => model.NumberOfItems) 25 |
26 |
27 | @Html.DisplayNameFor(model => model.IsUrgent) 28 |
29 |
30 | @Html.DisplayFor(model => model.IsUrgent) 31 |
32 |
33 | @Html.DisplayNameFor(model => model.Created) 34 |
35 |
36 | @Html.DisplayFor(model => model.Created) 37 |
38 |
39 |
40 |
41 | Edit | 42 | Back to List 43 |
44 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Orders/Edit.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.Order 2 | 3 | @{ 4 | ViewData["Title"] = "Edit"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Edit

9 | 10 |

Order

11 |
12 |
13 |
14 |
15 |
16 | 17 |
18 | 19 | 20 | 21 |
22 |
23 |
24 | 27 |
28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 | 36 |
37 | Back to List 38 |
39 | 40 | @section Scripts { 41 | @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} 42 | } 43 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Orders/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IEnumerable 2 | 3 | @{ 4 | ViewData["Title"] = "Index"; 5 | Layout = "~/Views/Shared/_Layout.cshtml"; 6 | } 7 | 8 |

Index

9 | 10 |

11 | Create New 12 |

13 | 14 | 15 | 16 | 19 | 22 | 25 | 28 | 29 | 30 | 31 | 32 | @foreach (var item in Model) { 33 | 34 | 37 | 40 | 43 | 46 | 51 | 52 | } 53 | 54 |
17 | @Html.DisplayNameFor(model => model.Name) 18 | 20 | @Html.DisplayNameFor(model => model.NumberOfItems) 21 | 23 | @Html.DisplayNameFor(model => model.IsUrgent) 24 | 26 | @Html.DisplayNameFor(model => model.Created) 27 |
35 | @Html.DisplayFor(modelItem => item.Name) 36 | 38 | @Html.DisplayFor(modelItem => item.NumberOfItems) 39 | 41 | @Html.DisplayFor(modelItem => item.IsUrgent) 42 | 44 | @Html.DisplayFor(modelItem => item.Created) 45 | 47 | Edit | 48 | Details | 49 | Delete 50 |
55 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Orders/OrderItems.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.Order 2 | @Html.EditorFor(model => model.Items) -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Shared/EditorTemplates/OrderItem.cshtml: -------------------------------------------------------------------------------- 1 | @model AddItemsDynamically.Models.OrderItem 2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 | 15 | 16 |
17 |
18 |
-------------------------------------------------------------------------------- /AddItemsDynamically/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

12 | Request ID: @Model.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 22 |

23 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Shared/_CookieConsentPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Http.Features 2 | 3 | @{ 4 | var consentFeature = Context.Features.Get(); 5 | var showBanner = !consentFeature?.CanTrack ?? false; 6 | var cookieString = consentFeature?.CreateConsentCookie(); 7 | } 8 | 9 | @if (showBanner) 10 | { 11 | 33 | 41 | } -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - AddItemsDynamically 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 39 | 40 | 41 | 42 |
43 | @RenderBody() 44 |
45 |
46 |

© 2019 - AddItemsDynamically

47 |
48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 62 | 68 | 69 | 70 | 71 | @RenderSection("Scripts", required: false) 72 | 73 | 74 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using AddItemsDynamically 2 | @using AddItemsDynamically.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /AddItemsDynamically/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /AddItemsDynamically/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /AddItemsDynamically/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=sampleDb;Trusted_Connection=True;MultipleActiveResultSets=true" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*" 11 | } 12 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\ 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | body { 4 | padding-top: 50px; 5 | padding-bottom: 20px; 6 | } 7 | 8 | /* Wrapping element */ 9 | /* Set some basic padding to keep content from hitting the edges */ 10 | .body-content { 11 | padding-left: 15px; 12 | padding-right: 15px; 13 | } 14 | 15 | /* Carousel */ 16 | .carousel-caption p { 17 | font-size: 20px; 18 | line-height: 1.4; 19 | } 20 | 21 | /* Make .svg files in the carousel display properly in older browsers */ 22 | .carousel-inner .item img[src$=".svg"] { 23 | width: 100%; 24 | } 25 | 26 | /* QR code generator */ 27 | #qrCode { 28 | margin: 15px; 29 | } 30 | 31 | /* Hide/rearrange for smaller screens */ 32 | @media screen and (max-width: 767px) { 33 | /* Hide captions */ 34 | .carousel-caption { 35 | display: none; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/wwwroot/favicon.ico -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/images/banner1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/images/banner2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/images/banner3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 3" 33 | }, 34 | "version": "3.3.7", 35 | "_release": "3.3.7", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.7", 39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 40 | }, 41 | "_source": "https://github.com/twbs/bootstrap.git", 42 | "_target": "v3.3.7", 43 | "_originalSource": "bootstrap", 44 | "_direct": true 45 | } -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Twitter, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevcooo/AddItemsDynamically/a488fafc3be35d15663892e739f0debbfd41ffb8/AddItemsDynamically/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 4 | "version": "3.2.9", 5 | "_release": "3.2.9", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "v3.2.9", 9 | "commit": "a91f5401898e125f10771c5f5f0909d8c4c82396" 10 | }, 11 | "_source": "https://github.com/aspnet/jquery-validation-unobtrusive.git", 12 | "_target": "^3.2.9", 13 | "_originalSource": "jquery-validation-unobtrusive", 14 | "_direct": true 15 | } -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (C) Microsoft Corporation. All rights reserved. 3 | // @version v3.2.9 4 | 5 | /*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 */ 6 | /*global document: false, jQuery: false */ 7 | 8 | (function (factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | // AMD. Register as an anonymous module. 11 | define("jquery.validate.unobtrusive", ['jquery.validation'], factory); 12 | } else if (typeof module === 'object' && module.exports) { 13 | // CommonJS-like environments that support module.exports 14 | module.exports = factory(require('jquery-validation')); 15 | } else { 16 | // Browser global 17 | jQuery.validator.unobtrusive = factory(jQuery); 18 | } 19 | }(function ($) { 20 | var $jQval = $.validator, 21 | adapters, 22 | data_validation = "unobtrusiveValidation"; 23 | 24 | function setValidationValues(options, ruleName, value) { 25 | options.rules[ruleName] = value; 26 | if (options.message) { 27 | options.messages[ruleName] = options.message; 28 | } 29 | } 30 | 31 | function splitAndTrim(value) { 32 | return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); 33 | } 34 | 35 | function escapeAttributeValue(value) { 36 | // As mentioned on http://api.jquery.com/category/selectors/ 37 | return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); 38 | } 39 | 40 | function getModelPrefix(fieldName) { 41 | return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); 42 | } 43 | 44 | function appendModelPrefix(value, prefix) { 45 | if (value.indexOf("*.") === 0) { 46 | value = value.replace("*.", prefix); 47 | } 48 | return value; 49 | } 50 | 51 | function onError(error, inputElement) { // 'this' is the form element 52 | var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), 53 | replaceAttrValue = container.attr("data-valmsg-replace"), 54 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; 55 | 56 | container.removeClass("field-validation-valid").addClass("field-validation-error"); 57 | error.data("unobtrusiveContainer", container); 58 | 59 | if (replace) { 60 | container.empty(); 61 | error.removeClass("input-validation-error").appendTo(container); 62 | } 63 | else { 64 | error.hide(); 65 | } 66 | } 67 | 68 | function onErrors(event, validator) { // 'this' is the form element 69 | var container = $(this).find("[data-valmsg-summary=true]"), 70 | list = container.find("ul"); 71 | 72 | if (list && list.length && validator.errorList.length) { 73 | list.empty(); 74 | container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 75 | 76 | $.each(validator.errorList, function () { 77 | $("
  • ").html(this.message).appendTo(list); 78 | }); 79 | } 80 | } 81 | 82 | function onSuccess(error) { // 'this' is the form element 83 | var container = error.data("unobtrusiveContainer"); 84 | 85 | if (container) { 86 | var replaceAttrValue = container.attr("data-valmsg-replace"), 87 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; 88 | 89 | container.addClass("field-validation-valid").removeClass("field-validation-error"); 90 | error.removeData("unobtrusiveContainer"); 91 | 92 | if (replace) { 93 | container.empty(); 94 | } 95 | } 96 | } 97 | 98 | function onReset(event) { // 'this' is the form element 99 | var $form = $(this), 100 | key = '__jquery_unobtrusive_validation_form_reset'; 101 | if ($form.data(key)) { 102 | return; 103 | } 104 | // Set a flag that indicates we're currently resetting the form. 105 | $form.data(key, true); 106 | try { 107 | $form.data("validator").resetForm(); 108 | } finally { 109 | $form.removeData(key); 110 | } 111 | 112 | $form.find(".validation-summary-errors") 113 | .addClass("validation-summary-valid") 114 | .removeClass("validation-summary-errors"); 115 | $form.find(".field-validation-error") 116 | .addClass("field-validation-valid") 117 | .removeClass("field-validation-error") 118 | .removeData("unobtrusiveContainer") 119 | .find(">*") // If we were using valmsg-replace, get the underlying error 120 | .removeData("unobtrusiveContainer"); 121 | } 122 | 123 | function validationInfo(form) { 124 | var $form = $(form), 125 | result = $form.data(data_validation), 126 | onResetProxy = $.proxy(onReset, form), 127 | defaultOptions = $jQval.unobtrusive.options || {}, 128 | execInContext = function (name, args) { 129 | var func = defaultOptions[name]; 130 | func && $.isFunction(func) && func.apply(form, args); 131 | }; 132 | 133 | if (!result) { 134 | result = { 135 | options: { // options structure passed to jQuery Validate's validate() method 136 | errorClass: defaultOptions.errorClass || "input-validation-error", 137 | errorElement: defaultOptions.errorElement || "span", 138 | errorPlacement: function () { 139 | onError.apply(form, arguments); 140 | execInContext("errorPlacement", arguments); 141 | }, 142 | invalidHandler: function () { 143 | onErrors.apply(form, arguments); 144 | execInContext("invalidHandler", arguments); 145 | }, 146 | messages: {}, 147 | rules: {}, 148 | success: function () { 149 | onSuccess.apply(form, arguments); 150 | execInContext("success", arguments); 151 | } 152 | }, 153 | attachValidation: function () { 154 | $form 155 | .off("reset." + data_validation, onResetProxy) 156 | .on("reset." + data_validation, onResetProxy) 157 | .validate(this.options); 158 | }, 159 | validate: function () { // a validation function that is called by unobtrusive Ajax 160 | $form.validate(); 161 | return $form.valid(); 162 | } 163 | }; 164 | $form.data(data_validation, result); 165 | } 166 | 167 | return result; 168 | } 169 | 170 | $jQval.unobtrusive = { 171 | adapters: [], 172 | 173 | parseElement: function (element, skipAttach) { 174 | /// 175 | /// Parses a single HTML element for unobtrusive validation attributes. 176 | /// 177 | /// The HTML element to be parsed. 178 | /// [Optional] true to skip attaching the 179 | /// validation to the form. If parsing just this single element, you should specify true. 180 | /// If parsing several elements, you should specify false, and manually attach the validation 181 | /// to the form when you are finished. The default is false. 182 | var $element = $(element), 183 | form = $element.parents("form")[0], 184 | valInfo, rules, messages; 185 | 186 | if (!form) { // Cannot do client-side validation without a form 187 | return; 188 | } 189 | 190 | valInfo = validationInfo(form); 191 | valInfo.options.rules[element.name] = rules = {}; 192 | valInfo.options.messages[element.name] = messages = {}; 193 | 194 | $.each(this.adapters, function () { 195 | var prefix = "data-val-" + this.name, 196 | message = $element.attr(prefix), 197 | paramValues = {}; 198 | 199 | if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy) 200 | prefix += "-"; 201 | 202 | $.each(this.params, function () { 203 | paramValues[this] = $element.attr(prefix + this); 204 | }); 205 | 206 | this.adapt({ 207 | element: element, 208 | form: form, 209 | message: message, 210 | params: paramValues, 211 | rules: rules, 212 | messages: messages 213 | }); 214 | } 215 | }); 216 | 217 | $.extend(rules, { "__dummy__": true }); 218 | 219 | if (!skipAttach) { 220 | valInfo.attachValidation(); 221 | } 222 | }, 223 | 224 | parse: function (selector) { 225 | /// 226 | /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 227 | /// with the [data-val=true] attribute value and enables validation according to the data-val-* 228 | /// attribute values. 229 | /// 230 | /// Any valid jQuery selector. 231 | 232 | // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one 233 | // element with data-val=true 234 | var $selector = $(selector), 235 | $forms = $selector.parents() 236 | .addBack() 237 | .filter("form") 238 | .add($selector.find("form")) 239 | .has("[data-val=true]"); 240 | 241 | $selector.find("[data-val=true]").each(function () { 242 | $jQval.unobtrusive.parseElement(this, true); 243 | }); 244 | 245 | $forms.each(function () { 246 | var info = validationInfo(this); 247 | if (info) { 248 | info.attachValidation(); 249 | } 250 | }); 251 | } 252 | }; 253 | 254 | adapters = $jQval.unobtrusive.adapters; 255 | 256 | adapters.add = function (adapterName, params, fn) { 257 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation. 258 | /// The name of the adapter to be added. This matches the name used 259 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 260 | /// [Optional] An array of parameter names (strings) that will 261 | /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and 262 | /// mmmm is the parameter name). 263 | /// The function to call, which adapts the values from the HTML 264 | /// attributes into jQuery Validate rules and/or messages. 265 | /// 266 | if (!fn) { // Called with no params, just a function 267 | fn = params; 268 | params = []; 269 | } 270 | this.push({ name: adapterName, params: params, adapt: fn }); 271 | return this; 272 | }; 273 | 274 | adapters.addBool = function (adapterName, ruleName) { 275 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 276 | /// the jQuery Validate validation rule has no parameter values. 277 | /// The name of the adapter to be added. This matches the name used 278 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 279 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 280 | /// of adapterName will be used instead. 281 | /// 282 | return this.add(adapterName, function (options) { 283 | setValidationValues(options, ruleName || adapterName, true); 284 | }); 285 | }; 286 | 287 | adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { 288 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 289 | /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and 290 | /// one for min-and-max). The HTML parameters are expected to be named -min and -max. 291 | /// The name of the adapter to be added. This matches the name used 292 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 293 | /// The name of the jQuery Validate rule to be used when you only 294 | /// have a minimum value. 295 | /// The name of the jQuery Validate rule to be used when you only 296 | /// have a maximum value. 297 | /// The name of the jQuery Validate rule to be used when you 298 | /// have both a minimum and maximum value. 299 | /// [Optional] The name of the HTML attribute that 300 | /// contains the minimum value. The default is "min". 301 | /// [Optional] The name of the HTML attribute that 302 | /// contains the maximum value. The default is "max". 303 | /// 304 | return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { 305 | var min = options.params.min, 306 | max = options.params.max; 307 | 308 | if (min && max) { 309 | setValidationValues(options, minMaxRuleName, [min, max]); 310 | } 311 | else if (min) { 312 | setValidationValues(options, minRuleName, min); 313 | } 314 | else if (max) { 315 | setValidationValues(options, maxRuleName, max); 316 | } 317 | }); 318 | }; 319 | 320 | adapters.addSingleVal = function (adapterName, attribute, ruleName) { 321 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 322 | /// the jQuery Validate validation rule has a single value. 323 | /// The name of the adapter to be added. This matches the name used 324 | /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name). 325 | /// [Optional] The name of the HTML attribute that contains the value. 326 | /// The default is "val". 327 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 328 | /// of adapterName will be used instead. 329 | /// 330 | return this.add(adapterName, [attribute || "val"], function (options) { 331 | setValidationValues(options, ruleName || adapterName, options.params[attribute]); 332 | }); 333 | }; 334 | 335 | $jQval.addMethod("__dummy__", function (value, element, params) { 336 | return true; 337 | }); 338 | 339 | $jQval.addMethod("regex", function (value, element, params) { 340 | var match; 341 | if (this.optional(element)) { 342 | return true; 343 | } 344 | 345 | match = new RegExp(params).exec(value); 346 | return (match && (match.index === 0) && (match[0].length === value.length)); 347 | }); 348 | 349 | $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { 350 | var match; 351 | if (nonalphamin) { 352 | match = value.match(/\W/g); 353 | match = match && match.length >= nonalphamin; 354 | } 355 | return match; 356 | }); 357 | 358 | if ($jQval.methods.extension) { 359 | adapters.addSingleVal("accept", "mimtype"); 360 | adapters.addSingleVal("extension", "extension"); 361 | } else { 362 | // for backward compatibility, when the 'extension' validation method does not exist, such as with versions 363 | // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for 364 | // validating the extension, and ignore mime-type validations as they are not supported. 365 | adapters.addSingleVal("extension", "extension", "accept"); 366 | } 367 | 368 | adapters.addSingleVal("regex", "pattern"); 369 | adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); 370 | adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); 371 | adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); 372 | adapters.add("equalto", ["other"], function (options) { 373 | var prefix = getModelPrefix(options.element.name), 374 | other = options.params.other, 375 | fullOtherName = appendModelPrefix(other, prefix), 376 | element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; 377 | 378 | setValidationValues(options, "equalTo", element); 379 | }); 380 | adapters.add("required", function (options) { 381 | // jQuery Validate equates "required" with "mandatory" for checkbox elements 382 | if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { 383 | setValidationValues(options, "required", true); 384 | } 385 | }); 386 | adapters.add("remote", ["url", "type", "additionalfields"], function (options) { 387 | var value = { 388 | url: options.params.url, 389 | type: options.params.type || "GET", 390 | data: {} 391 | }, 392 | prefix = getModelPrefix(options.element.name); 393 | 394 | $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { 395 | var paramName = appendModelPrefix(fieldName, prefix); 396 | value.data[paramName] = function () { 397 | var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']"); 398 | // For checkboxes and radio buttons, only pick up values from checked fields. 399 | if (field.is(":checkbox")) { 400 | return field.filter(":checked").val() || field.filter(":hidden").val() || ''; 401 | } 402 | else if (field.is(":radio")) { 403 | return field.filter(":checked").val() || ''; 404 | } 405 | return field.val(); 406 | }; 407 | }); 408 | 409 | setValidationValues(options, "remote", value); 410 | }); 411 | adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { 412 | if (options.params.min) { 413 | setValidationValues(options, "minlength", options.params.min); 414 | } 415 | if (options.params.nonalphamin) { 416 | setValidationValues(options, "nonalphamin", options.params.nonalphamin); 417 | } 418 | if (options.params.regex) { 419 | setValidationValues(options, "regex", options.params.regex); 420 | } 421 | }); 422 | adapters.add("fileextensions", ["extensions"], function (options) { 423 | setValidationValues(options, "extension", options.params.extensions); 424 | }); 425 | 426 | $(function () { 427 | $jQval.unobtrusive.parse(document); 428 | }); 429 | 430 | return $jQval.unobtrusive; 431 | })); -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (C) Microsoft Corporation. All rights reserved. 3 | // @version v3.2.9 4 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery.validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "https://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jquery-validation/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.17.0", 31 | "_release": "1.17.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.17.0", 35 | "commit": "fc9b12d3bfaa2d0c04605855b896edb2934c0772" 36 | }, 37 | "_source": "https://github.com/jzaefferer/jquery-validation.git", 38 | "_target": "^1.17.0", 39 | "_originalSource": "jquery-validation", 40 | "_direct": true 41 | } -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery-validation/dist/additional-methods.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g,h="string"==typeof d?d.replace(/\s/g,""):"image/*",i=this.optional(c);if(i)return i;if("file"===a(c).attr("type")&&(h=h.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g,"\\$&").replace(/,/g,"|").replace(/\/\*/g,"/.*"),c.files&&c.files.length))for(g=new RegExp(".?("+h+")$","i"),e=0;e9?"0":f,g="JABCDEFGHI".substr(f,1).toString(),i.match(/[ABEH]/)?k===f:i.match(/[KPQS]/)?k===g:k===f||k===g},"Please specify a valid CIF number."),a.validator.addMethod("cpfBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;e<=9;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;e<=10;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=!!e||c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="",q=5;if(l.length9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("netmask",function(a,b){return this.optional(b)||/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test(a)},"Please enter a valid netmask."),a.validator.addMethod("nieES",function(a,b){"use strict";if(this.optional(b))return!0;var c,d=new RegExp(/^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi),e="TRWAGMYFPDXBNJZSQVHLCKET",f=a.substr(a.length-1).toUpperCase();return a=a.toString().toUpperCase(),!(a.length>10||a.length<9||!d.test(a))&&(a=a.replace(/^[X]/,"0").replace(/^[Y]/,"1").replace(/^[Z]/,"2"),c=9===a.length?a.substr(0,8):a.substr(0,9),e.charAt(parseInt(c,10)%23)===f)},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a,b){"use strict";return!!this.optional(b)||(a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):!!/^[KLM]{1}/.test(a)&&a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,1)%23)))},"Please specify a valid NIF number."),a.validator.addMethod("nipPL",function(a){"use strict";if(a=a.replace(/[^0-9]/g,""),10!==a.length)return!1;for(var b=[6,5,7,2,3,4,5,6,7],c=0,d=0;d<9;d++)c+=b[d]*a[d];var e=c%11,f=10===e?0:e;return f===parseInt(a[9],10)},"Please specify a valid NIP number."),a.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return!!this.optional(b)||("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=!e&&"undefined"!=typeof c.caseSensitive&&c.caseSensitive,g=!e&&"undefined"!=typeof c.includeTerritories&&c.includeTerritories,h=!e&&"undefined"!=typeof c.includeMilitary&&c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(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(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!c.settings.submitHandler||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&(!j.form&&j.hasAttribute("contenteditable")&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},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.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name"));var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":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'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=d),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);if("function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f){if(j=f.call(b,j),"string"!=typeof j)throw new TypeError("The normalizer should return a string value.");delete g.normalizer}for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+""),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],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 a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},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(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a}); -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "3.3.1", 16 | "_release": "3.3.1", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "3.3.1", 20 | "commit": "9e8ec3d10fad04748176144f108d7355662ae75e" 21 | }, 22 | "_source": "https://github.com/jquery/jquery-dist.git", 23 | "_target": "^3.3.1", 24 | "_originalSource": "jquery", 25 | "_direct": true 26 | } -------------------------------------------------------------------------------- /AddItemsDynamically/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AddItemsDynamically 2 | Very often there is a need to add items in a collection of items. Usually we have some object that holds a list of complex objects, for 3 | example, one Order contains several OrderItems which are complex objects (has their properties). When creating a Controller and View for such object, Razor ignores these properties and doesn't create input fields for them. 4 | In this example, I can show you how I solve this problem without refreshing the page. 5 | 6 | ![animation](AddItemsDynamically/Media/AddItemsToList.gif) 7 | 8 | One of the first thins that you should do is to create an Editor for the Objects that are in the list, in this example the order items. This editor is simple copy-paste from its `Edit.cshtml file`, but remember to remove the `
    ` element, otherwise, the submit button will not work. Name of the editor must be the same as the name of the model that you're editing, in this case, `OrderItem` and place it under `Views/Shared/EditorTemplates`. If you don't have the `EditorTemplates` folder under `Shared`, create it. 9 | 10 | ![EditorTemplate](AddItemsDynamically/Media/OrderItemTemplate.png) 11 | 12 | When we have the EditorTemplate we can use it in the `Create.cshtml` file to display the collection of the items. Usually, we place this part in a separate `div` element with specific `id` (in this case it's `id="orderItemsContainer"` so we can later change the content of this div with ajax. 13 | 14 | ![EditorTemplate](AddItemsDynamically/Media/UsingEditorInCreate.png) 15 | 16 | After displaying the items, we should create a button that can be pressed to add a new element to the list. Let's create the Add Button together with the javascript code, that will be used for the ajax call. 17 | 18 | ![EditorTemplate](AddItemsDynamically/Media/AddButonAndJavScript.png) 19 | 20 | To be able to serialize this form, we should also add an `id` to the form in the create file. 21 | 22 | ![EditorTemplate](AddItemsDynamically/Media/FormIdAndSerialize.png) 23 | 24 | As you noted, we call a method `AddOrderItem` from `Orders` controller in the javascript ajax method, and this method we should also create in the controller and set up it's binding. This method in the controller is adding a new element to the list and rendering the whole list as a partial view which is later shown in the HTML. 25 | 26 | ![EditorTemplate](AddItemsDynamically/Media/AddOrderItemMethod.png) 27 | 28 | In the `AddOrderItem` method, we're returning PartialView where we render the list of the order items. Create a partial view in your Views/Order folder called `OrderItems.cshtml`. The Partial view is pretty much simple, it should only use the editor that we created previously. 29 | 30 | ![EditorTemplate](AddItemsDynamically/Media/PartialView.png) 31 | 32 | When we have everything shown on the screen, now we should add the binding for the list in the create method of the controller and we are ready to use it (include Items in the binding list, because they are not included by default). 33 | 34 | ![EditorTemplate](AddItemsDynamically/Media/CreateMethod.png) 35 | 36 | Notice that we changed the model, we added a default constructor that will initialize the list. Also, I've added a property that will give us the total number of items in the list, usually this logic should be in ViewModel, but for the sake of simplicity, I put it in the model. 37 | 38 | ![EditorTemplate](AddItemsDynamically/Media/OrderModel.png) 39 | --------------------------------------------------------------------------------