Programming By A Tool Do you program in the C#? Yes? How about the ASP.Net?



8Sep/0912

ASP.Net MVC: Upload Image to Database and Show Image “Dynamically” Using a View

- Sean

Oddly enough this came about from me wanting to do this, figuring it out, and then deciding not to bother with it. So there's a possibility this will happen to you too. Well that's not completely true. The first half where I was uploading and showing from a database, but showing an image through a view to mimic the .ashx functionality of WebForms is still pretty useful.

Saving the Image

First off, here's the look of the table:

Table

So pretty simple table. Most important parts are the ImageData and ContentType. Why? Well let's look at the action needed to save the image:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload(PhotoForSingleItem photo)
{
  //PhotoForSingleItem is just a class that has properties
  // Name and Alternate text.  I use strongly typed Views and Actions
  //  because I'm not a fan of using string to get the posted data from the
  //  FormCollection.  That just seems ugly and unreliable to me.

  //PhotoViewImage is just a Entityframework class that has
  // String Name, String AlternateText, Byte[] ActualImage,
  //  and String ContentType
  PhotoViewImage newImage = new PhotoViewImage();
  HttpPostedFileBase file = Request.Files["OriginalLocation"];
  newImage.Name = photo.Name;
  newImage.Alt = photo.AlternateText;

  //Here's where the ContentType column comes in handy.  By saving
  //  this to the database, it makes it infinitely easier to get it back
  //  later when trying to show the image.
  newImage.ContentType = file.ContentType;

  Int32 length = file.ContentLength;
  //This may seem odd, but the fun part is that if
  //  I didn't have a temp image to read into, I would
  //  get memory issues for some reason.  Something to do
  //  with reading straight into the object's ActualImage property.
  byte[] tempImage = new byte[length];
  file.InputStream.Read(tempImage, 0, length);
  newImage.ActualImage = tempImage ;

  newImage.Save();

  //This part is completely optional.  You could redirect on success
  // or handle errors ect.  Just wanted to keep this simple for the example.
  return View();
}

And here's the mark up to get this ball a rollin':

<form method="post" enctype="multipart/form-data" action="Photo/Upload">
  <div>
    <span>
     Name:
   </span>
   <span>
     <input type="text" id="Name" name="Name" />
   </span>
  </div>
  <div>
    <span>
      Alternate Text:
    </span>
    <span>
     <input type="text" id="AlternateText" name="AlternateText" />
    </span>
  </div>
  <div>
    <span>
      Image
    </span>
    <span>
      <input type="file" id="OriginalLocation" name="OriginalLocation" />
    </span>
  </div>
  <div>
    <input type="submit" value="Upload" />
  </div>
</form>

Biggest thing to notice in the markup is the enctype="multipart/form-data". This is a must to upload images. It was something I was missing originally and annoyed the hell out of me.

Showing the Image

So now that we have a we to upload the image, how the hell do you use it? Well that's not too hard. It just involves a new type of result, an action, and an img element.

So the first thing you need is an image result, and in using my superior intellect I came up with such a thing. And by superior intellect I mean I used StackOverflow. Oddly enough though, it's actually the second post that I got it from and I changed it a little. However, it was very useful.

using System.Web;
using System.Web.Mvc;
using System.IO;

public class ImageResult : ActionResult
{
  public String ContentType { get; set; }
  public byte[] ImageBytes { get; set; }
  public String SourceFilename { get; set; }

  //This is used for times where you have a physical location
  public ImageResult(String sourceFilename, String contentType)
  {
    SourceFilename = sourceFilename;
    ContentType = contentType;
  }

  //This is used for when you have the actual image in byte form
  //  which is more important for this post.
  public ImageResult(byte[] sourceStream, String contentType)
  {
    ImageBytes = sourceStream;
    ContentType = contentType;
  }

  public override void ExecuteResult(ControllerContext context)
  {
    var response = context.HttpContext.Response;
    response.Clear();
    response.Cache.SetCacheability(HttpCacheability.NoCache);
    response.ContentType = ContentType;

    //Check to see if this is done from bytes or physical location
    //  If you're really paranoid you could set a true/false flag in
    //  the constructor.
    if (ImageBytes != null)
    {
      var stream = new MemoryStream(ImageBytes);
      stream.WriteTo(response.OutputStream);
      stream.Dispose();
    }
    else
    {
      response.TransmitFile(SourceFilename);
    }
  }
}

And here's how you use the actual result.

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult ShowPhoto(Int32 id)
{
  //This is my method for getting the image information
  // including the image byte array from the image column in
  // a database.
  PhotoViewImage image = PhotoViewImage.GetById(id);
  //As you can see the use is stupid simple.  Just get the image bytes and the
  //  saved content type.  See this is where the contentType comes in real handy.
  ImageResult result = new ImageResult(image.ActualImage, image.ContentType);

  return result;
}

And the markup would go a little sumthin' like dis:

  <img src="/Photo/ShowPhoto/1" alt="" />

And now you too can upload an image to a database, show it, and then decide just to physically host the images anyway. Next post will be about how to use this with jQuery and asynchronously. I bet you can't wait!

Tagged as: , 12 Comments
11Aug/095

jQuery Slide Menu… Another Cause I Can Experiment

- Sean

So for no real reason at all I had it in my mind that I wanted to make a horizontal menu with jQuery that would work like that weird scrolling menu thing that Macs have. No idea what it's called. So basically I don't need it, have no reason for it, but damnit I'm going to make it happen and I did it with only 3 things from jquery.com; 1.3.2, ui 1.7.2, and jquery.timer . Now this is still rough in the sense it has no real styling but it works tried and true functionality wise.

The main idea is that there are two scroll arrows, one on each side, and X amount of divs. Now at the start, a certain amount of divs are hidden (global variable). When hovering over the left pager, for example, it causes one on the right to hide while one on the left appears giving the feeling of the items sliding.

