title: How to simplify my statefull interlaced modal dialogs in ASP.NET MVC
body: <p>I need keep state on many-to-many modal dialogs in a <a href="http://en.wikipedia.org/wiki/Progressive_enhancement" rel="nofollow noreferrer">progressive enhancement</a> way in ASP.NET MVC project.<br>
  In my code when javascript is disabled modal dialog turn in navigation to another page and return, but when javascript is enabled the dialog open as a jquery modal dialog, its OK.<br>
  Im using <a href="https://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mvc-framework/7111222#7111222">this</a> method to select action from click on view.<br>
  The code below show one master page calling detail page, there is the view and the controller. There is only one master calling one detail dialog but i have another views/controllers where one master can call many different detail dialog and sometimes one dialog can behave like a master page and call another dialog nested. Everything must keep state between calls.</p>
  
  <p><strong>The problem is</strong> its very complex, there is lots of code to keep state and manage dialog, i need repeat the same javascript and controller code everywhere, i wish some way to simplify it.<br>
  In view side need turn scripts generic to move to separate .js file and keep on view a minimum of javascript.<br>
  In controller side i search a lot for some generic way to do it like a filter or custom binder but cant find. </p>
  
  <p>CONTROLLER</p>
  
  <pre><code>//######################################################################  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.Mvc;
  using HYW.Models;
  using HYW.Helpers;
  
  namespace HYW.Controllers
  {
      public class TesteController : Controller
      {
          //-------
          private object getValue(string key)
          {
              return Session[key];
          }
          private void setValue(string key, object value)
          {
              Session[key] = value;
              if (value == null) { Session.Remove(key); }
          }
          //-------
          [AcceptVerbs(HttpVerbs.Get)]
          public ActionResult createitem()
          {
              setValue("item", null);
              setValue("detail", null);
              return View("item");
          }
          //-------
          [HttpPost]
          [ValidateAntiForgeryToken]
          [HlpFltButtonSelector(Name = "action", Argument = "saveitem")]
          public ActionResult saveitem(testePg01 model)
          {
              ModelState.Clear();
              return View("item", model);
          }
          //-------
          [HttpGet]
          public ActionResult opendialog()
          {
              ModelState.Clear();            
              testePg02 p2 = (testePg02)getValue("detail");
              if (p2 == null) { p2 = new testePg02(); }
              return View("detail", p2);
          }
          //-------
          [HttpPost]
          [ValidateAntiForgeryToken]
          [HlpFltButtonSelector(Name = "action", Argument = "opendialog")]
          public ActionResult opendialog(testePg01 model)
          {
              ModelState.Clear();
              setValue("item", model);
              testePg02 p2 = (testePg02)getValue("detail");
              if (p2 == null) { p2 = new testePg02(); }            
              return View("detail", p2);
          }
          //-------
          [HttpPost]
          [ValidateAntiForgeryToken]
          [HlpFltButtonSelector(Name = "action", Argument = "savedialog")]
          public ActionResult savedialog(testePg02 model)
          {
              ModelState.Clear();
              setValue("detail", model);
              testePg01 p1 = (testePg01)getValue("item");            
              if (p1 == null) { p1 = new testePg01(); }
              p1.p02 = model;            
              return View("item", p1);
          }
          //-------
          [HttpPost]
          [ValidateAntiForgeryToken]
          [HlpFltButtonSelector(Name = "action", Argument = "canceldialog")]
          public ActionResult canceldialog(testePg02 model)
          {
              ModelState.Clear();
              testePg01 p1 = (testePg01)getValue("item");
              setValue("detail", null);
              if (p1 == null) { p1 = new testePg01(); }
              p1.p02 = null;
              return View("item", p1);
          }
          //-------
      }
  }
  //######################################################################  
  </code></pre>
  
  <p>VIEW</p>
  
  <pre><code>@model HYW.Models.testePg01
  @{
      ViewBag.Title = "ITEM";
  }
  &lt;script type="text/javascript"&gt;
      //-------------------------------------------------
      var url_trg = '@Url.Content("~/Teste/opendialog")';
      var url_prl = '@Url.Content("~/Images/waitplease.gif")';
      //-------------------------------------------------
      function onloadpartial() {
          configDetailDialog(url_trg, "#tempcontent", "section[id='main']", "Detail", "#opendialog");
      }
      //-------------------------------------------------
      function configDetailDialog(trgurl, containerselector, contentselector, dlgtitle, buttonselector) {
          //-------
          $(document).ajaxError(
              function (event, jqXHR, ajaxSettings, thrownError) {
                  alert('[event:' + event + '], ' +
                          '[jqXHR:' + jqXHR + '], ' +
                          '[jqXHR_STATUS:' + jqXHR.status + '], ' + 
                          '[ajaxSettings:' + ajaxSettings + '], ' +
                          '[thrownError:' + thrownError + '])');
              });
          //-------
          $.ajaxSetup({ cache: false });
          //-------
          $(buttonselector).click(function (event) {
              event.preventDefault();
              openAjaxDialog(trgurl, containerselector, contentselector, dlgtitle);
          });
          //-------
      }
      //-------------------------------------------------
      function openAjaxDialog(trgurl, containerselector, contentselector, dlgtitle) {
          $.ajax({
              type: 'GET',
              url: trgurl,
              context: document.body,
              success: function (data) {
                  var dlg = $(data).find(contentselector);
                  $('#dlgdetail').remove();
                  $(containerselector).append("&lt;div id='dlgdetail'/&gt;");
                  $('#dlgdetail').append(dlg);
                  $('#dlgdetail')
                      .css("border", "solid")
                      .dialog({
                          autoOpen: true,
                          modal: true,
                          title: dlgtitle,
                          open: function () {
                              configDetailDialog();
                          },
                          close: function (event, ui) {
                              $('#dlgdetail').remove();
                          }
                      })
                      .find("form").submit(function (event) {
                          alert('clicou ' + event);
                          var form = $(this);
                          var faction = "http://" + window.location.host + trgurl;
                          var fdata = form.serialize() + "&amp;action:savedialog=savedialog";
                          $.ajax({                            
                              type: "POST",
                              url: faction,
                              data: fdata,
                              success: function (result) {
                                  alert(result);
                              }
                          });
                          event.preventDefault();
                          $('#dlgdetail').dialog('close');
                      });
              }
          });
      }
      //-------------------------------------------------
  &lt;/script&gt;
  &lt;div id='tempcontent'&gt;
  &lt;/div&gt;
  &lt;div id="formcontent"&gt;
      @Html.ValidationSummary(true, "Erro na pagina.")
      @using (Html.BeginForm())
      {
          @Html.AntiForgeryToken()
          &lt;div&gt;
              &lt;fieldset&gt;
                  &lt;legend&gt;Item&lt;/legend&gt;
                  &lt;div class="editor-label"&gt;
                      @Html.LabelFor(m =&gt; m.p01campo01)
                  &lt;/div&gt;
                  &lt;div class="editor-field"&gt;
                      @Html.TextBoxFor(m =&gt; m.p01campo01)
                      @Html.ValidationMessageFor(m =&gt; m.p01campo01)
                  &lt;/div&gt;
                  &lt;div class="editor-label"&gt;
                      @Html.LabelFor(m =&gt; m.p01campo02)
                  &lt;/div&gt;
                  &lt;div class="editor-field"&gt;
                      @Html.TextBoxFor(m =&gt; m.p01campo02)
                      @Html.ValidationMessageFor(m =&gt; m.p01campo02)
                  &lt;/div&gt;
                  &lt;p&gt;
                      &lt;input type="submit" style="background: #ffffff url('@Url.Content("~/Images/img01.png")')" value="opendialog" name="action:opendialog" id="opendialog" /&gt;
                      &lt;input type="submit" style="background: #ffffff url('@Url.Content("~/Images/img02.png")')" value="saveitem" name="action:saveitem" id="action:saveitem" /&gt;
                  &lt;/p&gt;
              &lt;/fieldset&gt;
          &lt;/div&gt;
      }
  &lt;/div&gt;
  </code></pre>