By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,742 Members | 1,206 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,742 IT Pros & Developers. It's quick & easy.

JavaScript GUI library idea

P: n/a
Hi,

I've been asking questions about library design over the last week and
would like to get feedback on my overall idea for a JavaScript GUI
library. I need a nice GUI library so there is a good chance I will
write this as I need new widgets. I haven't found anything like this
and I'm surprised/disapointed this doesn't already exist. My library
prototype works nicely. I think parts of these ideas are not commonly
used for JavaScript library development and before I dive in too deeply
any experienced advice might make my efforts a lot better.

While trying to develop a rich GUI for a web app backend I started
needing a large set of GUI widgets that behaved and were coded
similarly. Things like flyout menus, drop down menubars, tree menus,
adjustable table widths, spinners...all the things that are in Java
Swing or other GUI widget libraries. Yes I know all of these things
exist individually as JavaScripts but I would like to build a library
that uses a class hierarchy structure and inheritance to take advantage
of all the nice OOP ideas of encapsulation etc. Certainly this library
will be different than a desktop app GUI library since HTML, CSS and
the browser already provide a lot of what is needed (<ul>'s for menus,
<table> for tables, all sorts of font display stuff, some form
elements). In JavaScript we are adding functionality on top of what the
browser already gives us.

This could end up being a big library but if each class is in it's own
file and the class hierarchy is known then people could string together
only the pieces they need. I would like a develop a way to automate
this step. Something like compiling one JavaScript file with all you
need for your page from the big library.

For JavaScript inheritance I want to use these ideas
http://www.kevlindev.com/tutorials/j...t/inheritance/

I will use one namespace for everything. My library will not interfere
with other libraries.

No direct extending of Function or Array and breaking stuff like
Prototype.js does. Instead I will subclass these as necessary and
extend in the subclass. Directly extending Function or Array would not
go well with my namespace requirement.

No monolithic support script like Prototype.js that tries to turn
JavaScript into Ruby or Python or whatever. Just JavaScript.

All machinery CSS (the stuff that makes the items work eg. display:none
or display:block) inserted with JavaScript and the DOM into the tag's
style elements so that they have specificity 1,0,0,0. This way a user
of the library cannot override without using !important in their CSS
rules.

Separation of machinery CSS and the rest of the JavaScript with the
idea that every change to a DOM element's style attribute is and
"effect". So all the effects will be tucked away nicely in a single
Effects object. This one object will be the only place to look for
browser specific hacks. Hacks can be reused by composite effects.

A default set of CSS files for the pretty stuff that can be overridden
as desired by the library user in their own style sheets. This has
lowest possible specificity so these rules are easily overridden.

Two library interfaces. One advanced interface that allows access to
widget options through a single line of JavaScript per widget.

<head>
<script type="text/javascript" src="seriousWidgets.js"></script>
</head>
<body>
<ul id="myMenuBar">
<li>item 1<li>
<li>item 2<li>
<ul>
<script>
var my_menu_bar = new
Serious.MenuBar(document.getElementById("myMenuBar "),
{option1:value1,
option2:value2});
</script>
</body>

A second interface, a completely non-obtrusive facade for those who
want to avoid JavaScript at all costs and have widgets that function in
standard ways. Appearance still easily overridden with CSS.

<head>
<script type="text/javascript" src="easyWidgets.js"></script>
</head>
<body>
<ul class="easyMenuBar">
<li>item 1<li>
<li>item 2<li>
<ul>
</body>

Any thoughts, ideas, cautions or warnings appreciated.

Thanks,
Peter

Mar 25 '06 #1
Share this Question
Share on Google+
21 Replies


P: n/a
pe**********@gmail.com wrote:
I've been asking questions about library design over the last week and
would like to get feedback on my overall idea for a JavaScript GUI
library. I need a nice GUI library so there is a good chance I will
write this as I need new widgets. I haven't found anything like this
and I'm surprised/disapointed this doesn't already exist. My library
prototype works nicely. I think parts of these ideas are not commonly
used for JavaScript library development and before I dive in too deeply
any experienced advice might make my efforts a lot better.
It does not work without client-side script support which is its major flaw.
While trying to develop a rich GUI for a web app backend I started
needing a large set of GUI widgets that behaved and were coded
similarly. Things like flyout menus, drop down menubars, tree menus,
adjustable table widths, spinners...all the things that are in Java
Swing or other GUI widget libraries.
XUL and HTA exist.
Yes I know all of these things exist individually as JavaScripts but I
would like to build a library that uses a class hierarchy structure and
inheritance to take advantage of all the nice OOP ideas of encapsulation
etc.
Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
classes.

