6/26/2008 3:45:00 PM

News Ticker View for Graffiti CMS

A project on which I've been working required some nifty trickery and I thought it was something worth sharing. I bet one could easily add some transition effects to make it more nice-looking but the idea's pretty simple; rotate the titles of the articles you want displayed in a handy-dandy little auto-rotator as links to the article content. The code for this view is below.

<style>
#newsBox
{
    width: 300px;
    vertical-align: bottom;
    border: dotted 1px #eee;
    padding: 2px;
}
</style>

<div id="newsBox"></div>

<script language="javascript" type="text/javascript">

var NewsArticle = Class.create({
    initialize: function(title, url)
    {
        this.Title = title;
        this.Url = url;
    }
});

var NewsArticleRotator = Class.create({
    initialize: function()
    {
        this.Articles = new Array();
        #foreach($post in $data.PostsByCategory("news",10))
        this.Articles.push(  new NewsArticle("$post.Title","$post.Url")  );
        #end
    },
    rotate: function()
    {
        var rnd = Math.floor(Math.random()*this.Articles.length);
        $('newsBox').innerHTML = '<a onmouseover=\'toggleNewsLink();\' onmouseout=\'toggleNewsLink()\' href=\'' + this.Articles[rnd].Url + '\'>' + this.Articles[rnd].Title + '</a>';
    }
});

var isNewsLinkHot = false;

function toggleNewsLink()
{
    isNewsLinkHot = !isNewsLinkHot;
    if(!isNewsLinkHot)
        rotateNews();
}

function rotateNews()
{
    if(isNewsLinkHot) return;
    
    var rttr = new NewsArticleRotator();
    rttr.rotate();
    window.setTimeout(rotateNews, 3000);
}

rotateNews();

</script>

Happy Coding!

Note - Syntax Highlighter is busted and I'm sleepy so it'll look better tomorrow.

Further update - I touched a few files and all seems well again. 

Kick it! | del.icio.us | Comments (0) | Permalink

6/13/2008 3:52:00 PM

ASP.NET MVC, JSON, and Prototype

I've tinkered with the method of posting JSON between the browser and the server via a generic handler. When the new MVC Preview came out and had native support for JSON I knew I needed to do some further tinkering. This post will describe in brief how to perform such a thing. I'll demonstrate how to perform a login process using JSON communication between an MVC Controller's action method which returns a JsonResult instance. Sounds tricky, but that's how Prototype helps us. It makes the communication process pretty easy. I'll try to be pretty short and sweet here and will keep the code discussion to a bare minimum.

Environment Setup 

First and foremost, you'll need to learn the basics of the ASP.NET MVC approach and find the two downloads over at ScottGu's blog post on the topic. That's about the best place to start.  Once you've got everything installed you should create a new MVC project. Add a folder to the Views folder called Login. This is a relatively simple topic that all must implement at some point or another. I'll use the Prototype JavaScript framework for this. So make sure you download Prototype and put it into your web project. Finally, add a reference to the script in your Site.Master page, which should be in the Views/Shared folder. 

Creating the Login Index View and Controller

Within the new Login folder, create an MVC View Content Page named Index.aspx.  This page will contain some HTML code, as you'll see below. This code contains some form elements and some JavaScript code. The JavaScript code is what will perform the duty of packing up the data collected from the form in the structure of a JavaScript object called Login. Once the object is created, it will be shipped over HTTP to the server.

<%@ page title="" language="C#" masterpagefile="~/Views/Shared/Site.Master" autoeventwireup="true" codebehind="Index.aspx.cs" inherits="MvcPreviewThree.Views.Login.Index" %>

<asp:content id="Content1" contentplaceholderid="MainContent" runat="server">
    <div class="row">
        <div class="cell">
            <label for="username">username</label>
            <input type="text" id="username" value="username" />
        </div>
    </div>
    <div class="row">
        <div class="cell">
            <label for="pwd">password</label>
            <input type="password" id="pwd" value="password" />
        </div>
    </div>
    <div class="row">
        <div class="cell">
            <input type="button" id="buttonLogin" value="login" onclick="doLogin();" />
        </div>
    </div>

    <script language="javascript" type="text/javascript">

    var Login = Class.create(
    {
        initialize: function()
        {
            this.Username = $('username').value;
            this.Password = $('pwd').value;
        }
    });

    function doLogin()
    {
        var login = new Login();
        var request = new Ajax.Request('/Login/Authenticate', 
        {
            method: 'post',
            contentType: 'application/json; charset=utf-8',
            postBody: Object.toJSON(login),
            
            onSuccess: function(transport)
            {
                alert(transport.responseText);
            },
            
            onFailure: function()
            {
                alert('fail!');
            }
        });
    }

    </script>

</asp:content>
 

Controlling Things

Take note of the URL in the call to the Ajax.Request constructor. The call is going to be made to /Login/Authenticate. Understanding that step will give you a better comprehension of how the URL's are converted into useful routes on the server to view pages. The first step is to create a Controller class. Since I've created a Views folder named Login, I must create the class useful for controlling all login-related procedures. This class, LoginController, will contain action methods that perform various actions the user will need to execute during the Login routines. The first of these - the Index view - needs to be controlled first. 

