Question

Attention: cette question a plus de neuf ans!

Votre meilleure option est de rechercher de nouvelles questions, ou parmi les réponses ci-dessous, à la recherche de votre version spécifique de MVC, car de nombreuses réponses ici sont obsolètes.

Si vous trouvez une réponse qui convient à votre version, assurez-vous qu'elle contient bien la version de MVC que vous utilisez.
(La question initiale commence ci-dessous)

Cela me semble un peu bizarre, mais pour autant que je sache, voici comment vous procédez.

J'ai une collection d'objets et je veux que les utilisateurs en sélectionnent un ou plusieurs. Cela me dit & "Formulaire avec cases à cocher" & "; Mes objets n'ont aucun concept de & Quot; sélectionné & Quot; (Ce sont des POCO rudimentaires formés en désérialisant un appel wcf). Donc, je fais ce qui suit:

public class SampleObject{
  public Guid Id {get;set;}
  public string Name {get;set;}
}

Dans la vue:

<%
    using (Html.BeginForm())
    {
%>
  <%foreach (var o in ViewData.Model) {%>
    <%=Html.CheckBox(o.Id)%>&nbsp;<%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

Et, dans le contrôleur, c’est le seul moyen dont je dispose pour déterminer les objets vérifiés par l’utilisateur:

public ActionResult ThisLooksWeird(FormCollection result)
{
  var winnars = from x in result.AllKeys
          where result[x] != "false"
          select x;
  // yadda
}

C'est bizarre en premier lieu, et deuxièmement, pour les éléments que l'utilisateur a cochés, FormCollection indique sa valeur comme & "vrai faux &"; plutôt que juste vrai.

Évidemment, il me manque quelque chose. Je pense que ceci est construit avec l'idée en tête que les objets de la collection qui sont traités dans le formulaire html sont mis à jour en utilisant UpdateModel() ou par le biais d'un ModelBinder.

Mais mes objets ne sont pas configurés pour cela; cela signifie-t-il que c'est le seul moyen? Y a-t-il un autre moyen de le faire?

Était-ce utile?

La solution

Html.CheckBox fait quelque chose de bizarre - si vous affichez le source sur la page résultante, vous verrez qu'un <input type="hidden" /> est généré à côté de chaque case à cocher, ce qui explique le " vrai faux " les valeurs que vous voyez pour chaque élément de formulaire.

Essayez ceci, qui fonctionne vraiment sur ASP.NET MVC Beta parce que je viens de l'essayer.

Mettez ceci dans la vue au lieu d'utiliser Html.CheckBox ():

<% using (Html.BeginForm("ShowData", "Home")) {  %>
  <% foreach (var o in ViewData.Model) { %>
    <input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
    <%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

Vos cases à cocher s'appellent toutes selectedObjects, et le value de chaque case à cocher est le GUID de l'objet correspondant.

Envoyez ensuite l'action suivante sur le contrôleur (ou quelque chose de similaire qui fait quelque chose d'utile à la place de Response.Write ())

public ActionResult ShowData(Guid[] selectedObjects) {
    foreach (Guid guid in selectedObjects) {
        Response.Write(guid.ToString());
    }
    Response.End();
    return (new EmptyResult());
}

Cet exemple va simplement écrire les GUID des cases que vous avez cochées; ASP.NET MVC mappe les valeurs de GUID des cases à cocher sélectionnées dans le paramètre Guid[] selectedObjects et analyse même les chaînes de la collection Request.Form dans des objets GUID instanciés, ce qui me semble plutôt agréable.

Autres conseils

HtmlHelper ajoute une entrée cachée pour informer le contrôleur de l'état Non vérifié. Donc, pour avoir le statut vérifié correct:

bool bChecked = form[key].Contains("true");

Dans le cas où vous vous demandez POURQUOI ils ont mis un champ caché avec le même nom que la case à cocher, la raison est la suivante:

Commentaire du code source MVCBetaSource \ MVC \ src \ MvcFutures \ Mvc \ ButtonsAndLinkExtensions.cs

  

Afficher un <input type="hidden".../> supplémentaire pour les cases à cocher.   Cela concerne des scénarios où   les cases à cocher non cochées ne sont pas envoyées   la demande. Envoi d'une entrée masquée   permet de savoir que le   case à cocher était présent sur la page quand   la demande a été soumise.

Je suppose qu’en arrière-plan, ils doivent le savoir pour se lier aux paramètres des méthodes d’action du contrôleur. Vous pourriez alors avoir un booléen à trois états, je suppose (lié à un paramètre bool nullable). Je n'ai pas essayé, mais j'espère que c'est ce qu'ils ont fait.

Vous devez également utiliser <label for="checkbox1">Checkbox 1</label> car les utilisateurs peuvent cliquer sur le texte de l'étiquette ainsi que sur la case à cocher elle-même. Il est également plus facile à styler et au moins dans IE, il est mis en évidence lorsque vous parcourez les contrôles de la page.

<%= Html.CheckBox("cbNewColors", true) %><label for="cbNewColors">New colors</label>

Ce n’est pas simplement un truc du genre «je pourrais le faire». C'est une amélioration significative de l'expérience utilisateur. Même si tous les utilisateurs ne savent pas qu'ils peuvent cliquer sur l'étiquette, beaucoup le feront.

Je suis surpris qu'aucune de ces réponses n'utilise les fonctionnalités intégrées de MVC pour cela.

J'ai écrit un billet de blog à ce sujet here , qui lie même les étiquettes à la case à cocher. J'ai utilisé le dossier EditorTemplate pour y parvenir de manière propre et modulaire.

Vous allez simplement vous retrouver avec un nouveau fichier dans le dossier EditorTemplate qui ressemble à ceci:

@model SampleObject

@Html.CheckBoxFor(m => m.IsChecked)
@Html.HiddenFor(m => m.Id)
@Html.LabelFor(m => m.IsChecked, Model.Id)

dans votre vue réelle, il n'y aura pas besoin de boucler ceci, simplement 1 ligne de code:

@Html.EditorFor(x => ViewData.Model)

Visitez mon article de blog pour plus de détails.

Voici ce que j'ai fait.

Voir:


<input type="checkbox" name="applyChanges" />

Contrôleur:


var checkBox = Request.Form["applyChanges"];

if (checkBox == "on")
{
...
}

J'ai trouvé les méthodes d'aide HTML * pas utiles dans certains cas, et il valait mieux que je le fasse avec du vieux HTML ordinaire. Ceci étant l’un d’eux, l’autre qui me vient à l’esprit est le bouton radio.

Modifier: il s’agit de l’aperçu 5, bien évidemment de YMMV entre les versions.

Ils semblent vouloir ne lire que la première valeur, c'est donc & "true &"; lorsque la case à cocher est cochée, et " faux " lorsque seule la valeur cachée est incluse. Ceci est facilement récupéré avec un code comme celui-ci:

model.Property = collection["ElementId"].ToLower().StartsWith("true");

@Dylan Beattie Bonne découverte !!! Je vous remercie beaucoup. Pour étendre encore plus loin, cette technique fonctionne également parfaitement avec l'approche View Model. MVC est tellement cool qu'il est assez intelligent pour lier un tableau de Guids à une propriété du même nom que l'objet Model lié à la vue. Exemple:

Modèle de vue:

public class SampleViewModel
{
    public IList<SampleObject> SampleObjectList { get; set; }
    public Guid[] SelectedObjectIds { get; set; }

    public class SampleObject
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }
}

Voir:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View</h2>
<table>
    <thead> 
        <tr>
            <th>Checked</th>
            <th>Object Name</th>
        </tr>
    </thead> 
<% using (Html.BeginForm()) %>
<%{%>                    
    <tbody>
        <% foreach (var item in Model.SampleObjectList)
           { %>
            <tr>
                <td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
                <td><%= Html.Encode(item.Name)%></td>
            </tr>
        <% } %>
    </tbody>
</table>
<input type="submit" value="Submit" />
<%}%>                    

Contrôleur:

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult SampleView(Guid id)
    {
        //Object to pass any input objects to the View Model Builder 
        BuilderIO viewModelBuilderInput = new BuilderIO();

        //The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects
        SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput);

        return View("SampleView", viewModel);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult SampleView(SampleViewModel viewModel)
    {
        // The array of Guids successfully bound to the SelectedObjectIds property of the View Model!
        return View();
    }

Toute personne familière avec la philosophie View Model s’en réjouira, cela fonctionne comme un champion!

Je tiens également à préciser que vous pouvez nommer chaque case à cocher d'un nom différent et inclure ce nom dans les paramètres d'actionresults.

Exemple,

Voir:

 <%= Html.CheckBox("Rs232CheckBox", false, new { @id = "rs232" })%>RS-232

 <%= Html.CheckBox("Rs422CheckBox", false, new { @id = "rs422" })%>RS-422

Contrôleur:

public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
    ...
}

Les valeurs de la vue sont transmises à l'action car les noms sont les mêmes.

Je sais que cette solution n’est pas idéale pour votre projet, mais j’ai pensé que jetterais l’idée là-bas.

<input type = "checkbox" name = "checkbox1" /> <label> Check to say hi.</label>

À partir du contrôleur:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(FormCollection fc)
    {

         var s = fc["checkbox1"];

         if (s == "on")
         {
             string x = "Hi";
         }
    }

Ce problème se produit également dans la version 1.0. Html.Checkbox () provoque l'ajout d'un autre champ caché avec le même nom / id que celui de votre case à cocher d'origine. Et comme j'essayais de charger un tableau de cases à cocher en utilisant document.GetElemtentsByName (), vous pouvez deviner comment les choses se sont égarées. C'est bizarre.

D'après ce que je peux comprendre, le modèle ne veut pas deviner s'il est coché = vrai ou faux. J'ai contourné cela en définissant un attribut value sur l'élément checkbox avec jQuery avant de soumettre le formulaire comme suit:

 $('input[type="checkbox"]').each(function () {
       $(this).attr('value', $(this).is(':checked'));
 }); 

Ainsi, vous n'avez pas besoin d'un élément masqué pour stocker la valeur de la case à cocher.

Je sais que cette question a été écrite à l’époque où MVC3 n’était pas disponible, mais pour tous ceux qui viennent à cette question et utilisent MVC3, vous souhaiterez peut-être le & "correct &"; façon de le faire.

Bien que je pense que faire le tout

Contains("true");

chose est géniale et propre, et fonctionne sur toutes les versions de MVC, le problème est qu’elle ne tient pas compte de la culture (comme si c’était vraiment important dans le cas d’un bool).

Le " correct " Pour comprendre la valeur d’une valeur booléenne, du moins dans MVC3, utilisez ValueProvider.

var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool));

