18327


はじめまして。タイトルの通りです。AngularJSをつかって横方向に自動リサイズするinputのdirectiveをつくっています。以前こちらで質問させて頂いたときに教えて頂いたコードを参考に以下のように実装しているのですが、何点か思うようにいかないとろこがあり、再び相談させて頂いております。テキストを入力すると入力に応じてinputタグのwidthを変更していくものを想定しています。

困っているところとしましては、  
・ページ読み込み時に自動でリサイズされない（minWidthの値が適応され端が切れてしまう）  
・文字の幅をcharWidthで指定しているので、日本語と英語、さらには「a」と「i」でも文字の幅が異なるので若干幅がずれる

ということが起こっています。初歩的なところで詰まっているのはわかっているのですが自力では解決できなさそうだったので質問させていただきました。読みにくいコードかもしれませんがどうかよろしくお願いいたします。

[code]

    angular.module('myInput', []).directive 'myInput', ->
      {
        restrict: 'A'
        require: '?ngModel'
        link: (scope, elem, attrs, ngModel) ->
    
          calculateWidth = (length) ->
            minWidth = 30
            maxWidth = 730
            charWidth = 12
            width = length * charWidth
            if width > maxWidth then maxWidth else if width < minWidth then minWidth else width
    
          resize = (e) ->
            elem.css 'width', calculateWidth(newVal.length)
            elem.css 'height', '30px'
            return
    
          elem.on 'keypress', (e) ->
            if e.keyCode == 13
              elem.blur()
              return
    
          scope.$watch (->
            ngModel.$modelValue
          ), (newVal, oldVal) ->
            if angular.isDefined(newVal)
              elem.css 'width', calculateWidth(newVal.length)
              elem.css 'height', '30px'
            return
          return
      }
    
[/code]


CC BY-SA 3.0
2015-11-02T05:58:39.717
18316
2015-11-02T12:07:02.377
10441
question
javascript angularjs coffeescript
横方向に自動リサイズするinputのdirectiveの続き


以前の質問というのはこれですね。  
[横方向に自動リサイズするinputのdirectiveをつくりたい](https://ja.stackoverflow.com/questions/12520/%E6%A8%AA%E6%96%B9%E5%90%91%E3%81%AB%E8%87%AA%E5%8B%95%E3%83%AA%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%99%E3%82%8Binput%E3%81%AEdirective%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8A%E3%81%9F%E3%81%84)

こんな感じでどうでしょうか。  
<https://jsfiddle.net/4uktpu22/>

html

[code]

    <div ng-app="app" ng-controller="AppController as app">
        <resize-input text="app.text"></resize-input>
    </div>
    
[/code]

css

[code]

    .resize-input{
      font-family: 'メイリオ';
      font-size: 16px;
    }
    .resize-text{
      visibility: hidden;
      white-space:nowrap;
    }
    
[/code]

js

[code]

    angular.module('app', [])
    .controller('AppController', function(){
        this.text = 'hogehoge';
    })
    .directive('resizeInput', function(){
    
        function calculateWidth(stringWidth){
            var minWidth = 50;
            var padding = 10;
            return stringWidth + padding < minWidth? minWidth: stringWidth + padding;
        }
    
        return {
            restrict: 'E',
            scope: {
                text: '='
            },
            template: '<input type="text" ng-model="text" class="resize-input"><br><span class="resize-input resize-text">{{text}}</span>',
            link: function(scope, elem, attrs){
                scope.$watch('text', function(newVal, oldVal){
                    if(angular.isDefined(newVal)){
                        var width = elem.find('span')[0].offsetWidth;
                        console.log(width);
                        elem.find('input').css('width', calculateWidth(width));
                    }
                });
            }
        };
    });
    
[/code]

  1. `<input>`の下隣に`<span>`を置いて、`font-size`及び`font-family`を揃える
  2. `<span>`は`visibility: hidden`で隠す
  3. `<input>`への入力と`<span>`のテキストを同期させて`<span>`の横幅を`<input>`に反映する


CC BY-SA 3.0
2015-11-02T12:07:02.377
18327
2015-11-02T12:07:02.377
2017-04-13T12:52:38.920
-1
8532
18316
answer