Step 4. Adding the Required Files

Step 4. Adding the Required Files

Step 4.1. Setting Up Libraries

Install the next libraries in the created project via Nuget (Package Manager Console)

Note: Please, check your Default Project in all installations of nuget packages:

package manager console

PM>Install-Package Microsoft.AspNet.Mvc
PM>Install-Package jQuery
Install-Package DHTMLX.Scheduler.NET
PM>Install-Package EntityFramework
PM>Install-Package Microsoft.AspNet.Identity.EntityFramework
PM>Install-Package Microsoft.AspNet.Identity.Owin

Add following references: System.Runtime.Serialization

The following illustration shows the final folder structure of a project:

task manager mvc5

Step 4.2. Adding App.Config

Add connection string:

<configuration>
 <connectionStrings>
    <add name="TaskManagerString" connectionString="data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\TaskManager.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

Configure the globalization settings of the application:

<system.web>
      <globalization culture="en-US"/>
  </system.web>

Step 4.3. Updating Global.asax

To create a database paste in the following code to Global.asax

using System.Data.Entity;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Scheduler.MVC5.Users;
using TaskManager.MVC5.Model;
 
namespace TaskManager.MVC5
{
    public class MvcApplication : HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
 
            //to create users table with/without data if not exists
            Database.SetInitializer(new TaskManagerDbContextInit());
            var db = new TaskManagerDbContext();
            db.Database.Initialize(true);
            //to create others tables with/without data if not exists
            Database.SetInitializer(new UserIdentityDbContextInit());
            var users = new UserIdentityDbContext();
            users.Database.Initialize(true);
        }
    }
}

Step 4.4. Adding Startup Class

1. Add OWIN Startup Class to your task manager project:

add new item

2. Paste in the next following code to created file:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using Owin;
using Scheduler.MVC5.Users;
 
[assembly: OwinStartup(typeof(TaskManager.MVC5.Startup))]
 
namespace TaskManager.MVC5
{
    public class Startup
    {
        public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
 
        public void Configuration(IAppBuilder app)
        {
            // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
            app.CreatePerOwinContext((new UserIdentityDbContext()).Create);
            app.CreatePerOwinContext<AppUserManager>((new AppUserManager(new UserStore<ApplicationUser>(new UserIdentityDbContext()))).Create);
 
 
            OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
 
            //This will used the HTTP header: "Authorization" Value: "Bearer 1234123412341234asdfasdfasdfasdf"
            app.UseOAuthBearerAuthentication(OAuthBearerOptions);
            // Enable the application to use a cookie to store information for the signed in user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/LogOn")
            });
        }
    }
}

Step 4.5. Adding Models

1. Add a New Folder to the project with the name Models.

  • AccountModels
  1. AddClass to Model folder with Name AccountModels
  2. Update the code as follows:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Web.Security;
 
namespace TaskManager.MVC5.Models
{
 
    #region Model
     public class ChangePasswordModel
    {
        [Required]
        [DataType(DataType.Password)]
        [DisplayName("Current password")]
        public string OldPassword { get; set; }
 
        [Required]
        [DataType(DataType.Password)]
        [DisplayName("New password")]
        public string NewPassword { get; set; }
 
        [Required]
        [DataType(DataType.Password)]
        [DisplayName("Confirm new password")]
        public string ConfirmPassword { get; set; }
    }
 
    public class LogOnModel
    {
        [Required]
        [DisplayName("User name")]
        public string UserName { get; set; }
 
        [Required]
        [DataType(DataType.Password)]
        [DisplayName("Password")]
        public string Password { get; set; }
 
        [DisplayName("Remember me?")]
        public bool RememberMe { get; set; }
    }
 
     public class RegisterModel
    {
        [Required]
        [DisplayName("User name")]
        public string UserName { get; set; }
 
        [Required]
        [DataType(DataType.EmailAddress)]
        [DisplayName("Email address")]
        public string Email { get; set; }
 
        [Required]
        [DataType(DataType.Password)]
        [DisplayName("Password")]
        public string Password { get; set; }
 
        [Required]
        [DataType(DataType.Password)]
        [DisplayName("Confirm password")]
        public string ConfirmPassword { get; set; }
    }
    #endregion    
}
  • TaskDetails
  1. AddClass to Model folder with Name TaskDetails.cs
  2. Paste the following code:
using System.Collections.Generic;
using TaskManager.MVC5.Model;
 
namespace TaskManager.MVC5.Models
{
    public class TaskDetails
    {
        public Task Task { get; set; }
        public IEnumerable<Status> Statuses { get; set; }
        public TaskDetails(Task ts, IEnumerable<Status> st)
        {
            Task = ts;
            Statuses = st;
        }
    }
}

Step 4.6. Creating Views

Create into Views folders named Account, Shared, System.

  • Shared

The Shared folder is used to store views shared between controllers (layout page). Also this folder contain a user control partial view.

  • _Layout

At first you need to create a layout:

  1. Create a file called _Layout.cshtml inside the shared folder
  2. Insert the following code:
<!DOCTYPE html>
 
<html lang="en">
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Task Manager</title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="~/scripts/dhtmlxscheduler/dhtmlxscheduler_flat.css" rel="stylesheet" />
 
</head>
 
    <body>
 
        <div id="header">
 
            <div id="logindisplay">
                @Html.Partial("UserControl")
            </div>
 
        </div>
        <div class="page">
            @RenderBody()
        </div>
        <div id="footer">
            <p>&copy;@DateTime.Now.Year - DHTMLX Scheduler .NET</p>
        </div>
        <style type="text/css">
            /*for month events----------*/
            .state_1 {
                background-color: #5B9BE0;
            }
 
            .state_2 {
                background-color: #FE7510;
            }
 
            .state_3 {
                background-color: #76B007;
            }
        </style>
 
        <script type="text/javascript">
            scheduler.templates.event_class = function (start, end, ev) {
                return "state_" + ev.status_id;
            }
        </script>
    </body>
 
 
</html>
  • UserControl
  1. Inside the shared folder create file with Name UserControl.cshtml
  2. Delete the existing code from the opened file and paste the following code:
@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
    using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
    {
        @Html.AntiForgeryToken()
 
        <ul class="hr">
            <li>
               <a>Welcome  @User.Identity.GetUserName() !</a>
            </li>
            <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
        </ul>
    }
}
else
{
    <ul class="hr">
        <li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })</li>
        <li>@Html.ActionLink("Log in", "LogOn", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>
    </ul>
}
  • Account

The account folder contains pages for logging in and registering user accounts.

  1. Inside Account folder create LogOn.cshtml and Register.cshtml
  2. Paste the following code to LogOn.cshtml
@model TaskManager.MVC5.Models.LogOnModel
@{
    ViewBag.Title = "Log in";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<div id="loginContent" class="row">
    <p>Please enter your username and password.</p>
 
    <ul>
        <li>Manager/password</li>
        <li>David/password</li>
        <li>Dana/password</li>
        <li>Linda/password</li>
        <li>John/password</li>
    </ul>
    @using (Html.BeginForm("LogOn", "Account"))
    {
        @Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
        <div class="center-block ">
            <div class="form-group">
                <div class="editor-label">
                    @Html.LabelFor(m => m.UserName)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.UserName, new { @class = "dhx_cal_ltext" })
                    @Html.ValidationMessageFor(m => m.UserName)
                </div>
            </div>
 
            <div class="form-group">
                <div class="editor-label">
                    @Html.LabelFor(m => m.Password)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.Password, new { @type = "password", @class = "dhx_cal_ltext" })
                    @Html.ValidationMessageFor(m => m.Password)
                </div>
            </div>
 
            <div class="editor-label form-group">
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe)
            </div>
 
            <div class="form-group">
                <input type="submit" name="result" value="Log in" class="dhx_btn_set dhx_left_btn_set dhx_save_btn_set" style="width: 70px; float: right;" />
            </div>
        </div>
    }
</div>

3) Paste the following code to Register.cshtml

