Remember that question you never asked? Well once again I’ve answered it.

To take the normal sliding menu farther I thought I should have something happen when hovering over the menu items. Novel! Well as you can see if you clicked on the link above (Sorry, can’t repost the link. Links are expensive.) the menu items have large counter parts that show up when hovered over and don’t go away until the counter part or the main item is left. What does this all mean? I DON’T KNOW but I’ll find out eventually. It’s in the cards man, it’s in the cards…

//
// mouseenter: Find any menuItemBig within the given element and show// Reset the position of the menuItemBig element to appear// to be in the middle of the parent element// mouseleave: Hide the child menuItemBig//function setOnHoverForMenuItems(items)
{
jQuery(items)
.each
(
function ()
{
jQuery(this).mouseenter
(
function()
{
//Why the positioning? I wanted the child div to show up in the// middle of the parent div which is done by putting the child's left side// to half of the width of the parent over from the parent's left sidevar parentPosition = jQuery(this).position();
var bigItems = jQuery(this).children(".menuItemBig");
bigItems.css({ left: parentPosition.left - (jQuery(this).width() /2), top: parentPosition.top + 10 });
bigItems.show();
}
);
jQuery(this).mouseleave
(
function()
{
jQuery(this).children(".menuItemBig").hide();
}
);
}
);
}

Why not hover? *EDIT* It should be hover. Turns out an issue I was having with hover was not actually an issue with it… *END EDIT*

The other method I added was a simple one:

//// Used to find any element of menuItemBig//function hideAllBigItems(bigItemParentItems)
{
jQuery(bigItemParentItems).children(".menuItemBig").hide();
}

And where did I use these? I appended them to the setChildrenDivs method:

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.

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.

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)

In this wonderpost, I questioned the use of jQuery in the mind of the purist MVCist. (If that’s not a word yet, it is now and I expect royalties.) Now I’ll flip it tool style and ask it from another direction: Can MVC survive without jQuery?

Here’s the situation: I have a site that I made a while back (Basically a phone friendly chat room emulator) that was kind of experiment on a couple levels, one being the use of Entity Framework and WebForms. (It’s here if you are curious… right now you have to make an account though. Never got around to allowing non logged in users.) Another part was to see if I could make a multi phone compliant page that had to be fast and work on as many phones as possible. (Anything with a browser at least) And had to be touch friendly. (No links, just buttons)

A week back I decided, after trying to make new sites with MVC, to take an existing work and really give MVC a rugged test. Eythere was just that site. Now personally I thought this would be pretty simple since MVC seemed really good at simple, non business sites. What could be more simple than a chat room emulating site that has no javascript? (Aside from whatever Javascript WebForms use for postbacks) I mean in the end, it’s just a bunch of buttons right?

Yeah turns out what those buttons did was at the heart of my issues. You see, with WebForms, everything done on a page is meant for that page. Sure you can defer how things are handled from the page to another tier, but the action itself belongs to the page. For example, say that a user wanted to make a room a favorite, well there’s a button named favorite that he/she clicks to do so.

In webforms, the Room.aspx page would handle the Favorite button click and the current user’s favorite list would have the room removed or added depending. But the call to the add/remove would be handled by the button’s click event and then the page would be reloaded. Something we in the know call “easy”. (Like that word? Use it. It’s free because I’m such a nice guy)

Now with MVC it’s a whole new ballpark. With controllers, it becomes of question of what controller should handle this. It could go onto the room controller, but in the end it deals with a user and adding something to the user. So it’s fair to say that this is probably a job for Superman if Superman happens to be a UserController or you’ll most likely end up repeating code.

Now the issue: How is this handled? Whether link or button, something has to be posted to the user controller. Posting to the controller means that the controller, on finish, has to create a model and send it to a view. Well this kind of sucks doesn’t it? The user clicks the + Favorite button and bam is taken to a whole new page.

SURPRISE IT’S BEEN ADDED TO YOUR FAVORITES!

Not what I would call fluid. The other thought it to have a redirect, which in the end is more fluid in that it takes the user back to the original page BUT with that you have to send a lot of information back and forth. After all, in MVC a lot of the information for a given “page” is passed using get. So for instance you have a room with a roomid and a page number and a count of items to show and possibly a sort you’re looking at:

/Room/1/?pageNumber=1&amountToShow=5&sort=Date

Which means all of that has to be sent to the User controller in order to save the state, has to be put in session/some kind of user cache, or you just send the entire url. In any case, something has to be tossed around for this to work. More seamless than the other way but it is a lot of work for something so simple.

When it comes to ease of UI design, jQuery/asynchronous operations are a must.

Something I think that the MVC idea fails at it in a UI sense it was makes it strong in a programming sense, logical separation of tasks. Right off the bat, I hated the way WebForms handled AJAX “web methods”. Having to repeat methods per page so they could be “registered” was ugly and a pain. MVC and it’s separation/REST ways makes asynchronous calls so easy. However, what used to be a simple operation in WebForms has now become cumbersome without outside help. Straight up, it seems impossible to do non drill down design without using jQuery or some kind of javascript library equivalent without killing the separation that MVC seems to embrace.

