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 / Edit Template / Partial View -> CRUDModel null if Model contains List<string>

Hi,

I use the Grid component in an ASP.NET Core 3.1 application (Syncfusion EJ2 AspNet Core 17.4.0.39) and need "complex" controls on entry edit. So I use a server-side edit template using a partial view and an UrlAdaptor to save the data on the server. Most of the code is from the documentation and this forum.

My issue is:
If the Model of the Grid-Entries contains a property of type "List" the CRUDModel parameter in the service-side save endpoint is null. I need this type, as I want to use a MultiSelect-control in the edit view and need to "sync" the selected entry ids back to the server. 

Find a simple example attached. It will give you an NullReference-Exception in the serverside SaveData method (because the CRUDModel is null).
There is some uncommented code in the model "AppDataModel" and in the controller "HomeController", so you can quickly change the data type of the problematic property. This is to be able to verify that the rest of the implementation is working fine.

Is there a solution or workaround for this issue?

Attachment: SyncfusionTestWebApplication_fd0c8cb3.zip

5 Replies

MB Michael Bayer February 6, 2020 05:43 PM UTC

By taking a closer look at the network requests it shows:

If the multiselect control is bound to a list of string (also with array-type) using "ejs-for", then the post (save-action) posts the bound property as string (containg the first element of the list) instead of a list type.


TS Thiyagu Subramani Syncfusion Team February 10, 2020 06:27 PM UTC

Hi Michael , 

Greetings from Syncfusion forum. 

We have validated your requirement “Grid / Edit Template / Partial View -> CRUDModel null if Model contains List<string>” and we suspect your requirement is SaveData CRUDModel as null while editing multiselect in partial view. 

For this case, Multiselect control supports value as array type. So we suggest to use actionComplete event to render partial view and  cellEditTemplate for client-side multiselect value customization and here we haven't modified the dataSource value of the specified column as array type. In actionBegin event we have changed selected array value as string while save the edited value.  



Please refer to the below code snippet in your application. Its return the appropriate saved value in server side. 
 
 <ejs-grid id="Grid" gridLines="Both" actionComplete="actionComplete" toolbarClick="toolbarClick" actionBegin="actionBegin" toolbar=toolbarItems> 
        . . .  
        <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Dialog" template='#dialogtemplate'></e-grid-editSettings> 
        <e-grid-columns> 
         . .  . 
            <e-grid-column field="ShipCountry" width="100" edit="@(new {create = "create", read = "read", destroy = "destroy", write = "write"})"> </e-grid-column> 
            . . .  
    </ejs-grid> 
 
 
    <script> 
    var title; 
    var elem; 
    var dropdown; 
 
