# Thursday, October 15, 2009

When creating web applications I like to extract common pieces of mark-up into helper functions. I use Hasic which means helper functions are just simple VB functions that return XElement objects.

However, dynamic web pages often use javascript to add elements at runtime. Consider a page with a table of data which has an form to add rows. We want to add rows without reloading the whole page. So we use AJAX to post the new data, then, in javascript, create the new table row and append to the table.

So we have a repetition of the same HTML template; server-side and client-side.

Using Hasic we can eliminate this repetition. The following class field defines an HTML template:

Shared customerRow As New HtmlTemplate(Of String, String)("customerRow", Function(first, last) _
  <tr>
    <td><%= first %></td>
    <td><%= last %></td>
  </tr>)

Let’s break this down. We are creating an HTML template that takes two string arguments and returns an XElement. We have named it “customerRow” and given a lambda expression that returns the HTML. That second argument is an Expression(of Func(of String, String, XElement)). So the HtmlTemplate is able to parse the expression tree and generate an equivalent javascript function.

Within my page (server-side) I can use the template like a function (by using an indexer property).

Protected Overrides Function Contents() As XElement
  Return _
  <_>
    <table id="customers">
      <tr><th>First name</th><th>Last name</th></tr>
      <%= customerRow("Andrew", "Davey") %>
      <%= customerRow("John", "Smith") %>
    </table>
    <div>
      <button id="add">Add Row</button>
    </div>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <%= InlineJavascript(customerRow.Javascript) %>
    <script type="text/javascript">
$(function() {
    $('#add').click(
        function addRow() {
            $('#customers').append(customerRow('John','Smith'));
        }
    );
});
    </script>
  <_>
End Sub

The above code also includes the javascript for the page. Notice the customerRow.Javascript property. This returns the javascript function as a string. InlineJavascript is a helper that wraps up the javascript into a CDATA making the angle brackets safe. The javascript function looks like this:

function customerRow(first,last) {
  return '<tr><td>' + last + '</td><td>' + first + '</td></tr>';
}

The name of the function is what we gave to the HtmlTemplate constructor. Concat-ing strings may not be the best way, but it works for this prototype.

I hope you can see the value here. The template function is written only once. DRY win :)

hasic | html | javascript | vb.net | web
Thursday, October 15, 2009 12:39:59 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, March 13, 2009

Another approach I'm investigating for HTML form generation is using VB's XML literals.

Check out this screencast for a demo: http://screencast.com/t/WSoDB4B9M2

 

XML literals + Expression Trees gives us some serious power!

.net | html | screencast | vb.net | web | xml
Friday, March 13, 2009 6:44:33 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

HTML forms seem to be general enough to warrant a better abstraction than manually creating the HTML, or even using simple HTML helpers. Ideally the semantics of the form should be enough to generate all the HTML content.

I have been prototyping some ideas in this area. Here is some code that demonstrates a simple (but incomplete) login form.

class LoginData
{
    public string Username { get; set; }
    public string Password { get; set; }
    public bool Persist { get; set; }
}
 
 
class LoginForm : Form<LoginData>
{
    public LoginForm()
    {
        FieldContainer = new DivFieldContainer();
 
        Add(d => d.Username);
        Add(d => d.Password).AsPassword();
        Add(d => d.Persist).WithLabel("Stay logged in on this computer");
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        var data = new LoginData() { Username = "test" };
        var form = new LoginForm();
 
        var html = form.Create(data);
        Console.WriteLine(html.ToString());
    }
}

This generates the following HTML.

<form method="POST" action="http://localhost/">
  <div>
    <label for="Username">Username</label>
    <input id="Username" type="text" name="Username" value="test" />
  </div>
  <div>
    <label for="Password">Password</label>
    <input id="Password" type="password" name="Password" />
  </div>
  <div>
    <input id="Persist" type="checkbox" name="Persist" />
    <label for="Persist">Stay logged in on this computer</label>
  </div>
</form>

There is a clear separation of the data from the form meta-data. This lets me do interesting things like applying conventions, for example, the generation of label text from property names. I want to use mostly global conventions for a form, and then override a few specific fields where needed.

I think validation can also fit nicely into this approach. Validation logic can be put on the data model. The form model can then specify how errors are added to the HTML.

Has anyone else seen anything like this before? I don’t want the reinvent the wheel. Or at least I can steal some good ideas ;)

.net | c# | html | web
Friday, March 13, 2009 11:51:16 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, November 30, 2008

Continued work on my resource-oriented library for ASP.NET MVC has expanded to include an XDocument based view engine for ASP.NET MVC.

This means we can now use VB.NET XML literals to define XHTML views (or any XML views).

Get the latest from SVN.

.net | html | mvc | REST | vb.net | web | xml
Sunday, November 30, 2008 10:49:44 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, February 19, 2008

VB.NET 9 introduces a clean syntax for expressing XML data. XHTML is XML so why not use VB.NET to generate it, instead of ASPX pages? People are creating view engines for the new ASP.NET MVC framework. How about a view engine that uses VB.NET XML literals?

The benefits to this approach include full intellisense and access to a the full VB.NET language when creating HTML.

I see a view as a function from some data to an XML element (the <html> element):

Function CustomersPage(ByVal title As String, ByVal customers As IEnumerable(Of Customer)) As XElement
    Return _
        <html>
            <head>
                <title><%= title %></title>
            </head>
            <body>
            <%= From customer In customers Select _
                <div id=<%= customer.LastName %>>
                    <h1><%= customer.FirstName %></h1>
                </div> %>
            </body>
        </html>
End Function

The important change from ASPX is that this is HTML in Code, rather than Code in HTML. As a result less "automagical" behaviour is required; It's just a function! This means AJAX features like "partial rendering", where a section of page needs to be updated, can be expressed by just calling a function that returns a <div> element. That same function can be used by the full HTML page function too.

ASPX "usercontrols" become simply functions as well. ASPX Master Pages are functions that have arguments for "placeholders" that get inserted into an template HTML page. Instead of having to reinvent a bunch of programming language concepts inside ASPX, we can just use a programming language that now support XML!

The only down side to this approach is we lose the IDE visual designer support. However, I find viewing an ASPX page that contains even simple conditional data rendering next to useless. I'd rather keep IE open and just refresh the page to see changes.

I am yet to embrace the MVC framework. I am waiting to see if the next release can better support Snooze framework ideas. However, there's no reason I can't use this VB XML magic in Snooze as it current is.

.net | html | thinking | vb.net | web | xml
Tuesday, February 19, 2008 12:12:17 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, November 02, 2007

There is a lot of hype around Silverlight and WPF enabling true separation of developer and designer. This is certainly a great way to work. However, I don't think this is enabled only now by XAML. There is no reason the same cannot be achieved with HTML.

It seems like developers went so far down the server-side HTML generation route we left designers floundering with only CSS left in their toolkit. Whilst you can do some amazing things with CSS, sometimes you just need to change the HTML. If the HTML is riddled with <% %>, server controls or other template commands how is out poor designer going to work with the file?

My current attention is around using pure HTML and putting all dynamic content generation into JavaScript. The only thing to enforce on the HTML is that certain elements have known "id" attribute values.

html | programming | ria | thinking | web
Friday, November 02, 2007 4:42:04 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  |