Building a Better Server Control Experience, Part 1

Building a Better Server Control Experience, Part 1
Your Code Is Broken..... Or Is It? A Look At Coding For The Requirements

You know, I've seen some great server controls out there. The problem that I find is, people don't take enough time to engineer complete solutions around them. They demonstrate some functionality, and they're done. Darren Neimike confessed to this earlier this week in a really nice defense to Paschal's seven-post rampage earlier this week.

So I push pretty hard to get others to really brainstorm and completely reason out the entire process, from start to finish. A lot of times, controls suffer from “feature bloat” just to be able to jack up the price. Case in point: the competing control that was brought up called SuperGrid, is a scrollable, paging DataGrid, and it costs $150. Now let me ask you, do you REALLY need paging in a DataGrid that scrolls? Isn't that the POINT of making it scroll?

It's those things that really bother be. Asking me to pay $150 for a DataGrid that isn't even remotely cross browser compatible AND has too many features is just lame. So I try to make my components compelling in both features and price. But I've never focused on “Conceptual Completeness”, which is a topic I'll discuss today with server controls.

One of the things that was pointed out out the other day was the fact that the columns do not line up properly in my ScrollingGrid Demo. While at first glance, this would appear to be a flaw in the control, that is not the case. To understand why, you first have to understand the requirements for the control as a marketable commodity, and the limitations of rendering HTML in the browser.

Requirements for a 100% concept-complete, reusable Scrolling DataGrid control:

  1. Must not reinvent the wheel.
  2. Must not involve complex configuration (wiring up other controls, JavaScript files, etc)
  3. Must be completely server-side (must not use any client-side script to alter rendering)
  4. Must be cross-browser compatible.
  5. Must support all existing DataGrid functionality/extensibility (custom columns, sorting, databinding, programmatic access, etc)
  6. Must work with existing DataGrid declarative code.
  7. Header and footer must be extended to encompass addition of scrollbar (so it appears to be one unit)
  8. Must be completely self-contained (no external resources)
  9. Must be able to upgrade existing Datagrids by only changing the tag definition ( --> )
  10. Must be able to turn all enhancements off, declaratively or programmatically

Now stop for just a second and think about the process. Would you have taken the time to brainstorm all the requirements for a dinky little $10 control? Maybe, but I'm going to bet no, having seen what else is out there. That's the difference between a proof-of-concept (AKA a smoke-and-mirrors demo) that gets turned into production code, and a true solution.

This list is in order of priority. This process is extremely important, and essential to writing any complete solution. Many of the requirements are related. This can happen sometimes, but you must resist the tendancy to put them all into one requirement line-item. You must resist this, and break each requirement down to its most basic form. Now, I will discuss these elements in the order I just described.

1) Must not reinvent the wheel.
There is already a Datagrid written. It could use internal improvements, but it works. No need to write another one, and any attempt to do so would be out-of-scope for the problem that is being addressed. Therefore, the only course of action is to inherit the existing DataGrid and modify it's rendering functionality.

2) Must not involve complex configuration.
What's the point of a really cool control if it's too hard to use?

3) Must be completely-server side.
In my first post about ScrollingGrid, I talked about the Panel.htc behavior, and how our proof-of-concept demo utilized it in it's operation. But a proof-of-concept is just that. Using an HTC does not constitute a componentized solution, and you would still have to rebuild the headers manually to achieve the desired solution. Because we would be dealing with different browsers, I didn't want to deal with JavaScript compatibilities between browsers. So any of the basic re-rendering functionality had to be done solely on the server. There is also a great write-up on the client-side issues of this concept. This document was key to making the server-side only decision.

4) Must be cross-browser compatible.
Behaviors and CSS adjustments are not acceptable, because they are not supported on all browsers. Instead use the built-in browser compatibility system to render compatible objects.

5) Must support all existing DataGrid functionality/extensibility.
The worst thing we could do in trying to get this control on everyone's desktop is by breaking code that already works. By meeting requirement #1, this requirement was basically met as well. Therefore, you can add ScrollingGrid capabilities to any existing extension of the DataGrid by inheriting from Interscape.CodesideAssistance.ScrollingGrid instead of System.Web.UI.WebControls.ScrollingGrid