@model TaskManager.MVC5.Models.RegisterModel
@{
    ViewBag.Title = "Register";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@using (Html.BeginForm("Register", "Account"))
{
    <div class="center-block ">
 
        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(m => m.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.UserName)
                @Html.ValidationMessageFor(m => m.UserName)
            </div>
        </div>
 
        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(m => m.Email)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.Email)
                @Html.ValidationMessageFor(m => m.Email)
            </div>
        </div>
 
        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(m => m.Password)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.Password, new { @type = "password" })
                @Html.ValidationMessageFor(m => m.Password)
            </div>
        </div>
 
        <div class="form-group">
            <div class="editor-label">
                @Html.LabelFor(m => m.ConfirmPassword)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.ConfirmPassword, new { @type = "password" })
                @Html.ValidationMessageFor(m => m.ConfirmPassword)
            </div>
        </div>
        <div class="form-group">
            <input type="submit" name="result" value="Register" class="dhx_btn_set dhx_left_btn_set dhx_save_btn_set" style="width: 70px; float: right;" />
        </div>
    </div>
}
  • System

This folder contains manager.cshtml which represent the Manager page of the application. employee.cshtml represents Employee page, and TaskDetails.cshtml displays task details data for employees.

Employee

  1. Inside folder System AddView with Name Employee.cshtml
  2. Paste the folowing code:
