2012-10-17 32 views
10

मैं नॉकआउट बाउंड इनपुट में jQuery UI Spinner विजेट का उपयोग कैसे कर सकता हूं?jQueryUI स्पिनर विजेट नॉकआउट

ko.bindingHandlers.spinner = { 
    init: function(element, valueAccessor, allBindingsAccessor) { 
     //initialize spinner with some optional options 
     var options = allBindingsAccessor().spinnerOptions || {}; 
     $(element).spinner(options); 

     //handle the field changing 
     ko.utils.registerEventHandler(element, "spinchange", function() { 
      var observable = valueAccessor(); 
      observable($(element).spinner("value")); 
     }); 

     //handle disposal (if KO removes by the template binding) 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).spinner("destroy"); 
     }); 

    }, 
    update: function(element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()), 
      current = $(element).spinner("value"); 

     if (value !== current) { 
      $(element).spinner("value", value); 
     } 
    } 
}; 

और फिर बस value के बजाय इसका उपयोग बाध्यकारी:

<input 
    type="number" 
    style="width: 100px;" 
    data-bind="spinner: Price, spinnerOptions: { min: 0 } " /> 

यहाँ बेला काम कर रहा है

<tbody data-bind="foreach: orders"> 
     <tr> 
      <td data-bind="text: Name"></td> 
      <td><input type="number" style="width: 100px;" data-bind="value: Price" /></td> 
      <td><input type="number" style="width: 50px;" data-bind="value: VAT" /></td> 
      <td><input type="number" style="width: 50px;" data-bind="value: Number" /></td> 
      <td data-bind="text: Final()"></td> 
      <td><a href="javascript:void(0);" data-bind="click: $root.removeOrder">Remove</a></td> 
     </tr>  
    </tbody> 
+0

आप किस क्षेत्र में स्पिनर को लागू करना चाहते हैं? –

उत्तर

19

सबसे अच्छा तरीका है custom binding बनाने के लिए इनपुट करने के लिए बाध्य करने के लिए spinner है: http://jsfiddle.net/vyshniakov/SwKGb/

+0

वाह। बहुत बहुत धन्यवाद –

+0

@Artem - महान कोड! W/प्रत्येक क्लिक को आग लगाने के लिए कोई तरीका? फोकस छोड़ने पर नहीं? – ajwaka

+2

@Artem - "part" पाया - "spinchange" को "spinstop" में बदलें - बस क्रोम – ajwaka

0

@Artem Vyshni अकोव का जवाब सही है। हालांकि, अगर आप एक IE polyfill के लिए के बजाय देख ब्राउज़रों इसका समर्थन में एचटीएमएल 5 नंबर इनपुट की जगह कर रहे हैं, इस प्रयास करें:

ko.bindingHandlers.spinner = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     if (Modernizr.inputtypes.number) { 
      ko.bindingHandlers.value.init.apply(null, arguments); 
     } else { 
      //initialize spinner with some optional options 
      var options = allBindingsAccessor().spinnerOptions || {}; 
      $(element).spinner(options); 

      //handle the field changing 
      $(element).on("spinstop", function() { 
       var observable = valueAccessor(); 
       observable($(element).spinner("value")); 
      }); 

      //handle disposal 
      ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
       $(element).off("spinstop"); 
       $(element).spinner("destroy"); 
      }); 
     } 

    }, 
    update: function (element, valueAccessor, allBindingsAccessor) { 
     if (Modernizr.inputtypes.number) { 
      ko.bindingHandlers.value.update.apply(null, arguments); 
     } else { 
      var value = ko.utils.unwrapObservable(valueAccessor()); 

      var disable = allBindingsAccessor().disable; 

      if (typeof disable !== "undefined") { 
       $(element).spinner((disable) ? "disable" : "enable"); 
      } 

      var current = $(element).spinner("value"); 
      if (value !== current) { 
       $(element).spinner("value", value); 
      } 
     } 
    } 
}; 