6)Must work with existing DataGrid declarative code.
Similar to #5, we wanted people to be able to use the same column definitions, CSS, templating, etc. to define their grids. This criteria would be met through meeting criteria #1 and #4, but it was an issue nonetheless.

7) Header and footer must be extended to encompass addition of scrollbar.
Ladies and gentlemen, welcome to the reason this control is harder to code than it looks. For the control to appear to be a single functional unit, the header and footer rows must extend beyond the data area to “butt up” against the far right edge of the scrollbar. Otherwise, it just looks retarded.

8) Must be completely self-contained.
Following up on Requirement #3, there cannot be any external resources for the control. One of the biggest support issues for Cyberakt's controls is their reliance on external JS files for browser cacheability. Typically, when a user upgrades to a newer version of ASPnetMenu, they forget to upgrade all of their JS files as well, causing cryptic error messages like “The variable 'aspnm_mac' does not exist.” If we needed any external files, there would have to be a near-zero configuration way to access them from the assembly.

9) Must be able to upgrade existing Datagrids by only changing the tag definition.
This one's pretty self-explanatory. The single-best usability feature is our ability to tie Requirements #5 and #6 together into a compelling solution for your DataGrid. You can leave everything inside your tags alone, you should only need to change the actual tag declaration.

10) Must be able to turn all enhancements off, declaratively or programmatically.
This one is also a no-brainer. If people start using ScrollingGrid in place of the standard grid, they have to be able to make it render normally if they so desire.

Now, those may not be the only requirements, but the work that was just done represents a well thought out, complete idea. Now that we've defined the requirements, let's see the rammifications of the decisions we made. These are typically referred to as risks:

  • Requirement #3 will cause big problems for rendering in situations where the grid dimensions are not clearly defined or not available.
  • Requirements #5 and #6 mean that we can't do anything that will break other code.
  • Requirement #8 will become a problem, partially because of Requirement #2, if client-side code is needed for non-rendering features.

So, you've seen the problems with client-side grid manipulation, and you've seen our requirements and risks. Now we tackle the question: Why are the columns not aligned better in the ScrollingGrid demo? Well, the server-side solution means that we have to hijack the header rendering and completely replace it. In explicitly declared grids (the kind where columns are not autogenerated and rows , this is not usually an issue. (I say usually, because it can obviously be a problem). Because of the way the HTML is rendered, if the containing object's width is different than the sum of the children (in this case the cells), the browser may make [currently] unpredictable adjustments. Now, because of Requirements #3 and #4, using JavaScript is not an option for manipulating the grid rendering on the client. That functionality will be available for the Whidbey version of this control, to make use of the slick new adaptive rendering architecture. I may change that decision, but for now I feel it is the best decision to make.

Now, we handle the other scenarios (ones where we don't know the width) as best we can on the server side, determining visible columns and adjusting everything accordingly. It works very well, but again, it requires an undetrstanding of the limitations of HTML and work accordingly. Sure, you can slap on a DataGrid to a form and bind it quickly without specifying your columns and formatting, but that is really only for prototyping scenarios. In a final application, all your code should be completely fleshed out, including datagrid columns, widths, styles, and other UI details.

So, the route we have chosen is one of customer education. Our user's guide covers these scenarios, and helps people understand WHY it is the way it is. Some of it is of choice, but most if it is out of necessity. The better they understand it, the more effectively they'll be able to utilize the control. Any maybe someday one of our customers will show us how to do it even better.

So, you've seen a relatively simple concept fleshed out into a complete solution. Over the next several posts, I'll be discussing some of the little details that make all the difference in offering a complete server control solution. Will we be giving away some of our secrets? Yes. Will a better server control ecosystem exist because of it? I certainly hope so.

1 Comment

  • to the question:



    -----

    Now let me ask you, do you REALLY need paging in a DataGrid that scrolls? Isn't that the POINT of making it scroll?

    -----



    I think so. We built a grid with the same kind of features, and I struggled with the same question in the beginning. But, after playing around, we really needed both.



    Paging is a design that promotes scalability and site performance.



    Scrolling is needed when you want to place content to the right, or below the grid, or limit the grid to a specific size/layout despite the size of the grid's content.



    Using both turned out to be our best option.

Comments have been disabled for this content.