@{
    ViewBag.Title = "Employee";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@Html.Raw(Model.Render())
<div id="footer-top-border"></div>
<script>
 
    scheduler.attachEvent("onClick", function (id) {
        window.location = '@Url.Action("TaskDetails","System")?id=' + id;
    });
</script>

It will look like this:

calendar agenda

Manager

  1. In the folder System Add View named Manager.cshtml
  2. Update the code as follows:
@model TaskManager.MVC5.Controllers.SystemController.SystemModel
@{
    ViewBag.Title = "Manage Tasks";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@Html.Raw(Model.Scheduler.Render())
<div id="footer-top-border"></div>
<style type="text/css">
    @foreach(var state in Model.Statuses) {
        <text> .dhx_cal_event.state_@state.id div{
            background-color: @state.color;
        }
        </text>
    }
</style>
 
<script type="text/javascript">
    var data = JSON.parse('@Html.Raw(Model.Users)');
    scheduler.templates.event_header = function (start, end, ev) {
        return scheduler.templates.event_date(start) + " - " + scheduler.templates.event_date(end) + " (" + findById(data, ev.owner_id) + ")";
    };
 
    function findById(ar, id) {
        for (var i = 0; i < ar.length; i++) {
            if (ar[i].key == id) {
                return ar[i].userName;
            }
        }
        return "";
    }
</script>

staff calendar

TaskDetails

  1. Add to the folder System View with name TaskDetails
  2. Paste in the following code:
@{
    ViewBag.Title = "TaskDetails";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@model TaskManager.MVC5.Models.TaskDetails
 
<div class="page row">
 
    <span>@ViewData["user"], TaskDetails</span>
 
 
    @if (Model.Task != null)
    {
        using (Html.BeginForm("Index", "System/UpdateStatus", FormMethod.Post, null))
        {
            @Html.Hidden("id", Model.Task.id)
 
            <div class="center-block">
                <div class=" text-right form-group">
                    <span>
 
                        @String.Format("{0:MM/dd/yyyy}", Model.Task.start_date),
                        <b>
                            @String.Format("{0:HH:mm}", Model.Task.start_date)
                            &ndash; @String.Format("{0:HH:mm}", Model.Task.end_date)
                        </b>
                    </span>
                </div>
                <div class="text-left dhx_cal_ltext form-group">
                    <h1>@Model.Task.text</h1>
                </div>
                <div class="text-left details form-group">
                    <div @( string.IsNullOrEmpty(Model.Task.details) ? "style= 'color':#bbb;" : "") style="word-wrap: break-word;">@(string.IsNullOrEmpty(Model.Task.details) ? "Task has no description" : Model.Task.details)</div>
                </div>
                <div class="text-left form-group">
                    <span>Status: </span>
                    @Html.DropDownList("status_id", new SelectList(Model.Statuses, "id", "title", ViewData["status"]), new
                    {
                        @class = "dhx_cal_ltext",
                        @style = "width:172px;"
                    })
                </div>
 
                <div class=" text-center form-group">
                    <input type="submit" name="result" value="Update" class="dhx_btn_set dhx_left_btn_set dhx_save_btn_set" style="width: 70px;" />
 
                    <input type="submit" name="result" value="Cancel" class="dhx_btn_set dhx_right_btn_set dhx_delete_btn_set " style="float: right; width: 70px;" />
                </div>
            </div>
 
        }
    }
 
</div>

task status

  • Controllers

1. Inside Controllers folder Add → Empty Controllers named Account and System 2. AccountController contains action methods for log in and registeration. Update AccountController.cs aas follows:

using System.Threading.Tasks;
using System.Web.Mvc;
using Scheduler.MVC5.Users;
using TaskManager.MVC5.Models;
 
namespace TaskManager.MVC5.Controllers
{
    public class AccountController : Controller
    {
 
        #region sign in helper
        //get the SignInHelper object during a mvc controller execution 
        private SignInHelper _helper;
 
        private SignInHelper SignInHelper
        {
            get { return _helper ?? (_helper = new SignInHelper(AppUserManagerProvider.GetAppUserManager, AppUserManagerProvider.AuthenticationManager)); }
        }
        #endregion
 
        public AccountController(){}
 
        public AccountController(AppUserManager userManager)
        {
            AppUserManagerProvider.GetAppUserManager = userManager;
        }
 
        [HttpGet]
        public ActionResult LogOn()
        {
            return View();
        }
 
        [HttpPost]
        public async Task<ActionResult> LogOn(LogOnModel model, string returnUrl)
        {
            if (!ModelState.IsValid) return View(model);
            //Sign in if a model is valid
            var result = await SignInHelper.PasswordSignIn(model.UserName, model.Password, model.RememberMe);
 
            switch (result)
            {
                case "Success":
                {
                    return RedirectToAction("Index", "System");
                }
                default:
                {
                    ModelState.AddModelError("", "The user name or password is incorrect.");
 
                }break;
 
            }
            //if something failed, redisplay form
            return View(model);
        }
 
        public ActionResult LogOff()
        {
            AppUserManagerProvider.AuthenticationManager.SignOut();
            return RedirectToAction("LogOn", "Account");
        }
 
        public ActionResult Register()
        {
            return View();
        }
 
        [HttpPost]
        public async Task<ActionResult> Register(RegisterModel model)
        {
            if (!ModelState.IsValid) return View(model);
            //if a model is valid,create a user with credentials
            var user = new ApplicationUser {UserName = model.UserName, Email = model.Email};
            var result = await AppUserManagerProvider.GetAppUserManager.CreateAsync(user, model.Password);
 
            if (result.Succeeded)
            {
                //add default role for a new user
                await AppUserManagerProvider.GetAppUserManager.AddToRoleAsync(user.Id, "Employee");
                //sign in
                await SignInHelper.SignInAsync(user, isPersistent: true, rememderBrowser: false);
                return RedirectToAction("Index", "System");
            }
 
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError("", error);
            }
            //if something failed, redisplay form
            return View(model);
        }
    }
}

3. Update SystemController as it is shown below:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Web.Mvc;
using DHTMLX.Common;
using DHTMLX.Scheduler;
using DHTMLX.Scheduler.Authentication;
using DHTMLX.Scheduler.Controls;
using DHTMLX.Scheduler.Data;
 
using Scheduler.MVC5.Users;
using TaskManager.MVC5.Model;
using TaskManager.MVC5.Models;
using System.Runtime.Serialization.Json;
 
namespace TaskManager.MVC5.Controllers
{
    public class SystemController : Controller
    {
        private IRepository _repository;
        private AppUserManagerProvider _appUserManagerProvider;
        public IRepository Repository
        {
            get { return _repository ?? (_repository = new Repository()); }
        }
 
        public AppUserManagerProvider AppUserManagerProvider
        {
            get { return _appUserManagerProvider ?? (_appUserManagerProvider = new AppUserManagerProvider()); }
        }
 
 
 
        // GET: System
        public ActionResult Index()
        {
            //redirect to login page unauthorized user
            return !Request.IsAuthenticated ? RedirectToAction("LogOn", "Account") : RedirectToAction(User.IsInRole("Manager") ? "Manager" : "Employee", "System");
        }
 
        public ActionResult Manager()
        {
            var scheduler = new DHXScheduler(this);
 
            #region check rights
            if (!RoleIs("Manager"))// checks the role
                return RedirectToAction("Index", "System");//in case the role is not manager, redirects to the login page
 
            #endregion
 
            #region configuration
 
            scheduler.Config.first_hour = 8;//sets the minimum value for the hour scale (Y-Axis)
            scheduler.Config.hour_size_px = 88;
            scheduler.Config.last_hour = 17;//sets the maximum value for the hour scale (Y-Axis)
            scheduler.Config.time_step = 30;//sets the scale interval for the time selector in the lightbox. 
            scheduler.Config.full_day = true;// blocks entry fields in the 'Time period' section of the lightbox and sets time period to a full day from 00.00 the current cell date untill 00.00 next day. 
 
            scheduler.Skin = DHXScheduler.Skins.Flat;
            scheduler.Config.separate_short_events = true;
 
            scheduler.Extensions.Add(SchedulerExtensions.Extension.ActiveLinks);
 
            #endregion
 
            #region views configuration
            scheduler.Views.Clear();//removes all views from the scheduler
            scheduler.Views.Add(new WeekView());// adds a tab with the week view
            var units = new UnitsView("staff", "owner_id") { Label = "Staff" };// initializes the units view
 
            var users = AppUserManagerProvider.Users;
            var staff = new List<object>();
            foreach (var user in users)
            {
                if (AppUserManagerProvider.GetUserRolesName(user.Id).Contains("Employee"))
                {
                    staff.Add(new { key = user.Id, label = user.UserName });
                }
            }
 
            units.AddOptions(staff);// sets X-Axis items to names of employees  
            scheduler.Views.Add(units);//adds a tab with the units view
            scheduler.Views.Add(new MonthView()); // adds a tab with the Month view
            scheduler.InitialView = units.Name;// makes the units view selected initially
 
            scheduler.Config.active_link_view = units.Name;
            #endregion
 
            #region lightbox configuration
            var text = new LightboxText("text", "Task") { Height = 20, Focus = true };// initializes a text input with the label 'Task'
            scheduler.Lightbox.Add(text);// adds the control to the lightbox
            var description = new LightboxText("details", "Details") { Height = 80 };// initializes a text input with the label 'Task'
            scheduler.Lightbox.Add(description);
            var status = new LightboxSelect("status_id", "Status");// initializes a dropdown list with the label 'Status'
            status.AddOptions(Repository.GetAll<Status>().Select(s => new
            {
                key = s.id,
                label = s.title
            }));// populates the list with values from the 'Statuses' table
            scheduler.Lightbox.Add(status);
            //add users list 
            var sUser = new LightboxSelect("owner_id", "Employee");
            sUser.AddOptions(staff);
            //--
            scheduler.Lightbox.Add(sUser);
 
            scheduler.Lightbox.Add(new LightboxTime("time"));// initializes and adds a control area for setting start and end times of a task
            #endregion
 
            #region data
            scheduler.EnableDataprocessor = true;// enables dataprocessor
            scheduler.LoadData = true;//'says' to send data request after scheduler initialization 
            scheduler.Data.DataProcessor.UpdateFieldsAfterSave = true;// Tracks after server responses for modified event fields 
            #endregion
 
            Employees[] employees = users.Select(o => new Employees()
            {
                key = o.Id,
                userName = o.UserName
            }).ToArray();
 
            List<Status> statuses = Repository.GetAll<Status>().ToList();
 
            var js = new DataContractJsonSerializer(typeof(Employees[]));
            var ms = new MemoryStream();
            js.WriteObject(ms, employees);
            ms.Position = 0;
            var sr = new StreamReader(ms);
            var json = sr.ReadToEnd();
            sr.Close();
            ms.Close();
            var model = new SystemModel(scheduler, json,statuses);
            return View(model);
        }
 
        private bool RoleIs(string role)
        {
            return Request.IsAuthenticated && User.IsInRole(role);
        }
 
        public ActionResult Employee()
        {
            var scheduler = new DHXScheduler(this);
 
            #region check rights
            if (!RoleIs("Employee"))
            {
                return RedirectToAction("Index", "System");
            }
            #endregion
 
            #region configuration
 
            scheduler.Config.separate_short_events = true;
            scheduler.Config.hour_size_px = 88;
 
            scheduler.Extensions.Add(SchedulerExtensions.Extension.Cookie);// activates the extension to provide cookie
            scheduler.Extensions.Add(SchedulerExtensions.Extension.Tooltip);// activates the extension to provide tooltips
            var template = "<b>Task:</b> {text}<br/><b>Start date:</b>";
            template += "<%= scheduler.templates.tooltip_date_format(start) %><br/><b>End date:</b>";
            template += "<%= scheduler.templates.tooltip_date_format(end) %>";
            scheduler.Templates.tooltip_text = template; // sets template for the tooltip text
 
            scheduler.Skin = DHXScheduler.Skins.Flat;
            #endregion
 
            #region views
            scheduler.Views.Clear();//removes all views from the scheduler 
            scheduler.Views.Add(new WeekAgendaView());// adds a tab with the weekAgenda view
            scheduler.Views.Add(new MonthView()); // adds a tab with the Month view
            scheduler.InitialView = scheduler.Views[0].Name;// makes the weekAgenda view selected initially
            #endregion
 
            #region data
            scheduler.SetEditMode(EditModes.Forbid);// forbids editing of tasks  
            scheduler.LoadData = true;//'says' to send data request after scheduler initialization 
            scheduler.DataAction = "Tasks";//sets a controller action which will be called for data requests 
            scheduler.Data.Loader.PreventCache();// adds the current ticks value to url to prevent caching of the request 
            #endregion
 
            return View(scheduler);
        }
 
 
        public ActionResult Data()
        {
            //if the user is not authorized or not in the Manager Role, returns the empty dataset
            if (!RoleIs("Manager")) return new SchedulerAjaxData();
 
            var tasks = Repository.GetAll<Task>()
                .Join(Repository.GetAll<Status>(), task => task.status_id, status => status.id, (task, status) => new { Task = task, Status = status })
                .Select(o => new
                {
                    o.Status.color,
                    o.Task.id,
                    o.Task.owner_id,
                    o.Task.details,
                    o.Task.end_date,
                    o.Task.start_date,
                    o.Task.text,
                    o.Task.status_id
                });
 
            var resp = new SchedulerAjaxData(tasks);
            return resp;
 
        }
        public ActionResult Save(Task task)
        {
            // an action against particular task (updated/deleted/created) 
            var action = new DataAction(Request.Form);
            #region check rights
            if (!RoleIs("Manager"))
            {
                action.Type = DataActionTypes.Error;
                return new AjaxSaveResponse(action);
            }
            #endregion
 
            task.creator_id = Guid.Parse(AppUserManagerProvider.UserId);
            try
            {
                switch (action.Type)
                {
                    case DataActionTypes.Insert:
                        Repository.Insert(task);
                        break;
                    case DataActionTypes.Delete:
                        Repository.Delete(task);
                        break;
                    case DataActionTypes.Update:
                        Repository.Update(task);
                        break;
                }
                action.TargetId = task.id;
            }
            catch (Exception)
            {
                action.Type = DataActionTypes.Error;
            }
 
            var color = Repository.GetAll<Status>().SingleOrDefault(s => s.id == task.status_id);
 
            var result = new AjaxSaveResponse(action);
            result.UpdateField("color", color.color);
            return result;
        }
 
        public ActionResult Tasks()
        {
            #region check rights
            if (!RoleIs("Employee"))
            {
                return new SchedulerAjaxData();//returns the empty dataset
            }
            #endregion
 
 
            var result = Repository.GetAll<Task>()
                .Join(Repository.GetAll<Status>(), task => task.status_id, status => status.id, (task, status) => new { Task = task, Status = status })
                .Select(o => new
                {
                    o.Status.color,
                    o.Task.id,
                    o.Task.owner_id,
                    o.Task.details,
                    o.Task.end_date,
                    o.Task.start_date,
                    o.Task.text,
                    o.Task.status_id
                });
 
            var tasks = new List<object>();
 
            foreach (var r in result.ToList())
            {
                if (r.owner_id == Guid.Parse(AppUserManagerProvider.UserId))
                {
                    tasks.Add(new
                    {
                        r.color,
                        r.id,
                        r.owner_id,
                        r.details,
                        r.end_date,
                        r.start_date,
                        r.text,
                        r.status_id
                    });
                }
            }
 
            var resp = new SchedulerAjaxData(tasks);
            return resp;
        }
 
        public ActionResult TaskDetails(int? id)
        {
            #region check rights
 
            if (!RoleIs("Employee"))
            {
                return RedirectToAction("Index", "System");
            }
            #endregion
 
            var task = default(Task);
            if (id != null)
            {
                task = Repository.GetAll<Task>().FirstOrDefault(o => o.id == id);
 
                if (task.owner_id != Guid.Parse(AppUserManagerProvider.UserId))
                    task = default(Task);
            }
 
            var statuses = Repository.GetAll<Status>().ToArray();
 
            ViewData["status"] = task != default(Task) ? task.status_id : statuses[0].id;
            ViewData["user"] = User.Identity.Name;
            return View(new TaskDetails(task, statuses));
        }
 
        public ActionResult UpdateStatus(int? id)
        {
            if (!RoleIs("Employee") || this.Request.Form["result"] != "Update" || id == null)
                return RedirectToAction("Index", "System");
 
 
            var task = Repository.GetAll<Task>().SingleOrDefault(ev => ev.id == id);
 
            if (task == default(Task) && task.owner_id != Guid.Parse(AppUserManagerProvider.UserId))
                return RedirectToAction("Index", "System");
 
            task.status_id = int.Parse(this.Request.Form["status_id"]);
            UpdateModel(task);
            Repository.Update(task);
 
            return RedirectToAction("Index", "System");
        }
 
        public class SystemModel
        {
            public DHXScheduler Scheduler { get; set; }
            public string Users { get; set; }
            public List<Status> Statuses { get; set; } 
            public SystemModel(DHXScheduler sched, string users,List<Status> statuses )
            {
                Scheduler = sched;
                Users = users;
                Statuses = statuses;
            }
        }
 
 
        //class for json string
        [DataContract]
        public class Employees
        {
            [DataMember]
            public string key { get; set; }
            [DataMember]
            public string userName { get; set; }
        }
    }
}

The controller file in our application SystemController.cs defines the next controls:

- Index - Manager - Employee

In all the actions defined on this and further steps (except Index()), we will do 'rights checking' to protect the app from unauthorized access, in case a user skips the login page and loads our server-side login script URL directly in the browser. To avoid repeating one and the same code several times, we'll also specify a function (RoleIs) that will implement such checking functionality and later, when we need to check rights, we'll just call this function.

Data ActionResult loads data from the database. Save ActionResult saves changes to the database.

4. Move to Solution Explorer → RouteConfig.cs file.

5. Rewrite the default map route in the opened file as follows:

routes.MapRoute(
                "Default", // the route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "System", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
  • Style css

1. Add→ Style Sheet to the Content folder (create if it does not exist) and named it Site.css

This file contains styles for all site.

2. Paste the following code to the created file:

/*----------------------------------------------------------
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
----------------------------------------------------------*/
body {
    background-color: #ffffff;
    font-size: 14px;
    font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
    margin: 0;
    padding: 0;
    color: #000000;
}
 
a:link {
    color: #034af3;
    text-decoration: underline;
}
 
a:visited {
    color: #505abc;
}
 
a:hover {
    color: #1d60ff;
    text-decoration: none;
}
 
a:active {
    color: #12eb87;
}
 
p, ul {
    margin-bottom: 20px;
    line-height: 1.6em;
}
 
/* HEADINGS   
----------------------------------------------------------*/
h1, h2, h3, h4, h5, h6 {
    font-size: 18px;
    color: #000;
    font-family: Arial, Helvetica, sans-serif;
}
 
h1 {
    font-size: 36px;
    padding-bottom: 0;
    margin-bottom: 0;
}
 
h2 {
    font-size: 30px;
    padding: 0 0 10px 0;
}
 
h3 {
    font-size: 24px;
}
 
h4 {
    font-size: 18em;
}
 
h5, h6 {
    font-size: 14em;
}
 
/* this rule styles <h2> tags that are the 
first child of the left and right table columns */
.rightColumn > h1, .rightColumn > h2, .leftColumn > h1, .leftColumn > h2 {
    margin-top: 0;
}
/**/
body, html {
    height: 90%;
    margin: 0;
    padding: 0;
}
 
/* PRIMARY LAYOUT ELEMENTS   
----------------------------------------------------------*/
 
/* you can specify a greater or lesser percentage for the 
page width. Or, you can specify an exact pixel width. */
.page {
    height: 100%;
    margin-left: auto;
    margin-right: auto;
}
 
#header {
    position: relative;
    margin-bottom: 0px;
    color: #000;
    padding: 0;
    border-bottom: #5780AD 3px solid;
}
 
    #header h1 {
        font-weight: bold;
        padding: 5px 0;
        margin: 0;
        color: #fff;
        border: none;
        line-height: 2em;
        font-family: Arial, Helvetica, sans-serif;
    }
 
#main {
    padding: 30px 30px 15px 30px;
    background-color: #fff;
    margin-bottom: 30px;
    _height: 1px; /* only IE6 applies CSS properties starting with an underscore */
}
 