EXAMPLE HERE!!11

The markup is simple, a holder with x number of elements that are "menuitems" and two pager divs.

<div class="mainHolder">
  <div class="leftPager green floatLeft"><</div>
  <div class="menuItem floatLeft blue">1</div>
  <div class="menuItem floatLeft red">2</div>
  <div class="menuItem floatLeft yellow">3</div>
  <div class="menuItem floatLeft blue">4</div>
  <div class="menuItem floatLeft red">5</div>
  <div class="menuItem floatLeft yellow">6</div>
  <div class="menuItem floatLeft blue">7</div>
  <div class="rightPager green floatLeft">></div>
</div>

I think from the classes you can tell what you need to know about them.

First thing we need from jQuery is methods to find various elements in the container when paging.

//When using the left pager, it's important to find the first visible element
//then find the item before it so that it can be shown.
function getNextInLineBack(menuItems)
{
  var oneBefore = null;

  for (var loopCounter = 0; loopCounter < menuItems.length; loopCounter++)
  {
    if(jQuery(menuItems[loopCounter]).is(":visible") && loopCounter > 0)
    {
      oneBefore = jQuery(menuItems[loopCounter - 1 ]);
      break;
    }
  }

  return oneBefore;
}

//Find the first visible element from the beginning.
//This will be needed when paging right since it will have to be hidden
function getFirstVisible(menuItems)
{
  var firstVisible = null;

  for (var loopCounter = 0; loopCounter < menuItems.length; loopCounter++)
  {
    if(jQuery(menuItems[loopCounter]).is(":visible") && loopCounter < menuItems.length - maximumToShow)
    {
        firstVisible = menuItems[loopCounter];
        break;
    }
  }
  return firstVisible;
} 

//Get the last possible visible item
//If the item is in an index less than the maximum number to show, then null is returned since there has to be no more or less than the maximumToShow.
function getLastVisible(menuItems)
{
  var lastVisible = null;
  for (var loopCounter = menuItems.length - 1; loopCounter > maximumToShow - 1; loopCounter--)
  {
    if(jQuery(menuItems[loopCounter]).is(":visible"))
    {
      lastVisible = menuItems[loopCounter];
      break;
    }
  }

  return lastVisible;
}

//Find the first visible from the end
//Pretty simple, this will be important when paging left since this
//will be the next item to be hidden
function getNextInLineFront(menuItems)
{
  var lastOne = null;

  for (var loopCounter = menuItems.length-1; loopCounter > -1; loopCounter--)
  {
    if(jQuery(menuItems[loopCounter]).is(":visible"))
    {
      lastOne = menuItems[loopCounter + 1];
      break;
    }
  }

  return lastOne;
}

Next is a method that is just used to stop having to repeat the same thing over and over when needing a list of all the menu items.

function getMenuItems(mainHolder)
{
  return jQuery(mainHolder).children(".menuItem");
}

Next is the method to handle what item to show and what item to hide when the pager has the mouse over it. Instead of having methods for the right and left pager, I just ended up having the methods for finding the item to hide and show sent through as parameters.

function showHideOnHover(pager, timer, getHideMethod, getShowMethod)
{
  //This is just candy for changing the color of the pager when the mouse
  //is over it
  jQuery(pager).removeClass("green");
  jQuery(pager).addClass("orange");

  //Remember those methods I passed through, well here they
  //are in use.  I'm using them to get the item to hide and the item
  //to show along with the list of items.
  var menuItems = getMenuItems(jQuery(pager).parent());
  var hide = getHideMethod(menuItems);
  var show = getShowMethod(menuItems);

  //If neither is null, then go ahead and show/hide
  //If either one is null, something isn't right and the timer
  //needs to be stopped.... timer??  Well I'll get to that
  //next.
  if(show != null && hide != null)
  {
    jQuery(hide).hide( "slide", { direction: "right" } , 0);
    jQuery(show).show( "slide", { direction: "left" } , 100);
  }
  else
  {
    timer.stop();
  }
}

Now for the method above the last one, this one involves the timer passed in the last method. This method actually sets the mouseover/mouseout events (aka hover). When mouseover, the timer is created and the showHideOnHover method is called every 500 units, that's we'll call tools, (Not sure how much that is, seems like a half second) after the first time it's called. On mouseout, the timer is stopped, nulled out, and the pager changes it's color.

function setPager(pager, hideMethod, showMethod)
{
  //Making the timer variable "global" to the events so that I know
  //I have the same timer for both mouseover and mouseout.
  var newTimer;
  pager.hover
  (
    //Mouseover method
    function()
    {
      var first = true;
      //This sets the timer, consequently starting the method for the first time.
      //Why timer doesn't have a start method I don't know.  Ask jquery.com.
      //The first thing is just so that the first time around it runs right away,
      //then each call afterwards comes every 500 tools.
      newTimer = jQuery.timer
                      (
                         0, //First time through, runs after 0 tools.
                         function(timer)
                         {
                           showHideOnHover(pager, timer, hideMethod, showMethod);
                           //If this is the first time through, reset
                           //timer to run every 500 tools.
                           if(first)
                           {
                              timer.reset(500);
                              first = false;
                           }
                         }
                       );
    },

    //Mouseout method
    function()
    {
      //mouse is done, stop the timer
      newTimer.stop();
      newTimer = null;
      jQuery(pager).addClass("green");
      jQuery(pager).removeClass("orange")
    }
  );
}

Now for the method above the one... above. This is used to set the children of the passed in holder.

