Issue with setting up control for CustomValue

I am working on a combobox custom value control. I am following the example here combobox custom value demo source 

Instead of a json data source i am using a data source connected to a webAPI I got the filtering to work but I cannot get the template to come up 
when adding a not existing Item

I have looked for further documentation on how to do this but have not found anything.

I am trying to set it up to where I type in a category and it does not exist I want to be able to add it to the database.
how can this be achieved as again I have not really found any examples of it being done with a remote datasource.

any guidance would be helpful.

Attachment: App_176b3a88.zip

16 Replies

JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 7, 2020 12:57 PM UTC

Hi David, 
 
Greetings from Syncfusion support. 
 
We have received your query. We will check and update you shortly. 
 
Thanks, 
Jeyanth. 



JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 7, 2020 01:51 PM UTC

Hi David, 
 
Greetings from Syncfusion support. 
 
We would like to know you that you can use noRecordsTemplate property to display templates when no matches found while filtering. Also we suggest you to use addItem() method to add a new list item in the popup.

In the attached sample, we have rendered a button as noRecordsTemplate which will display when you type the value which is not actually in the datasource.



 
 

Also click event for the button is bound and in that handler we are getting typed value and add that value in to the listitems using addItem() method. And so, whenever we clicked that button, it will automatically added the typed value as a new item in suggestion list.


 
onclick: function() { 
  // get the typed characters 
  var dropdownInstance = document.getElementById("country").ej2_instances[0]; 
  this.customValue = dropdownInstance.element.value; 
  // make new object based on typed characters 
  this.newItem = { 
    ContactName: this.customValue, 
    CustomerID: this.customValue 
  }; 
  // close the popup element. 
  dropdownInstance.hidePopup(); 
  // pass new object to addItem method. 
  dropdownInstance.addItem(this.newItem); 
  // select the newly added item. 
  dropdownInstance.value = this.customValue; 
} 
 
 


 
 

We have prepared sample for your convenience . Please find the sample in the attachment.

Sample Link : https://codesandbox.io/s/combobox-no-records-template-remote-datasource-1o63k?file=/src/App.vue
 
 
Hope this helps to achieve your requirements. Please let us know if you need any further assistance on this. 
 
Regards, 
Jeyanth. 



DW David Wisenbaugh September 7, 2020 06:33 PM UTC

hello 

when i filter out items I and not able to get the noRecordsTemplate  to popup even though I followed the sample step for step. I need to get that part resolved first then I can work on actually adding a new Item.

Are there any suggestions you can give me to get the noRecordsTemplate  to come up when I do the filtering ?

thanks 
David


JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 8, 2020 04:12 PM UTC

Hi David, 

We would like to know you that noRecordsTemplate will be displayed when you type the value in the input element which is not actually present in the suggestion list. As you can see in the screenshot mentioned in the previous update, the typed value “Myname” is not actually present in the suggestions and so noRecordsTemplate will be displayed eventually.

Please let us know if you still need any further assistance regarding this.

Regards, 
Jeyanth. 



DW David Wisenbaugh September 9, 2020 02:25 AM UTC

So i am using an ASP.net core backend when I setup the onFiltering query and put in the table name like this 

this.query = (e.text !== "") ? this.query.from("Categories").where("categoryName", startswith, e.text. true) : this.query;  

the request fails in the network tab with error code 400. 

when I have it like this 

this.query = (e.text !== "") ? this.query.where("categoryName", startswith, e.text. true) : this.query;  

then the filter request goes through but Im not sure i am still getting the correct data  also if I still type a non existing Item I still DO NOT get the noRecords Template to come up Ive tried using oDataV4Adaptor and the WebApiAdaptor with no success. 

Also how do I know that I am getting data returned from the query or if there is no data at all that it is filtering by is this the correct query for an asp.net core backend or is there another way that I need to set it up to get the correct functionality of this component 

how is it that I know that im getting data returned from my backend to the component to filter by. It could be that in fact I am not getting the correct results thus why Im not getting the noRecordsTemplate.


