Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Today Javascript application of a relevant size become more and more common, and as the need arises, certain patterns are identified to manage the code complexity.

I try to follow good advice, but I have some trouble in organizing the view layer of an application I am writing. While the other layers are nicely decoupled, I have a big blob for the UI that I would like to avoid. To make things clear, I am not talking of application the size Osmani (see the link above) considers - like Gmail - but still big enough to deserve a slightly better architecture.

My problem is that I have a lot of UI elements that I have to place. All these elements can have margins, paddings and so on, and I need to explicitly set their size, as the UI has a lot of constraint that are not expressible by CSS (for instance, some images have to be sized to that an integer number of them appears in a row, without blank space at the end). As if this was not enough, the size of some elements depends on how much space their container allows, and this may depend on the size of other elements and so on.

What I am doing right now is to compute the size of all elements every time the window size changes. I start from the first one, which I can compute freely. As soon as this is placed, I fire an event which trigger the computation of the second one and so on.

This approach more or less works, but is ugly as hell. Every function is full of code like

function resizeFoo() {
    var parent = $('#foo').parent(),
        parentWidth = parent.width(),
        availableWidth = parentWidth - parseInt(parent.css('padding-left'), 10);

    $('#foo').width(availableWidth);
}

only much longer. As soon as I add some right padding to #foo's parent, I have to update this. Of course, I could subtract the padding from both sides right from the start, making it event longer.

Are there any useful patterns to handle complex UI sizing and positioning requirements, so that I can reorganize all of the above mess into something meaningful?

share|improve this question
    
Use a CSS pre processor that's clever enough to be able to do this for you –  Raynos Dec 4 '11 at 13:55
    
Why are you messing with padding calculations yourself, instead of using the jQuery innerWidth function? –  kevin cline Dec 4 '11 at 20:52
    
Study the component layout systems of frameworks like extjs and dojo. –  Joeri Sebrechts Dec 4 '11 at 21:57
    
@kevin: you are right for this particular computation, but the point does not change. I still have to position a lot of elements depending on various element sizes. –  Andrea Dec 5 '11 at 8:48
    
@Raynos: I already use a CSS preprocessor, namely Sass, together with the Compass framework. Anyway, no matter how clever the preprocessor is, at the end of the day it always outputs CSS, and this has limitations. Unless one uses the new CSS3 layout properties (grid and so on), which are not available everywhere, there is no way, as far as I know, to do the following: give elements a size so that an integer number will fit in the given container, considering margins and a minimum and maximum on the size; give the ratio between the width and the height; give a parent the size of its first child –  Andrea Dec 5 '11 at 8:52

1 Answer 1

up vote 2 down vote accepted

I'm posting this as an answer instead of a comment, because it's somewhat big for a comment, even though it's not a true answer.

As I said in my comment, component frameworks like ExtJS and Dojo solve this problem. They can serve as inspiration. I'm personally familiar with ExtJS, so I'll give some pointers on where to find what you need for ExtJS.

Essentially everything in the UI of an ExtJS app is a subclass of Ext.Component (= box on screen), and Ext.Container (component subclass that can contain components). The Ext.Container lays out its child components using a layout (subclass of Ext.layout.Layout). Layouts use a combination of CSS, event-driven javascript, and structural markup (e.g. table tags) to achieve their goal. You always use the layout system, direct positioning with CSS is not "the ExtJS way".

To find out how they implement this:

  1. Explanation about the component model and lifecycle: http://www.sencha.com/learn/components/
  2. An explanation about the layout system: http://www.slideshare.net/senchainc/layouts-5971880
  3. The ExtJS API docs: http://docs.sencha.com/ext-js/4-0/#!/api

In the API docs you can click on the title of a component's API page to see its source code.

If you read your way through all that, you'll get some insight into how ExtJS solves this problem. It's not a simple mechanism, but it's a very scalable system.

share|improve this answer
    
Thank you very much: this looks very interesting. I will have a look at the references and let you know –  Andrea Dec 5 '11 at 10:03
    
Those links are very interesting. I am now trying to apply those ideas. Thank you very much. –  Andrea Dec 6 '11 at 16:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.