none
Pagina estilo Wizard com Overlay Modal (Jquery Tools) RRS feed

  • Pergunta

  • Boa Tarde, estou iniciando com Mvc e acabei me deparando com alguns problemas:

     

    criei uma view onde o usuario irá clicar em um dos links e abre um modal para ele digitar as informaçoes de assinatura:

    Preciso pazer um "passo a passo" estilo wizard onde ele irápreenchendo alguns campos e indo para as proximas etapas...

    porem nao estou conseguindo recuperar os dados:

    segue o código:

     

    a view é Partial pois é renderizada dentro de uma div na view principal View

     

     

    @model Models.AssinaturaModel
    <h1>
      @ViewBag.TituloPagina
    </h1>
    
      @using (Ajax.BeginForm("TesteAjax", new AjaxOptions()
          {
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = @ViewBag.DivModalId
          }))
      {
        <button class="close">
          Close
        </button>
    <h1>
    @ViewBag.InformeDominio
    </h1>
    
     @ViewBag.PrefixoDominio
     @Html.TextBoxFor(m => m.Dominio)
     @Html.ValidationMessageFor(m => m.Dominio)
    
     @Html.DropDownListFor(m => m.Extensao, new[] {
                        new SelectListItem(){Text = ".com", Value=".com"}, 
                        new SelectListItem(){Text = ".com.br", Value=".com.br"},
                        new SelectListItem(){Text = ".net", Value=".net"},
                        new SelectListItem(){Text = ".org", Value=".org"},
                        new SelectListItem(){Text = ".info", Value=".info"},
                        new SelectListItem(){Text = ".biz", Value=".biz"},
                        new SelectListItem(){Text = ".tv", Value=".tv"},
                        new SelectListItem(){Text = ".name", Value=".name"},
                        new SelectListItem(){Text = ".ws", Value=".ws"},
                        new SelectListItem(){Text = ".cc", Value=".cc"},
                        new SelectListItem(){Text = ".blog.br", Value=".blog.br"},
                        new SelectListItem(){Text = ".flog.br", Value=".flog.br"},
                        new SelectListItem(){Text = ".vlog.br", Value=".vlog.br"},
                        new SelectListItem(){Text = ".wiki.br", Value=".wiki.br"},
                        new SelectListItem(){Text = ".adm.br", Value=".adm.br"},
                        new SelectListItem(){Text = ".adv.br", Value=".adv.br"},
                        new SelectListItem(){Text = ".agr.br", Value=".agr.br"},
                        new SelectListItem(){Text = ".am.br", Value=".am.br"}
                })
    <input type="image" name="avancar" value="avancar" src="../../Content/Imagens/botao/avancar.gif" /><br/><input type="image" name="voltar" value="voltar" src="../../Content/Imagens/botao/voltar.gif" /><br/>}<br/><br/>
    

     

     

    Quando o usuario clicar em avançar é enviado via Ajax um post com os dados do modelo, neste caso se o dominio e o prefixo estão preenchidos vai para a Partial2 caso contrario volta para a partial1 com os erros.

    Controller e model:

     

     public ActionResult TesteAjax(AssinaturaModel model)
        {
          if (Request.Form.AllKeys.Contains("voltar.x"))
          {
            return PartialView("_PartialPage1", model);
          }
          else if (Request.Form.AllKeys.Contains("avancar.x"))
          {
            if (ModelState.IsValid)
            {
              //aqui eu valido o dominio
              if (!model.ValidarDominio())
                ModelState.AddModelError("", "este dominio já possui um cadastro com a nossa empresa");
              else
                return PartialView("_PartialPage2", model);
            }
            else
            {
              return PartialView("_PartialPage1", model);
              //ModelState.AddModelError("", "algo esta errado");
    
            }
          }
          return PartialView("_PartialPage1", model);
        }

     public class AssinaturaModel
      {
        [Required(ErrorMessage = "Digite um dominio")]
        //[RegularExpression("")
        public string Dominio { get; set; }
    
        [Required(ErrorMessage = "selecione uma Extensao")]
        public string Extensao { get; set; }
    
        //[Required(ErrorMessage = "selecione uma opcaoRegistro")]
        public string OpcoesRegistro { get; set; }
    
        public int Tipo { get; set; }
    
    
        public bool ValidarDominio()
        {
          using (Entities contex = new Entities())
          {
            return (contex.dominio.Where(cis => cis.Nome == this.Dominio + this.Extensao).Count() == 0);
          }
        }
      }
    

    O que acontece é que:

    Dando erro no model quando eu volto para a Partial1 a ViewBag está vazia

    Quando eu vou para a Partial2 e preencho ou outros dados, na volta do submit os dados de Dominio e Extensão estão nulos.

     

    segue o codigo do Partial2

     

    @model Models.AssinaturaModel
    <h1>
      @ViewBag.TituloPagina
    </h1>
    
      @using (Ajax.BeginForm("TesteAjax", new AjaxOptions()
          {
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = @ViewBag.DivModalId
          }))
      {
        <button class="close">
          Close
        </button>
    
    @Html.RadioButtonFor(model => model.OpcoesRegistro, true) Desejo que a registrem o domínio para mim. Será cobrada uma taxa anual de R$ 15,00 pelo registro
                  de seu domínio.<br />
                  @Html.RadioButtonFor(model => model.OpcoesRegistro, true) Eu mesmo vou registrar
                  este domínio ou registrarei com outra empresa.<br />
    
    
    <input type="image" name="avancar" value="avancar" src="../../Content/Imagens/botao/avancar.gif" />
    <input type="image" name="voltar" value="voltar" src="../../Content/Imagens/botao/voltar.gif" />
    }

     

    Fico no Aguardo...

    quarta-feira, 4 de maio de 2011 15:40