<URL:http://javascript.crockford.com/inheritance.html>
Certainly this library will be different than a desktop app GUI library
since HTML, CSS and the browser already provide a lot of what is needed
(<ul>'s for menus, <table> for tables, all sorts of font display stuff,
some form elements).
You are misunderstanding a Web browser as an application platform.
In JavaScript we are adding functionality on top of what the browser
already gives us.
Which is why graceful degradation is possible.
[...]
For JavaScript inheritance I want to use these ideas
http://www.kevlindev.com/tutorials/j...t/inheritance/
Factually wrong.
I will use one namespace for everything.
Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
namespaces.
My library will not interfere with other libraries.
You cannot ensure that.
[...]
All machinery CSS (the stuff that makes the items work eg. display:none
or display:block) inserted with JavaScript and the DOM into the tag's
style elements so that they have specificity 1,0,0,0. This way a user
of the library cannot override without using !important in their CSS
rules.
[...]
<head>
<script type="text/javascript" src="seriousWidgets.js"></script>
</head>
<body>
<ul id="myMenuBar">
<li>item 1<li>
<li>item 2<li>
<ul>
<script>
var my_menu_bar = new
Serious.MenuBar(document.getElementById("myMenuBar "),
{option1:value1,
option2:value2});
</script>
</body>
This feature, which does not allow for graceful degradation, is required
only for current IEeeks, and hopefully not for its future versions. CSS
can do the work in all other UAs, and allows for graceful degradation.
A second interface, a completely non-obtrusive facade for those who
want to avoid JavaScript at all costs and have widgets that function in
standard ways. Appearance still easily overridden with CSS.
Nonsense. Both birds can all be killed with one stone.
Any thoughts, ideas, cautions or warnings appreciated.


[x] done
PointedEars
Mar 25 '06 #2

P: n/a
PointedEars,

Thanks for the reply. I'm interested in a bit of expansion on the
things you mentioned.
Thomas 'PointedEars' Lahn wrote:
Peter Michaux wrote: It does not work without client-side script support which is its major flaw.
I'm requiring the user has a browser released in the last couple years
and have turned javascript on. Is that unreasonable for a javascript
library? Do you consider all of your scripts as "majorly flawed"?
Perhaps I missed your point.
XUL and HTA exist.
These look specific to Mozilla and IE, respectively. If that is true it
doesn't cut it for what I want to do.
<URL:http://javascript.crockford.com/inheritance.html>
Thanks for the link.
For JavaScript inheritance I want to use these ideas
http://www.kevlindev.com/tutorials/j...t/inheritance/


Factually wrong.


Why is it factually wrong? I am very interested in justified criticisms
of this method.
Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
namespaces.


I mean simulated namespaces like
http://blog.dreamprojections.com/arc...12/27/450.aspx
[...]
All machinery CSS (the stuff that makes the items work eg. display:none
or display:block) inserted with JavaScript and the DOM into the tag's
style elements so that they have specificity 1,0,0,0. This way a user
of the library cannot override without using !important in their CSS
rules.
[...]
<head>
<script type="text/javascript" src="seriousWidgets.js"></script>
</head>
<body>
<ul id="myMenuBar">
<li>item 1<li>
<li>item 2<li>
<ul>
<script>
var my_menu_bar = new
Serious.MenuBar(document.getElementById("myMenuBar "),
{option1:value1,
option2:value2});
</script>
</body>


This feature, which does not allow for graceful degradation, is required
only for current IEeeks, and hopefully not for its future versions. CSS
can do the work in all other UAs, and allows for graceful degradation.


"IEeeks"? Don know that one.

Why does this code not allow for graceful degradation?
A second interface, a completely non-obtrusive facade for those who
want to avoid JavaScript at all costs and have widgets that function in
standard ways. Appearance still easily overridden with CSS.


Nonsense. Both birds can all be killed with one stone.


The reason for the two interfaces is efficiency. If a user will not use
the easyWidgets interface then there is no point in having the
javascript search through the html for tags with className including
"easyMenuBar" etc.

Thanks,
Peter

Mar 25 '06 #3

P: n/a
pe**********@gmail.com wrote:
Thomas 'PointedEars' Lahn wrote:
Peter Michaux wrote:
It does not work without client-side script support which is its major
flaw.
I'm requiring the user has a browser released in the last couple years
and have turned javascript on. Is that unreasonable for a javascript
library? Do you consider all of your scripts as "majorly flawed"?
Perhaps I missed your point.


