Bagaimana cara mendapatkan jQuery untuk memilih elemen dengan a. (titik) di ID mereka?

172

Diberikan kelas berikut dan metode tindakan pengontrol:

public School
{
  public Int32 ID { get; set; }
  publig String Name { get; set; }
  public Address Address { get; set; }
}

public class Address
{
  public string Street1 { get; set; }
  public string City { get; set; }
  public String ZipCode { get; set; }
  public String State { get; set; }
  public String Country { get; set; }
}

[Authorize(Roles = "SchoolEditor")]
[AcceptVerbs(HttpVerbs.Post)]
public SchoolResponse Edit(Int32 id, FormCollection form)
{
  School school = GetSchoolFromRepository(id);

  UpdateModel(school, form);

  return new SchoolResponse() { School = school };
}

Dan formulir berikut:

<form method="post">
  School: <%= Html.TextBox("Name") %><br />
  Street: <%= Html.TextBox("Address.Street") %><br />
  City:  <%= Html.TextBox("Address.City") %><br />
  Zip Code: <%= Html.TextBox("Address.ZipCode") %><br />
  Sate: <select id="Address.State"></select><br />
  Country: <select id="Address.Country"></select><br />
</form>

Saya dapat memperbarui instance Sekolah dan anggota Alamat sekolah. Ini cukup bagus! Terima kasih tim ASP.NET MVC!

Namun, bagaimana cara menggunakan jQuery untuk memilih daftar drop-down sehingga saya dapat mengisinya? Saya menyadari bahwa saya bisa melakukan sisi server ini tetapi akan ada elemen dinamis lainnya pada halaman yang mempengaruhi daftar.

Berikut ini adalah apa yang saya miliki sejauh ini, dan itu tidak berfungsi karena pemilih tampaknya tidak cocok dengan ID:

$(function() {
  $.getJSON("/Location/GetCountryList", null, function(data) {
    $("#Address.Country").fillSelect(data);
  });
  $("#Address.Country").change(function() {
    $.getJSON("/Location/GetRegionsForCountry", { country: $(this).val() }, function(data) {
      $("#Address.State").fillSelect(data);
    });
  });
});
Doug Wilson
sumber

Jawaban:

293

Dari Google Groups :

Gunakan dua garis miring terbalik sebelum setiap karakter khusus.

Garis miring terbalik di pemilih jQuery lolos dari karakter berikutnya. Tapi Anda perlu dua di antaranya karena backslash juga merupakan karakter pelarian untuk string JavaScript. Backslash pertama lolos dari yang kedua, memberi Anda satu backslash yang sebenarnya di string Anda - yang kemudian lolos dari karakter berikutnya untuk jQuery.

Jadi, saya kira Anda sedang melihatnya

$(function() {
  $.getJSON("/Location/GetCountryList", null, function(data) {
    $("#Address\\.Country").fillSelect(data);
  });
  $("#Address\\.Country").change(function() {
    $.getJSON("/Location/GetRegionsForCountry", { country: $(this).val() }, function(data) {
      $("#Address\\.State").fillSelect(data);
    });
  });
});

Lihat juga Bagaimana cara memilih elemen dengan ID yang memiliki karakter yang digunakan dalam notasi CSS? di FAQ jQuery.

bdukes
sumber
4
Saya ingin tahu apa rasionalisasi yang mengharuskan pengembang untuk melakukan ini, sepertinya seperangkat heuristik sederhana dalam jQuery akan menyelesaikan masalah ini, karena tidak ada yang salah dengan ID dengan periode di dalamnya ...
Jason Bunting
5
Jika Anda tidak harus melarikan diri, bagaimana Anda akan meminta elemen dengan Alamat ID dan status kelas (diberikan bahwa jika Anda tahu ID Anda tidak menambahkan banyak dengan menentukan kelas, tetapi itu masih harus valid, saya akan berpikir)?
bdukes
12
Untuk alasan itu, dalam CSS itu sendiri, Anda juga harus menghindari titik di ID. Semua yang dilakukan jQuery mengharuskan Anda untuk mengikuti aturan yang ditetapkan oleh CSS.
bdukes
6
Anda juga dapat memilih berdasarkan nama, bukan ID. Misalnya, $ ('[name = "Address.Country"]')
Funka
25

