Ayende @ Rahien

Unnatural acts on source code

Having Fun with SmartGridComponent

I am preparing to my Dev Teach talks, and I wanted to show a cool view component. Here is a sample of how it looks like now:

<%

component SmartGridComponent, {

      @source : customers,

      @displayAddress: false,

      @displayFax: false,

      @displayPhone: false

}

%>

I want to ignore some of the properties of the customer entity. This demonstrate both symbols in Brail (hmm, sounds like something else altogether :-) ) and using Convention over Configuration for this.

And here is a bit more complex example, showing how to display just the items that we want, in the order that we want:

<%

component SmartGridComponent, {

       @source : customers,

       @columns: [

              @customerId,

              @companyName,

              @contactName,

              @contactTitle

       ]

}

%>

And here is how I can override spesific behavior for the grid:

<%

component SmartGridComponent, {

       @source : customers,

       @columns: [

              @customerId,

              @companyName,

              @contactName,

              @contactTitle

       ]}:

       section customerIdHeader:

              output "<th>Id</th>"

       end

       section customerID:

       %>

       <td>${Html.LinkTo(item, "Customers", "ListOrder", item)}</td>

       <%

       end

end

%>

Here is how the last one looks like, by the way:

(Image from clipboard).png

Comments

Anders
04/05/2007 06:36 AM by
Anders

Is it possible to do something like @customerCompany.Name?

Ayende Rahien
04/05/2007 10:22 AM by
Ayende Rahien

It is not supported at the moment, but yes, that is trivially possible

Richard LOPES
04/05/2007 11:46 AM by
Richard LOPES

Hi,

I like this kind of code ! Looks like Rails.

In fact, Rails made me also build my components thinking convention over configuration. Simple ideas like that make our developer's lives easier !

I often think: Why should things be complicated ?

And what is a good programmer if not a lazy one ?

Thanks.

Jose
04/05/2007 12:44 PM by
Jose

Nice code to a nice result. Where can I find the SmartGridComponent?

Brendan Rice
04/05/2007 10:32 PM by
Brendan Rice

Nice work Ayende. Are you teasing us or are you going to show us the source?

I found this great link the other day, I just had to share:

http://icant.co.uk/csstablegallery/index.php?css=20#r20

Ayende Rahien
04/05/2007 10:38 PM by
Ayende Rahien

Definitely teasing, I have got a secret agenda that I want to carry on for a while

Ayende Rahien
04/07/2007 08:12 PM by
Ayende Rahien

@Jose,

http://rhino-tools.svn.sourceforge.net/viewvc/rhino-tools/trunk/SampleApplications/Exesto/Rhino.Components/

Adam B
04/12/2007 10:15 AM by
Adam B

I am using your smart grid component now exactly as you have described here albeit with NVelocity. It's really nice to use.

I was wondering, is it possible to add extra columns that are not bound to the source, such as an edit and delete column? Perhaps passing in an id for the $item value so to use $HtmlHelper.LinkTo('Edit', 'customers', 'edit', $item). I haven't been able to figure it out.

Simone Busoli
04/12/2007 08:44 PM by
Simone Busoli

Ever heard of Repeater, DataList and GridView?

Ayende Rahien
04/12/2007 08:49 PM by
Ayende Rahien

@Simone,

Why, yes I did.

Feel free to try to generate the same client UI for the grid view, I would be interested in seeing it.

The kind of things that I presenting here are nearly impossible to handle cleanly with those controls.

Simone Busoli
04/13/2007 12:19 AM by
Simone Busoli

Here's the code for a GrediView with the same UI.And you get sorting paging and a lot more for free:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1">

        <Columns>

            <asp:HyperLinkField DataNavigateUrlFields="CustomerID" DataNavigateUrlFormatString="ListOrder.aspx?id={0}"

                DataTextField="CustomerID" HeaderText="Id" SortExpression="CustomerID" />

            <asp:BoundField DataField="CompanyName" HeaderText="Company Name" SortExpression="CompanyName" />

            <asp:BoundField DataField="ContactName" HeaderText="Contact Name" SortExpression="ContactName" />

            <asp:BoundField DataField="ContactTitle" HeaderText="Contact Title" SortExpression="ContactTitle" />

        </Columns>

    </asp:GridView>
Ayende Rahien
04/13/2007 12:30 AM by
Ayende Rahien

@Simone,

Please check out this post:

http://ayende.com/Blog/archive/2007/04/08/Building-View-Components-For-MonoRail.aspx

Those are the capabilities that I am referring to, not just the basic of it.

Sorting and paging in the UI layer are a bad practice, mostly because it performs horribly the moment you put evena moderate amount of data into the system

Simone Busoli
04/13/2007 12:42 AM by
Simone Busoli

Looks to me like nothing you can't do with a Repeater as well, while a lot more like you're just trying to emulate what web controls do.

Ayende Rahien
04/13/2007 08:32 AM by
Ayende Rahien

Simone,

The idea here is not the formatting.

The idea is the ease of using presentation logic.

If I want to display in red based on a certain condition:

<% section customerName:

if Controller.IsCustomerInDebt(item):

 output "<td style='background-color: red'>${value}</td>"

end

end %>

Add several more condition, and a more complex UI requirements, and using web controls became a real PITA.

I did a screen cast on this subject, which you can watch here:

http://www.ayende.com/hibernating-rhinos.aspx

I hope it would make it clearer

Simone Busoli
04/13/2007 11:39 AM by
Simone Busoli

Didn't have time yet to check out your screencast, but I still don't get the point. Furthermore looks to me like your performing logic tasks in the view, what about using the ItemDataBound event of the ASP.NET web controls?

Ayende Rahien
04/13/2007 11:48 AM by
Ayende Rahien

The ItemDataBound event is the reason that I am calling this PITA.

You have to workaround the control model to get what you want.

Ayende Rahien
04/15/2007 11:38 PM by
Ayende Rahien

@Adam,

Yes, it is, just add them to the last column definition, and it would work

Adam B
04/16/2007 08:09 AM by
Adam B

Ah yes, thanks, this worked:

set ($cols = ["Code", "Company", "Website", "Description", "PrimaryKey"])

blockcomponent(SmartGridComponent with "source=$results" "columns=$cols")

#PrimaryKeyHeader

    <th></th>

#end

#PrimaryKey

    <td>$HtmlHelper.LinkTo('Edit', 'account', 'edit', $item)</td>

    <td>$HtmlHelper.LinkTo('Delete', 'account', 'delete', $item)</td>

#end

end

Tim Haines
04/29/2007 10:52 PM by
Tim Haines

Hi Ayende,

Interesting to see your work on this. The SmartGridComponent seems like it would be valuable to a lot of people that use Monorail. I've not yet grokked monorail enough to know if there's a place for contributed components? I'd like to use this, and extend it so clicking the column headers sorts the columns, add filters etc.

Having the component source live in a source repository for your demo app doesn't seem like a good place for a lot of people to reuse and improve it though.

What are your thoughts on this?

Cheers,

Tim.

hammett
04/30/2007 12:34 AM by
hammett

We could at least list them on http://using.castleproject.org

Ayende Rahien
04/30/2007 01:56 AM by
Ayende Rahien

The SmartGridComponent is going to move to the Castle Contrib, to a project that would aggregate all the common components.

I just need to dedicate some time to actually finish this...

How are you going to handle the sorting?

Comments have been closed on this topic.