How to filter array type of resource (e.g. Attendees)?

6 posts, 0 answers
  1. Denis Buchwald
    Denis Buchwald avatar
    28 posts
    Member since:
    Apr 2010

    Posted 08 Apr 2015 Link to this post

    I'm trying to filter calendar MeetingAttendees which can have multiple users. I've built a filter and tested with various options, but it doesn't work. The basic example shows how to filter a calendar owner (which is a single value) and it works fine for me. But Attendees is an array and when I'm trying to filter that all my events disappear.

    Here is my filter: 

        <script type="text/javascript">
            $(function () {
                $("#teamMembers :checkbox").change(function (e) {
     
     
                    var checked = $.map($("#teamMembers :checked"), function (checkbox) {
                        return parseInt($(checkbox).val());
                    });
                    //alert(checked);
                    var filter = {
                        logic: "or",
                        filters: $.map(checked, function (value) {
                            return {
                                operator: "eq",
                                field: "Attendees",
                                value: value
                            };
                        })
                    };
                    var scheduler = $("#scheduler").data("kendoScheduler");
                    scheduler.dataSource.filter(filter);
     
     
                });
            })
        </script>
    }

     

     

    Here is the code that loads calendar events:

    public virtual IQueryable<MeetingViewModel> GetAll()
    {
        return db.Meetings.ToList().Select(meeting => new MeetingViewModel
        {
            MeetingID = meeting.MeetingID,
            Title = meeting.Title,
            Start = DateTime.SpecifyKind(meeting.Start, DateTimeKind.Utc),
            End = DateTime.SpecifyKind(meeting.End, DateTimeKind.Utc),
            StartTimezone = meeting.StartTimezone,
            EndTimezone = meeting.EndTimezone,
            Description = meeting.Description,
            IsAllDay = meeting.IsAllDay,
            SupportGroupId = meeting.SupportGroupId,
            RecurrenceRule = meeting.RecurrenceRule,
            RecurrenceException = meeting.RecurrenceException,
            RecurrenceID = meeting.RecurrenceID,
            Attendees = meeting.MeetingAttendees.Select(m => m.AttendeeID).ToArray(),
            ActivityTypeId = meeting.ActivityTypeId
        }).AsQueryable();
    }

     

     

     

    Here is my custom editor template:

    @model Itsws.Models.MeetingViewModel
    @{
        //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>
     
    <div class="k-edit-label">
        @(Html.LabelFor(model => model.ActivityTypeId))
    </div>
    <div data-container-for="ActivityTypeId" class="k-edit-field">
        @(Html.Kendo().DropDownListFor(model => model.ActivityTypeId)
            .HtmlAttributes(new { data_bind = "value:ActivityTypeId", style = "width: 280px" })
            .DataTextField("Text")
            .DataValueField("Value")
            .OptionLabel("None")
            .ValuePrimitive(true)
            .Template("<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#")
            .BindTo(ViewBag.ActivityTypes).ToClientTemplate()
        )
    </div>
     
    <div class="k-edit-label">
        @(Html.LabelFor(model => model.SupportGroupId))
    </div>
    <div data-container-for="ActivityTypeId" class="k-edit-field">
        @(Html.Kendo().DropDownListFor(model => model.SupportGroupId)
            .HtmlAttributes(new { data_bind = "value:SupportGroupId", style = "width: 280px" })
            .DataTextField("Text")
            .DataValueField("Value")
            .OptionLabel("None")
            .ValuePrimitive(true)
            .Template("<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#")
            .BindTo(ViewBag.SupportGroups).ToClientTemplate()
        )
    </div>
     
    <div class="k-edit-label">
        @(Html.LabelFor(model => model.Attendees))
    </div>
    <div data-container-for="Attendees" class="k-edit-field">
        @(Html.Kendo().MultiSelectFor(model => model.Attendees)
            .HtmlAttributes(new { data_bind = "value:Attendees" })
            .DataTextField("Text")
            .DataValueField("Value")
            .ValuePrimitive(true)
            .TagTemplate("<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#")
            .ItemTemplate("<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#")
            .BindTo(ViewBag.TeamMembers).ToClientTemplate()
        )
    </div>
     
    @{
        ViewContext.FormContext = null;
    }

     

     

     

    Here is the sheduler code:

    @(Html.Kendo().Scheduler<Itsws.Models.MeetingViewModel>()
            .Name("scheduler")
            .Date(DateTime.Today)
            .Editable(editable =>
            {
                editable.TemplateName("CustomEditorTemplate");
            })
            .StartTime(new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 7, 00, 00))
            .Height(600)
            .Views(views =>
            {
                views.DayView();
                views.WeekView(weekView => weekView.Selected(true));
                views.MonthView();
                views.AgendaView();
                views.TimelineView();
            })
            .Timezone("Etc/UTC")
            .DataSource(d => d
                    .Model(m =>
                    {
                        m.Id(f => f.MeetingID);
                        m.Field(f => f.Title).DefaultValue("No title");
                        m.RecurrenceId(f => f.RecurrenceID);
                        m.Field(f => f.Title).DefaultValue("No title");
                    })
                .Read("Meetings_Read", "Scheduler")
                .Create("Meetings_Create", "Scheduler")
                .Destroy("Meetings_Destroy", "Scheduler")
                .Update("Meetings_Update", "Scheduler")
            )
    )

  2. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 10 Apr 2015 Link to this post

    Hi Denis,

    For your convenience I created small example of filtering multiple resource using checkboxes which you can use as baseline to achieve the desired behavior:


    Regards,
    Vladimir Iliev
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Denis Buchwald
    Denis Buchwald avatar
    28 posts
    Member since:
    Apr 2010

    Posted 13 Apr 2015 in reply to Vladimir Iliev Link to this post

    Thank you for the sample code, Vladimir. This worked like a charm.
  5. HDC
    HDC avatar
    214 posts
    Member since:
    Dec 2010

    Posted 16 May 2015 Link to this post

    Hi,

    I'm having the same problem Denis has. I followed the example (source code) but face some difficulties. In the
    line ‘if (item.indexOf(checked[i]) < 0)’ the code fails on ‘indexOf’, because item and value are undefined.

    I’m using the Razor syntax. Any chance on having some sample code on that?

     
    Regards,

    Heli.

  6. Georgi Krustev
    Admin
    Georgi Krustev avatar
    3706 posts

    Posted 20 May 2015 Link to this post

    Hi Heli,

    The shared code is relevant to ASP.NET MVC wrapper too, because the filtration done in the demo is performed on the client anyway. If the item variable is undefined, then you will need to verify that the "field" option is defined correctly. Also note that operator function will be called only if the client filtering is used.

    If you are still experiencing any troubles, then I will ask you to send us a repro demo. This will help us to review the problem and follow you up with more details.

    Regards,
    Georgi Krustev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  7. HDC
    HDC avatar
    214 posts
    Member since:
    Dec 2010

    Posted 20 May 2015 in reply to Georgi Krustev Link to this post

    Thank you Georgi. All is working well now.
Back to Top
UI for ASP.NET MVC is VS 2017 Ready