From 74a72a2030cb3755538ba465fe8ddfa48f5f8e8a Mon Sep 17 00:00:00 2001 From: Jonathan Park Date: Sat, 30 Jul 2011 11:06:23 -0700 Subject: [PATCH] Adding scaffolding --- GARDIS.sln | 3 + GARDIS.suo | Bin 20480 -> 49664 bytes .../ControllerWithContext.cs.t4 | 159 + .../DbContextEntityMember.cs.t4 | 2 + .../Repository.cs.t4 | 103 + .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 213 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 268 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 186 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 158 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 167 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 174 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 183 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 143 bytes .../base/images/ui-icons_222222_256x240.png | Bin 0 -> 7813 bytes .../base/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 8127 bytes .../base/images/ui-icons_454545_256x240.png | Bin 0 -> 7813 bytes .../base/images/ui-icons_888888_256x240.png | Bin 0 -> 8289 bytes .../base/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 7973 bytes GARDIS/Content/themes/base/jquery-ui.css | 635 + .../Controllers/Games/CategoryController.cs | 100 + GARDIS/Controllers/Games/EnvDTE.cs | 1 + GARDIS/Controllers/Games/Model.cs | 1 + GARDIS/Controllers/GamesController.cs | 99 + GARDIS/Controllers/HomeController.cs | 20 + GARDIS/Controllers/UserController.cs | 20 + GARDIS/Controllers/UsersController.cs | 99 + GARDIS/GARDIS.csproj | 140 +- GARDIS/GARDIS.csproj.user | 2 +- GARDIS/Models/DataBase.cs | 78 + GARDIS/Models/GARDISContext.cs | 26 + GARDIS/Models/Game.cs | 24 + GARDIS/Models/ICollectable.cs | 10 + GARDIS/Models/Properties/Game/Category.cs | 14 + GARDIS/Models/Properties/Game/Players.cs | 15 + GARDIS/Models/Properties/Game/Type.cs | 14 + GARDIS/Models/User.cs | 16 + .../Scripts/MicrosoftMvcValidation.debug.js | 18 +- GARDIS/Scripts/MicrosoftMvcValidation.js | 8 +- GARDIS/Scripts/jquery-1.4.1-vsdoc.js | 8061 ---- GARDIS/Scripts/jquery-1.4.1.js | 6111 --- GARDIS/Scripts/jquery-1.4.1.min.js | 167 - GARDIS/Scripts/jquery-1.6.2-vsdoc.js | 6987 ++++ GARDIS/Scripts/jquery-1.6.2.js | 8981 ++++ GARDIS/Scripts/jquery-1.6.2.min.js | 18 + GARDIS/Scripts/jquery-ui.js | 11630 +++++ GARDIS/Scripts/jquery-ui.min.js | 409 + GARDIS/Scripts/jquery.unobtrusive-ajax.js | 165 + GARDIS/Scripts/jquery.unobtrusive-ajax.min.js | 5 + GARDIS/Scripts/jquery.validate.unobtrusive.js | 319 + .../jquery.validate.unobtrusive.min.js | 5 + GARDIS/Views/Games/Category/Create.cshtml | 26 + GARDIS/Views/Games/Category/Delete.cshtml | 23 + GARDIS/Views/Games/Category/Details.cshtml | 20 + GARDIS/Views/Games/Category/Edit.cshtml | 24 + GARDIS/Views/Games/Category/Index.cshtml | 35 + .../Views/Games/Category/_CreateOrEdit.cshtml | 12 + GARDIS/Views/Games/Create.cshtml | 26 + GARDIS/Views/Games/Delete.cshtml | 35 + GARDIS/Views/Games/Details.cshtml | 32 + GARDIS/Views/Games/Edit.cshtml | 24 + GARDIS/Views/Games/Index.cshtml | 59 + GARDIS/Views/Games/_CreateOrEdit.cshtml | 20 + GARDIS/Views/Home/Index.cshtml | 16 + GARDIS/Views/Users/Create.cshtml | 26 + GARDIS/Views/Users/Delete.cshtml | 29 + GARDIS/Views/Users/Details.cshtml | 26 + GARDIS/Views/Users/Edit.cshtml | 24 + GARDIS/Views/Users/Index.cshtml | 47 + GARDIS/Views/Users/_CreateOrEdit.cshtml | 28 + GARDIS/Views/Web.config | 38 +- GARDIS/Web.config | 82 +- GARDIS/bin/DotNetOpenAuth.dll | Bin 0 -> 1006592 bytes GARDIS/bin/DotNetOpenAuth.dll.mdb | Bin 0 -> 265966 bytes GARDIS/bin/DotNetOpenAuth.xml | 34921 ++++++++++++++++ GARDIS/bin/EntityFramework.dll | Bin 0 -> 792880 bytes GARDIS/bin/EntityFramework.xml | 13478 ++++++ GARDIS/bin/GARDIS.dll | Bin 0 -> 18432 bytes GARDIS/bin/GARDIS.pdb | Bin 0 -> 44544 bytes .../Microsoft.Practices.ServiceLocation.dll | Bin 0 -> 29760 bytes .../Microsoft.Practices.ServiceLocation.pdb | Bin 0 -> 24064 bytes .../Microsoft.Practices.ServiceLocation.xml | 280 + ...icrosoft.Practices.Unity.Configuration.dll | Bin 0 -> 86840 bytes ...icrosoft.Practices.Unity.Configuration.xml | 2451 ++ GARDIS/bin/Microsoft.Practices.Unity.dll | Bin 0 -> 124216 bytes GARDIS/bin/Microsoft.Practices.Unity.xml | 5910 +++ GARDIS/bin/Newtonsoft.Json.dll | Bin 0 -> 348160 bytes GARDIS/bin/Newtonsoft.Json.pdb | Bin 0 -> 949760 bytes GARDIS/bin/Newtonsoft.Json.xml | 6862 +++ GARDIS/bin/Norm.dll | Bin 0 -> 210432 bytes GARDIS/bin/Norm.dll.mdb | Bin 0 -> 84037 bytes GARDIS/bin/Norm.pdb | Bin 0 -> 519680 bytes GARDIS/bin/Norm.xml | 6614 +++ GARDIS/bin/jonathan.silvenstudios.com.pdb | Bin 0 -> 56832 bytes GARDIS/bin/log4net.dll | Bin 0 -> 270336 bytes GARDIS/bin/log4net.xml | 28655 +++++++++++++ ...gnTimeResolveAssemblyReferencesInput.cache | Bin 8995 -> 15369 bytes .../Debug/GARDIS.csproj.FileListAbsolute.txt | 23 + GARDIS/obj/Debug/GARDIS.dll | Bin 0 -> 18432 bytes GARDIS/obj/Debug/GARDIS.pdb | Bin 0 -> 44544 bytes .../obj/Debug/ResolveAssemblyReference.cache | Bin 0 -> 102199 bytes GARDIS/packages.config | 11 + .../CommonServiceLocator.1.0.nupkg | Bin 0 -> 37216 bytes .../Microsoft.Practices.ServiceLocation.XML | 280 + .../Microsoft.Practices.ServiceLocation.dll | Bin 0 -> 29760 bytes .../Microsoft.Practices.ServiceLocation.pdb | Bin 0 -> 24064 bytes .../Microsoft.Practices.ServiceLocation.XML | 280 + .../Microsoft.Practices.ServiceLocation.dll | Bin 0 -> 26504 bytes .../DotNetOpenAuth.3.4.7.11121.nupkg | Bin 0 -> 825428 bytes .../content/web.config.transform | 69 + .../lib/DotNetOpenAuth.dll | Bin 0 -> 1006592 bytes .../lib/DotNetOpenAuth.xml | 34921 ++++++++++++++++ .../EntityFramework.4.1.10715.0.nupkg | Bin 0 -> 464972 bytes .../lib/EntityFramework.dll | Bin 0 -> 792880 bytes .../lib/EntityFramework.xml | 13478 ++++++ .../MvcScaffolding.1.0.0.nupkg | Bin 0 -> 92977 bytes .../content/InstallationDummyFile.txt | 2 + .../tools/Action/Action.cs.t4 | 12 + .../tools/Action/Action.vb.t4 | 10 + .../tools/Action/ActionPost.cs.t4 | 11 + .../tools/Action/ActionPost.vb.t4 | 11 + .../tools/Action/MvcScaffolding.Action.ps1 | 70 + .../tools/Action/ViewModel.cs.t4 | 13 + .../tools/Action/ViewModel.vb.t4 | 7 + .../MvcScaffolding.ActionUnitTest.ps1 | 53 + .../tools/ActionUnitTest/TestClass.cs.t4 | 15 + .../tools/ActionUnitTest/TestClass.vb.t4 | 11 + .../tools/ActionUnitTest/TestMethod.cs.t4 | 40 + .../tools/ActionUnitTest/TestMethod.vb.t4 | 42 + .../MvcScaffolding.ActionWithUnitTest.ps1 | 15 + .../tools/AspxView/Create.cs.t4 | 194 + .../tools/AspxView/Create.vb.t4 | 200 + .../tools/AspxView/CreateOrEdit.cs.t4 | 138 + .../tools/AspxView/CreateOrEdit.vb.t4 | 136 + .../tools/AspxView/Delete.cs.t4 | 193 + .../tools/AspxView/Delete.vb.t4 | 195 + .../tools/AspxView/Details.cs.t4 | 202 + .../tools/AspxView/Details.vb.t4 | 201 + .../tools/AspxView/Edit.cs.t4 | 198 + .../tools/AspxView/Edit.vb.t4 | 203 + .../tools/AspxView/Empty.cs.t4 | 79 + .../tools/AspxView/Empty.vb.t4 | 81 + .../tools/AspxView/Index.cs.t4 | 227 + .../tools/AspxView/Index.vb.t4 | 228 + .../AspxView/MvcScaffolding.AspxView.ps1 | 40 + .../Controller/ControllerWithContext.cs.t4 | 159 + .../Controller/ControllerWithContext.vb.t4 | 129 + .../Controller/ControllerWithRepository.cs.t4 | 173 + .../Controller/ControllerWithRepository.vb.t4 | 141 + .../Controller/MvcScaffolding.Controller.ps1 | 127 + ...vcScaffolding.ControllerWithRepository.ps1 | 36 + .../tools/RazorView/Create.cs.t4 | 140 + .../tools/RazorView/Create.vb.t4 | 137 + .../tools/RazorView/Delete.cs.t4 | 136 + .../tools/RazorView/Delete.vb.t4 | 139 + .../tools/RazorView/Details.cs.t4 | 138 + .../tools/RazorView/Details.vb.t4 | 141 + .../tools/RazorView/Edit.cs.t4 | 137 + .../tools/RazorView/Edit.vb.t4 | 140 + .../tools/RazorView/Empty.cs.t4 | 15 + .../tools/RazorView/Empty.vb.t4 | 15 + .../tools/RazorView/Index.cs.t4 | 165 + .../tools/RazorView/Index.vb.t4 | 174 + .../RazorView/MvcScaffolding.RazorView.ps1 | 60 + .../tools/RazorView/_CreateOrEdit.cs.t4 | 139 + .../tools/RazorView/_CreateOrEdit.vb.t4 | 137 + .../tools/Views/MvcScaffolding.Views.ps1 | 19 + packages/MvcScaffolding.1.0.0/tools/init.ps1 | 16 + .../MvcScaffolding.1.0.0/tools/install.ps1 | 31 + .../tools/registerWithMvcTooling.ps1 | 138 + .../Newtonsoft.Json.4.0.2.nupkg | Bin 0 -> 2369113 bytes .../lib/net20/Newtonsoft.Json.Net20.dll | Bin 0 -> 406016 bytes .../lib/net20/Newtonsoft.Json.Net20.pdb | Bin 0 -> 855552 bytes .../lib/net20/Newtonsoft.Json.Net20.xml | 6520 +++ .../lib/net35/Newtonsoft.Json.Net35.dll | Bin 0 -> 325632 bytes .../lib/net35/Newtonsoft.Json.Net35.pdb | Bin 0 -> 898560 bytes .../lib/net35/Newtonsoft.Json.Net35.xml | 6711 +++ .../lib/net40/Newtonsoft.Json.dll | Bin 0 -> 348160 bytes .../lib/net40/Newtonsoft.Json.pdb | Bin 0 -> 949760 bytes .../lib/net40/Newtonsoft.Json.xml | 6862 +++ .../sl3-wp/Newtonsoft.Json.WindowsPhone.dll | Bin 0 -> 295936 bytes .../sl3-wp/Newtonsoft.Json.WindowsPhone.pdb | Bin 0 -> 810496 bytes .../sl3-wp/Newtonsoft.Json.WindowsPhone.xml | 6331 +++ .../lib/sl4/Newtonsoft.Json.Silverlight.dll | Bin 0 -> 299520 bytes .../lib/sl4/Newtonsoft.Json.Silverlight.pdb | Bin 0 -> 816640 bytes .../lib/sl4/Newtonsoft.Json.Silverlight.xml | 6361 +++ .../T4Scaffolding.1.0.1.nupkg | Bin 0 -> 95637 bytes .../content/InstallationDummyFile.txt | 2 + .../CustomScaffolder/DefaultPs1Script.ps1.t4 | 17 + .../CustomScaffolder/DefaultT4Template.cs.t4 | 16 + .../CustomScaffolder/DefaultT4Template.vb.t4 | 9 + .../T4Scaffolding.CustomScaffolder.ps1 | 23 + .../T4Scaffolding.CustomTemplate.ps1 | 45 + .../tools/EFDbContext/DbContext.cs.t4 | 23 + .../tools/EFDbContext/DbContext.vb.t4 | 18 + .../EFDbContext/DbContextEntityMember.cs.t4 | 2 + .../EFDbContext/DbContextEntityMember.vb.t4 | 2 + .../EFDbContext/T4Scaffolding.EFDbContext.ps1 | 81 + .../tools/EFRepository/Repository.cs.t4 | 103 + .../tools/EFRepository/Repository.vb.t4 | 91 + .../T4Scaffolding.EFRepository.ps1 | 57 + .../tools/T4Scaffolding.Format.ps1xml | 26 + .../tools/T4Scaffolding.NuGetServices.dll | Bin 0 -> 24064 bytes .../tools/T4Scaffolding.dll | Bin 0 -> 115712 bytes packages/T4Scaffolding.1.0.1/tools/init.ps1 | 51 + .../T4Scaffolding.1.0.1/tools/install.ps1 | 32 + .../tools/scaffoldingTabExpansion.psm1 | 114 + .../T4Scaffolding.1.0.1/tools/uninstall.ps1 | 14 + .../Unity.2.1.505.0/Unity.2.1.505.0.nupkg | Bin 0 -> 303876 bytes ...icrosoft.Practices.Unity.Configuration.dll | Bin 0 -> 86840 bytes ...icrosoft.Practices.Unity.Configuration.xml | 2451 ++ .../lib/NET35/Microsoft.Practices.Unity.dll | Bin 0 -> 124216 bytes .../lib/NET35/Microsoft.Practices.Unity.xml | 5910 +++ .../Microsoft.Practices.Unity.Silverlight.dll | Bin 0 -> 123704 bytes .../Microsoft.Practices.Unity.Silverlight.xml | 5928 +++ packages/Unity.2.1.505.0/tools/Utils.psm1 | Bin 0 -> 4656 bytes packages/Unity.2.1.505.0/tools/install.ps1 | Bin 0 -> 646 bytes .../Content/Scripts/jquery-1.6.2-vsdoc.js | 6987 ++++ .../Content/Scripts/jquery-1.6.2.js | 8981 ++++ .../Content/Scripts/jquery-1.6.2.min.js | 18 + packages/jQuery.1.6.2/Tools/install.ps1 | 20 + .../Tools/jquery-1.6.2-vsdoc-para.js | 6987 ++++ packages/jQuery.1.6.2/Tools/uninstall.ps1 | 46 + packages/jQuery.1.6.2/jQuery.1.6.2.nupkg | Bin 0 -> 197708 bytes packages/repositories.config | 4 + scaffolding.config | 14 + 225 files changed, 255434 insertions(+), 14382 deletions(-) create mode 100644 GARDIS/CodeTemplates/Scaffolders/MvcScaffolding.Controller/ControllerWithContext.cs.t4 create mode 100644 GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFDbContext/DbContextEntityMember.cs.t4 create mode 100644 GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFRepository/Repository.cs.t4 create mode 100644 GARDIS/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 GARDIS/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 GARDIS/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 GARDIS/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 GARDIS/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 GARDIS/Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 GARDIS/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 GARDIS/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 GARDIS/Content/themes/base/images/ui-icons_222222_256x240.png create mode 100644 GARDIS/Content/themes/base/images/ui-icons_2e83ff_256x240.png create mode 100644 GARDIS/Content/themes/base/images/ui-icons_454545_256x240.png create mode 100644 GARDIS/Content/themes/base/images/ui-icons_888888_256x240.png create mode 100644 GARDIS/Content/themes/base/images/ui-icons_cd0a0a_256x240.png create mode 100644 GARDIS/Content/themes/base/jquery-ui.css create mode 100644 GARDIS/Controllers/Games/CategoryController.cs create mode 100644 GARDIS/Controllers/Games/EnvDTE.cs create mode 100644 GARDIS/Controllers/Games/Model.cs create mode 100644 GARDIS/Controllers/GamesController.cs create mode 100644 GARDIS/Controllers/HomeController.cs create mode 100644 GARDIS/Controllers/UserController.cs create mode 100644 GARDIS/Controllers/UsersController.cs create mode 100644 GARDIS/Models/DataBase.cs create mode 100644 GARDIS/Models/GARDISContext.cs create mode 100644 GARDIS/Models/Game.cs create mode 100644 GARDIS/Models/ICollectable.cs create mode 100644 GARDIS/Models/Properties/Game/Category.cs create mode 100644 GARDIS/Models/Properties/Game/Players.cs create mode 100644 GARDIS/Models/Properties/Game/Type.cs create mode 100644 GARDIS/Models/User.cs delete mode 100644 GARDIS/Scripts/jquery-1.4.1-vsdoc.js delete mode 100644 GARDIS/Scripts/jquery-1.4.1.js delete mode 100644 GARDIS/Scripts/jquery-1.4.1.min.js create mode 100644 GARDIS/Scripts/jquery-1.6.2-vsdoc.js create mode 100644 GARDIS/Scripts/jquery-1.6.2.js create mode 100644 GARDIS/Scripts/jquery-1.6.2.min.js create mode 100644 GARDIS/Scripts/jquery-ui.js create mode 100644 GARDIS/Scripts/jquery-ui.min.js create mode 100644 GARDIS/Scripts/jquery.unobtrusive-ajax.js create mode 100644 GARDIS/Scripts/jquery.unobtrusive-ajax.min.js create mode 100644 GARDIS/Scripts/jquery.validate.unobtrusive.js create mode 100644 GARDIS/Scripts/jquery.validate.unobtrusive.min.js create mode 100644 GARDIS/Views/Games/Category/Create.cshtml create mode 100644 GARDIS/Views/Games/Category/Delete.cshtml create mode 100644 GARDIS/Views/Games/Category/Details.cshtml create mode 100644 GARDIS/Views/Games/Category/Edit.cshtml create mode 100644 GARDIS/Views/Games/Category/Index.cshtml create mode 100644 GARDIS/Views/Games/Category/_CreateOrEdit.cshtml create mode 100644 GARDIS/Views/Games/Create.cshtml create mode 100644 GARDIS/Views/Games/Delete.cshtml create mode 100644 GARDIS/Views/Games/Details.cshtml create mode 100644 GARDIS/Views/Games/Edit.cshtml create mode 100644 GARDIS/Views/Games/Index.cshtml create mode 100644 GARDIS/Views/Games/_CreateOrEdit.cshtml create mode 100644 GARDIS/Views/Home/Index.cshtml create mode 100644 GARDIS/Views/Users/Create.cshtml create mode 100644 GARDIS/Views/Users/Delete.cshtml create mode 100644 GARDIS/Views/Users/Details.cshtml create mode 100644 GARDIS/Views/Users/Edit.cshtml create mode 100644 GARDIS/Views/Users/Index.cshtml create mode 100644 GARDIS/Views/Users/_CreateOrEdit.cshtml create mode 100644 GARDIS/bin/DotNetOpenAuth.dll create mode 100644 GARDIS/bin/DotNetOpenAuth.dll.mdb create mode 100644 GARDIS/bin/DotNetOpenAuth.xml create mode 100644 GARDIS/bin/EntityFramework.dll create mode 100644 GARDIS/bin/EntityFramework.xml create mode 100644 GARDIS/bin/GARDIS.dll create mode 100644 GARDIS/bin/GARDIS.pdb create mode 100644 GARDIS/bin/Microsoft.Practices.ServiceLocation.dll create mode 100644 GARDIS/bin/Microsoft.Practices.ServiceLocation.pdb create mode 100644 GARDIS/bin/Microsoft.Practices.ServiceLocation.xml create mode 100644 GARDIS/bin/Microsoft.Practices.Unity.Configuration.dll create mode 100644 GARDIS/bin/Microsoft.Practices.Unity.Configuration.xml create mode 100644 GARDIS/bin/Microsoft.Practices.Unity.dll create mode 100644 GARDIS/bin/Microsoft.Practices.Unity.xml create mode 100644 GARDIS/bin/Newtonsoft.Json.dll create mode 100644 GARDIS/bin/Newtonsoft.Json.pdb create mode 100644 GARDIS/bin/Newtonsoft.Json.xml create mode 100644 GARDIS/bin/Norm.dll create mode 100644 GARDIS/bin/Norm.dll.mdb create mode 100644 GARDIS/bin/Norm.pdb create mode 100644 GARDIS/bin/Norm.xml create mode 100644 GARDIS/bin/jonathan.silvenstudios.com.pdb create mode 100644 GARDIS/bin/log4net.dll create mode 100644 GARDIS/bin/log4net.xml create mode 100644 GARDIS/obj/Debug/GARDIS.csproj.FileListAbsolute.txt create mode 100644 GARDIS/obj/Debug/GARDIS.dll create mode 100644 GARDIS/obj/Debug/GARDIS.pdb create mode 100644 GARDIS/obj/Debug/ResolveAssemblyReference.cache create mode 100644 GARDIS/packages.config create mode 100644 packages/CommonServiceLocator.1.0/CommonServiceLocator.1.0.nupkg create mode 100644 packages/CommonServiceLocator.1.0/lib/NET35/Microsoft.Practices.ServiceLocation.XML create mode 100644 packages/CommonServiceLocator.1.0/lib/NET35/Microsoft.Practices.ServiceLocation.dll create mode 100644 packages/CommonServiceLocator.1.0/lib/NET35/Microsoft.Practices.ServiceLocation.pdb create mode 100644 packages/CommonServiceLocator.1.0/lib/SL30/Microsoft.Practices.ServiceLocation.XML create mode 100644 packages/CommonServiceLocator.1.0/lib/SL30/Microsoft.Practices.ServiceLocation.dll create mode 100644 packages/DotNetOpenAuth.3.4.7.11121/DotNetOpenAuth.3.4.7.11121.nupkg create mode 100644 packages/DotNetOpenAuth.3.4.7.11121/content/web.config.transform create mode 100644 packages/DotNetOpenAuth.3.4.7.11121/lib/DotNetOpenAuth.dll create mode 100644 packages/DotNetOpenAuth.3.4.7.11121/lib/DotNetOpenAuth.xml create mode 100644 packages/EntityFramework.4.1.10715.0/EntityFramework.4.1.10715.0.nupkg create mode 100644 packages/EntityFramework.4.1.10715.0/lib/EntityFramework.dll create mode 100644 packages/EntityFramework.4.1.10715.0/lib/EntityFramework.xml create mode 100644 packages/MvcScaffolding.1.0.0/MvcScaffolding.1.0.0.nupkg create mode 100644 packages/MvcScaffolding.1.0.0/content/InstallationDummyFile.txt create mode 100644 packages/MvcScaffolding.1.0.0/tools/Action/Action.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Action/Action.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Action/ActionPost.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Action/ActionPost.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Action/MvcScaffolding.Action.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Action/ViewModel.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Action/ViewModel.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/ActionUnitTest/MvcScaffolding.ActionUnitTest.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/ActionUnitTest/TestClass.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/ActionUnitTest/TestClass.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/ActionUnitTest/TestMethod.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/ActionUnitTest/TestMethod.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/ActionWithUnitTest/MvcScaffolding.ActionWithUnitTest.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Create.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Create.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Details.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Details.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Index.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/Index.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/AspxView/MvcScaffolding.AspxView.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.Controller.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.ControllerWithRepository.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Create.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Create.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Details.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Details.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Index.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/Index.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/MvcScaffolding.RazorView.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.cs.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.vb.t4 create mode 100644 packages/MvcScaffolding.1.0.0/tools/Views/MvcScaffolding.Views.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/init.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/install.ps1 create mode 100644 packages/MvcScaffolding.1.0.0/tools/registerWithMvcTooling.ps1 create mode 100644 packages/Newtonsoft.Json.4.0.2/Newtonsoft.Json.4.0.2.nupkg create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net20/Newtonsoft.Json.Net20.dll create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net20/Newtonsoft.Json.Net20.pdb create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net20/Newtonsoft.Json.Net20.xml create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net35/Newtonsoft.Json.Net35.dll create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net35/Newtonsoft.Json.Net35.pdb create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net35/Newtonsoft.Json.Net35.xml create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net40/Newtonsoft.Json.dll create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net40/Newtonsoft.Json.pdb create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/net40/Newtonsoft.Json.xml create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/sl3-wp/Newtonsoft.Json.WindowsPhone.dll create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/sl3-wp/Newtonsoft.Json.WindowsPhone.pdb create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/sl3-wp/Newtonsoft.Json.WindowsPhone.xml create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/sl4/Newtonsoft.Json.Silverlight.dll create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/sl4/Newtonsoft.Json.Silverlight.pdb create mode 100644 packages/Newtonsoft.Json.4.0.2/lib/sl4/Newtonsoft.Json.Silverlight.xml create mode 100644 packages/T4Scaffolding.1.0.1/T4Scaffolding.1.0.1.nupkg create mode 100644 packages/T4Scaffolding.1.0.1/content/InstallationDummyFile.txt create mode 100644 packages/T4Scaffolding.1.0.1/tools/CustomScaffolder/DefaultPs1Script.ps1.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/CustomScaffolder/DefaultT4Template.cs.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/CustomScaffolder/DefaultT4Template.vb.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/CustomScaffolder/T4Scaffolding.CustomScaffolder.ps1 create mode 100644 packages/T4Scaffolding.1.0.1/tools/CustomTemplate/T4Scaffolding.CustomTemplate.ps1 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFDbContext/DbContext.cs.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFDbContext/DbContext.vb.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFDbContext/DbContextEntityMember.cs.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFDbContext/DbContextEntityMember.vb.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFDbContext/T4Scaffolding.EFDbContext.ps1 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFRepository/Repository.cs.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFRepository/Repository.vb.t4 create mode 100644 packages/T4Scaffolding.1.0.1/tools/EFRepository/T4Scaffolding.EFRepository.ps1 create mode 100644 packages/T4Scaffolding.1.0.1/tools/T4Scaffolding.Format.ps1xml create mode 100644 packages/T4Scaffolding.1.0.1/tools/T4Scaffolding.NuGetServices.dll create mode 100644 packages/T4Scaffolding.1.0.1/tools/T4Scaffolding.dll create mode 100644 packages/T4Scaffolding.1.0.1/tools/init.ps1 create mode 100644 packages/T4Scaffolding.1.0.1/tools/install.ps1 create mode 100644 packages/T4Scaffolding.1.0.1/tools/scaffoldingTabExpansion.psm1 create mode 100644 packages/T4Scaffolding.1.0.1/tools/uninstall.ps1 create mode 100644 packages/Unity.2.1.505.0/Unity.2.1.505.0.nupkg create mode 100644 packages/Unity.2.1.505.0/lib/NET35/Microsoft.Practices.Unity.Configuration.dll create mode 100644 packages/Unity.2.1.505.0/lib/NET35/Microsoft.Practices.Unity.Configuration.xml create mode 100644 packages/Unity.2.1.505.0/lib/NET35/Microsoft.Practices.Unity.dll create mode 100644 packages/Unity.2.1.505.0/lib/NET35/Microsoft.Practices.Unity.xml create mode 100644 packages/Unity.2.1.505.0/lib/SL30/Microsoft.Practices.Unity.Silverlight.dll create mode 100644 packages/Unity.2.1.505.0/lib/SL30/Microsoft.Practices.Unity.Silverlight.xml create mode 100644 packages/Unity.2.1.505.0/tools/Utils.psm1 create mode 100644 packages/Unity.2.1.505.0/tools/install.ps1 create mode 100644 packages/jQuery.1.6.2/Content/Scripts/jquery-1.6.2-vsdoc.js create mode 100644 packages/jQuery.1.6.2/Content/Scripts/jquery-1.6.2.js create mode 100644 packages/jQuery.1.6.2/Content/Scripts/jquery-1.6.2.min.js create mode 100644 packages/jQuery.1.6.2/Tools/install.ps1 create mode 100644 packages/jQuery.1.6.2/Tools/jquery-1.6.2-vsdoc-para.js create mode 100644 packages/jQuery.1.6.2/Tools/uninstall.ps1 create mode 100644 packages/jQuery.1.6.2/jQuery.1.6.2.nupkg create mode 100644 packages/repositories.config create mode 100644 scaffolding.config diff --git a/GARDIS.sln b/GARDIS.sln index 9a66dc6..a20a204 100644 --- a/GARDIS.sln +++ b/GARDIS.sln @@ -17,4 +17,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35 + EndGlobalSection EndGlobal diff --git a/GARDIS.suo b/GARDIS.suo index 3e4e5f6bc8ad8152a9f173acd86b1a417ed9bc7d..03bc663fd8bb94cc18e56f78438a54df169d76f1 100644 GIT binary patch literal 49664 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 literal 20480 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 diff --git a/GARDIS/CodeTemplates/Scaffolders/MvcScaffolding.Controller/ControllerWithContext.cs.t4 b/GARDIS/CodeTemplates/Scaffolders/MvcScaffolding.Controller/ControllerWithContext.cs.t4 new file mode 100644 index 0000000..c1e52d5 --- /dev/null +++ b/GARDIS/CodeTemplates/Scaffolders/MvcScaffolding.Controller/ControllerWithContext.cs.t4 @@ -0,0 +1,159 @@ +<#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> +<#@ Output Extension="cs" #> +<#@ assembly name="System.Data.Entity" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<#@ import namespace="EnvDTE" #> +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Entity; +using System.Linq; +using System.Web; +using System.Web.Mvc; +<# if(!string.IsNullOrEmpty(Model.ModelTypeNamespace)) { #> +using <#= Model.ModelTypeNamespace #>; +<# } #> +<# if(Model.DbContextNamespace != Model.ModelTypeNamespace) { #> +using <#= Model.DbContextNamespace #>; +<# } #> + +namespace <#= Model.ControllerNamespace #> +{ +<# + var modelType = (CodeType)Model.ModelType; + var modelName = modelType.Name; + var modelNamePlural = Model.ModelTypePluralized; + var modelVariable = modelName.ToLower(); + var relatedEntities = ((IEnumerable)Model.RelatedEntities).OfType(); + var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); + var routingName = Regex.Replace(Model.ControllerName, "Controller$", "", RegexOptions.IgnoreCase); + var isObjectContext = ((CodeType)Model.DbContextType).IsAssignableTo(); +#> + public class <#= Model.ControllerName #> : Controller + { + private <#= ((CodeType)Model.DbContextType).Name #> context = new <#= ((CodeType)Model.DbContextType).Name #>(); + + // + // GET: /<#= routingName #>/ + + public ViewResult Index() + { +<# + var propertiesToInclude = relatedEntities.Select(relation => relation.LazyLoadingProperty).Where(x => x != null); + var includeExpressions = isObjectContext + ? String.Join("", propertiesToInclude.Select(x => String.Format(".Include(\"{0}\")", x.Name))) + : String.Join("", propertiesToInclude.Select(x => String.Format(".Include({0} => {0}.{1})", modelVariable, x.Name))); +#> + return View(context.<#= modelNamePlural #><#= includeExpressions #>.ToList()); + } + + // + // GET: /<#= routingName #>/Details/5 + + public ViewResult Details(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); + return View(<#= modelVariable #>); + } + + // + // GET: /<#= routingName #>/Create + + public ActionResult Create() + { +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(); + } + + // + // POST: /<#= routingName #>/Create + + [HttpPost] + public ActionResult Create(<#= modelName #> <#= modelVariable #>) + { + if (ModelState.IsValid) + { +<# if(primaryKeyProperty.Type.AsString == "System.Guid") { #> + <#= modelVariable #>.<#= primaryKeyProperty.Name #> = Guid.NewGuid(); +<# } #> +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.AddObject(<#= modelVariable #>); +<# } else { #> + context.<#= modelNamePlural #>.Add(<#= modelVariable #>); +<# } #> + context.SaveChanges(); + return RedirectToAction("Index"); + } + +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(<#= modelVariable #>); + } + + // + // GET: /<#= routingName #>/Edit/5 + + public ActionResult Edit(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(<#= modelVariable #>); + } + + // + // POST: /<#= routingName #>/Edit/5 + + [HttpPost] + public ActionResult Edit(<#= modelName #> <#= modelVariable #>) + { + if (ModelState.IsValid) + { +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.Attach(<#= modelVariable #>); + context.ObjectStateManager.ChangeObjectState(<#= modelVariable #>, EntityState.Modified); +<# } else { #> + context.Entry(<#= modelVariable #>).State = EntityState.Modified; +<# } #> + context.SaveChanges(); + return RedirectToAction("Index"); + } +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(<#= modelVariable #>); + } + + // + // GET: /<#= routingName #>/Delete/5 + + public ActionResult Delete(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); + return View(<#= modelVariable #>); + } + + // + // POST: /<#= routingName #>/Delete/5 + + [HttpPost, ActionName("Delete")] + public ActionResult DeleteConfirmed(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.DeleteObject(<#= modelVariable #>); +<# } else { #> + context.<#= modelNamePlural #>.Remove(<#= modelVariable #>); +<# } #> + context.SaveChanges(); + return RedirectToAction("Index"); + } + } +} \ No newline at end of file diff --git a/GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFDbContext/DbContextEntityMember.cs.t4 b/GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFDbContext/DbContextEntityMember.cs.t4 new file mode 100644 index 0000000..f6d1f51 --- /dev/null +++ b/GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFDbContext/DbContextEntityMember.cs.t4 @@ -0,0 +1,2 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +public DataBase<<#= ((EnvDTE.CodeType)Model.EntityType).FullName #>> <#= Model.EntityTypeNamePluralized #> { get { return new DataBase<<#= ((EnvDTE.CodeType)Model.EntityType).FullName #>>(); } } \ No newline at end of file diff --git a/GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFRepository/Repository.cs.t4 b/GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFRepository/Repository.cs.t4 new file mode 100644 index 0000000..2cd0805 --- /dev/null +++ b/GARDIS/CodeTemplates/Scaffolders/T4Scaffolding.EFRepository/Repository.cs.t4 @@ -0,0 +1,103 @@ +<#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> +<#@ assembly name="System.Data.Entity" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="EnvDTE" #> +<#@ Output Extension="cs" #> +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Entity; +using System.Linq; +using System.Linq.Expressions; +using System.Web; +<# foreach(var ns in new[] { Model.ModelTypeNamespace, Model.DbContextNamespace }.Where(x => !string.IsNullOrEmpty(x) && (x != Model.RepositoryNamespace)).Distinct()) { #> +using <#= ns #>; +<# } #> + +namespace <#= Model.RepositoryNamespace #> +{ +<# + var modelType = (CodeType)Model.ModelType; + var modelName = modelType.Name; + var modelNamePlural = Model.ModelTypePluralized; + var contextName = ((CodeType)Model.DbContextType).Name; + var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); + var isObjectContext = ((CodeType)Model.DbContextType).IsAssignableTo(); +#> + public class <#= modelName #>Repository : I<#= modelName #>Repository + { + <#= contextName #> context = new <#= contextName #>(); + + public IQueryable<<#= modelName #>> All + { + get { return context.<#= modelNamePlural #>; } + } + + public IQueryable<<#= modelName #>> AllIncluding(params Expression, object>>[] includeProperties) + { + IQueryable<<#= modelName #>> query = context.<#= modelNamePlural #>; + foreach (var includeProperty in includeProperties) { + query = query.Include(includeProperty); + } + return query; + } + + public <#= modelName #> Find(<#= primaryKeyProperty.Type.AsString #> id) + { +<# if(isObjectContext) { #> + return context.<#= modelNamePlural #>.Single(x => x.<#= Model.PrimaryKey #> == id); +<# } else { #> + return context.<#= modelNamePlural #>.Find(id); +<# } #> + } + + public void InsertOrUpdate(<#= modelName #> <#= modelName.ToLower() #>) + { + if (<#= modelName.ToLower() #>.<#= Model.PrimaryKey #> == default(<#= primaryKeyProperty.Type.AsString #>)) { + // New entity +<# if(primaryKeyProperty.Type.AsString == "System.Guid") { #> + <#= modelName.ToLower() #>.<#= primaryKeyProperty.Name #> = Guid.NewGuid(); +<# } #> +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.AddObject(<#= modelName.ToLower() #>); +<# } else { #> + context.<#= modelNamePlural #>.Add(<#= modelName.ToLower() #>); +<# } #> + } else { + // Existing entity +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.Attach(<#= modelName.ToLower() #>); + context.ObjectStateManager.ChangeObjectState(<#= modelName.ToLower() #>, EntityState.Modified); +<# } else { #> + context.Entry(<#= modelName.ToLower() #>).State = EntityState.Modified; +<# } #> + } + } + + public void Delete(<#= primaryKeyProperty.Type.AsString #> id) + { +<# if(isObjectContext) { #> + var <#= modelName.ToLower() #> = context.<#= modelNamePlural #>.Single(x => x.<#= Model.PrimaryKey #> == id); + context.<#= modelNamePlural #>.DeleteObject(<#= modelName.ToLower() #>); +<# } else { #> + var <#= modelName.ToLower() #> = context.<#= modelNamePlural #>.Find(id); + context.<#= modelNamePlural #>.Remove(<#= modelName.ToLower() #>); +<# } #> + } + + public void Save() + { + context.SaveChanges(); + } + } + + public interface I<#= modelName #>Repository + { + IQueryable<<#= modelName #>> All { get; } + IQueryable<<#= modelName #>> AllIncluding(params Expression, object>>[] includeProperties); + <#= modelName #> Find(<#= primaryKeyProperty.Type.AsString #> id); + void InsertOrUpdate(<#= modelName #> <#= modelName.ToLower() #>); + void Delete(<#= primaryKeyProperty.Type.AsString #> id); + void Save(); + } +} \ No newline at end of file diff --git a/GARDIS/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png b/GARDIS/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd9dee1a252d16716b9fc96e56c7f584aa02002 GIT binary patch literal 213 zcmaFAe{X=FJ1>_M7Xt$WucwDg5RldY;uH=xAo+g(-jt#$AfwvT#W5rU$b}$7Mj)*q zz+ea$F^^O!fpGZ5S%C~=AeOg|X9rRuA*`W}p#h@QrNj^KVLm!H8EC#H(0vS^u6`~+ Jwo?L-001DuOVj`W literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png b/GARDIS/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..8d14c9f1fa263dc80627a31e530d1de40594a0f0 GIT binary patch literal 268 zcmaFAe{X=FJ1>_M7Xt$WucwDg5RldY;uH=xAo+g(-jt#$AfwXL#W5rU$b}$7Mj)*q z0Fn=ah{$vDm_t|^CuTtyauA9SNO6Qg*a@l;oCC*{&H}oE1&B3`fP^2=TMVAAel9?^ IQv#3x0J$xQ2mk;8 literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png b/GARDIS/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..617bce12f0615900228edc123585fb93b3b78c8c GIT binary patch literal 186 zcmaFAe{X=FJ1>_M7Xt$WucwDg5RhgBqWAmvaEak-0c1mvAxPMO z!Rg|92tNlxB>*WiXCP4w;oGpp0vT37ECCS!lF<;B8jx}Vi8@Mf3PXfa&4Dz?q(Co- b0Nc?y0&IbiK#msB2@IaDel9?^6UY_-6XalY literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png b/GARDIS/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..9b31ae49766d8325d80ddedac74fb874377f7b2b GIT binary patch literal 158 zcmaFAe{X=FJ1>_M7Xt$WucwDg5RhgBqWAmvaEak-0c1mvA|Hc- z2%HCJXp3<|*k|@YXfGh;5u^zuqjR!>q^*BEL_z~d*(8AM;g$9Pl1e}fw1&ac)z1aU IbV>jc0Ip+BfdBvi literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png b/GARDIS/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..21b12d75fdd0b53fc6eeb1e7205cbf616bde2ac6 GIT binary patch literal 167 zcmaFAe{X=FJ1>_M7Xt$WucwDg5RhgBqWAmvaEak-0c0mv00{`H zS7T#i12O}XfP{o9kkExl07-KVI8zYFN=Qm_N>c_M7Xt$WucwDg5RhgBqWAmvaEak-0c1mvAs2&! z05hBmVN?RCP#})rfbczlR3d~4Bn2Em!qGrn9STxa%I*Lpfyf*}$p`~!CQb;)1xUF8 Pt!40Z^#ie;5`Y8%NW)pX literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png b/GARDIS/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..beab1c3094b29e620f3e82fdc0e297bf127a2ad8 GIT binary patch literal 183 zcmaFAe{X=FJ1>_M7Xt$WucwDg5RhgBqWAmvaEak-0c1mvAxPMO z!TI8RxDb$`zzQT(fY=#`oq!mEB!N_|oS}neYW%TQAUnYmWRNZpt0n^pUjrZkLEI2Z clOISc@q_H(1!5nd{S2P2el9?^Qv#3x08DFLBLDyZ literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/GARDIS/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac5b275c92ad924d84de42e15fbf39d81e051e9 GIT binary patch literal 143 zcmaFAe{X=FJ1>_M7Xt$WucwDg5RhgB;uH=xAnC3Xl>nr4JY5_^B;N1en_K}TAgErA zjg1Y+RCIw0$$J5rg%>;OAtHkMa2WMY literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-icons_222222_256x240.png b/GARDIS/Content/themes/base/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..257e401c0a8795e72efdee9ac0388b633af0ec9b GIT binary patch literal 7813 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 IUgZY+58CHQKL7v# literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-icons_888888_256x240.png b/GARDIS/Content/themes/base/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..078e505abe4dc9baede846bda48f95a622301609 GIT binary patch literal 8289 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 O)iv&SvCOMIVE+MVT}I^q literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/images/ui-icons_cd0a0a_256x240.png b/GARDIS/Content/themes/base/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc87a9220258d8f7b79d8b16b252a198da4bc6f GIT binary patch literal 7973 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 NZrtx=nb)|${tc^U&ZPhV literal 0 HcmV?d00001 diff --git a/GARDIS/Content/themes/base/jquery-ui.css b/GARDIS/Content/themes/base/jquery-ui.css new file mode 100644 index 0000000..30f0ed1 --- /dev/null +++ b/GARDIS/Content/themes/base/jquery-ui.css @@ -0,0 +1,635 @@ +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI CSS Framework 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Accordion 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; }/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Autocomplete 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Menu 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Button 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Datepicker 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Dialog 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Progressbar 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Resizable 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Selectable 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Slider 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI Tabs 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * Note: While Microsoft is not the author of this file, Microsoft is + * offering you a license subject to the terms of the Microsoft Software + * License Terms for Microsoft ASP.NET Model View Controller 3. + * Microsoft reserves all other rights. The notices below are provided + * for informational purposes only and are not the license terms under + * which Microsoft distributed this file. + * + * jQuery UI CSS Framework 1.8.7 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/ + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; } +.ui-widget-content a { color: #222222/*{fcContent}*/; } +.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; } +.ui-widget-header a { color: #222222/*{fcHeader}*/; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-top { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-right { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-left { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all { -moz-border-radius: 4px/*{cornerRadius}*/; -webkit-border-radius: 4px/*{cornerRadius}*/; border-radius: 4px/*{cornerRadius}*/; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; } +.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; } \ No newline at end of file diff --git a/GARDIS/Controllers/Games/CategoryController.cs b/GARDIS/Controllers/Games/CategoryController.cs new file mode 100644 index 0000000..8554cf1 --- /dev/null +++ b/GARDIS/Controllers/Games/CategoryController.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Entity; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using GARDIS.Models.Properties.Game; +using GARDIS.Models; + +namespace GARDIS.Controllers.Games +{ + public class CategoryController : Controller + { + private GARDISContext context = new GARDISContext(); + + // + // GET: /Category/ + + public ViewResult Index() + { + return View(context.GameCategories.GetAll().ToList()); + } + + // + // GET: /Category/Details/5 + + public ViewResult Details(Norm.ObjectId id) + { + Category category = context.GameCategories.GetAll().Single(x => x.Id == id); + return View(category); + } + + // + // GET: /Category/Create + + public ActionResult Create() + { + return View(); + } + + // + // POST: /Category/Create + + [HttpPost] + public ActionResult Create(Category category) + { + if (ModelState.IsValid) + { + context.GameCategories.Insert(category); + return RedirectToAction("Index"); + } + + return View(category); + } + + // + // GET: /Category/Edit/5 + + public ActionResult Edit(Norm.ObjectId id) + { + Category category = context.GameCategories.GetAll().Single(x => x.Id == id); + return View(category); + } + + // + // POST: /Category/Edit/5 + + [HttpPost] + public ActionResult Edit(Category category) + { + if (ModelState.IsValid) + { + context.GameCategories.Update(category); + return RedirectToAction("Index"); + } + return View(category); + } + + // + // GET: /Category/Delete/5 + + public ActionResult Delete(Norm.ObjectId id) + { + Category category = context.GameCategories.GetAll().Single(x => x.Id == id); + return View(category); + } + + // + // POST: /Category/Delete/5 + + [HttpPost, ActionName("Delete")] + public ActionResult DeleteConfirmed(Norm.ObjectId id) + { + Category category = context.GameCategories.GetAll().Single(x => x.Id == id); + context.GameCategories.Delete(category); + return RedirectToAction("Index"); + } + } +} \ No newline at end of file diff --git a/GARDIS/Controllers/Games/EnvDTE.cs b/GARDIS/Controllers/Games/EnvDTE.cs new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/GARDIS/Controllers/Games/EnvDTE.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/GARDIS/Controllers/Games/Model.cs b/GARDIS/Controllers/Games/Model.cs new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/GARDIS/Controllers/Games/Model.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/GARDIS/Controllers/GamesController.cs b/GARDIS/Controllers/GamesController.cs new file mode 100644 index 0000000..cc19bee --- /dev/null +++ b/GARDIS/Controllers/GamesController.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Entity; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using GARDIS.Models; + +namespace GARDIS.Controllers +{ + public class GamesController : Controller + { + private GARDISContext context = new GARDISContext(); + + // + // GET: /Games/ + + public ViewResult Index() + { + return View(context.Games.GetAll().ToList()); + } + + // + // GET: /Games/Details/5 + + public ViewResult Details(Norm.ObjectId id) + { + Game game = context.Games.GetAll().Single(x => x.Id == id); + return View(game); + } + + // + // GET: /Games/Create + + public ActionResult Create() + { + return View(); + } + + // + // POST: /Games/Create + + [HttpPost] + public ActionResult Create(Game game) + { + if (ModelState.IsValid) + { + context.Games.Insert(game); + return RedirectToAction("Index"); + } + + return View(game); + } + + // + // GET: /Games/Edit/5 + + public ActionResult Edit(Norm.ObjectId id) + { + Game game = context.Games.GetAll().Single(x => x.Id == id); + return View(game); + } + + // + // POST: /Games/Edit/5 + + [HttpPost] + public ActionResult Edit(Game game) + { + if (ModelState.IsValid) + { + context.Games.Update(game); + return RedirectToAction("Index"); + } + return View(game); + } + + // + // GET: /Games/Delete/5 + + public ActionResult Delete(Norm.ObjectId id) + { + Game game = context.Games.GetAll().Single(x => x.Id == id); + return View(game); + } + + // + // POST: /Games/Delete/5 + + [HttpPost, ActionName("Delete")] + public ActionResult DeleteConfirmed(Norm.ObjectId id) + { + Game game = context.Games.GetAll().Single(x => x.Id == id); + context.Games.Delete(game); + return RedirectToAction("Index"); + } + } +} \ No newline at end of file diff --git a/GARDIS/Controllers/HomeController.cs b/GARDIS/Controllers/HomeController.cs new file mode 100644 index 0000000..468a8ae --- /dev/null +++ b/GARDIS/Controllers/HomeController.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace GARDIS.Controllers +{ + public class HomeController : Controller + { + // + // GET: /Home/ + + public ActionResult Index() + { + return View(); + } + + } +} diff --git a/GARDIS/Controllers/UserController.cs b/GARDIS/Controllers/UserController.cs new file mode 100644 index 0000000..c3d94b1 --- /dev/null +++ b/GARDIS/Controllers/UserController.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace GARDIS.Controllers +{ + public class UserController : Controller + { + // + // GET: /User/ + + public ActionResult Index() + { + return View(); + } + + } +} diff --git a/GARDIS/Controllers/UsersController.cs b/GARDIS/Controllers/UsersController.cs new file mode 100644 index 0000000..b333bd1 --- /dev/null +++ b/GARDIS/Controllers/UsersController.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Entity; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using GARDIS.Models; + +namespace GARDIS.Controllers +{ + public class UsersController : Controller + { + private GARDISContext context = new GARDISContext(); + + // + // GET: /Users/ + + public ViewResult Index() + { + return View(context.Users.GetAll().ToList()); + } + + // + // GET: /Users/Details/5 + + public ViewResult Details(Norm.ObjectId id) + { + User user = context.Users.GetAll().Single(x => x.Id == id); + return View(user); + } + + // + // GET: /Users/Create + + public ActionResult Create() + { + return View(); + } + + // + // POST: /Users/Create + + [HttpPost] + public ActionResult Create(User user) + { + if (ModelState.IsValid) + { + context.Users.Insert(user); + return RedirectToAction("Index"); + } + + return View(user); + } + + // + // GET: /Users/Edit/5 + + public ActionResult Edit(Norm.ObjectId id) + { + User user = context.Users.GetAll().Single(x => x.Id == id); + return View(user); + } + + // + // POST: /Users/Edit/5 + + [HttpPost] + public ActionResult Edit(User user) + { + if (ModelState.IsValid) + { + context.Users.Update(user); + return RedirectToAction("Index"); + } + return View(user); + } + + // + // GET: /Users/Delete/5 + + public ActionResult Delete(Norm.ObjectId id) + { + User user = context.Users.GetAll().Single(x => x.Id == id); + return View(user); + } + + // + // POST: /Users/Delete/5 + + [HttpPost, ActionName("Delete")] + public ActionResult DeleteConfirmed(Norm.ObjectId id) + { + User user = context.Users.GetAll().Single(x => x.Id == id); + context.Users.Delete(user); + return RedirectToAction("Index"); + } + } +} \ No newline at end of file diff --git a/GARDIS/GARDIS.csproj b/GARDIS/GARDIS.csproj index 1c76878..fea7e08 100644 --- a/GARDIS/GARDIS.csproj +++ b/GARDIS/GARDIS.csproj @@ -7,7 +7,7 @@ 2.0 {B74AA50D-EBFC-44BD-B526-7693B5531983} - {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + {e53f8fea-eae0-44a6-8774-ffd645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} Library Properties GARDIS @@ -33,9 +33,37 @@ 4 + + False + ..\packages\DotNetOpenAuth.3.4.7.11121\lib\DotNetOpenAuth.dll + + + ..\packages\EntityFramework.4.1.10715.0\lib\EntityFramework.dll + + + False + bin\log4net.dll + + + ..\packages\CommonServiceLocator.1.0\lib\NET35\Microsoft.Practices.ServiceLocation.dll + + + ..\packages\Unity.2.1.505.0\lib\NET35\Microsoft.Practices.Unity.dll + + + ..\packages\Unity.2.1.505.0\lib\NET35\Microsoft.Practices.Unity.Configuration.dll + + + ..\packages\Newtonsoft.Json.4.0.2\lib\net40\Newtonsoft.Json.dll + + + False + ..\..\..\..\..\Desktop\atheken-NoRM-v0.9.8-6-g989765a (1)\atheken-NoRM-989765a\NoRM\bin\Release\Norm.dll + + @@ -49,7 +77,7 @@ 3.5 - + 3.5 @@ -63,26 +91,43 @@ + + + + + + + Global.asax + + + + + + + + - + + + + + Designer + Web.config Web.config - - - @@ -93,12 +138,91 @@ + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + focusin -// type === "blur" ? "focusout" : // blur --> focusout -// type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support -// type; -// -// if ( name === "live" ) { -// // bind live handler -// jQuery( this.context ).bind( liveConvert( type, this.selector ), { -// data: data, selector: this.selector, live: type -// }, fn ); -// -// } else { -// // unbind live handler -// jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null ); -// } -// } -// -// return this; -// } -// }); - -jQuery.fn[ "live" ] = function( types, data, fn ) { - /// - /// Attach a handler to the event for all elements which match the current selector, now or - /// in the future. - /// - /// - /// A string containing a JavaScript event type, such as "click" or "keydown". - /// - /// - /// A map of data that will be passed to the event handler. - /// - /// - /// A function to execute at the time the event is triggered. - /// - /// - - var type, i = 0; - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - types = (types || "").split( /\s+/ ); - - while ( (type = types[ i++ ]) != null ) { - type = type === "focus" ? "focusin" : // focus --> focusin - type === "blur" ? "focusout" : // blur --> focusout - type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support - type; - - if ( "live" === "live" ) { - // bind live handler - jQuery( this.context ).bind( liveConvert( type, this.selector ), { - data: data, selector: this.selector, live: type - }, fn ); - - } else { - // unbind live handler - jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null ); - } - } - - return this; -} - -jQuery.fn[ "die" ] = function( types, data, fn ) { - /// - /// Remove all event handlers previously attached using .live() from the elements. - /// - /// - /// A string containing a JavaScript event type, such as click or keydown. - /// - /// - /// The function that is to be no longer executed. - /// - /// - - var type, i = 0; - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - types = (types || "").split( /\s+/ ); - - while ( (type = types[ i++ ]) != null ) { - type = type === "focus" ? "focusin" : // focus --> focusin - type === "blur" ? "focusout" : // blur --> focusout - type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support - type; - - if ( "die" === "live" ) { - // bind live handler - jQuery( this.context ).bind( liveConvert( type, this.selector ), { - data: data, selector: this.selector, live: type - }, fn ); - - } else { - // unbind live handler - jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null ); - } - } - - return this; -} - -function liveHandler( event ) { - var stop, elems = [], selectors = [], args = arguments, - related, match, fn, elem, j, i, l, data, - live = jQuery.extend({}, jQuery.data( this, "events" ).live); - - // Make sure we avoid non-left-click bubbling in Firefox (#3861) - if ( event.button && event.type === "click" ) { - return; - } - - for ( j in live ) { - fn = live[j]; - if ( fn.live === event.type || - fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) { - - data = fn.data; - if ( !(data.beforeFilter && data.beforeFilter[event.type] && - !data.beforeFilter[event.type](event)) ) { - selectors.push( fn.selector ); - } - } else { - delete live[j]; - } - } - - match = jQuery( event.target ).closest( selectors, event.currentTarget ); - - for ( i = 0, l = match.length; i < l; i++ ) { - for ( j in live ) { - fn = live[j]; - elem = match[i].elem; - related = null; - - if ( match[i].selector === fn.selector ) { - // Those two events require additional checking - if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) { - related = jQuery( event.relatedTarget ).closest( fn.selector )[0]; - } - - if ( !related || related !== elem ) { - elems.push({ elem: elem, fn: fn }); - } - } - } - } - - for ( i = 0, l = elems.length; i < l; i++ ) { - match = elems[i]; - event.currentTarget = match.elem; - event.data = match.fn.data; - if ( match.fn.apply( match.elem, args ) === false ) { - stop = false; - break; - } - } - - return stop; -} - -function liveConvert( type, selector ) { - return "live." + (type ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&"); -} - -// jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + -// "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + -// "change select submit keydown keypress keyup error").split(" "), function( i, name ) { -// -// // Handle event binding -// jQuery.fn[ name ] = function( fn ) { -// return fn ? this.bind( name, fn ) : this.trigger( name ); -// }; -// -// if ( jQuery.attrFn ) { -// jQuery.attrFn[ name ] = true; -// } -// }); - -jQuery.fn[ "blur" ] = function( fn ) { - /// - /// 1: blur() - Triggers the blur event of each matched element. - /// 2: blur(fn) - Binds a function to the blur event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "blur", fn ) : this.trigger( "blur" ); -}; - -jQuery.fn[ "focus" ] = function( fn ) { - /// - /// 1: focus() - Triggers the focus event of each matched element. - /// 2: focus(fn) - Binds a function to the focus event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "focus", fn ) : this.trigger( "focus" ); -}; - -jQuery.fn[ "focusin" ] = function( fn ) { - /// - /// Bind an event handler to the "focusin" JavaScript event. - /// - /// - /// A function to execute each time the event is triggered. - /// - /// - - return fn ? this.bind( "focusin", fn ) : this.trigger( "focusin" ); -}; - -jQuery.fn[ "focusout" ] = function( fn ) { - /// - /// Bind an event handler to the "focusout" JavaScript event. - /// - /// - /// A function to execute each time the event is triggered. - /// - /// - - return fn ? this.bind( "focusout", fn ) : this.trigger( "focusout" ); -}; - -jQuery.fn[ "load" ] = function( fn ) { - /// - /// 1: load() - Triggers the load event of each matched element. - /// 2: load(fn) - Binds a function to the load event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "load", fn ) : this.trigger( "load" ); -}; - -jQuery.fn[ "resize" ] = function( fn ) { - /// - /// 1: resize() - Triggers the resize event of each matched element. - /// 2: resize(fn) - Binds a function to the resize event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "resize", fn ) : this.trigger( "resize" ); -}; - -jQuery.fn[ "scroll" ] = function( fn ) { - /// - /// 1: scroll() - Triggers the scroll event of each matched element. - /// 2: scroll(fn) - Binds a function to the scroll event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "scroll", fn ) : this.trigger( "scroll" ); -}; - -jQuery.fn[ "unload" ] = function( fn ) { - /// - /// 1: unload() - Triggers the unload event of each matched element. - /// 2: unload(fn) - Binds a function to the unload event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "unload", fn ) : this.trigger( "unload" ); -}; - -jQuery.fn[ "click" ] = function( fn ) { - /// - /// 1: click() - Triggers the click event of each matched element. - /// 2: click(fn) - Binds a function to the click event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "click", fn ) : this.trigger( "click" ); -}; - -jQuery.fn[ "dblclick" ] = function( fn ) { - /// - /// 1: dblclick() - Triggers the dblclick event of each matched element. - /// 2: dblclick(fn) - Binds a function to the dblclick event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "dblclick", fn ) : this.trigger( "dblclick" ); -}; - -jQuery.fn[ "mousedown" ] = function( fn ) { - /// - /// Binds a function to the mousedown event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mousedown", fn ) : this.trigger( "mousedown" ); -}; - -jQuery.fn[ "mouseup" ] = function( fn ) { - /// - /// Bind a function to the mouseup event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseup", fn ) : this.trigger( "mouseup" ); -}; - -jQuery.fn[ "mousemove" ] = function( fn ) { - /// - /// Bind a function to the mousemove event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mousemove", fn ) : this.trigger( "mousemove" ); -}; - -jQuery.fn[ "mouseover" ] = function( fn ) { - /// - /// Bind a function to the mouseover event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseover", fn ) : this.trigger( "mouseover" ); -}; - -jQuery.fn[ "mouseout" ] = function( fn ) { - /// - /// Bind a function to the mouseout event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseout", fn ) : this.trigger( "mouseout" ); -}; - -jQuery.fn[ "mouseenter" ] = function( fn ) { - /// - /// Bind a function to the mouseenter event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseenter", fn ) : this.trigger( "mouseenter" ); -}; - -jQuery.fn[ "mouseleave" ] = function( fn ) { - /// - /// Bind a function to the mouseleave event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "mouseleave", fn ) : this.trigger( "mouseleave" ); -}; - -jQuery.fn[ "change" ] = function( fn ) { - /// - /// 1: change() - Triggers the change event of each matched element. - /// 2: change(fn) - Binds a function to the change event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "change", fn ) : this.trigger( "change" ); -}; - -jQuery.fn[ "select" ] = function( fn ) { - /// - /// 1: select() - Triggers the select event of each matched element. - /// 2: select(fn) - Binds a function to the select event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "select", fn ) : this.trigger( "select" ); -}; - -jQuery.fn[ "submit" ] = function( fn ) { - /// - /// 1: submit() - Triggers the submit event of each matched element. - /// 2: submit(fn) - Binds a function to the submit event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "submit", fn ) : this.trigger( "submit" ); -}; - -jQuery.fn[ "keydown" ] = function( fn ) { - /// - /// 1: keydown() - Triggers the keydown event of each matched element. - /// 2: keydown(fn) - Binds a function to the keydown event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "keydown", fn ) : this.trigger( "keydown" ); -}; - -jQuery.fn[ "keypress" ] = function( fn ) { - /// - /// 1: keypress() - Triggers the keypress event of each matched element. - /// 2: keypress(fn) - Binds a function to the keypress event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "keypress", fn ) : this.trigger( "keypress" ); -}; - -jQuery.fn[ "keyup" ] = function( fn ) { - /// - /// 1: keyup() - Triggers the keyup event of each matched element. - /// 2: keyup(fn) - Binds a function to the keyup event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "keyup", fn ) : this.trigger( "keyup" ); -}; - -jQuery.fn[ "error" ] = function( fn ) { - /// - /// 1: error() - Triggers the error event of each matched element. - /// 2: error(fn) - Binds a function to the error event of each matched element. - /// - /// The function to execute. - /// - - return fn ? this.bind( "error", fn ) : this.trigger( "error" ); -}; - -// Prevent memory leaks in IE -// Window isn't included so as not to unbind existing unload events -// More info: -// - http://isaacschlueter.com/2006/10/msie-memory-leaks/ -if ( window.attachEvent && !window.addEventListener ) { - window.attachEvent("onunload", function() { - for ( var id in jQuery.cache ) { - if ( jQuery.cache[ id ].handle ) { - // Try/Catch is to handle iframes being unloaded, see #4280 - try { - jQuery.event.remove( jQuery.cache[ id ].handle.elem ); - } catch(e) {} - } - } - }); -} -/*! - * Sizzle CSS Selector Engine - v1.0 - * Copyright 2009, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function(){ - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function(selector, context, results, seed) { - results = results || []; - var origContext = context = context || document; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context), - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set ); - } - } - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - var ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; - } - - if ( context ) { - var ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray(set); - } else { - prune = false; - } - - while ( parts.length ) { - var cur = parts.pop(), pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - } else if ( context && context.nodeType === 1 ) { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - } else { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function(results){ - /// - /// Removes all duplicate elements from an array of elements. - /// - /// The array to translate - /// The array after translation. - - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort(sortOrder); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[i-1] ) { - results.splice(i--, 1); - } - } - } - } - - return results; -}; - -Sizzle.matches = function(expr, set){ - return Sizzle(expr, null, null, set); -}; - -Sizzle.find = function(expr, context, isXML){ - var set, match; - - if ( !expr ) { - return []; - } - - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var type = Expr.order[i], match; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice(1,1); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); - set = Expr.find[ type ]( match, context, isXML ); - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = context.getElementsByTagName("*"); - } - - return {set: set, expr: expr}; -}; - -Sizzle.filter = function(expr, set, inplace, not){ - var old = expr, result = [], curLoop = set, match, anyFound, - isXMLFilter = set && set[0] && isXML(set[0]); - - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - var filter = Expr.filter[ type ], found, item, left = match[1]; - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - } else { - curLoop[i] = false; - } - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw "Syntax error, unrecognized expression: " + msg; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - match: { - ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - leftMatch: {}, - attrMap: { - "class": "className", - "for": "htmlFor" - }, - attrHandle: { - href: function(elem){ - return elem.getAttribute("href"); - } - }, - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test(part), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - ">": function(checkSet, part){ - var isPartStr = typeof part === "string"; - - if ( isPartStr && !/\W/.test(part) ) { - part = part.toLowerCase(); - - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - } else { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - "": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = part.toLowerCase(); - checkFn = dirNodeCheck; - } - - checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); - }, - "~": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = part.toLowerCase(); - checkFn = dirNodeCheck; - } - - checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); - } - }, - find: { - ID: function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? [m] : []; - } - }, - NAME: function(match, context){ - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], results = context.getElementsByName(match[1]); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - TAG: function(match, context){ - return context.getElementsByTagName(match[1]); - } - }, - preFilter: { - CLASS: function(match, curLoop, inplace, result, not, isXML){ - match = " " + match[1].replace(/\\/g, "") + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - ID: function(match){ - return match[1].replace(/\\/g, ""); - }, - TAG: function(match, curLoop){ - return match[1].toLowerCase(); - }, - CHILD: function(match){ - if ( match[1] === "nth" ) { - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - ATTR: function(match, curLoop, inplace, result, not, isXML){ - var name = match[1].replace(/\\/g, ""); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - PSEUDO: function(match, curLoop, inplace, result, not){ - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - if ( !inplace ) { - result.push.apply( result, ret ); - } - return false; - } - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - POS: function(match){ - match.unshift( true ); - return match; - } - }, - filters: { - enabled: function(elem){ - return elem.disabled === false && elem.type !== "hidden"; - }, - disabled: function(elem){ - return elem.disabled === true; - }, - checked: function(elem){ - return elem.checked === true; - }, - selected: function(elem){ - // Accessing this property makes selected-by-default - // options in Safari work properly - elem.parentNode.selectedIndex; - return elem.selected === true; - }, - parent: function(elem){ - return !!elem.firstChild; - }, - empty: function(elem){ - return !elem.firstChild; - }, - has: function(elem, i, match){ - /// - /// Internal use only; use hasClass('class') - /// - /// - - return !!Sizzle( match[3], elem ).length; - }, - header: function(elem){ - return /h\d/i.test( elem.nodeName ); - }, - text: function(elem){ - return "text" === elem.type; - }, - radio: function(elem){ - return "radio" === elem.type; - }, - checkbox: function(elem){ - return "checkbox" === elem.type; - }, - file: function(elem){ - return "file" === elem.type; - }, - password: function(elem){ - return "password" === elem.type; - }, - submit: function(elem){ - return "submit" === elem.type; - }, - image: function(elem){ - return "image" === elem.type; - }, - reset: function(elem){ - return "reset" === elem.type; - }, - button: function(elem){ - return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; - }, - input: function(elem){ - return /input|select|textarea|button/i.test(elem.nodeName); - } - }, - setFilters: { - first: function(elem, i){ - return i === 0; - }, - last: function(elem, i, match, array){ - return i === array.length - 1; - }, - even: function(elem, i){ - return i % 2 === 0; - }, - odd: function(elem, i){ - return i % 2 === 1; - }, - lt: function(elem, i, match){ - return i < match[3] - 0; - }, - gt: function(elem, i, match){ - return i > match[3] - 0; - }, - nth: function(elem, i, match){ - return match[3] - 0 === i; - }, - eq: function(elem, i, match){ - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function(elem, match, i, array){ - var name = match[1], filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - } else if ( name === "not" ) { - var not = match[3]; - - for ( var i = 0, l = not.length; i < l; i++ ) { - if ( not[i] === elem ) { - return false; - } - } - - return true; - } else { - Sizzle.error( "Syntax error, unrecognized expression: " + name ); - } - }, - CHILD: function(elem, match){ - var type = match[1], node = elem; - switch (type) { - case 'only': - case 'first': - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - if ( type === "first" ) { - return true; - } - node = elem; - case 'last': - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - return true; - case 'nth': - var first = match[2], last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - if ( first === 0 ) { - return diff === 0; - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - ID: function(elem, match){ - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - TAG: function(elem, match){ - return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; - }, - CLASS: function(elem, match){ - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - ATTR: function(elem, match){ - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - POS: function(elem, match, i, array){ - var name = match[2], filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){ - return "\\" + (num - 0 + 1); - })); -} - -var makeArray = function(array, results) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 ); - -// Provide a fallback method if it does not work -} catch(e){ - makeArray = function(array, results) { - var ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - } else { - if ( typeof array.length === "number" ) { - for ( var i = 0, l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - } else { - for ( var i = 0; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.compareDocumentPosition ? -1 : 1; - } - - var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( "sourceIndex" in document.documentElement ) { - sortOrder = function( a, b ) { - if ( !a.sourceIndex || !b.sourceIndex ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.sourceIndex ? -1 : 1; - } - - var ret = a.sourceIndex - b.sourceIndex; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( document.createRange ) { - sortOrder = function( a, b ) { - if ( !a.ownerDocument || !b.ownerDocument ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.ownerDocument ? -1 : 1; - } - - var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); - aRange.setStart(a, 0); - aRange.setEnd(a, 0); - bRange.setStart(b, 0); - bRange.setEnd(b, 0); - var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} - -// Utility function for retreiving the text value of an array of DOM nodes -function getText( elems ) { - var ret = "", elem; - - for ( var i = 0; elems[i]; i++ ) { - elem = elems[i]; - - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; - - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += getText( elem.childNodes ); - } - } - - return ret; -} - -// [vsdoc] The following function has been modified for IntelliSense. -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - // var form = document.createElement("div"), - // id = "script" + (new Date).getTime(); - // form.innerHTML = ""; - - // // Inject it into the root element, check its status, and remove it quickly - // var root = document.documentElement; - // root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - // if ( document.getElementById( id ) ) { - Expr.find.ID = function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; - } - }; - - Expr.filter.ID = function(elem, match){ - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - // } - - // root.removeChild( form ); - root = form = null; // release memory in IE -})(); - -// [vsdoc] The following function has been modified for IntelliSense. -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - // var div = document.createElement("div"); - // div.appendChild( document.createComment("") ); - - // Make sure no comments are found - // if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function(match, context){ - var results = context.getElementsByTagName(match[1]); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - // } - - // Check to see if an attribute returns normalized href attributes - // div.innerHTML = ""; - // if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - // div.firstChild.getAttribute("href") !== "#" ) { - Expr.attrHandle.href = function(elem){ - return elem.getAttribute("href", 2); - }; - // } - - div = null; // release memory in IE -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, div = document.createElement("div"); - div.innerHTML = "

