We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Grid custom dialog template custom error message

I have using a custom dialog template for the Add function.  I want to show a custom error message from server side on the custom dialog template, i try using modelstate.adderror() and in the client side I use the @Html.ValidationSummary(true) but it not show.

Below is my code

index.cshtml

@model HomeIndexViewModel

@{
    ViewData["Title"] = "Home List";
}

<div class="card-body">
    <h3>
       Home
    </h3>
    

        <ejs-grid id="Grid" allowPaging="true" allowSorting="true" actionComplete="actionComplete" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
            <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Dialog" template="#dialogTemplate" showDeleteConfirmDialog="true"></e-grid-editSettings>
            <e-grid-pagesettings pageSize="5" pageSizes="true"></e-grid-pagesettings>
            <e-grid-selectionsettings checkboxMode="ResetOnRowClick" type="Single"></e-grid-selectionsettings>
            <e-data-manager adaptor="UrlAdaptor" url="/Home/DataSoruce" insertUrl="/Home/Create" updateUrl="/Home/Update" removeUrl="/Home/Delete"></e-data-manager>
            <e-grid-columns>
                <e-grid-column field="Id" headerText="Id" textAlign="Left" width="120" isPrimaryKey="true" visible="false"></e-grid-column>
                <e-grid-column field="Code" headerText="Code" textAlign="Left" width="120"></e-grid-column>
                <e-grid-column field="Description" headerText="Description" textAlign="Left" width="120" validationRules="@(new { required = true})"></e-grid-column>
            </e-grid-columns>
        </ejs-grid>

      <script>
            function actionComplete(args) {
                console.log(args.requestType);
                if (args.requestType === 'beginEdit' || args.requestType === 'add') {
                    //let spinner = ej.popups.createSpinner({ target: args.dialog.element });
                    //ej.popups.showSpinner(args.dialog.element);

                    if (args.requestType === 'add') {
                        args.dialog.header = 'Add Dialog11111';
                        var ajax = new ej.base.Ajax({
                            url: "/Product/CreatePartial", //render the partial view
                            type: "POST",
                            contentType: "application/json",
                            data: JSON.stringify({ value: args.rowData })
                        });
                        ajax.send().then(function (data) {
                            appendElement(data, args.form); //Render the edit form with selected record
                            args.form.elements.namedItem('Code').focus();
                        }).catch(function (xhr) {
                            console.log(xhr);
                        });
                    }

                }
            }
            function appendElement(elementString, form) {
                form.querySelector("#dialogTemp").innerHTML = elementString;
                var script = document.createElement('script');
                script.type = "text/javascript";
                var serverScript = form.querySelector("#dialogTemp").querySelector('script');
                script.textContent = serverScript.innerHTML;
                document.head.appendChild(script);
                serverScript.remove();
            }
        </script>


        <script id="dialogTemplate" type="text/x-template">
            <div id="dialogTemp"></div>
        </script>
    </div>
</div>

HomeController

 public IActionResult CreatePartial([FromBody] CRUDModel<HomeCreateViewModel> model)
        {
            return PartialView("CreatePartial");
        }
 
  [HttpPost]
        public async Task<IActionResult> Create([FromBody]CRUDModel<ProductCreateViewModel> model)
        {
            if (!ModelState.IsValid)
            {
               
                return View(model);
            }

            var duplicateCode = datasource.Where(r => r.Code == model.Value.Code);

            if (duplicateCode.Count() > 0)
            {
                ModelState.AddModelError(string.Empty, "Duplicate Code!");
                return View(model);
            }

            if (!await productService.CreateAsync(model.Value))
            {
                return View(model);
            }

            return RedirectToAction(nameof(Index));
        }

CreatePartial.cshtml

@using Syncfusion.EJ2