Anda tidak dapat menggunakan pemilih id jQuery jika id berisi spasi. Gunakan pemilih atribut:

$('[id=foo bar]').show();

Jika memungkinkan, tentukan juga jenis elemen:

$('div[id=foo bar]').show();
Elliot Nelson
sumber
Saya lebih suka melakukannya dengan cara ini daripada menggunakan karakter escape .... Jelas solusi terbaik adalah tidak menggunakan periode dalam id.
GordonB
Spasi tidak diperbolehkan dalam id, bahkan dalam penerimaan karakter HTML5 yang lebih liberal. stackoverflow.com/questions/70579/…
Jay Blanchard
Benar, tetapi apakah mereka diizinkan atau tidak tidak masalah bagi getah miskin yang macet menambahkan ganti jendela ke aplikasi web yang ditulis dengan buruk yang digunakan pada akhir 90-an.
Elliot Nelson
4
harus ada quate agar bisa berfungsi: `$ (" div [id = '"+ variable +"'] ")` atau `$ (" div [id = 'foo bar'] ")`
olga
Seperti @olga katakan, jawabannya tidak sah lagi. Secara khusus, Anda akan mendapatkan pesan kesalahan "Kesalahan Tidak Tertangkap: Kesalahan sintaksis, ekspresi yang tidak dikenal: div [id = foo bar]"
James Moore
13

Escape it for Jquery:

function escapeSelector(s){
    return s.replace( /(:|\.|\[|\])/g, "\\$1" );
}

contoh penggunaan:

e.find('option[value='+escapeSelector(val)+']')

info lebih lanjut di sini .


sumber
2
Solusi sesuai dengan dokumen jQuery adalah menambahkan hanya satu "\" (garis miring). lansiran (escapeSelector ("some.id")); akan menampilkan beberapa \ .id. Jadi saya kira ganti regex seharusnya s.replace (/(:|\.|[| ") / g," \\ $ 1 ");
Arun
Saya memiliki masalah yang sama, mengapa orang lain tidak melihat ini?
TruthOf42
9

Calon Rilis dari ASP.NET MVC yang baru saja dirilis memperbaiki masalah ini, sekarang menggantikan titik-titik dengan garis bawah untuk atribut ID.

<%= Html.TextBox("Person.FirstName") %>

Memberikan kepada

<input type="text" name="Person.FirstName" id="Person_FirstName" />

Untuk informasi lebih lanjut, lihat catatan rilis, mulai dari halaman 14.

Dale Ragan
sumber
1
Saya gagal melihat bagaimana ini merupakan "perbaikan" - mengapa ASP.NET MVC harus mengubah ID untuk sesuatu yang dibutuhkan jQuery? Saya pikir jQuery adalah tempat masalahnya, tidak menggunakan a. dalam ID.
Jason Bunting
7
dot memiliki arti khusus dalam CSS untuk mengidentifikasi / menggabungkan kelas, itulah sebabnya mengapa memiliki ID akan merepotkan. "Masalahnya" bukan dengan jquery.
Funka
4

Ini didokumentasikan dalam dokumen penyeleksi jQuery :

