2013-04-24 83 views
1

我试图用typeahead(twitter bootstrap)实现一个自动填充的输入字段。这个自动填充字段应该是一个模式,但我似乎无法让它工作!它也必须是可观察的,因为当你选择一个值时,其他字段应该被更新。在Durandal框架中使用Typeahead创建一个自动填充字段

所以我有点想在模态中做到这一点!

HTML

<div class="messageBox"> 
    <div class="modal-header"> 
     <h2>Adding a repairline</h2> 
    </div> 
    <div class="modal-body" style="width: 35em;"> 
     <form data-bind="submit: ok"> 
      <fieldset> 
       <!--<legend></legend> Deze niet toevoegen uitlijning is dan niet goed!--> 
       <div class="row-fluid"> 
        <div class="span6"> 
         <div> 
          <label> 
           Description: 
           <input type="text" id="testen" data-provide="typeahead" /> 



          </label> 
         </div> 
         <div> 
          <label> 
           Code: 
           <input data-bind="value: Code" required /> 
          </label> 
         </div>   
       <div> 
        <input class="btn btn-primary" type="submit" value="Add" /> 
       </div> 
      </fieldset> 
     </form> 
    </div> 
    <div class="modal-footer"> 
     <button class="btn" data-bind="click: closeModal">Cancel</button>  
    </div> 
</div> 

JS

define(function (require) { 
    var dataservice = require('services/dataservice'), 
     allCustomers = ko.observableArray([]), 
     repairlines = ko.observableArray([]); 


    function init() { 
     dataservice = new dataservice('api/data'); 
     dataservice.getAllRows('AllCustomers').then(function (data) { 
      data.results.forEach(function (item) { 
       allCustomers.push(item); 
      }); 
     }).fail(function() { 
     }); 

     dataservice.getAllRows('EntireRepairLineLib').then(function (data) { 
      data.results.forEach(function (item) { 
       repairlines.push(item); 
      }); 
     }).fail(function() { 
     }); 

     $('.testen .typeahead').typeahead({ 
      name: 'countries', 
      prefetch: 'http://twitter.github.io/typeahead.js/data/countries.json', 
      limit: 10 
     }); 
    } 

    init(); 

    AddRepairOrderLineModal = function (loggedInEmployee) { 
     //later ook customer en repairorder meegeven! 
     this.allCustomers = allCustomers; 
     this.choosenCustomerId = ko.observable(); //holds the Id of the chosen customer 
     this.Description = ko.observable(); 
     this.Code = ko.observable(); 
     this.Mat = ko.observable(); 
     this.Location = ko.observable(); 
     this.Rep = ko.observable(); 
     this.Dum = ko.observable(); 
     this.Dam = ko.observable(); 
     this.Qty = ko.observable(); 
     this.Hours = ko.observable(); 
     this.Tariff = ko.observable(); 
     this.Costs = ko.observable(); 
     this.CreationDate = (new Date().getMonth() + 1) + "-" + new Date().getDate() + "-" + new Date().getFullYear(); 

     this.IsAgreement = ko.observable(true); 
     this.IsAuthorized = ko.observable(true); 
     this.DoRepair = ko.observable(true); 
     this.selectedEmployee = loggedInEmployee; 

     /* $(".repairlinename").autocomplete({ 
      source: repairlines 
     });*/ 


     $(document).ready(function() { 
      alert('done'); 
      $('#testen').append(' Leroy'); 
     }); 
    }; 
    AddRepairOrderLineModal.prototype.ok = function() { 
     var jsonObj = []; 
     jsonObj.push({ 
      Description: this.Description(), Code: this.Code(), 
      Mat: this.Mat(), Location: this.Location(), 
      Rep: this.Rep(), Dum: this.Dum(), Dam: this.Dam(), 
      CustomerId: this.choosenCustomerId(), Qty: this.Qty(), Hours: this.Hours(), 
      Tariff: this.Tariff(), Costs: this.Costs(), CreationDate: this.CreationDate, 
      IsAgreement: this.IsAgreement(), IsAuthorized: this.IsAuthorized(), DoRepair: this.DoRepair(), 
     }); 
     this.modal.close(jsonObj); 
    }; 

    AddRepairOrderLineModal.prototype.closeModal = function() { 
     return this.modal.close(); 
    }; 
    return AddRepairOrderLineModal; 
}); 



    /*define(['durandal/app','services/dataservice'], function(app,dataservice) { 
     AddRepairOrderLineModal = function (loggedInEmployee) { 
      //later ook customer en repairorder meegeven! 




      this.Description = ko.observable(); 
      this.Code = ko.observable(); 
      this.Mat = ko.observable(); 
      this.Location = ko.observable(); 
      this.Rep = ko.observable(); 
      this.Dum = ko.observable(); 
      this.Dam = ko.observable(); 
      this.Customer = ko.observable(); 
      this.Qty = ko.observable(); 
      this.Hours = ko.observable(); 
      this.Tariff = ko.observable(); 
      this.Costs = ko.observable(); 
      this.CreationDate = (new Date().getMonth() + 1) + "-" + new Date().getDate() + "-" + new Date().getFullYear(); 

      this.IsAgreement = ko.observable(true); 
      this.IsAuthorized = ko.observable(true); 
      this.DoRepair = ko.observable(true); 
      this.selectedEmployee = loggedInEmployee; 
     }; 

     AddRepairOrderLineModal.prototype.ok = function() { 
      var jsonObj = []; 
      jsonObj.push({ 
       Description: this.Description(), Code: this.Code(), 
       Mat: this.Mat(), Location: this.Location(), 
       Rep: this.Rep(), Dum: this.Dum(), Dam: this.Dam(), 
       Customer: this.Customer(), Qty: this.Qty(), Hours: this.Hours(), 
       Tariff: this.Tariff(), Costs: this.Costs(), CreationDate: this.CreationDate, 
       IsAgreement: this.IsAgreement(), IsAuthorized: this.IsAuthorized(), DoRepair: this.DoRepair() 
      }); 
      this.modal.close(jsonObj); 
     }; 

     AddRepairOrderLineModal.prototype.closeModal = function() { 
      return this.modal.close(); 
     }; 
     return AddRepairOrderLineModal; 
     /* 
     http://stackoverflow.com/questions/7537002/autocomplete-combobox-with-knockout-js-template-jquery 
     http://jsfiddle.net/rniemeyer/PPsRC/ 
     *//* 
    }); 

    */ 

