This is a migrated thread and some comments may be shown as answers.

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

5 Answers 509 Views
Scheduler
This is a migrated thread and some comments may be shown as answers.
Denis Buchwald
Top achievements
Rank 1
Denis Buchwald asked on 08 Apr 2015, 04:09 PM

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")
        )
)

5 Answers, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 10 Apr 2015, 11:14 AM
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.

 
0
Denis Buchwald
Top achievements
Rank 1
answered on 13 Apr 2015, 05:57 PM
Thank you for the sample code, Vladimir. This worked like a charm.
0
HDC
Top achievements
Rank 1
answered on 16 May 2015, 04:17 PM
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.

0
Georgi Krustev
Telerik team
answered on 20 May 2015, 07:03 AM
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
0
HDC
Top achievements
Rank 1
answered on 20 May 2015, 12:03 PM
Thank you Georgi. All is working well now.
Tags
Scheduler
Asked by
Denis Buchwald
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Denis Buchwald
Top achievements
Rank 1
HDC
Top achievements
Rank 1
Georgi Krustev
Telerik team
Share this question
or