4

I have an input text box on my page and I need to have the width of this input box adjusted to his content. So for example: if there are only 2 characters inside of it then my input box should be smaller than if I have 10 characters in it.

I am able to do it with jQuery but this time I really wonder myself if this can be done with knockout?

Here is a jsFiddle as a starting point: http://jsfiddle.net/LkqTU/13554/

As you can see in this jsFiddle, the input text box for the content 'abc' is too much bigger... And when you click the button, then the input text box is too much smaller.

So what i need is a 'mechanism' where the box is automatically adjusted based on his content.

<input type="text" data-bind="value: myField">

<input type="button" value="Click me" data-bind="click: buttonClicked">

var ViewModel = function() {

    this.myField = ko.observable('abc');

    this.buttonClicked = function() {
        this.myField('azertyuiolkjhgfdsseryuujnbvcxsssx');
    }

};

ko.applyBindings(new ViewModel());

Thanks.

Bronzato
  • 9,438
  • 29
  • 120
  • 212

1 Answers1

2

Based on this answer I made a simple custom binding that you can use as follow :

Default options :

<input type="text" data-bind="value: myField, autoGrowInput: true">

With custom settings

<input type="text" data-bind="value: myField,
 autoGrowInput: {comfortZone :10, maxWidth:500, minWidth : 100}">

The custom binding :

ko.bindingHandlers.autoGrowInput = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
       var value = valueAccessor();
       var valueUnwrapped = ko.unwrap(value);
       if(valueUnwrapped === true) {
         // use default options
          $(element).autoGrowInput();
       }
       else if(valueUnwrapped === false) {
          // does nothing
          return;
       }
       else {
          // use custom options
          $(element).autoGrowInput(valueUnwrapped);
       }
        // looking for the value binding
        var ab = allBindings();
        if (ab['value']) {
            ab.value.subscribe(function () {
            $(element).trigger('update');
            });
        }

    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {

    }
};

See demo

Community
  • 1
  • 1
Damien
  • 8,889
  • 3
  • 32
  • 40
  • Waouw absolutely fabulous. Just one remark: when I click on the button to inject some text, the input boxes are not adjusted. I need to focus on it to proceed. Is there a way to adjust it automatically? – Bronzato Dec 19 '13 at 14:33
  • Looks pretty good, one minor comment is that you can just omit the `update` property -- you don't need a noop implementation. – ach Dec 19 '13 at 16:39
  • Yes that's a finy solution. I think I am fighting with is ti have a solution where the input text size is adjusted at the beginning (on page load). Any idea? – Bronzato Dec 19 '13 at 16:59
  • @Bronzato Yes, just set the minWidth to 1 :) – Damien Dec 19 '13 at 17:51
  • Thank you very much. I cannot use your solution as is because of my specific framework (Durandal) but this is very helpful. – Bronzato Dec 19 '13 at 18:22