web-dev-qa-db-ja.com

入力フォーカスでテキストを選択

テキスト入力があります。入力がフォーカスを受け取ったら、入力内のテキストを選択します。

JQueryを使用すると、次のようになります。

<input type="text" value="test" />
$("input[type=text]").click(function() {
    $(this).select();
    // would select "test" in this example
});

Angularの方法を探して見つけるために周りを検索しましたが、私が見つけているほとんどの例は、変更のためにモーダルプロパティを監視しているディレクティブを扱っています。フォーカスを受け取る入力を監視するディレクティブが必要だと仮定しています。どうすればいいですか?

118
Billy Coover

Angularでこれを行う方法は、自動選択を行うカスタムディレクティブを作成することです。

module.directive('selectOnClick', ['$window', function ($window) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function () {
                if (!$window.getSelection().toString()) {
                    // Required for mobile Safari
                    this.setSelectionRange(0, this.value.length)
                }
            });
        }
    };
}]);

次のようなディレクティブを適用します。

<input type="text" value="test" select-on-click />

View demo

Update1:jQuery依存関係を削除しました。

Update2:属性として制限します。

Update3:モバイルSafariで動作します。テキストの一部を選択できます(IE> 8が必要です)。

211
Martin

ユーザーがクリックして入力ボックスにカーソルを置いたときにテキストを再選択しないようにする拡張ディレクティブを次に示します。

module.directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element) {
            var focusedElement;
            element.on('click', function () {
                if (focusedElement != this) {
                    this.select();
                    focusedElement = this;
                }
            });
            element.on('blur', function () {
                focusedElement = null;
            });
        }
    };
})
43
Tamlyn

これは古い答えです。Angular 1.x

より良い方法は、ng-click組み込みディレクティブを使用することです。

<input type="text" ng-model="content" ng-click="$event.target.select()" />

編集:

JoshMB が親切に思い出させてくれた。 Angular 1.2+でDOMノードを参照することは許可されなくなりました。そこで、$event.target.select()をコントローラーに移動しました。

<input type="text" ng-model="content" ng-click="onTextClick($event)" />

次に、コントローラーで:

$scope.onTextClick = function ($event) {
    $event.target.select();
};

fiddle の例です。

39

提案された解決策のどちらも私にはうまくいきませんでした。簡単な調査の後、私はこれを思いつきました:

module.directive('selectOnFocus', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var focusedElement = null;

            element.on('focus', function () {
                var self = this;
                if (focusedElement != self) {
                    focusedElement = self;
                    $timeout(function () {
                        self.select();
                    }, 10);
                }
            });

            element.on('blur', function () {
                focusedElement = null;
            });
    }

  }

});

提案されたいくつかのソリューションの組み合わせですが、クリックとフォーカスの両方で機能し(オートフォーカスを考えてください)、入力の部分的な値を手動で選択できます。

15
xaralis

私にとって、ng-clickには意味がありませんでした。すべてのテキストを再度選択しないとカーソルの位置を変えることができなかったからです。入力がフォーカスされていない場合にのみテキストが選択されるので、ng-focusを使用することをお勧めします。もう一度クリックしてカーソルの位置を変更すると、テキストは選択解除されるだけで、その間で書き込むことができます。

私はこのアプローチが期待されるUXの振る舞いであると思いました。

ng-focus を使用します

オプション1:別のコード

<input type="text" ng-model="content" ng-focus="onTextFocus($event)" />

そしてコントローラーで

$scope.onTextFocus = function ($event) {
  $event.target.select();
};

オプション2:代替として、上記のコードをこの「ワンライナー」に結合できます(これはテストしませんでしたが、動作するはずです)

<input type="text" ng-model="content" ng-focus="$event.target.select()" />
12
jperelli

angular 2では、これはChromeとFirefoxの両方で機能しました:

<input type="text" (mouseup)="$event.target.select()">
6
guenam

受け入れられた答えはクリックイベントを使用していますが、フォーカスイベントを使用する場合、最初のクリックのみがイベントを発生させ、入力にフォーカスするために他のメソッドが使用されたときにも発生します(タブを押す、コードでフォーカスを呼び出すなど)。

また、タムリンの答えが示唆するように、要素がすでにフォーカスされているかどうかを確認する必要もありません。

app.directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('focus', function () {
                this.select();
            });
        }
    };
});
6
OrangeKing89

ディレクティブは必要ありません。入力要素またはテキスト領域にonfocus="this.select()"ネイティブJavaScriptを追加するだけです。

2
Adam Reis

私のために働いた修正版。最初のクリックでテキストが選択され、同じ要素で2回目のクリックでテキストの選択が解除される

module.directive('selectOnClick', function ($timeout) {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var prevClickElem = null; //Last clicked element
        var ignorePrevNullOnBlur = false; //Ignoring the prevClickElem = null in Blur massege function

        element.on('click', function () {
            var self = this;
            if (prevClickElem != self) { //First click on new element
                prevClickElem = self; 
                $timeout(function () { //Timer
                    if(self.type == "number")
                        self.select();
                    else
                        self.setSelectionRange(0, self.value.length)
                }, 10);
            }
            else { //Second click on same element
                if (self.type == "number") {
                    ignorePrevNullOnBlur = true;
                    self.blur();
                }
                else
                    self.setSelectionRange(self.value.length, self.value.length); //deselect and set cursor on last pos
            }
        });

        element.on('blur', function () {
            if (ignorePrevNullOnBlur == true)
                ignorePrevNullOnBlur = false; //blur called from code handeling the second click 
            else
                prevClickElem = null; //We are leaving input box
        });
    }
}

})

0
Ola