I gave a talk last week at Yahoo (at the request of the YUI team) all about the DOM. I outlined some of the reasons why the current situation is such a mess, outline some strategies for working around it, and then give some examples of real world code that’s being implemented in libraries today.
Video: John Resig: "The DOM Is a Mess"
Jonas Sicking (February 2, 2009 at 5:32 pm)
I’m always interested to hear if there’s anything we can do on the Firefox side to make things simpler. Now is a good time to speak up for getting things fixed/added to next version of firefox (after 3.1)
Dean Edwards (February 2, 2009 at 7:30 pm)
@Jonas
I think he works for your company. Maybe you can email him?
Hardik Varma (February 2, 2009 at 9:59 pm)
The deal on FF3 with appending a node from one document to another isn’t really a bug. It’s so because the DOM has the concept of document-node ownership, which is present in .NET as well.
Mark Zacher (February 2, 2009 at 10:19 pm)
Your cost/benefit graph for supporting browsers is laughable. 95% of the cost on the screen is supporting IE6 and IE7. Don’t you think that if those two were the only ones to support that there would be a great deal of simplicity? A huge cost is introduced when supporting real browsers like Firefox, then a minimal cost for tagging a few extra ‘real’ browsers like Safari and Opera on the end.
Like it or not, the reality of the world is that IE comes before the rest when “drawing a line in the sand”.
Jesse (February 2, 2009 at 10:24 pm)
@Mark
You’re obviously not a web developer. At any rate, did you pay attention to the slides after the graph? Dude how can you sit there and say IE6 doesn’t blo chunks.
John Resig (February 2, 2009 at 10:40 pm)
@Hardik Varma: Sure it’s a bug. Firefox doesn’t enforce that the correct context be set – which is contrary to the W3C DOM specification. That being said, just because it’s a bug doesn’t mean that it’s wrong (specifications can be wrong, of course).
@Mark Zacher: I’m going to side with Jesse here. When it comes to deviations from the published specifications, Internet Explorer is the absolute winner – and because of that developers are forced to spend significant amounts of time divining the exact problems that the browser embodies.
Larry Roth (February 2, 2009 at 10:51 pm)
@john Resig: I would support your argument. You didn’t say this explicitly, but the cost of going with IE as the “spec” would have a big impact in the forwards compatibility of your Web site. I would rather support an commonly agreed to standard–even if it lends it self to a bit of ambiguity–than support a standard that coincides with the “flavor of the month”.
mikeal (February 2, 2009 at 11:05 pm)
I think the main reason people develop on Firefox rather than IE and then do the IE work has less to do with implementation of standards or market share and more to do with the assortment of development tools for Firefox compared to IE.
I also think a lot of the pains people go through getting their code to work on IE has to do with a lack of tools as well, but this misses the point that if IE implemented the standards consistently the work load of doing compatibility between Firefox and IE would look more like the work between Firefox and Safari, which is much easier.
Ted (February 2, 2009 at 11:05 pm)
Use GWT?
skierpage (February 2, 2009 at 11:17 pm)
Great presentation. That mankz.com test is impressive, why is it on a DJ club remix site?
On the slide “Object Detection”: “Useful for detecting an APIs existence” — there’s a missing apostrophe in this possessive form of “existence of an API”.
Travis (February 2, 2009 at 11:32 pm)
I really enjoyed this talk John, thanks for posting! It was very interesting to listen to your techniques for browser capability checking and so on. Not only have you done so much toward making web developers’ lives easier, but you’re also keeping the browser vendors well informed about problems in their products too which is INCREDIBLY important.
And I certainly agree that IE (and IE 6 in particular) is the most painful browser to support… I’d be interested to know if Mark has ever had to deal with a memory leak before in IE 6 :P Here’s hoping the cost component of your chart is LOW for IE 8!!! Please Microsoft… please.
Jesse (February 2, 2009 at 11:32 pm)
Kudos to yahoo and John Resig for having this presentation. I personally think Yahoo should advise users to not use IE6 as Google recently has.
@Larry Roth I disagree with your use of the term “Flavor of the Month”. IE6/7 has had over 2/3 of all browser users for how many YEARS now? Once the browser’s out then there’s no hope in patching it because that’ll break the web. Non- Web Developers don’t know the agony of being a meticulous developer who appreciates standards/specs and we get stuck with pure garbage.
Gibson (February 3, 2009 at 1:12 am)
I will say what we are all thinking…
Go fuck yourselves, IE Team.
Dan Dorman (February 3, 2009 at 1:40 am)
Great talk, John!
I was struck, yet again, by how fortunate browser developers are to have such a vibrant open-source community making up for their products’ shortcomings; this is especially poignant in the case of IE, which generally requires the most special attention even as its corporate sponsor contributes the least back to the community.
Anyway, there’s a lot of good work going on in the land o’ the Javascript framework, and I’m grateful you’re so willing to share your knowledge, John.
Sudheer (February 3, 2009 at 1:54 am)
Wonderful presentation John. I really hope website owners start pushing their users to use browsers that are close to being standards compatible.
Michaël Lecerf (February 3, 2009 at 4:02 am)
@mikeal: You said that you think that the main reason people develop on Firefox first has much to do with the available development tools rather than the implementation of standards. I think just the opposite. People started to choose Firefox for its great implementation of standards and then development tools have been created to increase developers’ productivity (thanks to Firefox’s extension mechanism).
welefen (February 3, 2009 at 4:55 am)
Work Well,Make Test.
Make Fast,Do Thinking.
Louis (February 3, 2009 at 5:42 am)
@Michaël Lecerf: I agree. I develop with Firefox first and then test on everything else later. Yes, Firebug, Web Developer toolbar etc has a lot to do with it – but the main reason is that what’s in your head tends to work on screen quicker with Firefox, because of it’s standards-based design.
The IE6 issue is difficult at the moment. I develop for retail shopping websites, so compatibility with every browser is a must to maximise revenue. However, if we continue to make our sites compatible with IE6, despite it not being the current IE version, not only do we slow our own production, but users aren’t encouraged to upgrade to a more standards based (and let’s not forget SAFER!) browser.
Pete Austin (February 3, 2009 at 6:02 am)
Is there a transcript of this talk?
@IE Team (in the hope you’re reading this)
I don’t understand why you don’t you drop the existing aging IE codebase and rebuild based on WebKit? This would save Microsoft loads of money, help their reputation, and allow you guys to work on a leading-edge product. You shouldn’t take too long to add back any unique features you need, like support for ActiveX. This change would be a huge, huge, huge benefit for Web designers.
Oliver (February 3, 2009 at 6:27 am)
The talk is also available as a downloadable M4V from Yahoo UI Theatre: http://developer.yahoo.com/yui/theater/
Confused (February 3, 2009 at 7:38 am)
Great presentation. How do you use jQuery.data(elem, “events”) in Firebug console though? It does nothing.
John Resig (February 3, 2009 at 8:43 am)
@Pete Austin: There isn’t a transcript for the talk, as far as I know.
@Confused: You’ll need to use it on an element that actually has some events bound to it (otherwise it’ll return nothing). In my demo I was doing (if I remember correctly
$("ul.jq-checkpoints a").data("events")
on the jQuery homepage.Lucas (February 3, 2009 at 9:09 am)
Great presentation. It’s funny that DOM, one of the most powerful things of Javascript, is the one that’s giving us the most headaches.
Dustin Diaz (February 3, 2009 at 11:21 am)
Wow, what is up with people and comments these days…
congrats on your presentation John. I’m sure it went quite well :)
Oh, and hey, I was using jQuery on a Gmail prototype the other day (and not YUI for a change) (made me think of you ;). Cheers.
Alejandro Torras (February 3, 2009 at 11:24 am)
I absolutely agree with Mr. Lecerf and, as a web-developer, I think that the success of Firefox is that it works as expected in documentation, a well structured, simple, self-explaining and _correct_ documentation.
Adhering to the standards brings a common API and a unified behaviour of Firefox that has been designed by an experts comitee/community, ensuring (to some degree) quality and consistency.
Jean-Charles S (February 3, 2009 at 12:38 pm)
@John Resig Thanks for the presentation! Would it be possible for you to elaborate a bit on what you mentioned at the end regarding using a central data store for all events? It seems like this is an optimal solution to prevent event collisions and I’d love to know a little bit more about it.
John Resig (February 3, 2009 at 12:52 pm)
@Dustin: Great to hear! Hope you’re enjoying it :)
@Jean-Charles S: Actually, I’m going to be writing a chapter on it for my upcoming book on JavaScript and the DOM titled: Secrets of the JavaScript Ninja.
Ben (February 3, 2009 at 2:30 pm)
On slide 37, wouldn’t it be easier (and faster) to do the nodeType check for everything?
John Resig (February 3, 2009 at 3:15 pm)
@Ben: Easier, sure. Faster, definitely not. When we were able to remove that extra if statement from jQuery (for browsers that didn’t need it) it dramatically increased the performance of finding elements on the page. While I didn’t show it in my slide I also imply that you’ll be re-using this variable multiple times in your code (otherwise there’s no purpose to creating a variable in the first place).
Eric Ferraiuolo (February 3, 2009 at 3:21 pm)
I like your ideas about browser testing and how you choose which browsers to test. I recently updated my browser testing setup to handle dealing with future browsers like IE8 and wrote about my browser testing setup on my mac:
http://925html.com/techniques/browser-testing-ie-on-a-mac/
Lea Verou (February 3, 2009 at 4:11 pm)
Excellent presentation.
Lea Verou (February 3, 2009 at 5:04 pm)
I tried to test the bug you reported about Opera and document.getElementsByClassName() but either I misunderstood the bug, or they have fixed it in 9.63.
Here is one of my tests:
var prefix = 'someweirdstring';
var div = document.createElement('div');
var num = (new Date()).getTime();
div.className = prefix + num;
div = document.body.appendChild(div);
var ret = document.getElementsByClassName(prefix + num + ' ' + prefix + (num+1)).length;
document.body.removeChild(div);
alert(ret);
The result is zero as it should be. If every class but the first got ignored, then the result would be 1: The newly created div.
John Resig (February 3, 2009 at 5:35 pm)
@Lea: I uploaded a test here: http://ejohn.org/files/bugs/class/
^love *encounter ~flow (February 3, 2009 at 5:51 pm)
john, thanks for the great talk (that i just browsed thru for the sheer length of it) that rehabilitates hundreds of thousands of javascript dev guys who watched their (pre-js-framework days) apps fail in mysterious ways in popular browsers and came to thinking they were stupid—they are not. in this day and age, using a capable js framework, like yours, has become the sine qua non of writing in-browser code.
i am right now rewriting the (capability-wise fantastic) little typeface.js that does (great!) typography with canvas (i have tought the little critter to dynamically load character outlines from the server, among other things) and it is absolutely amazing to see how much even a not very long script profits in terms of readability and stability.
while i’m at it, it is not only the DOM, it is also the many subtle, well, err, bugturelets of javascript—things that work as advertised, but that were not done very wisely, or in easily comprehensible way—that can turn programming in javascript into an annoying way to pass time.
i had a nasty bug in my code where canvas dimensions would be weirdly off their expected value, and it took me considerable time to hunt it down. you’re often talking to people about pitfalls in javascript, so you might be interested in this one.—imagine a canvas that will show a single glyph outline in it. the script fetches the outline from the server, then sees how wide it is, then tells the canvas to stretch that wide, then draws the character, done.
it so happened i used a character with no outline in the database.
the way my app is written means that at the point in time when the ajax request returns, and did not bring along an outline for a given character, there will be an empty object there (waiting to be filled) which of course lacks metrics, so glyph.dx yields undefined.
one method in the script does some arithmetics with glyph metrics and should return a number that goes into the width attribute of the canvas. now there was indeed a canvas for that unsupported glyph, and it did look like <canvas width=’0′ …/>, which i had somehow expected, but in fact it was 300 pixels wide! a little research showed that where width is missing from canvas the browser assumes 300px, and where height is missing, 150px—in itself not a good idea imho.
i wanted to move away from attribute-based metrics and towards css-based metrics anyway, so i rewrote the attribute assignment as a css assignment, basically,
canvas.css( ‘width’, crunch_numbers( glyph.dx ) )
however, much to my surprise, wherever a missing glyph occurred, the canvas element style rules were now completely *missing* the width rule!
the solution to the riddle was as follows. javascript defines no less than four different NULL-like values—one called null, then undefined, NaN, and infinity. turns out the missing glyph.dx caused one equation to read like ( undefined * 42 ), which is Not a Number. now when you assign that to an attribute (like width), what you get is a zero—but, feed it to a css style rule, and you get naught, zilch, nothing. silently.
this is egregious. javascript throws errors and stops dead in its tracks on the slightest omission or oversight in syntax or some other holied rules. but when you divide by zero you get infinity. when you multiply with undefined you get “Not a Number”—which then, it depends, vanishes into thin air OR gets expressed as zero WHICH IS THEN INTERPRETED AS NUMBER THREE HUNDRED BY THE BROWSER!!!
the “beauty of javascript” is, for me, best expressed by the formula,
42 * undefined = NaN = 0 = 300 = (zilch)
i have little to say in favor of such arithmetics.
Lea Verou (February 3, 2009 at 5:53 pm)
Ohh! I had misunderstood the bug.
The actual one is much worse than my misconception!
And it even exists in Opera 10 beta!
S*** :(
^love *encounter ~flow (February 3, 2009 at 5:57 pm)
quick correction: “””where width is missing from canvas the browser assumes 300px …”””—read as: <canvas width=’0′ height=’0’/> is displayed exactly like <canvas width=’300′ height=’150’/> (it is fine to assume default dimensions where explicit dimensions are missing, but to read width=’0′ as width=’300′ is plain crazy).
John Resig (February 3, 2009 at 6:23 pm)
@^love *encounter ~flow: Aren’t browsers great? Hahaha. I can definitely commiserate with you, though.
@Lea: Yeah, sucks doesn’t it? :(
Lea Verou (February 3, 2009 at 6:27 pm)
This Opera bug is going to drive me crazy…
John, try changing the class named “a” with “b” in your test (obviously in both places), the bug seems to magically disappear! :-S
The only pattern I can find (and I’m not sure yet) is that if the 2nd class name is a substring of the first class name, the bug occurs, otherwise it doesn’t. :-S
John Resig (February 3, 2009 at 6:34 pm)
@Lea: You know what I bet they do? I bet their internal code looks something like this:
for ( var i = 0; i < classes.length; i++ ) {
if ( classes[i].indexOf(name) > -1 ) {
return classes[i] === name;
}
}
It doesn’t really make sense – but that seems to be close to what’s happening here.
Josh (February 3, 2009 at 7:05 pm)
So should “Array.prototype.indexOf” be avoided? I use it quite a bit.
Sorry if that sounds moronic.
Adam Schwartz (February 3, 2009 at 9:07 pm)
@Michaël Lecerf & mikeal: I think it was a little of both. Firebug was not developed for Firefox (and not IE) solely because Firefox followed standards more closely than IE. That having been said, there does exist DebugBar and several other pretty good development tools for IE. But developers I know still prefer Firebug/Firefox because there is a stronger feeling that “things will work like you expect them to” in Firefox than there is in IE.
John Resig (February 3, 2009 at 10:54 pm)
@Josh: It depends. In the case of indexOf it exists in JavavScript 1.7 (meaning that browsers that support it include the method). I would say that if you wanted that method you could add it in browsers that didn’t support it – as long as you matched the spec. Of course, that isn’t really something that I would do (personally) but I would leave it up to your prerogative. As a whole I like having less clutter up the global object and other extension points. And, if you think about it, is it really that much harder just having an indexOf function that accepts an array and an object to find as input?
Michaël Lecerf (February 4, 2009 at 4:11 am)
@Adam Schwartz: I agree. Of course, the reality is not as simplistic as what I said in my previous post. Firefox’s good standards implementation is not the only reason why excellent development tools have been created for it. We should not forget the Open Source aspect nor the extension mechanism. But, before we had such tools (or before those tools became well known among the Web developers), using a browser with the best implementation of standards as possible was the safest way to make things that work as expected. And today, if you want to follow Web standards, it is still logical to develop in a good browser (Gecko or Webkit based, or Opera for example) first and to fix some issues in IE after that.
sunnybear (February 4, 2009 at 5:34 am)
and no word about speed or efficiency. Most of proposed ways are slow — so we need to find a compromise (expecially for IE).
John Resig (February 4, 2009 at 9:08 am)
@sunnybear: How do you mean? I assume that you’re talking about feature simulation. jQuery now has a full battery of feature simulation tests (removed in place of using browser sniffing). In our tests we found that it takes approximately 4ms to run when the script is first loaded – which is a perfectly reasonable sacrifice to make to be able to have the script continue to work long into the future.
Lea Verou (February 4, 2009 at 2:35 pm)
Having an indexOf function that accepts both parameters (the haystack and the needle) would be equally easy, sure. BUT, given that we also try to reduce globals, we’d have to namespace it, so we would end up with something like foo.indexOf or even worse, foo.bar.indexOf, and that IS quite harder to type…
As for matching the spec, Mozilla developer center provides javascript code for the new array methods so that they can be implemented for non-supporting browsers as well: https://developer.mozilla.org/en/New_in_JavaScript_1.6
Josh you could use those. :)
By the way, as one can easily notice from the above URI, indexOf was firstly added to JavaScript 1.6, not 1.7 :)
I always wanted to ask you John, are potential collisions the only reason that you frown upon augmenting prototypes (Object.prototype is out of the question of course, I’m mostly asking about the Array, String and Function prototypes) or are there other reasons too?
PS: If something doesn’t make much sense bare with me, my native language isn’t English (sadly). :(
Josh Rehman (February 5, 2009 at 4:01 pm)
I think your talk was great for library developers, but also for users of jQuery who want to know how it works (like me). I think I speak for all users to say we are remarkably lucky to have you and the other jQuery committers so, er, committed to keeping up with the DOM Mess so that we application programmers don’t have to. (Well, we still have to worry about CSS incompatibilities!)
I particularly liked your elucidation of “feature simulation” and it’s benefits. It’s an approach that is handy not just for JavaScript but for any software designed to run in strange and interesting places. It occurs to me that an approach like GWT actually cannot do this. In fact, because GWT compiles for target browsers, presumably whenever a browser feature changes the application must be recompiled and redeployed. Of course, it could support feature detection but it would be a huge change for them (they implement a DOM class per browser, IIRC. They would have to move to a single feature detection DOM, which would remove a lot of the compile time goodness GWT gives.)
I didn’t fully understand your solution for inline script execution, or your earlier comment about “pages that use Object prototype”. Did you mean just pages that mutate the Object prototype?
Sarath (February 6, 2009 at 12:47 pm)
@John,
Excellent talk. I have a question about the sizzler engine. I was looking at the sizzle.js. Couldnot make a thorough examination, However, I have a real small suggestion that may improve the selection performace a lot in a huge page.
When a deep selection has an ID selector we could use a sub context to call find() to start with. For Example..
<div>
<div>
<div id="one">
<div>
<div>
<div id="two"><p><a href="#">Something 1</a> </p></div>
</div>
<a href="#">Something 2</a>
</div>
<a href="#">Something 3</a>
</div>
<a href="#">Something 4</a>
</div>
<a href="#">Something 5</a>
</div>
For
Sizzler("div div #two a")
find() would give all 5 “a”s orginally, if we use the sub context to find(only) it will return 1.
Something like..
var startCtx = context;
while ( (m = chunker.exec(selector)) !== null ) {
parts.push( m[1] );
//if there is an id in a deep selection, start filter from there
// okay.. this may look a little ancient, but you get the idea.
if(m[1].charAt(0) === '#'){
startCtx =
document.getElementById(m[1].substr(1));
}
if ( m[2] ) {
extra = RegExp.rightContext;
break;
}
}
And use this startCtx in find(). This will limit the selection to the last id selector to only those under it. Reducing the number of matches to do later.
The matching rules on the left of ID selector will apply as normal (use original context). I don’t have an idea on the full code for this but may be this will do some improvement.. What do you think?
Simon Kenyon Shepard (February 7, 2009 at 3:43 pm)
Hey John,
You mentioned a really interesting bug that I didn’t know about with IE, the one where you give an ID to a element that is also a native JavaScript property, and it overwrites it i.e. id=”length” – Is there a list of element properties – it would be great to role this check in to a JSlint style validator plugin so we can avoid conflicts in the future, or even have it as an element of a test suite that you can run your HTML through.
Cheers
Garrett Smith (February 8, 2009 at 7:15 pm)
Hi John,
Did you try running the code in the section “Figure Out Naming”?
Internet Explorer will return an object for getAttribute(“style”).
The test:-
if(div.getAttribute(“style”))
– will be true in IE and pretty much everywhere,
div.getAttribute(“cssText”)
– will be false in all browsers.
There is a bug in IE. IE returns an Object for getAttribute(‘style’). In IE, getAttribute does the same thing as property access.
See also:
http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/GetAttributeImplementation.html
and
http://groups.google.com/group/comp.lang.javascript/msg/0f946d014fed1b33
To set multiple values, use the style.cssText property:
document.body.style.cssText = “background: #0f0;border: 10px solid #990”;
Calling el.setAttribute(“cssText”, “color: red”), in any browser will result in the attribute “cssText” being created and having a string value: “color: red”. There will be no visual update of the document in any browser.
Here is your code:
style attribute
var STYLE_NAME = (function(){
var div = document.createElement(‘div’);
div.style.color=”red”;
if(div.getAttribute(‘style’) ) {
return ‘style’;
}
if( div.getAttribute(‘cssText’) ) {
return ‘cssText’;
}
})();
document.writeln(STYLE_NAME);
Will result “style” in all versions of FF, IE, Op, Saf, Seamonkey
Determining “Load Time Constants” is an excellent idea. The example does not even come close to doing it justice. Method setAttribute should not be needed (setAttribute is broken in IE as the c.l.js post explains). Best just access the style object directly from the element.
Another example:-
var dom = {};
dom.textContent = “textContent” in document.documentElement ? “textContent” : “innerText”;
can be later used:
el[dom.textContent] = “new text”;
Useful concept, just not a practical example.
Next: XPath:
with xPath, there is an id() function that is not slow.
The approach of converting html “adapt” to something standard seems a little heavy. A TD must be in a TR, etc. Of course. Knowledge of basic HTML is a prerequisite to RIA development. A library that attempts to cater to ignorance by trying to correct the authors’ HTML mistakes does so at the cost of efficiency. Simply setting innerHTML will work in most cases.
el.innerHTML = s;
Testing in IE will reveal the cases where it does not work. A general purpose solution to try and fix all the bugs in IE would be less efficient.
@Simon, yes there is such an article.
http://jibbering.com/faq/names/
Regards,
Garrett
carlos (February 9, 2009 at 6:22 am)
as everyone should know event listeners are pretty unuseful, you can write everything without them.they are commonly seen in js libraries for helping people to write code, but on a more specific basis they are completely useless and dont work properly if being stacked, a simple: window.onload=function(){“stack here your functions”} works perfectly.
event listener were created a couple time ago , it is funny to see that actionscript as adopted “eventlisteners” as there main “function” driven “object”.
carlos (February 9, 2009 at 1:32 pm)
for XHR event listeners might be cool:
# var req = new XMLHttpRequest();
#
# req.upload.addEventListener(“progress”, updateProgress, false);
# req.upload.addEventListener(“load”, transferComplete, false);
# req.upload.addEventListener(“error”, transferFailed, false);
# req.upload.addEventListener(“abort”, transferCanceled, false);
#
# req.open();
(but this only work in ff)
but arent those events just the same as the ones native to xhr?
but for the other stuff they are pretty old trick..
raymond (February 9, 2009 at 1:42 pm)
Hello,
I’ve been looking at the some of the HTML 5 tags and have been reading about some of the great things that can be done with the tag. Opera is even planning on adding hardware support for canvas.
How about adding video support to the tag and drop the need for ?
or
or
Another idea would be the ability to play a images stream:
The movie.zip would contain a list of png images.
Tim (February 9, 2009 at 4:43 pm)
I picked up on a brief reference towards the end (when you took questions) about identifying functions as having a ‘call’ method..
Have you tackled, or experienced the problem with native IE functions being typeof ‘object’ and having no call method? This has driven me up the wall in the past! (IE native functions bug?)
Kent (April 22, 2009 at 10:19 am)
Great presentation. I seem to get stuck building sites for companies with a loyal following of IE6 users and I couldn’t agree more with the idea of reducing the number of assumptions with cross-browser development. It’s a great way of putting it that will be a great way to explain it to my junior-level developers.
shamun (May 1, 2009 at 4:14 pm)
As new or experts still jquery is mess because you have libraries and then UI plugins which are growing daily as mess.
why not keeping it simple like java or vb.net GUI ?
code:
$(document).ready({
// Lets make a GUI simple
$(gui.form1).create.visible = show;
$(gui.form1.grid1).create.visible = show;
($(gui.form1.button1).top = $(gui.form1.grid1).height + 400; ).show();
// Lets apply actions
$(gui.form1.button1).submit or click = function () {
// load data or read data to grid via ajax from local drive or server script
}
class myClass {
private var1;
public var1;
public function() {}
}
// etc…………
// somthing gentle and very simple programming
// rather then mess plugins collect etc etc
});