function actionComplete(args) { 
            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 === 'beginEdit') { 
                    args.rowData.ShipCountry = dropdown.value; 
                    var ajax = new ej.base.Ajax({ 
                        url: "@Url.Action("EditPartial", "Home")", //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('OrderID').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(); 
        } 
 
        function actionBegin(args) { 
            if (args.requestType === 'save') { 
// array type value will be changed as string and sent to server side. 
            args.data.ShipCountry = args.data.ShipCountry.toString(); 
        } 
    } 
 
     function create() { 
        elem = document.createElement('input'); 
        return elem; 
    } 
    function read(args) { 
        var instances = document.getElementById('ShipCountry').ej2_instances[0]; 
        return instances.value; 
    } 
    function write(args) { 
        dropdown = new ej.dropdowns.MultiSelect({ 
            dataSource: data, 
            fields: { value: "ShipCountry" , text : "ShipCountry"}, 
            mode: 'CheckBox', 
            showSelectAll: true, 
            showDropDownIcon: true, 
            placeholder: 'Field', 
            filterBarPlaceholder: 'Search Field', 
            popupHeight: '350px', 
            // value will be changed as corresponding type. 
            value: typeof (args.rowData.ShipCountry) === 'string' ? args.rowData.ShipCountry.split(',') : args.rowData.ShipCountry, 
        }); 
        dropdown.appendTo(elem); 
         
    } 
    function destroy() { 
        dropdown.destroy(); 
    } 
    </script> 


Please get back to us, if you need any further assistance. 

Regards, 
Thiyagu S, 



MB Michael Bayer February 13, 2020 10:16 AM UTC

It seems you didn't really get my issue. First things first: I need the MultiSelect-control ON the PartialView for editing, as my grid cannot show all properties of the entrie-objects (as there are to many).

I managed to locate the issue and created a sample showing the problem in detail, so please refer to my sample (in my first post). I also attached detailed screenshots of this issue.

The problem shows in the following way:

If I use the MultiSelect-control on the partial edit view, everything looks fine:

SEE IMAGE 1 FROM THE ATTACHED ZIP

But if try to save, I see the following data sent to the SaveData-endpoint (you can see that Variable3 is of wrong type, as it is defined as string[] in the model)

SEE IMAGE 2 FROM THE ATTACHED ZIP

At the SaveData-endpoint the Model-object is null BECAUSE the property bound to the MultiSelect-control (here Variable3) is of the wrong type (string instead of string[]). If I remove this property or change it to any other type than string[] (which is needed to bind the selected values from the MultiSelect-control) the sample works (except for the selected values) and the CRUDModel is not null anymore.

SEE IMAGE 3 FROM THE ATTACHED ZIP

So it seems the Form-post from the PartialEditTemplate doesn't use the correct value type for the MultiSelect-control (string instead of string[]). Why is that? Is there any issue with the way the control is bound?
<ejs-multiselect id="multiselectfor" name="Variable3" ejs-for="@Model.Variable3" dataSource="selectionValues" allowCustomValue="false" placeholder="Selection Values" mode="Box">
                <e-multiselect-fields text="Name" value="Id"></e-multiselect-fields>
</ejs-multiselect>

Attachment: Screenshots_9a98f89f.zip


PA Pham Anh Dan May 11, 2020 03:06 AM UTC

I am like you, have you dealt with it? Please, email me if you have finished processing: danpa.itcbinhthuan@gmail.com


RR Rajapandi Ravi Syncfusion Team May 12, 2020 12:28 PM UTC

Hi Michael/ Pham, 

Thanks for the update. 

In your attached sample application we found that you are maintaining a string[] column for multiselect. By default in EJ2 Grid we do not have the array column support so you can maintain your datasource as string type for multiselect column.  

In the client side you have save the multiselect value as string type in by using actionBegin event. In this event we have convert the array values to the string type and send to the server. Now the controller receives the updated value instead of Null.  

Please refer the below code example, sample and screenshot for more information. 

 
   <div class="control-section"> 
        <ejs-grid id="Grid" actionBegin="begin" actionComplete="gridActionComplete" allowPdfExport="false" allowExcelExport="false" toolbar="toolbarItems" allowSorting="false" allowMultiSorting="true" allowPaging="false" allowFiltering="false"> 
            <e-data-manager url="@Url.Action("DataSource", "Home")" updateUrl="@Url.Action("SaveData", "Home")" adaptor="UrlAdaptor"></e-data-manager> 
            <e-grid-editSettings mode="Dialog" template='#dialogtemplate' allowAdding="false" allowDeleting="false" allowEditing="true"></e-grid-editSettings> 
            <e-grid-columns> 
                .  .  .  .  .  .  .   . 
            </e-grid-columns> 
        </ejs-grid> 
    </div> 
</div> 
 
 
    <script> 
        // GRID EVENTS 
        function begin(args) { 
            if (args.requestType === 'save') {  
                args.data.Variable3 = document.getElementsByClassName('e-multiselect')[1].ej2_instances[0].value.toString(); 
// array type value will be changed as string and sent to server side.  
        }  
        } 
</script> 
  

Screenshot: 

 


Regards, 
Rajapandi R

Loader.
Live Chat Icon For mobile
Up arrow icon