我希望有人能帮助我如何做到这一点!源是修复线,这些都是正确填写

回答

2

您需要将typeahead输入绑定到视图模型中暴露的数组。我不认为你现在在做什么。

去做你应该使用这里发现敲除引导绑定绑定: http://billpull.github.io/knockout-bootstrap/

一旦你已经包括在上述淘汰赛的自举绑定您可以在您的视图做到这一点:

<input type="text" data-bind="typeahead: repairlines" /> 

然后确保你正在向VM实例添加修补程序。把它添加到你的这个参考应该可以做到。

// this will add the repairlines observable array to your VM instance 
this.repairlines = repairlines; 

希望这有助于和好运:-)

+0

我的第一个想法是,这将做的伎俩,但它不:(我相信它与Durandal框架中的模态生命周期有关! – 2013-04-25 07:37:38

+0

对不起,没有阅读你的答案右XD,问题是我没有在我的项目中包含Knockout-bootstrap javascript :)现在一切都正常:) – 2013-04-25 07:51:17

+0

我确实有另外一件事,修复线是al对象,我该怎么做? – 2013-04-25 08:44:47

0

我会评论,但不能这样,我的笔记。在你的例子中,你有一个相同的原产地政策(SOP)问题。所以Twitter页面的数据没有被吸引。这几乎杀死了这个过程,所以你不会得到任何东西。

我发现,如果我有适当的样式(如一个TT-下拉菜单):