function setChildrenDivs(mainHolder)
{
  //Get the items for the holder
  var menuItems = getMenuItems(mainHolder);

  //Hide all the items after the first X items (maximumToShow)
  for (var loopCounter = 0; loopCounter < menuItems.length; loopCounter++)
  {
    if(loopCounter > maximumToShow - 1)
    {
      jQuery(menuItems[loopCounter]).hide();
    }
  }

  //set the pagers.
  setPager(jQuery(mainHolder).children(".leftPager"), getLastVisible, getNextInLineBack);
  setPager(jQuery(mainHolder).children(".rightPager"),getFirstVisible, getNextInLineFront);
}

FINALLY THE END! This is the document.ready method used to set this whole joke in motion. maximumToShow is just how many items to show at a time and is global.

var maximumToShow = 5;

jQuery(document).ready
(
  function()
  {
    //Find every holder on the page and set everything in motion.
    var mainHolders = jQuery(".mainHolder");
    for (var loopCounter = 0; loopCounter < mainHolders.length; loopCounter++)
    {
      setChildrenDivs(mainHolders[loopCounter]);
    }
  }
);

Why the timer? If you haven't figured that out yet, well it's because I had issues with how to get the menu to keep doing it's thing as long as the user had his/her mouse over a pager. I didn't want this to be a click menu because, let's be honest, that would be much easier. So as is, the timer is started the moment the mouse is over a pager and hides/shows an item. Then every 500 tools the mouse is over the pager, it continues the hide/show until it runs out of items to show/hide. (End of the list)

Uhg that's annoying to type out even with cut and paste so I will host it here.

I suppose the next part of this would have the items blow up or something when hovering over them but that should be much easier than this was.

Tagged as: , , 5 Comments
6Aug/090

ASP.NET MVC: Attributes and Semi Dynamic Check for Request Parameters

- Sean

If I were self involved I would say something silly like IN THIS AWESOME POST but I'm not. However in this post that is awesome I gave some examples of how to use attributes to set defaults or just check to see if an incoming id could be matched to a record somewhere... Sorry lost my track of thought. Watching the begining of Transformers... You know the part where it could have been good.

Anyway, I figured I'd add another debatable use for an attribute, the CheckForGivenRequest one. Basically in the other post I had something that was specific it was checking for, this is used if you are checking for a request parameter but you don't want to make an attribute for each and every one of them.

  //This is so you can use it many times on the same method
  //I know, I know... duh
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
  public sealed class CheckForGivenRequestAttribute : ActionFilterAttribute
  {
    //The constructor to set what should be looked for
    //Default amount is what it should be set if not there
    public CheckForGivenRequestAttribute(String requestParameterName, Object defaultAmount)
    {
      DefaultAmount = defaultAmount;
      RequestParameterName = requestParameterName;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
      base.OnActionExecuting(filterContext);
      //Check the extra request parameters (ie &someId=1) for if it exists
      //If it doesn't exist, then add it
      if (!filterContext.ActionParameters.ContainsKey(RequestParameterName))
      {
        filterContext.ActionParameters.Add(RequestParameterName, null);
      }

      //If it's null set to the default
      filterContext.ActionParameters[RequestParameterName] =
         filterContext.ActionParameters[RequestParameterName] ?? DefaultAmount;
    }

    //Just the properties, nothing to see here.  Go away...
    private Object DefaultAmount { get; set; }
    private String RequestParameterName { get; set; }
  }

And then the use of it:

  [CheckForGivenRequestAttribute("someStupidId", 1)]
  public ActionResult INeedAnExample(Int32 someStupidId)
  {
    ...
  }

Now you might ask why not make that attiribute generic to avoid boxing.

Why not make that attribute generic to avoid boxing?

Glad you asked. Turns out that you can't make attributes generic. Aparrently it's somwhat debatable why but not possible at the time being. Besides, the ActionParameters collection is <String, Object> anyhow, so at some point any stuct would be boxed anyhow.

On a side note, I never noticed this before, but when one of the non descript Autobots crashes near a pool, some kid is there to ask if he is the Tooth Fairy? Seriously? Are kids really that dumb? Cause every picture I've seen of the Tooth Fairy has been a 20 foot tall metal thing with no discernible features.

24Jul/0911

jQuery Slide and Pairing a Div’s Hover With a Div’s Slide

- Sean

So this could be filed under "I did it because I can" (which is a really good mantra in science...) and am not sure I'll use it but it is useful in the concept.

LIVE EXAMPLE HERE

The idea is to set the hover on one div to show/hide another div WITHOUT having to use some kind of id/name trick (as in setting the id to "divHide1") and to have it be completely self setting in the .ready method. Why would this be at all useful? Say you want to roll through a list of things and generate the divs, but want to defer the jQuery until the page has loaded. And you don't want to have to resort to:

    <div id="someDiv<%= someId %>"></div>

like structure where you parse some identifier from the id property. Mostly because you have no idea how many someDiv1s there could be on the page. It could be a highly reused name (someDiv) and that could lead to a mess.

Also the reason 'cuz. If you have any more questions of why after that answer, well you're just being annoying.

Anywho, here's the actual html for structure.

   <div class="mainDiv">
      <div class="showDiv" id="oneTop">
        Kaneda?
      </div>
      <div class="slideDiv" id="one">
        What do you see?!
      </div>
    </div>
    <div class="clear"></div>

Now I get that this isn't off a foreach, but it doesn't take much to figure out that it's easily made into a loop if you just loop it over and over. Why? Because first there are no ids or names so that you can't have two of the same name and also because that chunk is self contained.

So what is going on there? Simple, you have a parent container that holds a div to hold and a div to hover over and the other that will be shown/hidden.

Here's the styles involved just incase you care:

    <style type="text/css">
        .clear
        {
        	clear:both;
        }

        .leftDiv
        {
        	float:left;
        }

        .mainDiv
        {
        	margin:5px;
        	height:200px;
        }

        .rightDiv
        {
        	float:left;
        }

        .showDiv
        {
        	float:left;
        	margin-right:5px;
        	height:200px;
        	background-color:Silver;
        }

        .slideDiv
        {
        	background-color:Teal;
        	height:200px;
        	position:absolute;
        	float:left;
        	z-index:100;
        }
    </style>