Requiring a recent browser, and requiring it to have client-side script
support enabled are two different things. Especially with IEeek (see
below) and RadioActiveX (I think you get the idea). We really discussed
this ad nauseam here before. Search the archives about that, and search
them for UI library discussions. You are by far not the first person
(here) who thought of this, tried it and, inevitably, failed. Reading that
will probably help you investing your time in something that makes more
sense.
> For JavaScript inheritance I want to use these ideas
> http://www.kevlindev.com/tutorials/j...t/inheritance/


Factually wrong.


Why is it factually wrong? I am very interested in justified criticisms
of this method.


For example, there are no classes and no subclasses in the languages
supported by the execution environments you target. And the init()
approach, probably copied without minimum clue from the Prototype junk
code, is nonsense. The language already has constructors for that.
Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
namespaces.


I mean simulated namespaces like
http://blog.dreamprojections.com/arc...12/27/450.aspx


As I said, those are not namespaces. Using a user-defined container
object for other user-defined objects is a better approach than declaring
everything global, that is for sure. But there is no guarantee that there
will be no interference with other, unknown libraries. The dynamic nature
of ECMAScript 1-3 implementations does not allow for such restrictions.
> [...]
> All machinery CSS (the stuff that makes the items work eg. display:none
> or display:block) inserted with JavaScript and the DOM into the tag's
> style elements so that they have specificity 1,0,0,0. This way a user
> of the library cannot override without using !important in their CSS
> rules.
> [...]
> <head>
> <script type="text/javascript" src="seriousWidgets.js"></script>
> </head>
> <body>
> <ul id="myMenuBar">
> <li>item 1<li>
> <li>item 2<li>
> <ul>
> <script>
> var my_menu_bar = new
> Serious.MenuBar(document.getElementById("myMenuBar "),
> {option1:value1,
> option2:value2});
> </script>
> </body>


This feature, which does not allow for graceful degradation, is required
only for current IEeeks, and hopefully not for its future versions. CSS
can do the work in all other UAs, and allows for graceful degradation.


"IEeeks"? Don know that one.


IEs. User agents based on Microsoft Internet Explorer. Its layout engine
is this badly borken and its API is this flawed that some people, including
me, tend to think "Eeek" when talking about developing for it. And since
IE7 is not going to be released for Windows 2000 and earlier, it is
probably going to stay that way.
Why does this code not allow for graceful degradation?


Because there will be no menu without client-side script support.
Which can be easily avoided with a design approach that took more
consideration to develop.
> A second interface, a completely non-obtrusive facade for those who
> want to avoid JavaScript at all costs and have widgets that function in
> standard ways. Appearance still easily overridden with CSS.


Nonsense. Both birds can all be killed with one stone.


The reason for the two interfaces is efficiency. If a user will not
use the easyWidgets interface then there is no point in having the
javascript search through the html for tags with className including
"easyMenuBar" etc.


Efficiency and maintenance considerations are the reason why this should be
done with one script version, if that. One version that uses client-side
scripting only if necessary in the first place. It has been done before.

And, reconsidering this, for more recent IE versions apparently it can
be done without client-side scripting, too. The most recent and most
convincing example posted here that I can remember is

<URL:http://www.cssplay.co.uk/menus/dd_valid.html>
HTH

PointedEars
Mar 25 '06 #4

P: n/a

Thomas 'PointedEars' Lahn wrote:
Requiring a recent browser, and requiring it to have client-side script
support enabled are two different things. Especially with IEeek (see
below) and RadioActiveX (I think you get the idea). We really discussed
this ad nauseam here before. Search the archives about that, and search
them for UI library discussions.
Unfortunately I did not have a fruitful search with those key words.

You are by far not the first person (here) who thought of this,
tried it and, inevitably, failed.
Failed due to developing for a moving target of browser support?

Reading that will probably help you investing your time in
something that makes more sense.
What would make more sense for a GUI widget library? Or do you think
JavaScript GUI widgets are a waste of time?

For JavaScript inheritance I want to use these ideas
http://www.kevlindev.com/tutorials/j...t/inheritance/

Factually wrong.


Why is it factually wrong? I am very interested in justified criticisms
of this method.


For example, there are no classes and no subclasses in the languages
supported by the execution environments you target. And the init()
approach, probably copied without minimum clue from the Prototype junk
code, is nonsense. The language already has constructors for that.


I've tried the method on this page. It works nicely. It seems very
native JavaScript using prototype inheritance. I still don't understand
what you object to in this method.