please advise 


JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 9, 2020 06:07 PM UTC

Hi David, 

Thanks for your update. 
  
We would like to inform you that if you have provided table name in the datasource URL, then we suggest you to remove table name from the Query property. In the below example, we have provided Customers table in the datsource URL and so removed in the query property. Please refer the below code snippets.

TableName in Datasource URL 
data: new DataManager({ 
  url: "https://services.odata.org/V4/Northwind/Northwind.svc/Customers", 
  adaptor: new ODataV4Adaptor(), 
  crossDomain: true 
}), 

onFiltering: function(e) { 
  this.query = new Query(); 
  // frame the query based on search string with filter type. 
  this.query = 
    e.text !== "" 
      ? this.query 
        .where("ContactName", "startswith", e.text, true) 
      : this.query; 
  // pass the filter data source, filter query to updateData method. 
  e.updateData(this.data, this.query); 
}, 


TableName not in Datasource URL 
data: new DataManager({ 
  url: "https://services.odata.org/V4/Northwind/Northwind.svc/", 
  adaptor: new ODataV4Adaptor(), 
  crossDomain: true 
}), 


onFiltering: function(e) { 
  this.query = new Query(); 
  // frame the query based on search string with filter type. 
  this.query = 
    e.text !== "" 
      ? this.query 
          .from("Customers") 
          .where("ContactName", "startswith", e.text, true) 
      : this.query; 
  // pass the filter data source, filter query to updateData method. 
  e.updateData(this.data, this.query); 
} 




Also you can use actionComplete event to know whether the data can be fetched properly from the backend.

 
If the fetched data has values, then action complete result will have elements in array. If the fetched data has empty array, then it returns an empty array.
  

Screenshot:

Fetched data has value 
 

 Fetched data does not have value


 
 


Please find the sample in the below link.

Sample Link        : https://codesandbox.io/s/combobox-no-records-template-remote-datasource-forked-wu6xq?file=/src/App.vue 

If the provided suggestion does not help you, please make the simple sample or video to demonstrate the issue. If possible, try to replicate the reported issue in the attached sample that would help us to validate the issue further and provide you a better solution from our end.

  
Regards, 
Jeyanth. 



DW David Wisenbaugh September 9, 2020 07:56 PM UTC

Jeyanth

I have created a small video showing what the combobox is not doing what it should be doing

Attachment: comboboxexample_9a6788e.zip

also how can I tell if the filtering is even working at this point to me it seems that it is not working that is why im not getting the noRecordsTemplate to come up ? what else can we do to get this working as it should. Could there be anything on my end that could be messing it up

this is my onFiltering method.

 onFiltering: function(e) {
      this.query = new Query();
      // frame the query based on search string with filter type.
      this.query = e.text !== "" ? this.query.from("Categories").where("CategoryName", "startswith", e.text, true) : this.query;
      console.warn(this.query.from("Categories").where("categoryName", "startswith", e.text, true));
      // pass the filter data source, filter query to updateData method.
      e.updateData(this.data, this.query);
    },

as far as i know and according to the examples you have given me previously that is how it should be . so what else could be wrong 

also I have this query attached to the control
remoteQuery: new Query().from("Categories").select(["CategoryName", "id"]).take(6),
but i am still getting all items not just the 6 requested .. 

please advise 
thanks


JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 10, 2020 05:35 PM UTC

Hi David, 

Thanks for your elaboration. 

We have checked the attached video. We would like to inform you that filtering process will happen if allowFiltering is set as true. We suspect that allowFiltering is not enabled and so while typing, popup is not filtered and also noRecordsTemplate not displayed. So we suggest you to set allowFiltering as true to resolve the issue.  If still issue persists try to reproduce the reported issue in the attached sample that would help us to validate the issue and provide you a better solution. 

Regards, 
Jeyanth. 



DW David Wisenbaugh replied to Jeyanth Muthu Pratheeban Sankara Subramanian September 10, 2020 05:51 PM UTC