<div>
    <div class="form-row">
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                @Html.TextBox("Code")
                <span class="e-float-line"></span>
                @Html.Label("Code", "Code", new { @class = "e-float-text e-label-top" })
            </div>
        </div>
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                @Html.TextBox("Description")
                <span class="e-float-line"></span>
                @Html.Label("Description", "Description", new { @class = "e-float-text e-label-top" })
            </div>
        </div>
    </div>
   @Html.ValidationSummary(true)
</div>
@Html.EJS().ScriptManager()

What the mistake I make?  Please guide me to the correct direction.
Thanks

7 Replies

PS Pavithra Subramaniyam Syncfusion Team April 24, 2019 09:41 AM UTC

 
Hi Derick Loo, 
 
Thanks for contacting Syncfusion support. 
 
We could see you are using a HTML TextBox. To apply validation message to the corresponding validation element, you have to give the ValidationSummary within the form as discussed in the following article. 
 
 
By default, we have handled the validation for Grid columns using validationRules property. But, in your case, you have applied the external validation(ValidationSummary) on grid column(“CustomerID”) in dialog edit template so we have to pass the validation failure message from the server side to client end using “ActionFailure” event of EJ2 Grid. Please refer the below code example  to more information.  
[index.cshtml] 
<ejs-grid id="Grid" allowPaging="true" toolbar="@(new List<string>() {"Add", "Edit", "Update", "Delete" })" actionComplete="actionComplete" actionFailure="onActionFailure"> 
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Dialog" template='#dialogtemplate'></e-grid-editSettings> 
    <e-data-manager url="/Home/UrlDataSource" adaptor="UrlAdaptor" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Remove"></e-data-manager> 
    <e-grid-columns> 
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column> 
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column> 
        <e-grid-column field="ShipCity" headerText="Ship City" width="150"></e-grid-column> 
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column> 
    </e-grid-columns> 
</ejs-grid> 
 
<script id='dialogtemplate' type="text/x-template"> 
    <div id="dialogTemp"> 
    </div> 
</script> 
 
<script type="text/javascript"> 
 
    function onActionFailure(args) { 
        var errorMsg ; 
         // get the error message when failed the validation 
        if (args.error) { 
            errorMsg = args.error[0].error.responseText; 
        } else { 
            errorMsg = args[0].error.responseText; 
        }  
         // Generate error message is show on dialog edit template        
        var grid = document.getElementById("Grid").ej2_instances[0]; 
        var validationEle = grid.element.querySelector(".e-edit-dialog .form-row div.e-float-input #CustomerID"); 
        var spanEle = document.createElement("span"); 
        spanEle.textContent = '*'+ errorMsg; 
        spanEle.style.color = "red"; 
        validationEle.parentElement.appendChild(spanEle); 
    } 
 
 
 
Please get back to us, if you need further assistance. 
 
Regards, 
Pavithra S. 



DL Derick Loo April 24, 2019 02:21 PM UTC

Hi Pavithra,
    I follow the sample project but can't get it.  I get the error when I inspect the page

     Uncaught (in promise) TypeError: Cannot read property 'parentElement' of null
    at t.onActionFailure (Product:110)
    at e.notify (treemap.ts:2)
    at t.e.trigger (treemap.ts:2)
    at e.dataManagerFailure (treemap.ts:2)
    at treemap.ts:2