Why does this code not allow for graceful degradation?


Because there will be no menu without client-side script support.


I'm developing for an environment with client-side script support. So
that shouldn't be a problem. I get the feeling that you think using
JavaScript is a bad idea.

Which can be easily avoided with a design approach that took more
consideration to develop.
You mean there is always an alternative to using JavaScript that should
be used instead for GUI widgets?

By design approach do you mean graphic design? If so I can see your
point for menus but not for all GUI widgets. I think that some widgets
just need JavaScript (eg. a slider). If you mean JavaScript code design
then I don't know what you mean.

And, reconsidering this, for more recent IE versions apparently it can
be done without client-side scripting, too. The most recent and most
convincing example posted here that I can remember is

<URL:http://www.cssplay.co.uk/menus/dd_valid.html>


Very interesting menu design. This seems to use a lot of comments in
the html document. Since I'll be using/requiring JavaScript anyway I
don't see the harm in using JavaScript to run the menus.
Peter

Mar 26 '06 #5

P: n/a
pe**********@gmail.com said the following on 3/25/2006 8:30 PM:
Thomas 'PointedEars' Lahn wrote:
Requiring a recent browser, and requiring it to have client-side script
support enabled are two different things. Especially with IEeek (see
below) and RadioActiveX (I think you get the idea). We really discussed
this ad nauseam here before. Search the archives about that, and search
them for UI library discussions.
Unfortunately I did not have a fruitful search with those key words.


Welcome to comp.lang.javascript and Thomas. :-X
You are by far not the first person (here) who thought of this,
tried it and, inevitably, failed.
Failed due to developing for a moving target of browser support?


Inevitable failure is always the result of scripting. It is, be default,
part of it's nature.
Reading that will probably help you investing your time in
something that makes more sense.
What would make more sense for a GUI widget library? Or do you think
JavaScript GUI widgets are a waste of time?


Thomas thinks that anything that wasn't his idea is a waste of time.
> For JavaScript inheritance I want to use these ideas
> http://www.kevlindev.com/tutorials/j...t/inheritance/
Factually wrong.
Why is it factually wrong? I am very interested in justified criticisms
of this method. For example, there are no classes and no subclasses in the languages
supported by the execution environments you target. And the init()
approach, probably copied without minimum clue from the Prototype junk
code, is nonsense. The language already has constructors for that.


I've tried the method on this page. It works nicely. It seems very
native JavaScript using prototype inheritance. I still don't understand
what you object to in this method.


He seems to be stuck on your use of the word "classes" in Javascript. It
doesn't have classes but you can come real close to emulating them.
Why does this code not allow for graceful degradation?

Because there will be no menu without client-side script support.


I'm developing for an environment with client-side script support. So
that shouldn't be a problem. I get the feeling that you think using
JavaScript is a bad idea.


Again, meet Thomas. His ideas are not to help people but to merely point
out any/all flaws in any idea that isn't his.
Which can be easily avoided with a design approach that took more
consideration to develop.
You mean there is always an alternative to using JavaScript that should
be used instead for GUI widgets?

By design approach do you mean graphic design? If so I can see your
point for menus but not for all GUI widgets. I think that some widgets
just need JavaScript (eg. a slider). If you mean JavaScript code design
then I don't know what you mean.

And, reconsidering this, for more recent IE versions apparently it can
be done without client-side scripting, too. The most recent and most
convincing example posted here that I can remember is

<URL:http://www.cssplay.co.uk/menus/dd_valid.html>


Very interesting menu design.


Yes indeed.
IE: Tools>Internet Options>Accessibility>Ignore X 3

Menu looks nice then. But it's broken. So much for CSS degradation huh?

And Firefox? Disable CSS via any of the many add-ons and that page
becomes horrendous.

My point? Anything can be broken....
This seems to use a lot of comments in the html document.
Since I'll be using/requiring JavaScript anyway I don't see
the harm in using JavaScript to run the menus.


There isn't. Contrary to most people here's belief the trend on the web
is *towards* scripting, not away from it.

"Graceful Degradation" is one of those buzz terms people like to use in
order to argue against anything they don't agree with.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 26 '06 #6

P: n/a
pe**********@gmail.com writes:
I'm developing for an environment with client-side script support.
That's the problem. In this group, the default assumption, unless
something else is said, is that the scripting is for web pages
for the internet. The internet as a whole is not an environment
where client-side script support can be assumed. The percentages
of people browsing without Javascript varies. TheCounter.com has
had numbers up to 9% late last year, but is currently at 3%.
So that shouldn't be a problem. I get the feeling that you think
using JavaScript is a bad idea.