<span class="tt-dropdown-menu" style="position: absolute; top: 100%; left: 0px; z-index: 100; display: block; right: auto;"></span> 

,并有一个正常运作的数据集,它工作正常。这里是我尝试http://jsfiddle.net/rUdXt/的小提琴,这里有一个很棒的页面帮助了我(尤其是风格http://twitter.github.io/typeahead.js/examples/)。

+0

感谢小提琴和例子,但它也不会做的伎俩;(如果是它会正常的页面,但在我的模式,它只是没有按” t工作 – 2013-04-25 07:38:27

0

我已经通过添加一些额外的代码库解决了这个问题:https://github.com/billpull/knockout-bootstrap

这是淘汰赛,bootstrap.js,其中KO .bindingHandlers.typeahead被重写,因此它接受更新,minLength en项目。只需加载此脚本。

//UUID 
function s4() { 
    return Math.floor((1 + Math.random()) * 0x10000) 
     .toString(16) 
     .substring(1); 
} 

function guid() { 
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); 
} 

// Outer HTML 
(function($){ 
    $.fn.outerHtml = function() { 
    if (this.length == 0) return false; 
    var elem = this[0], name = elem.tagName.toLowerCase(); 
    if (elem.outerHTML) return elem.outerHTML; 
    var attrs = $.map(elem.attributes, function(i) { return i.name+'="'+i.value+'"'; }); 
    return "<"+name+(attrs.length > 0 ? " "+attrs.join(" ") : "")+">"+elem.innerHTML+"</"+name+">"; 
    }; 
})(jQuery); 

// Bind twitter typeahead 
ko.bindingHandlers.typeahead = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var $element = $(element); 
     var allBindings = allBindingsAccessor(); 
     var typeaheadArr = ko.utils.unwrapObservable(valueAccessor()); 

     $element.attr("autocomplete", "off") 
       .typeahead({ 
        'source': typeaheadArr, 
        'minLength': allBindings.minLength, 
        'items': allBindings.items, 
        'updater': allBindings.updater 
       }); 
    } 
}; 

/* 
ko.bindingHandlers.typeahead = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 


     var $element = $(element); 
     var t = valueAccessor(); 
     var typeaheadArr = ko.utils.unwrapObservable(valueAccessor()); 
     var k = allBindingsAccessor().v1; 

     $element.attr("autocomplete", "off") 
       .typeahead({ 
        'source' : typeaheadArr 
       }); 
    } 
}; 
*/ 

// Bind Twitter Progress 
ko.bindingHandlers.progress = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var $element = $(element); 

     var bar = $('<div/>', { 
      'class':'bar', 
      'data-bind':'style: { width:' + valueAccessor() + ' }' 
     }); 

     $element.attr('id', guid()) 
      .addClass('progress progress-info') 
      .append(bar); 

     ko.applyBindingsToDescendants(viewModel, $element[0]); 
    } 
} 

// Bind Twitter Alert 
ko.bindingHandlers.alert = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var $element = $(element); 
     var alertInfo = ko.utils.unwrapObservable(valueAccessor()); 

     var dismissBtn = $('<button/>', { 
      'type':'button', 
      'class':'close', 
      'data-dismiss':'alert' 
     }).html('&times;'); 

     var alertMessage = $('<p/>').html(alertInfo.message); 

     $element.addClass('alert alert-'+alertInfo.priority) 
       .append(dismissBtn) 
       .append(alertMessage); 
    } 
}; 

// Bind Twitter Tooltip 
ko.bindingHandlers.tooltip = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     // read tooltip options 
     var tooltipBindingValues = ko.utils.unwrapObservable(valueAccessor()); 

     // set tooltip title 
     var tooltipTitle = tooltipBindingValues.title; 

     // set tooltip placement 
     var tooltipPlacement = tooltipBindingValues.placement; 

     // set tooltip trigger 
     var tooltipTrigger = tooltipBindingValues.trigger; 

     var options = { 
      title: tooltipTitle 
     }; 

     ko.utils.extend(options, ko.bindingHandlers.tooltip.options); 

     if (tooltipPlacement) { 
      options.placement = tooltipPlacement; 
     } 

     if (tooltipTrigger) { 
      options.trigger = tooltipTrigger; 
     } 

     $(element).tooltip(options); 
    }, 
    options: { 
     placement: "top", 
     trigger: "hover" 
    } 
}; 

