Выберите текст в фокусе ввода

У меня есть текстовый ввод. Когда вход принимает фокус, я хочу выбрать текст внутри входа.

С jQuery я бы сделал это следующим образом:

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

Я искал, чтобы найти способ Angular, но большинство примеров, которые я нахожу, имеют дело с директивой, которая просматривает модальное свойство для изменения. Я предполагаю, что мне нужна директива, которая следит за входом, который получает фокус. Как мне это сделать?

Ответ 1

Способ сделать это в 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 />

Просмотреть демо

Update1: удалена зависимость jQuery.

Update2: Ограничить как атрибут.

Update3: работает в мобильном Safari. Позволяет выбрать часть текста (требуется IE > 8).

Ответ 2

Здесь расширенная директива, которая позволяет избежать повторного выбора текста, когда пользователь нажимает, чтобы поместить курсор в поле ввода.

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

Ответ 3

Это старый ответ, для Angular 1.x

Лучший способ сделать это - использовать встроенную директиву ng-click:

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

EDIT:

Как JoshMB любезно напомнил; ссылка на узлы DOM в Angular 1.2+ больше не разрешена. Итак, я переместил $event.target.select() в контроллер:

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

Затем в вашем контроллере:

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

Вот пример скрипта.

Ответ 4

Ни один из предлагаемых решений не работал хорошо для меня. После быстрых исследований я придумал следующее:

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

  }

});

Это сочетание нескольких предложенных решений, но работает как по щелчку, так и по фокусу (думаю, автофокус) и позволяет вручную выбирать частичное значение на входе.

Ответ 5

Для меня ng-click не имеет смысла, потому что вы никогда не сможете переместить курсор, не выбирая весь текст снова, я обнаружил, что это было annoing. Тогда лучше использовать 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()" />

Ответ 6

Принятый ответ использует событие щелчка, однако, если вы используете событие фокуса, только первый щелчок загорится, и он также срабатывает, когда какой-либо другой метод используется для фокусировки на входе (например, вкладка "Включение" или "Начать фокус" код).

Это также не требует проверки того, что элемент уже сфокусирован, как предполагает ответ Tamlyn.

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

Ответ 7

В angular 2 это работало для меня, как в Chrome, так и в Firefox:

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

Ответ 8

Модифицированная версия, которая работала для меня. Первый щелчок выбирает текст, второй щелчок на том же элементе отменяет выделение текста

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

})