Hi David, 

Thanks for your elaboration. 

We have checked the attached video. We would like to inform you that filtering process will happen if allowFiltering is set as true. We suspect that allowFiltering is not enabled and so while typing, popup is not filtered and also noRecordsTemplate not displayed. So we suggest you to set allowFiltering as true to resolve the issue.  If still issue persists try to reproduce the reported issue in the attached sample that would help us to validate the issue and provide you a better solution. 

Regards, 
Jeyanth. 



the allowFiltering  has always been set to true and Im still not getting the filtering results 
anything else to try 

please advise


PO Prince Oliver Syncfusion Team September 11, 2020 11:47 AM UTC

Hi David, 
 
Thank you for the update. Please check our sample in the earlier update and provide us steps to replicate issue in our sample. Else share us sample or code snippet sufficient to replicate the issue in our end. This will help us validate the root cause of the issue and provide a prompt solution. 

Regards, 
Prince 



DW David Wisenbaugh September 14, 2020 11:13 PM UTC

Ok From another post in your forums I found out that i had to use

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
      }
    }
  }
}

in a vue.config.js file.

Now my issue is that I am not even getting the template anymore and I think the reason is the fact that I am using ASP.NET core which returns JSON data not ODATA 
how to I setup to remotely query and access JSON response that my server is using.. even though I could query using WebApIAdaptor I am getting the data from the server but I cannot properly query it to have the template come up when I have it that way. 

As an experiment I added JsonAdaptor now Im not getting the data remotely but I am Getting the No records Template .. 

So what do i need to do to get this to work?

please Advise


JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 15, 2020 07:03 AM UTC

Hi David,

We have created a support incident for this under your Direct Trac account.  Please log on to our support website to check for further updates. Please refer the below link.

http://www.syncfusion.com/Account/Logon?ReturnUrl=%2fsupport%2fdirecttrac  
  
Regards, 
Jeyanth. 



DW David Wisenbaugh September 15, 2020 10:29 PM UTC

UPDATE

I have setup an odata endpoint on my backend and can now get the noRecordsTemplate.  Now my question is how can I add the new Item to my remote database when the Add new Item button is clicked.

I want to get the value as the Id of the selected Item and the Text as CategoryName. 

would I have to put this in the database first then update the custom value with the right data if how how can I get this done
please advise


Also how do you refresh the combobx list once new data is added so that I can get the correct value

and how do you enable the floating label on the combobox.

please advise


JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 16, 2020 05:21 PM UTC

  
Hi David, 

Thanks for your update.


 
We are glad to hear that you have achieved the noRecordsTemplate. We would like to know you that when adding new item using addItem() method, only a new li element will be added to the popup and existing datasource will not be affected. If you want to change to database then you need to manually change the value to the database and in the datasource variable also as like below.


 

onclick: function() { 
      // get the typed characters 
      var dropdownInstance = document.getElementById("country") 
        .ej2_instances[0]; 
      this.customValue = dropdownInstance.element.value; 
      // make new object based on typed characters 
      this.newItem = { 
        Name: this.customValue, 
        Code: this.customValue 
      }; 
      // pass new object to addItem method. 
      dropdownInstance.addItem(this.newItem); 
      //new object added to data source variable. 
      dropdownInstance.dataSource.push(this.newItem); 
      dropdownInstance.dataBind(); 
      // close the popup element. 
      dropdownInstance.hidePopup(); 
      // select the newly added item. 
      dropdownInstance.value = this.customValue; 
      document.getElementById("datasource").innerText = ""; 
      dropdownInstance.dataSource.forEach(element => { 
        document.getElementById("datasource").innerText += `${element.Code}\t ${ 
          element.Name 
        }\n`; 
      }); 
    } 




To manually insert the value in to the database, we suggest you to call the database method in the filtering event using Ajax call with the custom data as additional parameters. And in the server end, receive the custom data and insert the custom data in to the database. If possible kindly share the Odata method, we will assist you accordingly.