"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function(query, context, extra, seed){ - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && context.nodeType === 9 && !isXML(context) ) { - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(e){} - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - div = null; // release memory in IE - })(); -} - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function(match, context, isXML) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - div = null; // release memory in IE -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; - } - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -var contains = document.compareDocumentPosition ? function(a, b){ - /// - /// Check to see if a DOM node is within another DOM node. - /// - /// - /// The DOM element that may contain the other element. - /// - /// - /// The DOM node that may be contained by the other element. - /// - /// - - return a.compareDocumentPosition(b) & 16; -} : function(a, b){ - /// - /// Check to see if a DOM node is within another DOM node. - /// - /// - /// The DOM element that may contain the other element. - /// - /// - /// The DOM node that may be contained by the other element. - /// - /// - - return a !== b && (a.contains ? a.contains(b) : true); -}; - -var isXML = function(elem){ - /// - /// Determines if the parameter passed is an XML document. - /// - /// The object to test - /// True if the parameter is an XML document; otherwise false. - - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function(selector, context){ - var tmpSet = [], later = "", match, - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.getText = getText; -jQuery.isXMLDoc = isXML; -jQuery.contains = contains; - -return; - -window.Sizzle = Sizzle; - -})(); -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - slice = Array.prototype.slice; - -// Implement the identical functionality for filter and not -var winnow = function( elements, qualifier, keep ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return (elem === qualifier) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return (jQuery.inArray( elem, qualifier ) >= 0) === keep; - }); -}; - -jQuery.fn.extend({ - find: function( selector ) { - /// - /// Searches for all elements that match the specified expression. - /// This method is a good way to find additional descendant - /// elements with which to process. - /// All searching is done using a jQuery expression. The expression can be - /// written using CSS 1-3 Selector syntax, or basic XPath. - /// Part of DOM/Traversing - /// - /// - /// - /// An expression to search with. - /// - /// - - var ret = this.pushStack( "", "find", selector ), length = 0; - - for ( var i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( var n = length; n < ret.length; n++ ) { - for ( var r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - /// - /// Reduce the set of matched elements to those that have a descendant that matches the - /// selector or DOM element. - /// - /// - /// A string containing a selector expression to match elements against. - /// - /// - - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - /// - /// Removes any elements inside the array of elements from the set - /// of matched elements. This method is used to remove one or more - /// elements from a jQuery object. - /// Part of DOM/Traversing - /// - /// - /// A set of elements to remove from the jQuery set of matched elements. - /// - /// - - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - /// - /// Removes all elements from the set of matched elements that do not - /// pass the specified filter. This method is used to narrow down - /// the results of a search. - /// }) - /// Part of DOM/Traversing - /// - /// - /// - /// A function to use for filtering - /// - /// - - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - /// - /// Checks the current selection against an expression and returns true, - /// if at least one element of the selection fits the given expression. - /// Does return false, if no element fits or the expression is not valid. - /// filter(String) is used internally, therefore all rules that apply there - /// apply here, too. - /// Part of DOM/Traversing - /// - /// - /// - /// The expression with which to filter - /// - - return !!selector && jQuery.filter( selector, this ).length > 0; - }, - - closest: function( selectors, context ) { - /// - /// Get a set of elements containing the closest parent element that matches the specified selector, the starting element included. - /// - /// - /// A string containing a selector expression to match elements against. - /// - /// - /// A DOM element within which a matching element may be found. If no context is passed - /// in then the context of the jQuery set will be used instead. - /// - /// - - if ( jQuery.isArray( selectors ) ) { - var ret = [], cur = this[0], match, matches = {}, selector; - - if ( cur && selectors.length ) { - for ( var i = 0, l = selectors.length; i < l; i++ ) { - selector = selectors[i]; - - if ( !matches[selector] ) { - matches[selector] = jQuery.expr.match.POS.test( selector ) ? - jQuery( selector, context || this.context ) : - selector; - } - } - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( selector in matches ) { - match = matches[selector]; - - if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { - ret.push({ selector: selector, elem: cur }); - delete matches[selector]; - } - } - cur = cur.parentNode; - } - } - - return ret; - } - - var pos = jQuery.expr.match.POS.test( selectors ) ? - jQuery( selectors, context || this.context ) : null; - - return this.map(function( i, cur ) { - while ( cur && cur.ownerDocument && cur !== context ) { - if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) { - return cur; - } - cur = cur.parentNode; - } - return null; - }); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - /// - /// Searches every matched element for the object and returns - /// the index of the element, if found, starting with zero. - /// Returns -1 if the object wasn't found. - /// Part of Core - /// - /// - /// - /// Object to search for - /// - - if ( !elem || typeof elem === "string" ) { - return jQuery.inArray( this[0], - // If it receives a string, the selector is used - // If it receives nothing, the siblings are used - elem ? jQuery( elem ) : this.parent().children() ); - } - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - /// - /// Adds one or more Elements to the set of matched elements. - /// Part of DOM/Traversing - /// - /// - /// A string containing a selector expression to match additional elements against. - /// - /// - /// Add some elements rooted against the specified context. - /// - /// - - var set = typeof selector === "string" ? - jQuery( selector, context || this.context ) : - jQuery.makeArray( selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - /// - /// Adds the previous selection to the current selection. - /// - /// - - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, slice.call(arguments).join(",") ); - }; -}); - -jQuery.fn[ "parentsUntil" ] = function( until, selector ) { - /// - /// Get the ancestors of each element in the current set of matched elements, up to but not - /// including the element matched by the selector. - /// - /// - /// A string containing a selector expression to indicate where to stop matching ancestor - /// elements. - /// - /// - - var fn = function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - } - - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( "parentsUntil" ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "parentsUntil" ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, "parentsUntil", slice.call(arguments).join(",") ); -}; - -jQuery.fn[ "nextUntil" ] = function( until, selector ) { - /// - /// Get all following siblings of each element up to but not including the element matched - /// by the selector. - /// - /// - /// A string containing a selector expression to indicate where to stop matching following - /// sibling elements. - /// - /// - - var fn = function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - } - - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( "nextUntil" ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "nextUntil" ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, "nextUntil", slice.call(arguments).join(",") ); -}; - -jQuery.fn[ "prevUntil" ] = function( until, selector ) { - /// - /// Get all preceding siblings of each element up to but not including the element matched - /// by the selector. - /// - /// - /// A string containing a selector expression to indicate where to stop matching preceding - /// sibling elements. - /// - /// - - var fn = function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - } - - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( "prevUntil" ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "prevUntil" ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, "prevUntil", slice.call(arguments).join(",") ); -}; - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - /// - /// This member is internal only. - /// - /// - - var matched = [], cur = elem[dir]; - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - /// - /// This member is internal only. - /// - /// - - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - /// - /// This member is internal only. - /// - /// - - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); -var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g, - rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, - rtagName = /<([\w:]+)/, - rtbody = /"; - }, - wrapMap = { - option: [ 1, "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }; - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and +<# } #> + + + +<# } #> +<% using (Html.BeginForm()) { %> + <%: Html.ValidationSummary(true) %> +
+ <#= Model.ViewDataTypeName ?? String.Empty #> + + <%: Html.Partial("CreateOrEdit", Model) %> +

+ +

+
+<% } %> + +
+ <%: Html.ActionLink("Back to List", "Index") %> +
+<# +// The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +if(Model.IsContentPage) { +#> + + +<# + foreach(string cphid in Model.SectionNames) { + if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { + CPHCounter++; +#> + + + +<# + } + } +#> +<# +} else if(!Model.IsContentPage) { + ClearIndent(); +#> + + +<# +} +#> + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Create.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Create.vb.t4 new file mode 100644 index 0000000..219aae6 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Create.vb.t4 @@ -0,0 +1,200 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# +Dim viewDataType = CType(Model.ViewDataType, CodeType) +Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) +Dim CPHCounter As Integer = 1 +#> +<# +If Model.IsContentPage Then +#> +<%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + For Each cphid As String In Model.SectionNames + If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then +#> + + <#= Model.ViewName #> + + +<# + CPHCounter += 1 + End If + Next +#> + + +

<#= Model.ViewName #>

+ +<# +Else +#> +<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" ") +End If +#> +<%-- The following line works around an ASP.NET compiler warning --%> +<%: "" %> + +<# If Model.ReferenceScriptLibraries Then #> +<# If Not Model.IsContentPage Then #> + +<# End If #> + + + +<# End If #> +<% Using Html.BeginForm() %> + <%: Html.ValidationSummary(True) %> +
+ <#= If(Model.ViewDataTypeName, String.Empty) #> + + <%: Html.Partial("CreateOrEdit", Model) %> +

+ +

+
+<% End Using %> + +
+ <%: Html.ActionLink("Back to List", "Index") %> +
+<# +' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +If Model.IsContentPage +#> + +
+<# + For Each cphid As String In Model.SectionNames + If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then + CPHCounter +=1 +#> + + + +<# + End If + Next +#> +<# +Else If Not Model.IsContentPage Then + ClearIndent() +#> + + +<# +End If +#> + +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.cs.t4 new file mode 100644 index 0000000..c5b0445 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.cs.t4 @@ -0,0 +1,138 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="ascx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# + var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; + var mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; +#> +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<#= mvcViewDataTypeGenericString #>" %> + +<# +foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, false)) { + if (!property.IsPrimaryKey && !property.IsForeignKey && !property.IsReadOnly) { +#> +
+ <%: Html.LabelFor(model => model.<#= property.Name #>) %> +
+
+ <%: Html.EditorFor(model => model.<#= property.Name #>) %> + <%: Html.ValidationMessageFor(model => model.<#= property.Name #>) %> +
+ +<# + } +} +#> +<# +foreach (RelatedEntityInfo relation in ParentRelations) { +#> +
+ <#= relation.RelationName #> +
+
+ <%: Html.DropDownListFor(model => model.<#= relation.RelationProperty.Name #>, ((IEnumerable<<#= relation.RelatedEntityType.FullName #>>)ViewBag.Possible<#= relation.RelationNamePlural #>).Select(option => new SelectListItem { + Text = <#= GetValueExpression("option", relation.RelatedEntityType) #>, + Value = option.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), + Selected = (Model != null) && (option.<#= relation.RelatedEntityPrimaryKeyName #> == Model.<#= relation.RelationProperty.Name #>) + }), "Choose...") %> + <%: Html.ValidationMessageFor(model => model.<#= relation.RelationProperty.Name #>) %> +
+<# +} +#> +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.vb.t4 new file mode 100644 index 0000000..c301424 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/CreateOrEdit.vb.t4 @@ -0,0 +1,136 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="ascx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# +Dim viewDataType = CType(Model.ViewDataType, CodeType) +Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) +#> +<%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl<#= mvcViewDataTypeGenericString #>" %> + +<# +For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, False) + If (Not modelProp.IsPrimaryKey) AndAlso (Not modelProp.IsForeignKey) AndAlso (Not modelProp.IsReadOnly) Then +#> +
+ <%: Html.LabelFor(Function(model) model.<#= modelProp.Name #>) %> +
+
+ <%: Html.EditorFor(Function(model) model.<#= modelProp.Name #>) %> + <%: Html.ValidationMessageFor(Function(model) model.<#= modelProp.Name #>) %> +
+ +<# + End If +Next +#> +<# For Each relation As RelatedEntityInfo In ParentRelations #> +
+ <#= relation.RelationName #> +
+
+ <%: Html.DropDownListFor(Function(model) model.<#= relation.RelationProperty.Name #>, CType(ViewBag.Possible<#= relation.RelationNamePlural #>, IEnumerable(Of <#= relation.RelatedEntityType.FullName #>)).Select(Function(optionValue) New SelectListItem() With { _ + .Text = <#= GetValueExpression("optionValue", relation.RelatedEntityType) #>, _ + .Value = optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), _ + .Selected = (Model IsNot Nothing) AndAlso (optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.Equals(Model.<#= relation.RelationProperty.Name #>)) _ + }), "Choose...") %> + <%: Html.ValidationMessageFor(Function(model) model.<#= relation.RelationProperty.Name #>) %> +
+<# Next #><#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.cs.t4 new file mode 100644 index 0000000..1247d32 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.cs.t4 @@ -0,0 +1,193 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# +string mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; +int CPHCounter = 1; +#> +<# +if(Model.IsContentPage) { +#> +<%@ Page Title="" Language="C#" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + foreach(string cphid in Model.SectionNames) { + if(cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase)) { +#> + + <#= Model.ViewName #> + + +<# + CPHCounter++; + } + } +#> + + +

<#= Model.ViewName #>

+ +<# +} else { +#> +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" "); +} +#> +

Are you sure you want to delete this?

+
+ <#= Model.ViewDataTypeName ?? String.Empty #> +<# +foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, true)) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +
<#= property.Name #>
+
<%: <#= property.ValueExpression #> %>
+<# + } +} +#> +
+<% using (Html.BeginForm()) { %> +

+ | + <%: Html.ActionLink("Back to List", "Index") %> +

+<% } %> + +<# +// The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +if(Model.IsContentPage) { +#> +
+<# + foreach(string cphid in Model.SectionNames) { + if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { + CPHCounter++; +#> + + + +<# + } + } +#> +<# +} else if(!Model.IsContentPage) { + ClearIndent(); +#> + + +<# +} +#> + + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.vb.t4 new file mode 100644 index 0000000..c143349 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Delete.vb.t4 @@ -0,0 +1,195 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# +Dim viewDataType = CType(Model.ViewDataType, CodeType) +Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) +Dim CPHCounter As Integer = 1 +#> +<# +If Model.IsContentPage Then +#> +<%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + For Each cphid As String In Model.SectionNames + If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then +#> + + <#= Model.ViewName #> + + +<# + CPHCounter += 1 + End If + Next +#> + + +

<#= Model.ViewName #>

+ +<# +Else +#> +<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" ") +End If +#> +

Are you sure you want to delete this?

+
+ <#= If(Model.ViewDataTypeName, String.Empty) #> +<# +For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, True) + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +
<#= modelProp.Name #>
+
<%: <#= modelProp.ValueExpression #> %>
+<# + End If +Next +#> +
+<% Using Html.BeginForm() %> +

+ | + <%: Html.ActionLink("Back to List", "Index") %> +

+<% End Using %> + +<# +' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +If Model.IsContentPage +#> +
+<# + For Each cphid As String In Model.SectionNames + If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then + CPHCounter +=1 +#> + + + +<# + End If + Next +#> +<# +Else If Not Model.IsContentPage Then + ClearIndent() +#> + + +<# +End If +#> + +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Details.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Details.cs.t4 new file mode 100644 index 0000000..64b5638 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Details.cs.t4 @@ -0,0 +1,202 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# +string mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; +int CPHCounter = 1; +#> +<# +if(Model.IsContentPage) { +#> +<%@ Page Title="" Language="C#" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + foreach(string cphid in Model.SectionNames) { + if(cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase)) { +#> + + <#= Model.ViewName #> + + +<# + CPHCounter++; + } + } +#> + + +

<#= Model.ViewName #>

+ +<# +} else { +#> +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" "); +} +#> +
+ <#= Model.ViewDataTypeName ?? String.Empty #> +<# +foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, true)) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +
<#= property.Name #>
+
<%: <#= property.ValueExpression #> %>
+<# + } +} +#> +
+

+<# +if (!String.IsNullOrEmpty(Model.PrimaryKeyName)) { +#> + + <%: Html.ActionLink("Edit", "Edit", new { id=Model.<#= Model.PrimaryKeyName #> }) %> | + <%: Html.ActionLink("Back to List", "Index") %> +<# +} else { +#> + <%: Html.ActionLink("Edit", "Edit", new { /* id=Model.PrimaryKey */ }) %> | + <%: Html.ActionLink("Back to List", "Index") %> +<# +} +#> +

+<# +// The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +if(Model.IsContentPage) { +#> + +
+<# + foreach(string cphid in Model.SectionNames) { + if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { + CPHCounter++; +#> + + + +<# + } + } +#> +<# +} else if(!Model.IsContentPage) { + ClearIndent(); +#> + + +<# +} +#> + + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Details.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Details.vb.t4 new file mode 100644 index 0000000..0dd7e18 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Details.vb.t4 @@ -0,0 +1,201 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# +Dim viewDataType = CType(Model.ViewDataType, CodeType) +Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) +Dim CPHCounter As Integer = 1 +#> +<# +If Model.IsContentPage Then +#> +<%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + For Each cphid As String In Model.SectionNames + If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then +#> + + <#= Model.ViewName #> + + +<# + CPHCounter += 1 + End If + Next +#> + + +

<#= Model.ViewName #>

+ +<# +Else +#> +<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" ") +End If +#> +
+ <#= If(Model.ViewDataTypeName, String.Empty) #> +<# +For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, True) + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +
<#= modelProp.Name #>
+
<%: <#= modelProp.ValueExpression #> %>
+<# + End If +Next +#> +
+

+<# If Not String.IsNullOrEmpty(Model.PrimaryKeyName) Then #> + <%: Html.ActionLink("Edit", "Edit", New With {.id = Model.<#= Model.PrimaryKeyName #>}) %> | + <%: Html.ActionLink("Back to List", "Index") %> +<# +Else +#> + <%--<%: Html.ActionLink("Edit", "Edit", New With {.id = Model.PrimaryKey}) %> |--%> + <%: Html.ActionLink("Back to List", "Index") %> +<# +End If +#> +

+<# +' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +If Model.IsContentPage +#> + +
+<# + For Each cphid As String In Model.SectionNames + If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then + CPHCounter +=1 +#> + + + +<# + End If + Next +#> +<# +Else If Not Model.IsContentPage Then + ClearIndent() +#> + + +<# +End If +#> + +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.cs.t4 new file mode 100644 index 0000000..e6c18d4 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.cs.t4 @@ -0,0 +1,198 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# +string mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; +int CPHCounter = 1; +#> +<# +if(Model.IsContentPage) { +#> +<%@ Page Title="" Language="C#" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + foreach(string cphid in Model.SectionNames) { + if(cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase)) { +#> + + <#= Model.ViewName #> + + +<# + CPHCounter++; + } + } +#> + + +

<#= Model.ViewName #>

+ +<# +} else { +#> +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" "); +} +#> +<# if (Model.ReferenceScriptLibraries) { #> +<# if (!Model.IsContentPage) { #> + +<# } #> + + + +<# } #> +<% using (Html.BeginForm()) { %> + <%: Html.ValidationSummary(true) %> +
+ <#= Model.ViewDataTypeName ?? String.Empty #> + +<# foreach (ModelProperty property in GetModelProperties(viewDataType, false).Where(x => x.IsPrimaryKey)) { #> + <%: Html.HiddenFor(model => model.<#= property.Name #>) %> +<# } #> + <%: Html.Partial("CreateOrEdit", Model) %> +

+ +

+
+<% } %> + +
+ <%: Html.ActionLink("Back to List", "Index") %> +
+<# +// The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +if(Model.IsContentPage) { +#> + +
+<# + foreach(string cphid in Model.SectionNames) { + if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { + CPHCounter++; +#> + + + +<# + } + } +#> +<# +} else if(!Model.IsContentPage) { + ClearIndent(); +#> + + +<# +} +#> + + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.vb.t4 new file mode 100644 index 0000000..38d68ef --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Edit.vb.t4 @@ -0,0 +1,203 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# +Dim viewDataType = CType(Model.ViewDataType, CodeType) +Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) +Dim CPHCounter As Integer = 1 +#> +<# +If Model.IsContentPage Then +#> +<%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + For Each cphid As String In Model.SectionNames + If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then +#> + + <#= Model.ViewName #> + + +<# + CPHCounter += 1 + End If + Next +#> + + +

<#= Model.ViewName #>

+ +<# +Else +#> +<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" ") +End If +#> +<%-- The following line works around an ASP.NET compiler warning --%> +<%: "" %> + +<# If Model.ReferenceScriptLibraries Then #> +<# If Not Model.IsContentPage Then #> + +<# End If #> + + + +<# End If #> +<% Using Html.BeginForm() %> + <%: Html.ValidationSummary(True) %> +
+ <#= If(Model.ViewDataTypeName, String.Empty) #> + +<# For Each modelProp As ModelProperty In GetModelProperties(viewDataType, False).Where(Function(x) x.IsPrimaryKey) #> + <%: Html.HiddenFor(Function(model) model.<#= modelProp.Name #>) %> +<# Next #> + <%: Html.Partial("CreateOrEdit", Model) %> +

+ +

+
+<% End Using %> + +
+ <%: Html.ActionLink("Back to List", "Index") %> +
+<# +' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +If Model.IsContentPage +#> + +
+<# + For Each cphid As String In Model.SectionNames + If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then + CPHCounter +=1 +#> + + + +<# + End If + Next +#> +<# +Else If Not Model.IsContentPage Then + ClearIndent() +#> + + +<# +End If +#> + +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.cs.t4 new file mode 100644 index 0000000..293dc27 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.cs.t4 @@ -0,0 +1,79 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# +string mvcViewDataTypeGenericString = (viewDataType != null) ? "<" + viewDataType.FullName + ">" : ""; +int CPHCounter = 1; +#> +<# if(Model.IsContentPage) { #> +<%@ Page Title="" Language="C#" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + foreach(string cphid in Model.SectionNames) { + if(cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase)) { +#> + + <#= Model.ViewName #> + + +<# + CPHCounter++; + } + } +#> + + +

<#= Model.ViewName #>

+ +<# +} else { +#> +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" "); +} +#> +<# +if(!Model.IsContentPage) { +#> +
+ +
+<# +} +#> +<# +// The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +if(Model.IsContentPage) { +#> +
+<# + foreach(string cphid in Model.SectionNames) { + if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { + CPHCounter++; +#> + + + +<# + } + } +#> +<# +} else if(!Model.IsContentPage) { + ClearIndent(); +#> + + +<# +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.vb.t4 new file mode 100644 index 0000000..7d65ef2 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Empty.vb.t4 @@ -0,0 +1,81 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<# +Dim viewDataType = CType(Model.ViewDataType, EnvDTE.CodeType) +Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of " & viewDataType.FullName & ")", String.Empty) +Dim CPHCounter As Integer = 1 +#> +<# +If Model.IsContentPage Then +#> +<%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + For Each cphid As String In Model.SectionNames + If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then +#> + + <#= Model.ViewName #> + + +<# + CPHCounter += 1 + End If + Next +#> + + +

<#= Model.ViewName #>

+ +<# +Else +#> +<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" ") +End If +#> +<# +If Not Model.IsContentPage Then +#> +
+ +
+<# +End If +#> +<# +' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +If Model.IsContentPage Then +#> +
+<# + For Each cphid As String In Model.SectionNames + If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then + CPHCounter += 1 +#> + + + +<# + End If + Next +#> +<# +Else If Not Model.IsContentPage Then + ClearIndent() +#> + + +<# +End If +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Index.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Index.cs.t4 new file mode 100644 index 0000000..b5c1b7c --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Index.cs.t4 @@ -0,0 +1,227 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# +string mvcViewDataTypeGenericString = (viewDataType != null) ? ">" : ">"; +int CPHCounter = 1; +#> +<# +if(Model.IsContentPage) { +#> +<%@ Page Title="" Language="C#" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + foreach(string cphid in Model.SectionNames) { + if(cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase)) { +#> + + <#= Model.ViewName #> + + +<# + CPHCounter++; + } + } +#> + + +

<#= Model.ViewName #>

+ +<# +} else { +#> +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" "); +} +#> +

+ <%: Html.ActionLink("Create New", "Create") %> +

+ + + +<# +List properties = GetModelProperties(Model.ViewDataType, true); +foreach (ModelProperty property in properties) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +<# + } +} +#> + + +<% foreach (var item in Model) { %> + +<# +if (!String.IsNullOrEmpty(Model.PrimaryKeyName)) { +#> + +<# +} else { +#> + +<# +} + +foreach (ModelProperty property in properties) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +<# + } +} +#> + +<% } %> + +
+ <#= property.Name #> +
+ <%: Html.ActionLink("Edit", "Edit", new { id=item.<#= Model.PrimaryKeyName #> }) %> | + <%: Html.ActionLink("Details", "Details", new { id=item.<#= Model.PrimaryKeyName #> }) %> | + <%: Html.ActionLink("Delete", "Delete", new { id=item.<#= Model.PrimaryKeyName #> }) %> + + <%: Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) %> | + <%: Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) %> | + <%: Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) %> + + <%: <#= property.ValueExpression.Replace("Model.", "item.") #> %> +
+<# +// The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +if(Model.IsContentPage) { +#> + +
+<# + foreach(string cphid in Model.SectionNames) { + if(!cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) && !cphid.Equals(Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase)) { + CPHCounter++; +#> + + + +<# + } + } +#> +<# +} else if(!Model.IsContentPage) { + ClearIndent(); +#> + + +<# +} +#> + + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/Index.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/AspxView/Index.vb.t4 new file mode 100644 index 0000000..eb56f2e --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/Index.vb.t4 @@ -0,0 +1,228 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="aspx" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# +Dim viewDataType = CType(Model.ViewDataType, CodeType) +Dim mvcViewDataTypeGenericString As String = If(viewDataType IsNot Nothing, "(Of IEnumerable (Of " & viewDataType.FullName & "))", String.Empty) +Dim CPHCounter As Integer = 1 +#> +<# +If Model.IsContentPage Then +#> +<%@ Page Title="" Language="VB" MasterPageFile="~<#= Model.Layout #>" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + +<# + For Each cphid As String In Model.SectionNames + If cphid.Equals("TitleContent", StringComparison.OrdinalIgnoreCase) Then +#> + + <#= Model.ViewName #> + + +<# + CPHCounter += 1 + End If + Next +#> + + +

<#= Model.ViewName #>

+ +<# +Else +#> +<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage<#= mvcViewDataTypeGenericString #>" %> + + + + + <#= Model.ViewName #> + + +<# + PushIndent(" ") +End If +#> +

+ <%: Html.ActionLink("Create New", "Create") %> +

+ + + +<# +Dim properties As List(Of ModelProperty) = GetModelProperties(Model.ViewDataType, True) +For Each modelProp As ModelProperty In properties + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +<# + End If +Next +#> + + +<% For Each item In Model %> + <% Dim itemValue = item %> + +<# If Not String.IsNullOrEmpty(Model.PrimaryKeyName) Then #> + +<# +Else +#> + +<# +End If + +For Each modelProp As ModelProperty In properties + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +<# + End If +Next +#> + +<% Next %> + +
+ <#= modelProp.Name #> +
+ <%: Html.ActionLink("Edit", "Edit", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) %> | + <%: Html.ActionLink("Details", "Details", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) %> | + <%: Html.ActionLink("Delete", "Delete", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) %> + + <%--<%: Html.ActionLink("Edit", "Edit", New With {.id = itemValue.PrimaryKey}) %> | + <%: Html.ActionLink("Details", "Details", New With {.id = itemValue.PrimaryKey}) %> | + <%: Html.ActionLink("Delete", "Delete", New With {.id = itemValue.PrimaryKey}) %>--%> + + <%: <#= modelProp.ValueExpression.Replace("Model.", "itemValue.") #> %> +
+<# +' The following code closes the asp:Content tag used in the case of a master page and the body and html tags in the case of a regular view page +#> +<# +If Model.IsContentPage +#> + +
+<# + For Each cphid As String In Model.SectionNames + If String.Compare(cphid, "TitleContent", StringComparison.OrdinalIgnoreCase) <> 0 AndAlso String.Compare(cphid, Model.PrimarySectionName, StringComparison.OrdinalIgnoreCase) <> 0 Then + CPHCounter +=1 +#> + + + +<# + End If + Next +#> +<# +Else If Not Model.IsContentPage Then + ClearIndent() +#> + + +<# +End If +#> + +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/AspxView/MvcScaffolding.AspxView.ps1 b/packages/MvcScaffolding.1.0.0/tools/AspxView/MvcScaffolding.AspxView.ps1 new file mode 100644 index 0000000..95d889c --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/AspxView/MvcScaffolding.AspxView.ps1 @@ -0,0 +1,40 @@ +[T4Scaffolding.ViewScaffolder("ASPX", Description = "Adds an ASP.NET MVC view using the ASPX view engine", LayoutPageFilter = "*.master|*.master")][CmdletBinding()] +param( + [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)][string]$Controller, + [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 1)][string]$ViewName, + [string]$ModelType, + [string]$Template = "Empty", + [string]$Area, + [alias("Layout")]$MasterPage = "", + [alias("SectionNames")][string[]]$ContentPlaceholderIDs, + [alias("PrimarySectionName")][string]$PrimaryContentPlaceholderID, + [switch]$ReferenceScriptLibraries = $false, + [string]$Project, + [string]$CodeLanguage, + [string[]]$TemplateFolders, + [switch]$Force = $false +) + +# Populate masterpage-related args with defaults based on standard MVC 3 site template where not specified. +# If you haven't passed a -MasterPage argument but it looks like you are using a standard master page, assume +# you do want to use that master page. If you really don't want any master, explicitly pass -MasterPage $null. +$defaultMasterPage = "/Views/Shared/Site.Master" +if ($MasterPage -eq "") { + $MasterPage = if (Get-ProjectItem $defaultMasterPage) { $defaultMasterPage } else { $null } +} +if (!$ContentPlaceholderIDs) { $ContentPlaceholderIDs = @("TitleContent", "MainContent") } +if (!$PrimaryContentPlaceholderID) { $PrimaryContentPlaceholderID = "MainContent" } + +# In the case of view names with a leading underscore, this is a Razor convention that Aspx doesn't follow +# so we just strip off any leading underscore +if ($Template.StartsWith("_") -and ($Template.Length -gt 1)) { $Template = $Template.Substring(1) } +if ($ViewName.StartsWith("_") -and ($ViewName.Length -gt 1)) { $ViewName = $ViewName.Substring(1) } + +# In the case of master page names with a leading tilde, strip it off, because the view templates +# automatically prefix the master name with a tilde +if ($MasterPage -and $MasterPage.StartsWith("~")) { + $MasterPage = $MasterPage.Substring(1) +} + +# Inherit all logic from MvcScaffolding.RazorView (merely override the templates) +Scaffold MvcScaffolding.RazorView -Controller $Controller -ViewName $ViewName -ModelType $ModelType -Template $Template -Area $Area -Layout $MasterPage -SectionNames $ContentPlaceholderIDs -PrimarySectionName $PrimaryContentPlaceholderID -ReferenceScriptLibraries:$ReferenceScriptLibraries -Project $Project -CodeLanguage $CodeLanguage -OverrideTemplateFolders $TemplateFolders -Force:$Force \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.cs.t4 new file mode 100644 index 0000000..c1e52d5 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.cs.t4 @@ -0,0 +1,159 @@ +<#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> +<#@ Output Extension="cs" #> +<#@ assembly name="System.Data.Entity" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<#@ import namespace="EnvDTE" #> +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Entity; +using System.Linq; +using System.Web; +using System.Web.Mvc; +<# if(!string.IsNullOrEmpty(Model.ModelTypeNamespace)) { #> +using <#= Model.ModelTypeNamespace #>; +<# } #> +<# if(Model.DbContextNamespace != Model.ModelTypeNamespace) { #> +using <#= Model.DbContextNamespace #>; +<# } #> + +namespace <#= Model.ControllerNamespace #> +{ +<# + var modelType = (CodeType)Model.ModelType; + var modelName = modelType.Name; + var modelNamePlural = Model.ModelTypePluralized; + var modelVariable = modelName.ToLower(); + var relatedEntities = ((IEnumerable)Model.RelatedEntities).OfType(); + var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); + var routingName = Regex.Replace(Model.ControllerName, "Controller$", "", RegexOptions.IgnoreCase); + var isObjectContext = ((CodeType)Model.DbContextType).IsAssignableTo(); +#> + public class <#= Model.ControllerName #> : Controller + { + private <#= ((CodeType)Model.DbContextType).Name #> context = new <#= ((CodeType)Model.DbContextType).Name #>(); + + // + // GET: /<#= routingName #>/ + + public ViewResult Index() + { +<# + var propertiesToInclude = relatedEntities.Select(relation => relation.LazyLoadingProperty).Where(x => x != null); + var includeExpressions = isObjectContext + ? String.Join("", propertiesToInclude.Select(x => String.Format(".Include(\"{0}\")", x.Name))) + : String.Join("", propertiesToInclude.Select(x => String.Format(".Include({0} => {0}.{1})", modelVariable, x.Name))); +#> + return View(context.<#= modelNamePlural #><#= includeExpressions #>.ToList()); + } + + // + // GET: /<#= routingName #>/Details/5 + + public ViewResult Details(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); + return View(<#= modelVariable #>); + } + + // + // GET: /<#= routingName #>/Create + + public ActionResult Create() + { +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(); + } + + // + // POST: /<#= routingName #>/Create + + [HttpPost] + public ActionResult Create(<#= modelName #> <#= modelVariable #>) + { + if (ModelState.IsValid) + { +<# if(primaryKeyProperty.Type.AsString == "System.Guid") { #> + <#= modelVariable #>.<#= primaryKeyProperty.Name #> = Guid.NewGuid(); +<# } #> +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.AddObject(<#= modelVariable #>); +<# } else { #> + context.<#= modelNamePlural #>.Add(<#= modelVariable #>); +<# } #> + context.SaveChanges(); + return RedirectToAction("Index"); + } + +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(<#= modelVariable #>); + } + + // + // GET: /<#= routingName #>/Edit/5 + + public ActionResult Edit(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(<#= modelVariable #>); + } + + // + // POST: /<#= routingName #>/Edit/5 + + [HttpPost] + public ActionResult Edit(<#= modelName #> <#= modelVariable #>) + { + if (ModelState.IsValid) + { +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.Attach(<#= modelVariable #>); + context.ObjectStateManager.ChangeObjectState(<#= modelVariable #>, EntityState.Modified); +<# } else { #> + context.Entry(<#= modelVariable #>).State = EntityState.Modified; +<# } #> + context.SaveChanges(); + return RedirectToAction("Index"); + } +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #>; +<# } #> + return View(<#= modelVariable #>); + } + + // + // GET: /<#= routingName #>/Delete/5 + + public ActionResult Delete(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); + return View(<#= modelVariable #>); + } + + // + // POST: /<#= routingName #>/Delete/5 + + [HttpPost, ActionName("Delete")] + public ActionResult DeleteConfirmed(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= modelName #> <#= modelVariable #> = context.<#= modelNamePlural #>.Single(x => x.<#= primaryKeyProperty.Name #> == id); +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.DeleteObject(<#= modelVariable #>); +<# } else { #> + context.<#= modelNamePlural #>.Remove(<#= modelVariable #>); +<# } #> + context.SaveChanges(); + return RedirectToAction("Index"); + } + } +} \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.vb.t4 new file mode 100644 index 0000000..dc9aa5d --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithContext.vb.t4 @@ -0,0 +1,129 @@ +<#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> +<#@ Output Extension="vb" #> +<#@ assembly name="System.Data.Entity" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<#@ import namespace="EnvDTE" #> +Imports System.Data +Imports System.Data.Entity +Imports System.Linq +Imports System.Web.Mvc +<# if(!string.IsNullOrEmpty(Model.ModelTypeNamespace)) { #> +Imports <#= Model.ModelTypeNamespace #> +<# } #> +<# if((!string.IsNullOrEmpty(Model.DbContextNamespace)) && (Model.DbContextNamespace != Model.ModelTypeNamespace)) { #> +Imports <#= Model.DbContextNamespace #> +<# } #> + +<#= T4Scaffolding.Namespaces.BeginVb(Model.ControllerNamespace, Model.DefaultNamespace) #> +<# + var modelType = (CodeType)Model.ModelType; + var modelName = modelType.Name; + var modelNamePlural = Model.ModelTypePluralized; + var modelVariable = modelName.ToLower(); + var relatedEntities = ((IEnumerable)Model.RelatedEntities).OfType(); + var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); + var routingName = Regex.Replace(Model.ControllerName, "Controller$", "", RegexOptions.IgnoreCase); + var isObjectContext = ((CodeType)Model.DbContextType).IsAssignableTo(); +#> + Public Class <#= Model.ControllerName #> : Inherits Controller + Private context As <#= ((CodeType)Model.DbContextType).Name #> = New <#= ((CodeType)Model.DbContextType).Name #>() + + ' GET: /<#= routingName #>/ + Public Function Index() As ViewResult +<# + var propertiesToInclude = relatedEntities.Select(relation => relation.LazyLoadingProperty).Where(x => x != null); + var includeExpressions = isObjectContext + ? String.Join("", propertiesToInclude.Select(x => String.Format(".Include(\"{0}\")", x.Name))) + : String.Join("", propertiesToInclude.Select(x => String.Format(".Include(Function({0}) {0}.{1})", modelVariable, x.Name))); +#> + return View(context.<#= modelNamePlural #><#= includeExpressions #>.ToList()) + End Function + + ' GET: /<#= routingName #>/Details/5 + Public Function Details(id As <#= primaryKeyProperty.Type.AsString #>) As ViewResult + Dim <#= modelVariable #> As <#= modelName #> = context.<#= modelNamePlural #>.Single(Function(x) x.<#= primaryKeyProperty.Name #> = id) + Return View(<#= modelVariable #>) + End Function + + ' GET: /<#= routingName #>/Create + Public Function Create() As ViewResult +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #> +<# } #> + Return View() + End Function + + ' POST: /<#= routingName #>/Create + + Public Function Create(<#= modelVariable #> As <#= modelName #>) As ActionResult + If ModelState.IsValid +<# if(primaryKeyProperty.Type.AsString == "System.Guid") { #> + <#= modelVariable #>.<#= primaryKeyProperty.Name #> = Guid.NewGuid() +<# } #> +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.AddObject(<#= modelVariable #>) +<# } else { #> + context.<#= modelNamePlural #>.Add(<#= modelVariable #>) +<# } #> + context.SaveChanges() + Return RedirectToAction("Index") + Else +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #> +<# } #> + Return View() + End If + End Function + + ' GET: /<#= routingName #>/Edit/5 + Public Function Edit(id As <#= primaryKeyProperty.Type.AsString #>) As ViewResult + Dim <#= modelVariable #> As <#= modelName #> = context.<#= modelNamePlural #>.Single(Function(x) x.<#= primaryKeyProperty.Name #> = id) +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #> +<# } #> + Return View(<#= modelVariable #>) + End Function + + ' POST: /<#= routingName #>/Edit/5 + + Public Function Edit(<#= modelVariable #> As <#= modelName #>) As ActionResult + If ModelState.IsValid +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.Attach(<#= modelVariable #>) + context.ObjectStateManager.ChangeObjectState(<#= modelVariable #>, EntityState.Modified) +<# } else { #> + context.Entry(<#= modelVariable #>).State = EntityState.Modified +<# } #> + context.SaveChanges() + Return RedirectToAction("Index") + Else +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = context.<#= relatedEntity.RelatedEntityTypeNamePlural #> +<# } #> + Return View() + End If + End Function + + ' GET: /<#= routingName #>/Delete/5 + Public Function Delete(id As <#= primaryKeyProperty.Type.AsString #>) As ViewResult + Dim <#= modelVariable #> as <#= modelName #> = context.<#= modelNamePlural #>.Single(Function(x) x.<#= primaryKeyProperty.Name #> = id) + Return View(<#= modelVariable #>) + End Function + + ' POST: /<#= routingName #>/Delete/5 + + Public Function DeleteConfirmed(id as <#= primaryKeyProperty.Type.AsString #>) As ActionResult + Dim <#= modelVariable #> As <#= modelName #> = context.<#= modelNamePlural #>.Single(Function(x) x.<#= primaryKeyProperty.Name #> = id) +<# if(isObjectContext) { #> + context.<#= modelNamePlural #>.DeleteObject(<#= modelVariable #>) +<# } else { #> + context.<#= modelNamePlural #>.Remove(<#= modelVariable #>) +<# } #> + context.SaveChanges() + Return RedirectToAction("Index") + End Function + End Class +<#= T4Scaffolding.Namespaces.EndVb(Model.ControllerNamespace, Model.DefaultNamespace) #> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.cs.t4 new file mode 100644 index 0000000..d3d60ba --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.cs.t4 @@ -0,0 +1,173 @@ +<#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> +<#@ Output Extension="cs" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<#@ import namespace="EnvDTE" #> +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +<# if(!string.IsNullOrEmpty(Model.ModelTypeNamespace)) { #> +using <#= Model.ModelTypeNamespace #>; +<# } #> +<# if((!string.IsNullOrEmpty(Model.RepositoriesNamespace)) && (Model.RepositoriesNamespace != Model.ModelTypeNamespace)) { #> +using <#= Model.RepositoriesNamespace #>; +<# } #> + +namespace <#= Model.ControllerNamespace #> +{ +<# + var modelType = (CodeType)Model.ModelType; + var modelName = modelType.Name; + var modelNamePlural = Model.ModelTypePluralized; + var modelVariable = modelName.ToLower(); + var relatedEntities = ((IEnumerable)Model.RelatedEntities).OfType(); + var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); + var routingName = Regex.Replace(Model.ControllerName, "Controller$", "", RegexOptions.IgnoreCase); +#> + public class <#= Model.ControllerName #> : Controller + { +<# foreach(var repository in Repositories.Values) { #> + private readonly I<#= repository.RepositoryTypeName #> <#= repository.VariableName #>; +<# } #> + + // If you are using Dependency Injection, you can delete the following constructor + public <#= Model.ControllerName #>() : this(<#= String.Join(", ", Repositories.Values.Select(x => "new " + x.RepositoryTypeName + "()")) #>) + { + } + + public <#= Model.ControllerName #>(<#= String.Join(", ", Repositories.Values.Select(x => "I" + x.RepositoryTypeName + " " + x.VariableName)) #>) + { +<# foreach(var repository in Repositories.Values) { #> + this.<#= repository.VariableName #> = <#= repository.VariableName #>; +<# } #> + } + + // + // GET: /<#= routingName #>/ + + public ViewResult Index() + { +<# + var propertiesToInclude = relatedEntities.Select(relation => relation.LazyLoadingProperty).Where(x => x != null); + var includeExpression = String.Join(", ", propertiesToInclude.Select(x => String.Format("{0} => {0}.{1}", modelVariable, x.Name))); + if (!string.IsNullOrEmpty(includeExpression)) { + includeExpression = "Including(" + includeExpression + ")"; + } +#> + return View(<#= Repositories[modelType.FullName].VariableName #>.All<#= includeExpression #>); + } + + // + // GET: /<#= routingName #>/Details/5 + + public ViewResult Details(<#= primaryKeyProperty.Type.AsString #> id) + { + return View(<#= Repositories[modelType.FullName].VariableName #>.Find(id)); + } + + // + // GET: /<#= routingName #>/Create + + public ActionResult Create() + { +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All; +<# } #> + return View(); + } + + // + // POST: /<#= routingName #>/Create + + [HttpPost] + public ActionResult Create(<#= modelName #> <#= modelVariable #>) + { + if (ModelState.IsValid) { + <#= Repositories[modelType.FullName].VariableName #>.InsertOrUpdate(<#= modelVariable #>); + <#= Repositories[modelType.FullName].VariableName #>.Save(); + return RedirectToAction("Index"); + } else { +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All; +<# } #> + return View(); + } + } + + // + // GET: /<#= routingName #>/Edit/5 + + public ActionResult Edit(<#= primaryKeyProperty.Type.AsString #> id) + { +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All; +<# } #> + return View(<#= Repositories[modelType.FullName].VariableName #>.Find(id)); + } + + // + // POST: /<#= routingName #>/Edit/5 + + [HttpPost] + public ActionResult Edit(<#= modelName #> <#= modelVariable #>) + { + if (ModelState.IsValid) { + <#= Repositories[modelType.FullName].VariableName #>.InsertOrUpdate(<#= modelVariable #>); + <#= Repositories[modelType.FullName].VariableName #>.Save(); + return RedirectToAction("Index"); + } else { +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All; +<# } #> + return View(); + } + } + + // + // GET: /<#= routingName #>/Delete/5 + + public ActionResult Delete(<#= primaryKeyProperty.Type.AsString #> id) + { + return View(<#= Repositories[modelType.FullName].VariableName #>.Find(id)); + } + + // + // POST: /<#= routingName #>/Delete/5 + + [HttpPost, ActionName("Delete")] + public ActionResult DeleteConfirmed(<#= primaryKeyProperty.Type.AsString #> id) + { + <#= Repositories[modelType.FullName].VariableName #>.Delete(id); + <#= Repositories[modelType.FullName].VariableName #>.Save(); + + return RedirectToAction("Index"); + } + } +} + +<#+ +class RepositoryInfo { + public string RepositoryTypeName { get; set; } + public string VariableName { get; set; } +} + +IDictionary _repositories; +IDictionary Repositories { + get { + if (_repositories == null) { + var relatedEntities = ((IEnumerable)Model.RelatedEntities).OfType(); + var relatedTypes = relatedEntities.Where(x => x.RelationType == RelationType.Parent).Select(x => x.RelatedEntityType).Distinct(); + _repositories = relatedTypes.ToDictionary( + relatedType => relatedType.FullName, + relatedType => new RepositoryInfo { RepositoryTypeName = relatedType.Name + "Repository", VariableName = relatedType.Name.ToLower() + "Repository" } + ); + _repositories[((CodeType)Model.ModelType).FullName] = new RepositoryInfo { RepositoryTypeName = Model.Repository, VariableName = ((CodeType)Model.ModelType).Name.ToLower() + "Repository" }; + } + return _repositories; + } +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.vb.t4 new file mode 100644 index 0000000..510c798 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/Controller/ControllerWithRepository.vb.t4 @@ -0,0 +1,141 @@ +<#@ template language="C#" HostSpecific="True" inherits="DynamicTransform" #> +<#@ Output Extension="vb" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<#@ import namespace="EnvDTE" #> +Imports System.Linq +Imports System.Web.Mvc +<# if(!string.IsNullOrEmpty(Model.ModelTypeNamespace)) { #> +Imports <#= Model.ModelTypeNamespace #> +<# } #> +<# if((!string.IsNullOrEmpty(Model.RepositoriesNamespace)) && (Model.RepositoriesNamespace != Model.ModelTypeNamespace)) { #> +Imports <#= Model.RepositoriesNamespace #> +<# } #> + +<#= T4Scaffolding.Namespaces.BeginVb(Model.ControllerNamespace, Model.DefaultNamespace) #> +<# + var modelType = (CodeType)Model.ModelType; + var modelName = modelType.Name; + var modelNamePlural = Model.ModelTypePluralized; + var modelVariable = modelName.ToLower(); + var relatedEntities = ((IEnumerable)Model.RelatedEntities).OfType(); + var primaryKeyProperty = modelType.VisibleMembers().OfType().Single(x => x.Name == Model.PrimaryKey); + var routingName = Regex.Replace(Model.ControllerName, "Controller$", "", RegexOptions.IgnoreCase); +#> + Public Class <#= Model.ControllerName #> : Inherits Controller +<# foreach(var repository in Repositories.Values) { #> + Private ReadOnly <#= repository.VariableName #> As I<#= repository.RepositoryTypeName #> +<# } #> + + ' If you are using Dependency Injection, you can delete the following constructor + Public Sub New() + Me.New(<#= String.Join(", ", Repositories.Values.Select(x => "New " + x.RepositoryTypeName + "()")) #>) + End Sub + + Public Sub New(<#= String.Join(", ", Repositories.Values.Select(x => "ByVal " + x.VariableName + " As I" + x.RepositoryTypeName)) #>) +<# foreach(var repository in Repositories.Values) { #> + Me.<#= repository.VariableName #> = <#= repository.VariableName #> +<# } #> + End Sub + + ' GET: /<#= routingName #>/ + Public Function Index() As ViewResult +<# + var propertiesToInclude = relatedEntities.Select(relation => relation.LazyLoadingProperty).Where(x => x != null); + var includeExpression = String.Join(", ", propertiesToInclude.Select(x => String.Format("Function({0}) {0}.{1}", modelVariable, x.Name))); + if (!string.IsNullOrEmpty(includeExpression)) { + includeExpression = "Including(" + includeExpression + ")"; + } +#> + Return View(<#= Repositories[modelType.FullName].VariableName #>.All<#= includeExpression #>) + End Function + + ' GET: /<#= routingName #>/Details/5 + Public Function Details(ByVal id As <#= primaryKeyProperty.Type.AsString #>) As ViewResult + Return View(<#= Repositories[modelType.FullName].VariableName #>.Find(id)) + End Function + + ' GET: /<#= routingName #>/Create + Public Function Create() As ActionResult +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All +<# } #> + Return View() + End Function + + ' POST: /<#= routingName #>/Create + + Public Function Create(ByVal <#= modelVariable #> As <#= modelName #>) As ActionResult + If ModelState.IsValid + <#= Repositories[modelType.FullName].VariableName #>.InsertOrUpdate(<#= modelVariable #>) + <#= Repositories[modelType.FullName].VariableName #>.Save() + Return RedirectToAction("Index") + Else +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All +<# } #> + Return View() + End If + End Function + + ' GET: /<#= routingName #>/Edit/5 + Public Function Edit(ByVal id As <#= primaryKeyProperty.Type.AsString #>) As ActionResult +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All +<# } #> + Return View(<#= Repositories[modelType.FullName].VariableName #>.Find(id)) + End Function + + ' POST: /<#= routingName #>/Edit/5 + + Public Function Edit(ByVal <#= modelVariable #> As <#= modelName #>) As ActionResult + If ModelState.IsValid + <#= Repositories[modelType.FullName].VariableName #>.InsertOrUpdate(<#= modelVariable #>) + <#= Repositories[modelType.FullName].VariableName #>.Save() + Return RedirectToAction("Index") + Else +<# foreach(var relatedEntity in relatedEntities.Where(x => x.RelationType == RelationType.Parent)) { #> + ViewBag.Possible<#= relatedEntity.RelationNamePlural #> = <#= Repositories[relatedEntity.RelatedEntityType.FullName].VariableName #>.All +<# } #> + Return View() + End If + End Function + + ' GET: /<#= routingName #>/Delete/5 + Public Function Delete(ByVal id As <#= primaryKeyProperty.Type.AsString #>) As ActionResult + Return View(<#= Repositories[modelType.FullName].VariableName #>.Find(id)) + End Function + + ' POST: /<#= routingName #>/Delete/5 + + Public Function DeleteConfirm(ByVal id As <#= primaryKeyProperty.Type.AsString #>) As ActionResult + <#= Repositories[modelType.FullName].VariableName #>.Delete(id) + <#= Repositories[modelType.FullName].VariableName #>.Save() + Return RedirectToAction("Index") + End Function + End Class +<#= T4Scaffolding.Namespaces.EndVb(Model.ControllerNamespace, Model.DefaultNamespace) #> +<#+ +class RepositoryInfo { + public string RepositoryTypeName { get; set; } + public string VariableName { get; set; } +} + +IDictionary _repositories; +IDictionary Repositories { + get { + if (_repositories == null) { + var relatedEntities = ((IEnumerable)Model.RelatedEntities).OfType(); + var relatedTypes = relatedEntities.Where(x => x.RelationType == RelationType.Parent).Select(x => x.RelatedEntityType).Distinct(); + _repositories = relatedTypes.ToDictionary( + relatedType => relatedType.FullName, + relatedType => new RepositoryInfo { RepositoryTypeName = relatedType.Name + "Repository", VariableName = relatedType.Name.ToLower() + "Repository" } + ); + _repositories[((CodeType)Model.ModelType).FullName] = new RepositoryInfo { RepositoryTypeName = Model.Repository, VariableName = ((CodeType)Model.ModelType).Name.ToLower() + "Repository" }; + } + return _repositories; + } +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.Controller.ps1 b/packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.Controller.ps1 new file mode 100644 index 0000000..f58e460 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.Controller.ps1 @@ -0,0 +1,127 @@ +[T4Scaffolding.ControllerScaffolder("Controller with read/write action and views, using EF data access code", Description = "Adds an ASP.NET MVC controller with views and data access code", SupportsModelType = $true, SupportsDataContextType = $true, SupportsViewScaffolder = $true)][CmdletBinding()] +param( + [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ControllerName, + [string]$ModelType, + [string]$Project, + [string]$CodeLanguage, + [string]$DbContextType, + [string]$Area, + [string]$ViewScaffolder = "View", + [alias("MasterPage")]$Layout, + [alias("ContentPlaceholderIDs")][string[]]$SectionNames, + [alias("PrimaryContentPlaceholderID")][string]$PrimarySectionName, + [switch]$ReferenceScriptLibraries = $false, + [switch]$Repository = $false, + [switch]$NoChildItems = $false, + [string[]]$TemplateFolders, + [switch]$Force = $false, + [string]$ForceMode +) + +if (!((Get-ProjectAspNetMvcVersion -Project $Project) -ge 3)) { + Write-Error ("Project '$((Get-Project $Project).Name)' is not an ASP.NET MVC 3 project.") + return +} + +# Interpret the "Force" and "ForceMode" options +$overwriteController = $Force -and ((!$ForceMode) -or ($ForceMode -eq "ControllerOnly")) +$overwriteFilesExceptController = $Force -and ((!$ForceMode) -or ($ForceMode -eq "PreserveController")) + +# Ensure you've referenced System.Data.Entity +(Get-Project $Project).Object.References.Add("System.Data.Entity") | Out-Null + +# If you haven't specified a model type, we'll guess from the controller name +if (!$ModelType) { + if ($ControllerName.EndsWith("Controller", [StringComparison]::OrdinalIgnoreCase)) { + # If you've given "PeopleController" as the full controller name, we're looking for a model called People or Person + $ModelType = [System.Text.RegularExpressions.Regex]::Replace($ControllerName, "Controller$", "", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) + $foundModelType = Get-ProjectType $ModelType -Project $Project -BlockUi -ErrorAction SilentlyContinue + if (!$foundModelType) { + $ModelType = [string](Get-SingularizedWord $ModelType) + $foundModelType = Get-ProjectType $ModelType -Project $Project -BlockUi -ErrorAction SilentlyContinue + } + } else { + # If you've given "people" as the controller name, we're looking for a model called People or Person, and the controller will be PeopleController + $ModelType = $ControllerName + $foundModelType = Get-ProjectType $ModelType -Project $Project -BlockUi -ErrorAction SilentlyContinue + if (!$foundModelType) { + $ModelType = [string](Get-SingularizedWord $ModelType) + $foundModelType = Get-ProjectType $ModelType -Project $Project -BlockUi -ErrorAction SilentlyContinue + } + if ($foundModelType) { + $ControllerName = [string](Get-PluralizedWord $foundModelType.Name) + "Controller" + } + } + if (!$foundModelType) { throw "Cannot find a model type corresponding to a controller called '$ControllerName'. Try supplying a -ModelType parameter value." } +} else { + # If you have specified a model type + $foundModelType = Get-ProjectType $ModelType -Project $Project -BlockUi + if (!$foundModelType) { return } + if (!$ControllerName.EndsWith("Controller", [StringComparison]::OrdinalIgnoreCase)) { + $ControllerName = $ControllerName + "Controller" + } +} +Write-Host "Scaffolding $ControllerName..." + +if(!$DbContextType) { $DbContextType = [System.Text.RegularExpressions.Regex]::Replace((Get-Project $Project).Name, "[^a-zA-Z0-9]", "") + "Context" } +if (!$NoChildItems) { + if ($Repository) { + Scaffold Repository -ModelType $foundModelType.FullName -DbContextType $DbContextType -Area $Area -Project $Project -CodeLanguage $CodeLanguage -Force:$overwriteFilesExceptController -BlockUi + } else { + $dbContextScaffolderResult = Scaffold DbContext -ModelType $foundModelType.FullName -DbContextType $DbContextType -Area $Area -Project $Project -CodeLanguage $CodeLanguage -BlockUi + $foundDbContextType = $dbContextScaffolderResult.DbContextType + if (!$foundDbContextType) { return } + } +} +if (!$foundDbContextType) { $foundDbContextType = Get-ProjectType $DbContextType -Project $Project } +if (!$foundDbContextType) { return } + +$primaryKey = Get-PrimaryKey $foundModelType.FullName -Project $Project -ErrorIfNotFound +if (!$primaryKey) { return } + +$outputPath = Join-Path Controllers $ControllerName +# We don't create areas here, so just ensure that if you specify one, it already exists +if ($Area) { + $areaPath = Join-Path Areas $Area + if (-not (Get-ProjectItem $areaPath -Project $Project)) { + Write-Error "Cannot find area '$Area'. Make sure it exists already." + return + } + $outputPath = Join-Path $areaPath $outputPath +} + +# Prepare all the parameter values to pass to the template, then invoke the template with those values +$repositoryName = $foundModelType.Name + "Repository" +$defaultNamespace = (Get-Project $Project).Properties.Item("DefaultNamespace").Value +$modelTypeNamespace = [T4Scaffolding.Namespaces]::GetNamespace($foundModelType.FullName) +$controllerNamespace = [T4Scaffolding.Namespaces]::Normalize($defaultNamespace + "." + [System.IO.Path]::GetDirectoryName($outputPath).Replace([System.IO.Path]::DirectorySeparatorChar, ".")) +$areaNamespace = if ($Area) { [T4Scaffolding.Namespaces]::Normalize($defaultNamespace + ".Areas.$Area") } else { $defaultNamespace } +$dbContextNamespace = $foundDbContextType.Namespace.FullName +$repositoriesNamespace = [T4Scaffolding.Namespaces]::Normalize($areaNamespace + ".Models") +$modelTypePluralized = Get-PluralizedWord $foundModelType.Name +$relatedEntities = [Array](Get-RelatedEntities $foundModelType.FullName -Project $project) +if (!$relatedEntities) { $relatedEntities = @() } + +$templateName = if($Repository) { "ControllerWithRepository" } else { "ControllerWithContext" } +Add-ProjectItemViaTemplate $outputPath -Template $templateName -Model @{ + ControllerName = $ControllerName; + ModelType = [MarshalByRefObject]$foundModelType; + PrimaryKey = [string]$primaryKey; + DefaultNamespace = $defaultNamespace; + AreaNamespace = $areaNamespace; + DbContextNamespace = $dbContextNamespace; + RepositoriesNamespace = $repositoriesNamespace; + ModelTypeNamespace = $modelTypeNamespace; + ControllerNamespace = $controllerNamespace; + DbContextType = [MarshalByRefObject]$foundDbContextType; + Repository = $repositoryName; + ModelTypePluralized = [string]$modelTypePluralized; + RelatedEntities = $relatedEntities; +} -SuccessMessage "Added controller {0}" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$overwriteController + +if (!$NoChildItems) { + $controllerNameWithoutSuffix = [System.Text.RegularExpressions.Regex]::Replace($ControllerName, "Controller$", "", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) + if ($ViewScaffolder) { + Scaffold Views -ViewScaffolder $ViewScaffolder -Controller $controllerNameWithoutSuffix -ModelType $foundModelType.FullName -Area $Area -Layout $Layout -SectionNames $SectionNames -PrimarySectionName $PrimarySectionName -ReferenceScriptLibraries:$ReferenceScriptLibraries -Project $Project -CodeLanguage $CodeLanguage -Force:$overwriteFilesExceptController + } +} \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.ControllerWithRepository.ps1 b/packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.ControllerWithRepository.ps1 new file mode 100644 index 0000000..f8a0629 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/Controller/MvcScaffolding.ControllerWithRepository.ps1 @@ -0,0 +1,36 @@ +[T4Scaffolding.ControllerScaffolder("Controller with read/write action and views, using repositories", HideInConsole = $true, Description = "Adds an ASP.NET MVC controller with views and data access code", SupportsModelType = $true, SupportsDataContextType = $true, SupportsViewScaffolder = $true)][CmdletBinding()] +param( + [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ControllerName, + [string]$ModelType, + [string]$Project, + [string]$CodeLanguage, + [string]$DbContextType, + [string]$Area, + [string]$ViewScaffolder = "View", + [alias("MasterPage")]$Layout, + [alias("ContentPlaceholderIDs")][string[]]$SectionNames, + [alias("PrimaryContentPlaceholderID")][string]$PrimarySectionName, + [switch]$ReferenceScriptLibraries = $false, + [switch]$NoChildItems = $false, + [string[]]$TemplateFolders, + [switch]$Force = $false, + [string]$ForceMode +) + +Scaffold MvcScaffolding.Controller ` + -ControllerName $ControllerName ` + -ModelType $ModelType ` + -Project $Project ` + -CodeLanguage $CodeLanguage ` + -DbContextType $DbContextType ` + -Area $Area ` + -ViewScaffolder $ViewScaffolder ` + -Layout $Layout ` + -SectionNames $SectionNames ` + -PrimarySectionName $PrimarySectionName ` + -ReferenceScriptLibraries:$ReferenceScriptLibraries ` + -NoChildItems:$NoChildItems ` + -OverrideTemplateFolders $TemplateFolders ` + -Force:$Force ` + -ForceMode $ForceMode ` + -Repository diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Create.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Create.cs.t4 new file mode 100644 index 0000000..53c0622 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Create.cs.t4 @@ -0,0 +1,140 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="cshtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# if(viewDataType != null) { #> +@model <#= viewDataType.FullName #> + +<# } #> +@{ + ViewBag.Title = "<#= Model.ViewName #>"; +<# +if (!String.IsNullOrEmpty(Model.Layout)) { +#> + Layout = "<#= Model.Layout #>"; +<# +} +#> +} + +

<#= Model.ViewName #>

+ +<# if(Model.ReferenceScriptLibraries) { #> + + + +<# } #> +@using (Html.BeginForm()) { + @Html.ValidationSummary(true) +
+ <#= Model.ViewDataTypeName ?? String.Empty #> + + @Html.Partial("_CreateOrEdit", Model) + +

+ +

+
+} + +
+ @Html.ActionLink("Back to List", "Index") +
+ + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Create.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Create.vb.t4 new file mode 100644 index 0000000..6a7edd5 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Create.vb.t4 @@ -0,0 +1,137 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="vbhtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> +<# If viewDataType IsNot Nothing #> +@ModelType <#= viewDataType.FullName #> + +<# End If #> +@Code + ViewData("Title") = "<#= Model.ViewName #>" +<# If Not String.IsNullOrEmpty(Model.Layout) #> + Layout = "<#= Model.Layout #>" +<# End If #> +End Code + +

<#= Model.ViewName #>

+ +<# If Model.ReferenceScriptLibraries Then #> + + + +<# End If #> +@Using Html.BeginForm() + @Html.ValidationSummary(True) + @
+ <#= If(Model.ViewDataTypeName, String.Empty) #> + + @Html.Partial("_CreateOrEdit", Model) +

+ +

+
+End Using + +
+ @Html.ActionLink("Back to List", "Index") +
+ +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.cs.t4 new file mode 100644 index 0000000..694d3c3 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.cs.t4 @@ -0,0 +1,136 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="cshtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# if(viewDataType != null) { #> +@model <#= viewDataType.FullName #> + +<# } #> +@{ + ViewBag.Title = "<#= Model.ViewName #>"; +<# if (!String.IsNullOrEmpty(Model.Layout)) { #> + Layout = "<#= Model.Layout #>"; +<# } #> +} + +

<#= Model.ViewName #>

+ +

Are you sure you want to delete this?

+
+ <#= Model.ViewDataTypeName ?? String.Empty #> +<# +foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, true)) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +
<#= property.Name #>
+
@<#= property.ValueExpression #>
+<# + } +} +#> +
+@using (Html.BeginForm()) { +

+ | + @Html.ActionLink("Back to List", "Index") +

+} + + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.vb.t4 new file mode 100644 index 0000000..c3d1365 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Delete.vb.t4 @@ -0,0 +1,139 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="vbhtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> +<# If viewDataType IsNot Nothing #> +@ModelType <#= viewDataType.FullName #> + +<# End If #> +@Code + ViewData("Title") = "<#= Model.ViewName #>" +<# If Not String.IsNullOrEmpty(Model.Layout) #> + Layout = "<#= Model.Layout #>" +<# End If #> +End Code + +

<#= Model.ViewName #>

+ +

Are you sure you want to delete this?

+
+ <#= If(Model.ViewDataTypeName, String.Empty) #> +<# +For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, True) + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +
<#= modelProp.Name #>
+
@<#= modelProp.ValueExpression #>
+<# + End If +Next +#> +
+ +@Using Html.BeginForm() + @

+ | + @Html.ActionLink("Back to List", "Index") +

+End Using + +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Details.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Details.cs.t4 new file mode 100644 index 0000000..3555614 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Details.cs.t4 @@ -0,0 +1,138 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="cshtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# if(viewDataType != null) { #> +@model <#= viewDataType.FullName #> + +<# } #> +@{ + ViewBag.Title = "<#= Model.ViewName #>"; +<# if (!String.IsNullOrEmpty(Model.Layout)) { #> + Layout = "<#= Model.Layout #>"; +<# } #> +} + +

<#= Model.ViewName #>

+ +
+ <#= Model.ViewDataTypeName ?? String.Empty #> +<# +foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, true)) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +
<#= property.Name #>
+
@<#= property.ValueExpression #>
+<# + } +} +#> +
+

+<# if (!String.IsNullOrEmpty(Model.PrimaryKeyName)) { #> + @Html.ActionLink("Edit", "Edit", new { id=Model.<#= Model.PrimaryKeyName #> }) | + @Html.ActionLink("Back to List", "Index") +<# } else { #> + @Html.ActionLink("Edit", "Edit", new { /* id=Model.PrimaryKey */ }) | + @Html.ActionLink("Back to List", "Index") +<# } #> +

+ + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Details.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Details.vb.t4 new file mode 100644 index 0000000..53876c6 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Details.vb.t4 @@ -0,0 +1,141 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="vbhtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> +<# If viewDataType IsNot Nothing #> +@ModelType <#= viewDataType.FullName #> + +<# End If #> +@Code + ViewData("Title") = "<#= Model.ViewName #>" +<# If Not String.IsNullOrEmpty(Model.Layout) #> + Layout = "<#= Model.Layout #>" +<# End If #> +End Code + +

<#= Model.ViewName #>

+ +
+ <#= If(Model.ViewDataTypeName, String.Empty) #> +<# +For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, True) + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +
<#= modelProp.Name #>
+
@<#= modelProp.ValueExpression #>
+<# + End If +Next +#> +
+ +

+<# If Not String.IsNullOrEmpty(Model.PrimaryKeyName) Then #> + @Html.ActionLink("Edit", "Edit", New With {.id = Model.<#= Model.PrimaryKeyName #>}) | + @Html.ActionLink("Back to List", "Index") +<# Else #> + @*@Html.ActionLink("Edit", "Edit", New With {.id = Model.PrimaryKey}) |*@ + @Html.ActionLink("Back to List", "Index") +<# End If #> +

+ +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.cs.t4 new file mode 100644 index 0000000..cb1cf0a --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.cs.t4 @@ -0,0 +1,137 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="cshtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# if(viewDataType != null) { #> +@model <#= viewDataType.FullName #> + +<# } #> +@{ + ViewBag.Title = "<#= Model.ViewName #>"; +<# if (!String.IsNullOrEmpty(Model.Layout)) { #> + Layout = "<#= Model.Layout #>"; +<# } #> +} + +

<#= Model.ViewName #>

+ +<# if(Model.ReferenceScriptLibraries) { #> + + + +<# } #> +@using (Html.BeginForm()) { + @Html.ValidationSummary(true) +
+ <#= Model.ViewDataTypeName ?? String.Empty #> + +<# foreach (ModelProperty property in GetModelProperties(viewDataType, false).Where(x => x.IsPrimaryKey)) { #> + @Html.HiddenFor(model => model.<#= property.Name #>) +<# } #> + @Html.Partial("_CreateOrEdit", Model) + +

+ +

+
+} + +
+ @Html.ActionLink("Back to List", "Index") +
+<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.vb.t4 new file mode 100644 index 0000000..8fb62d8 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Edit.vb.t4 @@ -0,0 +1,140 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="vbhtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> +<# If viewDataType IsNot Nothing #> +@ModelType <#= viewDataType.FullName #> + +<# End If #> +@Code + ViewData("Title") = "<#= Model.ViewName #>" +<# If Not String.IsNullOrEmpty(Model.Layout) #> + Layout = "<#= Model.Layout #>" +<# End If #> +End Code + +

<#= Model.ViewName #>

+ +<# If Model.ReferenceScriptLibraries Then #> + + + +<# End If #> +@Using Html.BeginForm() + @Html.ValidationSummary(True) + @
+ <#= If(Model.ViewDataTypeName, String.Empty) #> + +<# For Each modelProp As ModelProperty In GetModelProperties(viewDataType, False).Where(Function(x) x.IsPrimaryKey) #> + @Html.HiddenFor(Function(model) model.<#= modelProp.Name #>) +<# Next #> + @Html.Partial("_CreateOrEdit", Model) +

+ +

+
+End Using + +
+ @Html.ActionLink("Back to List", "Index") +
+ +<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.cs.t4 new file mode 100644 index 0000000..9e35656 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.cs.t4 @@ -0,0 +1,15 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="cshtml" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# if(viewDataType != null) { #> +@model <#= viewDataType.FullName #> + +<# } #> +@{ + ViewBag.Title = "<#= Model.ViewName #>"; +<# if (!String.IsNullOrEmpty(Model.Layout)) { #> + Layout = "<#= Model.Layout #>"; +<# } #> +} + +

<#= Model.ViewName #>

\ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.vb.t4 new file mode 100644 index 0000000..9b9c940 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Empty.vb.t4 @@ -0,0 +1,15 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="vbhtml" #> +<# Dim viewDataType = CType(Model.ViewDataType, EnvDTE.CodeType) #> +<# If viewDataType IsNot Nothing Then #> +@ModelType <#= viewDataType.FullName #> + +<# End If #> +@Code + ViewData("Title") = "<#= Model.ViewName #>" +<# If Not String.IsNullOrEmpty(Model.Layout) #> + Layout = "<#= Model.Layout #>" +<# End If #> +End Code + +

<#= Model.ViewName #>

\ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Index.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Index.cs.t4 new file mode 100644 index 0000000..c42b669 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Index.cs.t4 @@ -0,0 +1,165 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="cshtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# if(viewDataType != null) { #> +@model IEnumerable<<#= viewDataType.FullName #>> + +<# } #> +@{ + ViewBag.Title = "<#= Model.ViewName #>"; +<# if (!String.IsNullOrEmpty(Model.Layout)) { #> + Layout = "<#= Model.Layout #>"; +<# } #> +} + +

<#= Model.ViewName #>

+ +

+ @Html.ActionLink("Create New", "Create") +

+ + + +<# +List properties = GetModelProperties(Model.ViewDataType, true); +foreach (ModelProperty property in properties) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +<# + } +} +#> + + +@foreach (var item in Model) { + +<# if (!String.IsNullOrEmpty(Model.PrimaryKeyName)) { #> + +<# } else { #> + +<# } #> +<# +foreach (ModelProperty property in properties) { + if (!property.IsPrimaryKey && !property.IsForeignKey) { +#> + +<# + } +} +#> + +} + +
+ <#= property.Name #> +
+ @Html.ActionLink("Edit", "Edit", new { id=item.<#= Model.PrimaryKeyName #> }) | + @Html.ActionLink("Details", "Details", new { id=item.<#= Model.PrimaryKeyName #> }) | + @Html.ActionLink("Delete", "Delete", new { id=item.<#= Model.PrimaryKeyName #> }) + + @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) | + @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) | + @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) + + @<#= property.ValueExpression.Replace("Model.", "item.") #> +
+ + +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/Index.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/Index.vb.t4 new file mode 100644 index 0000000..22d9fad --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/Index.vb.t4 @@ -0,0 +1,174 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="vbhtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> +<# If viewDataType IsNot Nothing #> +@ModelType IEnumerable(Of <#= viewDataType.FullName #>) + +<# End If #> +@Code + ViewData("Title") = "<#= Model.ViewName #>" +<# +If Not String.IsNullOrEmpty(Model.Layout) +#> + Layout = "<#= Model.Layout #>" +<# +End If +#> +End Code + +

<#= Model.ViewName #>

+ +

+ @Html.ActionLink("Create New", "Create") +

+ + + +<# +Dim properties As List(Of ModelProperty) = GetModelProperties(Model.ViewDataType, True) +For Each modelProp As ModelProperty In properties + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +<# + End If +Next +#> + + +@For Each item In Model + Dim itemValue = item + @ +<# If Not String.IsNullOrEmpty(Model.PrimaryKeyName) Then #> + +<# +Else +#> + +<# +End If + +For Each modelProp As ModelProperty In properties + If (Not modelProp.IsPrimaryKey AndAlso Not modelProp.IsForeignKey) Then +#> + +<# + End If +Next +#> + +Next + +
+ <#= modelProp.Name #> +
+ @Html.ActionLink("Edit", "Edit", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) | + @Html.ActionLink("Details", "Details", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) | + @Html.ActionLink("Delete", "Delete", New With {.id = itemValue.<#= Model.PrimaryKeyName #>}) + + @*@Html.ActionLink("Edit", "Edit", New With {.id = itemValue.PrimaryKey}) | + @Html.ActionLink("Details", "Details", New With {.id = itemValue.PrimaryKey}) | + @Html.ActionLink("Delete", "Delete", New With {.id = itemValue.PrimaryKey})*@ + + @<#= modelProp.ValueExpression.Replace("Model.", "itemValue.") #> +
+<#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/MvcScaffolding.RazorView.ps1 b/packages/MvcScaffolding.1.0.0/tools/RazorView/MvcScaffolding.RazorView.ps1 new file mode 100644 index 0000000..6e876b0 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/MvcScaffolding.RazorView.ps1 @@ -0,0 +1,60 @@ +[T4Scaffolding.ViewScaffolder("Razor", Description = "Adds an ASP.NET MVC view using the Razor view engine", IsRazorType = $true, LayoutPageFilter = "*.cshtml,*.vbhtml|*.cshtml,*.vbhtml")][CmdletBinding()] +param( + [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)][string]$Controller, + [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 1)][string]$ViewName, + [string]$ModelType, + [string]$Template = "Empty", + [string]$Area, + [alias("MasterPage")]$Layout, # If not set, we'll use the default layout + [string[]]$SectionNames, + [string]$PrimarySectionName, + [switch]$ReferenceScriptLibraries = $false, + [string]$Project, + [string]$CodeLanguage, + [string[]]$TemplateFolders, + [switch]$Force = $false +) + +# Ensure this is a valid target project +if (!((Get-ProjectAspNetMvcVersion -Project $Project) -ge 3)) { + Write-Error ("Project '$((Get-Project $Project).Name)' is not an ASP.NET MVC 3 project.") + return +} + +# Ensure we have a controller name, plus a model type if specified +if ($ModelType) { + $foundModelType = Get-ProjectType $ModelType -Project $Project + if (!$foundModelType) { return } + $primaryKeyName = [string](Get-PrimaryKey $foundModelType.FullName -Project $Project) +} + +# Decide where to put the output +$outputFolderName = Join-Path Views $Controller +if ($Area) { + # We don't create areas here, so just ensure that if you specify one, it already exists + $areaPath = Join-Path Areas $Area + if (-not (Get-ProjectItem $areaPath -Project $Project)) { + Write-Error "Cannot find area '$Area'. Make sure it exists already." + return + } + $outputFolderName = Join-Path $areaPath $outputFolderName +} + + +if ($foundModelType) { $relatedEntities = [Array](Get-RelatedEntities $foundModelType.FullName -Project $project) } +if (!$relatedEntities) { $relatedEntities = @() } + +# Render the T4 template, adding the output to the Visual Studio project +$outputPath = Join-Path $outputFolderName $ViewName +Add-ProjectItemViaTemplate $outputPath -Template $Template -Model @{ + IsContentPage = [bool]$Layout; + Layout = $Layout; + SectionNames = $SectionNames; + PrimarySectionName = $PrimarySectionName; + ReferenceScriptLibraries = $ReferenceScriptLibraries.ToBool(); + ViewName = $ViewName; + PrimaryKeyName = $primaryKeyName; + ViewDataType = [MarshalByRefObject]$foundModelType; + ViewDataTypeName = $foundModelType.Name; + RelatedEntities = $relatedEntities; +} -SuccessMessage "Added $ViewName view at '{0}'" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.cs.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.cs.t4 new file mode 100644 index 0000000..43c374d --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.cs.t4 @@ -0,0 +1,139 @@ +<#@ Template Language="C#" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="cshtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<# var viewDataType = (EnvDTE.CodeType) Model.ViewDataType; #> +<# if(viewDataType != null) { #> +@model <#= viewDataType.FullName #> + +<# } #> +@* This partial view defines form fields that will appear when creating and editing entities *@ + +<# +foreach (ModelProperty property in GetModelProperties(Model.ViewDataType, false)) { + if (!property.IsPrimaryKey && !property.IsForeignKey && !property.IsReadOnly) { +#> +
+ @Html.LabelFor(model => model.<#= property.Name #>) +
+
+ @Html.EditorFor(model => model.<#= property.Name #>) + @Html.ValidationMessageFor(model => model.<#= property.Name #>) +
+ +<# + } +} +#> +<# +foreach (RelatedEntityInfo relation in ParentRelations) { +#> +
+ <#= relation.RelationName #> +
+
+ @Html.DropDownListFor(model => model.<#= relation.RelationProperty.Name #>, ((IEnumerable<<#= relation.RelatedEntityType.FullName #>>)ViewBag.Possible<#= relation.RelationNamePlural #>).Select(option => new SelectListItem { + Text = <#= GetValueExpression("option", relation.RelatedEntityType) #>, + Value = option.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), + Selected = (Model != null) && (option.<#= relation.RelatedEntityPrimaryKeyName #> == Model.<#= relation.RelationProperty.Name #>) + }), "Choose...") + @Html.ValidationMessageFor(model => model.<#= relation.RelationProperty.Name #>) +
+<# +} +#> +<#+ +// Describes the information about a property on the model +class ModelProperty { + public string Name { get; set; } + public string ValueExpression { get; set; } + public EnvDTE.CodeTypeRef Type { get; set; } + public bool IsPrimaryKey { get; set; } + public bool IsForeignKey { get; set; } + public bool IsReadOnly { get; set; } +} + +// Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +static Type[] bindableNonPrimitiveTypes = new[] { + typeof(string), + typeof(decimal), + typeof(Guid), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(TimeSpan), +}; + +// Call this to get the list of properties in the model. Change this to modify or add your +// own default formatting for display values. +List GetModelProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = GetEligibleProperties(typeInfo, includeUnbindableProperties); + + foreach (ModelProperty prop in results) { + if (prop.Type.UnderlyingTypeIs() || prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")"; + } + else if (prop.Type.UnderlyingTypeIs()) { + prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")"; + } + else if (!IsBindableType(prop.Type)) { + prop.ValueExpression = GetValueExpression("Model." + prop.Name, (EnvDTE.CodeType)prop.Type.CodeType); + } + } + + return results; +} + +// Change this list to include the names of properties that should be selected to represent an entity as a single string +static string[] displayPropertyNames = new[] { "Name", "Title", "LastName", "Surname", "Subject", "Count" }; + +string GetValueExpression(string propertyExpression, EnvDTE.CodeType propertyType) { + if (propertyType != null) { + var chosenSubproperty = propertyType.DisplayColumnProperty() ?? propertyType.FindProperty(displayPropertyNames); + if (chosenSubproperty != null) { + var toStringSuffix = chosenSubproperty.Type.AsFullName == "System.String" ? "" : ".ToString()"; + return String.Format("({0} == null ? \"None\" : {0}.{1}{2})", propertyExpression, chosenSubproperty.Name, toStringSuffix); + } + } + return "Html.DisplayTextFor(_ => " + propertyExpression + ").ToString()"; +} + +// Helper +List GetEligibleProperties(EnvDTE.CodeType typeInfo, bool includeUnbindableProperties) { + List results = new List(); + if (typeInfo != null) { + foreach (var prop in typeInfo.VisibleMembers().OfType()) { + if (prop.IsReadable() && !prop.HasIndexParameters() && (includeUnbindableProperties || IsBindableType(prop.Type))) { + results.Add(new ModelProperty { + Name = prop.Name, + ValueExpression = "Model." + prop.Name, + Type = prop.Type, + IsPrimaryKey = Model.PrimaryKeyName == prop.Name, + IsForeignKey = ParentRelations.Any(x => x.RelationProperty == prop), + IsReadOnly = !prop.IsWriteable() + }); + } + } + } + + return results; +} + +IEnumerable ParentRelations { + get { return ((IEnumerable)Model.RelatedEntities).OfType().Where(x => x.RelationType == RelationType.Parent); } +} + +// Helper +bool IsBindableType(EnvDTE.CodeTypeRef type) { + return type.UnderlyingIsPrimitive() || bindableNonPrimitiveTypes.Any(x => type.UnderlyingTypeIs(x)); +} +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.vb.t4 b/packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.vb.t4 new file mode 100644 index 0000000..6d43a38 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/RazorView/_CreateOrEdit.vb.t4 @@ -0,0 +1,137 @@ +<#@ Template Language="VB" HostSpecific="True" Inherits="DynamicTransform" #> +<#@ Output extension="vbhtml" #> +<#@ assembly name="System.ComponentModel.DataAnnotations" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Linq" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.ComponentModel.DataAnnotations" #> +<#@ import namespace="System.Data.Linq.Mapping" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="EnvDTE" #> +<# Dim viewDataType = CType(Model.ViewDataType, CodeType) #> +<# If viewDataType IsNot Nothing #> +@ModelType <#= viewDataType.FullName #> + +<# End If #> +@* This partial view defines form fields that will appear when creating and editing entities *@ + +<# +For Each modelProp As ModelProperty In GetModelProperties(Model.ViewDataType, False) + If (Not modelProp.IsPrimaryKey) AndAlso (Not modelProp.IsForeignKey) AndAlso (Not modelProp.IsReadOnly) Then +#> +
+ @Html.LabelFor(Function(model) model.<#= modelProp.Name #>) +
+
+ @Html.EditorFor(Function(model) model.<#= modelProp.Name #>) + @Html.ValidationMessageFor(Function(model) model.<#= modelProp.Name #>) +
+ +<# + End If +Next +#> +<# For Each relation As RelatedEntityInfo In ParentRelations #> +
+ <#= relation.RelationName #> +
+
+ @Html.DropDownListFor(Function(model) model.<#= relation.RelationProperty.Name #>, CType(ViewBag.Possible<#= relation.RelationNamePlural #>, IEnumerable(Of <#= relation.RelatedEntityType.FullName #>)).Select(Function(optionValue) New SelectListItem() With { _ + .Text = <#= GetValueExpression("optionValue", relation.RelatedEntityType) #>, _ + .Value = optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.ToString(), _ + .Selected = (Model IsNot Nothing) AndAlso (optionValue.<#= relation.RelatedEntityPrimaryKeyName #>.Equals(Model.<#= relation.RelationProperty.Name #>)) _ + }), "Choose...") + @Html.ValidationMessageFor(Function(model) model.<#= relation.RelationProperty.Name #>) +
+<# Next #><#+ +' Describes the information about a property on the model +Private Class ModelProperty + Public Name As String + Public ValueExpression As String + Public Type As CodeTypeRef + Public IsReadOnly As Boolean + Public IsPrimaryKey As Boolean + Public IsForeignKey As Boolean +End Class + +' Change this list to include any non-primitive types you think should be eligible to be edited using a textbox +Private Shared bindableNonPrimitiveTypes As Type() = New Type() { + GetType(String), + GetType(Decimal), + GetType(Guid), + GetType(DateTime), + GetType(DateTimeOffset), + GetType(TimeSpan) +} + +' Call this to get the list of properties in the model. Change this to modify or add your +' own default formatting for display values. +Private Function GetModelProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As List(Of ModelProperty) = GetEligibleProperties(type, includeUnbindableProperties) + + For Each modelProp As ModelProperty In results + If ((modelProp.Type.UnderlyingTypeIs(GetType(Double))) OrElse (modelProp.Type.UnderlyingTypeIs(GetType(Decimal)))) Then + modelProp.ValueExpression = ("String.Format(""{0:F}"", " & modelProp.ValueExpression & ")") + ElseIf (modelProp.Type.UnderlyingTypeIs(GetType(DateTime))) Then + modelProp.ValueExpression = ("String.Format(""{0:g}"", " & modelProp.ValueExpression & ")") + ElseIf (Not IsBindableType(modelProp.Type)) + modelProp.ValueExpression = GetValueExpression("Model." & modelProp.Name, CType(modelProp.Type.CodeType, CodeType)) + End If + Next + + Return results +End Function + +' Change this list to include the names of properties that should be selected to represent an entity as a single string +Private Shared displayPropertyNames As String() = New String() { "Name", "Title", "LastName", "Surname", "Subject", "Count" } + +Private Function GetValueExpression(ByVal propertyExpression As String, ByVal propertyType As CodeType) As String + If propertyType IsNot Nothing Then + Dim chosenSubproperty = If(propertyType.DisplayColumnProperty(), propertyType.FindProperty(displayPropertyNames)) + If chosenSubproperty IsNot Nothing Then + Dim toStringSuffix = If(chosenSubproperty.Type.AsFullName = "System.String", "", ".ToString()") + Return String.Format("(If({0} Is Nothing, ""None"", {0}.{1}{2}))", propertyExpression, chosenSubproperty.Name, toStringSuffix) + End If + End If + Return "Html.DisplayTextFor(Function(model) " & propertyExpression & ").ToString()" +End Function + +' Helper +Private Function GetEligibleProperties(ByVal type As CodeType, ByVal includeUnbindableProperties As Boolean) As List(Of ModelProperty) + Dim results As New List(Of ModelProperty) + + If type IsNot Nothing Then + For Each prop As CodeProperty In type.VisibleMembers().OfType(Of CodeProperty)() + Dim propValue = prop + If (prop.IsReadable() AndAlso (Not prop.HasIndexParameters()) AndAlso (includeUnbindableProperties OrElse IsBindableType(prop.Type))) Then + results.Add(New ModelProperty() With { _ + .Name = prop.Name, _ + .ValueExpression = ("Model." & prop.Name), _ + .Type = prop.Type, _ + .IsPrimaryKey = Model.PrimaryKeyName = prop.Name, _ + .IsReadOnly = Not prop.IsWriteable(), _ + .IsForeignKey = ParentRelations.Any(Function(x) propValue.Name = x.RelationProperty.Name) _ + }) + End If + Next + End If + + Return results +End Function + +Private ReadOnly Property ParentRelations As IEnumerable(Of RelatedEntityInfo) + Get + Return CType(Model.RelatedEntities, IEnumerable).OfType(Of RelatedEntityInfo)().Where(Function(x) x.RelationType = RelationType.Parent) + End Get +End Property + +' Helper +Private Function IsBindableType(ByVal type As CodeTypeRef) As Boolean + Return type.UnderlyingIsPrimitive() OrElse bindableNonPrimitiveTypes.Any(Function(x) type.UnderlyingTypeIs(x)) +End Function +#> \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/Views/MvcScaffolding.Views.ps1 b/packages/MvcScaffolding.1.0.0/tools/Views/MvcScaffolding.Views.ps1 new file mode 100644 index 0000000..37d3932 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/Views/MvcScaffolding.Views.ps1 @@ -0,0 +1,19 @@ +[T4Scaffolding.Scaffolder(Description = "Adds ASP.NET MVC views for Create/Read/Update/Delete/Index scenarios")][CmdletBinding()] +param( + [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)][string]$Controller, + [string]$ModelType, + [string]$Area, + [alias("MasterPage")]$Layout, # If not set, we'll use the default layout + [alias("ContentPlaceholderIDs")][string[]]$SectionNames, + [alias("PrimaryContentPlaceholderID")][string]$PrimarySectionName, + [switch]$ReferenceScriptLibraries = $false, + [string]$Project, + [string]$CodeLanguage, + [string[]]$TemplateFolders, + [string]$ViewScaffolder = "View", + [switch]$Force = $false +) + +@("Create", "Edit", "Delete", "Details", "Index", "_CreateOrEdit") | %{ + Scaffold $ViewScaffolder -Controller $Controller -ViewName $_ -ModelType $ModelType -Template $_ -Area $Area -Layout $Layout -SectionNames $SectionNames -PrimarySectionName $PrimarySectionName -ReferenceScriptLibraries:$ReferenceScriptLibraries -Project $Project -CodeLanguage $CodeLanguage -OverrideTemplateFolders $TemplateFolders -Force:$Force -BlockUi +} \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/init.ps1 b/packages/MvcScaffolding.1.0.0/tools/init.ps1 new file mode 100644 index 0000000..8791d6d --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/init.ps1 @@ -0,0 +1,16 @@ +param($rootPath, $toolsPath, $package, $project) + +# Note that as of NuGet 1.0, the init.ps1 scripts run in an undefined order, +# so this script must not depend on T4Scaffolding already being initialized. + +# Simplistic tab expansion +if (!$global:scaffolderTabExpansion) { $global:scaffolderTabExpansion = @{ } } +$global:scaffolderTabExpansion["MvcScaffolding.RazorView"] = $global:scaffolderTabExpansion["MvcScaffolding.AspxView"] = { + param($filter, $allTokens) + $secondLastToken = $allTokens[-2] + if ($secondLastToken -eq 'Template') { + return @("Create", "Delete", "Details", "Edit", "Index") + } +} + +. (Join-Path $toolsPath "registerWithMvcTooling.ps1") \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/install.ps1 b/packages/MvcScaffolding.1.0.0/tools/install.ps1 new file mode 100644 index 0000000..2c4baa0 --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/install.ps1 @@ -0,0 +1,31 @@ +param($rootPath, $toolsPath, $package, $project) + +# Bail out if scaffolding is disabled (probably because you're running an incompatible version of NuGet) +if (-not (Get-Command Invoke-Scaffolder)) { return } + +function CountSolutionFilesByExtension($extension) { + $files = (Get-Project).DTE.Solution ` + | ?{ $_.FileName } ` + | %{ [System.IO.Path]::GetDirectoryName($_.FileName) } ` + | %{ [System.IO.Directory]::EnumerateFiles($_, "*." + $extension, [System.IO.SearchOption]::AllDirectories) } + ($files | Measure-Object).Count +} + +function InferPreferredViewEngine() { + # Assume you want Razor except if you already have some ASPX views and no Razor ones + if ((CountSolutionFilesByExtension aspx) -eq 0) { return "razor" } + if (((CountSolutionFilesByExtension cshtml) -gt 0) -or ((CountSolutionFilesByExtension vbhtml) -gt 0)) { return "razor" } + return "aspx" +} + +if ($project) { $projectName = $project.Name } +Get-ProjectItem "InstallationDummyFile.txt" -Project $projectName | %{ $_.Delete() } + +Set-DefaultScaffolder -Name Controller -Scaffolder MvcScaffolding.Controller -SolutionWide -DoNotOverwriteExistingSetting +Set-DefaultScaffolder -Name Views -Scaffolder MvcScaffolding.Views -SolutionWide -DoNotOverwriteExistingSetting +Set-DefaultScaffolder -Name Action -Scaffolder MvcScaffolding.Action -SolutionWide -DoNotOverwriteExistingSetting +Set-DefaultScaffolder -Name UnitTest -Scaffolder MvcScaffolding.ActionUnitTest -SolutionWide -DoNotOverwriteExistingSetting + +# Infer which view engine you're using based on the files in your project +$viewScaffolder = if ([string](InferPreferredViewEngine) -eq 'aspx') { "MvcScaffolding.AspxView" } else { "MvcScaffolding.RazorView" } +Set-DefaultScaffolder -Name View -Scaffolder $viewScaffolder -SolutionWide -DoNotOverwriteExistingSetting \ No newline at end of file diff --git a/packages/MvcScaffolding.1.0.0/tools/registerWithMvcTooling.ps1 b/packages/MvcScaffolding.1.0.0/tools/registerWithMvcTooling.ps1 new file mode 100644 index 0000000..c028f3f --- /dev/null +++ b/packages/MvcScaffolding.1.0.0/tools/registerWithMvcTooling.ps1 @@ -0,0 +1,138 @@ +# Ensure we're on the right version of the tooling. If not, there's nothing for us to do here. +$toolingExists = [System.AppDomain]::CurrentDomain.GetAssemblies() | ?{ $_.GetType("Microsoft.VisualStudio.Web.Mvc.Scaffolding.ScaffolderProviders") } +if (!$toolingExists) { return } + +# Todo: Scope the following to this module if possible +function global:MvcScaffoldingHashTableToPsObject($hashOfScriptMethods) { + $result = New-Object PSObject + $hashOfScriptMethods.Keys | %{ Add-Member -InputObject $result -Member ScriptMethod -Name $_ -Value $hashOfScriptMethods[$_] } + $result +} + +function global:MvcScaffoldingInvokeViaScriptExecutor($scriptToExecute) { + $completeScript = @" + try { + # Activate output pane + `$packageManagerOutputPaneGuid = "{CEC55EC8-CC51-40E7-9243-57B87A6F6BEB}" + `$dteService = [NuGet.VisualStudio.ServiceLocator].GetMethods() | ?{ `$_.Name -eq 'GetInstance' } | %{ `$_.MakeGenericMethod([Microsoft.VisualStudio.Shell.Interop.SDTE]).Invoke(`$null, [Array]`$null) } + `$outputWindow = `$dteService.Windows.Item([EnvDTE.Constants]::vsWindowKindOutput) + `$packageManagerOutputPane = `$outputWindow.Object.OutputWindowPanes.Item(`$packageManagerOutputPaneGuid) + `$packageManagerOutputPane.Clear() + `$packageManagerOutputPane.Activate() + `$outputWindow.Activate() + + # Invoke requested script + $scriptToExecute + } catch { + [System.Windows.Forms.MessageBox]::Show("An error occurred during scaffolding:`n`n`$(`$_.Exception.ToString())`n`nYou may need to upgrade to a newer version of MvcScaffolding.", "Scaffolding error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) | Out-Null + } +"@ + try { + # Write the script to disk + $tempDir = Join-Path $env:Temp ([System.Guid]::NewGuid()) + $tempScriptFilename = Join-Path $tempDir "tools\tempScript.ps1" + md $tempdir + md ([System.IO.Path]::GetDirectoryName($tempScriptFilename)) + Set-Content -Path $tempScriptFilename -Value $completeScript + + # Ensure we're on the right NuGet version + $scriptExecutorExists = [System.AppDomain]::CurrentDomain.GetAssemblies() | ?{ $_.GetType("NuGet.VisualStudio.IScriptExecutor") } + if (!$scriptExecutorExists) { + [System.Windows.Forms.MessageBox]::Show("Sorry, this operation requires NuGet 1.2 or later.", "Scaffolding error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) | Out-Null + return + } + + # Invoke via IScriptExecutor, then clean up + $scriptExecutor = [NuGet.VisualStudio.ServiceLocator].GetMethods() | ?{ $_.Name -eq 'GetInstance' } | %{ $_.MakeGenericMethod([NuGet.VisualStudio.IScriptExecutor]).Invoke($null, [Array]$null) } + $scriptExecutor.Execute($tempDir, "tempScript.ps1", $null, $null, (New-Object NuGet.NullLogger)) + rmdir $tempdir -Force -Recurse + } catch { + [System.Windows.Forms.MessageBox]::Show("An error occurred during scaffolding:`n`n$($_.Exception.ToString())`n`nYou may need to upgrade to a newer version of MvcScaffolding.", "Scaffolding error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) | Out-Null + } +} + +$mvcScaffoldingProvider = global:MvcScaffoldingHashTableToPsObject @{ + ID = { "{9EC893D9-B925-403C-B785-A50545149521}" }; + GetControllerScaffolders = { + param($project) + $allControllerScaffolders = Get-Scaffolder -Project $project.Name -IncludeHidden | ?{ $_.ScaffolderAttribute -is [T4Scaffolding.ControllerScaffolderAttribute] } + if (!$allControllerScaffolders) { return @() } + + $result = $allControllerScaffolders | %{ + global:MvcScaffoldingHashTableToPsObject @{ + ID = { $_.Name }.GetNewClosure(); + DisplayName = { "MvcScaffolding: " + $_.ScaffolderAttribute.DisplayName }.GetNewClosure(); + SupportsModelType = { $_.ScaffolderAttribute.SupportsModelType }.GetNewClosure(); + SupportsDataContextType = { $_.ScaffolderAttribute.SupportsDataContextType }.GetNewClosure(); + ViewsScaffolders = { + if (!$_.ScaffolderAttribute.SupportsViewScaffolder) { return @() } + $viewScaffolderSelector = $_.ScaffolderAttribute.ViewScaffolderSelector + if (!$viewScaffolderSelector) { $viewScaffolderSelector = [T4Scaffolding.ViewScaffolderAttribute] } + $viewScaffolders = Get-Scaffolder -Project $project.Name -IncludeHidden | ?{ $viewScaffolderSelector.IsAssignableFrom($_.ScaffolderAttribute.GetType()) } + + # Put default view engine at the top of the list so it's the default selection until you choose otherwise + $defaultViewScaffolder = (Get-DefaultScaffolder View).ScaffolderName + $viewScaffolders = $viewScaffolders | Sort-Object { if($_.Name -eq $defaultViewScaffolder) { "" } else { $_.Name } } + + $result = $viewScaffolders | %{ + global:MvcScaffoldingHashTableToPsObject @{ + ID = { $_.Name }.GetNewClosure(); + DisplayName = { $_.ScaffolderAttribute.DisplayName }.GetNewClosure(); + LayoutPageFilter = { $_.ScaffolderAttribute.LayoutPageFilter }.GetNewClosure(); + } + } + return ,[Array]$result + }.GetNewClosure(); + Execute = { + param($container, $controllerName, $modelType, $dataContextType, $viewsScaffolder, $options) + + # Infer possible area name from container location + $areaName = $null + if ($container -is [EnvDTE.ProjectItem]) { + $containerNamespace = $container.Properties.Item("DefaultNamespace").Value + $areaMatch = [System.Text.RegularExpressions.Regex]::Match($containerNamespace, "(^|\.)Areas\.(.*)\.Controllers($|\.)") + $areaName = if ($areaMatch.Success) { $areaMatch.Groups[2].Value } + } + + $scriptToExecute = @" + # These are all the args we may pass to the target scaffolder... + `$possibleArgs = @{ + ControllerName = `"$controllerName`"; + ModelType = `"$modelType`"; + DbContextType = `"$dataContextType`"; + Project = `"$($project.Name)`"; + Area = $(if($areaName) { "`"" + $areaName + "`"" } else { "`$null" }); + ViewScaffolder = $(if($viewsScaffolder) { "`"" + $viewsScaffolder.ID + "`"" } else { "`$null" }); + Force = $(if($options.OverwriteViews -or $options.OverwriteController) { "`$true" } else { "`$false" }); + ForceMode = $(if($options.OverwriteViews -and $options.OverwriteController) { "`$null" } else { if($options.OverwriteViews) { "`"PreserveController`"" } else { "`"ControllerOnly`"" } }); + Layout = $(if($options.UseLayout) { "`"" + $options.Layout + "`"" } else { "`$null" }); + PrimarySectionName = $(if($options.PrimarySectionName) { "`"" + $options.PrimarySectionName + "`"" } else { "`$null" }); + ReferenceScriptLibraries = $(if($options.ReferenceScriptLibraries) { "`$true" } else { "`$false" }); + } + # ... but we only pass the ones it actually accepts + `$actualArgs = @{} + `$acceptedParameterNames = (Get-Command Invoke-Scaffolder -ArgumentList @(`"$($_.Name)`")).Parameters.Keys + `$acceptedParameterNames | ?{ `$possibleArgs.ContainsKey(`"`$_`") } | %{ `$actualArgs.Add(`$_, `$possibleArgs[`$_]) } + Invoke-Scaffolder `"$($_.Name)`" @actualArgs +"@ + global:MvcScaffoldingInvokeViaScriptExecutor $scriptToExecute | Out-Null + + # Trick PowerShell into not unrolling the return collection by wrapping it in a further collection + $result = [System.Activator]::CreateInstance(([System.Collections.Generic.List``1].MakeGenericType([System.Object]))) + $result.Add(([System.Activator]::CreateInstance(([System.Collections.Generic.List``1].MakeGenericType([EnvDTE.ProjectItem]))))) + return $result + }.GetNewClosure(); + } + } + return ,[Array]$result + } +} + +# Remove existing MvcScaffolding providers +$allProviders = [Microsoft.VisualStudio.Web.Mvc.Scaffolding.ScaffolderProviders]::Providers +$existingMvcScaffoldingProviders = $allProviders | ?{ $_.ID -eq $mvcScaffoldingProvider.ID() } +$existingMvcScaffoldingProviders | %{ $allProviders.Remove($_) } | Out-Null + +# Add new provider +$newProvider = New-Object Microsoft.VisualStudio.Web.Mvc.Scaffolding.PowerShell.PowerShellScaffolderProvider($mvcScaffoldingProvider) +$allProviders.Add($newProvider) | Out-Null \ No newline at end of file diff --git a/packages/Newtonsoft.Json.4.0.2/Newtonsoft.Json.4.0.2.nupkg b/packages/Newtonsoft.Json.4.0.2/Newtonsoft.Json.4.0.2.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..684a6f2cc77997e5229421fe3af073faac9f59b0 GIT binary patch literal 2369113 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

- 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