Scheduler UI MVC Custom Editor Template Issues

4 posts, 0 answers
  1. Roy
    Roy avatar
    30 posts
    Member since:
    Oct 2007

    Posted 08 Jul 2014 Link to this post

    I am using the MVC extensions to try and accomplish what I am trying to do here. I have been trying to get the Scheduler custom editor to work. I have followed the example provided in the link ?? But still when I call double click the scheduler instead of giving me my custom template it just provides all the properties of the model on a pop-up window. I have included here the method from the controller , as well as my view and the template I am trying to implement,along with the viewmodel being used. I have also provided screen shots of the directory structure and the pop-up. I have not yet created the Appointments_Create, Appointments_Update or Appointments_Destory at this time because I just wanted the pop-up to load correctly.


    //*********************************
    //*     Controller Method         *
    //*********************************
            [Authorize(Roles = "Customer")]  // need to add client role also
            public virtual JsonResult Appointments_Read([DataSourceRequest] DataSourceRequest request)
            {
                var sbasUser = new SBASUser();
                var user = sbasUser.GetSBASUserByEmail(User.Identity.GetUserName());

                var appointments = new Appointment().GetAllCustomerAppointments(user.UserId);
                var t = appointments.ToList().Select(m => new AppointmentModel
                {
                    AppointmentId = m.AppointmentId,
                    Title = m.Title,
                    Start = m.Start,
                    End = m.End,
                    StartTimezone = m.StartTimezone,
                    EndTimezone = m.EndTimezone,
                    Description = m.Description,
                    IsAllDay = m.IsAllDay,
                    RecurrenceID = m.RecurrenceId,
                    RecurrenceException = m.RecurrenceException,
                    RecurrenceRule = m.RecurrenceRule,
                    AddressId = m.AddressId,
                    CustomerId = m.CustomerId,
                    ClientId = m.ClientId,
                    ServiceTypeId = m.ServiceTypeId
                }).AsQueryable();

                return Json(t.ToDataSourceResult(request));
            }
            
    //*********************************
    //*          Index.cshtml         *
    //*********************************
    @{
        Layout = "~/Views/Shared/_CustomerLoggedInLayout.cshtml";
    }

    <div class="row">
        <div class="col-lg-12">
            <h1>Appointments Calendar</h1>
        </div>
    </div>
    @{
        var startdate = DateTime.Now;
    }
    <nav class="navbar navbar-default" role="navigation">
        <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li class="btn btn-primary" >Submit</li>
                </ul>
            </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
    </nav>
    <div class="row">
        <div class="col-lg-12">
        @(Html.Kendo().Scheduler<SBAS_Web.Models.AppointmentModel>()
        .Name("scheduler")
        .Date(new DateTime(startdate.Year, startdate.Month, startdate.Day))
        .StartTime(new DateTime(startdate.Year, startdate.Month, startdate.Day, 8, 00, 00))
        .Height(500)
        .Views(views =>
        {
            views.DayView(dayView=>dayView.Selected(true));
            views.WeekView();
            views.MonthView();
        })
        .Editable(editable => editable.TemplateName("CustomEditorTemplate"))
        .Timezone("Etc/UTC")
        .DataSource(d => d
            .Model(m =>
            {
                m.Id(f => f.AppointmentId);
                m.Field(f => f.Title).DefaultValue("No title");
                m.RecurrenceId(f => f.RecurrenceID);
            })                     
            .Events(e => e.Error("error_handler"))
            .Read("Appointments_Read", "Appointment")

        )
            )
        </div>
    </div>
    <div id="map_canvas">

    </div>

    <script type="text/javascript">
        function error_handler(e) {
            if (e.errors) {
                var message = "Errors:\n";
                $.each(e.errors, function (key, value) {
                    if ('errors' in value) {
                        $.each(value.errors, function () {
                            message += this + "\n";
                        });
                    }
                });
                alert(message);

                var scheduler = $("#scheduler").data("kendoScheduler");
                scheduler.one("dataBinding", function(e) {
                    //prevent saving if server error is thrown
                    e.preventDefault();
                });
            }
        }
    </script>




    //*********************************
    //*   AppointmentModel class      *
    //*********************************

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Kendo.Mvc.UI;
    using SBAS_Core.Common.Attributes;

    namespace SBAS_Web.Models
    {
        public class AppointmentModel : ISchedulerEvent
        {
            private DateTime _start;
            private DateTime _end;

            public long AppointmentId { get; set; }
            [Required]
            public string Title { get; set; }
            public string Description { get; set; }
            [Required]
            public DateTime Start
            { get  { return _start; }
              set  { _start = value.ToUniversalTime(); }
            }
            [Required]
            [DateGreaterThan(OtherField = "Start")]
            public DateTime End
            { get { return _end; }
              set {  _end = value.ToUniversalTime(); }
            }
            public bool IsAllDay { get; set; }
            public string RecurrenceRule { get; set; }
            public int? RecurrenceID { get; set; }
            public string RecurrenceException { get; set; }
            public string StartTimezone { get; set; }
            public string EndTimezone { get; set; }
            public long CustomerId { get; set; }
            public long ClientId { get; set; }
            public bool UseClientAddress { get; set; }
            public long? AddressId { get; set; }
            //For type of service this appointment is for
            public long ServiceTypeId { get; set; }
            public string AddressLine1 { get; set; }
            public string AddressLine2 { get; set; }
            public long SelectedCityId { get; set; }
            public long SelectedStateId { get; set; }
            [Display(Name = "City")]
            public SelectList CityList { get; set; }
            [Display(Name = "State")]
            public SelectList StateList { get; set; }
            public string ZipCode { get; set; }
            public decimal? Longitude { get; set; }
            public decimal? Latitude { get; set; }
        }
    }




    //***********************************
    //*   CustomEditorTemplate.cshtml   *
    //***********************************

    @model SBAS_Web.Models.AppointmentModel
    @{
        //required in order to render validation attributes
        ViewContext.FormContext = new FormContext();
    }

    @functions{
        public Dictionary<string, object> generateDatePickerAttributes(
               string elementId,
               string fieldName,
               string dataBindAttribute,
               Dictionary<string, object> additionalAttributes = null)
        {

            Dictionary<string, object> datePickerAttributes = additionalAttributes != null ? new Dictionary<string, object>(additionalAttributes) : new Dictionary<string, object>();

            datePickerAttributes["id"] = elementId;
            datePickerAttributes["name"] = fieldName;
            datePickerAttributes["data-bind"] = dataBindAttribute;
            datePickerAttributes["required"] = "required";
            datePickerAttributes["style"] = "z-index: inherit;";

            return datePickerAttributes;
        }
    }

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.Title))
    </div>
    <div data-container-for="title" class="k-edit-field">
        @(Html.TextBoxFor(model => model.Title, new { @class = "k-textbox", data_bind = "value:title" }))
    </div>

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.Start))
    </div>
    <div data-container-for="start" class="k-edit-field">

        @(Html.Kendo().DateTimePickerFor(model => model.Start)
            .HtmlAttributes(generateDatePickerAttributes("startDateTime", "start", "value:start,invisible:isAllDay")))

        @(Html.Kendo().DatePickerFor(model => model.Start)
            .HtmlAttributes(generateDatePickerAttributes("startDate", "start", "value:start,visible:isAllDay")))

        <span data-bind="text: startTimezone"></span>
        <span data-for="start" class="k-invalid-msg"></span>
    </div>

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.End))
    </div>
    <div data-container-for="end" class="k-edit-field">

        @(Html.Kendo().DateTimePickerFor(model => model.End)
            .HtmlAttributes(generateDatePickerAttributes(
                "endDateTime",
                "end",
                "value:end,invisible:isAllDay",
                new Dictionary<string, object>() {{"data-dateCompare-msg", "End date should be greater than or equal to the start date"}})))
            
        @(Html.Kendo().DatePickerFor(model => model.End)
            .HtmlAttributes(generateDatePickerAttributes(
                "endDate",
                "end",
                "value:end,visible:isAllDay",
                new Dictionary<string, object>() {{"data-dateCompare-msg", "End date should be greater than or equal to the start date"}})))

        <span data-bind="text: endTimezone"></span>
        <span data-for="end" class="k-invalid-msg"></span>
    </div>

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.IsAllDay))
    </div>
    <div data-container-for="isAllDay" class="k-edit-field">
        <input data-bind="checked: isAllDay" data-val="true" id="IsAllDay" name="IsAllDay" type="checkbox" />
    </div>

    <div class="endTimezoneRow">
        <div class="k-edit-label"></div>
        <div class="k-edit-field">
            <label class="k-check">
                <input checked="checked" class="k-timezone-toggle" type="checkbox" value="true" />
                Use separate start and end time zones
            </label>
        </div>
    </div>
    <script>
        $(".k-timezone-toggle").on("click", function () {
            var isVisible = $(this).is(":checked");
            var container = $(this).closest(".k-popup-edit-form");

            var endTimezoneRow = container.find("label[for='EndTimezone']").parent().add(container.find("div[data-container-for='endTimezone']"));
            endTimezoneRow.toggle(isVisible);

            if (!isVisible) {
                var uid = container.attr("data-uid");
                var scheduler = $("\#scheduler").data("kendoScheduler");
                var model = scheduler.dataSource.getByUid(uid);
                model.set("endTimezone", null);
            }
        });

        var endTimezone = '${data.endTimezone}';

        if (!endTimezone || endTimezone == "null") {
            $(".k-timezone-toggle").trigger('click');
        }
    </script>

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.StartTimezone))
    </div>
    <div data-container-for="startTimezone" class="k-edit-field">
        @(Html.Kendo().TimezoneEditorFor(model => model.StartTimezone)
            .HtmlAttributes(new { data_bind = "value:startTimezone" }))
    </div>

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.EndTimezone))
    </div>
    <div data-container-for="endTimezone" class="k-edit-field">
        @(Html.Kendo().TimezoneEditorFor(model => model.EndTimezone)
            .HtmlAttributes(new { data_bind = "value:endTimezone" }))
    </div>

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.RecurrenceRule))
    </div>
    <div data-container-for="recurrenceRule" class="k-edit-field">
        @(Html.Kendo().RecurrenceEditorFor(model => model.RecurrenceRule)
            .HtmlAttributes(new { data_bind = "value:recurrenceRule" }))
    </div>

    <div class="k-edit-label">
        @(Html.LabelFor(model => model.Description))
    </div>
    <div data-container-for="description" class="k-edit-field">
        @(Html.TextAreaFor(model => model.Description, new { @class = "k-textbox", data_bind = "value:description" }))
    </div>

    @{
        ViewContext.FormContext = null;
    }
  2. Roy
    Roy avatar
    30 posts
    Member since:
    Oct 2007

    Posted 08 Jul 2014 in reply to Roy Link to this post

    I forgot the link that had the example that I tried implementing, here is the link http://www.telerik.com/support/code-library/custom-editor-9fd60fca3c02
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Roy
    Roy avatar
    30 posts
    Member since:
    Oct 2007

    Posted 09 Jul 2014 Link to this post

    Ok I have resolved this, I needed to create another class and apply the ISchedulerEvent Interface then I was ok, also found that the link to the example above is broken with the logic toa Start and End Timezone thre is no editor for those that is being implemented in the examples.
  5. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 10 Jul 2014 Link to this post

    Hi Roy,

    From your last reply is not clear what is the exact issue that you are experiencing as the linked demo have "startTimezone" and "endTimezone" editors (as seen in this screencast) - could you please clarify?

    Also from the previous posts I notice that the editor template is not nested inside the "EditorTemplates" folder which is mandatory - for more information you can check the following help article:

    Regards,
    Vladimir Iliev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top
UI for ASP.NET MVC is VS 2017 Ready