#footer {
    color: #000000;
    text-align: center;
    line-height: normal;
    bottom: 0;
    margin-bottom: 0;
}
 
#footer-top-border {
    border-top: 1px solid #CECECE;
}
 
/* FORM LAYOUT ELEMENTS   
----------------------------------------------------------*/
 
fieldset {
    margin: 1em 0;
    padding: 1em;
    border: 1px solid #ffffff;
}
 
    fieldset p {
        margin: 2px 12px 10px 10px;
    }
 
 
 
input[type="text"] {
    width: 200px;
    border: 1px solid #CCC;
}
 
input[type="password"] {
    width: 200px;
    border: 1px solid #CCC;
}
 
 
/* MISC  
----------------------------------------------------------*/
.clear {
    clear: both;
}
 
.error {
    color: Red;
}
 
#menucontainer {
    margin-top: 40px;
}
 
div#title {
    display: block;
    float: left;
    text-align: left;
}
 
#logindisplay {
    display: block;
    text-align: right;
    margin: 10px;
    color: #000000;
}
 
    #logindisplay a:link {
        color: #000000;
        text-decoration: underline;
    }
 
    #logindisplay a:visited {
        color: #000000;
        text-decoration: underline;
    }
 
    #logindisplay a:hover {
        color: #000000;
        text-decoration: none;
    }
 
