Telerik Forums
UI for ASP.NET Core Forum
1 answer
15 views

I had recently had an issue with Kendo Grid's export to excel feature not working and it was correctly resolved in this forum post:
https://www.telerik.com/forums/kendo-grid-excel-export-crashing-widget

I am now experiencing an issue that appears to be distinct and unrelated to the above problem on a different view within my project.

I have a Grid where I want to export the entire contents of the grid (both hidden and unhidden columns) to an excel spreadsheet.  When I click my "Export to Excel" button the following happens:

  • The "Exporting" animation shows up and hangs

  • I receive a console error indicating that the export request returned a status 405, I can also see this in the network tab

  • The breakpoint I set in my ExcelExportSave() method in my HomeController is not being hit.

What could be causing this? 

I have already implemented the fix suggested in the above linked post to import that I add JSZip directly to my layout:

<script src="https://unpkg.com/jszip/dist/jszip.min.js"></script>

 

Additional Context

The Export to Excel will fail even if I attempt to export the contents of the grid before any lines are added.

This is a read-only grid that populates 1 to N lines based on an Ajax call.  Due to the way I need this to function for my users I did not use the dataSource CRUD operations.  Rather, I use external JavaScript to directly edit the table contents.  This could be a possible source of the problem, but I do not know how I would fix.

There are two ways to add lines to the table, the first is to paste in rows and wait for the Ajax call.  The second is to add them using an input field above the grid. 

The Code

Here's the table and the relevant JavaScript that populates it:

Html.Kendo().Grid<UPH.ADCommander.Models.ExtendedUserDisplayObject>()
.Name("Grid")
.Columns(columns =>
{
    columns.Bound(c => c.SamAccountName).Title("SamAccount").Width(110).HeaderHtmlAttributes(new { style = "font-weight: bold" }).EditorTemplateName("SamAccountNameEditor");
    columns.Bound(c => c.GivenName).Title("First Name").HeaderHtmlAttributes(new { style = "font-weight: bold" });
    columns.Bound(c => c.MiddleInitial).Title("MI").Width(50).HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.Surname).Title("Last Name").HeaderHtmlAttributes(new { style = "font-weight: bold" });
    columns.Bound(c => c.Title).Title("Title").HeaderHtmlAttributes(new { style = "font-weight: bold" });
    columns.Bound(c => c.Manager).Title("Manager").HeaderHtmlAttributes(new { style = "font-weight: bold" });
    columns.Bound(c => c.ExtendedAttribute2).Title("Ex. Attr 2").HeaderHtmlAttributes(new { style = "font-weight: bold" });
    columns.Bound(c => c.ExtendedAttribute3).Title("Ex. Attr 3").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.ExtendedAttribute4).Title("Ex. Attr 4").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.ExtendedAttribute5).Title("Ex. Attr 5").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.ExtendedAttribute6).Title("Ex. Attr 6").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.ExtendedAttribute7).Title("Ex. Attr 7").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.ExtendedAttribute9).Title("Ex. Attr 9").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.ExtendedAttribute12).Title("Ex. Attr 11").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    columns.Bound(c => c.ExtendedAttribute13).Title("Ex. Attr 12").HeaderHtmlAttributes(new { style = "font-weight: bold" }).Hidden(true);
    // test columns, add more once PoC is getting the necessary data
})
.Sortable()
.Selectable(selectable => selectable
    .Mode(GridSelectionMode.Multiple)
    .Type(GridSelectionType.Cell)
)
.Navigatable()
.Scrollable()
.AllowCopy(true)
.ToolBar(tools =>
{
    tools.Custom().Text("Copy to Clipboard").HtmlAttributes(new { id = "copyButton" });
    tools.Excel();
    tools.Custom().Text("Clear").HtmlAttributes(new { id = "clearButton" });
    tools.Search();
})
.AutoBind(false)
.DataSource(dataSource => dataSource
    .Ajax() // no actual Ajax call is made with this, this is solely to define a primary key for the table so we can use the dataSource API
    .Update("GetUserDetail", "UserLookup")
    .Model(model =>
    {
        model.Id(p => p.SamAccountName); // Set SamAccountName as the ID field
    })
)
.Excel(excel => excel
    .FileName("UserDetails_" + DateTime.Now.Date.ToShortDateString() + ".xlsx")
    .Filterable(true)
    .ProxyURL(Url.Action("ExcelExportSave", "Home"))
)

                       

    function initializeGridPasteHandler(gridSelector) {
        $(gridSelector).on('contextmenu', function (e) {
            if ($(e.target).is(".k-link, .k-grid-toolbar, .k-grid-pager")) {
                return;
            }

            var offset = $(this).find("table").offset();
            var textarea = $("<textarea>");
            textarea.css({
                position: 'absolute',
                opacity: 0,
                top: offset.top,
                left: offset.left,
                border: 'none',
                width: $(this).find("table").width(),
                height: $(this).find(".k-grid-content").height()
            })
                .appendTo('body')
                .on("click", function (e) {
                    textarea.remove();
                    $(document.elementFromPoint(e.clientX, e.clientY)).click();
                })
                .on('paste', function () {
                    setTimeout(function () {
                        var value = $.trim(textarea.val());
                        var grid = $(gridSelector).data("kendoGrid");
                        var rows = value.split('\n');

                        var newRows = addRowsToGrid(rows);

                        sendUserDetailsToController(newRows);

                        textarea.remove();
                    });
                }).focus();

            return false;
        });
    }

 