Respostas

  • Voce pode usar o método TryUpdateModel, assim:

    public ActionResult Parte3(AssinaturaModel model)
    {
      var assinaturaTemp = Session["assinatura"] as AssinaturaModel;
      TryUpdateModel(assinaturaTemp);
      //Resto do seu codigo
    

    O método TryUpdateModel copia os dados do model, e passa para a Session, dessa forma você não precisa fazer de um a um.


    Contato: alberto.monteiro@live.com - Se ajudei, marca como útil.
    Twitter: Me siga!!
    Blog:http://albertomonteiro.net/

    • Sugerido como Resposta Alberto Monteiro terça-feira, 10 de maio de 2011 20:31
    • Marcado como Resposta Fernando Mondo quarta-feira, 11 de maio de 2011 12:05
    • Não Marcado como Resposta Fernando Mondo quinta-feira, 12 de maio de 2011 13:22
    • Marcado como Resposta Fernando Mondo quinta-feira, 12 de maio de 2011 19:02
    terça-feira, 10 de maio de 2011 20:31

Todas as Respostas

  • Use Session, ViewBag so dura por um "ciclo"

    Contato: alberto.monteiro@live.com - Se ajudei, marca como útil.
    Twitter: Me siga!!
    Blog:http://albertomonteiro.net/

    quarta-feira, 4 de maio de 2011 16:31
  • descupe a ignorancia, mas eu pensei que só poderia usar session com classes statics, vou fazer uns testes e direi se consegui

     

    Obrigado

    quarta-feira, 4 de maio de 2011 17:15
  • Não , não, Session é uma implementação "parecido" com um Dictionary<string,object>
    Você pode usar ela para gravar qualquer coisa de qualquer tipo :)

    Contato: alberto.monteiro@live.com - Se ajudei, marca como útil.
    Twitter: Me siga!!
    Blog:http://albertomonteiro.net/

    quarta-feira, 4 de maio de 2011 17:48
  • Demorou mas eu voltei...

     

    eu acabei fazendo assim:

    public AssinaturaModel assinaturaModel
            {
                get
                {
                    if (Session["assinatura"] == null)
                        Session["assinatura"] = new AssinaturaModel();

                    return (AssinaturaModel)Session["assinatura"];

                }
                set { Session["assinatura"] = value; }
            }

     

     public ActionResult Parte1(AssinaturaModel model)
            {
                ViewBag.DivModalId = "hospedagem";
                ViewBag.TituloPagina = "Assinatura de Hospedagem de Site";
                ViewBag.InformeDominio = "Informe o nome do domínio que deseja";
                ViewBag.PrefixoDominio = "www.";

                assinaturaModel.Dominio = model.Dominio;
                assinaturaModel.Extensao = model.Extensao;
                assinaturaModel.DivModalId = model.DivModalId;

    ...

    }

     public ActionResult Parte2(AssinaturaModel model)
            {
                assinaturaModel.OpcoesRegistro = model.OpcoesRegistro;
    ...

    }

     public ActionResult Parte3(AssinaturaModel model)
            {
                    assinaturaModel.IdPlano = model.IdPlano;
                    assinaturaModel.Periodicidade = model.Periodicidade;
                    assinaturaModel.CadastroSiteDeBusca = model.CadastroSiteDeBusca;
    ...

    }

     

    mas dai o modelo que retorna no post logicamente nao vem com todos os dados preenchidos e eu tenho que guardar um por um no assinaturaModel que está na session...

    então eu nao posso usar o modelState.IsValid para verificar se está ok

     

    Desculpe a perguntas idiotas mas tem uma soluçao melhor?

     

     

     

    terça-feira, 10 de maio de 2011 18:00
  • Voce pode usar o método TryUpdateModel, assim:

    public ActionResult Parte3(AssinaturaModel model)
    {
      var assinaturaTemp = Session["assinatura"] as AssinaturaModel;
      TryUpdateModel(assinaturaTemp);
      //Resto do seu codigo
    

    O método TryUpdateModel copia os dados do model, e passa para a Session, dessa forma você não precisa fazer de um a um.


    Contato: alberto.monteiro@live.com - Se ajudei, marca como útil.
    Twitter: Me siga!!
    Blog:http://albertomonteiro.net/

    • Sugerido como Resposta Alberto Monteiro terça-feira, 10 de maio de 2011 20:31
    • Marcado como Resposta Fernando Mondo quarta-feira, 11 de maio de 2011 12:05
    • Não Marcado como Resposta Fernando Mondo quinta-feira, 12 de maio de 2011 13:22
    • Marcado como Resposta Fernando Mondo quinta-feira, 12 de maio de 2011 19:02
    terça-feira, 10 de maio de 2011 20:31
  • Obrigado Alberto, ta me dando uma baita mão...

    Porem....

     

    TryUpdateModel(assinaturaTemp);
    ou
    assinaturaModel.IdPlano = model.IdPlano; assinaturaModel.Periodicidade = model.Periodicidade; assinaturaModel.CadastroSiteDeBusca = model.CadastroSiteDeBusca;


    ajuda no fato de escrever menos linhas, mas o modelState.IsValid continua retornando false.

    • Editado Fernando Mondo quarta-feira, 11 de maio de 2011 17:08 Achei que tinha resolvido mas o ModelState retorna False
    quarta-feira, 11 de maio de 2011 12:06
  • O mode state é de toda a entidade, então aconselho a você validar manualmente da etapa


    Contato: alberto.monteiro@live.com - Se ajudei, marca como útil.
    Twitter: Me siga!!
    Blog:http://albertomonteiro.net/

    quinta-feira, 12 de maio de 2011 23:07
  • resolvi este problema com o seguinte filter

     

     public class ValidateOnlyIncomingValuesAttribute : ActionFilterAttribute
            {
                public override void OnActionExecuting(ActionExecutingContext filterContext)
                {
                    var modelState = filterContext.Controller.ViewData.ModelState;
                    var valueProvider = filterContext.Controller.ValueProvider;

                    var keysWithNoIncomingValue = modelState.Keys.Where(x => !valueProvider.ContainsPrefix(x));
                    foreach (var key in keysWithNoIncomingValue)
                        modelState[key].Errors.Clear();
                }
            }

     


    • Editado Fernando Mondo sexta-feira, 13 de maio de 2011 12:32 erro de digitação
    sexta-feira, 13 de maio de 2011 12:18