/* Styles for validation helpers
-----------------------------------------------------------*/
.field-validation-error {
    color: #ff0000;
}
 
.field-validation-valid {
    display: none;
}
 
.input-validation-error {
    border: 1px solid #ff0000;
    background-color: #ffeeee;
}
 
.validation-summary-errors {
    font-weight: bold;
    color: #ff0000;
}
 
.validation-summary-valid {
    display: none;
}
 
/* Styles for editor and display helpers
----------------------------------------------------------*/
.display-label,
.editor-label,
.display-field,
.editor-field {
    margin: 0.5em 0;
}
 
.text-box {
    width: 30em;
}
 
    .text-box.multi-line {
        height: 6.5em;
    }
 
.tri-state {
    width: 6em;
}
/*horizontal list*/
ul.hr {
    margin: 0;
    padding: 4px;
}
 
    ul.hr li {
        display: inline;
        margin-right: 5px;
        padding: 3px;
    }
 
 
.center-block {
    width: 220px;
    padding: 10px;
    margin: 0 auto;
}
 
.row {
    margin-left: 15px;
    margin-right: 15px;
}
 
.text-left {
    text-align: left;
}
 
.text-center {
    text-align: center;
}
 
.text-right {
    text-align: right;
}
 
.form-group {
    margin-top: 10px;
    margin-bottom: 10px;
}
 
input[type="text"], input[type="password"], input[type="checkbox"] {
    padding: 7px 9px;
}
 
input[type="submit"].dhx_save_btn_set:hover {
    background-color: #528CCA;
}
 
input[type="submit"].dhx_save_btn_set:active {
    background-color: #6BA5E3;
}
 
 
input[type="submit"].dhx_delete_btn_set:hover {
    background-color: #CCCCCC;
}
 
input[type="submit"].dhx_delete_btn_set:active {
    background-color: #949494;
}
 
.details {
    white-space: pre;
    border: 1px solid #eeeeee;
    padding: 10px;
}
 
.form-bordered {
    border: 1px solid #eeeeee;
}
 
div.dhx_cal_ltext {
    height: 26px !important;
}
/*for month events----------*/
.dhx_cal_event_clear {
    padding: 2px 0 2px 5px !important;
    -ms-border-radius: 13px !important;
    border-radius: 13px !important;
    line-height: 14px !important;
    color: white !important;
}

That's all. You can download task manager sample in MVC5

previous button step four


comments powered by Disqus