Javascript is a great idea for *enhancing* pages, but if the page
*depends* on Javascript, then there are people who cannot use it at
all. Graceful degredation would ensure that these people can still
use the page, they just don't have the bells and whistles of
Javascript enhancements.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Mar 26 '06 #7

P: n/a
Lasse,

Thanks for the reply.

Lasse Reichstein Nielsen wrote:
pe**********@gmail.com writes:
I'm developing for an environment with client-side script support.


That's the problem. In this group, the default assumption, unless
something else is said, is that the scripting is for web pages
for the internet. The internet as a whole is not an environment
where client-side script support can be assumed. The percentages
of people browsing without Javascript varies. TheCounter.com has
had numbers up to 9% late last year, but is currently at 3%.


I wonder what those 3% are doing on the web? I have a feeling that
anyone who wants to use my app with the dhtml widgets will have
JavaScript running in thier browser. Otherwise...

<noscript>
<strong>Turn on JavaScript.</strong>
</noscript>
So that shouldn't be a problem. I get the feeling that you think
using JavaScript is a bad idea.


Javascript is a great idea for *enhancing* pages, but if the page
*depends* on Javascript, then there are people who cannot use it at
all.


I understand this argument. Mission critcal pages like an ecommerce
store front probably shouldn't have JavaScript dependence.

Who cannot use JavaScript? Not to be an instigator but if this argument
is taken to an only slightly larger level we could argue that we should
not write <form>s with <button>, <select> etc tags because people
without an html browser will not be able to use the form. By writing
for the web we are making assumptions. As time goes by can't we make
more demanding assumptions as new techonology adoption improves? At
only 3%, I think we are at a point where we can assume JavaScript is on
for users of many types of web pages.

Better to make a rich GUI page depend on JavaScript or Flash? If the
JavaScript world doesn't think the answer is JavaScript then Flash will
take over. I think a rich GUI library is really needed for JavaScript.
I know that I need one. Otherwise I'm going to start writing Flash/Flex
apps or Java Swing desktop apps that talk to my web server with SOAP.

Peter

Mar 26 '06 #8

P: n/a
pe**********@gmail.com writes:
PointedEars,

Factually wrong.


Why is it factually wrong? I am very interested in justified criticisms
of this method.


I think the page does a decent job of explaining what it does, but
what it does is a somewhat roundabout way of doing what it means to do :)

I see no need for the init function to begin with. If you want to
create a "subclass", you want the constructor function to call the
"superclass" constructor and you want the objects to inherit each
other. Introducing an "init" function that you can inherit is missing
the point that the constructor already is a function.

His fiddling with using a no-argument call to the constructor to
create a clone of the prototype object is just a hack. There are
easier ways to create clones of objects.

E.g.
----
function Person(first,last){
this.first = first;
this.last = last;
}
Person.prototype.toString = function toString() {
return this.first + " " + this.last;
};