function addRowsToGrid(rows) {
    console.log("addRowsToGrid fired");
    var grid = $("#Grid").data("kendoGrid");
    var existingData = grid.dataSource.data().toJSON();

    var newData = rows.map(function (row) {
        return { SamAccountName: row.trim() };
    });

    // Append new data to the existing data
    var combinedData = existingData.concat(newData);

    // Update the grid with the combined data
    grid.dataSource.data(combinedData);

    return newData;
}

 

// send the controller a list of samAccount names to get the user detail information
function sendUserDetailsToController(newRows) {
    console.log("sendUserDetailsToController fired");

    // Show the loading indicator
    $("#gridLoader").show();

    var samAccountNames = newRows.map(function (row) {
        return row.SamAccountName;
    });

    // Make the AJAX call with the new samAccountNames only
    $.ajax({
        type: "POST",
        url: "/UserLookup/GetUserDetails",
        contentType: "application/json",
        data: JSON.stringify(samAccountNames),
        success: function (response) {
            console.log("Data sent to the controller successfully.");
            updateGridWithUserDetails(response); // Update the grid with the response data
        },
        error: function (xhr, status, error) {
            console.log("An error occurred while sending data to the controller.");
        },
        complete: function () {
            $("#gridLoader").hide();; // close loading animation
        }
    });
}

 

function updateGridWithUserDetails(userDetails) {
    console.log("updateGridWithUserDetails fired");
    var grid = $("#Grid").data("kendoGrid");
    var dataSource = grid.dataSource;
    var data = dataSource.data();

    userDetails.forEach(function (userDetail) {
        var matchedRow = data.find(function (row) {
            console.log("user: " + userDetail.samAccountName);
            return row.SamAccountName.toLowerCase() === userDetail.samAccountName.toLowerCase();
        });

        console.log("matched row:" +matchedRow.SamAccountName)
        // Necessary in case of a case mismatch, e.g. SSS401 will match sss401 on the backed if you don't do this you'll get a fun bonus row added.
        matchedRow.SamAccountName = userDetail.samAccountName;

        if (matchedRow) {
            console.log("matched row:" + matchedRow.SamAccountName);

            // Update the SamAccountName to the correctly cased value
            matchedRow.set("SamAccountName", userDetail.samAccountName);

            // Update the rest of the row with the user details
            matchedRow.set("GivenName", userDetail.givenName);
            matchedRow.set("MiddleInitial", userDetail.middleInitial);
            matchedRow.set("Surname", userDetail.surname);
            matchedRow.set("Title", userDetail.title);
            matchedRow.set("Manager", userDetail.manager);
            matchedRow.set("ExtendedAttribute2", userDetail.extendedAttribute2);
            matchedRow.set("ExtendedAttribute3", userDetail.extendedAttribute3);
            matchedRow.set("ExtendedAttribute4", userDetail.extendedAttribute4);
            matchedRow.set("ExtendedAttribute5", userDetail.extendedAttribute5);
            matchedRow.set("ExtendedAttribute6", userDetail.extendedAttribute6);
            matchedRow.set("ExtendedAttribute7", userDetail.extendedAttribute7);
            matchedRow.set("ExtendedAttribute9", userDetail.extendedAttribute9);
            matchedRow.set("ExtendedAttribute12", userDetail.extendedAttribute12);
            matchedRow.set("ExtendedAttribute13", userDetail.extendedAttribute13);
        } 
    });

    // Refresh the grid to display the updated data
    grid.refresh();
}

 