That doesn't entirely matter, but it does to show the div "sliding" over another div. Kind of a little somethin' somethin' I threw in at no extra cost. Now for the jQuery:

First the method for setting the mouse over and out events for the show div, we turn to .hover:

    function setHover(currentSlideDiv, currentStableDiv)
    {
      currentStableDiv.hover
      (
        //first parameter is the method for showing the div on mouse over
        function()
        {
          if (currentSlideDiv.is(":hidden"))
          {
            currentSlideDiv.show("slide", { direction: "left" }, 100);
          }
        },
        //second parameter is the method for hiding the div on mouse out
        function()
        {
          if (currentSlideDiv.is(":visible"))
          {
            currentSlideDiv.hide("slide", { direction: "left" }, 100);
          }
        }
      );
    };

Now for the method that actually uses these:

    //This is used to take in one of the main divs and set all the
    //show and slide divs within.
    function setChildrenDivs(mainDiv)
    {
      //get all the show and slide dvis within the main div
      var mainChildrenStableDiv = jQuery(mainDiv).children(".showDiv");
      var mainChildrenSlide = jQuery(mainDiv).children(".slideDiv");

      //loop through the list of show divs
      for (var loopCounter = 0; loopCounter < mainChildrenStableDiv.length; loopCounter++)
      {
        //Get the show div and it's corresponding slide div using the
        //two lists and the current counter.
        var currentStableDiv = jQuery(mainChildrenStableDiv[loopCounter]);
        var currentSlideDiv = jQuery(mainChildrenSlide[loopCounter]);

         //This is to make sure the slide is where it should be.
         //to the right of the show div.
         var containerPosition = jQuery(currentStableDiv).position();
         jQuery(currentSlideDiv).css({ left: containerPosition.left + currentStableDiv.width() });
        //Set the mouse over and the mouse out on the show div
        setHover(currentSlideDiv, currentStableDiv);
      }
    }

Now the final touch, the .ready method:

    jQuery(document).ready
    (
      function()
      {
        //hide all the slide divs
        jQuery(".slideDiv").hide();

        //find all the parent divs
        var mainDivs = jQuery(".mainDiv");

        //set the children
        for (var loopCounter = 0; loopCounter < mainDivs.length; loopCounter++)
        {
          setChildrenDivs(mainDivs[loopCounter]);
        }
      }
    );

And boom, now you have multiple show/hide (Slide in this instance). Now if I could just find a use for it...

Oh yeah and you'll need jQuery 1.3.2 and jQuery ui 1.7.2 to use this. At least those are the versions I know this works with.

Update: Due to popular demand... one person... Source can be found here.

Tagged as: , 11 Comments
21Jul/090

Entity Framework: LINQ to Entities only supports casting Entity Data Model primitive types

- Sean

So in typical tool fashion I posted this little gem without realizing a glaring error... the order by clause. The whole idea is to create a method that can get a collection, sort it, then grab a certain number for paging. The issue was this:

    Expression<Func<K, IComparable>> orderBy

The problem comes in when the entire expression is run, meaning when Entity Frame work takes:

    context.Select(selectMethod).Where(whereClause).OrderBy(orderBy).ToList();

and creates SQL out of it. Entity Framework doesn't really know how to handle IComparable as it has not primitive/sql type to match to it. Why it can't see the underlying type of say DateTime, no idea, but this is life.

So this should be an easy fix, right? Eh... yeah. First I thought instead of IComparable I could just convert to some kind of primitive type so that the EF could be on it's merry. Not so much. Turns out this probably isn't possible.

