Autocomplete Events in MVVM, How to?

13 posts, 1 answers
  1. Duke
    Duke avatar
    17 posts
    Member since:
    Apr 2013

    Posted 30 May 2013 Link to this post

    Hey everyone!

    I was searching all over but couldn't find an answer to my question. I'm initializing an autocomplete widget as the following:

    This code is loaded into my DOM as a result of an Ajax request:
    <div id="view_ticketCreate">
        <form id="jar_ticketing_create"action="" class="k-block jar-container">
            <fieldset class="login">
                <legend>Kontaktinformationen</legend>
                <p class="notice">Definieren Sie hier die Kontaktinformationen zu diesem Ticket.</p>
                <p>
                    <label>Kunde</label>
                    <input data-role="autocomplete" data-bind="source: customers, events{click: inject}" data-text-field="CName" placeholder="Suchen Sie nach dem Kunde" type="text" id="jtc_cID" class="k-textbox sourced">
                </p>
                <p>
                    <label>Kontakt</label>
                    <input type="text" name="jtc_cName" class="k-textbox">
                </p>
                <p>
                    <label>E-Mail</label>
                    <input data-bind="value: cMail" type="text" name="jtc_cMail" class="k-textbox">
                </p>
                <p>
                    <label>Telefon</label>
                    <input data-bind="value: cPhone" type="text" name="jtc_cPhone" class="k-textbox">
                </p>
                <p>
                    <label>Gerät</label>
                    <select name="dID" class="k-textbox sourced">
                      <option value="000">Nicht geräte spezifisch</option>
                      <option value="001">CFBS01</option>
                      <option value="002">CFBS02</option>
                      <option value="003">CFBS03</option>
                      <option value="004">CFBS04</option>
                    </select>
                </p>
                <p>
                    <label>Login</label>
                    <input type="text" name="cLogin" class="k-textbox">
                </p>
            </fieldset>
    </form>
    </div>
    <script>
          kendo.bind($("#view_ticketCreate"), view_ticketCreate);
    </script>
    in my main (an always loaded) JS file i got:
    var view_ticketCreate = kendo.observable({
           customers: new kendo.data.DataSource({
               transport: {
                   read: {
                       url: "http://server/API/customers/search/",
                       dataType: "jsonp",
                       contentType: "application/json; charset=utf-8"
                   },
                   parameterMap: function(options, operation) {
                       return {
                           SearchTag: options.filter.filters[0].value
                       }
                   }
               },
               schema: {
                   data: "data"
               },
               serverFiltering: true,
               dataTextField: "CName",
                select: function(e){
                    if (e.item == null) return;
                    var DataItem = this.dataItem(e.item.index())
                    cPhone: DataItem.Telefon
                }
           }),
           inject: function(e){
               alert('ok')
           },
           cPhone: "0123456789",
           cMail: "asd@asd.de"
    });
    However,  the autocomplete search works perfect. But now I want to populate the fields jtc_cMail and  jtc_cPhone with values from my autocomplete request. But either the select: Function is working (not allowed here (guess because MVVM?), also the custom event inject is fireing.

    I couldn't find anything how I need to go on. Please help me out.

    Greetings

    Duke
  2. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 31 May 2013 Link to this post

    Hello,

     I created a short demo which shows how to use the change event of the autocomplete when bound to a data source via MVVM: http://jsbin.com/iluquq/2/edit

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Duke
    Duke avatar
    17 posts
    Member since:
    Apr 2013

    Posted 31 May 2013 Link to this post

    Good Morning Atanas

    I updated your jsBIN to show you what I'm exactly looking for:

    http://jsbin.com/oponat/4/edit

    But I don't know how do parse the response fields to the input elements.

    Another question: I'm injecting the hole Form by Ajax in a new Tab from a tabStrip instance. So I'm using observable. Is this correct?

    Greetings & Thank you for your help!
  4. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 31 May 2013 Link to this post

    Hello,

     The updated jsbin doesn't do anything right now. The `this.dataItem` exression is evaluated to `undefined` and nothing will happen after that. To get the value of the autocomplete widget you should use the value() method which I have demonstrated in my jsbin demo. The value method will return the value currently selected by the user (the property specified by data-text-field).

    I don't understand your next question. What does "injecting the hole form by ajax in a new tab" mean?

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  5. Duke
    Duke avatar
    17 posts
    Member since:
    Apr 2013

    Posted 31 May 2013 Link to this post

    The autocomplete gets a JSON response. And I want to transfer the values of UnitPrice and UnitsInStock into the input fields as soon as I'm selecting a product from the autocomplete list. (The idea behind this is, that parts of a html form gets prepopulated depending on my selection in the autocomplete field)

    The value() only grants me access to the ProductName, right? So how do I access the other JSON values that I get from the dataSource:

    [{"ProductID":1,"ProductName":"Chai","UnitPrice":18,"UnitsInStock":39,"Discontinued":false}]
    Or how can I access the JSON object to transfer part of it into my other input elements.

    Hope its more clear now. Appriciate you stick on my thread. Thank you!
  6. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 31 May 2013 Link to this post

    Hi,

     The autocomplete doesn't provide the whole data item. So you have two options:
    1. Traverse all products to find the one whose product name is the selected one
    2. Use a different widget which supports text and value binding - ComboBox, DropDownList. I have updated your demo to show how this could be done: http://jsbin.com/oponat/8/edit

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  7. Duke
    Duke avatar
    17 posts
    Member since:
    Apr 2013

    Posted 31 May 2013 Link to this post

    Hey Atanas

    Thank you for the example. But you just get the hole set of data as values for the combobox. I need to get the datasource requeryed and filtered on the server while typing, because its a lot of data. I've got a working example of autocomplete which does exactly what I need but isn't in MVVM:

    'use strict';
     
    (function($, kendo) {
         
        $("#autocomplete").kendoAutoComplete({
           minLength: 3,
           dataSource: new kendo.data.DataSource({
               transport: {
                   read: {
                       url: "http://server/API/customers/search/",
                       dataType: "jsonp",
                       contentType: "application/json; charset=utf-8"
                   },
                   parameterMap: function(options, operation) {
                       return {
                           SearchTag: options.filter.filters[0].value
                       }
                   }
               },
               schema: {
                   data: "data"
               },
               serverFiltering: true
           }),
           dataTextField: "CName",
           placeholder: "Search for a Name",
           select: function(e){
            if (e.item == null) return;
            var DataItem = this.dataItem(e.item.index());
            alert("You selected the customer with ID" + DataItem.cID + " and Customer Name " + DataItem.cName")
       })
    When I initialize the same unter the MVVM pattern, as you noticed e.item is undefined.

    So which options do I have now to achieve my goals?

    If I take the way from your example:

    1. how can I pass what I'm typing as filter to my datasource
    2. how can I force to requery the datasource while typing

    Hope you got it. Thank you very much.
  8. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 03 Jun 2013 Link to this post

    Hello,

     Your original code doesn't work because you have set autocomplete options (e.g. dataTextField, select, etc). in the data source configuration. Those should be set via data attributes (the options) and the events binding (for the select event). Here is a sample code snippet:

    <input data-role="autocomplete" data-text-field="foo" data-bind="source: dataSource, events { select: select }" />

    var viewModel = kendo.observable({
        dataSource: new kendo.data.DataSource( { /* data source configuration */ }),
        select: function(e) {
           var autocomplete= e.sender;
           var dataItem = autocomplete.dataItem(e.item.index());
        }
    });

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  9. Duke
    Duke avatar
    17 posts
    Member since:
    Apr 2013

    Posted 04 Jun 2013 Link to this post

    Hi Atanas

    I guess I'm very close to the solution now. Here is my actual code:

    var view_ticketCreate = kendo.observable({
      products: new kendo.data.DataSource({
        transport: {
          read: {
            dataType: "jsonp"
          }
        }
      }),
      product: null,
      ProductName: "1",
      UnitPrice: "2",
      UnitsInStock: "3",
      select: function(e){
        var autocomplete = e.sender;
        var dataItem  = autocomplete.dataItem(e.item.index());
        ProductName   = dataItem.ProductName;
        UnitPrice     = dataItem.UnitPrice;
        UnitsInStock  = dataItem.UnitsinStock;
      }
    });
     
    kendo.bind($("#view_ticketCreate"), view_ticketCreate);
    However, my fields don't get updated. If I check with the console from jsBIN and also with firebug I don't get any errors. If I put an alert within my select function as
    alert(dataItem.UnitsinStock)
    I get the right value. Here is an updated jsBIN:

    http://jsbin.com/oponat/10/edit

    Thanks in advance!
  10. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 04 Jun 2013 Link to this post

    Hello,

     You need to use the set method of an observable object in order to update its fields:

    this.set("ProductName",  dataItem.ProductName); 

     I recommend checking the ObservableObject help topic for additional info.

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  11. Duke
    Duke avatar
    17 posts
    Member since:
    Apr 2013

    Posted 04 Jun 2013 Link to this post

    Hello Atanas

    It did the trick, how to bind the vales to the input elements. But what I still couldn't figure out is how to enable serverFiltering and pass a SearchString to the jsonp datasource?
  12. Answer
    Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 04 Jun 2013 Link to this post

    Hi,

     What happens when you use your code which worked? Setting serverFiltering and providing a parameterMap in the data source is enough.

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  13. Duke
    Duke avatar
    17 posts
    Member since:
    Apr 2013

    Posted 04 Jun 2013 Link to this post

    Yeay!

    I finally got it working as expected. Here is my code:

    var view_ticketCreate = kendo.observable({
       customers: new kendo.data.DataSource({
           transport: {
               read: {
                   url: "http://server/API/customers/search/",
                   dataType: "jsonp",
                   contentType: "application/json; charset=utf-8"
               },
               parameterMap: function(options) {
                   return {
                       SearchTag: options.filter.filters[0].value
                   }
               }
           },
           schema: {
               data: "data"
           },
           serverFiltering: true
       }),
       cName: null,
           cPhone: null,
           cMail: null,
           select: function(e){
            var autocomplete = e.sender;
            var dataItem  = autocomplete.dataItem(e.item.index());
            this.set("cName",  dataItem.CName);
            this.set("cPhone",  dataItem.Telefon);
            this.set("cMail",  dataItem.Mail);
           }
    });
    Thank you so much for your help Atanas. It's now querying my JSONP remote dataSource while typing and on select, it fills out phone number and email address.

    Perfect, like a charm!

    Thank you again and have a great day!
Back to Top