function Employee(first, last, id) {
this.superclass(this, first, last);
this.id = id;
}
Employee.prototype = clone(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.superclass = Person;
Employee.prototype.toString = function toString() {
return this.id + ":" + this.super.toString.call(this);
};

function Manager(first, last, id, department) {
this.superclass(first, last, id);
this.department = department;
}
Manager.prototype = clone(Employee.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.superclass = Employee;
Manager.prototype.toString = function toString() {
return this.super.toString.call(this) + " manages " + this.department;
};

function clone(prototype) {
function dummy(){};
dummy.prototype = prototype;
var clone = new dummy();
clone.super = prototype;
return clone;
}
----

You could even make an "extend" function for doing most of this work:
---
/**
* Makes constructor extend superclass by inheriting
* from superclass.prototype and extending its own
* prototype with "superclass" referring to superclass
* and "super" referring to "superclass.prototype".
*/
function extend(constructor, superclass) {
function dummy(){};
dummy.prototype = superclass.prototype;
var prototype = new dummy();
prototype.constructor = constructor;
prototype.superclass = superclass;
prototype.super = superclass.prototype;
constructor.prototype = prototype;
return constructor;
}

function Person(first, last) {
this.first = first;
this.last = last;
}
Person.prototype.toString = function toString() {
return this.first + " " + this.last;
};
function Employee(first, last, id) {
this.superclass(first, last);
this.id = id;
}
extend(Employee, Person);
Employee.prototype.toString = function toString() {
return this.id + ":" + this.super.toString.call(this);
};
----
I'm also not convinced that trying to program class-based in a
prototype-based language is the best way to work. There are
plenty of people trying to build class scaffoldings around
Javascript, but learning to program prototype based is probably
better in the long run.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Mar 26 '06 #9

P: n/a
Lasse,

Thank you for your reply. Very interesting. I will study this in more
detail.
I'm also not convinced that trying to program class-based in a prototype-based language is the best way to work.


This sounds very reasonable. How is one to learn and develop intution
about the best way to work in a prototype based language? I find the
idea very foreign even though I've been playing with JavaScript for
months. I'm sure this problem plagues many people used to Java, C++,
Ruby, etc when they start learning JavaScript. This problem probably
causes a lot of bad JavaScript being written.

What would this example of people, employee and manager look like in a
more prototype inheritance way?

Thanks,
Peter

Mar 26 '06 #10

P: n/a
Lasse Reichstein Nielsen wrote:
pe**********@gmail.com writes:
I'm developing for an environment with client-side script support.


That's the problem. In this group, the default assumption, unless
something else is said, is that the scripting is for web pages
for the internet. The internet as a whole is not an environment
where client-side script support can be assumed. The percentages
of people browsing without Javascript varies. TheCounter.com has
had numbers up to 9% late last year, but is currently at 3%.
So that shouldn't be a problem. I get the feeling that you think
using JavaScript is a bad idea.


Javascript is a great idea for *enhancing* pages, but if the page
*depends* on Javascript, then there are people who cannot use it at
all. Graceful degredation would ensure that these people can still
use the page, they just don't have the bells and whistles of
Javascript enhancements.

/L


The topic started as JavaScript GUI library idea, so it should be safe
to assume that we have "some" JS support. The gracefull degradation
would be nice, but is absolutely not on the top of the requirements for
me. The web-app would gracefully notify the user w/o JavaScript about
this requirement and render nothing. Users not willing or not able to
enable JS would be simply left-out.

Roman
Mar 26 '06 #11

P: n/a
Lasse Reichstein Nielsen wrote:
You could even make an "extend" function for doing most of this work:
function extend(constructor, superclass) {
function dummy(){};
dummy.prototype = superclass.prototype;
var prototype = new dummy();
prototype.constructor = constructor;
prototype.superclass = superclass;
prototype.super = superclass.prototype;
constructor.prototype = prototype;
return constructor;
}


I've been playing with this. This idea is really great! Nice an clean.
(Why didn't I think of that?)

Thanks again,
Peter

Mar 26 '06 #12

P: n/a
pe**********@gmail.com said the following on 3/25/2006 9:55 PM:
Lasse,

Thanks for the reply.

Lasse Reichstein Nielsen wrote:
pe**********@gmail.com writes:
I'm developing for an environment with client-side script support. That's the problem. In this group, the default assumption, unless
something else is said, is that the scripting is for web pages
for the internet. The internet as a whole is not an environment
where client-side script support can be assumed. The percentages
of people browsing without Javascript varies. TheCounter.com has
had numbers up to 9% late last year, but is currently at 3%.


I wonder what those 3% are doing on the web?


With the advent of non-scriptable PDA's and Cell Phones I am not sure I
would believe that 3%. Historically, it has been between 10-20% that are
non-scriptable. But I do believe that the trend is towards scripting and
not away from and if the 3 and 9 are correct then that backs up my belief.
I have a feeling that anyone who wants to use my app with the dhtml
widgets will have JavaScript running in thier browser. Otherwise...

<noscript>
<strong>Turn on JavaScript.</strong>
</noscript>


The only problem with that approach is that if scripting is enabled and
for some reason there is a script error in the page, the user doesn't
get the content delivered via JS and they won't see the noscript block.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Mar 26 '06 #13

P: n/a
pe**********@gmail.com writes:
What would this example of people, employee and manager look like in a
more prototype inheritance way?


I won't claim I'm an expert on prototype based programming, but here is
my take on it ...

First, there are no classes. Objects inherit from other objects and
are then specialized. I.e., to make "a person similar to John, but
with another name", you do:

var paul = clone(john);
paul.first = "Paul";
paul.last = "McCartney";

Javascript makes this proces easy, because they do both cloning and
update in one operation using an initialization function (aka
constructor function), so you would have:

function PersonSimilarToJohn(first,last) {
this.first = first;
this.last = last;
}
PersonSimilarToJohn.prototype = john;

Sometimes you start out with an *idea* of a person, more than a real
person. You create an object that can serve as the prototype for
actual objects without really being one itself - an abstract prototype.
You do that by createing a real object with default values:

var john = {first: "John", last: "Doe",
toString: function toString(){return first + " " + last;}};

or without them (usually directly on the existing prototype object
of the initializer function):

function Person /* aka PersonSimilarToPersonPrototype */() {
this.first = first;
this.last = last;
}
Person.prototype.toString = function toString(){return first + " " + last;};
So far, Javascript is with us. Now, if you want to further specialize
a person, you can either do it directly:

function employ(person, newId) {
person.id = newId;
var oldToString = person.toString;
person.toString = function() {
return this.id + ":" + oldToString.call(this);
}
}

After calling this, that person is employed. It's hard to fire him, since
it's the same object that is modified.

Another approach is to create a new object view of PersonAsEmployee:

function employ(person, newId) {
function Employee(person, newId) {
this.person = person;
this.id = newId;
};
Employee.prototype = person;
var employee = new Employee(newId);
employee.toString = function() {
retrun this.id + ":" + this.person.toString();
};
employee.asPerson = function() {
return this.person;
}
return employee;
}

Here your employee inherits from a real person. If that person changes
his name, so does the employee. You can employ the same person several
times at different companies.
(A better modelling to begin with would perhaps be a person having a
number of employments, so employee again becomes just a role of a
person, not a special type of person).

This is looking at a person as the primary entity, and being employed
as a role.
Likewise, you can promote to manager by extending the person or by
making a manager view of the person.

Since Javascript doesn't have multiple inheritance, you can't inherit
from both a person and a manager prototype. That is why I add the
emplyee and manager features manually instead of on an initializer
prototype. I believe Self could do multiple inheritance.

The general pattern for creating new objects is: Take an existing
object, clone it, and adapt the clone to the new needs. I.e.,
"I want something like that, only with the exceptions ... ".
A somewhat less prototype base approach would be the one I suggested,
where you keep a parallel hierarchy of prototype objects and
initializers, so that an actual employee is created based on the
prototype of a person extended to a prototype of an employee, and then
initialized as both. This is clearly class based thinking (which
appears to be much easier to grok for the average programmer :)
Ob-link:
<URL:http://en.wikipedia.org/wiki/Prototype-based_programming>

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Mar 26 '06 #14

P: n/a
Lasse,

Wow, thanks for writing such a detailed explanation. Better than what
I've read before.

Prototype-style programming looks like a really different mind set.
Certainly not the way my mind has been trained to think. Perhaps it was
a fluke of this person/employee/manager example but the code using
simulated class-based inheritance seems less bulky to me.

I think that me using simulated class-based inheritance in JavaScript
would not be the end of the world because
1) a lot of people know and think in class-based inheritance
2) a lot of people use JavaScript infrequently and don't know prototype
inheritance well
3) I haven't yet run into a downside for simulating class-based
inheritance in JavaScript
4) JavaScript allows for a short, tidy way to simulate class-based
inheritance (your extend function). Since it is such a short and tidy
method using the prototype I'm surprised this is looked down upon at
all. It *is* native JavaScript and only a few lines of code at that. It
doesn't create a nightmare like using goto statements. It is just a
different style of prototype manipulation. You can program in C++ or
Java either in an OOP or procedural style. And some people are happy
with one or the other. You can even program in C to simulate classes.

