1

typehead (twitter ブートストラップ) でオートコンプリート入力フィールドを実現しようとしています。このオートコンプリート フィールドはモーダルにする必要がありますが、機能していないようです! また、値を選択すると他のフィールドが更新される必要があるため、ノックアウトで観察可能でなければなりません。

だから私はモーダルでこれをやろうと思っています!

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/
        *//*
    });

    */

誰かがこれを行う方法について私を助けてくれることを願っています! ソースは修復ラインです。これらはすべて正しく入力されています

4

4 に答える 4

2

ビューモデルで公開されている配列に先行入力をバインドする必要があります。現時点ではどちらも行っていないと思います。

バインディングを行うには、http: //billpull.github.io/knockout-bootstrap/にあるノックアウト ブートストラップ バインディングを使用する必要があります。

上記のノックアウト ブートストラップ バインディングを含めたら、ビューでこれを行うことができます。

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

次に、VM インスタンスに修復ラインを追加していることを確認します。this 参照に追加すると、うまくいくはずです。

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

これがお役に立てば幸いです:-)

于 2013-04-24T17:32:40.603 に答える
0

私はコメントしますが、できません。ここに私のメモがあります。あなたの例では、同じオリジン ポリシー (SOP) の問題があります。そのため、Twitter ページからのデータは取り込まれません。これにより、プロセスがほぼ停止するため、最終的には何も得られません。

適切なスタイル (tt-dropdown-menu のスタイルなど) を含めると、次のことがわかりました。

<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/)。

于 2013-04-24T17:29:43.950 に答える
0

ライブラリに追加のコードを追加して、この問題を修正しました: https://github.com/billpull/knockout-bootstrap

これはノックアウト-bootstrap.js で、ko.bindingHandlers.typeahead が書き直され、更新、minLength、アイテムを受け入れるようになっています。このスクリプトをロードするだけです。

//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;
});

人々がこれを理解してくれることを願っています;)、それが役立つことを願っています.Bill Pull ;)とAlex Prestonに多くのクレジットが送られます.

于 2013-05-03T08:58:36.093 に答える