0
votes

I am trying to pass the Kendo Grid row data to the partial view rendered through Kendo popup window.

In the partial view, an image file can be uploaded for the row record. This part is asynchronous and separate from the row edit. I have got uploading and saving image working, but I need to get the ID of the row so that I can save the image file for that record.

Also, I need to pass the image data to the partial view and display it later on once there is any.

How do I pass data to the partial view(Kendo popup window) from the Kendo Grid perfectly on the client side since the data is already in the Kendo Grid dataSource?

JS:

$("#manageLostPropertiesGrid").kendoGrid({
    dataSource: lostPropertyDataSource,
    pageable: true,
    height: 550,
    toolbar: ["create"],
    columns: [
        {
            command: { text: "View", click: showPhoto },
            title: "Photo",
            filterable: false, sortable: false, width: 100,
        },
        { field: "PropertyName", title: "Property Name", width: "150px" },
        { field: "CategoryName", title: "Category", editor: propertyCategoryList, width: "150px" },
        { field: "PropertyDescription", title: "Description", width: "200px" },
        {
            field: "FoundDate", type: "date", title: "Found Date", format: "dd/MM/yyyy",
            template: "#= kendo.toString(kendo.parseDate(FoundDate, 'dd-MM-yyyy'), 'dd/MM/yyyy') #", width: "130px"
        },
        { field: "FoundLocation", title: "Found Location", width: "120px" },
        { command: ["edit", "destroy"], title: " ", width: "250px" }],
    editable: "popup"
}).data("kendoGrid");

// Pop-up window for photo view/upload
    wnd = $("#photo-window")
        .kendoWindow({
            content: {
                url: "ImageUploader",
            },
            title: "Image Uploader",
            modal: true,
            visible: false,
            resizable: true,
            width: 750,
            height: 500
        }).data("kendoWindow");

    photoTemplate = kendo.template($("#template").html());

    function showPhoto(e) {
        e.preventDefault();

        var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
        wnd.center().open();
    }

Partial View:

<div id="example" class="k-content">
<div class="demo-section k-content wide">
    <div class="wrapper">
        <div id="products"></div>
        <div class="dropZoneElement">
            <div class="textWrapper">
                <p>Add Image</p>
                <p class="dropImageHereText">Drop image here to upload</p>
            </div>
        </div>
    </div>
</div>

<input name="files" id="files" type="file" />

<script type="text/x-kendo-template" id="template">
    <div class="product"></div>
</script>

<script>
    $(function () {
        var template = kendo.template($("#template").html());
        var initialFiles = [];

        $("#products").html(kendo.render(template, initialFiles));

        $("#files").kendoUpload({
            async: {
                saveUrl: "save?id=" + "1",//Need the row Id here
                removeUrl: "remove",
                autoUpload: true
            },
            multiple: false,
            validation: {
                allowedExtensions: [".jpg", ".jpeg", ".png", ".bmp", ".gif"]
            },
            success: onSuccess,
            dropZone: ".dropZoneElement"
        });

        function onSuccess(e) {
            if (e.operation == "upload") {
                var file = e.files[0].rawFile;
                if (file) {
                    var reader = new FileReader();

                    reader.onloadend = function () {
                        $("#products").empty().append("<div class='product'><img src=" + this.result + " /></div>");
                    };
                    reader.readAsDataURL(file);
                }
            }
            if (e.operation == "remove") {
                $("#products").empty();
            }
        }
    });
</script>

1
I am not sure if you can do this only at client side. Because in time when you click on button, that partial view is already rendered on the page. So you will need refresh DOM content with ajax/dynamically. And for that scenario, Telerik has refresh function - link, eventually here. If you would want update only data in Telerik's template, it shouldn't be problem. For partial view, I am afraid you need make server callAdemar
@Ademar, How do I pass the Id of the row to the partial view. If I make a server call, how does the server side know which row did I click and pass to the partial view at the same time?Salomon Zhang
@Ademar Thanks for your suggestion, I did make a server-side call to get the Id. I posted my solution.Salomon Zhang

1 Answers

1
votes

I have got a solution to my own question.

I did make a server-side call to pass the row Id to the partial view.

The working solution code below:

Controller:

public PartialViewResult ImageUploader(int? propertyId)
{
    var viewModel = new LostPropertyViewModel();

    using (var dbContext = new PortalEntities())
    {
        if (propertyId != null)
        {
            viewModel = dbContext.sz_LostProperty.Where(x => x.Id == propertyId).Select(x => new LostPropertyViewModel
            {
                PropertyId = x.Id,
                Image = x.Image
            }).FirstOrDefault();
        }
        return PartialView("_ImageUploader", viewModel);
    }
}

View:

// Click function for Kendo grid button
function showPhoto(e) {
    e.preventDefault();

    var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
    var propertyId = dataItem.PropertyId;
    console.log(propertyId);

    // Pop-up window for photo view/upload
    var wnd = $("#photo-window")
        .kendoWindow({
            content: {
                url: "ImageUploader",
                data: { propertyId: propertyId }
            },
            title: "Image Uploader",
            modal: true,
            visible: false,
            resizable: true,
            width: 750,
            height: 500
        }).data("kendoWindow");
    wnd.center().open();
}

Partial view:

@using WebApp.ViewModels
@model LostPropertyViewModel
@{ 
    var propertyId = Model.PropertyId;
}
<div id="example" class="k-content">

    <div class="demo-section k-content wide">
        <div class="wrapper">
            <div id="products"></div>
            <div class="dropZoneElement">
                <div class="textWrapper">
                    <p>Add Image</p>
                    <p class="dropImageHereText">Drop image here to upload</p>
                </div>
            </div>
        </div>
    </div>

    <input name="files" id="files" type="file" />

    <script type="text/x-kendo-template" id="template">
        <div class="product">
            <img src="../content/web/foods/#= name #" alt="#: name # image" />
        </div>
    </script>

    <script>
        $(function () {
            var template = kendo.template($("#template").html());
            var initialFiles = [];

            $("#products").html(kendo.render(template, initialFiles));

            $("#files").kendoUpload({
                async: {
                    saveUrl: "save?id=" + @propertyId,
                    removeUrl: "remove",
                    autoUpload: true
                },
                multiple: false,
                validation: {
                    allowedExtensions: [".jpg", ".jpeg", ".png", ".bmp", ".gif"]
                },
                success: onSuccess,
                dropZone: ".dropZoneElement"
            });

            function onSuccess(e) {
                if (e.operation == "upload") {
                    var file = e.files[0].rawFile;

                    if (file) {
                        var reader = new FileReader();

                        reader.onloadend = function () {
                            $("#products").empty().append("<div class='product'><img src=" + this.result + " /></div>");
                        };

                        reader.readAsDataURL(file);
                    }
                }
                if (e.operation == "remove") {
                    $("#products").empty();
                }
            }
        });

    </script>
</div>