@ -0,0 +1,259 @@ |
|||
## Ignore Visual Studio temporary files, build results, and |
|||
## files generated by popular Visual Studio add-ons. |
|||
|
|||
# User-specific files |
|||
*.suo |
|||
*.user |
|||
*.userosscache |
|||
*.sln.docstates |
|||
|
|||
# User-specific files (MonoDevelop/Xamarin Studio) |
|||
*.userprefs |
|||
|
|||
# Build results |
|||
[Dd]ebug/ |
|||
[Dd]ebugPublic/ |
|||
[Rr]elease/ |
|||
[Rr]eleases/ |
|||
x64/ |
|||
x86/ |
|||
bld/ |
|||
[Bb]in/ |
|||
[Oo]bj/ |
|||
[Ll]og/ |
|||
|
|||
# Visual Studio 2015 cache/options directory |
|||
.vs/ |
|||
# Uncomment if you have tasks that create the project's static files in wwwroot |
|||
#wwwroot/ |
|||
|
|||
# MSTest test Results |
|||
[Tt]est[Rr]esult*/ |
|||
[Bb]uild[Ll]og.* |
|||
|
|||
# NUNIT |
|||
*.VisualState.xml |
|||
TestResult.xml |
|||
|
|||
# Build Results of an ATL Project |
|||
[Dd]ebugPS/ |
|||
[Rr]eleasePS/ |
|||
dlldata.c |
|||
|
|||
# DNX |
|||
project.lock.json |
|||
artifacts/ |
|||
|
|||
*_i.c |
|||
*_p.c |
|||
*_i.h |
|||
*.ilk |
|||
*.meta |
|||
*.obj |
|||
*.pch |
|||
*.pdb |
|||
*.pgc |
|||
*.pgd |
|||
*.rsp |
|||
*.sbr |
|||
*.tlb |
|||
*.tli |
|||
*.tlh |
|||
*.tmp |
|||
*.tmp_proj |
|||
*.log |
|||
*.vspscc |
|||
*.vssscc |
|||
.builds |
|||
*.pidb |
|||
*.svclog |
|||
*.scc |
|||
|
|||
# Chutzpah Test files |
|||
_Chutzpah* |
|||
|
|||
# Visual C++ cache files |
|||
ipch/ |
|||
*.aps |
|||
*.ncb |
|||
*.opendb |
|||
*.opensdf |
|||
*.sdf |
|||
*.cachefile |
|||
*.VC.db |
|||
*.VC.VC.opendb |
|||
|
|||
# Visual Studio profiler |
|||
*.psess |
|||
*.vsp |
|||
*.vspx |
|||
*.sap |
|||
|
|||
# TFS 2012 Local Workspace |
|||
$tf/ |
|||
|
|||
# Guidance Automation Toolkit |
|||
*.gpState |
|||
|
|||
# ReSharper is a .NET coding add-in |
|||
_ReSharper*/ |
|||
*.[Rr]e[Ss]harper |
|||
*.DotSettings.user |
|||
|
|||
# JustCode is a .NET coding add-in |
|||
.JustCode |
|||
|
|||
# TeamCity is a build add-in |
|||
_TeamCity* |
|||
|
|||
# DotCover is a Code Coverage Tool |
|||
*.dotCover |
|||
|
|||
# NCrunch |
|||
_NCrunch_* |
|||
.*crunch*.local.xml |
|||
nCrunchTemp_* |
|||
|
|||
# MightyMoose |
|||
*.mm.* |
|||
AutoTest.Net/ |
|||
|
|||
# Web workbench (sass) |
|||
.sass-cache/ |
|||
|
|||
# Installshield output folder |
|||
[Ee]xpress/ |
|||
|
|||
# DocProject is a documentation generator add-in |
|||
DocProject/buildhelp/ |
|||
DocProject/Help/*.HxT |
|||
DocProject/Help/*.HxC |
|||
DocProject/Help/*.hhc |
|||
DocProject/Help/*.hhk |
|||
DocProject/Help/*.hhp |
|||
DocProject/Help/Html2 |
|||
DocProject/Help/html |
|||
|
|||
# Click-Once directory |
|||
publish/ |
|||
|
|||
# Publish Web Output |
|||
*.[Pp]ublish.xml |
|||
*.azurePubxml |
|||
# TODO: Comment the next line if you want to checkin your web deploy settings |
|||
# but database connection strings (with potential passwords) will be unencrypted |
|||
*.pubxml |
|||
*.publishproj |
|||
|
|||
# Microsoft Azure Web App publish settings. Comment the next line if you want to |
|||
# checkin your Azure Web App publish settings, but sensitive information contained |
|||
# in these scripts will be unencrypted |
|||
PublishScripts/ |
|||
|
|||
# NuGet Packages |
|||
*.nupkg |
|||
# The packages folder can be ignored because of Package Restore |
|||
**/packages/* |
|||
# except build/, which is used as an MSBuild target. |
|||
!**/packages/build/ |
|||
# Uncomment if necessary however generally it will be regenerated when needed |
|||
#!**/packages/repositories.config |
|||
# NuGet v3's project.json files produces more ignoreable files |
|||
*.nuget.props |
|||
*.nuget.targets |
|||
|
|||
# Microsoft Azure Build Output |
|||
csx/ |
|||
*.build.csdef |
|||
|
|||
# Microsoft Azure Emulator |
|||
ecf/ |
|||
rcf/ |
|||
|
|||
# Windows Store app package directories and files |
|||
AppPackages/ |
|||
BundleArtifacts/ |
|||
Package.StoreAssociation.xml |
|||
_pkginfo.txt |
|||
|
|||
# Visual Studio cache files |
|||
# files ending in .cache can be ignored |
|||
*.[Cc]ache |
|||
# but keep track of directories ending in .cache |
|||
!*.[Cc]ache/ |
|||
|
|||
# Others |
|||
ClientBin/ |
|||
~$* |
|||
*~ |
|||
*.dbmdl |
|||
*.dbproj.schemaview |
|||
*.pfx |
|||
*.publishsettings |
|||
node_modules/ |
|||
orleans.codegen.cs |
|||
|
|||
# Since there are multiple workflows, uncomment next line to ignore bower_components |
|||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) |
|||
#bower_components/ |
|||
|
|||
# RIA/Silverlight projects |
|||
Generated_Code/ |
|||
|
|||
# Backup & report files from converting an old project file |
|||
# to a newer Visual Studio version. Backup files are not needed, |
|||
# because we have git ;-) |
|||
_UpgradeReport_Files/ |
|||
Backup*/ |
|||
UpgradeLog*.XML |
|||
UpgradeLog*.htm |
|||
|
|||
# SQL Server files |
|||
*.mdf |
|||
*.ldf |
|||
|
|||
# Business Intelligence projects |
|||
*.rdl.data |
|||
*.bim.layout |
|||
*.bim_*.settings |
|||
|
|||
# Microsoft Fakes |
|||
FakesAssemblies/ |
|||
|
|||
# GhostDoc plugin setting file |
|||
*.GhostDoc.xml |
|||
|
|||
# Node.js Tools for Visual Studio |
|||
.ntvs_analysis.dat |
|||
|
|||
# Visual Studio 6 build log |
|||
*.plg |
|||
|
|||
# Visual Studio 6 workspace options file |
|||
*.opt |
|||
|
|||
# Visual Studio LightSwitch build output |
|||
**/*.HTMLClient/GeneratedArtifacts |
|||
**/*.DesktopClient/GeneratedArtifacts |
|||
**/*.DesktopClient/ModelManifest.xml |
|||
**/*.Server/GeneratedArtifacts |
|||
**/*.Server/ModelManifest.xml |
|||
_Pvt_Extensions |
|||
|
|||
# Paket dependency manager |
|||
.paket/paket.exe |
|||
paket-files/ |
|||
|
|||
# FAKE - F# Make |
|||
.fake/ |
|||
|
|||
# JetBrains Rider |
|||
.idea/ |
|||
*.sln.iml |
|||
pub/ |
|||
/src/Web/WebMVC/Properties/PublishProfiles/eShopOnContainersWebMVC2016 - Web Deploy-publish.ps1 |
|||
/src/Web/WebMVC/Properties/PublishProfiles/publish-module.psm1 |
|||
/src/Services/Identity/eShopOnContainers.Identity/Properties/launchSettings.json |
|||
|
|||
#Ignore marker-file used to know which docker files we have. |
|||
.eshopdocker_* |
|||
@ -0,0 +1,41 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio 15 |
|||
VisualStudioVersion = 15.0.26228.4 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{419A6ACE-0419-4315-A6FB-B0E63D39432E}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "src\Infrastructure\Infrastructure.csproj", "{7C461394-ABDC-43CD-A798-71249C58BA67}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "src\Web\Web.csproj", "{9CB6566E-E86A-4C07-BB8D-E0B95BCD4BD2}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Business", "src\Business\Business.csproj", "{A81FBFCF-757E-4E38-BD15-A9C4DC3A68C0}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{7C461394-ABDC-43CD-A798-71249C58BA67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{7C461394-ABDC-43CD-A798-71249C58BA67}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{7C461394-ABDC-43CD-A798-71249C58BA67}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{7C461394-ABDC-43CD-A798-71249C58BA67}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{9CB6566E-E86A-4C07-BB8D-E0B95BCD4BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{9CB6566E-E86A-4C07-BB8D-E0B95BCD4BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{9CB6566E-E86A-4C07-BB8D-E0B95BCD4BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{9CB6566E-E86A-4C07-BB8D-E0B95BCD4BD2}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{A81FBFCF-757E-4E38-BD15-A9C4DC3A68C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{A81FBFCF-757E-4E38-BD15-A9C4DC3A68C0}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{A81FBFCF-757E-4E38-BD15-A9C4DC3A68C0}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{A81FBFCF-757E-4E38-BD15-A9C4DC3A68C0}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(NestedProjects) = preSolution |
|||
{7C461394-ABDC-43CD-A798-71249C58BA67} = {419A6ACE-0419-4315-A6FB-B0E63D39432E} |
|||
{9CB6566E-E86A-4C07-BB8D-E0B95BCD4BD2} = {419A6ACE-0419-4315-A6FB-B0E63D39432E} |
|||
{A81FBFCF-757E-4E38-BD15-A9C4DC3A68C0} = {419A6ACE-0419-4315-A6FB-B0E63D39432E} |
|||
EndGlobalSection |
|||
EndGlobal |
|||
@ -0,0 +1,7 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard1.4</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard1.4</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Business\Business.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,3 @@ |
|||
{ |
|||
"directory": "wwwroot/lib" |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
* |
|||
!obj/Docker/publish/* |
|||
!obj/Docker/empty/ |
|||
@ -0,0 +1,7 @@ |
|||
namespace Microsoft.eShopWeb |
|||
{ |
|||
public class CatalogSettings |
|||
{ |
|||
public string CatalogBaseUrl { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
using Microsoft.eShopWeb.Services; |
|||
using Microsoft.eShopWeb.ViewModels; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
|
|||
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
|||
|
|||
namespace Microsoft.eShopWeb.Controllers |
|||
{ |
|||
public class CatalogController : Controller |
|||
{ |
|||
private readonly IHostingEnvironment _env; |
|||
private readonly ICatalogService _catalogSvc; |
|||
|
|||
public CatalogController(IHostingEnvironment env, ICatalogService catalogSvc) |
|||
{ |
|||
_env = env; |
|||
_catalogSvc = catalogSvc; |
|||
} |
|||
|
|||
|
|||
// GET: /<controller>/
|
|||
public async Task<IActionResult> Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page) |
|||
{ |
|||
var itemsPage = 10; |
|||
var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied); |
|||
|
|||
var vm = new CatalogIndex() |
|||
{ |
|||
CatalogItems = catalog.Data, |
|||
Brands = await _catalogSvc.GetBrands(), |
|||
Types = await _catalogSvc.GetTypes(), |
|||
BrandFilterApplied = BrandFilterApplied ?? 0, |
|||
TypesFilterApplied = TypesFilterApplied ?? 0, |
|||
PaginationInfo = new PaginationInfo() |
|||
{ |
|||
ActualPage = page ?? 0, |
|||
ItemsPerPage = catalog.Data.Count, |
|||
TotalItems = catalog.Count, |
|||
TotalPages = int.Parse(Math.Ceiling(((decimal)catalog.Count / itemsPage)).ToString()) |
|||
} |
|||
}; |
|||
|
|||
vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : ""; |
|||
vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : ""; |
|||
|
|||
return View(vm); |
|||
} |
|||
|
|||
[HttpGet("{id}")] |
|||
[Route("[controller]/pic/{id}")]
|
|||
// GET: /<controller>/pic/{id}
|
|||
public IActionResult GetImage(int id) |
|||
{ |
|||
var contentRoot = _env.ContentRootPath + "//Pics"; |
|||
var path = Path.Combine(contentRoot, id + ".png"); |
|||
Byte[] b = System.IO.File.ReadAllBytes(path); |
|||
return File(b, "image/png"); |
|||
|
|||
} |
|||
|
|||
public IActionResult Error() |
|||
{ |
|||
return View(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
FROM microsoft/aspnetcore:1.1 |
|||
ARG source |
|||
WORKDIR /app |
|||
EXPOSE 80 |
|||
COPY ${source:-obj/Docker/publish} . |
|||
ENTRYPOINT ["dotnet", "eShopWeb.dll"] |
|||
@ -0,0 +1,79 @@ |
|||
namespace Microsoft.eShopWeb.Infrastructure |
|||
{ |
|||
using eShopWeb.Models; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
|||
|
|||
public class CatalogContext : DbContext |
|||
{ |
|||
public CatalogContext(DbContextOptions options) : base(options) |
|||
{ |
|||
} |
|||
public DbSet<CatalogItem> CatalogItems { get; set; } |
|||
public DbSet<CatalogBrand> CatalogBrands { get; set; } |
|||
public DbSet<CatalogType> CatalogTypes { get; set; } |
|||
protected override void OnModelCreating(ModelBuilder builder) |
|||
{ |
|||
builder.Entity<CatalogBrand>(ConfigureCatalogBrand); |
|||
builder.Entity<CatalogType>(ConfigureCatalogType); |
|||
builder.Entity<CatalogItem>(ConfigureCatalogItem); |
|||
} |
|||
|
|||
void ConfigureCatalogItem(EntityTypeBuilder<CatalogItem> builder) |
|||
{ |
|||
builder.ToTable("Catalog"); |
|||
|
|||
builder.Property(ci => ci.Id) |
|||
.ForSqlServerUseSequenceHiLo("catalog_hilo") |
|||
.IsRequired(); |
|||
|
|||
builder.Property(ci => ci.Name) |
|||
.IsRequired(true) |
|||
.HasMaxLength(50); |
|||
|
|||
builder.Property(ci => ci.Price) |
|||
.IsRequired(true); |
|||
|
|||
builder.Property(ci => ci.PictureUri) |
|||
.IsRequired(false); |
|||
|
|||
builder.HasOne(ci => ci.CatalogBrand) |
|||
.WithMany() |
|||
.HasForeignKey(ci => ci.CatalogBrandId); |
|||
|
|||
builder.HasOne(ci => ci.CatalogType) |
|||
.WithMany() |
|||
.HasForeignKey(ci => ci.CatalogTypeId); |
|||
} |
|||
|
|||
void ConfigureCatalogBrand(EntityTypeBuilder<CatalogBrand> builder) |
|||
{ |
|||
builder.ToTable("CatalogBrand"); |
|||
|
|||
builder.HasKey(ci => ci.Id); |
|||
|
|||
builder.Property(ci => ci.Id) |
|||
.ForSqlServerUseSequenceHiLo("catalog_brand_hilo") |
|||
.IsRequired(); |
|||
|
|||
builder.Property(cb => cb.Brand) |
|||
.IsRequired() |
|||
.HasMaxLength(100); |
|||
} |
|||
|
|||
void ConfigureCatalogType(EntityTypeBuilder<CatalogType> builder) |
|||
{ |
|||
builder.ToTable("CatalogType"); |
|||
|
|||
builder.HasKey(ci => ci.Id); |
|||
|
|||
builder.Property(ci => ci.Id) |
|||
.ForSqlServerUseSequenceHiLo("catalog_type_hilo") |
|||
.IsRequired(); |
|||
|
|||
builder.Property(cb => cb.Type) |
|||
.IsRequired() |
|||
.HasMaxLength(100); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,102 @@ |
|||
namespace Microsoft.eShopWeb.Infrastructure |
|||
{ |
|||
using eShopWeb.Models; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
public class CatalogContextSeed |
|||
{ |
|||
public static async Task SeedAsync(IApplicationBuilder applicationBuilder, ILoggerFactory loggerFactory, int? retry = 0) |
|||
{ |
|||
int retryForAvaiability = retry.Value; |
|||
try |
|||
{ |
|||
var context = (CatalogContext)applicationBuilder |
|||
.ApplicationServices.GetService(typeof(CatalogContext)); |
|||
|
|||
context.Database.Migrate(); |
|||
|
|||
if (!context.CatalogBrands.Any()) |
|||
{ |
|||
context.CatalogBrands.AddRange( |
|||
GetPreconfiguredCatalogBrands()); |
|||
|
|||
await context.SaveChangesAsync(); |
|||
} |
|||
|
|||
if (!context.CatalogTypes.Any()) |
|||
{ |
|||
context.CatalogTypes.AddRange( |
|||
GetPreconfiguredCatalogTypes()); |
|||
|
|||
await context.SaveChangesAsync(); |
|||
} |
|||
|
|||
if (!context.CatalogItems.Any()) |
|||
{ |
|||
context.CatalogItems.AddRange( |
|||
GetPreconfiguredItems()); |
|||
|
|||
await context.SaveChangesAsync(); |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
if (retryForAvaiability < 10) |
|||
{ |
|||
retryForAvaiability++; |
|||
var log = loggerFactory.CreateLogger("catalog seed"); |
|||
log.LogError(ex.Message); |
|||
await SeedAsync(applicationBuilder, loggerFactory, retryForAvaiability); |
|||
} |
|||
} |
|||
} |
|||
|
|||
static IEnumerable<CatalogBrand> GetPreconfiguredCatalogBrands() |
|||
{ |
|||
return new List<CatalogBrand>() |
|||
{ |
|||
new CatalogBrand() { Brand = "Azure"}, |
|||
new CatalogBrand() { Brand = ".NET" }, |
|||
new CatalogBrand() { Brand = "Visual Studio" }, |
|||
new CatalogBrand() { Brand = "SQL Server" }, |
|||
new CatalogBrand() { Brand = "Other" } |
|||
}; |
|||
} |
|||
|
|||
static IEnumerable<CatalogType> GetPreconfiguredCatalogTypes() |
|||
{ |
|||
return new List<CatalogType>() |
|||
{ |
|||
new CatalogType() { Type = "Mug"}, |
|||
new CatalogType() { Type = "T-Shirt" }, |
|||
new CatalogType() { Type = "Sheet" }, |
|||
new CatalogType() { Type = "USB Memory Stick" } |
|||
}; |
|||
} |
|||
|
|||
static IEnumerable<CatalogItem> GetPreconfiguredItems() |
|||
{ |
|||
return new List<CatalogItem>() |
|||
{ |
|||
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Bot Black Sweatshirt", Name = ".NET Bot Black Sweatshirt", Price = 19.5M, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/1" }, |
|||
new CatalogItem() { CatalogTypeId=1,CatalogBrandId=2, Description = ".NET Black & White Mug", Name = ".NET Black & White Mug", Price= 8.50M, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/2" }, |
|||
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Prism White T-Shirt", Name = "Prism White T-Shirt", Price = 12, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/3" }, |
|||
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Foundation Sweatshirt", Name = ".NET Foundation Sweatshirt", Price = 12, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/4" }, |
|||
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=5, Description = "Roslyn Red Sheet", Name = "Roslyn Red Sheet", Price = 8.5M, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/5" }, |
|||
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=2, Description = ".NET Blue Sweatshirt", Name = ".NET Blue Sweatshirt", Price = 12, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/6" }, |
|||
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Roslyn Red T-Shirt", Name = "Roslyn Red T-Shirt", Price = 12, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/7" }, |
|||
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Kudu Purple Sweatshirt", Name = "Kudu Purple Sweatshirt", Price = 8.5M, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/8" }, |
|||
new CatalogItem() { CatalogTypeId=1,CatalogBrandId=5, Description = "Cup<T> White Mug", Name = "Cup<T> White Mug", Price = 12, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/9" }, |
|||
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=2, Description = ".NET Foundation Sheet", Name = ".NET Foundation Sheet", Price = 12, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/10" }, |
|||
new CatalogItem() { CatalogTypeId=3,CatalogBrandId=2, Description = "Cup<T> Sheet", Name = "Cup<T> Sheet", Price = 8.5M, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/11" }, |
|||
new CatalogItem() { CatalogTypeId=2,CatalogBrandId=5, Description = "Prism White TShirt", Name = "Prism White TShirt", Price = 12, PictureUri = "http://catalogbaseurltobereplaced/catalog/pic/12" } |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Metadata; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace Microsoft.eShopWeb.Infrastructure.Migrations |
|||
{ |
|||
[DbContext(typeof(CatalogContext))] |
|||
[Migration("20170302162241_Initial")] |
|||
partial class Initial |
|||
{ |
|||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|||
{ |
|||
modelBuilder |
|||
.HasAnnotation("ProductVersion", "1.1.0-rtm-22752") |
|||
.HasAnnotation("SqlServer:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") |
|||
.HasAnnotation("SqlServer:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") |
|||
.HasAnnotation("SqlServer:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogBrand", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); |
|||
|
|||
b.Property<string>("Brand") |
|||
.IsRequired() |
|||
.HasMaxLength(100); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("CatalogBrand"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogItem", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); |
|||
|
|||
b.Property<int>("CatalogBrandId"); |
|||
|
|||
b.Property<int>("CatalogTypeId"); |
|||
|
|||
b.Property<string>("Description"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(50); |
|||
|
|||
b.Property<string>("PictureUri"); |
|||
|
|||
b.Property<decimal>("Price"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("CatalogBrandId"); |
|||
|
|||
b.HasIndex("CatalogTypeId"); |
|||
|
|||
b.ToTable("Catalog"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogType", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); |
|||
|
|||
b.Property<string>("Type") |
|||
.IsRequired() |
|||
.HasMaxLength(100); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("CatalogType"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogItem", b => |
|||
{ |
|||
b.HasOne("eShopWeb.Models.CatalogBrand", "CatalogBrand") |
|||
.WithMany() |
|||
.HasForeignKey("CatalogBrandId") |
|||
.OnDelete(DeleteBehavior.Cascade); |
|||
|
|||
b.HasOne("eShopWeb.Models.CatalogType", "CatalogType") |
|||
.WithMany() |
|||
.HasForeignKey("CatalogTypeId") |
|||
.OnDelete(DeleteBehavior.Cascade); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace Microsoft.eShopWeb.Infrastructure.Migrations |
|||
{ |
|||
public partial class Initial : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateSequence( |
|||
name: "catalog_brand_hilo", |
|||
incrementBy: 10); |
|||
|
|||
migrationBuilder.CreateSequence( |
|||
name: "catalog_hilo", |
|||
incrementBy: 10); |
|||
|
|||
migrationBuilder.CreateSequence( |
|||
name: "catalog_type_hilo", |
|||
incrementBy: 10); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "CatalogBrand", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<int>(nullable: false), |
|||
Brand = table.Column<string>(maxLength: 100, nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_CatalogBrand", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "CatalogType", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<int>(nullable: false), |
|||
Type = table.Column<string>(maxLength: 100, nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_CatalogType", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "Catalog", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<int>(nullable: false), |
|||
CatalogBrandId = table.Column<int>(nullable: false), |
|||
CatalogTypeId = table.Column<int>(nullable: false), |
|||
Description = table.Column<string>(nullable: true), |
|||
Name = table.Column<string>(maxLength: 50, nullable: false), |
|||
PictureUri = table.Column<string>(nullable: true), |
|||
Price = table.Column<decimal>(nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_Catalog", x => x.Id); |
|||
table.ForeignKey( |
|||
name: "FK_Catalog_CatalogBrand_CatalogBrandId", |
|||
column: x => x.CatalogBrandId, |
|||
principalTable: "CatalogBrand", |
|||
principalColumn: "Id", |
|||
onDelete: ReferentialAction.Cascade); |
|||
table.ForeignKey( |
|||
name: "FK_Catalog_CatalogType_CatalogTypeId", |
|||
column: x => x.CatalogTypeId, |
|||
principalTable: "CatalogType", |
|||
principalColumn: "Id", |
|||
onDelete: ReferentialAction.Cascade); |
|||
}); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Catalog_CatalogBrandId", |
|||
table: "Catalog", |
|||
column: "CatalogBrandId"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Catalog_CatalogTypeId", |
|||
table: "Catalog", |
|||
column: "CatalogTypeId"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "Catalog"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "CatalogBrand"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "CatalogType"); |
|||
|
|||
migrationBuilder.DropSequence( |
|||
name: "catalog_brand_hilo"); |
|||
|
|||
migrationBuilder.DropSequence( |
|||
name: "catalog_hilo"); |
|||
|
|||
migrationBuilder.DropSequence( |
|||
name: "catalog_type_hilo"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,95 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Metadata; |
|||
|
|||
namespace Microsoft.eShopWeb.Infrastructure.Migrations |
|||
{ |
|||
[DbContext(typeof(CatalogContext))] |
|||
partial class CatalogContextModelSnapshot : ModelSnapshot |
|||
{ |
|||
protected override void BuildModel(ModelBuilder modelBuilder) |
|||
{ |
|||
modelBuilder |
|||
.HasAnnotation("ProductVersion", "1.1.0-rtm-22752") |
|||
.HasAnnotation("SqlServer:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") |
|||
.HasAnnotation("SqlServer:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") |
|||
.HasAnnotation("SqlServer:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogBrand", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); |
|||
|
|||
b.Property<string>("Brand") |
|||
.IsRequired() |
|||
.HasMaxLength(100); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("CatalogBrand"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogItem", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); |
|||
|
|||
b.Property<int>("CatalogBrandId"); |
|||
|
|||
b.Property<int>("CatalogTypeId"); |
|||
|
|||
b.Property<string>("Description"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(50); |
|||
|
|||
b.Property<string>("PictureUri"); |
|||
|
|||
b.Property<decimal>("Price"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("CatalogBrandId"); |
|||
|
|||
b.HasIndex("CatalogTypeId"); |
|||
|
|||
b.ToTable("Catalog"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogType", b => |
|||
{ |
|||
b.Property<int>("Id") |
|||
.ValueGeneratedOnAdd() |
|||
.HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") |
|||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); |
|||
|
|||
b.Property<string>("Type") |
|||
.IsRequired() |
|||
.HasMaxLength(100); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.ToTable("CatalogType"); |
|||
}); |
|||
|
|||
modelBuilder.Entity("eShopWeb.Models.CatalogItem", b => |
|||
{ |
|||
b.HasOne("eShopWeb.Models.CatalogBrand", "CatalogBrand") |
|||
.WithMany() |
|||
.HasForeignKey("CatalogBrandId") |
|||
.OnDelete(DeleteBehavior.Cascade); |
|||
|
|||
b.HasOne("eShopWeb.Models.CatalogType", "CatalogType") |
|||
.WithMany() |
|||
.HasForeignKey("CatalogTypeId") |
|||
.OnDelete(DeleteBehavior.Cascade); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
namespace Microsoft.eShopWeb.Models |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
|
|||
public class CatalogBrand |
|||
{ |
|||
public int Id { get; set; } |
|||
|
|||
public string Brand { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System; |
|||
|
|||
namespace Microsoft.eShopWeb.Models |
|||
{ |
|||
public class CatalogItem |
|||
{ |
|||
public int Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public decimal Price { get; set; } |
|||
|
|||
public string PictureUri { get; set; } |
|||
|
|||
public int CatalogTypeId { get; set; } |
|||
|
|||
public CatalogType CatalogType { get; set; } |
|||
|
|||
public int CatalogBrandId { get; set; } |
|||
|
|||
public CatalogBrand CatalogBrand { get; set; } |
|||
|
|||
public CatalogItem() { } |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
namespace Microsoft.eShopWeb.Models |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
public class CatalogType |
|||
{ |
|||
public int Id { get; set; } |
|||
|
|||
public string Type { get; set; } |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 170 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 179 KiB |
|
After Width: | Height: | Size: 182 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 40 KiB |
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
|
|||
namespace Microsoft.eShopWeb |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static void Main(string[] args) |
|||
{ |
|||
var host = new WebHostBuilder() |
|||
.UseKestrel() |
|||
.UseUrls("http://0.0.0.0:5106") |
|||
.UseContentRoot(Directory.GetCurrentDirectory()) |
|||
.UseIISIntegration() |
|||
.UseStartup<Startup>() |
|||
.UseApplicationInsights() |
|||
.Build(); |
|||
|
|||
host.Run(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:5106/", |
|||
"sslPort": 0 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"eShopWeb": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "http://localhost:58299" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,88 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.eShopWeb.Models; |
|||
using Microsoft.AspNetCore.Mvc.Rendering; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.eShopWeb.Infrastructure; |
|||
using Microsoft.eShopWeb.ViewModels; |
|||
|
|||
namespace Microsoft.eShopWeb.Services |
|||
{ |
|||
public class CatalogService : ICatalogService |
|||
{ |
|||
private readonly CatalogContext _context; |
|||
private readonly IOptionsSnapshot<CatalogSettings> _settings; |
|||
|
|||
public CatalogService(CatalogContext context, IOptionsSnapshot<CatalogSettings> settings) |
|||
{ |
|||
_context = context; |
|||
_settings = settings; |
|||
} |
|||
|
|||
public async Task<Catalog> GetCatalogItems(int pageIndex, int itemsPage, int? brandId, int? typeId) |
|||
{ |
|||
var root = (IQueryable<CatalogItem>)_context.CatalogItems; |
|||
|
|||
if (typeId.HasValue) |
|||
{ |
|||
root = root.Where(ci => ci.CatalogTypeId == typeId); |
|||
} |
|||
|
|||
if (brandId.HasValue) |
|||
{ |
|||
root = root.Where(ci => ci.CatalogBrandId == brandId); |
|||
} |
|||
|
|||
var totalItems = await root |
|||
.LongCountAsync(); |
|||
|
|||
var itemsOnPage = await root |
|||
.Skip(itemsPage * pageIndex) |
|||
.Take(itemsPage) |
|||
.ToListAsync(); |
|||
|
|||
itemsOnPage = ComposePicUri(itemsOnPage); |
|||
|
|||
return new Catalog() { Data = itemsOnPage, PageIndex = pageIndex, Count = (int)totalItems }; |
|||
} |
|||
|
|||
public async Task<IEnumerable<SelectListItem>> GetBrands() |
|||
{ |
|||
var brands = await _context.CatalogBrands.ToListAsync(); |
|||
var items = new List<SelectListItem>(); |
|||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true }); |
|||
foreach (CatalogBrand brand in brands) |
|||
{ |
|||
items.Add(new SelectListItem() { Value = brand.Id.ToString(), Text = brand.Brand }); |
|||
} |
|||
|
|||
return items; |
|||
} |
|||
|
|||
public async Task<IEnumerable<SelectListItem>> GetTypes() |
|||
{ |
|||
var types = await _context.CatalogTypes.ToListAsync(); |
|||
var items = new List<SelectListItem>(); |
|||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true }); |
|||
foreach (CatalogType type in types) |
|||
{ |
|||
items.Add(new SelectListItem() { Value = type.Id.ToString(), Text = type.Type }); |
|||
} |
|||
|
|||
return items; |
|||
} |
|||
|
|||
private List<CatalogItem> ComposePicUri(List<CatalogItem> items) |
|||
{ |
|||
var baseUri = _settings.Value.CatalogBaseUrl; |
|||
items.ForEach(x => |
|||
{ |
|||
x.PictureUri = x.PictureUri.Replace("http://catalogbaseurltobereplaced", baseUri); |
|||
}); |
|||
|
|||
return items; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Microsoft.AspNetCore.Mvc.Rendering; |
|||
using Microsoft.eShopWeb.ViewModels; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Services |
|||
{ |
|||
public interface ICatalogService |
|||
{ |
|||
Task<Catalog> GetCatalogItems(int pageIndex, int itemsPage, int? brandID, int? typeId); |
|||
Task<IEnumerable<SelectListItem>> GetBrands(); |
|||
Task<IEnumerable<SelectListItem>> GetTypes(); |
|||
} |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
using Microsoft.eShopWeb.Infrastructure; |
|||
using Microsoft.eShopWeb.Services; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace Microsoft.eShopWeb |
|||
{ |
|||
public class Startup |
|||
{ |
|||
public Startup(IHostingEnvironment env) |
|||
{ |
|||
var builder = new ConfigurationBuilder() |
|||
.SetBasePath(env.ContentRootPath) |
|||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) |
|||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) |
|||
.AddEnvironmentVariables(); |
|||
Configuration = builder.Build(); |
|||
} |
|||
|
|||
public IConfigurationRoot Configuration { get; } |
|||
|
|||
// This method gets called by the runtime. Use this method to add services to the container.
|
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
// Requires LocalDB which can be installed with SQL Server Express 2016
|
|||
// https://www.microsoft.com/en-us/download/details.aspx?id=54284
|
|||
services.AddDbContext<CatalogContext>(c => |
|||
{ |
|||
try |
|||
{ |
|||
var text = Configuration["ConnectionString"]; |
|||
c.UseSqlServer(Configuration["ConnectionString"]); |
|||
c.ConfigureWarnings(wb => |
|||
{ |
|||
//By default, in this application, we don't want to have client evaluations
|
|||
wb.Log(RelationalEventId.QueryClientEvaluationWarning); |
|||
}); |
|||
} |
|||
catch (System.Exception ex ) |
|||
{ |
|||
var message = ex.Message; |
|||
} |
|||
}); |
|||
|
|||
services.AddTransient<ICatalogService, CatalogService>(); |
|||
services.Configure<CatalogSettings>(Configuration); |
|||
services.AddMvc(); |
|||
} |
|||
|
|||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) |
|||
{ |
|||
loggerFactory.AddConsole(Configuration.GetSection("Logging")); |
|||
loggerFactory.AddDebug(); |
|||
|
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
app.UseBrowserLink(); |
|||
} |
|||
else |
|||
{ |
|||
app.UseExceptionHandler("/Catalog/Error"); |
|||
} |
|||
|
|||
app.UseStaticFiles(); |
|||
|
|||
app.UseMvc(routes => |
|||
{ |
|||
routes.MapRoute( |
|||
name: "default", |
|||
template: "{controller=Catalog}/{action=Index}/{id?}"); |
|||
}); |
|||
|
|||
//Seed Data
|
|||
CatalogContextSeed.SeedAsync(app, loggerFactory) |
|||
.Wait(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using Microsoft.eShopWeb.Models; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Microsoft.eShopWeb.ViewModels |
|||
{ |
|||
public class Catalog |
|||
{ |
|||
public int PageIndex { get; set; } |
|||
public int PageSize { get; set; } |
|||
public int Count { get; set; } |
|||
public List<CatalogItem> Data { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using Microsoft.eShopWeb.Models; |
|||
using Microsoft.AspNetCore.Mvc.Rendering; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Microsoft.eShopWeb.ViewModels |
|||
{ |
|||
public class CatalogIndex |
|||
{ |
|||
public IEnumerable<CatalogItem> CatalogItems { get; set; } |
|||
public IEnumerable<SelectListItem> Brands { get; set; } |
|||
public IEnumerable<SelectListItem> Types { get; set; } |
|||
public int? BrandFilterApplied { get; set; } |
|||
public int? TypesFilterApplied { get; set; } |
|||
public PaginationInfo PaginationInfo { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.ViewModels |
|||
{ |
|||
public class PaginationInfo |
|||
{ |
|||
public int TotalItems { get; set; } |
|||
public int ItemsPerPage { get; set; } |
|||
public int ActualPage { get; set; } |
|||
public int TotalPages { get; set; } |
|||
public string Previous { get; set; } |
|||
public string Next { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
@{ |
|||
ViewData["Title"] = "Catalog"; |
|||
@model Microsoft.eShopWeb.ViewModels.CatalogIndex |
|||
} |
|||
<section class="esh-catalog-hero"> |
|||
<div class="container"> |
|||
<img class="esh-catalog-title" src="../images/main_banner_text.png" /> |
|||
</div> |
|||
</section> |
|||
|
|||
<section class="esh-catalog-filters"> |
|||
<div class="container"> |
|||
<form asp-action="Index" asp-controller="Catalog" method="post"> |
|||
<label class="esh-catalog-label" data-title="brand"> |
|||
<select asp-for="@Model.BrandFilterApplied" asp-items="@Model.Brands" class="esh-catalog-filter"></select> |
|||
</label> |
|||
<label class="esh-catalog-label" data-title="type"> |
|||
<select asp-for="@Model.TypesFilterApplied" asp-items="@Model.Types" class="esh-catalog-filter"></select> |
|||
</label> |
|||
<input class="esh-catalog-send" type="image" src="images/arrow-right.svg" /> |
|||
</form> |
|||
</div> |
|||
</section> |
|||
|
|||
<div class="container"> |
|||
|
|||
@if (Model.CatalogItems.Any()) |
|||
{ |
|||
@Html.Partial("_pagination", Model.PaginationInfo) |
|||
|
|||
<div class="esh-catalog-items row"> |
|||
@foreach (var catalogItem in Model.CatalogItems) |
|||
{ |
|||
<div class="esh-catalog-item col-md-4"> |
|||
@Html.Partial("_product", catalogItem) |
|||
</div> |
|||
} |
|||
</div> |
|||
|
|||
@Html.Partial("_pagination", Model.PaginationInfo) |
|||
} |
|||
else |
|||
{ |
|||
<div class="esh-catalog-items row"> |
|||
THERE ARE NO RESULTS THAT MATCH YOUR SEARCH |
|||
</div> |
|||
} |
|||
</div> |
|||
@ -0,0 +1,32 @@ |
|||
@model Microsoft.eShopWeb.ViewModels.PaginationInfo |
|||
|
|||
<div class="esh-pager"> |
|||
<div class="container"> |
|||
<article class="esh-pager-wrapper row"> |
|||
<nav> |
|||
<a class="esh-pager-item esh-pager-item--navigable @Model.Previous" |
|||
id="Previous" |
|||
asp-controller="Catalog" |
|||
asp-action="Index" |
|||
asp-route-page="@(Model.ActualPage -1)" |
|||
aria-label="Previous"> |
|||
Previous |
|||
</a> |
|||
|
|||
<span class="esh-pager-item"> |
|||
Showing @Model.ItemsPerPage of @Model.TotalItems products - Page @(Model.ActualPage + 1) - @Model.TotalPages |
|||
</span> |
|||
|
|||
<a class="esh-pager-item esh-pager-item--navigable @Model.Next" |
|||
id="Next" |
|||
asp-controller="Catalog" |
|||
asp-action="Index" |
|||
asp-route-page="@(Model.ActualPage + 1)" |
|||
aria-label="Next"> |
|||
Next |
|||
</a> |
|||
</nav> |
|||
</article> |
|||
</div> |
|||
</div> |
|||
|
|||
@ -0,0 +1,24 @@ |
|||
@model Microsoft.eShopWeb.Models.CatalogItem |
|||
|
|||
|
|||
<form asp-controller="Cart" asp-action="AddToCart"> |
|||
|
|||
<img class="esh-catalog-thumbnail" src="@Model.PictureUri" /> |
|||
<input class="esh-catalog-button @((!User.Identity.IsAuthenticated) ? "is-disabled" : "")" type="submit" value="[ ADD TO CART ]" /> |
|||
|
|||
<div class="esh-catalog-name"> |
|||
<span>@Model.Name</span> |
|||
</div> |
|||
<div class="esh-catalog-price"> |
|||
<span>@Model.Price.ToString("N2")</span> |
|||
</div> |
|||
<input type="hidden" asp-for="@Model.CatalogBrand" name="brand" /> |
|||
<input type="hidden" asp-for="@Model.CatalogBrandId" name="brandId" /> |
|||
<input type="hidden" asp-for="@Model.CatalogType" name="type" /> |
|||
<input type="hidden" asp-for="@Model.CatalogTypeId" name="typeId" /> |
|||
<input type="hidden" asp-for="@Model.Description" name="description" /> |
|||
<input type="hidden" asp-for="@Model.Id" name="id" /> |
|||
<input type="hidden" asp-for="@Model.Name" name="name" /> |
|||
<input type="hidden" asp-for="@Model.PictureUri" name="pictureUri" /> |
|||
<input type="hidden" asp-for="@Model.Price" name="price" /> |
|||
</form> |
|||
@ -0,0 +1,14 @@ |
|||
@{ |
|||
ViewData["Title"] = "Error"; |
|||
} |
|||
|
|||
<h1 class="text-danger">Error.</h1> |
|||
<h2 class="text-danger">An error occurred while processing your request.</h2> |
|||
|
|||
<h3>Development Mode</h3> |
|||
<p> |
|||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred. |
|||
</p> |
|||
<p> |
|||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application. |
|||
</p> |
|||
@ -0,0 +1,75 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<title>@ViewData["Title"] - Microsoft.eShopOnContainers.WebMVC</title> |
|||
|
|||
<environment names="Development"> |
|||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> |
|||
<link rel="stylesheet" href="~/css/app.css" /> |
|||
<link rel="stylesheet" href="~/css/catalog/pager.css" /> |
|||
<link rel="stylesheet" href="~/css/catalog/catalog.component.css" /> |
|||
</environment> |
|||
<environment names="Staging,Production"> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" |
|||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" |
|||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" /> |
|||
<link rel="stylesheet" href="~/css/app.min.css" asp-append-version="true" /> |
|||
</environment> |
|||
</head> |
|||
<body> |
|||
<header class="navbar navbar-light navbar-static-top"> |
|||
<div class="container"> |
|||
<article class="row"> |
|||
|
|||
<section class="col-lg-7 col-md-6 col-xs-12"> |
|||
<a class="navbar-brand" routerLink="catalog"> |
|||
<a asp-area="" asp-controller="Catalog" asp-action="Index"> |
|||
<img src="../images/brand.png" /> |
|||
</a> |
|||
</section> |
|||
|
|||
</article> |
|||
</div> |
|||
</header> |
|||
|
|||
@RenderBody() |
|||
|
|||
|
|||
<footer class="esh-app-footer"> |
|||
<div class="container"> |
|||
<article class="row"> |
|||
|
|||
<section class="col-sm-6"> |
|||
<img class="esh-app-footer-brand" src="../images/brand_dark.png" /> |
|||
</section> |
|||
|
|||
<section class="col-sm-6"> |
|||
<div class="esh-app-footer-text hidden-xs"> e-ShoponContainers. All right reserved </div> |
|||
</section> |
|||
|
|||
</article> |
|||
</div> |
|||
</footer> |
|||
|
|||
<environment names="Development"> |
|||
<script src="~/lib/jquery/dist/jquery.js"></script> |
|||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script> |
|||
<script src="~/js/site.js" asp-append-version="true"></script> |
|||
</environment> |
|||
<environment names="Staging,Production"> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js" |
|||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js" |
|||
asp-fallback-test="window.jQuery"> |
|||
</script> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js" |
|||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js" |
|||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"> |
|||
</script> |
|||
<script src="~/js/site.min.js" asp-append-version="true"></script> |
|||
</environment> |
|||
|
|||
@RenderSection("scripts", required: false) |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,18 @@ |
|||
<environment names="Development"> |
|||
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script> |
|||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> |
|||
</environment> |
|||
<environment names="Staging,Production"> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js" |
|||
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js" |
|||
asp-fallback-test="window.jQuery && window.jQuery.validator" |
|||
crossorigin="anonymous" |
|||
integrity="sha384-Fnqn3nxp3506LP/7Y3j/25BlWeA3PXTyT1l78LjECcPaKCV12TsZP7yyMxOe/G/k"> |
|||
</script> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js" |
|||
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" |
|||
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive" |
|||
crossorigin="anonymous" |
|||
integrity="sha384-JrXK+k53HACyavUKOsL+NkmSesD2P+73eDMrbTtTk0h4RmOF8hF8apPlkp26JlyH"> |
|||
</script> |
|||
</environment> |
|||
@ -0,0 +1,2 @@ |
|||
@using Microsoft.eShopWeb |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@ -0,0 +1,3 @@ |
|||
@{ |
|||
Layout = "_Layout"; |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp1.1</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup> |
|||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback> |
|||
<RuntimeFrameworkVersion>1.1.0</RuntimeFrameworkVersion> |
|||
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" /> |
|||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.0.0-msbuild3-final" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" /> |
|||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0-msbuild3-final" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Folder Include="Models\" /> |
|||
<Folder Include="Pics\" /> |
|||
<Folder Include="Views\Catalog\" /> |
|||
<Folder Include="wwwroot\css\catalog\" /> |
|||
<Folder Include="wwwroot\fonts\" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Business\Business.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,10 @@ |
|||
{ |
|||
"Logging": { |
|||
"IncludeScopes": false, |
|||
"LogLevel": { |
|||
"Default": "Debug", |
|||
"System": "Information", |
|||
"Microsoft": "Information" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
{ |
|||
"ConnectionString": "Server=(localdb)\\ProjectsV13;Integrated Security=true;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;", |
|||
"CatalogBaseUrl": "http://localhost:5106", |
|||
"Logging": { |
|||
"IncludeScopes": false, |
|||
"LogLevel": { |
|||
"Default": "Warning" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
{ |
|||
"name": "asp.net", |
|||
"private": true, |
|||
"dependencies": { |
|||
"bootstrap": "3.3.7", |
|||
"jquery": "2.2.0", |
|||
"jquery-validation": "1.14.0", |
|||
"jquery-validation-unobtrusive": "3.2.6" |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Configure bundling and minification for the project. |
|||
// More info at https://go.microsoft.com/fwlink/?LinkId=808241 |
|||
[ |
|||
{ |
|||
"outputFileName": "wwwroot/css/site.min.css", |
|||
// An array of relative input file paths. Globbing patterns supported |
|||
"inputFiles": [ |
|||
"wwwroot/css/site.css" |
|||
] |
|||
}, |
|||
{ |
|||
"outputFileName": "wwwroot/js/site.min.js", |
|||
"inputFiles": [ |
|||
"wwwroot/js/site.js" |
|||
], |
|||
// Optionally specify minification options |
|||
"minify": { |
|||
"enabled": true, |
|||
"renameLocals": true |
|||
}, |
|||
// Optionally generate .map file |
|||
"sourceMap": false |
|||
} |
|||
] |
|||
@ -0,0 +1,86 @@ |
|||
@font-face { |
|||
font-family: Montserrat; |
|||
font-weight: 400; |
|||
src: url(".../fonts/Montserrat-Regular.eot?") format("eot"), url("../fonts/Montserrat-Regular.woff") format("woff"), url("../fonts/Montserrat-Regular.ttf") format("truetype"), url("../fonts/Montserrat-Regular.svg#Montserrat") format("svg"); |
|||
} |
|||
|
|||
@font-face { |
|||
font-family: Montserrat; |
|||
font-weight: 700; |
|||
src: url("../fonts/Montserrat-Bold.eot?") format("eot"), url("../fonts/Montserrat-Bold.woff") format("woff"), url("../fonts/Montserrat-Bold.ttf") format("truetype"), url("../fonts/Montserrat-Bold.svg#Montserrat") format("svg"); |
|||
} |
|||
|
|||
html, |
|||
body { |
|||
font-family: Montserrat, sans-serif; |
|||
font-size: 16px; |
|||
font-weight: 400; |
|||
z-index: 10; |
|||
} |
|||
|
|||
*, |
|||
*::after, |
|||
*::before { |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.preloading { |
|||
color: #00A69C; |
|||
display: block; |
|||
font-size: 1.5rem; |
|||
left: 50%; |
|||
position: fixed; |
|||
top: 50%; |
|||
transform: translate(-50%, -50%); |
|||
} |
|||
|
|||
select::-ms-expand { |
|||
display: none; |
|||
} |
|||
|
|||
@media screen and (min-width: 992px) { |
|||
.form-input { |
|||
max-width: 360px; |
|||
width: 360px; |
|||
} |
|||
} |
|||
|
|||
.form-input { |
|||
border-radius: 0; |
|||
height: 45px; |
|||
padding: 10px; |
|||
} |
|||
|
|||
.form-input-small { |
|||
max-width: 100px !important; |
|||
} |
|||
|
|||
.form-input-medium { |
|||
width: 150px !important; |
|||
} |
|||
|
|||
.alert { |
|||
padding-left: 0; |
|||
} |
|||
|
|||
.alert-danger { |
|||
background-color: transparent; |
|||
border: 0; |
|||
color: #FB0D0D; |
|||
font-size: 12px; |
|||
} |
|||
|
|||
a, |
|||
a:active, |
|||
a:hover, |
|||
a:visited { |
|||
color: #000; |
|||
text-decoration: none; |
|||
transition: color 0.35s; |
|||
} |
|||
|
|||
a:hover, |
|||
a:active { |
|||
color: #75B918; |
|||
transition: color 0.35s; |
|||
} |
|||
@ -0,0 +1,147 @@ |
|||
.esh-catalog-hero { |
|||
background-image: url("../../images/main_banner.png"); |
|||
background-size: cover; |
|||
height: 260px; |
|||
width: 100%; |
|||
} |
|||
|
|||
.esh-catalog-title { |
|||
position: relative; |
|||
top: 74.28571px; |
|||
} |
|||
|
|||
.esh-catalog-filters { |
|||
background-color: #00A69C; |
|||
height: 65px; |
|||
} |
|||
|
|||
.esh-catalog-filter { |
|||
background-color: transparent; |
|||
border-color: #00d9cc; |
|||
color: #FFFFFF; |
|||
cursor: pointer; |
|||
margin-right: 1rem; |
|||
margin-top: .5rem; |
|||
outline-color: #83D01B; |
|||
padding-bottom: 0; |
|||
padding-left: 0.5rem; |
|||
padding-right: 0.5rem; |
|||
padding-top: 1.5rem; |
|||
min-width: 140px; |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
.esh-catalog-filter option { |
|||
background-color: #00A69C; |
|||
} |
|||
|
|||
.esh-catalog-label { |
|||
display: inline-block; |
|||
position: relative; |
|||
z-index: 0; |
|||
} |
|||
|
|||
.esh-catalog-label::before { |
|||
color: rgba(255, 255, 255, 0.5); |
|||
content: attr(data-title); |
|||
font-size: 0.65rem; |
|||
margin-top: 0.65rem; |
|||
margin-left: 0.5rem; |
|||
position: absolute; |
|||
text-transform: uppercase; |
|||
z-index: 1; |
|||
} |
|||
|
|||
.esh-catalog-label::after { |
|||
background-image: url("../../images/arrow-down.png"); |
|||
height: 7px; |
|||
content: ''; |
|||
position: absolute; |
|||
right: 1.5rem; |
|||
top: 2.5rem; |
|||
width: 10px; |
|||
z-index: 1; |
|||
} |
|||
|
|||
.esh-catalog-send { |
|||
background-color: #83D01B; |
|||
color: #FFFFFF; |
|||
cursor: pointer; |
|||
font-size: 1rem; |
|||
transform: translateY(.5rem); |
|||
padding: 0.5rem; |
|||
transition: all 0.35s; |
|||
} |
|||
|
|||
.esh-catalog-send:hover { |
|||
background-color: #4a760f; |
|||
transition: all 0.35s; |
|||
} |
|||
|
|||
.esh-catalog-items { |
|||
margin-top: 1rem; |
|||
} |
|||
|
|||
.esh-catalog-item { |
|||
text-align: center; |
|||
margin-bottom: 1.5rem; |
|||
width: 33%; |
|||
display: inline-block; |
|||
float: none !important; |
|||
} |
|||
|
|||
@media screen and (max-width: 1024px) { |
|||
.esh-catalog-item { |
|||
width: 50%; |
|||
} |
|||
} |
|||
|
|||
@media screen and (max-width: 768px) { |
|||
.esh-catalog-item { |
|||
width: 100%; |
|||
} |
|||
} |
|||
|
|||
.esh-catalog-thumbnail { |
|||
max-width: 370px; |
|||
width: 100%; |
|||
} |
|||
|
|||
.esh-catalog-button { |
|||
background-color: #83D01B; |
|||
border: none; |
|||
color: #FFFFFF; |
|||
cursor: pointer; |
|||
font-size: 1rem; |
|||
height: 3rem; |
|||
margin-top: 1rem; |
|||
transition: all 0.35s; |
|||
width: 80%; |
|||
} |
|||
.esh-catalog-button.is-disabled { |
|||
opacity: .5; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.esh-catalog-button:hover { |
|||
background-color: #4a760f; |
|||
transition: all 0.35s; |
|||
} |
|||
|
|||
.esh-catalog-name { |
|||
font-size: 1rem; |
|||
font-weight: 300; |
|||
margin-top: .5rem; |
|||
text-align: center; |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
.esh-catalog-price { |
|||
text-align: center; |
|||
font-weight: 900; |
|||
font-size: 28px; |
|||
} |
|||
|
|||
.esh-catalog-price::before { |
|||
content: '$'; |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
.esh-pager-wrapper { |
|||
padding-top: 1rem; |
|||
text-align: center; |
|||
} |
|||
|
|||
.esh-pager-item { |
|||
margin: 0 5vw; |
|||
} |
|||
|
|||
.esh-pager-item--navigable { |
|||
display: inline-block; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.esh-pager-item--navigable.is-disabled { |
|||
opacity: 0; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.esh-pager-item--navigable:hover { |
|||
color: #83D01B; |
|||
} |
|||
|
|||
@media screen and (max-width: 1280px) { |
|||
.esh-pager-item { |
|||
font-size: 0.85rem; |
|||
} |
|||
} |
|||
|
|||
@media screen and (max-width: 1024px) { |
|||
.esh-pager-item { |
|||
margin: 0 4vw; |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 693 B |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 429 B |
|
After Width: | Height: | Size: 713 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 221 B |
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1 @@ |
|||
// Write your Javascript code.
|
|||
@ -0,0 +1,45 @@ |
|||
{ |
|||
"name": "bootstrap", |
|||
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", |
|||
"keywords": [ |
|||
"css", |
|||
"js", |
|||
"less", |
|||
"mobile-first", |
|||
"responsive", |
|||
"front-end", |
|||
"framework", |
|||
"web" |
|||
], |
|||
"homepage": "http://getbootstrap.com", |
|||
"license": "MIT", |
|||
"moduleType": "globals", |
|||
"main": [ |
|||
"less/bootstrap.less", |
|||
"dist/js/bootstrap.js" |
|||
], |
|||
"ignore": [ |
|||
"/.*", |
|||
"_config.yml", |
|||
"CNAME", |
|||
"composer.json", |
|||
"CONTRIBUTING.md", |
|||
"docs", |
|||
"js/tests", |
|||
"test-infra" |
|||
], |
|||
"dependencies": { |
|||
"jquery": "1.9.1 - 3" |
|||
}, |
|||
"version": "3.3.7", |
|||
"_release": "3.3.7", |
|||
"_resolution": { |
|||
"type": "version", |
|||
"tag": "v3.3.7", |
|||
"commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" |
|||
}, |
|||
"_source": "https://github.com/twbs/bootstrap.git", |
|||
"_target": "v3.3.7", |
|||
"_originalSource": "bootstrap", |
|||
"_direct": true |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
The MIT License (MIT) |
|||
|
|||
Copyright (c) 2011-2016 Twitter, Inc. |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in |
|||
all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
THE SOFTWARE. |
|||
@ -0,0 +1,587 @@ |
|||
/*! |
|||
* Bootstrap v3.3.7 (http://getbootstrap.com) |
|||
* Copyright 2011-2016 Twitter, Inc. |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|||
*/ |
|||
.btn-default, |
|||
.btn-primary, |
|||
.btn-success, |
|||
.btn-info, |
|||
.btn-warning, |
|||
.btn-danger { |
|||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); |
|||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); |
|||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); |
|||
} |
|||
.btn-default:active, |
|||
.btn-primary:active, |
|||
.btn-success:active, |
|||
.btn-info:active, |
|||
.btn-warning:active, |
|||
.btn-danger:active, |
|||
.btn-default.active, |
|||
.btn-primary.active, |
|||
.btn-success.active, |
|||
.btn-info.active, |
|||
.btn-warning.active, |
|||
.btn-danger.active { |
|||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); |
|||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); |
|||
} |
|||
.btn-default.disabled, |
|||
.btn-primary.disabled, |
|||
.btn-success.disabled, |
|||
.btn-info.disabled, |
|||
.btn-warning.disabled, |
|||
.btn-danger.disabled, |
|||
.btn-default[disabled], |
|||
.btn-primary[disabled], |
|||
.btn-success[disabled], |
|||
.btn-info[disabled], |
|||
.btn-warning[disabled], |
|||
.btn-danger[disabled], |
|||
fieldset[disabled] .btn-default, |
|||
fieldset[disabled] .btn-primary, |
|||
fieldset[disabled] .btn-success, |
|||
fieldset[disabled] .btn-info, |
|||
fieldset[disabled] .btn-warning, |
|||
fieldset[disabled] .btn-danger { |
|||
-webkit-box-shadow: none; |
|||
box-shadow: none; |
|||
} |
|||
.btn-default .badge, |
|||
.btn-primary .badge, |
|||
.btn-success .badge, |
|||
.btn-info .badge, |
|||
.btn-warning .badge, |
|||
.btn-danger .badge { |
|||
text-shadow: none; |
|||
} |
|||
.btn:active, |
|||
.btn.active { |
|||
background-image: none; |
|||
} |
|||
.btn-default { |
|||
text-shadow: 0 1px 0 #fff; |
|||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); |
|||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); |
|||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-color: #dbdbdb; |
|||
border-color: #ccc; |
|||
} |
|||
.btn-default:hover, |
|||
.btn-default:focus { |
|||
background-color: #e0e0e0; |
|||
background-position: 0 -15px; |
|||
} |
|||
.btn-default:active, |
|||
.btn-default.active { |
|||
background-color: #e0e0e0; |
|||
border-color: #dbdbdb; |
|||
} |
|||
.btn-default.disabled, |
|||
.btn-default[disabled], |
|||
fieldset[disabled] .btn-default, |
|||
.btn-default.disabled:hover, |
|||
.btn-default[disabled]:hover, |
|||
fieldset[disabled] .btn-default:hover, |
|||
.btn-default.disabled:focus, |
|||
.btn-default[disabled]:focus, |
|||
fieldset[disabled] .btn-default:focus, |
|||
.btn-default.disabled.focus, |
|||
.btn-default[disabled].focus, |
|||
fieldset[disabled] .btn-default.focus, |
|||
.btn-default.disabled:active, |
|||
.btn-default[disabled]:active, |
|||
fieldset[disabled] .btn-default:active, |
|||
.btn-default.disabled.active, |
|||
.btn-default[disabled].active, |
|||
fieldset[disabled] .btn-default.active { |
|||
background-color: #e0e0e0; |
|||
background-image: none; |
|||
} |
|||
.btn-primary { |
|||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); |
|||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); |
|||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-color: #245580; |
|||
} |
|||
.btn-primary:hover, |
|||
.btn-primary:focus { |
|||
background-color: #265a88; |
|||
background-position: 0 -15px; |
|||
} |
|||
.btn-primary:active, |
|||
.btn-primary.active { |
|||
background-color: #265a88; |
|||
border-color: #245580; |
|||
} |
|||
.btn-primary.disabled, |
|||
.btn-primary[disabled], |
|||
fieldset[disabled] .btn-primary, |
|||
.btn-primary.disabled:hover, |
|||
.btn-primary[disabled]:hover, |
|||
fieldset[disabled] .btn-primary:hover, |
|||
.btn-primary.disabled:focus, |
|||
.btn-primary[disabled]:focus, |
|||
fieldset[disabled] .btn-primary:focus, |
|||
.btn-primary.disabled.focus, |
|||
.btn-primary[disabled].focus, |
|||
fieldset[disabled] .btn-primary.focus, |
|||
.btn-primary.disabled:active, |
|||
.btn-primary[disabled]:active, |
|||
fieldset[disabled] .btn-primary:active, |
|||
.btn-primary.disabled.active, |
|||
.btn-primary[disabled].active, |
|||
fieldset[disabled] .btn-primary.active { |
|||
background-color: #265a88; |
|||
background-image: none; |
|||
} |
|||
.btn-success { |
|||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); |
|||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); |
|||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-color: #3e8f3e; |
|||
} |
|||
.btn-success:hover, |
|||
.btn-success:focus { |
|||
background-color: #419641; |
|||
background-position: 0 -15px; |
|||
} |
|||
.btn-success:active, |
|||
.btn-success.active { |
|||
background-color: #419641; |
|||
border-color: #3e8f3e; |
|||
} |
|||
.btn-success.disabled, |
|||
.btn-success[disabled], |
|||
fieldset[disabled] .btn-success, |
|||
.btn-success.disabled:hover, |
|||
.btn-success[disabled]:hover, |
|||
fieldset[disabled] .btn-success:hover, |
|||
.btn-success.disabled:focus, |
|||
.btn-success[disabled]:focus, |
|||
fieldset[disabled] .btn-success:focus, |
|||
.btn-success.disabled.focus, |
|||
.btn-success[disabled].focus, |
|||
fieldset[disabled] .btn-success.focus, |
|||
.btn-success.disabled:active, |
|||
.btn-success[disabled]:active, |
|||
fieldset[disabled] .btn-success:active, |
|||
.btn-success.disabled.active, |
|||
.btn-success[disabled].active, |
|||
fieldset[disabled] .btn-success.active { |
|||
background-color: #419641; |
|||
background-image: none; |
|||
} |
|||
.btn-info { |
|||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); |
|||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); |
|||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-color: #28a4c9; |
|||
} |
|||
.btn-info:hover, |
|||
.btn-info:focus { |
|||
background-color: #2aabd2; |
|||
background-position: 0 -15px; |
|||
} |
|||
.btn-info:active, |
|||
.btn-info.active { |
|||
background-color: #2aabd2; |
|||
border-color: #28a4c9; |
|||
} |
|||
.btn-info.disabled, |
|||
.btn-info[disabled], |
|||
fieldset[disabled] .btn-info, |
|||
.btn-info.disabled:hover, |
|||
.btn-info[disabled]:hover, |
|||
fieldset[disabled] .btn-info:hover, |
|||
.btn-info.disabled:focus, |
|||
.btn-info[disabled]:focus, |
|||
fieldset[disabled] .btn-info:focus, |
|||
.btn-info.disabled.focus, |
|||
.btn-info[disabled].focus, |
|||
fieldset[disabled] .btn-info.focus, |
|||
.btn-info.disabled:active, |
|||
.btn-info[disabled]:active, |
|||
fieldset[disabled] .btn-info:active, |
|||
.btn-info.disabled.active, |
|||
.btn-info[disabled].active, |
|||
fieldset[disabled] .btn-info.active { |
|||
background-color: #2aabd2; |
|||
background-image: none; |
|||
} |
|||
.btn-warning { |
|||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); |
|||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); |
|||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-color: #e38d13; |
|||
} |
|||
.btn-warning:hover, |
|||
.btn-warning:focus { |
|||
background-color: #eb9316; |
|||
background-position: 0 -15px; |
|||
} |
|||
.btn-warning:active, |
|||
.btn-warning.active { |
|||
background-color: #eb9316; |
|||
border-color: #e38d13; |
|||
} |
|||
.btn-warning.disabled, |
|||
.btn-warning[disabled], |
|||
fieldset[disabled] .btn-warning, |
|||
.btn-warning.disabled:hover, |
|||
.btn-warning[disabled]:hover, |
|||
fieldset[disabled] .btn-warning:hover, |
|||
.btn-warning.disabled:focus, |
|||
.btn-warning[disabled]:focus, |
|||
fieldset[disabled] .btn-warning:focus, |
|||
.btn-warning.disabled.focus, |
|||
.btn-warning[disabled].focus, |
|||
fieldset[disabled] .btn-warning.focus, |
|||
.btn-warning.disabled:active, |
|||
.btn-warning[disabled]:active, |
|||
fieldset[disabled] .btn-warning:active, |
|||
.btn-warning.disabled.active, |
|||
.btn-warning[disabled].active, |
|||
fieldset[disabled] .btn-warning.active { |
|||
background-color: #eb9316; |
|||
background-image: none; |
|||
} |
|||
.btn-danger { |
|||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); |
|||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); |
|||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-color: #b92c28; |
|||
} |
|||
.btn-danger:hover, |
|||
.btn-danger:focus { |
|||
background-color: #c12e2a; |
|||
background-position: 0 -15px; |
|||
} |
|||
.btn-danger:active, |
|||
.btn-danger.active { |
|||
background-color: #c12e2a; |
|||
border-color: #b92c28; |
|||
} |
|||
.btn-danger.disabled, |
|||
.btn-danger[disabled], |
|||
fieldset[disabled] .btn-danger, |
|||
.btn-danger.disabled:hover, |
|||
.btn-danger[disabled]:hover, |
|||
fieldset[disabled] .btn-danger:hover, |
|||
.btn-danger.disabled:focus, |
|||
.btn-danger[disabled]:focus, |
|||
fieldset[disabled] .btn-danger:focus, |
|||
.btn-danger.disabled.focus, |
|||
.btn-danger[disabled].focus, |
|||
fieldset[disabled] .btn-danger.focus, |
|||
.btn-danger.disabled:active, |
|||
.btn-danger[disabled]:active, |
|||
fieldset[disabled] .btn-danger:active, |
|||
.btn-danger.disabled.active, |
|||
.btn-danger[disabled].active, |
|||
fieldset[disabled] .btn-danger.active { |
|||
background-color: #c12e2a; |
|||
background-image: none; |
|||
} |
|||
.thumbnail, |
|||
.img-thumbnail { |
|||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|||
} |
|||
.dropdown-menu > li > a:hover, |
|||
.dropdown-menu > li > a:focus { |
|||
background-color: #e8e8e8; |
|||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); |
|||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.dropdown-menu > .active > a, |
|||
.dropdown-menu > .active > a:hover, |
|||
.dropdown-menu > .active > a:focus { |
|||
background-color: #2e6da4; |
|||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); |
|||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.navbar-default { |
|||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); |
|||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); |
|||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-radius: 4px; |
|||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); |
|||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); |
|||
} |
|||
.navbar-default .navbar-nav > .open > a, |
|||
.navbar-default .navbar-nav > .active > a { |
|||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); |
|||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); |
|||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); |
|||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); |
|||
} |
|||
.navbar-brand, |
|||
.navbar-nav > li > a { |
|||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25); |
|||
} |
|||
.navbar-inverse { |
|||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); |
|||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); |
|||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|||
background-repeat: repeat-x; |
|||
border-radius: 4px; |
|||
} |
|||
.navbar-inverse .navbar-nav > .open > a, |
|||
.navbar-inverse .navbar-nav > .active > a { |
|||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); |
|||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); |
|||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); |
|||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); |
|||
} |
|||
.navbar-inverse .navbar-brand, |
|||
.navbar-inverse .navbar-nav > li > a { |
|||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); |
|||
} |
|||
.navbar-static-top, |
|||
.navbar-fixed-top, |
|||
.navbar-fixed-bottom { |
|||
border-radius: 0; |
|||
} |
|||
@media (max-width: 767px) { |
|||
.navbar .navbar-nav .open .dropdown-menu > .active > a, |
|||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover, |
|||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus { |
|||
color: #fff; |
|||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); |
|||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
} |
|||
.alert { |
|||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2); |
|||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); |
|||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); |
|||
} |
|||
.alert-success { |
|||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); |
|||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); |
|||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
border-color: #b2dba1; |
|||
} |
|||
.alert-info { |
|||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); |
|||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); |
|||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
border-color: #9acfea; |
|||
} |
|||
.alert-warning { |
|||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); |
|||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); |
|||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
border-color: #f5e79e; |
|||
} |
|||
.alert-danger { |
|||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); |
|||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); |
|||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
border-color: #dca7a7; |
|||
} |
|||
.progress { |
|||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); |
|||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); |
|||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.progress-bar { |
|||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); |
|||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); |
|||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.progress-bar-success { |
|||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); |
|||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); |
|||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.progress-bar-info { |
|||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); |
|||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); |
|||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.progress-bar-warning { |
|||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); |
|||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); |
|||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.progress-bar-danger { |
|||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); |
|||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); |
|||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.progress-bar-striped { |
|||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); |
|||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); |
|||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); |
|||
} |
|||
.list-group { |
|||
border-radius: 4px; |
|||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|||
} |
|||
.list-group-item.active, |
|||
.list-group-item.active:hover, |
|||
.list-group-item.active:focus { |
|||
text-shadow: 0 -1px 0 #286090; |
|||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); |
|||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); |
|||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
border-color: #2b669a; |
|||
} |
|||
.list-group-item.active .badge, |
|||
.list-group-item.active:hover .badge, |
|||
.list-group-item.active:focus .badge { |
|||
text-shadow: none; |
|||
} |
|||
.panel { |
|||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); |
|||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05); |
|||
} |
|||
.panel-default > .panel-heading { |
|||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); |
|||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.panel-primary > .panel-heading { |
|||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); |
|||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.panel-success > .panel-heading { |
|||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); |
|||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); |
|||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.panel-info > .panel-heading { |
|||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); |
|||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); |
|||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.panel-warning > .panel-heading { |
|||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); |
|||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); |
|||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.panel-danger > .panel-heading { |
|||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); |
|||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); |
|||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
} |
|||
.well { |
|||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); |
|||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); |
|||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); |
|||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); |
|||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); |
|||
background-repeat: repeat-x; |
|||
border-color: #dcdcdc; |
|||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); |
|||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); |
|||
} |
|||
/*# sourceMappingURL=bootstrap-theme.css.map */ |
|||
|
After Width: | Height: | Size: 106 KiB |
@ -0,0 +1,13 @@ |
|||
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
|
|||
require('../../js/transition.js') |
|||
require('../../js/alert.js') |
|||
require('../../js/button.js') |
|||
require('../../js/carousel.js') |
|||
require('../../js/collapse.js') |
|||
require('../../js/dropdown.js') |
|||
require('../../js/modal.js') |
|||
require('../../js/tooltip.js') |
|||
require('../../js/popover.js') |
|||
require('../../js/scrollspy.js') |
|||
require('../../js/tab.js') |
|||
require('../../js/affix.js') |
|||
@ -0,0 +1,44 @@ |
|||
{ |
|||
"name": "jquery-validation-unobtrusive", |
|||
"version": "3.2.6", |
|||
"homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", |
|||
"description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.", |
|||
"main": [ |
|||
"jquery.validate.unobtrusive.js" |
|||
], |
|||
"ignore": [ |
|||
"**/.*", |
|||
"*.json", |
|||
"*.md", |
|||
"*.txt", |
|||
"gulpfile.js" |
|||
], |
|||
"keywords": [ |
|||
"jquery", |
|||
"asp.net", |
|||
"mvc", |
|||
"validation", |
|||
"unobtrusive" |
|||
], |
|||
"authors": [ |
|||
"Microsoft" |
|||
], |
|||
"license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm", |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "git://github.com/aspnet/jquery-validation-unobtrusive.git" |
|||
}, |
|||
"dependencies": { |
|||
"jquery-validation": ">=1.8", |
|||
"jquery": ">=1.8" |
|||
}, |
|||
"_release": "3.2.6", |
|||
"_resolution": { |
|||
"type": "version", |
|||
"tag": "v3.2.6", |
|||
"commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7" |
|||
}, |
|||
"_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git", |
|||
"_target": "3.2.6", |
|||
"_originalSource": "jquery-validation-unobtrusive" |
|||
} |
|||
@ -0,0 +1,416 @@ |
|||
/*! |
|||
** Unobtrusive validation support library for jQuery and jQuery Validate |
|||
** Copyright (C) Microsoft Corporation. All rights reserved. |
|||
*/ |
|||
|
|||
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ |
|||
/*global document: false, jQuery: false */ |
|||
|
|||
(function ($) { |
|||
var $jQval = $.validator, |
|||
adapters, |
|||
data_validation = "unobtrusiveValidation"; |
|||
|
|||
function setValidationValues(options, ruleName, value) { |
|||
options.rules[ruleName] = value; |
|||
if (options.message) { |
|||
options.messages[ruleName] = options.message; |
|||
} |
|||
} |
|||
|
|||
function splitAndTrim(value) { |
|||
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); |
|||
} |
|||
|
|||
function escapeAttributeValue(value) { |
|||
// As mentioned on http://api.jquery.com/category/selectors/
|
|||
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); |
|||
} |
|||
|
|||
function getModelPrefix(fieldName) { |
|||
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); |
|||
} |
|||
|
|||
function appendModelPrefix(value, prefix) { |
|||
if (value.indexOf("*.") === 0) { |
|||
value = value.replace("*.", prefix); |
|||
} |
|||
return value; |
|||
} |
|||
|
|||
function onError(error, inputElement) { // 'this' is the form element
|
|||
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), |
|||
replaceAttrValue = container.attr("data-valmsg-replace"), |
|||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; |
|||
|
|||
container.removeClass("field-validation-valid").addClass("field-validation-error"); |
|||
error.data("unobtrusiveContainer", container); |
|||
|
|||
if (replace) { |
|||
container.empty(); |
|||
error.removeClass("input-validation-error").appendTo(container); |
|||
} |
|||
else { |
|||
error.hide(); |
|||
} |
|||
} |
|||
|
|||
function onErrors(event, validator) { // 'this' is the form element
|
|||
var container = $(this).find("[data-valmsg-summary=true]"), |
|||
list = container.find("ul"); |
|||
|
|||
if (list && list.length && validator.errorList.length) { |
|||
list.empty(); |
|||
container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); |
|||
|
|||
$.each(validator.errorList, function () { |
|||
$("<li />").html(this.message).appendTo(list); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function onSuccess(error) { // 'this' is the form element
|
|||
var container = error.data("unobtrusiveContainer"); |
|||
|
|||
if (container) { |
|||
var replaceAttrValue = container.attr("data-valmsg-replace"), |
|||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; |
|||
|
|||
container.addClass("field-validation-valid").removeClass("field-validation-error"); |
|||
error.removeData("unobtrusiveContainer"); |
|||
|
|||
if (replace) { |
|||
container.empty(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
function onReset(event) { // 'this' is the form element
|
|||
var $form = $(this), |
|||
key = '__jquery_unobtrusive_validation_form_reset'; |
|||
if ($form.data(key)) { |
|||
return; |
|||
} |
|||
// Set a flag that indicates we're currently resetting the form.
|
|||
$form.data(key, true); |
|||
try { |
|||
$form.data("validator").resetForm(); |
|||
} finally { |
|||
$form.removeData(key); |
|||
} |
|||
|
|||
$form.find(".validation-summary-errors") |
|||
.addClass("validation-summary-valid") |
|||
.removeClass("validation-summary-errors"); |
|||
$form.find(".field-validation-error") |
|||
.addClass("field-validation-valid") |
|||
.removeClass("field-validation-error") |
|||
.removeData("unobtrusiveContainer") |
|||
.find(">*") // If we were using valmsg-replace, get the underlying error
|
|||
.removeData("unobtrusiveContainer"); |
|||
} |
|||
|
|||
function validationInfo(form) { |
|||
var $form = $(form), |
|||
result = $form.data(data_validation), |
|||
onResetProxy = $.proxy(onReset, form), |
|||
defaultOptions = $jQval.unobtrusive.options || {}, |
|||
execInContext = function (name, args) { |
|||
var func = defaultOptions[name]; |
|||
func && $.isFunction(func) && func.apply(form, args); |
|||
} |
|||
|
|||
if (!result) { |
|||
result = { |
|||
options: { // options structure passed to jQuery Validate's validate() method
|
|||
errorClass: defaultOptions.errorClass || "input-validation-error", |
|||
errorElement: defaultOptions.errorElement || "span", |
|||
errorPlacement: function () { |
|||
onError.apply(form, arguments); |
|||
execInContext("errorPlacement", arguments); |
|||
}, |
|||
invalidHandler: function () { |
|||
onErrors.apply(form, arguments); |
|||
execInContext("invalidHandler", arguments); |
|||
}, |
|||
messages: {}, |
|||
rules: {}, |
|||
success: function () { |
|||
onSuccess.apply(form, arguments); |
|||
execInContext("success", arguments); |
|||
} |
|||
}, |
|||
attachValidation: function () { |
|||
$form |
|||
.off("reset." + data_validation, onResetProxy) |
|||
.on("reset." + data_validation, onResetProxy) |
|||
.validate(this.options); |
|||
}, |
|||
validate: function () { // a validation function that is called by unobtrusive Ajax
|
|||
$form.validate(); |
|||
return $form.valid(); |
|||
} |
|||
}; |
|||
$form.data(data_validation, result); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
$jQval.unobtrusive = { |
|||
adapters: [], |
|||
|
|||
parseElement: function (element, skipAttach) { |
|||
/// <summary>
|
|||
/// Parses a single HTML element for unobtrusive validation attributes.
|
|||
/// </summary>
|
|||
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
|
|||
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
|
|||
/// validation to the form. If parsing just this single element, you should specify true.
|
|||
/// If parsing several elements, you should specify false, and manually attach the validation
|
|||
/// to the form when you are finished. The default is false.</param>
|
|||
var $element = $(element), |
|||
form = $element.parents("form")[0], |
|||
valInfo, rules, messages; |
|||
|
|||
if (!form) { // Cannot do client-side validation without a form
|
|||
return; |
|||
} |
|||
|
|||
valInfo = validationInfo(form); |
|||
valInfo.options.rules[element.name] = rules = {}; |
|||
valInfo.options.messages[element.name] = messages = {}; |
|||
|
|||
$.each(this.adapters, function () { |
|||
var prefix = "data-val-" + this.name, |
|||
message = $element.attr(prefix), |
|||
paramValues = {}; |
|||
|
|||
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
|
|||
prefix += "-"; |
|||
|
|||
$.each(this.params, function () { |
|||
paramValues[this] = $element.attr(prefix + this); |
|||
}); |
|||
|
|||
this.adapt({ |
|||
element: element, |
|||
form: form, |
|||
message: message, |
|||
params: paramValues, |
|||
rules: rules, |
|||
messages: messages |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
$.extend(rules, { "__dummy__": true }); |
|||
|
|||
if (!skipAttach) { |
|||
valInfo.attachValidation(); |
|||
} |
|||
}, |
|||
|
|||
parse: function (selector) { |
|||
/// <summary>
|
|||
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
|
|||
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
|
|||
/// attribute values.
|
|||
/// </summary>
|
|||
/// <param name="selector" type="String">Any valid jQuery selector.</param>
|
|||
|
|||
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
|
|||
// element with data-val=true
|
|||
var $selector = $(selector), |
|||
$forms = $selector.parents() |
|||
.addBack() |
|||
.filter("form") |
|||
.add($selector.find("form")) |
|||
.has("[data-val=true]"); |
|||
|
|||
$selector.find("[data-val=true]").each(function () { |
|||
$jQval.unobtrusive.parseElement(this, true); |
|||
}); |
|||
|
|||
$forms.each(function () { |
|||
var info = validationInfo(this); |
|||
if (info) { |
|||
info.attachValidation(); |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
adapters = $jQval.unobtrusive.adapters; |
|||
|
|||
adapters.add = function (adapterName, params, fn) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
|||
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
|
|||
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
|
|||
/// mmmm is the parameter name).</param>
|
|||
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
|
|||
/// attributes into jQuery Validate rules and/or messages.</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
if (!fn) { // Called with no params, just a function
|
|||
fn = params; |
|||
params = []; |
|||
} |
|||
this.push({ name: adapterName, params: params, adapt: fn }); |
|||
return this; |
|||
}; |
|||
|
|||
adapters.addBool = function (adapterName, ruleName) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
|||
/// the jQuery Validate validation rule has no parameter values.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
|||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
|||
/// of adapterName will be used instead.</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
return this.add(adapterName, function (options) { |
|||
setValidationValues(options, ruleName || adapterName, true); |
|||
}); |
|||
}; |
|||
|
|||
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
|||
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
|
|||
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
|||
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
|||
/// have a minimum value.</param>
|
|||
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
|||
/// have a maximum value.</param>
|
|||
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
|
|||
/// have both a minimum and maximum value.</param>
|
|||
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
|||
/// contains the minimum value. The default is "min".</param>
|
|||
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
|||
/// contains the maximum value. The default is "max".</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { |
|||
var min = options.params.min, |
|||
max = options.params.max; |
|||
|
|||
if (min && max) { |
|||
setValidationValues(options, minMaxRuleName, [min, max]); |
|||
} |
|||
else if (min) { |
|||
setValidationValues(options, minRuleName, min); |
|||
} |
|||
else if (max) { |
|||
setValidationValues(options, maxRuleName, max); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
adapters.addSingleVal = function (adapterName, attribute, ruleName) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
|||
/// the jQuery Validate validation rule has a single value.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
|
|||
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
|
|||
/// The default is "val".</param>
|
|||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
|||
/// of adapterName will be used instead.</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
return this.add(adapterName, [attribute || "val"], function (options) { |
|||
setValidationValues(options, ruleName || adapterName, options.params[attribute]); |
|||
}); |
|||
}; |
|||
|
|||
$jQval.addMethod("__dummy__", function (value, element, params) { |
|||
return true; |
|||
}); |
|||
|
|||
$jQval.addMethod("regex", function (value, element, params) { |
|||
var match; |
|||
if (this.optional(element)) { |
|||
return true; |
|||
} |
|||
|
|||
match = new RegExp(params).exec(value); |
|||
return (match && (match.index === 0) && (match[0].length === value.length)); |
|||
}); |
|||
|
|||
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { |
|||
var match; |
|||
if (nonalphamin) { |
|||
match = value.match(/\W/g); |
|||
match = match && match.length >= nonalphamin; |
|||
} |
|||
return match; |
|||
}); |
|||
|
|||
if ($jQval.methods.extension) { |
|||
adapters.addSingleVal("accept", "mimtype"); |
|||
adapters.addSingleVal("extension", "extension"); |
|||
} else { |
|||
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
|
|||
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
|
|||
// validating the extension, and ignore mime-type validations as they are not supported.
|
|||
adapters.addSingleVal("extension", "extension", "accept"); |
|||
} |
|||
|
|||
adapters.addSingleVal("regex", "pattern"); |
|||
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); |
|||
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); |
|||
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); |
|||
adapters.add("equalto", ["other"], function (options) { |
|||
var prefix = getModelPrefix(options.element.name), |
|||
other = options.params.other, |
|||
fullOtherName = appendModelPrefix(other, prefix), |
|||
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; |
|||
|
|||
setValidationValues(options, "equalTo", element); |
|||
}); |
|||
adapters.add("required", function (options) { |
|||
// jQuery Validate equates "required" with "mandatory" for checkbox elements
|
|||
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { |
|||
setValidationValues(options, "required", true); |
|||
} |
|||
}); |
|||
adapters.add("remote", ["url", "type", "additionalfields"], function (options) { |
|||
var value = { |
|||
url: options.params.url, |
|||
type: options.params.type || "GET", |
|||
data: {} |
|||
}, |
|||
prefix = getModelPrefix(options.element.name); |
|||
|
|||
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { |
|||
var paramName = appendModelPrefix(fieldName, prefix); |
|||
value.data[paramName] = function () { |
|||
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']"); |
|||
// For checkboxes and radio buttons, only pick up values from checked fields.
|
|||
if (field.is(":checkbox")) { |
|||
return field.filter(":checked").val() || field.filter(":hidden").val() || ''; |
|||
} |
|||
else if (field.is(":radio")) { |
|||
return field.filter(":checked").val() || ''; |
|||
} |
|||
return field.val(); |
|||
}; |
|||
}); |
|||
|
|||
setValidationValues(options, "remote", value); |
|||
}); |
|||
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { |
|||
if (options.params.min) { |
|||
setValidationValues(options, "minlength", options.params.min); |
|||
} |
|||
if (options.params.nonalphamin) { |
|||
setValidationValues(options, "nonalphamin", options.params.nonalphamin); |
|||
} |
|||
if (options.params.regex) { |
|||
setValidationValues(options, "regex", options.params.regex); |
|||
} |
|||
}); |
|||
|
|||
$(function () { |
|||
$jQval.unobtrusive.parse(document); |
|||
}); |
|||
}(jQuery)); |
|||
@ -0,0 +1,40 @@ |
|||
{ |
|||
"name": "jquery-validation", |
|||
"homepage": "http://jqueryvalidation.org/", |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "git://github.com/jzaefferer/jquery-validation.git" |
|||
}, |
|||
"authors": [ |
|||
"Jörn Zaefferer <joern.zaefferer@gmail.com>" |
|||
], |
|||
"description": "Form validation made easy", |
|||
"main": "dist/jquery.validate.js", |
|||
"keywords": [ |
|||
"forms", |
|||
"validation", |
|||
"validate" |
|||
], |
|||
"license": "MIT", |
|||
"ignore": [ |
|||
"**/.*", |
|||
"node_modules", |
|||
"bower_components", |
|||
"test", |
|||
"demo", |
|||
"lib" |
|||
], |
|||
"dependencies": { |
|||
"jquery": ">= 1.7.2" |
|||
}, |
|||
"version": "1.14.0", |
|||
"_release": "1.14.0", |
|||
"_resolution": { |
|||
"type": "version", |
|||
"tag": "1.14.0", |
|||
"commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48" |
|||
}, |
|||
"_source": "git://github.com/jzaefferer/jquery-validation.git", |
|||
"_target": ">=1.8", |
|||
"_originalSource": "jquery-validation" |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
The MIT License (MIT) |
|||
===================== |
|||
|
|||
Copyright Jörn Zaefferer |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in |
|||
all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
THE SOFTWARE. |
|||