DataGrid autocomplete using Razor pages

Hi,

is there an example available for Razor pages on how to use autocomplete functionality in DataGrid?

I want to use URLadaptor same as I do in DataGrid to capture data on the serverside and return the result to display in autocomplete.

my grid looks like this:

<ejs-grid id="PaleteGrid" load="onLoad" showColumnChooser="true" allowPaging="true" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel", "ColumnChooser" })" allowFiltering="true" allowSorting="true" allowPaging="true"})">
    <e-grid-editsettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal" showDeleteConfirmDialog="true"></e-grid-editsettings>
    <e-data-manager url="Palete/Index?handler=DataSource" insertUrl="Palete/Index?handler=Insert" updateUrl="Palete/Index?handler=Update" removeUrl="Palete/Index?handler=Delete" adaptor="UrlAdaptor"></e-data-manager>
    <e-grid-filterSettings type="Menu"></e-grid-filterSettings>
    <e-grid-aggregates>
        <e-grid-aggregate>
            <e-aggregate-columns>
                <e-aggregate-column field="volumen" type="Sum" format="N2" footerTemplate="${Sum} m<sup>2</sup>"></e-aggregate-column>
             </e-aggregate-columns>
        </e-grid-aggregate>
    </e-grid-aggregates>
    <e-grid-pageSettings pageCount="5" pageSize="10"></e-grid-pageSettings>
    <e-grid-columns>
        <e-grid-column field="id" headerText="ID" visible="true" isidentity="true" isPrimaryKey="true" textAlign="Right"> </e-grid-column>
        <e-grid-column field="dobavnica.dobavitelj.naziv" headerText="Dobavitelj" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="dobavnica.stevilka" headerText="Dobavncia" type="string" width="120" edit="@(new {create="create", read="read", destroy="destroy", write="write"})"></e-grid-column>
        <e-grid-column field="datum" headerText="Datum" customFormat="@(new { type ="date", format="dd.MM.yyyy" })" type="date" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="tip" headerText="Tip" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="dolzina" headerText="Dolžina" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="sirina" headerText="Širina" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="visina" headerText="Višina" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="steviloKosov" headerText="Kolicina" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="volumen" headerText="Volumen" Format="N2" validationRules="@(new { required=true})"> </e-grid-column>
        <e-grid-column field="status" headerText="Status" validationRules="@(new { required=true})"> </e-grid-column>
    </e-grid-columns>
</ejs-grid>

I would like to create autocomplete for field dobavnica.stevilka




9 Replies 1 reply marked as answer

RS Rajapandiyan Settu Syncfusion Team January 11, 2022 10:42 AM UTC

Hi Miha 
 
You can achieve your requirement by using cellEditTemplate feature. 


Find the below code example and sample for your reference. 


[index.cshtml] 

--- 
<e-grid-column field="Dobavnica.Stevilka" headerText="Dobavnica" width="120" edit="@(new {create="create", read="read", destroy="destroy", write="write"})"></e-grid-column> 
 
 
<script> 
 
    var ddlObject; 
    function create() { 
        //  create a input element 
        return document.createElement('input'); 
    } 
 
    function read(args) { 
        // return the value which will be saved in the grid 
        return ddlObject.value; 
    } 
 
    function destroy() { 
        // destroy the custom component. 
        ddlObject.destroy(); 
    } 
 
    function write(args) { 
        console.log(args); 
        console.log(args.rowData); 
        // create a autoComplete control 
        ddlObject = new ej.dropdowns.AutoComplete({ 
            //bind the URL Adaptor 
            dataSource: new ej.data.DataManager({ 
               url: 'Index?handler=UrlDatasourceDD', 
               adaptor: new ej.data.UrlAdaptor(), 
               headers: [{ 'XSRF-TOKEN': $("input:hidden[name=__RequestVerificationToken]").val() }], // send the AntiForgery token 
               crossDomain: true 
            }), 
            //bind the current cell value to the autocomplete which will be displayed only when the dataSource contains that value 
            value: args.rowData["Dobavnica"]["Stevilka"], 
            //map the appropriate columns to fields property 
            fields: { text: 'ShipCountry', value: 'ShipCountry' }, 
            //set the placeholder to AutoComplete input 
            placeholder: "Find a customer" 
        }); 
        //render the component 
        ddlObject.appendTo(args.element); 
    } 
</script> 



Please get back to us if you need further assistance with this. 

Regards,  
Rajapandiyan S 


MI Miha January 11, 2022 08:15 PM UTC

Hi  Rajapandiyan,