Je le fais dans l'un des sites de mes clients lorsque je modifie des autorisations:

var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList();
var allPermissions = new List<KeyValuePair<int, bool>>();

foreach (var key in allPermissionsBase)
{
     // Try to parse the key as int
     int keyAsInt;
     int.TryParse(key.Replace("permission_", ""), out keyAsInt);

     // Try to get the value as bool
     var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool));
}

Maintenant, la beauté de ceci est que vous pouvez l'utiliser avec n'importe quel type simple, et que cela sera même correct en fonction de la culture (pensez à l'argent, les décimales, etc.).

Le ValueProvider est ce qui est utilisé lorsque vous formez vos actions comme ceci:

public ActionResult UpdatePermissions(bool permission_1, bool permission_2)

mais lorsque vous essayez de construire ces listes de manière dynamique et de vérifier les valeurs, vous ne connaissez jamais l’ID au moment de la compilation, vous devez donc les traiter à la volée.

La façon la plus simple de le faire est de le faire ...

Vous définissez le nom et la valeur.

<input type="checkbox" name="selectedProducts" value="@item.ProductId" />@item.Name

Ensuite, en soumettant, saisissez les valeurs des cases à cocher et enregistrez-les dans un tableau int. puis la fonction LinQ appropriée. C'est ça ..

[HttpPost]
        public ActionResult Checkbox(int[] selectedObjects)
        {
            var selected = from x in selectedObjects
                           from y in db
                           where y.ObjectId == x
                           select y;                   

            return View(selected);
        }

Comme pour la réponse de nautic20, utilisez simplement la liste de cases à cocher de liaison de modèle par défaut de MVC avec le même nom qu'une propriété de collection de string / int / enum dans ViewModel. C'est ça.

Mais un problème doit être souligné. Dans chaque composant de case à cocher, vous ne devez pas mettre & "Id &"; qui affectera la liaison du modèle MVC.

Le code suivant fonctionnera pour la liaison de modèle:

 <% foreach (var item in Model.SampleObjectList)
       { %>
        <tr>
            <td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
            <td><%= Html.Encode(item.Name)%></td>
        </tr>
 <% } %>

Les codes suivants ne seront pas liés au modèle (la différence est son identifiant attribué à chaque case à cocher)

<% foreach (var item in Model.SampleObjectList)
       { %>
        <tr>
            <td><input type="checkbox" name="SelectedObjectIds" id="[some unique key]" value="<%= item.Id%>" /></td>
            <td><%= Html.Encode(item.Name)%></td>
        </tr>
<% } %>

C’est ce que j’ai fait pour perdre les valeurs doubles en utilisant Html.CheckBox (...

Replace("true,false","true").Split(',')

avec 4 cases cochées, décochées, décochées, cochées vrai, faux, faux, faux, vrai, faux dans vrai, faux, faux, vrai. juste ce dont j'avais besoin

Pourquoi pas quelque chose comme ça?

bool isChecked = false;
if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false)
    ModelState.AddModelError(”chkHuman”, “Nice try.”);

Lorsque vous utilisez la case à cocher HtmlHelper, je préfère de loin travailler avec les données de formulaire de case à cocher publiées en tant que tableau. Je ne sais pas vraiment pourquoi, je sais que les autres méthodes fonctionnent, mais je pense que je préfère simplement traiter les chaînes séparées par des virgules comme un tableau autant que possible.

Donc, faire un test "vérifié" ou réel serait:

//looking for [true],[false]
bool isChecked = form.GetValues(key).Contains("true"); 

Faire un faux chèque serait:

//looking for [false],[false] or [false]
bool isNotChecked = !form.GetValues(key).Contains("true"); 

La principale différence est d'utiliser GetValues car cela retourne sous forme de tableau.

Faites ceci simplement sur $(document).ready:

$('input:hidden').each(function(el) {
    var that = $(this)[0];
    if(that.id.length < 1 ) {

        console.log(that.id);
        that.parentElement.removeChild(that);

    }
});

Ma solution est la suivante:

<input type="checkbox"  id="IsNew-checkbox"  checked="checked" />     
<input type="hidden"  id="IsNew" name="IsNew" value="true"  />      
<script language="javascript" type="text/javascript" >     
  $('#IsNew-checkbox').click(function () {    
      if ($('#IsNew-checkbox').is(':checked')) {    
          $('#IsNew').val('true');    
      } else {    
          $('#IsNew').val('false');    
       }    
  });   
</script>  

Plus vous pouvez trouver ici: http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-de-string-was-not-recognized- as-a-valid-boolean /

J'ai eu à peu près le même problème, mais la valeur de retour de mon contrôleur a été bloquée avec d'autres valeurs.

Nous avons trouvé une solution simple mais qui semble un peu rugueuse.

Essayez de taper Viewbag. dans votre contrôleur et vous lui donnez maintenant un nom comme Viewbag.Checkbool

Basculez maintenant vers la vue et essayez ceci @Viewbag.Checkbool avec cela, vous obtiendrez la valeur du contrôleur.

Les paramètres de mon contrôleur ressemblent à ceci:

public ActionResult Anzeigen(int productid = 90, bool islive = true)

et ma case à cocher se mettra à jour comme suit:

<input id="isLive" type="checkbox" checked="@ViewBag.Value" ONCLICK="window.location.href = '/MixCategory/Anzeigen?isLive=' + isLive.checked.toString()" />

En utilisant @mmacaulay, j'ai trouvé ceci pour bool:

// MVC Work around for checkboxes.
bool active = (Request.Form["active"] == "on");

Si coché actif = vrai

Si décoché actif = faux

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top