public class LoginController : Controller
{
    public ActionResult Index()
    {
        return View();
    }


}
 

This one's pretty obvious - the call to View() will just render the Index view I already created, with the login form and JavaScript call. The next one isn't so obvious and requires a quick glance at some helper methods I've written into a JsonHelper class. This class just makes some of the heavy lifting easier in a moment. The ToJson extension method wouldn't have been possible without a post from ScottGu's blog.

public static class JsonHelper
{
    public static string ToJson(this object target)
    {
        JavaScriptSerializer ser = new JavaScriptSerializer();
        return ser.Serialize(target);
    }

    public static T FromJson<T>(string json)
    {
        JavaScriptSerializer ser = new JavaScriptSerializer();
        return ser.Deserialize<T>(json);
    }

    public static T FromJson<T>(Stream stream)
    {
        StreamReader rdr = new StreamReader(stream);
        return FromJson<T>(rdr.ReadToEnd());
    }
}

The last step in our controller class is the actual niftyness of the whole post. Within this method the code takes a peek at the current Request, specifically the incoming JSON string contained within the request's InputStream property. This is where I'll use my JsonHelper class, which makes it a snap to parse an HTTP Request into a JSON object. 

public JsonResult Authenticate()
{
    Login login = JsonHelper.FromJson<Login>(this.Request.InputStream);
    return new JsonResult
    {
        Data = (login.Username == "username" && login.Password == "password")
    };


}

The Final Touch

Last, I'll need to give the user some way of finding the Login's Index view so I'll add a link to the view in the Site.Master file's navigation section.

Once you've done all this you should be able to run the code with success. I'll get around to uploading this sample onto the server so you can see it working in the next few days, but I couldn't wait to share this technique. Using Prototype as a means to communicate with a ASP.NET MVC Controller class' JsonResult methods makes for a powerful combination of tools to build truly rich, interactive applications that run in all modern browsers.

Happy Coding! 

 

Kick it! | del.icio.us | Comments (4) | Permalink

5/14/2008 7:51:00 AM

On "Software Developers Never Change"

Nick B writes today about some of the traditional "I'm smarter than you OR your mama" developers face. Though I would agree with an overwhelming majority of the points he makes and with virtually all of his rather comical approach, I feel as though I have something to add.

Best part is that it's relatively simple and I can make my point in a fraction of the time it took Nick to make his (not saying he took too long, I'm just going to be more condensed as I'm ready to go home). 

It's simple - there should never be a qualitative discussion of code. It's that stinking simple. If I do it with prototype and you do it with jquery, who gives a rat's ass which framework is better, so long as both approaches resolve to the same end? The bottom line is this - there is no such thing as better code, as long as the code you wrote solves the problem it was meant to solve. Just because a better way comes along, the old way does not automatically become the bad way. Improvement does not denote previous failure. Improvement is indicative of progress. 

There will always arise a better mouse trap if you wait long enough.

Kick it! | del.icio.us | Comments (1) | Permalink

5/7/2008 4:55:00 AM

SyntaxHighlighter and Field DataBinding

Today during a search to find a good BlogEngine.Net code syntax highlighter I came across that which you can read more about over here. This post will commence a test of the installation of said highlighter. If you see a little codeblock below and it looks decent, things are cooking.

protected string GetFieldValueForDataItem(object target, string fieldName)
{
    Type t = target.GetType();
    object value = t.GetField(fieldName).GetValue(target);
    if (value == null) return string.Empty;
    return value.ToString();
}

The code itself was needed last night during development. I was having an issue databinding a Repeater on an ASPX page to an instance of a class that had no properties, but many fields to which I could bind. Thing is, you can't just bind to fields without doing a little trickery, so this code was born. 

Kick it! | del.icio.us | Comments (0) | Permalink

3/27/2008 3:10:00 PM

Woot Watcher - My First ASP.Net MVC App

Like most everyone else in the ASP.Net community I've been dedicating a good deal of time recently to learning more about the ASP.Net MVC implementation. Today, as you may already know, Woot.com is having a woot-off. Given that most of the tools I've found on line for tracking these wonderful events seem to crash I thought I should create my own Woot-monitoring page.

Woot Watcher was inspired by a few simultaneous events. A woot-off was occurring, I was learning the ASP.Net MVC framework, and my finger became cramped beyond control from repeatedly tapping the F5 key. With that I decided I needed to simplify my ability to keep up with what was going on at Woot.com and that the best way to do that would be to use the ASP.Net MVC framework to do it.

So, feel free to check it out. You'll notice it changing frequently until the woot-off is over, then it'll just sort of stay the same each day. I'll try to add some Ajax features, but first I need to learn how the MVC model allows for this. For now, check out Woot Watcher.  

Kick it! | del.icio.us | Comments (2) | Permalink