my code as below

               <script id="dialogTemplate" type="text/x-template">
            <div id="dialogTemp"></div>
        </script>

        <script type="text/javascript">
            function onActionFailure(args) {
                var errorMsg;
                if (args.error) {
                    errorMsg = args.error[0].error.responseText;
                } else {
                    errorMsg = args[0].error.responseText;
                }
                alert(errorMsg);
                var grid = document.getElementById("Grid").ej2_instances[0];
                var validationEle = grid.element.querySelector(".e-edit-dialog .form-row div.e-float-input #ShipCity");
                var validationEle = grid.element.querySelector(".e-edit-dialog #ErrorMessage")
                var spanEle = document.createElement("span");
                spanEle.textContent = '*' + errorMsg;
                spanEle.style.color = "red";
                validationEle.parentElement.appendChild(spanEle)
            }

            function actionComplete(args) {
                console.log(args.requestType);
                if (args.requestType === 'beginEdit' || args.requestType === 'add') {
                    let spinner = ej.popups.createSpinner({ target: args.dialog.element });
                    ej.popups.showSpinner(args.dialog.element);

                    if (args.requestType === 'add') {
                        args.dialog.header = 'Create Product';
                        var ajax = new ej.base.Ajax({
                            //url: "/Product/CreatePartial", //render the partial view
                            url: "@Url.Action("CreatePartial", "Product")", //render the partial view
                            type: "POST",
                            contentType: "application/json",
                            data: JSON.stringify({ value: args.rowData })
                        });
                        ajax.send().then(function (data) {
                            appendElement(data, args.form); //Render the edit form with selected record
                            args.form.elements.namedItem('Code').focus();
                            ej.popups.hideSpinner(args.dialog.element);
                        }).catch(function (xhr) {
                            console.log(xhr);
                            ej.popups.hideSpinner(args.dialog.element);
                        });
                    }

                }
            }
            function appendElement(elementString, form) {
                form.querySelector("#dialogTemp").innerHTML = elementString;
                var script = document.createElement('script');
                script.type = "text/javascript";
                var serverScript = form.querySelector("#dialogTemp").querySelector('script');
                script.textContent = serverScript.innerHTML;
                document.head.appendChild(script);
                serverScript.remove();
            }
        </script>

My partial file
@model ProductIndexViewModel
@using Syncfusion.EJ2

<div>
    <div class="form-row">
        <div class="form-group col-md-4">
            <div class="e-float-input e-control-wrapper">
                @Html.TextBox("Code")
                <span class="e-float-line"></span>
                @Html.Label("Code", "Code", new { @class = "e-float-text e-label-top" })
            </div>
        </div>
        <div class="form-group col-md-4">
            <div class="e-float-input e-control-wrapper">
                @Html.TextBox("Description")
                <span class="e-float-line"></span>
                @Html.Label("Description", "Description", new { @class = "e-float-text e-label-top" })
            </div>
        </div>
        <div class="form-group col-md-4">
            <div class="e-float-input e-control-wrapper">
                <label id="ErrorMessage" class="e-float-text e-label-top"></label>
                @Html.ValidationSummary(true)
            </div>
        </div>
    </div>
</div>
<ejs-scripts></ejs-scripts>

Best regards,
Derick


DL Derick Loo April 24, 2019 03:12 PM UTC

I try to put an alert in the action failure, it seem like the grid element query selector is null

var validationEle = grid.element.querySelector(".e-edit-dialog .form-row div.e-float-input");

What's the wrong of my code?


PS Pavithra Subramaniyam Syncfusion Team April 25, 2019 06:50 AM UTC

Hi Derick Loo, 
 
Thanks for your update. 
 
As per your query, we have applied your code in our end but we are unable to reproduce the reported defect and we can get the error message on “ActionFailure” event of EJ2 Grid. since we have shared the video demonstrate your requirement for your references. 
 
 
If you are still facing the issue, Could please share the reported issue reproducing video demonstrate and hosted sample link to better assistance. 
 
Regards, 
Pavithra S. 



DL Derick Loo April 25, 2019 01:45 PM UTC

Hi Pavithra ,
     May I know any configuration in the startup file?  Any MVC services need added?

Thanks,
Derick




DL Derick Loo April 25, 2019 02:47 PM UTC

I have attached the video demo of the error.

Attachment: 20190425_51d3eace.rar


PS Pavithra Subramaniyam Syncfusion Team April 29, 2019 11:54 AM UTC

Hi Derick, 
 
Thanks for your update.  
 
We have created a new incident #234720 under your account, regarding your query. So we suggest you to log in your account and follow the new incident to get more update. 
 
Regards, 
Pavithra S. 


Loader.
Live Chat Icon For mobile
Up arrow icon