function onAddRowClick(){
    var samAccountName = $("#searchInput").val().trim();

    // Check if the input is not empty
    if (samAccountName === "") {
        alert("Please enter a SamAccount name.");
        return;
    }
    var newRow = { SamAccountName: samAccountName };
    var newRows = addRowsToGrid([samAccountName]);

    // send to the Ajax call
    sendUserDetailsToController(newRows);
}

Note that # gridLoader is just my poor attempt at making a waiting animation.  It references this .css class.  This should be irrelevant to the problem, but for ease of running this content locally:

#gridLoader {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.8);
    z-index: 1000;
    display: none;
    align-items: center;
    justify-content: center;
}

Finally, here is my HomeController action:

        [HttpPost]
        public ActionResult ExcelExportSave(string contentType, string base64, string fileName)
        {
            var fileContents = Convert.FromBase64String(base64);
            return File(fileContents, contentType, fileName);
        }

 

 

 

 

My Environment and Project

This is an ASP.NET Core 8 MVC project being run in Visual Studio 2022 on a Windows laptop.  The project does use Microsoft Identity authentication and I am developing by running it on Localhost.  Notably, my HomeController currently has no authentication or authorization applied as I'm still just doing early stage development on localhost.  

Any assistance that could be provided or suggestions as to why this is failing would be appreciated.

 

 

Mihaela
Telerik team
 answered on 07 Jun 2024
1 answer
19 views

This was a wonderful solution to add checkboxes to a grid w/o needing to double click to enter the editor.

https://www.telerik.com/forums/how-can-i-have-a-checkbox-column-in-a-grid-without-having-to-click-on-the-checkbox-twice-to-edit#1557957

Is there a way to add a filter to the checkbox columns as well?

Tsvetomila
Telerik team
 answered on 06 Jun 2024
1 answer
14 views
I want to set child grid value as html attribute. I tried like this \\#=ImportName_InlowerCase\\#. this is not working in asp.net core CShtml files. Please help me to resolve this. 
Mihaela
Telerik team
 answered on 31 May 2024
1 answer
19 views

Given the following form:

        <kendo-form orientation="vertical" layout="grid" name="formEntity" size="medium">
            <form-items>
                <form-item hidden-editor="true" field="Id"></form-item>
                <form-item hidden-editor="true" field="ParentId"></form-item>
                <form-item hidden-editor="true" field="ClientId"></form-item>
                <form-item field="EntityName" editor-handler="setRequiredTextboxEditor">
                    <item-label text="Name" optional="false"/>
                </form-item>
                <form-item field="EntityEmail" editor-handler="setRequiredTextboxEditor">
                    <item-label text="Email" optional="false"/>
                </form-item>
                <form-item field="EntityPhone" editor-handler="setRequiredTextboxEditor">
                    <item-label text="Phone" optional="false"/>
                </form-item>
            </form-items>
            <validatable validate-on-blur="true" error-template="<span class='k-form-error'>#:message#</span>" validation-summary="false"></validatable>
        </kendo-form>

I am trying to create a custom template to house the buttons displayed on the form. All I really wish to do is show/hide the Clear button under certain circumstances and I figured doing so in a template might be my best option.

However, I cannot get a custom template to appear for the form and there are no examples of how to do this in the documentation that I could find.

I assumed it would be something like this:

            <buttons-template>
                <kendo-template>
                    <div class="k-form-buttons">
                        <button id="btnSave" class="k-form-submit k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary k-focus" data-role="button" type="submit" role="button" aria-disabled="false" tabindex="0"><span class="k-button-text">Submit</span></button>
                        <button id="btnClear" class="k-form-clear k-button k-button-md k-rounded-md k-button-solid k-button-solid-base" data-role="button" type="button" role="button" aria-disabled="false" tabindex="0"><span class="k-button-text">Clear</span></button>
                    </div>
                </kendo-template>
            </buttons-template>