Untuk menggunakan salah satu meta-karakter (seperti !"#$%&'()*+,./:;<=>?@[\]^`{|}~) sebagai bagian literal dari sebuah nama, itu harus melarikan diri dengan dengan dua backslashes: \\. Misalnya, elemen dengan id="foo.bar", dapat menggunakan pemilih $("#foo\\.bar").

Singkatnya, awali .dengan \\sebagai berikut:

$("#Address\\.Country")

Mengapa .ID saya tidak berfungsi?

Masalahnya adalah yang .memiliki signifikansi khusus, string berikut ditafsirkan sebagai pemilih kelas. Jadi $('#Address.Country')akan cocok <div id="Address" class="Country">.

Ketika lolos sebagai \\., titik akan diperlakukan sebagai teks normal tanpa arti khusus, cocok dengan ID yang Anda inginkan <div id="Address.Country">.

Ini berlaku untuk semua karakter !"#$%&'()*+,./:;<=>?@[\]^`{|}~yang seharusnya memiliki arti khusus sebagai pemilih di jQuery. Cukup tambahkan \\untuk memperlakukan mereka sebagai teks biasa.

Kenapa 2 \\?

Seperti disebutkan dalam jawaban bdukes, ada alasan kita membutuhkan 2 \karakter. \akan keluar dari karakter berikut dalam JavaScript. Se ketika JavaScript mengartikan string "#Address\.Country", ia akan melihat \, mengartikannya dengan mengambil karakter berikut secara litteral dan menghapusnya ketika string diteruskan sebagai argumen $(). Itu berarti jQuery masih akan melihat string sebagai "#Address.Country".

Di situlah yang kedua \datang untuk bermain. Yang pertama memberi tahu JavaScript untuk menafsirkan yang kedua sebagai karakter literal (non-khusus). Ini berarti yang kedua akan dilihat oleh jQuery dan memahami bahwa . karakter berikut adalah karakter literal.

Fiuh! Mungkin kita bisa memvisualisasikannya.

//    Javascript, the following \ is not special.
//         | 
//         |
//         v    
$("#Address\\.Country");
//          ^ 
//          |
//          |
//      jQuery, the following . is not special.
Jon Surrell
sumber
2

Menggunakan dua Backslash tidak apa-apa, itu berfungsi. Tetapi jika Anda menggunakan nama dinamis, maksud saya, nama variabel, Anda harus mengganti karakter.

Jika Anda tidak ingin mengubah nama variabel Anda, Anda dapat melakukan ini:

var variable="namewith.andother";    
var jqueryObj = $(document.getElementById(variable));

dan daripada Anda memiliki objek jquery Anda.

Daniel
sumber
0

Hanya informasi tambahan: Lihat masalah ASP.NET MVC # 2403 ini .

Sampai masalah ini diperbaiki, saya menggunakan metode ekstensi saya sendiri seperti Html.TextBoxFixed, dll. Yang hanya menggantikan titik-titik dengan garis bawah pada atribut id (bukan dalam atribut nama), sehingga Anda menggunakan jquery seperti $ ("# Address_Street") tetapi di server, itu seperti Address.Street.

Kode contoh berikut:

public static string TextBoxFixed(this HtmlHelper html, string name, string value)
{
    return html.TextBox(name, value, GetIdAttributeObject(name));
}

public static string TextBoxFixed(this HtmlHelper html, string name, string value, object htmlAttributes)
{
    return html.TextBox(name, value, GetIdAttributeObject(name, htmlAttributes));
}

private static IDictionary<string, object> GetIdAttributeObject(string name)
{
    Dictionary<string, object> list = new Dictionary<string, object>(1);
    list["id"] = name.Replace('.', '_');
    return list;
}

private static IDictionary<string, object> GetIdAttributeObject(string name, object baseObject)
{
    Dictionary<string, object> list = new Dictionary<string, object>();
    list.LoadFrom(baseObject);
    list["id"] = name.Replace('.', '_');
    return list;
}
jenius
sumber
1
dari masalah yang disebutkan di atas: "UpdateModel () menggunakan titik karena itulah cara elemen formulir masuk. Elemen formulir menggunakan titik karena itulah cara mereka ditentukan dalam panggilan penolong HTML. Panggilan penolong HTML menggunakan titik karena itulah cara ViewData.Eval () berfungsi. Akhirnya, ViewData.Eval () menggunakan sebuah titik karena itulah cara seseorang memisahkan objek dan propertinya dalam bahasa .NET Framework utama. Menggunakan pembatas selain titik pada titik mana pun dalam rantai ini akan memecah aliran untuk seluruh rantai. "
Simon_Weaver
0

Saya memecahkan masalah dengan solusi yang diberikan oleh dokumen jquery

Fungsi saya:

//funcion to replace special chars in ID of  HTML tag

function jq(myid){


//return "#" + myid.replace( /(:|\.|\[|\]|,)/g, "\\$1" );
return myid.replace( /(:|\.|\[|\]|,)/g, "\\$1" );


}

Catatan: saya menghapus "#" karena dalam kode saya saya menggabungkan ID dengan teks lain

Font: Jquery Docs pilih elemen dengan karakter utama

Gabriel Molina
sumber