Maybe one day the whole idea of the intended use of prototype style
will click in my head and I will be trying to simulate that in Ruby.

Lasse, thanks again for helping educate my brain.

As a note, I emailed Kevin, the author of the
class-based-inheritance-in-JavaScript tutorial and a friendly guy. He
says that your extend function is very similar to what he uses now and
he has had plans to update his tutorial to reflect this.

Peter

Mar 26 '06 #15

P: n/a
I want to use simulated namespaces and so am defining my "classes" with
function literals. I found that Safari could not quite use the extend
function if the superclass constructor was defined as a function
literal. Seems like there must be a Safari bug. Firefox had no trouble.
I added a line to the extend function to explicitly set the
constructor.

Also Safari did not like the use of a property named "super" in the
original example.

-Peter

function extend(subclass, superclass) {
function Dummy(){};
Dummy.prototype = superclass.prototype;
subclass.prototype = new Dummy();
subclass.prototype.constructor = subclass;
subclass.prototype.superclass = superclass.prototype;
// Safari needs some help if the superclass constructor
// is defined with a function literal
subclass.prototype.superclass.constructor = superclass;
};

Person = function(first, last) {
this.first = first;
this.last = last;
};
Person.prototype.toString = function toString() {
return this.first + " " + this.last;
};

Employee = function(first, last, id) {
this.superclass.constructor(first, last);
this.id = id;
};
extend(Employee, Person);
Employee.prototype.toString = function toString() {
return this.id + ":" + this.superclass.toString.call(this);
};

