Kendo Grid and two columns.ForeignKey

1 Answer 18 Views
DropDownList Grid
David
Top achievements
Rank 1
David asked on 21 Feb 2024, 12:26 PM

I need to send a model to my controller action. I have created a Kendo grid:

Html.Kendo().Grid<XXXX.WebUI.Models.Employees.LocationsListViewModel>()
    .Name("EmployeeLocationsGrid")
    .Columns(columns => {
        columns.Select().Width(45);
        columns.Bound(c => c.UIDEmployee).Visible(false);
        columns.Bound(c => c.UIDEmployee_Location).Title("Id").Width(50);
        if (Model.LocationsEntities != null)
        {
            columns.ForeignKey(f => f.UIDLocation, Model.LocationsEntities?.Items, "UIDEntity", "Name")
                .Title("Location")
                .EditorTemplateName("FieldListLocations")
                .EditorViewData(new { locations = Model.LocationsEntities.Items })
                .Width(200);
        }
        if (Model.LocationsEntities != null)
        {
            columns.ForeignKey(f => f.UIDSublocation, Model.SublocationsEntities?.Items, "UIDEntity", "Name")
                    .Title("Sublocation")
                    .EditorTemplateName("FieldListSublocations")
                    .EditorViewData(new { sublocations = Model.SublocationsEntities.Items })
                    .Width(200);
        }
        columns.Bound(c => c.Main)
            .Title("Main")
            .EditorTemplateName("FieldCheckBox")
            .ClientTemplate("#= Main ? 'Yes' : 'No' #")
            .Width(100);
        columns.Bound(c => c.PercentageOfDedication)
            .Title("% Dedication")
            .EditorTemplateName("FieldNumericTextBox")
            .Format("{0} %")
            .Width(200);
        columns.Bound(c => c.StartDate)
            .Title("Start Date")
            .ClientTemplate("#= kendo.toString(kendo.parseDate(StartDate), 'dd/MM/yyyy') #")
            .EditorTemplateName("FieldDateOnlyPicker")
            .Width(200);
        columns.Bound(c => c.EndDate)
            .Title("End Date")
            .ClientTemplate("#= EndDate != null ? kendo.toString(kendo.parseDate(EndDate), 'dd/MM/yyyy') : '<strong>Currently</strong>' #")
            .EditorTemplateName("FieldDateOnlyPicker")
            .Width(200);
        columns.Bound(c => c.Comments)
            .Title("Comments")
            .EditorTemplateName("FieldTextArea")
            .Width(250);
        columns.Command(command => {
            command.Edit().Text(" ").UpdateText(" ").CancelText(" ").IconClass("bi bi-pencil-square").HtmlAttributes(new { @class = "btn btn-outline-primary", title = "Edit" });
            command.Custom("deleteLocation")
                .Click("function(e) { var dataItemLoc = this.dataItem($(e.target).closest('tr')); window.i3.OnDeleteEmployeeLocation(dataItemLoc); }")
                .Text(" ").IconClass("bi bi-trash3")
                .HtmlAttributes(new { @class = "btn btn-outline-primary", title = "Delete" });
        }).Title("Actions");
    })
    .NoRecords(s => s.Template("<span class='ms-3 mt-3'><i class='bi bi-people-fill me-2'></i><strong>This employee was not assigned to any location.</strong></span>"))
    .AutoBind(true)
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .Sortable(sorting => sorting.Enabled(true))
    .Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple).DragToSelect(false))
    .Events(events => events
        .Sort("window.i3.OnColumnSorted").Save("window.i3.OnSaveLocation")
    )
    .DataSource(ds => ds
        .Ajax()
        .Model(gridModel =>
        {
            gridModel.Id(entity => entity.UIDEmployee_Location);
            gridModel.Field(p => p.UIDEmployee_Location).Editable(false);
            gridModel.Field(p => p.UIDEmployee).Editable(false).DefaultValue(Model.UIDEmployee);
            gridModel.Field(p => p.UIDLocation).Editable(true);
            gridModel.Field(p => p.UIDSublocation).Editable(true);
            gridModel.Field(p => p.UIDStatus).Editable(false);
            gridModel.Field(p => p.UIDPosition).Editable(false);
        })
        .Read(r => r.Action("GetAllEmployeeLocations", "Employees", new { EmployeeID = Model.UIDEmployee }))
        .Events(events => events
            .RequestEnd("window.i3.OnRequestEndLocation")
        )
        .PageSize(10)
    )
)