We also would like to aware you that calling dataBind() method will allow to refresh the properties which we have affected. In the above sample we have affected the datasource property and we called dataBind() method to get refreshed. 

To enable the floatlabel in Combobox, we suggest you to set floatLabelType property. Setting floatLabelType as Always set the label element to be floated always at the top of the input element, setting Auto will float the label element when control gets focus and setting Never will not make the label element to float.

API Link: https://ej2.syncfusion.com/vue/documentation/api/combo-box#floatlabeltype 


 
Regards, 
Jeyanth. 



DW David Wisenbaugh September 22, 2020 09:14 PM UTC

 this is my odata post method on the backend 

[HttpPost]
        [EnableQuery]
        public async Task PostCategory([FromForm] CategoryCreateDto categoryCreateDto)
        {
            try
            {
                var category = _mapper.Map(categoryCreateDto);
                _context.Categories.Add(category);
                await _context.SaveChangesAsync();
                var categoryDto = _mapper.Map(category);
                ExpandoObject response = new ExpandoObject();
                response.TryAdd("Categories", _context.Categories);
                //response.TryAdd("CategoryAdded", categoryDto);

                return CreatedAtAction("GetCategories", response);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
           
        }

I was able to get an axios call to post  in the onClick method which did add it once to the database but did not get the refreshed data for the dropdown so I can select
the new Item and get the id value.

Im not sure adding the post method to the onFiltering is the right way to go as it will add each typed letter of the query unless there is a way I can set it to add it once the whole category is typed in. 

this is my axios/ajax call to the database 

// add new item to database.
const formData = new FormData()
formData.append('CategoryName', customValue)
axios({
method: 'post',
url: 'https://localhost:5001/odata/Categories',
data: formData,
headers: { 'Content-Type': undefined }
})
.then((response) => {
console.warn('Axios Response: ', response)
})

how do i proceed 

please advise



JM Jeyanth Muthu Pratheeban Sankara Subramanian Syncfusion Team September 28, 2020 05:47 PM UTC

Hi David,

Thanks for your patience.

We have prepared sample for your requirement. Please find the details below. You can add the custom data to the server using axios call in Filtering event only when filtered value in not in datasource.


Also you can make the dropdown to refresh the added custom data in either any of the two ways.

1. Using addItem() method.

With the help of  addItem() method, a new list item will be created based on the typed custom data. You need to pass the custom data as arguments of this method.


 

onclick: function() { 
      // get the typed characters 
      var dropdownInstance = document.getElementById("country") 
        .ej2_instances[0]; 
      this.customValue = dropdownInstance.element.value; 
      // make new object based on typed characters 
      this.newItem = { 
        Name: this.customValue, 
      }; 
      // pass new object to addItem method. 
      dropdownInstance.addItem(this.newItem); 
      // select the newly added item. 
      dropdownInstance.value = this.customValue; 
} 
 




2. Updating the dataSource property.

In the server end, we need to return the JSON data. Once the made axios call is success, we get the returned data as response and we can update that data to the dataSource property.


 

axios({  
      method: 'post',  
      url: 'https://localhost:44345/Home/UrlDatasource',  
      data: customData,  
      headers: {  'Content-Type': 'application/json'}  
    } 
      .then((response) => {  
        console.warn('Axios Response: ', response); 
        dropdownInstance.dataSource = new DataManager(response.data); 
        dropdownInstance.refresh();  
      } 



Also when focus out the control, popup will be closed. Data will be filtered again once the value is typed in the input element. To manually filter the data when focus the control, we suggest you to call the searchLists() method in the focus event.

 

onFocus: function(e) { 
            var dropdownInstance = document.getElementById("country").ej2_instances[0]; 
            if(dropdownInstance.element.value){ 
              dropdownInstance.searchLists(e); 
            } 
        } 


Please find the sample in the below link.

Sample Links

 

Regards, 
Jeyanth. 


Loader.
Up arrow icon