var e = new Employee("ted", "henry", 18);
document.write(e.toString());

Mar 26 '06 #16

P: n/a
pe**********@gmail.com writes:
I want to use simulated namespaces and so am defining my "classes" with
function literals. I found that Safari could not quite use the extend
function if the superclass constructor was defined as a function
literal. Seems like there must be a Safari bug. Firefox had no trouble.
There's always one more bug :)
I added a line to the extend function to explicitly set the
constructor.
Shouldn't be necessary, but ... well. If it is, it is.

Employee = function(first, last, id) {
this.superclass.constructor(first, last);


Here the method is called with "this" referring to this.superclass,
i.e., the extended functions prototype. That means that the first
and last properties are set on that, not on this object. If you create two
emplyees, they will have the same name, the second of the two.
You have to do:
this.superclass.constructor.call(this, first, last);
to avoid this. (This was why I preferred the "superclass" property on
the object itself - you could call it without having to use "call")

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Mar 26 '06 #17

P: n/a

Lasse Reichstein Nielsen wrote:
There's always one more bug :)


I think there is another one and I think I know what is going wrong.
When I make the example contain the third level of Manager I get
infinite recursion on the superclass call in the Employee constructor.
This is because when extend(Manager, Employee) is called it overwrites
this.superclass with Employee for the object. So when Employee tries to
call it's superclass it calls itself.

I think this is why in Kevin's tutorial he didn't add the superclass to
the instances but rather he added the superclass property to the Class
constructor of each class up the hierarchy.

Peter

extend = function(subclass, superclass) {
function dummy(){};
dummy.prototype = superclass.prototype;
subclass.prototype = new dummy();
subclass.prototype.constructor = subclass;
subclass.superclass = superclass.prototype;
subclass.superclass.constructor = superclass;
}

Person = function(first, last) {
this.first = first;
this.last = last;
}
Person.prototype.toString = function toString() {
return this.first + " " + this.last;
};
Employee = function(first, last, id) {
Employee.superclass.constructor.call(this,first, last);
this.id = id;
}
extend(Employee, Person);
Employee.prototype.toString = function toString() {
return this.id + ":" + Employee.superclass.toString.call(this);
};

Manager = function(dept, first, last, id) {
Manager.superclass.constructor.call(this,first, last, id);
this.dept = dept;
}
extend(Manager, Employee);
Manager.prototype.toString = function toString() {
return this.dept + ":" + Manager.superclass.toString.call(this);
};

var e = new Manager("DEPT", "ted", "henry", 26);
document.write(e.toString());

Mar 26 '06 #18

P: n/a

pe**********@gmail.com wrote:

[snip]
I've been asking questions about library design over the last week and
would like to get feedback on my overall idea for a JavaScript GUI
library. I need a nice GUI library so there is a good chance I will
write this as I need new widgets.I haven't found anything like this
and I'm surprised/disapointed this doesn't already exist.

[/snip]

But what about:-

<URL:http://www.bindows.net>
<URL:http://dojotoolkit.org/> (In particular, Widgets)
<URL:http://www.activewidgets.com/>

Regards

Julian

Mar 27 '06 #19

P: n/a

Julian Turner wrote:
But what about:-

<URL:http://www.bindows.net>
<URL:http://dojotoolkit.org/> (In particular, Widgets)
<URL:http://www.activewidgets.com/>


or

<URL:http://qooxdoo.oss.schlund.de/>

Which is OSS (unlike activewidgets and bindows) and conatins a pretty
full featured set of common ui widgets (unlike Dojo).

Mar 27 '06 #20

P: n/a
Hi Julian,

Thanks for the links
<URL:http://www.bindows.net>
~ $700 for a developer licence $2000/site <URL:http://dojotoolkit.org/> (In particular, Widgets)
TurboWidgets $200/site
Nice looking widgets.
This looks like a pretty cool project.
<URL:http://www.activewidgets.com/>


Look at what happens when text size is increased.

Peter

Mar 27 '06 #21

P: n/a
> <URL:http://qooxdoo.oss.schlund.de/>

Wow. Lots of features.

Mar 27 '06 #22

This discussion thread is closed

Replies have been disabled for this discussion.