// Bind Twitter Popover 
ko.bindingHandlers.popover = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     // read popover options 
     var popoverBindingValues = ko.utils.unwrapObservable(valueAccessor()); 

     // set popover title 
     var popoverTitle = popoverBindingValues.title; 

     // set popover template id 
     var tmplId = popoverBindingValues.template; 

     // set popover trigger 
     var trigger = 'click'; 

     if (popoverBindingValues.trigger) { 
      trigger = popoverBindingValues.trigger; 
     } 

     // update triggers 
     if (trigger === 'hover') { 
      trigger = 'mouseenter mouseleave'; 
     } else if (trigger === 'focus') { 
      trigger = 'focus blur'; 
     } 

     // set popover placement 
     var placement = popoverBindingValues.placement; 

     // get template html 
     var tmplHtml = $('#' + tmplId).html(); 

     // create unique identifier to bind to 
     var uuid = guid(); 
     var domId = "ko-bs-popover-" + uuid; 

     // create correct binding context 
     var childBindingContext = bindingContext.createChildContext(viewModel); 

     // create DOM object to use for popover content 
     var tmplDom = $('<div/>', { 
      "class" : "ko-popover", 
      "id" : domId 
     }).html(tmplHtml); 

     // set content options 
     options = { 
      content: $(tmplDom[0]).outerHtml(), 
      title: popoverTitle 
     }; 

     if (placement) { 
      options.placement = placement; 
     } 

     // Need to copy this, otherwise all the popups end up with the value of the last item 
     var popoverOptions = $.extend({}, ko.bindingHandlers.popover.options, options); 

     // bind popover to element click 
     $(element).bind(trigger, function() { 
      var popoverAction = 'show'; 
      var popoverTriggerEl = $(this); 

      // popovers that hover should be toggled on hover 
      // not stay there on mouseout 
      if (trigger !== 'click') { 
       popoverAction = 'toggle'; 
      } 

      // show/toggle popover 
      popoverTriggerEl.popover(popoverOptions).popover(popoverAction); 

      // hide other popovers and bind knockout to the popover elements 
      var popoverInnerEl = $('#' + domId); 
      $('.ko-popover').not(popoverInnerEl).parents('.popover').remove(); 

      // if the popover is visible bind the view model to our dom ID 
      if($('#' + domId).is(':visible')){ 
       ko.applyBindingsToDescendants(childBindingContext, $('#' + domId)[0]); 
      } 

      // bind close button to remove popover 
      $(document).on('click', '[data-dismiss="popover"]', function (e) { 
       popoverTriggerEl.popover('hide'); 
      }); 
     }); 

     // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice 
     return { controlsDescendantBindings: true }; 
    }, 
    options: { 
     placement: "right", 
     title: "", 
     html: true, 
     content: "", 
     trigger: "manual" 
    } 
}; 

在您的HTML中执行此操作。

<input type="text" data-bind="typeahead: repairlines(), minLength: 2, updater: updateViewAfterSelection, value: Description" required/> 

这是我的视图模型:

