Как получить jQuery для выбора элементов с помощью. (период) в их ID?

Учитывая следующие классы и метод действий контроллера:

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

И следующий вид:

<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>

Я могу обновить экземпляр школы и адрес в школе. Это очень приятно! Спасибо команде ASP.NET MVC!

Однако, как я могу использовать jQuery для выбора раскрывающегося списка, чтобы я мог его предварительно заполнить? Я понимаю, что я мог бы сделать эту серверную часть, но на странице будут влиять другие динамические элементы, которые влияют на список.

Следующее - это то, что у меня есть до сих пор, и оно не работает, поскольку селекторы, похоже, не соответствуют идентификаторам:

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

Ответ 1

Из Группы Google:

Используйте два обратных слэша перед каждым специальным символом.

Обратная косая черта в селекторе jQuery ускользает от следующего символа. Но вам нужно два из них, потому что обратная косая черта также является символом escape для JavaScript строки. Первая обратная косая черта ускользает от второй, давая вам один фактический обратная косая черта в вашей строке, которая затем ускользает от следующего символа для jQuery.

Итак, я думаю, вы смотрите на

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

Также проверьте Как выбрать элемент с помощью идентификатора, который имеет символы, используемые в нотации CSS? в FAQ jQuery.

Ответ 2

Вы не можете использовать селектор id jQuery, если идентификатор содержит пробелы. Используйте селектор атрибутов:

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

Если возможно, укажите также тип элемента:

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

Ответ 3

Побег в JQuery:

function escapeSelector(s){
    return s.replace( /(:|\.|\[|\])/g, "\\$1" );
}
Пример использования

:

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

подробнее здесь.

Ответ 4

Кандидат Release ASP.NET MVC, который только что был выпущен, исправил эту проблему, теперь он заменяет точки символами подчеркивания для атрибута ID.

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

Относится к

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

Подробнее см. примечания к выпуску, начиная со страницы 14.

Ответ 5

Это описано в jQuery Selectors docs:

Чтобы использовать любой из метасимволов (например, !"#$%&'()*+,./:;<=>[email protected][\]^`{|}~) как буквальная часть имени, она должна сбежать с двумя обратными косыми чертами: \\. Например, элемент с id="foo.bar", можно использовать селектор $("#foo\\.bar").

Короче говоря, префикс . с помощью \\ следующим образом:

$("#Address\\.Country")

Почему в моем идентификаторе не работает .?

Проблема в том, что . имеет особое значение, следующая строка интерпретируется как селектор классов. Таким образом, $('#Address.Country') будет соответствовать <div id="Address" class="Country">.

Если выбрано значение \\., точка будет обрабатываться как обычный текст без особого значения, соответствующий желаемому ID <div id="Address.Country">.

Это относится ко всем символам !"#$%&'()*+,./:;<=>[email protected][\]^`{|}~, которые в противном случае имели бы особое значение как селектор в jQuery. Просто добавьте \\, чтобы рассматривать их как обычный текст.

Почему 2 \\?

Как отмечено в ответах bdukes, есть причина, по которой нам нужны 2 \ символов. \ будет избегать следующего символа в JavaScript. Se, когда JavaScript интерпретирует строку "#Address\.Country", она увидит \, интерпретирует ее как означающую перевод следующего символа и удаляем ее, когда строка передается как аргумент $(). Это означает, что jQuery по-прежнему будет видеть строку как "#Address.Country".

То, в которое входит вторая \. Первый говорит JavaScript, чтобы интерпретировать второй как буквенный (неспециальный) символ. Это означает, что второй будет отображаться jQuery и понять, что следующий символ . - это буквальный символ.

Уф! Возможно, мы можем это представить.

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

Ответ 6

Используя две обратные косые черты, все в порядке, это работает. Но если вы используете динамическое имя, я имею в виду, имя переменной, вам нужно будет заменить символы.

Если вы не хотите менять имена переменных, вы можете сделать это:

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

и у вас есть свой объект jquery.

Ответ 7

Только дополнительная информация: Проверьте Проблема ASP.NET MVС# 2403.

Пока проблема не исправлена, я использую свои собственные методы расширения, такие как Html.TextBoxFixed и т.д., которые просто заменяют точки подчеркиваниями в атрибуте id (не в атрибуте name), так что вы используете jquery как $( "# Address_Street" ), но на сервере это похоже на Address.Street.

Пример кода:

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

Ответ 8

Я решил проблему с решением, заданным jquery docs

Моя функция:

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

function jq(myid){


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


}

Примечание: я удаляю "#", потому что в моем коде я конкатью идентификатор с другим текстом

Шрифт: JQuery Docs выбирает элемент с особыми символами