2013-11-02 60 views
0

我正在使用自動完成功能,但同時我希望更改事件將模糊或更改中的值保存在數據庫中。Knockoutjs - 自動完成「偷取」更改事件

<input type="text" data-bind="event: {change: $parent.saveVariable}, 
    autocomplete:{ 
     url: $root.api.autocomplete.searchMasterVariableUrl(), 
     renderitem: renderMasterVariableSearch, 
     onselection: function (item) { if (item.text) masterText(item.text); } 
    }, 
    autocompletevalue: masterCode" /> 

這不起作用....如果我刪除自動完成功能它的作品!

有什麼建議嗎?

問候 肛

自動完成的實現如下(它是一個bindinghandler):

(函數($,KO){

ko.bindingHandlers.autocomplete = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var $element = $(element), 
      opt = valueAccessor(), 
      allBindings = allBindingsAccessor(); 

     function writeToModel(newValue) { 
      if (!ko.isObservable(allBindings.autocompletevalue) || ko.isWriteableObservable(allBindings.autocompletevalue)) { 
       var currentValue = ko.utils.unwrapObservable(allBindings.autocompletevalue); 

       if (newValue && $.isFunction(opt.valueselector)) { 
        newValue = opt.valueselector.call(this, newValue); 
       } 
       else if (newValue && newValue.label) { 
        newValue = newValue.label; 
       } 

       if (currentValue !== newValue) { 
        if (ko.isWriteableObservable(allBindings.autocompletevalue)) { 
         allBindings.autocompletevalue(newValue); 
        } 
        else { 
         allBindings.autocompletevalue = newValue; 
        } 
       } 
      } 
     } 

     var config = { 
      minLength: opt.minLength || 2, 
      source: function (request, response) { 
       var req = { term: request.term }; 
       if($.isFunction(opt.requestdataselector)) { 
        opt.requestdataselector.call(this, req); 
       } 
       $.getJSON(opt.url, req, function (data, status, xhr) { 
        if (opt.label) { 
         if (typeof opt.label === 'string') { 
          $.each(data, function (idx, el) { el.label = el[opt.label]; }); 
         } 
         else if ($.isFunction(opt.label)) { 
          $.each(data, function (idx, el) { el.label = opt.label.call(this, el); }); 
         } 
        } 

        response(data); 
       }).fail(function(error) { 
        toastr.error('Failed autocomplete search: ' + error.responseText); 
       }); 
      }, 
      focus: function (ev, ui) { 
       $element.val(ui.item.label); 
       return false; 
      }, 
      select: function (ev, ui) { 
       $element.val(ui.item.label); 

       writeToModel(ui.item); 

       if ($.isFunction(opt.onselection)) { 
        var ctx = ko.dataFor(this); 
        opt.onselection.call(ctx, ui.item); 

        if ($.isFunction(opt.afterselection)) { 
         opt.afterselection.call(this, $element, ui.item, this); 
        } 
       } 

       return false; 
      }, 
      change: function (ev, ui) { 
       var val = $(ev.target).val(); 
       if (opt.allowcustomtext) { 
        writeToModel(val); 
       } 
       else { 
        if (ko.isObservable(allBindings.autocompletevalue) && allBindings.autocompletevalue() !== val) { 
         $element.val(null); 
         writeToModel(null); 
        } 
       } 
      } 
     }; 

     var subscription; 
     if (ko.isWriteableObservable(allBindings.autocompletevalue)) { 
      subscription = allBindings.autocompletevalue.subscribe(function (newValue) { 
       $element.val(newValue); 
      }); 
      var val = ko.utils.unwrapObservable(allBindings.autocompletevalue); 
      $element.val(val); 
     } 

     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $element.autocomplete("destroy"); 
      if (subscription) { 
       subscription.dispose(); 
      } 
     }); 

     $element.autocomplete(config); 
     if($.isFunction(opt.onenter)) { 
      $element.on('keydown', function (ev) { 
       if(ev.keyCode === 13) { 
        ev.preventDefault(); 
        ev.stopPropagation(); 

        opt.onenter.call(this, ko.dataFor(ev.target), ev.target); 
       } 
      }); 
     } 

     if ($.isFunction(opt.renderitem)) { 
      $element.data("ui-autocomplete")._renderItem = opt.renderitem; 
     } 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var $element = $(element), 
      opt = valueAccessor(), 
      allBindings = allBindingsAccessor(); 

     if (ko.isObservable(allBindings.autocompletevalue)) { 
      var val = allBindings.autocompletevalue(); 
      $element.val(val); 
     } 
    } 
}; 

})(jQuery的,KO );

