Search code examples
jqueryjquery-uiautocompletedurandal

How to make jQuery AutoComplete function work in Durandal?


I'm adding autoComplete functionality in a existing Durandal app. I've declared the jQuery-UI lib in the main.js and in my component. I've built a test-array with values to feed the AutoComplete widget (a console.log shows that this array has value in it). I've set a hold point near the AutoComplete function and I can see the app passing in when document.ready function triggers. When I try to input some letters in the input field, no values are displayed. What did I forget ?

Here is my HTML (just a part) :

<!-- Operation ID -->
<div class="form-group">
    <label class="col-xs-4" data-bind="text:props.getProperty('label.search.operation.id')"></label>
    <div class="col-xs-8">
        <input type="text" id="operationID" data-bind="value: model.filter().operationID, click: advancedSearch" class="form-control" autocomplete=on />
    </div>
</div>

Here is the corresponding JS file (part), function can be seen at the end of file :

define(['durandal/app', 'knockout', 'jquery', 'services/propertiesService', 'utils/dateUtils', 'jquery-ui'],
    function(app, ko, $, props, dateUtils, ui) {

        var model = {};

        model.trackedObjects = [];
        model.successes = ko.observableArray();
        model.errors = ko.observableArray();
        model.warnings = ko.observableArray();

        model.currencies = ko.observableArray([]);
        model.buyers = ko.observableArray([]);
        model.platforms = ko.observableArray([]);
        model.steps = ko.observableArray([]);
        model.operationTypes = ko.observableArray([]);
        model.counterparts = ko.observableArray([]);

        model.choosenRoleCode = ko.observableArray();
        model.resultCount = ko.observable(0);

        // .................................
        // Many other properties

        //Set the button 'Go on top' if the scrolling is not on top of the window
        $(window).scroll(function(event) {
            var st = $(this).scrollTop();
            if (st > 0) {
                //On top
                model.hasScrollbar(true);
            } else {
                model.hasScrollbar(false);
            }
        });
        /* _____________________ENDING - Scroll bar____________________ */

        // AUTOCOMPLETE : Fill OperationID with values
        $(document).ready(function() {
            var availableTags = [
                "TOTO",
                "TITI",
                "TUTU"
            ];
            console.log("hop : " + availableTags); // hop : TOTO,TITI,TUTU
            $("#operationID").autocomplete({
                source: availableTags
            });
        });

        return model;
    })

Has anybody already encountered this problem ?


Solution

  • You should move all the jQuery functionality inside the Lifecycle callback named compositionComplete. This function is executed after the entire view is composed and operationID is available on the DOM

    define(['durandal/app', 'knockout', 'jquery', 'services/propertiesService', 
           'utils/dateUtils', 'jquery-ui'],
      function(app, ko, $, props, dateUtils, ui) {
    
        var model = {};
    
        model.trackedObjects = [];
        model.successes = ko.observableArray();
        model.errors = ko.observableArray();
        model.warnings = ko.observableArray();
    
        // ........
    
        model.compositionComplete: function() {
          var availableTags = ["TOTO", "TITI", "TUTU"];
    
          $("#operationID").autocomplete({
            source: availableTags
          });
    
          $(window).scroll(function(event) {
            var st = $(this).scrollTop();
            if (st > 0) {
              //On top
              model.hasScrollbar(true);
            } else {
              model.hasScrollbar(false);
            }
          });
        }
    
        return model;
      })