Tuesday, November 16, 2010

Contextual View - graceful degrading put still wizbangy!

Ok, So in my MyDojo project my I've got a really simple view to create a new school. Controller method looks like so.
   1:   public ActionResult Create()
   2:         {
   3:             var model = new CreateSchoolForm();
   4:             return View(model);
   5:         }



Really really simple... I typically start with UIs like this, then our UI engineers at work come and say "Oh, we wanna do this via ajax! Can you just change that to a Json method? Then we end up with 2 methods.

   1:   public ActionResult CreateAjax()
   2:         {
   3:             var model = new CreateSchoolForm();
   4:             return Json(model,JsonRequestBehavior.AllowGet);
   5:         }

So on the actual view, they'll actually set the url on a link to the Create action on the controller, but use Jquery to override the onclick on to just make an Ajax get to Create Ajax.

Something like this...


   1:   <script>
   2:          $(document).ready(function () {
   3:              $('#makeAjaxRequest').click(function (ev) {
   4:                  $.get(this.href.replace('Create','CreateAjax'), null, function (data) { alert(data); });
   5:                  ev.returnVal = false;
   6:                  return false;
   7:              });
   8:          });
   9:      </script>



I hate having 2 methods that do the exact same thing, and that the url that I gave them won't work (they've gotta replace the url for ajax). So sometimes I'll do this.

   1:   public ActionResult Create()
   2:         {
   3:             var model = new CreateSchoolForm();
   4:              return _request.IsAjaxRequest() ? (ActionResult)Json(model) : (ActionResult)View(model);
   5:         }

Ok, whatever... Simple enough, but I'm sick of forking code like that all the darn time. So I just added this to my abstract base controller.

   1:  protected ActionResult ContextualView(object model, string viewName=null)
   2:          {
   3:              if(Request.IsAjaxRequest())
   4:              {
   5:                  return Json(model, JsonRequestBehavior.AllowGet);    
   6:              }
   7:              return String.IsNullOrEmpty(viewName) ? View(model) : View(viewName, model);
   8:          }
 
Works like a charm!
 
Need to get this puppy encapsulated into it's own ActionResult class, that way we could use it with without inheriting the base controller class. Yeah, one day I'll do that. It just won't be today.

No comments:

Post a Comment