web-dev-qa-db-fra.com

Comment faire en sorte que jQuery sélectionne des éléments avec un fichier. (période) dans leur identité?

Étant donné les classes suivantes et la méthode d'action du contrôleur:

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

Et le formulaire suivant:

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

Je suis en mesure de mettre à jour l'instance School et le membre Address de l'école. C'est assez gentil! Merci à l’équipe ASP.NET MVC!

Cependant, comment utiliser jQuery pour sélectionner la liste déroulante afin de pouvoir la pré-remplir? Je me rends compte que je pourrais faire ce côté serveur, mais il y aura d'autres éléments dynamiques sur la page qui affectent la liste.

Ce qui suit est ce que j'ai jusqu'à présent, et cela ne fonctionne pas car les sélecteurs ne semblent pas correspondre aux identifiants:

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

De Groupes Google :

Utilisez deux barres obliques inverses avant chaque caractère spécial.

Une barre oblique inverse dans un sélecteur jQuery échappe au caractère suivant. Mais vous en avez besoin de deux car la barre oblique inverse est également le caractère d'échappement des chaînes JavaScript. La première barre oblique inversée échappe à la seconde, vous donnant une barre oblique inverse dans votre chaîne, qui échappe ensuite au caractère suivant pour jQuery.

Donc, je suppose que vous regardez

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

Consultez également Comment sélectionner un élément à l'aide d'un ID comportant des caractères utilisés en notation CSS? dans la FAQ jQuery.

285
bdukes

Vous ne pouvez pas utiliser un sélecteur d'identifiant jQuery si celui-ci contient des espaces. Utilisez un sélecteur d'attribut:

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

Si possible, spécifiez également le type d'élément:

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

Escape it pour JQuery:

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

exemple d'utilisation:

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

plus d'infos ici .

11
user669677

La version finale de ASP.NET MVC qui venait d'être publiée a résolu ce problème. Elle remplace maintenant les points par des traits de soulignement pour l'attribut ID.

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

Rend à

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

Pour plus d'informations, consultez les notes de publication à partir de la page 14.

9
Dale Ragan

Ceci est documenté dans documentation jQuery Selectors :

Pour utiliser n'importe lequel des méta-caractères (tels que !"#$%&'()*+,./:;<=>?@[\]^`{|}~) en tant que partie littérale d'un nom, il doit être échappé avec deux barres obliques inverses: \\. Par exemple, un élément avec id="foo.bar" Peut utiliser le sélecteur $("#foo\\.bar").

En bref, préfixez le . Avec \\ Comme suit:

$("#Address\\.Country")

Pourquoi . Ne fonctionne-t-il pas avec mon identifiant?

Le problème est que . A une signification particulière, la chaîne suivante est interprétée comme un sélecteur de classe. Donc, $('#Address.Country') correspondrait à <div id="Address" class="Country">.

Lorsque échappé en tant que \\., Le point sera traité comme du texte normal sans signification particulière, correspondant à l'ID souhaité <div id="Address.Country">.

Ceci s'applique à tous les caractères !"#$%&'()*+,./:;<=>?@[\]^`{|}~ qui auraient autrement une signification particulière en tant que sélecteur dans jQuery. Ajoutez simplement \\ Pour les traiter comme du texte normal.

Pourquoi 2 \\?

Comme indiqué dans la réponse de bdukes, il y a une raison pour laquelle nous avons besoin de 2 caractères \. \ Échappera le caractère suivant en JavaScript. Si JavaScript interprète la chaîne "#Address\.Country", Il verra le \, Interprété comme signifiant prend le caractère suivant littéralement et le supprime lorsque la chaîne est transmise en tant qu'argument à $(). Cela signifie que jQuery verra toujours la chaîne sous la forme "#Address.Country".

C'est là que le deuxième \ Entre en jeu. Le premier indique à JavaScript d'interpréter le second comme un caractère littéral (non spécial). Cela signifie que le second sera vu par jQuery et comprendra que le caractère . Suivant est un caractère littéral.

Phew! Peut-être pouvons-nous visualiser cela.

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

Utiliser deux barres obliques inverses c’est bien, c’est efficace. Mais si vous utilisez un nom dynamique, je veux dire un nom de variable, vous devrez remplacer les caractères.

Si vous ne voulez pas changer les noms de vos variables, vous pouvez le faire:

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

et que vous avez votre objet jQuery.

2
Daniel

Juste des informations supplémentaires: Cochez ceci numéro ASP.NET MVC # 24 .

Tant que le problème n'est pas résolu, j'utilise mes propres méthodes d'extension, telles que Html.TextBoxFixed, etc. mais sur le serveur, c'est comme Address.Street.

Exemple de code suit:

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

J'ai résolu le problème avec la solution proposée par jquery docs

Ma fonction:

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

function jq(myid){


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


}

Note: je supprime le "#" car dans mon code je concat l'ID avec un autre texte

Police: Jquery Docs sélectionne un élément avec des caractères spéciaux

0
Gabriel Molina