Cuidado: Esta pergunta tem mais de nove anos!
Sua melhor opção é procurar por perguntas mais recentes ou procurar as respostas abaixo procurando sua versão específica do MVC, pois muitas respostas aqui estão obsoletas agora.
Se você encontrar uma resposta que funcione para sua versão, verifique se a resposta contém a versão do MVC que você está usando.
(A pergunta original começa abaixo)
Isso me parece um pouco bizarro, mas até onde eu sei, é assim que você faz.
Eu tenho uma coleção de objetos e quero que os usuários selecionem um ou mais deles. Isso me diz "formulário com caixas de seleção". Meus objetos não têm nenhum conceito de "selecionado" (são POCOs rudimentares formados pela desserialização de uma chamada wcf). Então, eu faço o seguinte:
public class SampleObject{
public Guid Id {get;set;}
public string Name {get;set;}
}
Na visualização:
<%
using (Html.BeginForm())
{
%>
<%foreach (var o in ViewData.Model) {%>
<%=Html.CheckBox(o.Id)%> <%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
E, no controlador, é a única maneira que posso ver para descobrir quais objetos o usuário verificou:
public ActionResult ThisLooksWeird(FormCollection result)
{
var winnars = from x in result.AllKeys
where result[x] != "false"
select x;
// yadda
}
É esquisito em primeiro lugar e, em segundo lugar, para os itens que o usuário verificou, o FormCollection lista seu valor como "verdadeiro falso" e não apenas verdadeiro.
Obviamente, estou perdendo alguma coisa. Eu acho que isso é construído com a idéia de que os objetos na coleção que são UpdateModel()
acionados no formulário html são atualizados usando ou através de um ModelBinder.
Mas meus objetos não estão configurados para isso; isso significa que este é o único caminho? tem outro jeito de fazer isto?
fonte
Respostas:
Html.CheckBox está fazendo algo estranho - se você visualizar a fonte na página resultante, verá que está
<input type="hidden" />
sendo gerado ao lado de cada caixa de seleção, o que explica os valores "true false" que você está vendo para cada elemento do formulário.Tente isso, que definitivamente funciona no ASP.NET MVC Beta, porque eu apenas tentei.
Coloque isso na exibição em vez de usar Html.CheckBox ():
Suas caixas de seleção são todas chamadas
selectedObjects
e asvalue
de cada caixa de seleção é o GUID do objeto correspondente.Poste na ação do controlador a seguir (ou algo semelhante que faça algo útil em vez de Response.Write ())
Este exemplo escreverá apenas os GUIDs das caixas marcadas; O ASP.NET MVC mapeia os valores GUID das caixas de seleção selecionadas no
Guid[] selectedObjects
parâmetro para você e até analisa as seqüências de caracteres da coleção Request.Form em objetos GUID instantâneos, o que eu acho bastante agradável.fonte
O HtmlHelper adiciona uma entrada oculta para notificar o controlador sobre o status Não verificado. Portanto, para ter o status verificado correto:
fonte
Caso você esteja se perguntando POR QUE eles colocam um campo oculto com o mesmo nome da caixa de seleção, o motivo é o seguinte:
Comentário do código-fonte MVCBetaSource \ MVC \ src \ MvcFutures \ Mvc \ ButtonsAndLinkExtensions.cs
Eu acho que nos bastidores eles precisam saber disso para vincular parâmetros nos métodos de ação do controlador. Suponho que você possa ter um booleano de três estados (vinculado a um parâmetro bool anulável). Eu não tentei, mas espero que seja o que eles fizeram.
fonte
Você também deve usar,
<label for="checkbox1">Checkbox 1</label>
pois as pessoas podem clicar no texto do rótulo e na própria caixa de seleção. Também é mais fácil de estilizar e, pelo menos no IE, será destacado quando você guia os controles da página.Isso não é apenas uma coisa do tipo 'oh, eu poderia fazer'. É uma melhoria significativa na experiência do usuário. Mesmo que nem todos os usuários saibam que podem clicar no rótulo, muitos o farão.
fonte
Estou surpreso que nenhuma dessas respostas tenha usado os recursos MVC integrados para isso.
Escrevi um post sobre isso aqui , que até vincula os rótulos à caixa de seleção. Usei a pasta EditorTemplate para fazer isso de maneira limpa e modular.
Você simplesmente terminará com um novo arquivo na pasta EditorTemplate que se parece com isso:
na sua visão atual, não haverá necessidade de fazer um loop, simplesmente uma linha de código:
Visite meu blog para obter mais detalhes.
fonte
+1
e + cervejaAqui está o que eu tenho feito.
Visão:
Controlador:
Eu achei os métodos auxiliares Html. * Não tão úteis em alguns casos, e era melhor fazê-lo em HTML simples e antigo. Sendo um deles, o outro que vem à mente são os botões de opção.
Edit: isso está na visualização 5, obviamente YMMV entre as versões.
fonte
Eles parecem optar por ler apenas o primeiro valor, portanto, isso é "verdadeiro" quando a caixa de seleção está marcada e "falso" quando apenas o valor oculto é incluído. Isso é facilmente buscado com código como este:
fonte
@Dylan Beattie Great Find !!! Eu agradeço muito. Para expandir ainda mais, essa técnica também funciona perfeitamente com a abordagem Exibir modelo. O MVC é tão legal que é inteligente o suficiente vincular uma matriz de Guids a uma propriedade com o mesmo nome do objeto Model vinculado à View. Exemplo:
ViewModel:
Visão:
Controlador:
Qualquer pessoa familiarizada com a filosofia do View Model se alegra, isso funciona como um campeão!
fonte
Gostaria também de ressaltar que você pode nomear cada caixa de seleção com um nome diferente e fazer com que esse nome faça parte dos parâmetros de resultados da ação.
Exemplo,
Visão:
Controlador:
Os valores da visualização são transmitidos para a ação, pois os nomes são os mesmos.
Sei que essa solução não é ideal para o seu projeto, mas pensei em lançar a idéia lá fora.
fonte
Do controlador:
fonte
Esse problema também está acontecendo no release 1.0. Html.Checkbox () faz com que outro campo oculto seja adicionado com o mesmo nome / ID da sua caixa de seleção original. E enquanto eu tentava carregar uma matriz de caixas de seleção usando document.GetElemtentsByName (), você pode adivinhar como as coisas estavam ficando complicadas. Isso é bizarro.
fonte
Pelo que pude entender, o modelo não quer adivinhar se marcado = verdadeiro ou falso, resolvi isso definindo um atributo de valor no elemento checkbox com o jQuery antes de enviar o formulário da seguinte maneira:
Dessa forma, você não precisa de um elemento oculto apenas para armazenar o valor da caixa de seleção.
fonte
Sei que essa pergunta foi escrita quando o MVC3 não estava disponível, mas para quem chega a essa pergunta e está usando o MVC3, convém a maneira "correta" de fazer isso.
Enquanto eu acho que fazer o todo
Se tudo é ótimo e limpo, e funciona em todas as versões do MVC, o problema é que não leva em consideração a cultura (como se realmente importasse no caso de um bool).
A maneira "correta" de descobrir o valor de um bool, pelo menos no MVC3, é usar o ValueProvider.
Faço isso em um dos sites do meu cliente quando edito as permissões:
Agora, a beleza disso é que você pode usá-lo com praticamente qualquer tipo simples, e até estará correto com base na Cultura (pense em dinheiro, decimais, etc.).
O ValueProvider é o que é usado quando você forma suas ações assim:
mas quando você estiver tentando criar dinamicamente essas listas e verificar os valores, nunca conhecerá o ID em tempo de compilação; portanto, é necessário processá-los rapidamente.
fonte
A maneira mais fácil de fazer é ...
Você define o nome e o valor.
<input type="checkbox" name="selectedProducts" value="@item.ProductId" />@item.Name
Em seguida, ao enviar, pegue os valores das caixas de seleção e salve em uma matriz int. então a função LinQ apropriada. É isso aí..
fonte
Igual à resposta de nautic20, basta usar a lista de caixas de seleção de ligação de modelo padrão do MVC com o mesmo nome que uma propriedade de coleção de string / int / enum no ViewModel. É isso.
Mas uma questão precisa apontar. Em cada componente da caixa de seleção, você não deve colocar "Id" nele, o que afetará a ligação do modelo MVC.
O código a seguir funcionará para a ligação de modelo:
Os códigos a seguir não serão vinculativos ao modelo (diferença aqui é o ID atribuído para cada caixa de seleção)
fonte
isto é o que eu fiz para perder os valores duplos ao usar o Html.CheckBox (...
com 4 caixas marcadas, desmarcada, desmarcada, marcada, torna-se verdadeiro, falso, falso, falso, falso, verdadeiro, falso em verdadeiro, falso, falso, verdadeiro. exatamente o que eu precisava
fonte
Que tal algo como isso?
fonte
Ao usar a caixa de seleção HtmlHelper, prefiro trabalhar com os dados do formulário da caixa de seleção postada como uma matriz. Eu realmente não sei por que, sei que os outros métodos funcionam, mas acho que prefiro tratar as seqüências separadas por vírgula como uma matriz, tanto quanto possível.
Portanto, fazer um teste 'marcado' ou verdadeiro seria:
Fazer uma verificação falsa seria:
A principal diferença é usar,
GetValues
pois isso retorna como uma matriz.fonte
Basta fazer isso em
$(document).ready
:fonte
Minha solução é:
Você pode encontrar mais aqui: http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized-as-a- valid-boolean /
fonte
Eu tive quase o mesmo problema, mas o valor de retorno do meu controlador foi bloqueado com outros valores.
Encontrei uma solução simples, mas parece um pouco difícil.
Tente digitar o
Viewbag.
seu Controller e agora dê um nome comoViewbag.Checkbool
Agora mude para o modo de exibição e tente isso
@Viewbag.Checkbool
com isso, você obterá o valor do controlador.Meus parâmetros de controlador são assim:
e minha caixa de seleção será atualizada assim:
fonte
Usando @mmacaulay, eu vim com isso para bool:
Se marcado ativo = verdadeiro
Se desmarcado, ativo = falso
fonte