Tuesday, July 1, 2014

get basic CRUD working at a DevExpress GridView in an MVC project

Following up on what I started this weekend I have gotten the canned CRUD stuff working within my application. I only really changed two files. The first one was _Layout.cshtml. I both stripped out a lot of the noise to dumb it down and I added some must have scripts which were not there by default. It now just looks like this:

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width" />
   <title>@ViewBag.Title</title>
   @Styles.Render("~/Content/css")
   @Scripts.Render("~/bundles/modernizr")
   @Scripts.Render("~/bundles/jquery")
   @Html.DevExpress().GetScripts(
      new Script { ExtensionSuite = ExtensionSuite.NavigationAndLayout },
      new Script { ExtensionSuite = ExtensionSuite.HtmlEditor },
      new Script { ExtensionSuite = ExtensionSuite.GridView },
      new Script { ExtensionSuite = ExtensionSuite.Editors },
      new Script { ExtensionSuite = ExtensionSuite.Scheduler }
   )
</head>
   <body>
      <div style="margin: 0 auto; width: 90%;">
         @RenderBody()   
      </div>
   </body>
</html>

 
 

HomeController really changed. It now looks like this:

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using DevExpress.Web.Mvc;
using DummyDevExpressApplication.Models;
using DummyDevExpressApplication.Utilities;
namespace DummyDevExpressApplication.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         return View();
      }
      
      [ValidateInput(false)]
      public ActionResult GridViewPartial()
      {
         if (DevExpressHelper.IsCallback)
         {
            if (DevExpressHelper.CallbackArgument.Contains("STARTEDIT"))
            {
               string[] bits = DevExpressHelper.CallbackArgument.Split('|');
               Session["scope"] = bits[bits.Length - 1].Split(';')[0];
            }
         }
         return PartialView("_GridViewPartial", getPlanets());
      }
      
      [HttpPost, ValidateInput(false)]
      public ActionResult GridViewPartialAddNew([ModelBinder(typeof
            (DevExpressEditorsBinder))] Planet addition)
      {
         if (addition != null)
         {
            List<Planet> p = getPlanets();
            p.Add(addition);
            Session["planets"] = p.OrderBy(x =>
                  x.ClosestAstronomicalUnitDistanceFromSun).ToList();
         }
         return PartialView("_GridViewPartial", getPlanets());
      }
      
      [HttpPost, ValidateInput(false)]
      public ActionResult GridViewPartialUpdate([ModelBinder(typeof
            (DevExpressEditorsBinder))] Planet alteration)
      {
         string scope = Session["scope"] as string;
         if (scope != null && alteration != null)
         {
            List<Planet> p = getPlanets();
            for (int i = 0; i < p.Count; i++) if (p[i].Name == scope) p[i] = alteration;
            Session["planets"] = p.OrderBy(x =>
                  x.ClosestAstronomicalUnitDistanceFromSun).ToList();
         }
         return PartialView("_GridViewPartial", getPlanets());
      }
      
      [HttpPost, ValidateInput(false)]
      public ActionResult GridViewPartialDelete(string Name)
      {
         if (Name != null)
         {
            Session["planets"] = getPlanets().Where(planet => planet.Name
                  != Name).ToList();
         }
         return PartialView("_GridViewPartial", getPlanets());
      }
      
      private List<Planet> getPlanets()
      {
         List<Planet> planets = Session["planets"] as List<Planet>;
         if (planets == null)
         {
            planets = PlanetFactory.GetPlanets();
            Session["planets"] = planets;
         }
         planets = Session["planets"] as List<Planet>;
         return planets;
      }
   }
}

 
 

The GridViewPartialDelete previously had a System.Int32 variable named "Line" in it and Visual Studio, or perhaps JetBrains ReSharper, put a squiggly blue line under the word and when one moused over it some text popped up reading "Name 'Line' does not match rule 'Parameters'. Suggested name is 'line'." This was one of the more confusing things I bumped into. Why was there a "bad" name? It turns out that Line is a property on Antlr.Runtime.ICharStream which was the original model I picked through circumstance. In order to make the unique key value carry over into the method signature when this method was hit, I had to use the name of the property for the unique key (Name on Planet) as the name of this variable. What else was challeging? What if we are to edit a planet while changing its name which is its unique id? Well, we would need to know what planet id we just changed, correct? That won't be hanging off the alteration variable in the GridViewPartialUpdate method's signature. There is a callback event on any GridView and it should get triggered on the C# side whenever one clicks the Edit, New, or Delete buttons (links). It will happen, in the case of an Edit button click, just before a form for editing an item such as this is displayed:

 
 

Here, one may look to DevExpressHelper.CallbackArgument to get a string of gunk with pipe-separated notes on what is going on. The note at the very end of the string is the unique key for the item to be edited in the case of an edit. Also in the case of an edit STARTEDIT appears midway within all of the nastiness. An example of what is in DevExpressHelper.CallbackArgument is:

c0:KV|88;['Mercury','Venus','Earth','Mars','Ceres','Jupiter','Saturn','Uranus','Neptune','Pluto'];
      GB|18;9|STARTEDIT5|Earth;

 
 

That is really all I have to show off in this blog posting. I will mention that while I was figuring this out that I also figured out how to wire up client-side events. One could do so by adding a line like this to _GridViewPartial.cshtml:

settings.ClientSideEvents.BeginCallback = "BeforeCallback";

 
 

This means there has to be a "BeforeCallback" in JavaScript like so:

function BeforeCallback(s, e) {
   console.log(s);
   console.log(e);
}

 
 

I made a file for this stuff called solarsystemscripts.js and I referenced it in _Layout.cshtml like so:

<script src="/Scripts/solarsystemscripts.js"></script>

 
 

Having said that, I couldn't really find something spiffy to do with "BeforeCallback" though I did confirm that it would run before the if (DevExpressHelper.IsCallback) check on the C# side. My stylesheet styling still needs a lot of work, huh?

No comments:

Post a Comment