But this just hides the buttons entirely. I know I am missing something, I just don't know what it is.

Thanks.

Marc
Top achievements
Rank 2
Iron
 answered on 29 May 2024
1 answer
13 views
I am using a custom template and custom form for adding and editing the nodes in my OrgChart. How can I refresh the data without reloading the entire page in order to ensure the OrgChart is displaying the correct data?
Marc
Top achievements
Rank 2
Iron
 answered on 29 May 2024
2 answers
29 views

Hello, I hope you are well.

I hope you can help me with this problem I have.

I am using the Kendo UI for JQuery Upload.

What I require is to upload an entire folder of TXT files, but I have a routine that validates that the name and content meet certain rules.

I apply these rules within the foreach loop (var file in files), because what is required is that if the file is valid it shows a text that it is valid, otherwise it shows a text that is not valid and for both options to continue processing the next file.

But by marking that file as erroneous, the controller is exited and the view is returned, thus leaving the processing of the rest of the files incomplete.

I share the code of the view and the controller, hoping you can give me some light.

View Code:

<div class="centered">
    @using Kendo.Mvc.UI
    <div>
        <div class="demo-section">
            @(Html.Kendo().Upload()
                .Name("files")
                .Async(a => a
                    .Save("ChunkSave", "Upload")
                    .Remove("Chunk_Upload_Remove", "Upload")
                    .AutoUpload(true)
                    .ChunkSize(11000)

                )
                .Multiple(true) // Enable multiple file selection
                    .Directory(true)
                    .DirectoryDrop(true)
                .Validation(validation =>
                {
                    //validation.MaxFileSize(20000000);
                })
                .Events(events =>
                {
                    events.Upload("onUpload");
                    events.Success("onUploadSuccess");
                    events.Error("onUploadError");
                    events.Select("onSelect");
                })
                .Messages(messages =>
                {
                    messages
                        .Select("Seleccionar archivos")
                        .DropFilesHere("Suelta archivos aquí para cargarlos")
                        .Remove("Eliminar")
                        .Retry("Reintentar")
                        .StatusFailed("Error")
                        .StatusUploaded("Terminado")
                        .StatusUploading("Cargando")
                        .UploadSelectedFiles("Cargar archivos")
                        .UploadFail("Error al procesar el archivo.")
                        .HeaderStatusUploaded("Terminado");
                })

            )
        </div>
    </div>
</div>

 

Controller Code:

public async Task<ActionResult> ChunkSave(IEnumerable<IFormFile> files, string metaData, string cve)
{

    int status = 0;
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ChunkMetaData));


    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(metaData));
    ChunkMetaData? somemetaData = serializer.ReadObject(ms) as ChunkMetaData;
    string path = String.Empty;

    if (files != null)
    {
        foreach (var file in files)
        {
            cap_dbt controller = new cap_dbt(_context);
            controller.ProcessFile(file, somemetaData.FileName, cve);
            status = controller.ProcessFile(file, somemetaData.FileName, cve);
            if (status == 1)
            {
                Upload(files, somemetaData.FileName);
            }
        }
    }


    if (somemetaData is null)
    {
        throw new Exception("No Metadata!");
    }

    Util.FileResult fileBlob = new Util.FileResult();
    fileBlob.uploaded = somemetaData.TotalChunks - 1 <= somemetaData.ChunkIndex;
    fileBlob.fileUid = somemetaData.UploadUid;
    fileBlob.warnings = Mensajes.msgLoadCsvWarning;
    fileBlob.message = "[" + somemetaData.FileName + "]\t";

    try
    {
        if (!fileBlob.uploaded)
        {
            fileBlob.message += "[ERROR]" + Mensajes.msgLoadCsvError;

            return StatusCode(500, fileBlob);
        }
        else if (status == -1)
        {
            fileBlob.uploaded = false;
            fileBlob.message += "[ERROR] " + Mensajes.msgLoadCsvError;
            throw new Exception(fileBlob.message); // <------- If I remove this line, it continues processing, but it no longer changes the file, it stays with the same name or empty.

        }

        if (fileBlob.warnings.Equals(""))
        {
            fileBlob.message += Mensajes.msgLoadCsvOk;
        }
    }

    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        return StatusCode(500, fileBlob);
    }
    finally
    {
        Mensajes.resetMsg();
    }

    return Json(fileBlob);
}

