Pilih teks pada fokus masukan

121

Saya memiliki masukan teks. Saat masukan menerima fokus, saya ingin memilih teks di dalam masukan.

Dengan jQuery, saya akan melakukannya dengan cara ini:

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

Saya telah mencari-cari untuk mencoba dan menemukan cara Angular tetapi sebagian besar contoh yang saya temukan berhubungan dengan arahan yang memperhatikan properti modal untuk perubahan. Saya berasumsi saya membutuhkan arahan yang mengawasi input yang menerima fokus. Bagaimana saya melakukannya?

Billy Coover
sumber
Saya mengerti Anda ingin menemukan 'Angular way', namun adakah alasan Anda tidak melakukannya <input type="text" value="test" onclick="this.select()" />?
Josef P.

Jawaban:

216

Cara untuk melakukan ini di Angular adalah dengan membuat perintah kustom yang melakukan autoselect untuk Anda.

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

Terapkan arahan seperti ini:

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

View demo

Pembaruan1 : Menghapus ketergantungan jQuery.

Pembaruan2 : Batasi sebagai atribut.

Pembaruan3 : Bekerja di Safari seluler. Mengizinkan memilih bagian teks (memerlukan IE> 8).

Martin
sumber
10
Jika Anda ingin melakukan ini tanpa jquery, ubah element.click menjadi element.bind ('click', function () {...} dan element.select () menjadi element [0] .select ()
jack
3
Bagus dan elegan. Saya juga akan secara eksplisit membatasi direktif untuk diterapkan sebagai atribut (dengan mengembalikan literal dan pengaturan objek restrict: 'A'), karena arahan ini bertujuan untuk memperluas perilaku elemen yang ada .
Eliran Malka
@Martin tahu bagaimana melakukan itu pada halaman terbuka, tanpa klik pengguna? Masalahnya adalah bahwa nilai default disetel di pengontrol lain sebelum selectOnLoadtautan direktif saya (). Namun di link (), meskipun scope sudah terisi, elemen DOM belum disinkronkan dengan $ scope, jadi ketika saya memanggil select (), elemen masih kosong dan tidak ada yang dipilih. Satu-satunya cara untuk mengatasi yang saya temukan, adalah $ timeout, tetapi saya merasa itu dapat berhenti berfungsi dengan beberapa versi Angular baru.
Dzmitry Lazerka
ini berfungsi dengan baik di desktop / android tetapi ketika saya mencoba di ipad sepertinya tidak berhasil. Apakah ada pekerjaan yang diketahui di sekitar sini?
ak85
44

Berikut adalah arahan yang disempurnakan yang menghindari pemilihan ulang teks saat pengguna mengklik untuk memposisikan kursor di kotak input.

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;
            });
        }
    };
})
Tamlyn
sumber
3
Saya pikir jawaban ini lebih baik dari yang diterima, karena memungkinkan set kursor ke beberapa posisi dalam teks masuk, tapi, seperti direktif memiliki ruang sendiri - saya mengusulkan untuk mengubah nama focusedElement variabel untuk isElementFocused dan toko ada benar atau salah
Vladimir Gordienko
2
Saya mendapatkan TypeError Tidak Tertangkap: undefined bukanlah fungsi pada "ini" untuk .select (); dan ya, jQuery 1.9.1 disertakan.
Robbie Smith
@RobbieSmith Saya terlambat 3 tahun, tetapi ubah semua contoh thismenjadi element[0]dan itu akan berhasil. Saya juga merekomendasikan clickuntuk mengubah focussehingga teks akan dipilih jika tab pengguna menjadi input daripada mengkliknya.
Lex
40

Ini adalah jawaban lama, untuk Angular 1.x

Cara yang lebih baik untuk melakukannya adalah dengan menggunakan ng-clickdirektif bawaan:

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

EDIT:

Seperti yang diingatkan oleh JoshMB ; mereferensikan simpul DOM di Angular 1.2+ tidak lagi diizinkan. Jadi, saya telah pindah $event.target.select()ke pengontrol:

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

Kemudian di pengontrol Anda:

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

Berikut ini contoh biola .