Well thanks to a push from Ben M at The O Flow I got to thinking about how to attack this. Instead of sending in an expression for the order by, why not send in a method that would take in a query and tell it how to order itself. Sounds hard right? (If not then you're obviously too cool for this school) Well it's not, just a different way to think about it.

Right off the bat, the change to the method signature would look like this:

Old order by parameter signature:

    Expression<Func<K, IComparable>> orderBy

New order by parameter signature:

    Func<IQueryable<T>, IOrderedQueryable<T>> orderBy

So what does that mean? It means that I am going to supply the method with a method that will take in a query and return an ordered query... well not ordered yet per se but the blueprint on how to order when that time comes around. Now here's how that's used:

First you need the query:

    var initialQuery = query
    .Where
    (
        somethingEqualsSomething
    );

Then you apply the orderby method, and in the case of the original paging method, the paging too:

    var orderedQuery = orderBy(initialQuery);

    returnValue = orderedQuery
      .Skip(numberToShow * realPage)
      .Take(numberToShow)
      .ToList();

So overall, doesn't look too much different. Just instead of supplying the OrderBy method with a Func, you give a method that creates an ordered query.

How would you use this? Remember the signature was (whereClause, selectClause, orderBy, pageNumber, numberToShow, realPage, totalCountOfPages)

    Tools.GetListForGrid
    (
      tool => tool.EntityId == userId,
      tool => new { Name = tool.Name },  //Select Clause, I'll get to that next
      toolOuter => toolOuter.OrderBy(toolInner => toolInner .Name),  //OrderBy
      ...
    )

Two things you might notice. One would be the OrderBy signature:

   toolOuter => toolOuter.OrderBy(toolInner => toolInner .Name),

What the hell? Remember the method you are sending takes in a query and returns an ordered query. toolOuter is your query, toolOuter.OrderBy(toolInner => toolInner .Name) is your blueprint (IOrderedQueryable) on how it should be queried.

Second thing is that when I showed how to use the OrderBy method above:

    var orderedQuery = orderBy(initialQuery);

    returnValue = orderedQuery
      .Skip(numberToShow * realPage)
      .Take(numberToShow)
      .ToList();

I didn't include the select clause. Partially because I didn't want to complicate it yet, partially because it has it's own issue. If you're like me, you use the select clause a lot. Why? Because it limits the amount of information you take from the database. Say if you are trying to fill a drop down list, why select an entire Tool object (Which could have a ton of mapped properties) when all you need is Id and Name? Seems silly. That's where the Select clause comes in. Now the issue is where to put the order by. You would think after the select clause, since you want to sort on only what you are selecting. Problem is, with paging that gets screwed up. The way sql server "pages" is that it selects twice.

Select all the things that match this where clause.
Select a certain number of items from that starting at X.

The first select creates a dataset with row numbers, and the second one selects the items based on those row numbers. IE take 5 starting at row 5. Now the way the EF handles the order by is to grab the info you need from the Select (Ordered by something... you don't get to choose) and THEN order and grab. As you can guess this may not give the needed results. So how can this be solved? Order before the select as witnessed in the new and improved method:

public static IList<K> GetListForGrid<T, K>
(
    this ObjectQuery<T> query,
    Expression<Func<T, Boolean>> somethingEqualsSomething,
    Expression<Func<T, K>> selectClause,
    Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
    Int32 pageNumber,
    Int32 numberToShow,
    out Int32 realPage,
    out Int32 totalCountOfPages
)
{
    IList<K> returnValue;

    Int32 totalItemCount =
        query
        .Count
        (
          somethingEqualsSomething
        );

    totalCountOfPages = Methods.TotalCountOfPages(totalItemCount, numberToShow);
    realPage = Methods.GetRealPage(totalCountOfPages, pageNumber);

    var initialQuery =
      query
      .Where
      (
        somethingEqualsSomething
      );

   var orderedQuery = orderBy(initialQuery);

    returnValue = orderedQuery
      .Select
      (
        selectClause
      )
      .Skip(numberToShow * realPage)
      .Take(numberToShow)
      .ToList();

      return returnValue;
}

And usage:

    Tools.GetListForGrid
    (
       tool => tool.Id == userId,
       tool => new { Name = tool.Name },  //Select Clause
       toolOuter => toolOuter.OrderBy(toolInner => toolInner .Name),  //OrderBy
       pageNumber,
       amountToShow,
       out realPage,
       out totalCountOfPages
    );

Now this one actually works with Entity Framework and not just Linq to objects like the last one.

16Jul/092

ASP.Net MVC, jQuery, JSon, and paging… how’s that for a SOE title?

- Sean

One of the things I've come to realize is how easy it easy to do a lot of things with these three buzzwords. In fact, I'm pretty convinced it's so easy that it's actually complex and I am a genius. Not buying it? Neither am I.

So for an experiement the other day I decided to try my hand at some sort of dynamic grid using jQuery's ajax fun and JSon. Just so happens that this works really well with MVC's REST like makeup. Don't know what REST is? On a very tool level, it's using a url and a command to tell the server what to do. So something like:

www.byatool.com/users/dostuff

Could mean either get all users (if using get) or create a user (If using post). And yes that is probably a ridiculously simplistic view so I'd suggest consulting the Wikitruth. In an MVC sense this would be:

Controller: Users
Action: dostuff

Now most likely your Get All Users action isn't going to the same as your Add A User action, but it was just a stupid example ok?

However, with jQuery what this means is you have a simple url that it can call and get information from, making it incredibly easy to set up a dynamic grid.

So first off, lets say I have a Forum controller with an action of IndexJquery... yeah I know cheesy name, but it gets the job done. Basically the method IndexJquery would have to take in a page number and optionally (And for this example) how many items to show along with a sort. With that it should return a JSon "object" that will be in this example holds first page, last page, next page, previous page, sortBy, and some kind of list of stuff. (For the two people actually reading this, comment if you want the c# code. It's really just basic MVC stuff.)

The markup for this is pretty simple. I have a div to hold the grid, four directional divs that work as buttons (First, Previous, Next, Last), and two div "butons" for how many items to show.

    <div>
        <div id="divHolder">
        </div>
    </div>
    <div>
        <div id="divFirstPage" class="divLink floatLeft">
            <<
        </div>
        <div id="divPreviousPage" class="divLink floatLeft">
            <
        </div>
        <div id="divNextPage" class="divLink floatLeft">
            >
        </div>
        <div id="divLastPage" class="divLink floatLeft">
            >>
        </div>
    </div>
    <div class="clear"></div>
    <div>
        <div id="divAmountToShowOne" class="divLink floatLeft">
            1
        </div>
        <div id="divAmountToShowFive" class="divLink floatLeft">
            5
        </div>
    </div>
    <div class="clear"></div>

As you can see exactly as advertised.

Ready for the call? It's waaaaay hard:

        function getGrid(pageNumberIn, amountToShowIn, sortByIn)
        {
            jQuery.getJSON
            (
               //This is the url for the information I need
               "http://www.someurl.com/Forum/IndexJquery/",
               //this is the construction of the "object" to send... really this just
               //means that I have a method somewhere looking for pageNumber,
               //amountToShow, and sortBy
               {
                   pageNumber: pageNumberIn,
                   amountToShow: amountToShowIn,
                   sortBy: sortByIn
               },
               //This is the method to call once this ajax transaction has completed...
               //transaction may not be the best word.  Basically it has to be a method
               //that takes in the result from the getJSon call
               returned
            );
        }

Next would be the script to actually create the grid. Looks verbose, but most likely thats because I didn't refactor much.

    function returned(jsonObject)
    {
        //Have to remove all the previous click event handlers since because
        //this is all client side, there's no "refresh" and therefore the object
        //is still in memory.  So even though I might call the method to get the
        //information, the "objects" are still in memory.
        jQuery("#divFirstPage").unbind("click");
        jQuery("#divLastPage").unbind("click");
        jQuery("#divNextPage").unbind("click");
        jQuery("#divPreviousPage").unbind("click");
        jQuery("#divAmountToShowOne").unbind("click");
        jQuery("#divAmountToShowFive").unbind("click");

        //Ok so now that the event is not being listened to, set up the listeners
        //The idea is to call that getGrid method and pass in the values straight
        //off the previously returned json object.  Using jQuery's easy .click method
        //makes this so simple.
        jQuery("#divFirstPage").click(function() { getGrid(jsonObject.FirstPage, jsonObject.AmountToShow, jsonObject.SortBy); })
        jQuery("#divPreviousPage").click(function() { getGrid(jsonObject.PreviousPage, jsonObject.AmountToShow, jsonObject.SortBy); })
        jQuery("#divNextPage").click(function() { getGrid(jsonObject.NextPage, jsonObject.AmountToShow, jsonObject.SortBy); })
        jQuery("#divLastPage").click(function() { getGrid(jsonObject.LastPage, jsonObject.AmountToShow, jsonObject.SortBy); })
        jQuery("#divAmountToShowOne").click(function() { getGrid(0, 1, jsonObject.SortBy); })
        jQuery("#divAmountToShowFive").click(function() { getGrid(0, 5, jsonObject.SortBy); })

        //Again since this is client side, the divHolder "object" still is holding
        //the previous results.  These have to be cleared.
        jQuery("#divHolder").children().remove();

        //Create the table and loop through the list.
        var mytable = document.createElement("table");
        var mytablebody = document.createElement("tbody");

        for (loopCounter = 0; loopCounter < jsonObject.ListForViewing.length; loopCounter++)
        {
           var currentItem = something.ListForViewing[loopCounter];
           var mycurrent_row = document.createElement("tr");

           var mycurrent_cell = document.createElement("td");
           var currentText = document.createTextNode(currentItem.ForumName);
           mycurrent_cell.appendChild(currentText);
           mycurrent_row.appendChild(mycurrent_cell);

           mytablebody.appendChild(mycurrent_row);
        }

        mytable.appendChild(mytablebody);
        //Don't forget to add the table to the div!!11
        jQuery("#divHolder").append(mytable);
        return false;
    }

And boom. So easy even a ca... tool can do it. Now if you want this grid to come preloaded, it's pretty easy:

    jQuery(document).ready
    (
        function setPage()
        {
            getGrid(0, 10, null);
        }
    )
Tagged as: , , 2 Comments
16Mar/090

jQuery: Add a Pop Up Div to a Link Dynamically

- Sean

So as an exercise to learn more about jQuery, I decided to redo this little gem using jQuery. Have to say though only technically XHTML compliant, it worked out much better and with less code. So the idea is to have something really easy for non programmers (You know, lesser people) to be able to have a pop up comment added to some chunk of text on a web site. What I came up with before was ok but kind of annoying since it looked like this:

<a onclick="return ShowCommentForPost('1', this, 'THIS IS SO STUPID!');" href="www.byatool.com">word.</a>

Kind of annoying since I would have to explain that '1' is the name and it has to be unique for every one of these, this isn't really understood by those people, and well it just seems more complicated then it needs to be. So what if I told you it could look like this?

<a href="http://www.byatool.com" class="showItLink" xmlns:comment="hihihi">HI</a>

Gorsh, that seems even better and it works in both IE and Firefox... which might be a first for this site and anything javascript. First let's get the css out of the way, shall we?

    .showItLink
    {
    }

    .postComment
    {
        background-color:Gray;
        border-color:Black;
        border-style:dotted;
        border-width:thin;
        color:White;
        margin-right:3px;
        padding:3px;
        position:absolute;
        text-decoration:none;
        z-index:50;
    }

Most of the is just for looks, but like the older example I've called upon the power of position:absolute and z-index well that's just pulling it in front of everything else.

Next part will be the actual code, and if you take the method from THE POSITION ABSOLUTE POST

    function SetTopAndLeft(parentContainer, elementToSet)
    {
        var containerPosition;

        containerPosition = $(parentContainer).position();
        $(elementToSet).css({ top: containerPosition.top + 10, left: containerPosition.left + 10 });
    }

and add in a simple span creation method:

    function CreateDiv(innerText, cssClass)
    {
        var spanToAdd;

        spanToAdd = document.createElement('span');
        spanToAdd.className = cssClass;
        spanToAdd.innerHTML = innerText;

        return spanToAdd;
    }

you're ready for the actual fun part... making sure something pops up when the link is clicked.

jQuery(document).ready  //Everything inside this will load as soon as the DOM is loaded and before the page contents are loaded.*
(
    function()  //this is the start of an anonymous method
    {
        jQuery(".showItLink").click //find all things with the .showItLink class and assign the click event to the next anonymous method
        (
            function(event) //this is the start of an anonymous method for the click event
            {
                var containerPosition;
                var createdSpan;
                var comment;

                comment = jQuery(this).attr("xmlns:comment");  //Get the value from the comment attribute on the link.
                createdSpan = jQuery(this).children(".postComment"); //Find a possible span already attached to the link if it exists.  The span is of class 'postComment'

                if (createdSpan.length == 0)  //span doesn't exist
                {
                    createdSpan= CreateDiv(comment, "postComment");  //create the span
                    jQuery(this).append(createdSpan);  //Add the span to the link
                    jQuery(this).children(".postComment").hide();  //Make sure the new span is hidden
                }
                SetTopAndLeft(this, createdSpan);  //Set the position of the span
                jQuery(createdDiv).toggle();  //This will hide if it's showing, show if it's hidden... kind of nice huh?

                event.preventDefault();  //Equivalent to false.  Need this for Firefox.
            }
        );
    }
);

And boom you have something that works. Hooray.

Couple things of note:

.Hide - At first I though this would screw up my class for the span by removing the current class and adding display:none. Turns out it doesn't harm the original class. Kind of nice.

.Toggle() - This is really nice. It will hide if it is showing and show if hidden. Stupid easy to use and is pretty effective. Just like .Hide, the class of the element is not harmed.

$ versus jQuery - Some people might notice that I am not using the short hand $ for my jQuery calls. Turns out that it might be safer this way. There are other javascript libraries that use the $ short hand like prototype. I ran into this with WordPress since it uses both jQuery and Prototype and blocks jQuery from using $ since it could conflict with other libraries. Weeeee!

13Mar/092

JQuery, Position : Absolute, and How to Make It All Work

- Sean

This is a really quick one but when I was taking my cheesy pop up and reworking it using JQuery (After Andre the Annoying wouldn't shut up about it), I ran into a fun problem: position:absolute wasn't working like it should. You know "absolute is positioned at the specified coordinates relative to its containing block.". Meaning it should at worst show up within it's container, where ever that is. Now IE is fine with that and the thing was showing up well:

absolutepositionie

Firefox? Not so much:

absolutepositionfirefox

Well... turns out JQuery pretty much does it for me. With a simple method, you can set one element's position relative to a parent's position:

    function SetTopAndLeft(parentContainer, elementToSet)
    {
        var containerPosition;

        containerPosition = $(parentContainer).position();
        $(elementToSet).css({ top: containerPosition.top + 10, left: containerPosition.left + 10 });
    }

Really simple, you get the position of the parent container and you set the child element's top and left to it. Or in this case, I have it just off since hiding the parent container could be problematic. (Say if the parent container is a link AND NOW YOU CAN'T FIND IT TO CLICK ON IT AND THINGS HAPPEN BAD THINGS AND THE WORLD EXPLODES BECAUSE OF YOU!)

And boom, you can for once be a winner just like me.

12Mar/090

Add a Pop Up Div to a Link Dynamically

- Sean

Sometimes in life you have to ask "should I do this", this is not one of those times. The idea is simple, click on a link and a div appears over the link with some kind of message in it. Kind of like being able to add a pop up note to a word. If you are absolutely amazed by that, don't be afraid. Most likely you'll die soon from forgetting to breathe. However, if you are just slightly curious as to why and how, keep reading.

So why did I do this? Well it started with the idea of having something simple for a blog that has multiple authors: What if other authors could add notes to someone's post in the post. Well the idea of using some kind of text change (Like italics) sounded lame. I wanted something easy that could be replicated quickly and wouldn't be visible unless needed. Thus the onClick idea. Now the next problem I had was the class needed for the style sheet. As you can see, when the div is shown, it doesn't displace any of the items on the page. This is because I am using position:absolute and a high z-index. This allows for the div to lay on top of other things and not touch them. Problem with absolute is that it basicaly plants the div in relation to it's parent container. Now that whole parent container thing seems to be up for interpretation when you are talking about browsers. Each seems to deal with it the way it sees fit.

Originally I had it as a div that would contain this new div. This was a pain in the -ss. In IE it showed up over the div, FireFox not so much. So the next thought was to create a div to hold the div that held the div. Something that isn't exactly "user friendly" to be sure. Then it hit me, maybe I could put this in a link. After all, people who are viewing the blog would understand it's something they can click on (Provided I don't screw with the link styles too much) and it's easy for non coders to copy and paste.

So on to the promised land. First I'll just get the CSS out of the way since it's absolutely needed but needs little explanation:

.hidePostComment
{
    visibility:hidden;
    position: absolute;
    z-index:-100;
}

.showPostComment
{
    background-color:Gray;
    border-color:Black;
    border-style:dotted;
    border-width:thin;
    color:White;
    margin-right:3px;
    padding:3px;
    position:absolute;
    text-decoration:none;
    visibility:visible;
    width:100px;
    z-index:10;
}

.hidePostComment

As you can see, I've screwed with the z-index, visibility, and position. Position I've already explained, and I think you can understand why visibility is hidden with this class. However, z-index might not be something you know about. Basically,z-index tells the browser where an item is in a vertical sense. When you look at a browser, there are actually a lot of layers regardless of the 2nd appearance. The z-index is used to bring something forward or backward. If I want the div to be behind say the text I am typing right now, it has to be at a z-index lower than the text. I used -100 in the example just to make sure it's behind anything. It's really an arbitrary number though. A positive number would make the div appear in front of the text (And in that case the text would not show up since it would be "behind" the div) which is what I did with the visibility class.

.showPostComment

Mostly just a bunch of visual changes like border and background color. However, you will also notice the the position is still absolute and that the z-index is now 10. (positive) The div will now effectively be "in front" of the link when it shows up giving it the pop up look. One Note: I had to add in text-decoration:none since the div is attached to the link and IE wants to drag the underline with the pop up causing the text to up with an underline. Kind of odd but no big deal.

Now for the code:

function BuildSelectableSpanForPost(spanName, parentElement, innerText)
{
    var divToAdd;
    var parentContainer;
    //check to see if the parentElement is actually an element or string.  If string, use it
    //to find the element.
    if (typeof parentElement == 'string')
    {
        parentContainer = document.getElementById(parentElement);
    }
    else
    {
        parentContainer = parentElement;
    }
    //Create the div
    //set the name (The name must unique since there could be a million "pop ups" per page
    //set the id
    //set the text for the div which is what we want to show up in the pop up
    divToAdd = document.createElement('span');
    divToAdd.setAttribute('name', spanName);
    divToAdd.id = spanName;
    divToAdd.innerHTML = innerText;

    //Add the div to whatever element that was found.  For this post it will be a link
    //but it doesn't really matter.
    parentContainer.appendChild(divToAdd);

    return divToAdd;
}

So there is the building of the pop up div. Here's the method to be called by the onclick event:

function ShowCommentForPost(postName, parentElement, innerText)
{
    var divName;
    var createdDiv;
    var parentContainer;

    //Same as before
    if (typeof parentElement == 'string')
    {
        parentContainer = document.getElementById(parentElement);
    }
    else
    {
        parentContainer = parentElement;
    }
    //See if the pop up div  already exists.  If it does, then don't create again
    //I didn't have this before and it would create a new div everytime
    //That's what some might call a surprise feature
    divName = 'comment' + postName;
    createdDiv = document.getElementById(divName);
    //Ooops, the div didn't exist, create it and add the hide class
    if (createdDiv == null)
    {
        createdDiv = BuildSelectableSpanForPost(divName, parentContainer, innerText);
        //this is a method found on this post
        ClassHandler.AddClass(createdDiv, 'hidePostComment');
    }

    //this is a method based off this post
    //As you can guess it will show or hide depending on which class it already has.
    ShowHideElementBasedOnCss(createdDiv);

    return false;
}

To start, there is the code to create the actual div.

Now for the actual use:

<a onclick="return ShowCommentForPost('1', this, 'THIS IS SO STUPID!');" href="www.byatool.com">word.</a>

Pretty easy to actually use right? The actual location doesn't really matter since it the method will always return false and therefore the link will never redirect. Also, you'll see that I put 1 as the name sent in. The name sent in doesn't matter what it is, but for every link it has to be different. If you are using this in a blog situation where there could be multiple blog posts in one page, I would suggest the name sent in would be the title and an increasing number.

If you got to this point and feel robbed of five minutes in your life, well just be happy this post robbed me of 15 minutes of mine.

11Mar/090

Add, Remove, or Replace a CSS Class Using Javascript

- Sean

Now honestly, I think the all famous Prototype has something for this, but if you aren't using the all famous Prototype... well you're screwed. Until now.

This is the idea, you want show or hide something on a click of it.

    <div onclick="HideOrShowMe();">
      YAYAAYAYAY!
    </div>

Annoying thing is trying to keep up with whether it's hidden or not. Now there are ways to do this for sure, but if you had them you wouldn't be here... or you just love idiotic banter. Either way, you're here.

To start, get a class going:

    if (typeof ClassHandler != 'object')
    {
      ClassHandler = new Object();
    }

Normal declaration. Yeehaw. Now we need a method to check for the class:

ClassHandler.CheckForClass = function(element, nameOfClass)
{
    var returnValue = false;

    //Check to see if the element variable is a string or (hopefully) a control.
    //If it is a string, get the control that belongs to that id.
    if (typeof element == 'string')
    {
        element = document.getElementById(element);
    }

    //next you use a regular expression to check the className property for
    //  the class you want.  If it finds a match, you're good to go.
    if (element.className != '')
    {
        returnValue = new RegExp('\\b' + nameOfClass + '\\b').test(element.className);
    }

    return returnValue;
}

Ok so now you have a method to check if it's there... but what about if you want to replace the old one with a new one? Well that could be broken into two methods first (Both that are useful). First one is the removal of the old class:

ClassHandler.RemoveClass = function(element, nameOfClass)
{
    var returnValue = false;

    //You know the drill
    if (typeof element == 'string')
    {
        element = document.getElementById(element);
    }

    //Hey cool, I just used the CheckForClass method
    if (ClassHandler.CheckForClass(element, nameOfClass))
    {
        //Real simple, replace the old
        //But you have to check if the nameOfClass exists with a preceding space
        //If it does, then you replace that with a space, other wise just replace
        //the nameOfClass with a space.
        element.className = element.className.replace((element.className.indexOf(' ' + nameOfClass) >= 0 ? ' ' + nameOfClass : nameOfClass),'');
        returnValue = true;
    } 

    return returnValue;
}

And now you'll have to add in the new one.

ClassHandler.AddClass = function(element, nameOfClass)
{
    var returnValue = false;
    //lalalala
    if (typeof element == 'string')
    {
        element = document.getElementById(element);
    }
    //If className already has a value, precede the nameOfClass with a space
    // otherwise just add it in.
    if (!ClassHandler.CheckForClass(element, nameOfClass))
    {
        element.className += (element.className ?  '  '  :  '') + nameOfClass;
        returnValue = true;
    } 

    return returnValue;
}

Now for the replace:

ClassHandler.ReplaceClass = function(element, classToRemove, classToAdd)
{
    var returnValue = false;

    //african elephants only have four teeth for chewing their food.
    if (typeof element == 'string')
    {
        element = document.getElementById(element);
    }

    //Remove the old one
    //Add the new one
    if(ClassHandler.CheckForClass(element, classToRemove))
    {
        ClassHandler.RemoveClass(element, classToRemove);
        ClassHandler.AddClass(element, classToAdd);
        returnValue = true;
    }

    return returnValue;
}

Now you might be thinking, "Tool, why don't you just use the replace method in the replace method." Well I suppose you could, but this way you have two other methods at your disposal for future use. Up to you really, part of this was because I actually needed those methods and the title says "Add, Remove, or Replace". I can't go against the title. I don't have that kind of strength.

Usage? Well there are couple ways you can do this.

    if(ClassHandler.CheckForClass('someDiv', 'hide'))
    {
       ClassHandler.ReplaceClass('someDiv', 'hide', 'show');
    }
    else
    {
       ClassHandler.ReplaceClass('someDiv', 'show', 'hide');
    }

or this:

    if(!ClassHandler.ReplaceClass('someDiv', 'hide', 'show'))
    {
       ClassHandler.ReplaceClass('someDiv', 'show', 'hide'));
    }

And other ways to be sure. Now I'm not saying this is the best way to do it, just a decent way... although looking back on this I wonder if I could clean up the regex stuff.

NetDevInc.com