thank you very much for the answer. The example works perfectly. However, I don't understand how it works. Where do I bind the data that I want to send to the server-side, and most import how do I retrieve this data on the server-side?

For example, before I was using jQuery to handle autocomplete. Binding the data was straightforward there and also retrieving them.


Example jQuery :

$('#DobavnicaStevilka').autocomplete({
        autoFocus: true,
        source: function (request, response) {
            $.ajax({
                url: '/Palete/Create?handler=AutoCompleteDobavnica',
                beforeSend: function (xhr) {
                    xhr.setRequestHeader("XSRF-TOKEN",
                        $('input:hidden[name="__RequestVerificationToken"]').val());
                },
                data: { "prefix": request.term, "dobaviteljNaziv": DobaviteljNaziv.value },
                type: "POST",
                success: function (data) {
                    response($.map(data, function (item) {
                        return item;
                    }))
                },
                error: function (response) {
                    alert(response.responseText);
                },
                failure: function (response) {
                    alert(response.responseText);
                }
            });
        },
        select: function (event, ui) {
            if (document.getElementById("DobaviteljNaziv").value == "") {
                var $form = $('form');
                var data = {
                    'dobavnicaSt': ''
                };
                data.dobavnicaSt = ui.item.label;
                data = $form.serialize() + '&' + $.param(data);
                $.post('/Palete/Create?handler=DobavnicaSelect', data, function (msg) {
                    document.getElementById("DobaviteljNaziv").value = msg;
                });
            }
        }
    });


Server-side:

public async Task<IActionResult> OnPostAutoCompleteDobavnicaAsync(string prefix, string dobaviteljNaziv)
        {
            if (dobaviteljNaziv != null)
            {
                var Dobavnica = await _context.Dobavnica
                    .Where(d => d.Stevilka.Contains(prefix) && d.Dobavitelj.Naziv.Contains(dobaviteljNaziv))
                    .Select(d => d.Stevilka)
                    .ToListAsync();
                return new JsonResult(Dobavnica);
            }
            else
            {
                var Dobavnica = await _context.Dobavnica
                    .Where(d => d.Stevilka.Contains(prefix))
                    .Select(d => d.Stevilka)
                    .ToListAsync();
                return new JsonResult(Dobavnica);
            }
        }


The models look like that:

    public class Dobavitelj
    {
        public int Id { get; set; }
        [StringLength(30)]
        [Display(Name = "Naziv dobavitelja")]
        public string Naziv { get; set; }
        #nullable enable
        [StringLength(30)]
        [Display(Name = "Naslov")]
        public string? Naslov { get; set; }
        [Display(Name = "Poštna številka")]
        public int? PostnaStevilka { get; set; }
        [Display(Name = "Pošta")]
        [StringLength(30)]
        public string? Posta { get; set; }
        [Display(Name = "Država")]
        [StringLength(30)]
        public string? Drzava { get; set; }
        [Display(Name = "Datum vnosa kupca")]
        #nullable disable
        public DateTime DatumVnosa { get; set; }
        public ICollection<Dobavnica> Dobavnica { get; set; }
    }


public class Dobavnica
    {
        public int Id { get; set; }
        public int DobaviteljID { get; set; }
        [Display(Name = "Številka dobavnice")]
        [StringLength(20, MinimumLength = 2)]
        public string Stevilka { get; set; }
        [Display(Name = "Datum dobavnice")]
        [DataType(DataType.Date)]
        //[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
        public DateTime Datum { get; set; }
        public Dobavitelj Dobavitelj { get; set; }
        public ICollection<Paleta> Paleta { get; set; }
    }


    public enum Status
    {
        Dobava,
        Skladišče,
        Sušenje,
        Posušeno,
        Razrez,
        Razrezano
    }
    public class Paleta
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }
        [Required]
        [Display(Name = "Številka dobavnice")]
        public int DobavnicaID { get; set; }
        [Display(Name = "Datum dobave")]
        [DataType(DataType.Date)]
        //[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
        public DateTime Datum { get; set; }
        [Required]
        [StringLength(20)]
        [Display(Name = "Material")]
        public string Tip { get; set; }
        [Required]
        [Display(Name = "Dolžina")]
        public int Dolzina { get; set; }
        [Required]
        [Display(Name = "Širina")]
        public int Sirina { get; set; }
        [Required]
        [Display(Name = "Debelina")]
        public int Visina { get; set; }
        [Required]
        [Display(Name = "Količina")]
        public int? SteviloKosov { get; set; }
        [Display(Name = "Volumen")]
        [DisplayFormat(DataFormatString = "{0:0.00}", ApplyFormatInEditMode = true)]
        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public double Volumen { get; private set; }
        [Display(Name = "Status palete")]
        public Status Status { get; set; }
        public Dobavnica Dobavnica { get; set; }
    }