+0

您可以添加代碼自動完成實施? – pax162

+1

看看這個。 http://jsfiddle.net/7bRVH/214/ – naveen

回答

0

我更新了上述人員提交的代碼,以改爲使用自動完成的更改。

簡而言之,自動完成具有自己的更改參數和回調。 e.g

$(".selector").autocomplete({ 
    change: function(event, ui) {} 
}); 

JsFiddle sample

<label for="name-search">Search language:</label> 
<input type="text" id="name-search" data-bind="value: langName, 
ko_autocomplete: { change: handleChange, source: getLangs(), select: addLang }" /> 
<div style="margin-top:1em">The observable array contains the following elements: 
    <ul data-bind="foreach: selectedLangs"> 
     <li data-bind="text: $data" /> 
    </ul> 
</div> 
<div id="pickedval">test</div> 
<input type="text" value="for using tab"> 

ko.bindingHandlers.ko_autocomplete = { 
    init: function (element, params) { 
     $(element).autocomplete(params()); 
    }, 
    update: function (element, params) { 
     $(element).autocomplete("option", "source", params().source); 
    } 
     }; 
$(document).ready(
function() { 

    var availableTags = [{ 
     label: "ActionScript", 
     value: 1 
    }, { 
     label: "AppleScript", 
     value: 2 
    }, { 
     label: "Asp", 
     value: 3 
    }, { 
     label: "BASIC", 
     value: 4 
    }, { 
     label: "C", 
     value: 5 
    }, { 
     label: "C++", 
     value: 6 
    }, { 
     label: "Clojure", 
     value: 7 
    }, { 
     label: "COBOL", 
     value: 8 
    }, { 
     label: "ColdFusion", 
     value: 9 
    }, { 
     label: "Erlang", 
     value: 10 
    }, { 
     label: "Fortran", 
     value: 11 
    }, { 
     label: "Groovy", 
     value: 12 
    }, { 
     label: "Haskell", 
     value: 13 
    }, { 
     label: "Java", 
     value: 14 
    }, { 
     label: "JavaScript", 
     value: 15 
    }, { 
     label: "Lisp", 
     value: 16 
    }, { 
     label: "Perl", 
     value: 17 
    }, { 
     label: "PHP", 
     value: 18 
    }, { 
     label: "Python", 
     value: 19 
    }, { 
     label: "Ruby", 
     value: 20 
    }, { 
     label: "Scala", 
     value: 21 
    }, { 
     label: "Scheme", 
     value: 22 
    }]; 

    // knockout view model      
    var ViewModel = function() { 

     var self = this; 

     self.langName = ko.observable(); 
     self.selectedLangs = ko.observableArray(); 

     self.handleChange = function() { 
      alert("change event fired"); 
      return true; 
     } 
     // return some programming languages 
     self.getLangs = function() { 
      return availableTags; 
     } 

     // user clicked on a auto complete item 
     self.addLang = function (event, ui) { 

      $(event.target).val(""); 
      self.handleChange(event); 
      var lang = ui.item.label; 
      var id = ui.item.value; 

      self.selectedLangs.push("id: " + id + ", Language: " + lang); 

      return false; 
     } 

     return { 
      getLangs: self.getLangs, 
      addLang: self.addLang, 
      langName: self.langName, 
      handleChange: self.handleChange, 
      selectedLangs: self.selectedLangs 
     } 
    }; 

    //bind knockout model 
    ko.applyBindings(new ViewModel()); 

}); 
+0

我能做到嗎?即使自動完成是綁定?我的意思是數據綁定=「自動完成:等等」 – Ano