Why is this a problem? For the most part it isn’t. Most people aren’t going to try something like EyThere (Wouldn’t recommend it, it was a pain) since how many people create sites with multiple phones in mind? However, it does serve to show what seems to be a glaring annoyance with MVC. Either use asynchronous calls or just sink.

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:

<divid="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.

<divclass="mainDiv"><divclass="showDiv"id="oneTop">
Kaneda?
</div><divclass="slideDiv"id="one">
What do you see?!
</div></div><divclass="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.

//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 divsfor (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);
}
}

This is something I started to think about the other day as I have been diving deeper into MVC. In it’s purest form, at least to what I understand, is that the whole idea of MVC is to have a separation between information handling (controller), information delivery method (model), and the information presentation (View). What this means is that the View itself should only be around to display or return information, but that’s it. Have a form? Great, here’s the information you need to fill out and I’ll send it on it’s way. And even with that idea, the View itself doesn’t really send anything. It just passes what it knows off to the model and it’s back in happy land. (The view gets nervous sometimes… performance anxiety) The whole system works well in actuallity, it does what is expected. There are no events simulated and possibly tangled. There’s no smoke and mirrors when it comes to the display and what the user is seeing. I want a grid of users? Here it is. I want to edit this user? Great! I’ll take you to the page that does that. Life is great and wonderful.

But wait, here comes jQuery, Json, and Asynchronous Calls. Now I can do crazy things with the view that I could never do before. Remember that grid of users? Well you don’t really have to go to another page to edit. Hell, just click this link and a form can appear to take in what you need to change. Even better, the grid itself will change and allow you to edit any row you want, and when you’re done the grid will come back all new an refreshed. What a crazy party this is now. Kind of sounds familiar right? Yeah WebForms. With these three helpers we’ve now cut out the middle man in the Model and passed the savings onto you. Essentially the whole idea has been chucked and jQuery has allowed us to invoke the same event model WebForms was chastised for. In fact, you could go to the logical end and have one page once again that controls everything. The View once again has the power much like it did in WebForms (provided you look at the Page and code behind being more like a View than separate entities). Isn’t that the whole thing we were trying to get away from?

I suppose you could make the argument that no one is putting a gun to your head to use jQuery for anything other that simple things like UI manipulation (date pickers, sliding controls, drag drop, ect) but that wouldn’t be the situation being argued here, now would it?

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.

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);
returnfalse;
}

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

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:

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?

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!

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:

Firefox? Not so much:

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:

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!)

So you have been reading about jQuery and want to dive in and try some? I recently attended the MSDN Dev Conference in Detroit where jQuery integration and client-side programming were very hot topics. With Microsoft’s acceptance of the open source library, I figured I would give it a try. This is what I have learned so far. Before I can show you what you can do with jQuery, I think I should probably show you how to get a reference to jQuery into your code. In ASP.NET you can add your reference directly to your Script Manager

What does jQuery have to offer? First and foremost, jQuery has given me power over the Document Object Model (DOM)! jQuery Selectors are the greatest thing since sliced bread, no lie. Being able to EASILY find an object or group of objects in the DOM by ID, CSS Class, or by HTML Tag is something web developers have long needed. To select an object from the DOM by ID would look like this:

$('#ID_Goes_Here')

To select an object from the DOM by CSS Class would look like this:

$('.CSS_Class_Name_Goes_Here')

To select an object from the DOM by HTML Tag would look like this:

$('
')

With jQuery Selectors being so simple, it allows the developer to easily select an object or a group of objects. Now that we can select objects, what can we do with them? This is where the power of Selectors really builds into what else you can do. In a web application, round trips to the server to manage UI is wasteful. I avoid JavaScript like the plague because it’s a pain in the ass. jQuery makes client-side UI management feel like climbing the rope in gym class. For example, if I have a label that I want to be rendered but not visible I could create the label.

And later on in jQuery I can hide it like this.

$('#Label4').css('display', 'none');

It’s nice to be able to easily select an object and modify it, but what if you have a whole group of items you want to modify? With jQuery, you can EASILY loop through a collection of objects. In this example I have a group of labels.

Now I want to update the text of each label to include its ID. I am going to loop through each object in the DOM with a CSS Class of .myLabel.

$('.myLabel').each(function() { $(this).append(this.id); });

What the jQuery code above does is execute a function that will append the object’s ID to its text value. Notice the Selector inside the function $(this). The syntax is used to find the loop’s current object in the DOM. I do a lot of web work where I create controls on the fly. For my last example, I just wanted to show a way to quickly insert some HTML into a container object. I will start with a Panel AKA a DIV.

Now I am going to use jQuery to select my DIV and add some HTML to it.

$("#Panel1").html("

Item One

Item 2

");

Now I have shown you some snippets here and there, let me show you what my page actually looks like.