now the question is how to implement passing the data in the same way to serverside and then back to the front end?


Thank you very much for your support, 



RS Rajapandiyan Settu Syncfusion Team January 12, 2022 09:44 AM UTC

Hi Miha 

Before proceeding with your query, we need a confirmation from your side. Are you want to send additional parameters to the server side with using URL Adaptor in AutoComplete control? Please confirm on that. 

If this not your requirement, kindly share more details to proceed further. 

Regards,  
Rajapandiyan S 



MI Miha January 12, 2022 04:05 PM UTC

Hi Rajapandiyan,


This is correct. I need to send additional parameters to the server-side.


My case is that I have customers (Dobavitelji). Each customer has multiple delivery notes (Dobavnica). But the delivery note has only one customer (foreign key). This is why I would like to display in autocomplete control only the delivery notes which are bound to the customer. This means I need to send to the server-side the name of the selected customer in order to obtain the delivery notes only from that specific customer.


Best Regards, M



RS Rajapandiyan Settu Syncfusion Team January 13, 2022 07:56 AM UTC

Hi Miha, 

Thanks for your update. 
 
You can send additional parameters to the server side by using addparams method in AutoComplete component. 
 
In the write method, we send multiple parameters in the AutoComplete’s query. Please find the below code example for more information. 
 
 
 
[index.cshtml] 
 
    function write(args) { 
        // add multiple parameters in the Query 
        var query = new ej.data.Query(); 
        query.addParams('CustomerID', args.rowData.CustomerID); 
        query.addParams('OrderID', args.rowData.OrderID) 
 
        ddlObject = new ej.dropdowns.AutoComplete({ 
            ---- 
            //bind query property 
            query: query 
        }); 
        //render the component 
        ddlObject.appendTo(args.element); 
    } 
 
 
[index.cshtml.cs] 
        public JsonResult OnPostUrlDatasourceDD([FromBody] Data dm) 
        { 
            ---- 
            return new JsonResult(Data); 
        } 
        public class Data 
        { 
            public int take { get; set; } 
            public List<Wheres> where { get; set; } 
            public ParamObject Params { get; set; }  // use paramObject to retrieve the additional parameters 
        } 
        public class ParamObject   // define the required field as you want 
        { 
            public int? OrderID { get; set; } 
            public string CustomerID { get; set; } 
        } 
 
 
Screenshot: 
 
 
 
Please get back to us if you need further assistance with this. 
 
Regards, 
Rajapandiyan S 


Marked as answer

MI Miha January 13, 2022 01:11 PM UTC

Dear Rajapandiyan,


thank you for your support this solved my question. I must say I'm impressed about your product and also the support.


Best Regards, Miha



MI Miha January 17, 2022 05:46 AM UTC

One more thing,

When I complete the autoselect the chosen value must reflect directly in the grid in order to load new data for the foreign key autocomplete. I believe this is possible to achieve through querySelector. querySelector is working perfectly for this as long as I don't have complex fields. The question is now how do I set a complex field in querySelector?


my grid name:

<ejs-grid id="PaleteGrid"

complex column name:

<e-grid-column field="Dobavnica.Dobavitelj.Naziv"

query selector:

change: (e) => {
            document.querySelector("#PaleteGridDobavnicaDobaviteljNaziv").value = e.value;
}


What am I missing?




MI Miha January 17, 2022 09:42 PM UTC

I had figured this one out:


you access a complex element like:


<e-grid-column field="Dobavnica.Dobavitelj.Naziv"


by using triple underscore instant of dot:


var formEle = document.getElementById("PaleteGrid").querySelector("form").ej2_instances[0];
var dobaviteljEle = formEle.getInputElement('Dobavnica___Dobavitelj___Naziv');





RS Rajapandiyan Settu Syncfusion Team January 18, 2022 06:25 AM UTC

Hi Miha, 
 
We are glad that the provided solution resolves your requirement and always happy to assist you. 
 
By default, Triple underscore(‘___’)  is used for the complex field in the Grid edit Form. This has been already included in our release note section. 
 
 
So, we suggest you to use triple underscore in place of dot to access the input element of complex field. 
 
 
var dobaviteljEle = formEle.getInputElement('Dobavnica___Dobavitelj___Naziv'); 
 
 
Regards, 
Rajapandiyan S 


Loader.
Up arrow icon