This data reaches me at this event where I process it:

public OnSaveLocation(e: kendo.ui.GridSaveEvent): void {
    e.preventDefault();

    const gridLocation = $("#EmployeeLocationsGrid").data("kendoGrid");
    const locationsItems: LocationsListViewModel[] = (gridLocation?.dataSource.data() as unknown) as LocationsListViewModel[];
    let newLocItem: LocationsListViewModel = (e.model as any) as LocationsListViewModel;

    // Fix Date
    let startLocationDateNew = new Date(newLocItem.StartDate);
    let endLocationDateNew = new Date(newLocItem.EndDate);
    let offsetLocationNew = startLocationDateNew.getTimezoneOffset();
    startLocationDateNew = new Date(startLocationDateNew.getTime() - (offsetLocationNew * 60 * 1000));
    endLocationDateNew = new Date(endLocationDateNew.getTime() - (offsetLocationNew * 60 * 1000));

    let newLocationItem: LocationsListViewModel = {
        UIDEmployee_Location: newLocItem.UIDEmployee_Location,
        UIDEmployee: newLocItem.UIDEmployee,
        UIDLocation: newLocItem.UIDLocation,
        UIDSublocation: newLocItem.UIDSublocation,
        UIDPosition: newLocItem.UIDPosition,
        Main: newLocItem.Main,
        PercentageOfDedication: newLocItem.PercentageOfDedication,
        StartDate: startLocationDateNew.toISOString().split('T')[0],
        EndDate: endLocationDateNew.toISOString().split('T')[0],
        UIDStatus: newLocItem.UIDStatus,
        Comments: newLocItem.Comments
    };
}

All the data is well collected except Sublocations is set to null. Where it should be an int ID. I share with you the Template and the model:

@using XXXX.Application.Application.Maintenances.DTOs;

@model int?

@(Html.Kendo().DropDownListFor(m => m)
    .DataTextField("Name")
    .DataValueField("UIDEntity")
    .OptionLabel("Select...")
    .BindTo((IEnumerable<GenericMaintenanceEntityDTO>)ViewData["sublocations"]!)
)
@using XXXX.Application.Application.Maintenances.DTOs;

@model int

@(Html.Kendo().DropDownListFor(m => m)
    .DataTextField("Name")
    .DataValueField("UIDEntity")
    .OptionLabel("Select...")
    .BindTo((IEnumerable<GenericMaintenanceEntityDTO>)ViewData["locations"]!)
)
interface LocationsListViewModel {
    UIDEmployee_Location: number;
    UIDEmployee: number;
    UIDLocation: number;
    UIDSublocation: number;
    UIDPosition: number;
    Main: boolean;
    PercentageOfDedication: string;
    StartDate: string;
    EndDate: string;
    UIDStatus: number;
    Comments: string;
}

I have been looking for the problem for quite some time but I can't find it. Can someone help me?

Thanks

1 Answer, 1 is accepted

Sort by
0
Mihaela
Telerik team
answered on 26 Feb 2024, 08:27 AM

Hello David,

Thank you for sharing the code snippets.

I tried to reproduce the aforementioned behavior in the attached runnable sample, and it appears that the "UIDSublocation" property value is available at my end. 

Would you review it and try to modify the sample based on your code to replicate the issue and send it back in the thread to review it?

Thank you for your cooperation.

 

Regards,
Mihaela
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages. If you're new to the Telerik family, be sure to check out our getting started resources, as well as the only REPL playground for creating, saving, running, and sharing server-side code.
Tags
DropDownList Grid
Asked by
David
Top achievements
Rank 1
Answers by
Mihaela
Telerik team
Share this question
or