The following line was created to manipulate the Upload properties:
Util.FileResult fileBlob = new Util.FileResult();

I know what I can do if my file is not valid:
fileuid=""
success = false

But I see that if success is false it stops processing all the files and exits and goes to view.
Ashapura Softech
Top achievements
Rank 1
Iron
 answered on 29 May 2024
1 answer
17 views

I've implemented a column editor for a ComboBox in a Grid.  The dropdown functionality is working but the filtering functionality is not.  So if I type in the first 3 characters of a value in the data, it's displaying all entries instead of filtering the entries. The filterLocations function never gets called so I'm assuming I don't have the snytax correct but I can't find an example of this anywhere.  Plenty of examples of a column editor for a DropDown but none with a ComboBox.  Appreciate any help in correcting my syntax or pointing me towards a working demo.

 

Grid Column
        <column field="LocationId" title="Location" template="#=locationTemplate(data)#" editor="locationEditor">
            <filterable extra="false" enabled="false">
                <cell show-operators="false"></cell>
            </filterable>
        </column>

JavaScript

function locationEditor(container, options) {
    $('<input required validationMessage="Please select a location." name="' + options.field + '"/>')
        .appendTo(container)
        .kendoComboBox({
            autoBind: true,
            dataTextField: "Text",
            dataValueField: "Value",
            placeholder: "- Select or Enter -",
            filter: "contains",
            minLength: 3,
            dataSource: {
                serverFiltering: true,
                transport: {
                    read: "/ComboBox/LocationsRead",
                    data: "filterLocations"
                }
            }
        });
}

function filterLocations() {
    return {
        locationFilter: $("#Input_LocationId").data("kendoComboBox").input.val()
    };
}


Aleksandar
Telerik team
 answered on 28 May 2024
1 answer
22 views

I'm encountering a difficult to troubleshoot issue with a Kendo Grid apparently crashing when I attempt to export its contents to an excel file.  I've successfully set up Kendo Grids to export to excel before, and my code here is very closely based on other solutions I've had in similar projects.  Below is the widget code:

@(
    Html.Kendo().Grid(Model.Groups)
    .Name("Grid")
    .Columns(columns =>
    {
        columns.Bound(c => c.SamAccountName).Title("SamAccount").Width(250).HeaderHtmlAttributes(new { style = "font-weight: bold" });
        columns.Bound(c => c.DistinguishedName).Title("Full Name").Width(400).HeaderHtmlAttributes(new { style = "font-weight: bold" });
        columns.Bound(c => c.IsSecurityGroup)
            .Width(75)
            .Title("Security Group?")
            .ClientTemplate("#= IsSecurityGroup ? 'Yes' : 'No' #")
            .HeaderHtmlAttributes(new { style = "font-weight: bold" });
    })
    .Sortable()
    .Selectable(selectable => selectable
        .Mode(GridSelectionMode.Multiple)
        .Type(GridSelectionType.Cell))
    .Navigatable()
    .AllowCopy(true)
    .ToolBar(tools =>
    {
        tools.Custom().Text("Copy to Clipboard").HtmlAttributes(new { id = "copyButton" });
        tools.Excel();
        tools.Search();
    }).Excel(excel =>
    {
        excel.FileName(Model.SearchString + "GroupsExport_" + DateTime.Now.Date.ToShortDateString() + ".xlsx");
        excel.AllPages(true);
        excel.ForceProxy(true);
        excel.ProxyURL(Url.Action("ExcelExportSave", "Home"));
    })
)

And below is the corresponding action in my HomeController:

        [HttpPost]
        public ActionResult ExcelExportSave(string contentType, string base64, string fileName)
        {
            var fileContents = Convert.FromBase64String(base64);
            return File(fileContents, contentType, fileName);
        }


Behavior

The Grid will correctly load, and allow the user to search, sort, scroll, etc. However upon clicking the Export to Excel button the widget will enter a loading animation and then spin forever.  The rightmost IsSecurityGroup column will also appear to be duplicated, but I think this is a visual glitch as I'm not actually seeing an additional column be created in the page elements, this visual glitch goes away if I add "Scrollable".