Onur Yıldırım
sumber
2
Sejauh yang saya tahu, ini tidak lagi didukung. Angular menampilkan error: "Merujuk node DOM dalam ekspresi Angular tidak diizinkan!". Lihat utas ini untuk info lebih lanjut: groups.google.com/forum/#!topic/angular/bsTbZ86WAY4 . Namun, pendekatan direktif bekerja dengan baik.
JoshMB
Kamu benar. Ini adalah kasus untuk Angular 1.2+. Saya akan memperbarui jawabannya.
Onur Yıldırım
2
Perubahan DOM harus dilakukan dalam arahan, atau tidak?
Piioo
Untuk beberapa alasan solusi lain tidak berhasil untuk saya tetapi ini berhasil. Saya pikir masalahnya adalah saya sudah memiliki arahan pada elemen tempat saya menambahkan acara klik ini.
Precastic
Serius, bahkan onTextClick ($ event) yang melempar kesalahan sekarang. Selain dari sifat tidak intuitif dari binatang ini, berapa banyak ketidaknyamanan yang merugikan kita dalam kinerja?
jcalfee314
15

Tak satu pun dari solusi yang diusulkan bekerja dengan baik untuk saya. Setelah penelitian singkat saya menemukan ini:

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

  }

});

Ini adalah campuran dari beberapa solusi yang diusulkan, tetapi berfungsi baik pada klik dan fokus (pikirkan fokus otomatis) dan memungkinkan pemilihan manual dari nilai parsial dalam input.

xaralis.dll
sumber
1
Kesalahan sintaks diperbaiki: last}); ganti dengan:}}; });
Blackfire
Yang ini berfungsi untuk input type = "number", yang bagus! Terima kasih
Louis
Hei, ini berfungsi untuk Ionic di Android, tetapi tidak di iOS ... tahu mengapa? Terima kasih
Louis
2
Sepertinya Anda meninggalkan beberapa kode saat Anda mengadaptasinya dari onClick ... apa gunanya focusedElement?
Langdon
12

Bagi saya, ng-click tidak masuk akal, karena Anda tidak akan pernah dapat memposisikan ulang kursor tanpa memilih semua teks lagi, saya menemukan ini mengumumkan. Maka lebih baik menggunakan ng-focus, karena teks dipilih hanya jika input tidak fokus, jika Anda klik lagi untuk memposisikan kursor maka teks hanya batal, seperti yang diharapkan, dan Anda dapat menulis di antaranya.

Saya menemukan pendekatan ini menjadi perilaku UX yang diharapkan.

Gunakan ng-focus

Opsi 1: kode terpisah

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

dan dalam pengontrol

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

Opsi 2: sebagai alternatif, Anda dapat menggabungkan kode di atas ke dalam "satu baris" ini (Saya tidak menguji ini, tetapi seharusnya berfungsi)

<input type="text" ng-model="content" ng-focus="$event.target.select()" />
jperelli
sumber
Sederhana dan berhasil. Ini juga memungkinkan untuk memposisikan kursor Anda dalam teks yang dipilih, seperti yang dibahas di atas.
pistol-pete
7

Di sudut 2, ini berhasil untuk saya, baik di Chrome & Firefox:

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

Jawaban yang diterima adalah menggunakan peristiwa klik, namun jika Anda menggunakan peristiwa fokus, hanya klik pertama yang akan mengaktifkan peristiwa dan juga aktif ketika beberapa metode lain digunakan untuk fokus pada masukan (seperti menekan tab atau memanggil fokus dalam kode).

Ini juga membuatnya tidak perlu untuk memeriksa apakah elemen tersebut sudah fokus seperti yang disarankan oleh jawaban Tamlyn.

app.directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('focus', function () {
                this.select();
            });
        }
    };
});
OrangeKing89
sumber
Di Firefox 38.0.5 mengklik di tengah teks akan memilih semua, tapi kemudian menghapus pilihan, jadi ini tidak akan berhasil.
pengguna1338062
1
Ini mungkin tidak akan pernah berhasil secara konsisten tanpa penundaan this.select.
Langdon
6

Tidak perlu arahan, cukup tambahkan onfocus="this.select()"javascript asli ke elemen masukan atau area teks.

Adam Reis
sumber
1
kenapa begitu banyak orang datang dengan semua jawaban kompleks ini, padahal cara termudah ada di sini: D Terima kasih Adam
SwissCoder
0

Versi modifikasi yang berhasil untuk saya. Klik pertama memilih teks, klik kedua pada elemen yang sama membatalkan pilihan teks

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

})

Ola
sumber
0

Cara termudah untuk memilih semua teks pada klik atau fokus atau tab, adalah !!!:

<input (focus)="inputFocused($event)">

...

inputFocused(event: any){
    event.target.select()
}
Dan Ortega
sumber