├── .gitattributes ├── .gitignore ├── AspNetCoreServerSide ├── AspNetCoreServerSide.csproj ├── Contracts │ └── IDemoService.cs ├── Controllers │ └── HomeController.cs ├── Fingers10DbContext.cs ├── Helpers │ ├── EnumHelper.cs │ └── SplitHelper.cs ├── Infrastructure │ └── MappingProfile.cs ├── Migrations │ ├── 20200405103253_initial-create.Designer.cs │ ├── 20200405103253_initial-create.cs │ └── Fingers10DbContextModelSnapshot.cs ├── Models │ ├── Demo.cs │ ├── DemoEntity.cs │ ├── DemoNestedLevelOne.cs │ ├── DemoNestedLevelOneEntity.cs │ ├── DemoNestedLevelTwo.cs │ ├── DemoNestedLevelTwoEntity.cs │ └── Enum.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── SeedData.cs ├── Services │ └── DefaultDemoService.cs ├── Startup.cs ├── Views │ ├── Home │ │ ├── Index.cshtml │ │ ├── _Create.cshtml │ │ └── _Edit.cshtml │ └── _ViewImports.cshtml ├── appsettings.Development.json ├── appsettings.json ├── libman.json └── wwwroot │ ├── css │ └── app.css │ ├── favicon.png │ ├── images │ └── demo.gif │ ├── js │ └── app.js │ ├── lang │ └── fr.po │ └── lib │ ├── datatables │ ├── css │ │ ├── buttons.dataTables.min.css │ │ └── dataTables.bootstrap4.min.css │ ├── images │ │ ├── sort_asc.png │ │ ├── sort_asc_disabled.png │ │ ├── sort_both.png │ │ ├── sort_desc.png │ │ └── sort_desc_disabled.png │ └── js │ │ ├── dataTables.bootstrap4.min.js │ │ ├── dataTables.buttons.min.js │ │ └── jquery.dataTables.min.js │ ├── jquery │ └── jquery.min.js │ ├── momentjs │ └── moment.min.js │ └── twitter-bootstrap │ ├── css │ └── bootstrap.min.css │ └── js │ └── bootstrap.min.js ├── JqueryDataTablesServerSideDemo.sln ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /AspNetCoreServerSide/AspNetCoreServerSide.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netcoreapp3.1 4 | Latest 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Contracts/IDemoService.cs: -------------------------------------------------------------------------------- 1 | using AspNetCoreServerSide.Models; 2 | using JqueryDataTables.ServerSide.AspNetCoreWeb.Models; 3 | using System.Threading.Tasks; 4 | 5 | namespace AspNetCoreServerSide.Contracts 6 | { 7 | public interface IDemoService 8 | { 9 | Task> GetDataAsync(JqueryDataTablesParameters table); 10 | Task GetDataByIdAsync(int id); 11 | Task CreateDataAsync(Demo demo); 12 | Task UpdateDataAsync(Demo demo); 13 | Task DeleteDataAsync(int id); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using AspNetCoreServerSide.Contracts; 2 | using AspNetCoreServerSide.Models; 3 | using JqueryDataTables.ServerSide.AspNetCoreWeb.ActionResults; 4 | using JqueryDataTables.ServerSide.AspNetCoreWeb.Models; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Localization; 7 | using Microsoft.AspNetCore.Mvc; 8 | using System; 9 | using System.Text.Json; 10 | using System.Threading.Tasks; 11 | 12 | namespace AspNetCoreServerSide.Controllers 13 | { 14 | public class HomeController : Controller 15 | { 16 | private readonly IDemoService _demoService; 17 | 18 | public HomeController(IDemoService demoService) 19 | { 20 | _demoService = demoService; 21 | } 22 | 23 | public IActionResult Index() 24 | { 25 | return View(new Demo()); 26 | } 27 | 28 | //public async Task LoadTable([ModelBinder(typeof(JqueryDataTablesBinder))] JqueryDataTablesParameters param) 29 | //{ 30 | // try 31 | // { 32 | // var results = await _demoService.GetDataAsync(param); 33 | 34 | // return new JsonResult(new JqueryDataTablesResult 35 | // { 36 | // Draw = param.Draw, 37 | // Data = results.Items, 38 | // RecordsFiltered = results.TotalSize, 39 | // RecordsTotal = results.TotalSize 40 | // }); 41 | // } 42 | // catch (Exception e) 43 | // { 44 | // Console.Write(e.Message); 45 | // return new JsonResult(new { error = "Internal Server Error" }); 46 | // } 47 | //} 48 | 49 | //public async Task GetExcel([ModelBinder(typeof(JqueryDataTablesBinder))] JqueryDataTablesParameters param) 50 | //{ 51 | // var results = await _demoService.GetDataAsync(param); 52 | // return new JqueryDataTablesExcelResult(results.Items, "Demo Sheet Name", "Fingers10"); 53 | // return new JqueryDataTablesCSVResult(results.Items, "Fingers10"); 54 | //} 55 | 56 | [HttpPost] 57 | public async Task LoadTable([FromBody]JqueryDataTablesParameters param) 58 | { 59 | try 60 | { 61 | HttpContext.Session.SetString(nameof(JqueryDataTablesParameters), JsonSerializer.Serialize(param)); 62 | var results = await _demoService.GetDataAsync(param); 63 | 64 | return new JsonResult(new JqueryDataTablesResult 65 | { 66 | Draw = param.Draw, 67 | Data = results.Items, 68 | RecordsFiltered = results.TotalSize, 69 | RecordsTotal = results.TotalSize 70 | }); 71 | } 72 | catch (Exception e) 73 | { 74 | Console.Write(e.Message); 75 | return new JsonResult(new { error = "Internal Server Error" }); 76 | } 77 | } 78 | 79 | public async Task GetExcel() 80 | { 81 | var param = HttpContext.Session.GetString(nameof(JqueryDataTablesParameters)); 82 | 83 | var results = await _demoService.GetDataAsync(JsonSerializer.Deserialize(param)); 84 | return new JqueryDataTablesExcelResult(results.Items, "Demo Sheet Name", "Fingers10"); 85 | //return new JqueryDataTablesCSVResult(results.Items, "Fingers10"); 86 | } 87 | 88 | [HttpPost] 89 | public async Task Create(Demo item) 90 | { 91 | await _demoService.CreateDataAsync(item); 92 | 93 | return NoContent(); 94 | } 95 | 96 | public async Task Edit(int id) 97 | { 98 | var item = await _demoService.GetDataByIdAsync(id); 99 | 100 | return PartialView("_Edit", item); 101 | } 102 | 103 | [HttpPut] 104 | public async Task Edit(Demo item) 105 | { 106 | await _demoService.UpdateDataAsync(item); 107 | 108 | return NoContent(); 109 | } 110 | 111 | [HttpDelete] 112 | public async Task Delete(int id) 113 | { 114 | await _demoService.DeleteDataAsync(id); 115 | 116 | return NoContent(); 117 | } 118 | 119 | [HttpGet] 120 | public IActionResult SetLanguage(string culture, string returnUrl) 121 | { 122 | Response.Cookies.Append( 123 | CookieRequestCultureProvider.DefaultCookieName, 124 | CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), 125 | new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } 126 | ); 127 | 128 | return LocalRedirect(returnUrl); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Fingers10DbContext.cs: -------------------------------------------------------------------------------- 1 | using AspNetCoreServerSide.Models; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace AspNetCoreServerSide 5 | { 6 | public class Fingers10DbContext : DbContext 7 | { 8 | public Fingers10DbContext(DbContextOptions options) 9 | : base(options) { } 10 | 11 | public DbSet Demos { get; set; } 12 | 13 | protected override void OnModelCreating(ModelBuilder modelBuilder) 14 | { 15 | modelBuilder 16 | .Entity() 17 | .Property(e => e.Position) 18 | .HasColumnType("nvarchar(max)") 19 | .HasConversion(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Helpers/EnumHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Reflection; 6 | 7 | namespace AspNetCoreServerSide.Helpers 8 | { 9 | // Taken from Stackoveflow. 10 | // https://stackoverflow.com/questions/13099834/how-to-get-the-display-name-attribute-of-an-enum-member-via-mvc-razor-code 11 | 12 | public static class EnumHelper 13 | { 14 | public static IList GetValues(Enum value) 15 | { 16 | var enumValues = new List(); 17 | 18 | foreach (FieldInfo fi in value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public)) 19 | { 20 | enumValues.Add((T)Enum.Parse(value.GetType(), fi.Name, false)); 21 | } 22 | return enumValues; 23 | } 24 | 25 | public static T Parse(string value) 26 | { 27 | return (T)Enum.Parse(typeof(T), value, true); 28 | } 29 | 30 | public static IList GetNames(Enum value) 31 | { 32 | return value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public).Select(fi => fi.Name).ToList(); 33 | } 34 | 35 | public static IList GetDisplayValues(Enum value) 36 | { 37 | return GetNames(value).Select(obj => GetDisplayValue(Parse(obj))).ToList(); 38 | } 39 | 40 | private static string LookupResource(Type resourceManagerProvider, string resourceKey) 41 | { 42 | foreach (PropertyInfo staticProperty in resourceManagerProvider.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) 43 | { 44 | if (staticProperty.PropertyType == typeof(System.Resources.ResourceManager)) 45 | { 46 | System.Resources.ResourceManager resourceManager = (System.Resources.ResourceManager)staticProperty.GetValue(null, null); 47 | return resourceManager.GetString(resourceKey); 48 | } 49 | } 50 | 51 | return resourceKey; // Fallback with the key name 52 | } 53 | 54 | public static string GetDisplayValue(T value) 55 | { 56 | var fieldInfo = value.GetType().GetField(value.ToString()); 57 | 58 | var descriptionAttributes = fieldInfo.GetCustomAttributes( 59 | typeof(DisplayAttribute), false) as DisplayAttribute[]; 60 | 61 | if (descriptionAttributes[0].ResourceType != null) 62 | return LookupResource(descriptionAttributes[0].ResourceType, descriptionAttributes[0].Name); 63 | 64 | if (descriptionAttributes == null) return string.Empty; 65 | return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Name : value.ToString(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Helpers/SplitHelper.cs: -------------------------------------------------------------------------------- 1 | namespace AspNetCoreServerSide.Helpers 2 | { 3 | public static class SplitHelper 4 | { 5 | public static string Split(string value, char separator, int position) 6 | { 7 | return value.Split(separator)[position]; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Infrastructure/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | using AspNetCoreServerSide.Helpers; 2 | using AspNetCoreServerSide.Models; 3 | using AutoMapper; 4 | 5 | namespace AspNetCoreServerSide.Infrastructure 6 | { 7 | public class MappingProfile : Profile 8 | { 9 | public MappingProfile() 10 | { 11 | CreateMap() 12 | .ForMember(dest => dest.Name, opts => opts.MapFrom(src => $"{src.FirstName} {src.LastName}")) 13 | .ForMember(dest => dest.Position, opts => opts.MapFrom(src => EnumHelper.GetDisplayValue(src.Position))) 14 | .ForMember(dest => dest.Offices, opts => opts.MapFrom(src => src.Office)) 15 | .ReverseMap() 16 | .ForMember(dest => dest.FirstName, opts => opts.MapFrom(src => SplitHelper.Split(src.Name, ' ', 0))) 17 | .ForMember(dest => dest.LastName, opts => opts.MapFrom(src => SplitHelper.Split(src.Name, ' ', 1))); 18 | 19 | CreateMap() 20 | .ForMember(dest => dest.Extension, opts => opts.MapFrom(src => src.Extn)) 21 | .ForMember(dest => dest.DemoNestedLevelTwos, opts => opts.MapFrom(src => src.DemoNestedLevelTwo)) 22 | .ReverseMap(); 23 | 24 | CreateMap() 25 | .ForMember(dest => dest.StartDates, opts => opts.MapFrom(src => src.StartDate)) 26 | .ReverseMap(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Migrations/20200405103253_initial-create.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using AspNetCoreServerSide; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Migrations; 8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 9 | 10 | namespace AspNetCoreServerSide.Migrations 11 | { 12 | [DbContext(typeof(Fingers10DbContext))] 13 | [Migration("20200405103253_initial-create")] 14 | partial class initialcreate 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "3.1.3") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoEntity", b => 25 | { 26 | b.Property("Id") 27 | .ValueGeneratedOnAdd() 28 | .HasColumnType("int") 29 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 30 | 31 | b.Property("DemoNestedLevelOneId") 32 | .HasColumnType("int"); 33 | 34 | b.Property("FirstName") 35 | .HasColumnType("nvarchar(max)"); 36 | 37 | b.Property("LastName") 38 | .HasColumnType("nvarchar(max)"); 39 | 40 | b.Property("Office") 41 | .HasColumnType("nvarchar(max)"); 42 | 43 | b.Property("Position") 44 | .IsRequired() 45 | .HasColumnType("nvarchar(max)"); 46 | 47 | b.HasKey("Id"); 48 | 49 | b.HasIndex("DemoNestedLevelOneId"); 50 | 51 | b.ToTable("Demos"); 52 | }); 53 | 54 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoNestedLevelOneEntity", b => 55 | { 56 | b.Property("Id") 57 | .ValueGeneratedOnAdd() 58 | .HasColumnType("int") 59 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 60 | 61 | b.Property("DemoNestedLevelTwoId") 62 | .HasColumnType("int"); 63 | 64 | b.Property("Experience") 65 | .HasColumnType("smallint"); 66 | 67 | b.Property("Extn") 68 | .HasColumnType("int"); 69 | 70 | b.HasKey("Id"); 71 | 72 | b.HasIndex("DemoNestedLevelTwoId"); 73 | 74 | b.ToTable("DemoNestedLevelOneEntity"); 75 | }); 76 | 77 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoNestedLevelTwoEntity", b => 78 | { 79 | b.Property("Id") 80 | .ValueGeneratedOnAdd() 81 | .HasColumnType("int") 82 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 83 | 84 | b.Property("Salary") 85 | .HasColumnType("bigint"); 86 | 87 | b.Property("StartDate") 88 | .HasColumnType("datetime2"); 89 | 90 | b.HasKey("Id"); 91 | 92 | b.ToTable("DemoNestedLevelTwoEntity"); 93 | }); 94 | 95 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoEntity", b => 96 | { 97 | b.HasOne("AspNetCoreServerSide.Models.DemoNestedLevelOneEntity", "DemoNestedLevelOne") 98 | .WithMany() 99 | .HasForeignKey("DemoNestedLevelOneId"); 100 | }); 101 | 102 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoNestedLevelOneEntity", b => 103 | { 104 | b.HasOne("AspNetCoreServerSide.Models.DemoNestedLevelTwoEntity", "DemoNestedLevelTwo") 105 | .WithMany() 106 | .HasForeignKey("DemoNestedLevelTwoId"); 107 | }); 108 | #pragma warning restore 612, 618 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Migrations/20200405103253_initial-create.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace AspNetCoreServerSide.Migrations 5 | { 6 | public partial class initialcreate : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.CreateTable( 11 | name: "DemoNestedLevelTwoEntity", 12 | columns: table => new 13 | { 14 | Id = table.Column(nullable: false) 15 | .Annotation("SqlServer:Identity", "1, 1"), 16 | StartDate = table.Column(nullable: true), 17 | Salary = table.Column(nullable: true) 18 | }, 19 | constraints: table => 20 | { 21 | table.PrimaryKey("PK_DemoNestedLevelTwoEntity", x => x.Id); 22 | }); 23 | 24 | migrationBuilder.CreateTable( 25 | name: "DemoNestedLevelOneEntity", 26 | columns: table => new 27 | { 28 | Id = table.Column(nullable: false) 29 | .Annotation("SqlServer:Identity", "1, 1"), 30 | Experience = table.Column(nullable: true), 31 | Extn = table.Column(nullable: true), 32 | DemoNestedLevelTwoId = table.Column(nullable: true) 33 | }, 34 | constraints: table => 35 | { 36 | table.PrimaryKey("PK_DemoNestedLevelOneEntity", x => x.Id); 37 | table.ForeignKey( 38 | name: "FK_DemoNestedLevelOneEntity_DemoNestedLevelTwoEntity_DemoNestedLevelTwoId", 39 | column: x => x.DemoNestedLevelTwoId, 40 | principalTable: "DemoNestedLevelTwoEntity", 41 | principalColumn: "Id", 42 | onDelete: ReferentialAction.Restrict); 43 | }); 44 | 45 | migrationBuilder.CreateTable( 46 | name: "Demos", 47 | columns: table => new 48 | { 49 | Id = table.Column(nullable: false) 50 | .Annotation("SqlServer:Identity", "1, 1"), 51 | FirstName = table.Column(nullable: true), 52 | LastName = table.Column(nullable: true), 53 | Position = table.Column(nullable: false), 54 | Office = table.Column(nullable: true), 55 | DemoNestedLevelOneId = table.Column(nullable: true) 56 | }, 57 | constraints: table => 58 | { 59 | table.PrimaryKey("PK_Demos", x => x.Id); 60 | table.ForeignKey( 61 | name: "FK_Demos_DemoNestedLevelOneEntity_DemoNestedLevelOneId", 62 | column: x => x.DemoNestedLevelOneId, 63 | principalTable: "DemoNestedLevelOneEntity", 64 | principalColumn: "Id", 65 | onDelete: ReferentialAction.Restrict); 66 | }); 67 | 68 | migrationBuilder.CreateIndex( 69 | name: "IX_DemoNestedLevelOneEntity_DemoNestedLevelTwoId", 70 | table: "DemoNestedLevelOneEntity", 71 | column: "DemoNestedLevelTwoId"); 72 | 73 | migrationBuilder.CreateIndex( 74 | name: "IX_Demos_DemoNestedLevelOneId", 75 | table: "Demos", 76 | column: "DemoNestedLevelOneId"); 77 | } 78 | 79 | protected override void Down(MigrationBuilder migrationBuilder) 80 | { 81 | migrationBuilder.DropTable( 82 | name: "Demos"); 83 | 84 | migrationBuilder.DropTable( 85 | name: "DemoNestedLevelOneEntity"); 86 | 87 | migrationBuilder.DropTable( 88 | name: "DemoNestedLevelTwoEntity"); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Migrations/Fingers10DbContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using AspNetCoreServerSide; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | 9 | namespace AspNetCoreServerSide.Migrations 10 | { 11 | [DbContext(typeof(Fingers10DbContext))] 12 | partial class Fingers10DbContextModelSnapshot : ModelSnapshot 13 | { 14 | protected override void BuildModel(ModelBuilder modelBuilder) 15 | { 16 | #pragma warning disable 612, 618 17 | modelBuilder 18 | .HasAnnotation("ProductVersion", "3.1.3") 19 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 21 | 22 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoEntity", b => 23 | { 24 | b.Property("Id") 25 | .ValueGeneratedOnAdd() 26 | .HasColumnType("int") 27 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 28 | 29 | b.Property("DemoNestedLevelOneId") 30 | .HasColumnType("int"); 31 | 32 | b.Property("FirstName") 33 | .HasColumnType("nvarchar(max)"); 34 | 35 | b.Property("LastName") 36 | .HasColumnType("nvarchar(max)"); 37 | 38 | b.Property("Office") 39 | .HasColumnType("nvarchar(max)"); 40 | 41 | b.Property("Position") 42 | .IsRequired() 43 | .HasColumnType("nvarchar(max)"); 44 | 45 | b.HasKey("Id"); 46 | 47 | b.HasIndex("DemoNestedLevelOneId"); 48 | 49 | b.ToTable("Demos"); 50 | }); 51 | 52 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoNestedLevelOneEntity", b => 53 | { 54 | b.Property("Id") 55 | .ValueGeneratedOnAdd() 56 | .HasColumnType("int") 57 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 58 | 59 | b.Property("DemoNestedLevelTwoId") 60 | .HasColumnType("int"); 61 | 62 | b.Property("Experience") 63 | .HasColumnType("smallint"); 64 | 65 | b.Property("Extn") 66 | .HasColumnType("int"); 67 | 68 | b.HasKey("Id"); 69 | 70 | b.HasIndex("DemoNestedLevelTwoId"); 71 | 72 | b.ToTable("DemoNestedLevelOneEntity"); 73 | }); 74 | 75 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoNestedLevelTwoEntity", b => 76 | { 77 | b.Property("Id") 78 | .ValueGeneratedOnAdd() 79 | .HasColumnType("int") 80 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 81 | 82 | b.Property("Salary") 83 | .HasColumnType("bigint"); 84 | 85 | b.Property("StartDate") 86 | .HasColumnType("datetime2"); 87 | 88 | b.HasKey("Id"); 89 | 90 | b.ToTable("DemoNestedLevelTwoEntity"); 91 | }); 92 | 93 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoEntity", b => 94 | { 95 | b.HasOne("AspNetCoreServerSide.Models.DemoNestedLevelOneEntity", "DemoNestedLevelOne") 96 | .WithMany() 97 | .HasForeignKey("DemoNestedLevelOneId"); 98 | }); 99 | 100 | modelBuilder.Entity("AspNetCoreServerSide.Models.DemoNestedLevelOneEntity", b => 101 | { 102 | b.HasOne("AspNetCoreServerSide.Models.DemoNestedLevelTwoEntity", "DemoNestedLevelTwo") 103 | .WithMany() 104 | .HasForeignKey("DemoNestedLevelTwoId"); 105 | }); 106 | #pragma warning restore 612, 618 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Models/Demo.cs: -------------------------------------------------------------------------------- 1 | using Fingers10.ExcelExport.Attributes; 2 | using JqueryDataTables.ServerSide.AspNetCoreWeb.Attributes; 3 | using System.ComponentModel.DataAnnotations; 4 | 5 | namespace AspNetCoreServerSide.Models 6 | { 7 | public class Demo 8 | { 9 | public Demo() 10 | { 11 | DemoNestedLevelOne = new DemoNestedLevelOne(); 12 | } 13 | 14 | [JqueryDataTableColumn(Order = 1)] 15 | public int Id { get; set; } 16 | 17 | [IncludeInReport(Order = 1)] 18 | [JqueryDataTableColumn(Order = 2)] 19 | [SearchableString(EntityProperty = "FirstName,LastName")] 20 | [Sortable(EntityProperty = "FirstName,LastName", Default = true)] 21 | public string Name { get; set; } 22 | 23 | [JqueryDataTableColumn(Exclude = true)] 24 | public string FirstName { get; set; } 25 | 26 | [JqueryDataTableColumn(Exclude = true)] 27 | public string LastName { get; set; } 28 | 29 | [IncludeInReport(Order = 2)] 30 | [JqueryDataTableColumn(Order = 3)] 31 | [SearchableEnum(typeof(Position))] 32 | [Sortable] 33 | public string Position { get; set; } 34 | 35 | [Display(Name = "Office")] 36 | [IncludeInReport(Order = 3)] 37 | [JqueryDataTableColumn(Order = 4)] 38 | [SearchableString(EntityProperty = "Office")] 39 | [Sortable(EntityProperty = "Office")] 40 | public string Offices { get; set; } 41 | 42 | [NestedIncludeInReport] 43 | [NestedSearchable] 44 | [NestedSortable] 45 | public DemoNestedLevelOne DemoNestedLevelOne { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Models/DemoEntity.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Metadata.Internal; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace AspNetCoreServerSide.Models 5 | { 6 | public class DemoEntity 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | public string FirstName { get; set; } 11 | public string LastName { get; set; } 12 | public Position Position { get; set; } 13 | public string Office { get; set; } 14 | 15 | public DemoNestedLevelOneEntity DemoNestedLevelOne { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Models/DemoNestedLevelOne.cs: -------------------------------------------------------------------------------- 1 | using Fingers10.ExcelExport.Attributes; 2 | using JqueryDataTables.ServerSide.AspNetCoreWeb.Attributes; 3 | using System.ComponentModel; 4 | 5 | namespace AspNetCoreServerSide.Models 6 | { 7 | public class DemoNestedLevelOne 8 | { 9 | public DemoNestedLevelOne() 10 | { 11 | DemoNestedLevelTwos = new DemoNestedLevelTwo(); 12 | } 13 | 14 | [IncludeInReport(Order = 4)] 15 | [JqueryDataTableColumn(Order = 5)] 16 | [SearchableShort] 17 | [Sortable] 18 | public short? Experience { get; set; } 19 | 20 | [DisplayName("Extn")] 21 | [IncludeInReport(Order = 5)] 22 | [JqueryDataTableColumn(Order = 6)] 23 | [SearchableInt(EntityProperty = "Extn")] 24 | [Sortable(EntityProperty = "Extn")] 25 | public int? Extension { get; set; } 26 | 27 | [NestedIncludeInReport] 28 | [NestedSearchable(ParentEntityProperty = "DemoNestedLevelTwo")] 29 | [NestedSortable(ParentEntityProperty = "DemoNestedLevelTwo")] 30 | public DemoNestedLevelTwo DemoNestedLevelTwos { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Models/DemoNestedLevelOneEntity.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace AspNetCoreServerSide.Models 4 | { 5 | public class DemoNestedLevelOneEntity 6 | { 7 | [Key] 8 | public int Id { get; set; } 9 | 10 | public short? Experience { get; set; } 11 | public int? Extn { get; set; } 12 | 13 | public DemoNestedLevelTwoEntity DemoNestedLevelTwo { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Models/DemoNestedLevelTwo.cs: -------------------------------------------------------------------------------- 1 | using Fingers10.ExcelExport.Attributes; 2 | using JqueryDataTables.ServerSide.AspNetCoreWeb.Attributes; 3 | using System; 4 | using System.ComponentModel; 5 | 6 | namespace AspNetCoreServerSide.Models 7 | { 8 | public class DemoNestedLevelTwo 9 | { 10 | [DisplayName("Start Date")] 11 | [IncludeInReport(Order = 6)] 12 | [JqueryDataTableColumn(Order = 7)] 13 | [SearchableDateTime(EntityProperty = "StartDate")] 14 | [Sortable(EntityProperty = "StartDate")] 15 | public DateTime? StartDates { get; set; } 16 | 17 | [IncludeInReport(Order = 7)] 18 | [JqueryDataTableColumn(Order = 8)] 19 | [SearchableLong] 20 | [Sortable] 21 | public long? Salary { get; set; } 22 | 23 | [JqueryDataTableColumn(Order = 9)] 24 | public string Action { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Models/DemoNestedLevelTwoEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace AspNetCoreServerSide.Models 5 | { 6 | public class DemoNestedLevelTwoEntity 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | 11 | public DateTime? StartDate { get; set; } 12 | public long? Salary { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Models/Enum.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace AspNetCoreServerSide.Models 4 | { 5 | public enum Position 6 | { 7 | [Display(Name = "Accountant")] 8 | Accountant, 9 | [Display(Name = "Chief Executive Officer (CEO)")] 10 | ChiefExecutiveOfficer, 11 | [Display(Name = "Integration Specialist")] 12 | IntegrationSpecialist, 13 | [Display(Name = "Junior Technical Author")] 14 | JuniorTechnicalAuthor, 15 | [Display(Name = "Pre Sales Support")] 16 | PreSalesSupport, 17 | [Display(Name = "Sales Assistant")] 18 | SalesAssistant, 19 | [Display(Name = "Senior Javascript Developer")] 20 | SeniorJavascriptDeveloper, 21 | [Display(Name = "Software Engineer")] 22 | SoftwareEngineer 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Hosting; 5 | using Microsoft.Extensions.Logging; 6 | using System; 7 | using System.Threading.Tasks; 8 | 9 | namespace AspNetCoreServerSide 10 | { 11 | public class Program 12 | { 13 | public async static Task Main(string[] args) 14 | { 15 | var host = CreateHostBuilder(args).Build(); 16 | await InitializeDatabase(host); 17 | host.Run(); 18 | } 19 | 20 | public static IHostBuilder CreateHostBuilder(string[] args) => 21 | Host.CreateDefaultBuilder(args) 22 | .ConfigureWebHostDefaults(webBuilder => 23 | { 24 | webBuilder.ConfigureKestrel(serverOptions => 25 | { 26 | // Set properties and call methods on options 27 | }) 28 | .UseStartup(); 29 | }); 30 | 31 | private async static Task InitializeDatabase(IHost host) 32 | { 33 | using var scope = host.Services.CreateScope(); 34 | var services = scope.ServiceProvider; 35 | 36 | try 37 | { 38 | var finger10Context = services.GetRequiredService(); 39 | await finger10Context.Database.MigrateAsync(); 40 | SeedData.InitializeAsync(services).Wait(); 41 | } 42 | catch (Exception ex) 43 | { 44 | var logger = services.GetRequiredService>(); 45 | logger.LogError(ex, "An error occurred seeding the database."); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:50313", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "AspNetCoreServerSide": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /AspNetCoreServerSide/SeedData.cs: -------------------------------------------------------------------------------- 1 | using AspNetCoreServerSide.Models; 2 | using Microsoft.EntityFrameworkCore.Internal; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace AspNetCoreServerSide 10 | { 11 | public static class SeedData 12 | { 13 | public static async Task InitializeAsync(IServiceProvider services) 14 | { 15 | await AddTestData( 16 | services.GetRequiredService()); 17 | } 18 | 19 | public static async Task AddTestData(Fingers10DbContext context) 20 | { 21 | if (context.Demos.Any()) 22 | { 23 | // Already has data 24 | return; 25 | } 26 | 27 | var testData = new List() 28 | { 29 | new DemoEntity { 30 | FirstName = "Airi", 31 | LastName = "Satou", 32 | Position = Position.Accountant, 33 | Office = "Tokyo", 34 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 35 | { 36 | Experience = null, 37 | Extn = null, 38 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 39 | { 40 | StartDate = null, 41 | Salary = null 42 | } 43 | } 44 | }, 45 | new DemoEntity { 46 | FirstName = "Angelica", 47 | LastName = "Ramos", 48 | Position = Position.ChiefExecutiveOfficer, 49 | Office = "London", 50 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 51 | { 52 | Experience = 1, 53 | Extn = 5797, 54 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 55 | { 56 | StartDate = new DateTime(2009,10,09), 57 | Salary = 1200000 58 | } 59 | } 60 | }, 61 | new DemoEntity { 62 | FirstName = "Ashton", 63 | LastName = "Cox", 64 | Position = Position.JuniorTechnicalAuthor, 65 | Office = "San Francisco", 66 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 67 | { 68 | Experience = 2, 69 | Extn = 1562, 70 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 71 | { 72 | StartDate = new DateTime(2009,01,12), 73 | Salary = 86000 74 | } 75 | } 76 | }, 77 | new DemoEntity { 78 | FirstName = "Bradley", 79 | LastName = "Greer", 80 | Position = Position.SoftwareEngineer, 81 | Office = "London", 82 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 83 | { 84 | Experience = 3, 85 | Extn = 2558, 86 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 87 | { 88 | StartDate = new DateTime(2012,10,13), 89 | Salary = 132000 90 | } 91 | } 92 | }, 93 | new DemoEntity { 94 | FirstName = "Brenden", 95 | LastName = "Wagner", 96 | Position = Position.SoftwareEngineer, 97 | Office = "San Francisco", 98 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 99 | { 100 | Experience = 4, 101 | Extn = 1314, 102 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 103 | { 104 | StartDate = new DateTime(2011,06,07), 105 | Salary = 206850 106 | } 107 | } 108 | }, 109 | new DemoEntity { 110 | FirstName = "Brielle", 111 | LastName = "Williamson", 112 | Position = Position.IntegrationSpecialist, 113 | Office = "New York", 114 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 115 | { 116 | Experience = 5, 117 | Extn = 4804, 118 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 119 | { 120 | StartDate = new DateTime(2012,12,02), 121 | Salary = 372000 122 | } 123 | } 124 | }, 125 | new DemoEntity { 126 | FirstName = "Bruno", 127 | LastName = "Nash", 128 | Position = Position.SoftwareEngineer, 129 | Office = "London", 130 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 131 | { 132 | Experience = 6, 133 | Extn = 6222, 134 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 135 | { 136 | StartDate = new DateTime(2011,05,03), 137 | Salary = 163500 138 | } 139 | } 140 | }, 141 | new DemoEntity { 142 | FirstName = "Caesar", 143 | LastName = "Vance", 144 | Position = Position.PreSalesSupport, 145 | Office = "New York", 146 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 147 | { 148 | Experience = 7, 149 | Extn = 8330, 150 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 151 | { 152 | StartDate = new DateTime(2011,12,12), 153 | Salary = 106450 154 | } 155 | } 156 | }, 157 | new DemoEntity { 158 | FirstName = "Cara", 159 | LastName = "Stevens", 160 | Position = Position.SalesAssistant, 161 | Office = "New York", 162 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 163 | { 164 | Experience = 8, 165 | Extn = 3990, 166 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 167 | { 168 | StartDate = new DateTime(2011,12,06), 169 | Salary = 145600 170 | } 171 | } 172 | }, 173 | new DemoEntity { 174 | FirstName = "Cedric", 175 | LastName = "Kelly", 176 | Position = Position.SeniorJavascriptDeveloper, 177 | Office = "Edinburgh", 178 | DemoNestedLevelOne = new DemoNestedLevelOneEntity 179 | { 180 | Experience = 9, 181 | Extn = 6224, 182 | DemoNestedLevelTwo = new DemoNestedLevelTwoEntity 183 | { 184 | StartDate = new DateTime(2012,03,29), 185 | Salary = 433060 186 | } 187 | } 188 | } 189 | }; 190 | 191 | context.Demos.AddRange(testData); 192 | 193 | await context.SaveChangesAsync(); 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Services/DefaultDemoService.cs: -------------------------------------------------------------------------------- 1 | using AspNetCoreServerSide.Contracts; 2 | using AspNetCoreServerSide.Models; 3 | using AutoMapper; 4 | using AutoMapper.QueryableExtensions; 5 | using JqueryDataTables.ServerSide.AspNetCoreWeb.Infrastructure; 6 | using JqueryDataTables.ServerSide.AspNetCoreWeb.Models; 7 | using Microsoft.EntityFrameworkCore; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | 11 | namespace AspNetCoreServerSide.Services 12 | { 13 | public class DefaultDemoService : IDemoService 14 | { 15 | private readonly Fingers10DbContext _context; 16 | private readonly IConfigurationProvider _mappingConfiguration; 17 | 18 | public DefaultDemoService(Fingers10DbContext context, IConfigurationProvider mappingConfiguration) 19 | { 20 | _context = context; 21 | _mappingConfiguration = mappingConfiguration; 22 | } 23 | 24 | public async Task> GetDataAsync(JqueryDataTablesParameters table) 25 | { 26 | Demo[] items = null; 27 | IQueryable query = _context.Demos 28 | .AsNoTracking() 29 | .Include(x => x.DemoNestedLevelOne) 30 | .ThenInclude(y => y.DemoNestedLevelTwo); 31 | 32 | query = SearchOptionsProcessor.Apply(query, table.Columns); 33 | query = SortOptionsProcessor.Apply(query, table); 34 | 35 | var size = await query.CountAsync(); 36 | 37 | if (table.Length > 0) 38 | { 39 | items = await query 40 | .Skip((table.Start / table.Length) * table.Length) 41 | .Take(table.Length) 42 | .ProjectTo(_mappingConfiguration) 43 | .ToArrayAsync(); 44 | } 45 | else 46 | { 47 | items = await query 48 | .ProjectTo(_mappingConfiguration) 49 | .ToArrayAsync(); 50 | } 51 | 52 | return new JqueryDataTablesPagedResults 53 | { 54 | Items = items, 55 | TotalSize = size 56 | }; 57 | } 58 | 59 | public async Task GetDataByIdAsync(int id) 60 | { 61 | var item = await _context.Demos.AsNoTracking() 62 | .Include(x => x.DemoNestedLevelOne) 63 | .ThenInclude(y => y.DemoNestedLevelTwo) 64 | .SingleOrDefaultAsync(x => x.Id.Equals(id)); 65 | 66 | return _mappingConfiguration.CreateMapper().Map(item); 67 | } 68 | 69 | public async Task CreateDataAsync(Demo demo) 70 | { 71 | var entity = _mappingConfiguration.CreateMapper().Map(demo); 72 | 73 | await _context.Demos.AddAsync(entity); 74 | await _context.SaveChangesAsync(); 75 | } 76 | 77 | public async Task UpdateDataAsync(Demo demo) 78 | { 79 | var entity = await _context.Demos.AsNoTracking() 80 | .Include(x => x.DemoNestedLevelOne) 81 | .ThenInclude(y => y.DemoNestedLevelTwo) 82 | .SingleOrDefaultAsync(x => x.Id.Equals(demo.Id)); 83 | 84 | entity = _mappingConfiguration.CreateMapper().Map(demo, entity); 85 | 86 | _context.Demos.Update(entity); 87 | await _context.SaveChangesAsync(); 88 | } 89 | 90 | public async Task DeleteDataAsync(int id) 91 | { 92 | var item = await _context.Demos.FindAsync(id); 93 | 94 | _context.Demos.Remove(item); 95 | await _context.SaveChangesAsync(); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Startup.cs: -------------------------------------------------------------------------------- 1 | using AspNetCoreServerSide.Contracts; 2 | using AspNetCoreServerSide.Services; 3 | using AutoMapper; 4 | using Microsoft.AspNetCore.Builder; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.AspNetCore.Localization; 7 | using Microsoft.AspNetCore.Mvc.Razor; 8 | using Microsoft.EntityFrameworkCore; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.Extensions.Hosting; 11 | using System.Collections.Generic; 12 | using System.Globalization; 13 | using System.Text.Json.Serialization; 14 | 15 | namespace AspNetCoreServerSide 16 | { 17 | public class Startup 18 | { 19 | // This method gets called by the runtime. Use this method to add services to the container. 20 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 21 | public void ConfigureServices(IServiceCollection services) 22 | { 23 | services.AddScoped(); 24 | 25 | // Use in-memory database for quick dev and testing 26 | services.AddDbContext( 27 | options => 28 | { 29 | //options.UseInMemoryDatabase("fingers10db"); 30 | options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=JqueryDataTablesAspNetServerSide;Trusted_Connection=True;MultipleActiveResultSets=true"); 31 | }); 32 | 33 | // Set the languages you want to support in your app. 34 | services.Configure(options => 35 | { 36 | var ciEn = new CultureInfo("en"); 37 | var ciFr = new CultureInfo("fr"); 38 | var supportedCultures = new List 39 | { 40 | ciEn, 41 | ciFr 42 | }; 43 | 44 | options.DefaultRequestCulture = new RequestCulture("en"); 45 | options.SupportedCultures = supportedCultures; 46 | options.SupportedUICultures = supportedCultures; 47 | }); 48 | services.AddPortableObjectLocalization(options => options.ResourcesPath = "wwwroot/lang"); 49 | 50 | services.AddControllersWithViews() 51 | //.AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver()); 52 | .AddJsonOptions(options => 53 | { 54 | options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); 55 | options.JsonSerializerOptions.PropertyNamingPolicy = null; 56 | }) 57 | // Add those 2 functions to support localization 58 | .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) 59 | .AddDataAnnotationsLocalization();; 60 | 61 | services.AddSession(); 62 | services.AddAutoMapper(typeof(Startup)); 63 | } 64 | 65 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 66 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 67 | { 68 | if (env.IsDevelopment()) 69 | { 70 | app.UseDeveloperExceptionPage(); 71 | } 72 | 73 | app.UseRouting(); 74 | app.UseStaticFiles(); 75 | app.UseSession(); 76 | //To use the localization in your app 77 | app.UseRequestLocalization(); 78 | 79 | app.UseEndpoints(endpoints => 80 | { 81 | endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); 82 | }); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model AspNetCoreServerSide.Models.Demo 2 | @{ 3 | Layout = null; 4 | var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}"; 5 | 6 | var requestCulture = Context.Features.Get(); 7 | var langFileUrl = string.Empty; 8 | if (requestCulture.RequestCulture.UICulture.Name == "en") 9 | { 10 | langFileUrl = "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/English.json"; 11 | } 12 | else 13 | { 14 | langFileUrl = "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/French.json"; 15 | } 16 | } 17 | 18 | 19 | 20 | 21 | 22 | 23 | Jquery DataTables - Asp.Net Core Server Side 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | @Html.AntiForgeryToken(); 32 | 33 |
34 |
35 |
36 | @Localizer["Choose your language"] 37 |
38 |
39 | English 40 |
41 |
42 | Français 43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |

@Localizer["Asp.Net Core - Jquery DataTables Server Side Multi Column Filtering And Ordering With Pagination And Excel Export Demo."]

51 |
52 |
53 |
54 | 55 |
56 | 57 |
58 |
59 | 60 | 70 | 71 | 72 | 73 |
74 |
75 | 78 |
79 |
80 |
81 |
82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 97 | 98 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Views/Home/_Create.cshtml: -------------------------------------------------------------------------------- 1 | @model Demo 2 | 3 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Views/Home/_Edit.cshtml: -------------------------------------------------------------------------------- 1 | @model Demo 2 | 3 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Mvc.Localization 2 | @inject IViewLocalizer Localizer 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | @addTagHelper *, JqueryDataTables.ServerSide.AspNetCoreWeb 5 | @using AspNetCoreServerSide.Models -------------------------------------------------------------------------------- /AspNetCoreServerSide/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "defaultProvider": "cdnjs", 4 | "libraries": [ 5 | { 6 | "library": "jquery@3.3.1", 7 | "destination": "wwwroot/lib/jquery/", 8 | "files": [ 9 | "jquery.min.js" 10 | ] 11 | }, 12 | { 13 | "library": "moment.js@2.23.0", 14 | "destination": "wwwroot/lib/momentjs/", 15 | "files": [ 16 | "moment.min.js" 17 | ] 18 | }, 19 | { 20 | "library": "twitter-bootstrap@4.2.1", 21 | "destination": "wwwroot/lib/twitter-bootstrap/", 22 | "files": [ 23 | "js/bootstrap.min.js", 24 | "css/bootstrap.min.css" 25 | ] 26 | }, 27 | { 28 | "library": "datatables@1.10.19", 29 | "destination": "wwwroot/lib/datatables/", 30 | "files": [ 31 | "js/jquery.dataTables.min.js", 32 | "images/sort_asc.png", 33 | "images/sort_asc_disabled.png", 34 | "images/sort_both.png", 35 | "images/sort_desc.png", 36 | "images/sort_desc_disabled.png", 37 | "css/dataTables.bootstrap4.min.css", 38 | "js/dataTables.bootstrap4.min.js" 39 | ] 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/css/app.css: -------------------------------------------------------------------------------- 1 | .page-item.active .page-link { 2 | background-color: black; 3 | border-color: black; 4 | } 5 | 6 | .page-link, 7 | .page-link:hover { 8 | color: black; 9 | } 10 | 11 | .page-link:focus { 12 | box-shadow: none; 13 | } 14 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingers10/JqueryDataTablesServerSideDemo/a2a586a92639bbebd273f114ba4ec7dc4fc1d1c4/AspNetCoreServerSide/wwwroot/favicon.png -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingers10/JqueryDataTablesServerSideDemo/a2a586a92639bbebd273f114ba4ec7dc4fc1d1c4/AspNetCoreServerSide/wwwroot/images/demo.gif -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/js/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | $(() => { 4 | if ($('#fingers10').length !== 0) { 5 | var table = $('#fingers10').DataTable({ 6 | language: { 7 | url: langFileUrl 8 | }, 9 | processing: true, 10 | serverSide: true, 11 | orderCellsTop: true, 12 | autoWidth: true, 13 | deferRender: true, 14 | lengthMenu: [[5, 10, 15, 20, -1], [5, 10, 15, 20, "All"]], 15 | dom: '<"row"<"col-sm-12 col-md-6"B><"col-sm-12 col-md-6 text-right"l>><"row"<"col-sm-12"tr>><"row"<"col-sm-12 col-md-5"i><"col-sm-12 col-md-7"p>>', 16 | buttons: [ 17 | { 18 | text: exportToExcelText, 19 | className: 'btn btn-sm btn-dark', 20 | action: function (e, dt, node, config) { 21 | window.location.href = "/Home/GetExcel"; 22 | }, 23 | init: function (api, node, config) { 24 | $(node).removeClass('dt-button'); 25 | } 26 | }, 27 | { 28 | text: createText, 29 | className: 'btn btn-sm btn-success', 30 | action: function (e, dt, node, config) { 31 | $('#createModal').modal('show'); 32 | }, 33 | init: function (api, node, config) { 34 | $(node).removeClass('dt-button'); 35 | } 36 | } 37 | ], 38 | ajax: { 39 | type: "POST", 40 | url: '/Home/LoadTable/', 41 | contentType: "application/json; charset=utf-8", 42 | async: true, 43 | headers: { 44 | "XSRF-TOKEN": document.querySelector('[name="__RequestVerificationToken"]').value 45 | }, 46 | data: function (data) { 47 | let additionalValues = []; 48 | additionalValues[0] = "Additional Parameters 1"; 49 | additionalValues[1] = "Additional Parameters 2"; 50 | data.AdditionalValues = additionalValues; 51 | 52 | return JSON.stringify(data); 53 | } 54 | }, 55 | columns: [ 56 | { 57 | data: "Id", 58 | name: "eq", 59 | visible: false, 60 | searchable: false, 61 | orderable: false 62 | }, 63 | { 64 | data: "Name", 65 | name: "co" 66 | }, 67 | { 68 | data: "Position", 69 | name: "co" 70 | }, 71 | { 72 | data: "Offices", 73 | name: "eq" 74 | }, 75 | { 76 | data: "DemoNestedLevelOne.Experience", 77 | name: "eq" 78 | }, 79 | { 80 | data: "DemoNestedLevelOne.Extension", 81 | name: "eq" 82 | }, 83 | { 84 | data: "DemoNestedLevelOne.DemoNestedLevelTwos.StartDates", 85 | render: function (data, type, row) { 86 | if (data) 87 | return window.moment(data).format("DD/MM/YYYY"); 88 | else 89 | return null; 90 | }, 91 | name: "gt" 92 | }, 93 | { 94 | data: "DemoNestedLevelOne.DemoNestedLevelTwos.Salary", 95 | name: "lte" 96 | }, 97 | { 98 | orderable: false, 99 | width: 100, 100 | data: "DemoNestedLevelOne.DemoNestedLevelTwos.Action", 101 | render: function (data, type, row) { 102 | return `
103 | 104 | 105 |
`; 106 | } 107 | } 108 | ] 109 | }); 110 | 111 | table.columns().every(function (index) { 112 | $('#fingers10 thead tr:last th:eq(' + index + ') input') 113 | .on('keyup', 114 | function (e) { 115 | if (e.keyCode === 13) { 116 | table.column($(this).parent().index() + ':visible').search(this.value).draw(); 117 | } 118 | }); 119 | }); 120 | 121 | $(document) 122 | .off('click', '#btnCreate') 123 | .on('click', '#btnCreate', function () { 124 | fetch('/Home/Create/', 125 | { 126 | method: 'POST', 127 | cache: 'no-cache', 128 | body: new URLSearchParams(new FormData(document.querySelector('#frmCreate'))) 129 | }) 130 | .then((response) => { 131 | table.ajax.reload(); 132 | $('#createModal').modal('hide'); 133 | document.querySelector('#frmCreate').reset(); 134 | }) 135 | .catch((error) => { 136 | console.log(error); 137 | }); 138 | }); 139 | 140 | $(document) 141 | .off('click', '.btnEdit') 142 | .on('click', '.btnEdit', function () { 143 | const id = $(this).attr('data-key'); 144 | 145 | fetch(`/Home/Edit/${id}`, 146 | { 147 | method: 'GET', 148 | cache: 'no-cache' 149 | }) 150 | .then((response) => { 151 | return response.text(); 152 | }) 153 | .then((result) => { 154 | $('#editPartial').html(result); 155 | $('#editModal').modal('show'); 156 | }) 157 | .catch((error) => { 158 | console.log(error); 159 | }); 160 | }); 161 | 162 | $(document) 163 | .off('click', '#btnUpdate') 164 | .on('click', '#btnUpdate', function () { 165 | fetch('/Home/Edit/', 166 | { 167 | method: 'PUT', 168 | cache: 'no-cache', 169 | body: new URLSearchParams(new FormData(document.querySelector('#frmEdit'))) 170 | }) 171 | .then((response) => { 172 | table.ajax.reload(); 173 | $('#editModal').modal('hide'); 174 | $('#editPartial').html(''); 175 | }) 176 | .catch((error) => { 177 | console.log(error); 178 | }); 179 | }); 180 | 181 | $(document) 182 | .off('click', '.btnDelete') 183 | .on('click', '.btnDelete', function () { 184 | const id = $(this).attr('data-key'); 185 | 186 | if (confirm('Are you sure?')) { 187 | fetch(`/Home/Delete/${id}`, 188 | { 189 | method: 'DELETE', 190 | cache: 'no-cache' 191 | }) 192 | .then((response) => { 193 | table.ajax.reload(); 194 | }) 195 | .catch((error) => { 196 | console.log(error); 197 | }); 198 | } 199 | }); 200 | 201 | $('#btnExternalSearch').click(function () { 202 | table.column('0:visible').search($('#txtExternalSearch').val()).draw(); 203 | }); 204 | } 205 | }); -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lang/fr.po: -------------------------------------------------------------------------------- 1 | msgid "Asp.Net Core - Jquery DataTables Server Side Multi Column Filtering And Ordering With Pagination And Excel Export Demo." 2 | msgstr "Asp.Net Core - Jquery Filtrage et classement multi-colonnes côté serveur DataTables avec pagination et démonstration d'exportation Excel" 3 | 4 | msgid "Choose your language" 5 | msgstr "Choisissez votre langue" 6 | 7 | msgid "Create" 8 | msgstr "Créer" 9 | 10 | msgid "Delete" 11 | msgstr "Supprimer" 12 | 13 | msgid "Demo By" 14 | msgstr "Démo par" 15 | 16 | msgid "Edit" 17 | msgstr "Modifier" 18 | 19 | msgid "Experience" 20 | msgstr "Expérience" 21 | 22 | msgid "Export to Excel" 23 | msgstr "Exporter vers Excel" 24 | 25 | msgid "External Search" 26 | msgstr "Recherche externe" 27 | 28 | msgid "Name" 29 | msgstr "Nom" 30 | 31 | msgid "Office" 32 | msgstr "Bureau" 33 | 34 | msgid "Position" 35 | msgstr "Position" 36 | 37 | msgid "Salary" 38 | msgstr "Salaire" 39 | 40 | msgid "Search" 41 | msgstr "Rechercher" 42 | 43 | msgid "Start Date" 44 | msgstr "Date début" 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/css/buttons.dataTables.min.css: -------------------------------------------------------------------------------- 1 | @keyframes dtb-spinner { 2 | 100% { 3 | transform: rotate(360deg) 4 | } 5 | } 6 | 7 | @-o-keyframes dtb-spinner { 8 | 100% { 9 | -o-transform: rotate(360deg); 10 | transform: rotate(360deg) 11 | } 12 | } 13 | 14 | @-ms-keyframes dtb-spinner { 15 | 100% { 16 | -ms-transform: rotate(360deg); 17 | transform: rotate(360deg) 18 | } 19 | } 20 | 21 | @-webkit-keyframes dtb-spinner { 22 | 100% { 23 | -webkit-transform: rotate(360deg); 24 | transform: rotate(360deg) 25 | } 26 | } 27 | 28 | @-moz-keyframes dtb-spinner { 29 | 100% { 30 | -moz-transform: rotate(360deg); 31 | transform: rotate(360deg) 32 | } 33 | } 34 | 35 | div.dt-button-info { 36 | position: fixed; 37 | top: 50%; 38 | left: 50%; 39 | width: 400px; 40 | margin-top: -100px; 41 | margin-left: -200px; 42 | background-color: white; 43 | border: 2px solid #111; 44 | box-shadow: 3px 3px 8px rgba(0,0,0,0.3); 45 | border-radius: 3px; 46 | text-align: center; 47 | z-index: 21 48 | } 49 | 50 | div.dt-button-info h2 { 51 | padding: 0.5em; 52 | margin: 0; 53 | font-weight: normal; 54 | border-bottom: 1px solid #ddd; 55 | background-color: #f3f3f3 56 | } 57 | 58 | div.dt-button-info > div { 59 | padding: 1em 60 | } 61 | 62 | div.dt-button-collection-title { 63 | text-align: center; 64 | padding: 0.3em 0 0.5em; 65 | font-size: 0.9em 66 | } 67 | 68 | div.dt-button-collection-title:empty { 69 | display: none 70 | } 71 | 72 | button.dt-button, div.dt-button, a.dt-button { 73 | position: relative; 74 | display: inline-block; 75 | box-sizing: border-box; 76 | margin-right: 0.333em; 77 | margin-bottom: 0.333em; 78 | padding: 0.5em 1em; 79 | border: 1px solid #999; 80 | border-radius: 2px; 81 | cursor: pointer; 82 | font-size: 0.88em; 83 | line-height: 1.6em; 84 | color: black; 85 | white-space: nowrap; 86 | overflow: hidden; 87 | background-color: #e9e9e9; 88 | background-image: -webkit-linear-gradient(top, #fff 0%, #e9e9e9 100%); 89 | background-image: -moz-linear-gradient(top, #fff 0%, #e9e9e9 100%); 90 | background-image: -ms-linear-gradient(top, #fff 0%, #e9e9e9 100%); 91 | background-image: -o-linear-gradient(top, #fff 0%, #e9e9e9 100%); 92 | background-image: linear-gradient(to bottom, #fff 0%, #e9e9e9 100%); 93 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='white', EndColorStr='#e9e9e9'); 94 | -webkit-user-select: none; 95 | -moz-user-select: none; 96 | -ms-user-select: none; 97 | user-select: none; 98 | text-decoration: none; 99 | outline: none 100 | } 101 | 102 | button.dt-button.disabled, div.dt-button.disabled, a.dt-button.disabled { 103 | color: #999; 104 | border: 1px solid #d0d0d0; 105 | cursor: default; 106 | background-color: #f9f9f9; 107 | background-image: -webkit-linear-gradient(top, #fff 0%, #f9f9f9 100%); 108 | background-image: -moz-linear-gradient(top, #fff 0%, #f9f9f9 100%); 109 | background-image: -ms-linear-gradient(top, #fff 0%, #f9f9f9 100%); 110 | background-image: -o-linear-gradient(top, #fff 0%, #f9f9f9 100%); 111 | background-image: linear-gradient(to bottom, #fff 0%, #f9f9f9 100%); 112 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ffffff', EndColorStr='#f9f9f9') 113 | } 114 | 115 | button.dt-button:active:not(.disabled), button.dt-button.active:not(.disabled), div.dt-button:active:not(.disabled), div.dt-button.active:not(.disabled), a.dt-button:active:not(.disabled), a.dt-button.active:not(.disabled) { 116 | background-color: #e2e2e2; 117 | background-image: -webkit-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%); 118 | background-image: -moz-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%); 119 | background-image: -ms-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%); 120 | background-image: -o-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%); 121 | background-image: linear-gradient(to bottom, #f3f3f3 0%, #e2e2e2 100%); 122 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f3f3f3', EndColorStr='#e2e2e2'); 123 | box-shadow: inset 1px 1px 3px #999999 124 | } 125 | 126 | button.dt-button:active:not(.disabled):hover:not(.disabled), button.dt-button.active:not(.disabled):hover:not(.disabled), div.dt-button:active:not(.disabled):hover:not(.disabled), div.dt-button.active:not(.disabled):hover:not(.disabled), a.dt-button:active:not(.disabled):hover:not(.disabled), a.dt-button.active:not(.disabled):hover:not(.disabled) { 127 | box-shadow: inset 1px 1px 3px #999999; 128 | background-color: #cccccc; 129 | background-image: -webkit-linear-gradient(top, #eaeaea 0%, #ccc 100%); 130 | background-image: -moz-linear-gradient(top, #eaeaea 0%, #ccc 100%); 131 | background-image: -ms-linear-gradient(top, #eaeaea 0%, #ccc 100%); 132 | background-image: -o-linear-gradient(top, #eaeaea 0%, #ccc 100%); 133 | background-image: linear-gradient(to bottom, #eaeaea 0%, #ccc 100%); 134 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#eaeaea', EndColorStr='#cccccc') 135 | } 136 | 137 | button.dt-button:hover, div.dt-button:hover, a.dt-button:hover { 138 | text-decoration: none 139 | } 140 | 141 | button.dt-button:hover:not(.disabled), div.dt-button:hover:not(.disabled), a.dt-button:hover:not(.disabled) { 142 | border: 1px solid #666; 143 | background-color: #e0e0e0; 144 | background-image: -webkit-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%); 145 | background-image: -moz-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%); 146 | background-image: -ms-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%); 147 | background-image: -o-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%); 148 | background-image: linear-gradient(to bottom, #f9f9f9 0%, #e0e0e0 100%); 149 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f9f9f9', EndColorStr='#e0e0e0') 150 | } 151 | 152 | button.dt-button:focus:not(.disabled), div.dt-button:focus:not(.disabled), a.dt-button:focus:not(.disabled) { 153 | border: 1px solid #426c9e; 154 | text-shadow: 0 1px 0 #c4def1; 155 | outline: none; 156 | background-color: #79ace9; 157 | background-image: -webkit-linear-gradient(top, #bddef4 0%, #79ace9 100%); 158 | background-image: -moz-linear-gradient(top, #bddef4 0%, #79ace9 100%); 159 | background-image: -ms-linear-gradient(top, #bddef4 0%, #79ace9 100%); 160 | background-image: -o-linear-gradient(top, #bddef4 0%, #79ace9 100%); 161 | background-image: linear-gradient(to bottom, #bddef4 0%, #79ace9 100%); 162 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#bddef4', EndColorStr='#79ace9') 163 | } 164 | 165 | .dt-button embed { 166 | outline: none 167 | } 168 | 169 | div.dt-buttons { 170 | position: relative; 171 | float: left 172 | } 173 | 174 | div.dt-buttons.buttons-right { 175 | float: right 176 | } 177 | 178 | div.dt-button-collection { 179 | position: absolute; 180 | top: 0; 181 | left: 0; 182 | width: 150px; 183 | margin-top: 3px; 184 | padding: 8px 8px 4px 8px; 185 | border: 1px solid #ccc; 186 | border: 1px solid rgba(0,0,0,0.4); 187 | background-color: white; 188 | overflow: hidden; 189 | z-index: 2002; 190 | border-radius: 5px; 191 | box-shadow: 3px 3px 5px rgba(0,0,0,0.3); 192 | -webkit-column-gap: 8px; 193 | -moz-column-gap: 8px; 194 | -ms-column-gap: 8px; 195 | -o-column-gap: 8px; 196 | column-gap: 8px 197 | } 198 | 199 | div.dt-button-collection button.dt-button, div.dt-button-collection div.dt-button, div.dt-button-collection a.dt-button { 200 | position: relative; 201 | left: 0; 202 | right: 0; 203 | width: 100%; 204 | display: block; 205 | float: none; 206 | margin-bottom: 4px; 207 | margin-right: 0 208 | } 209 | 210 | div.dt-button-collection button.dt-button:active:not(.disabled), div.dt-button-collection button.dt-button.active:not(.disabled), div.dt-button-collection div.dt-button:active:not(.disabled), div.dt-button-collection div.dt-button.active:not(.disabled), div.dt-button-collection a.dt-button:active:not(.disabled), div.dt-button-collection a.dt-button.active:not(.disabled) { 211 | background-color: #dadada; 212 | background-image: -webkit-linear-gradient(top, #f0f0f0 0%, #dadada 100%); 213 | background-image: -moz-linear-gradient(top, #f0f0f0 0%, #dadada 100%); 214 | background-image: -ms-linear-gradient(top, #f0f0f0 0%, #dadada 100%); 215 | background-image: -o-linear-gradient(top, #f0f0f0 0%, #dadada 100%); 216 | background-image: linear-gradient(to bottom, #f0f0f0 0%, #dadada 100%); 217 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f0f0f0', EndColorStr='#dadada'); 218 | box-shadow: inset 1px 1px 3px #666 219 | } 220 | 221 | div.dt-button-collection.fixed { 222 | position: fixed; 223 | top: 50%; 224 | left: 50%; 225 | margin-left: -75px; 226 | border-radius: 0 227 | } 228 | 229 | div.dt-button-collection.fixed.two-column { 230 | margin-left: -150px 231 | } 232 | 233 | div.dt-button-collection.fixed.three-column { 234 | margin-left: -225px 235 | } 236 | 237 | div.dt-button-collection.fixed.four-column { 238 | margin-left: -300px 239 | } 240 | 241 | div.dt-button-collection > * { 242 | -webkit-column-break-inside: avoid; 243 | break-inside: avoid 244 | } 245 | 246 | div.dt-button-collection.two-column { 247 | width: 300px; 248 | padding-bottom: 1px; 249 | -webkit-column-count: 2; 250 | -moz-column-count: 2; 251 | -ms-column-count: 2; 252 | -o-column-count: 2; 253 | column-count: 2 254 | } 255 | 256 | div.dt-button-collection.three-column { 257 | width: 450px; 258 | padding-bottom: 1px; 259 | -webkit-column-count: 3; 260 | -moz-column-count: 3; 261 | -ms-column-count: 3; 262 | -o-column-count: 3; 263 | column-count: 3 264 | } 265 | 266 | div.dt-button-collection.four-column { 267 | width: 600px; 268 | padding-bottom: 1px; 269 | -webkit-column-count: 4; 270 | -moz-column-count: 4; 271 | -ms-column-count: 4; 272 | -o-column-count: 4; 273 | column-count: 4 274 | } 275 | 276 | div.dt-button-collection .dt-button { 277 | border-radius: 0 278 | } 279 | 280 | div.dt-button-background { 281 | position: fixed; 282 | top: 0; 283 | left: 0; 284 | width: 100%; 285 | height: 100%; 286 | background: rgba(0,0,0,0.7); 287 | background: -ms-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%); 288 | background: -moz-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%); 289 | background: -o-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%); 290 | background: -webkit-gradient(radial, center center, 0, center center, 497, color-stop(0, rgba(0,0,0,0.3)), color-stop(1, rgba(0,0,0,0.7))); 291 | background: -webkit-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%); 292 | background: radial-gradient(ellipse farthest-corner at center, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%); 293 | z-index: 2001 294 | } 295 | 296 | @media screen and (max-width: 640px) { 297 | div.dt-buttons { 298 | float: none !important; 299 | text-align: center 300 | } 301 | } 302 | 303 | button.dt-button.processing, div.dt-button.processing, a.dt-button.processing { 304 | color: rgba(0,0,0,0.2) 305 | } 306 | 307 | button.dt-button.processing:after, div.dt-button.processing:after, a.dt-button.processing:after { 308 | position: absolute; 309 | top: 50%; 310 | left: 50%; 311 | width: 16px; 312 | height: 16px; 313 | margin: -8px 0 0 -8px; 314 | box-sizing: border-box; 315 | display: block; 316 | content: ' '; 317 | border: 2px solid #282828; 318 | border-radius: 50%; 319 | border-left-color: transparent; 320 | border-right-color: transparent; 321 | animation: dtb-spinner 1500ms infinite linear; 322 | -o-animation: dtb-spinner 1500ms infinite linear; 323 | -ms-animation: dtb-spinner 1500ms infinite linear; 324 | -webkit-animation: dtb-spinner 1500ms infinite linear; 325 | -moz-animation: dtb-spinner 1500ms infinite linear 326 | } 327 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/css/dataTables.bootstrap4.min.css: -------------------------------------------------------------------------------- 1 | table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important;border-spacing:0}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:auto;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:0.85em;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap;justify-content:flex-end}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:before,table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:0.9em;display:block;opacity:0.3}table.dataTable thead .sorting:before,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:before{right:1em;content:"\2191"}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{right:0.5em;content:"\2193"}table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:after{opacity:1}table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{opacity:0}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:before,div.dataTables_scrollBody table thead .sorting_asc:before,div.dataTables_scrollBody table thead .sorting_desc:before,div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot>.dataTables_scrollFootInner{box-sizing:content-box}div.dataTables_scrollFoot>.dataTables_scrollFootInner>table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-sm>thead>tr>th{padding-right:20px}table.dataTable.table-sm .sorting:before,table.dataTable.table-sm .sorting_asc:before,table.dataTable.table-sm .sorting_desc:before{top:5px;right:0.85em}table.dataTable.table-sm .sorting:after,table.dataTable.table-sm .sorting_asc:after,table.dataTable.table-sm .sorting_desc:after{top:5px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0} 2 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingers10/JqueryDataTablesServerSideDemo/a2a586a92639bbebd273f114ba4ec7dc4fc1d1c4/AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_asc.png -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingers10/JqueryDataTablesServerSideDemo/a2a586a92639bbebd273f114ba4ec7dc4fc1d1c4/AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingers10/JqueryDataTablesServerSideDemo/a2a586a92639bbebd273f114ba4ec7dc4fc1d1c4/AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_both.png -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingers10/JqueryDataTablesServerSideDemo/a2a586a92639bbebd273f114ba4ec7dc4fc1d1c4/AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_desc.png -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingers10/JqueryDataTablesServerSideDemo/a2a586a92639bbebd273f114ba4ec7dc4fc1d1c4/AspNetCoreServerSide/wwwroot/lib/datatables/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/js/dataTables.bootstrap4.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | DataTables Bootstrap 4 integration 3 | ©2011-2017 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d,m){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", 6 | renderer:"bootstrap"});b.extend(f.ext.classes,{sWrapper:"dataTables_wrapper dt-bootstrap4",sFilterInput:"form-control form-control-sm",sLengthSelect:"custom-select custom-select-sm form-control form-control-sm",sProcessing:"dataTables_processing card",sPageButton:"paginate_button page-item"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,s,j,n){var o=new f.Api(a),t=a.oClasses,k=a.oLanguage.oPaginate,u=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault(); 7 | !b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")};l=0;for(h=f.length;l", 8 | {"class":t.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("",{href:"#","aria-controls":a.sTableId,"aria-label":u[c],"data-dt-idx":p,tabindex:a.iTabIndex,"class":"page-link"}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(v){}q(b(h).empty().html('
    ').children("ul"),s);i!==m&&b(h).find("[data-dt-idx="+i+"]").focus()};return f}); 9 | -------------------------------------------------------------------------------- /AspNetCoreServerSide/wwwroot/lib/datatables/js/dataTables.buttons.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Buttons for DataTables 1.5.6 3 | ©2016-2019 SpryMedia Ltd - datatables.net/license 4 | */ 5 | var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(d,q,n){d instanceof String&&(d=String(d));for(var l=d.length,u=0;u").addClass(this.c.dom.container.className)};this._constructor()};d.extend(t.prototype,{action:function(a,b){a=this._nodeToButton(a);if(b===l)return a.conf.action;a.conf.action= 10 | b;return this},active:function(a,b){var c=this._nodeToButton(a);a=this.c.dom.button.active;c=d(c.node);if(b===l)return c.hasClass(a);c.toggleClass(a,b===l?!0:b);return this},add:function(a,b){var c=this.s.buttons;if("string"===typeof b){b=b.split("-");c=this.s;for(var d=0,f=b.length-1;d").addClass(y.className).attr("role","menu");m.conf._collection=m.collection; 16 | this._expandButton(m.buttons,m.conf.buttons,!0,e)}v.init&&v.init.call(f.button(m.node),f,d(m.node),v);g++}}}},_buildButton:function(a,b){var c=this.c.dom.button,e=this.c.dom.buttonLiner,f=this.c.dom.collection,g=this.s.dt,h=function(b){return"function"===typeof b?b(g,m,a):b};b&&f.button&&(c=f.button);b&&f.buttonLiner&&(e=f.buttonLiner);if(a.available&&!a.available(g,a))return!1;var k=function(a,b,c,e){e.action.call(b.button(c),a,b,c,e);d(b.table().node()).triggerHandler("buttons-action.dt",[b.button(c), 17 | b,c,e])};f=a.tag||c.tag;var v=a.clickBlurs===l?!0:a.clickBlurs,m=d("<"+f+"/>").addClass(c.className).attr("tabindex",this.s.dt.settings()[0].iTabIndex).attr("aria-controls",this.s.dt.table().node().id).on("click.dtb",function(b){b.preventDefault();!m.hasClass(c.disabled)&&a.action&&k(b,g,m,a);v&&m.blur()}).on("keyup.dtb",function(b){13===b.keyCode&&!m.hasClass(c.disabled)&&a.action&&k(b,g,m,a)});"a"===f.toLowerCase()&&m.attr("href","#");"button"===f.toLowerCase()&&m.attr("type","button");e.tag?(f= 18 | d("<"+e.tag+"/>").html(h(a.text)).addClass(e.className),"a"===e.tag.toLowerCase()&&f.attr("href","#"),m.append(f)):m.html(h(a.text));!1===a.enabled&&m.addClass(c.disabled);a.className&&m.addClass(a.className);a.titleAttr&&m.attr("title",h(a.titleAttr));a.attr&&m.attr(a.attr);a.namespace||(a.namespace=".dt-button-"+C++);e=(e=this.c.dom.buttonContainer)&&e.tag?d("<"+e.tag+"/>").addClass(e.className).append(m):m;this._addKey(a);this.c.buttonCreated&&(e=this.c.buttonCreated(a,e));return{conf:a,node:m.get(0), 19 | inserter:e,buttons:[],inCollection:b,collection:null}},_nodeToButton:function(a,b){b||(b=this.s.buttons);for(var c=0,d=b.length;c").addClass(b).css("display","none").insertAfter(e).stop().fadeIn(c): 23 | d("div."+b).stop().fadeOut(c,function(){d(this).removeClass(b).remove()})};t.instanceSelector=function(a,b){if(!a)return d.map(b,function(a){return a.inst});var c=[],e=d.map(b,function(a){return a.name}),f=function(a){if(d.isArray(a))for(var g=0,k=a.length;g'+e.collectionTitle+"");e._collection.addClass(e.collectionLayout).css("display","none").insertAfter(l).stop().fadeIn(e.fade); 29 | g=e._collection.css("position");if(k&&"absolute"===g)e._collection.css({top:k.top,left:k.left});else if("absolute"===g){e._collection.css({top:a.top+c.outerHeight(),left:a.left});k=h.offset().top+h.height();k=a.top+c.outerHeight()+e._collection.outerHeight()-k;g=a.top-e._collection.outerHeight();var m=h.offset().top;(k>m-g||e.dropup)&&e._collection.css("top",a.top-e._collection.outerHeight()-5);e._collection.hasClass(e.rightAlignClassName)&&e._collection.css("left",a.left+c.outerWidth()-e._collection.outerWidth()); 30 | k=a.left+e._collection.outerWidth();h=h.offset().left+h.width();k>h&&e._collection.css("left",a.left-(k-h));c=c.offset().left+e._collection.outerWidth();c>d(q).width()&&e._collection.css("left",a.left-(c-d(q).width()))}else c=e._collection.height()/2,c>d(q).height()/2&&(c=d(q).height()/2),e._collection.css("marginTop",-1*c);e.background&&t.background(!0,e.backgroundClassName,e.fade,l);setTimeout(function(){d("div.dt-button-background").on("click.dtb-collection",function(){});d("body").on("click.dtb-collection", 31 | function(a){var b=d.fn.addBack?"addBack":"andSelf";d(a.target).parents()[b]().filter(e._collection).length||f()}).on("keyup.dtb-collection",function(a){27===a.keyCode&&f()});if(e.autoClose)b.on("buttons-action.b-internal",function(){f()})},10)}},background:!0,collectionLayout:"",collectionTitle:"",backgroundClassName:"dt-button-background",rightAlignClassName:"dt-button-right",autoClose:!1,fade:400,attr:{"aria-haspopup":!0}},copy:function(a,b){if(r.copyHtml5)return"copyHtml5";if(r.copyFlash&&r.copyFlash.available(a, 32 | b))return"copyFlash"},csv:function(a,b){if(r.csvHtml5&&r.csvHtml5.available(a,b))return"csvHtml5";if(r.csvFlash&&r.csvFlash.available(a,b))return"csvFlash"},excel:function(a,b){if(r.excelHtml5&&r.excelHtml5.available(a,b))return"excelHtml5";if(r.excelFlash&&r.excelFlash.available(a,b))return"excelFlash"},pdf:function(a,b){if(r.pdfHtml5&&r.pdfHtml5.available(a,b))return"pdfHtml5";if(r.pdfFlash&&r.pdfFlash.available(a,b))return"pdfFlash"},pageLength:function(a){a=a.settings()[0].aLengthMenu;var b=d.isArray(a[0])? 33 | a[0]:a,c=d.isArray(a[0])?a[1]:a;return{extend:"collection",text:function(a){return a.i18n("buttons.pageLength",{"-1":"Show all rows",_:"Show %d rows"},a.page.len())},className:"buttons-page-length",autoClose:!0,buttons:d.map(b,function(a,b){return{text:c[b],className:"button-page-length",action:function(b,c){c.page.len(a).draw()},init:function(b,c,d){var e=this;c=function(){e.active(b.page.len()===a)};b.on("length.dt"+d.namespace,c);c()},destroy:function(a,b,c){a.off("length.dt"+c.namespace)}}}), 34 | init:function(a,b,c){var d=this;a.on("length.dt"+c.namespace,function(){d.text(c.text)})},destroy:function(a,b,c){a.off("length.dt"+c.namespace)}}}});p.Api.register("buttons()",function(a,b){b===l&&(b=a,a=l);this.selector.buttonGroup=a;var c=this.iterator(!0,"table",function(c){if(c._buttons)return t.buttonSelector(t.instanceSelector(a,c._buttons),b)},!0);c._groupSelector=a;return c});p.Api.register("button()",function(a,b){a=this.buttons(a,b);1"+a+"":"";d('
    ').html(a).append(d("
    ")["string"===typeof b?"html":"append"](b)).css("display","none").appendTo("body").fadeIn();c!==l&&0!==c&&(w=setTimeout(function(){e.buttons.info(!1)},c)); 40 | return this});p.Api.register("buttons.exportData()",function(a){if(this.context.length)return D(new p.Api(this.context[0]),a)});p.Api.register("buttons.exportInfo()",function(a){a||(a={});var b=a;var c="*"===b.filename&&"*"!==b.title&&b.title!==l&&null!==b.title&&""!==b.title?b.title:b.filename;"function"===typeof c&&(c=c());c===l||null===c?c=null:(-1!==c.indexOf("*")&&(c=d.trim(c.replace("*",d("head > title").text()))),c=c.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g,""),(b=x(b.extension))|| 41 | (b=""),c+=b);b=x(a.title);b=null===b?null:-1!==b.indexOf("*")?b.replace("*",d("head > title").text()||"Exported data"):b;return{filename:c,title:b,messageTop:z(this,a.message||a.messageTop,"top"),messageBottom:z(this,a.messageBottom,"bottom")}});var x=function(a){return null===a||a===l?null:"function"===typeof a?a():a},z=function(a,b,c){b=x(b);if(null===b)return null;a=d("caption",a.table().container()).eq(0);return"*"===b?a.css("caption-side")!==c?null:a.length?a.text():"":b},A=d("