function Order(name, price, vat, number) { 
    var self = this; 

    self.Name = ko.observable(name); 
    self.Price = ko.observable(price); 
    self.VAT = ko.observable(vat); 
    self.Number = ko.observable(number); 

    self.Final = ko.computed(function() { 
     return (self.Price() + self.VAT()) * self.Number(); 
    }); 
} 

function ViewModel() { 
    var self = this; 

    self.orders = ko.observableArray(); 

    self.removeOrder = function(item) { 
     self.orders.remove(item); 
    }; 

    self.save = function() { 
     alert(ko.toJSON(self)); 
    }; 
} 

var viewModel = new ViewModel(); 
viewModel.orders.push(new Order("Sugar", 100, 15, 3)); 
viewModel.orders.push(new Order("Salt", 200, 25, 4)); 
viewModel.orders.push(new Order("Milk", 200, 35, 1)); 

ko.applyBindings(viewModel); 

पूरा यहाँ फिडल: http://jsfiddle.net/mberkom/pCJWc/

2

इस पृष्ठ पर उत्तर सही हैं और सहायक। हालांकि, मैंने पाया कि जब कोई क्षेत्र में कोई मूल्य टाइप कर रहा था तो मुझे बुरा व्यवहार हो रहा था। प्रत्येक कुंजी प्रेस एक "spinstop" घटना भी आग लगती है। इसके अलावा, कीप्रेस फ़ील्ड स्वरूपण और विकल्प को छोड़कर थे। चरण। सौभाग्य से हम आने वाली घटना की जांच कर सकते हैं कि वास्तव में क्या हो रहा है। बेहतर तरीके हो सकते हैं लेकिन मैंने सोचा कि मैं वैसे भी साझा करूंगा।

// Abstract to a function to allow for multiple binding types 
function createSpinner(defaultOptions) { 
    return { 
     init: function (element, valueAccessor, allBindingsAccessor) { 
      var options = $.extend(true, {}, allBindingsAccessor().spinnerOptions, defaultOptions); 
      var widget = $(element); 
      var observable = valueAccessor(); 

      widget.spinner(options); 

      // handle field changes onblur [copies field -> model] 
      ko.utils.registerEventHandler(element, "blur", function (event) { 
       var inputValue = Number(widget.spinner("value")); 
       var modelValue = observable(); 
       if (inputValue !== modelValue) { 
        // Set the widget (this forces formatting and rounding) - does not fire events 
        widget.spinner("value", inputValue); 
        // Read the value back out (saves us rounding) 
        var numberValue = Number(widget.spinner("value")); 
        // Set the observable 
        observable(numberValue); 
       } 
      }); 

      // handle other field changes 
      ko.utils.registerEventHandler(element, "spinstop", function (event) { 
       // jQuery.spinner spinstop is a bit overzealous with its spinstop event. 
       if (event.keyCode !== undefined) { 
        // If it has a keyCode someone is typing... so don't interfere 
       } else if (event.originalEvent && event.originalEvent.type === "mouseup") { 
        // This is an *actual* spinstop 
        var numberValue = Number(widget.spinner("value")); 
        observable(numberValue); 
       } 
      }); 

      // handle disposal 
      ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
       widget.spinner("destroy"); 
      }); 
     }, 
     update: function (element, valueAccessor) { 
      // [copies model -> field] 
      var widget = $(element); 
      var observable = valueAccessor(); 
      var inputValue = Number(widget.spinner("value")); 
      var modelValue = observable(); 
      if (inputValue !== modelValue) { 
       widget.spinner("value", modelValue); 
      } 
     } 
    }; 
} 
ko.bindingHandlers.moneyspin = createSpinner({ numberFormat: 'C0', culture: 'en-GB', min: 0, incremental: true }); 
ko.bindingHandlers.intspin = createSpinner({ numberFormat: 'n0', culture: 'en-GB' });