My breakpoint in the ExcelExportSave() controller action is not being hit, and if I check the network tab it does not appear that a network request is even being made. 

There are no errors or warnings printed to the browser console.  

Troubleshooting steps I've tried:

  • Changing the controller for the ExcelExportSave action and also making the action [Anonymous]
  • Simplifying the Grid by removing the client-templates, dynamic filename, and custom button.
  • Removed other JS functions from the page (there aren't many, this is a pretty simple page and shouldn't have much conflicting logic)
  • Verified that the ViewModel values are not null and as expected on pageload
  • I have generally tried adjusting some of the Excel configuration options, but none of these seem to alter the behavior.

Kendo otherwise appears to be correctly imported into the project and I am not experiencing other issues.

My Environment and Project

This is an ASP.NET Core 8 MVC project being run in Visual Studio 2022 on a Windows laptop.  The project does use Microsoft Identity authentication and I am developing by running it on Localhost.  

 

Any help that anyone can provide would be greatly appreciated.  

Ivan Danchev
Telerik team
 answered on 27 May 2024
0 answers
16 views

Please delete. Not a bug. 

Hannah
Top achievements
Rank 2
 updated question on 21 May 2024
1 answer
33 views

Here's my grid:

 

@(Html.Kendo().Grid<SalaryIncrease>()
    .Name("SalaryIncreaseGrid")
    .Columns(columns =>
    {
        columns.Command(command =>
                        {
                            command.Custom("Edit").Click("meVM.editSalaryIncrease");
                            command.Custom("Delete").Click("meVM.deleteSalaryIncrease");
                        }).Width(100);
        columns.Bound(p => p.FiscalYear).Title("Fiscal Year").Width(250);
        columns.Bound(p => p.SalaryIncreaseCategory.Name).Title("Salary Increase Category").Width(400);
        columns.Bound(p => p.CurrencyId).Title("Currency").Width(250);
        columns.Bound(p => p.IncreaseAmount).Title("Increase Amount").Width(500).Format("{0:###,##0.00}");
        columns.Bound(p => p.EffectiveDate).Title("Effective Date").Width(500).Format("{0:yyyy-MM-dd}");
    })
    .Pageable(pageable => pageable
    .Refresh(false)
    .PageSizes(new[] { 5, 10, 25, 50, 100 })
    .ButtonCount(6)
    )
    .Sortable()
    .Selectable(selectable => selectable.Mode(GridSelectionMode.Single))
    .Resizable(resize => resize.Columns(true))
    .Scrollable()
    .ColumnMenu(menu => { menu.ComponentType("modern"); })
    .Events(e => e.DataBound("meVM.onSalaryIncreaseGridDataBound"))
    .DataSource(dataSource => dataSource
    .Ajax()
    .Batch(true)
    .PageSize(10)
    .Model(model => model.Id(p => p.Id))
    .ServerOperation(false)
    .Read(read => read.Url("/Employee/ManageEmployee?handler=SalaryIncrease_Read").Type(HttpVerbs.Get))))
What I want to do is pass the id specified in the `.Model` line to the javascript functions `meVM.editSalaryIncrease` and `meVM.deleteSalaryIncrease`. When I look at the documentation it always uses `this.dataItem($(e.currentTarget).closest("tr"))` to find the dataItem and get the Id. The problem is I have javascript classes acting as client-side view models. The functions on those view models are defined as arrow functions so that `this` points to the class and I can call private functions. But if I do that here, then `this` will not contain dataItem. All of this could be resolved if I could just call `meVM.editSalaryIncrease(Id)` to pass the parameter. How can I do this?
Legion
Top achievements
Rank 1
Iron
 answered on 09 May 2024
Narrow your results
Selected tags
Tags
+? more
Top users last month
Michael
Top achievements
Rank 1
Iron
Wilfred
Top achievements
Rank 1
Alexander
Top achievements
Rank 2
Iron
Iron
Matthew
Top achievements
Rank 1
Iron
ibra
Top achievements
Rank 1
Want to show your ninja superpower to fellow developers?
Top users last month
Michael
Top achievements
Rank 1
Iron
Wilfred
Top achievements
Rank 1
Alexander
Top achievements
Rank 2
Iron
Iron
Matthew
Top achievements
Rank 1
Iron
ibra
Top achievements
Rank 1
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?