define(function (require) { 
    var dataservice = require('services/dataservice'), 
     allCustomers = ko.observableArray([]), 
     repairlinesRaw = ko.observableArray([]), 
     Description = ko.observable(), 
     InternalCode = ko.observable(), 
     Mat = ko.observable(), 
     Location = ko.observable(), 
     Rep = ko.observable(), 
     Dum = ko.observable(), 
     Dam = ko.observable(), 
     Qty = ko.observable(0).extend({ numeric: 2 }), 
     Hours = ko.observable(0).extend({ numeric: 2 }), 
     Tariff = ko.observable(0).extend({ numeric: 2 }), 
     Costs = ko.observable(0).extend({ numeric: 2 }); 

    function init() { 
     dataservice = new dataservice('api/data'); 
     dataservice.getAllRows('AllCustomers').then(function (data) { 
      data.results.forEach(function (item) { 
       allCustomers.push(item); 
      }); 
     }).fail(function() { 
     }); 

     dataservice.getAllRows('EntireRepairLineLib').then(function (data) { 
      data.results.forEach(function (item) { 
       repairlinesRaw.push(item); 
      }); 
     }).fail(function() { 
     }); 
    } 

    init(); 

    AddRepairOrderLineModal = function (loggedInEmployee) { 
     //later ook customer en repairorder meegeven! 
     this.allCustomers = allCustomers; 
     this.choosenCustomerId = ko.observable(); //holds the Id of the chosen customer 
     this.Description = Description; 
     this.InternalCode = InternalCode; 
     this.Mat = Mat; 
     this.Location = Location; 
     this.Rep = Rep; 
     this.Dam = Dam; 
     this.Qty = Qty; 
     this.Hours = Hours; 
     this.Tariff = Tariff; 
     this.Costs = Costs; 
     //this.CreationDate = (new Date().getMonth() + 1) + "-" + new Date().getDate() + "-" + new Date().getFullYear(); 
     this.repairlines = function() { 
      var repairlinesName = []; 
      map = {}; 
      var data = repairlinesRaw(); 
      $.each(data, function (i, repairline) { 
       map[repairline.Description()] = repairline; 
       repairlinesName.push(repairline.Description()); 
      }); 
      return repairlinesName; 
     }; 

     this.IsAgreement = ko.observable(true); 
     this.IsAuthorized = ko.observable(true); 
     this.DoRepair = ko.observable(true); 
     this.selectedEmployee = loggedInEmployee; 
    }; 

    AddRepairOrderLineModal.prototype.updateViewAfterSelection = function(item) { 
     //map can be found in the repairlines function 
     Description(map[item].Description()); 
     InternalCode(map[item].InternalCode()); 
     Mat(map[item].MaterialCode()); 
     Location(map[item].LocationCode()); 
     Rep(map[item].RepairCode()); 
     Dam(map[item].DamageCode()); 
     Qty(map[item].Quantity()); 
     Hours(map[item].Hours()); 
     Costs(map[item].Costs()); 
     return item; 
    }; 

    AddRepairOrderLineModal.prototype.ok = function() { 
     var jsonObj = []; 
     jsonObj.push({ 
      Description: this.Description(), InternalCode: this.InternalCode(), 
      Mat: this.Mat(), Location: this.Location(), 
      Rep: this.Rep(), Dam: this.Dam(), 
      CustomerId: this.choosenCustomerId(), Qty: this.Qty(), Hours: this.Hours(), 
      Tariff: this.Tariff(), Costs: this.Costs(), 
      IsAgreement: this.IsAgreement(), IsAuthorized: this.IsAuthorized(), DoRepair: this.DoRepair(), 
     }); 

     //empty all fields after JSON 
     //Otherwise the values would still be there when a new modal is opened again. 
     Description(null); 
     InternalCode(null); 
     Mat(null); 
     Location(null); 
     Rep(null); 
     Dum(null); 
     Dam(null); 
     Qty(0); 
     Hours(0); 
     Tariff(0); 
     Costs(0); 

     this.modal.close(jsonObj); 
    }; 

    AddRepairOrderLineModal.prototype.closeModal = function() { 
     return this.modal.close(); 
    }; 
    return AddRepairOrderLineModal; 
}); 

希望大家明白这一点;),希望有帮助,很多学分的去比尔拉)和亚历克斯·普雷斯顿

0

无法理解这样的因为它太杂乱。也就是说,typeahead位与所有其他内容混合在一起。 那么一个简单的例子,只有提前的东西,也许组成一个视图/ viewmodel像一个小部件,所以它可以被重用。

然后我们就可以有机会去了解它

相关问题