eval

G

Gordon

I have a script that creates new objects based on the value of a form
field. Basically, the code looks like this.

eval ('new ' + objType.value + '(val1, val2, val3');

objType is a select with the different types of objects you can create
as values.

I really don't like using eval, and it's causing problems, like if I
do something like the following:

eval ('localVar = new ' + objType.value + '(val1, val2, val3');

localVar should refer to a variable local to the calling object, but
with the eval approach it ends up being the local variable for the
scope from which the eval was first executed.

I could use a seitch statement, but this approach means I now have an
extra place where I need to change my code so I'd like to afford this
if possible.

Is there another approach to creating a new instance of an object
dependant on the value of some variable?
 
E

Erwin Moller

Gordon schreef:
I have a script that creates new objects based on the value of a form
field. Basically, the code looks like this.

eval ('new ' + objType.value + '(val1, val2, val3');

objType is a select with the different types of objects you can create
as values.

I really don't like using eval, and it's causing problems, like if I
do something like the following:

eval ('localVar = new ' + objType.value + '(val1, val2, val3');

localVar should refer to a variable local to the calling object, but
with the eval approach it ends up being the local variable for the
scope from which the eval was first executed.

Hi Gordon,

So the scope is the problem, not eval? Right?

I guess your eval-code is in some function.

Without knowing anything about your code, and who calls what, what about
returning the object?
So:
eval ('var localVar = new ' + objType.value + '(val1, val2, val3');
return localVar;

And when calling the routine:
theObj = myEvalRoutine(vars here);

Could that help?

Regards,
Erwin Moller
 
G

Gordon

Gordon schreef:









Hi Gordon,

So the scope is the problem, not eval? Right?

I guess your eval-code is in some function.

Without knowing anything about your code, and who calls what, what about
returning the object?
So:
eval ('var localVar = new ' + objType.value + '(val1, val2, val3');
return localVar;

And when calling the routine:
theObj = myEvalRoutine(vars here);

Could that help?

Regards,
Erwin Moller

The eval was a quick and dirty alternative to a switch statement for
each kind of object that i want to be able to instantize. The problem
is that using the eval is screwing up the scoping rules that normally
apply in javascript that involve coming up with inelegant workarounds,
such as putting stuff that I'd normally keep in the scope of the cose
I'm running in the global scope instead.

Of the two choices the switch statement is probably the better one,
but it adds an extra point in the code that has to be changed should,
for example, I choose to add a new object type. It also adds n lines
of code per object type, and I'd like to find a better solution. I
guess what I really want to be able to do is something like:

var localVar = new objType.value ()

But when I try that I just get an objType.value is not a function
message.
 
H

Henry

On Jun 12, 5:03 pm, Gordon wrote:
The eval was a quick and dirty alternative to a switch
statement for each kind of object that i want to be able
to instantize. The problem is that using the eval is
screwing up the scoping rules that normally apply in
javascript that involve coming up with inelegant workarounds,

The scope used in an eval execution context is the same scope as the
execution context from which eval is called, so what you are saying
does not make sense.
such as putting stuff that I'd normally keep in the scope
of the cose I'm running in the global scope instead.

And that makes even less sense.
Of the two choices the switch statement is probably the better
one, but it adds an extra point in the code that has to be
changed should, for example, I choose to add a new object type.
It also adds n lines of code per object type, and I'd like to
find a better solution. I guess what I really want to be able
to do is something like:

var localVar = new objType.value ()

But when I try that I just get an objType.value is not a
function message.

As is should, but if you provided some context for you code you might
get a decent answer to your question. Which will be how a bracket
notation property access can be employed here. For example, if all
your constructors were globally declared functions and environment was
a web browser were no alternative means of accessing the global object
had been created those constructors could be references as members of
the object referred to by - window -. I.E.:-

var localVar = new window[objType.value]();
 
L

Lasse Reichstein Nielsen

Gordon said:
I have a script that creates new objects based on the value of a form
field. Basically, the code looks like this.

eval ('new ' + objType.value + '(val1, val2, val3');

Reduce the scope of eval as much as possible (preferably to nothing :).
This can be reduced to:
new (eval(objType.value))(val1, val2, val3);
(or, more readable:
var Constructor = eval(objType.value);
... new Constructor(val1, val2, val3) ...
)
objType is a select with the different types of objects you can create
as values.

Who created the objType objects? Why do they contain the names of
functions instead of the functions themselves?
There can be good reasons for it, but if it is possible to rewrite
the data so that the objType contains the actual constructor function
instead of, or in addition to, its name, then many things become
simpler.
localVar should refer to a variable local to the calling object,

What does that mean? Objects do not have variables. Scopes have
variables, and objects have properties.
but with the eval approach it ends up being the local variable for
the scope from which the eval was first executed.

That's what the code would mean without the eval too:

localVar = new (eval(objType.value))(val1,val2,val3);

assigns to the "localVar" variable in the current scope chain.
I could use a seitch statement, but this approach means I now have an
extra place where I need to change my code so I'd like to afford this
if possible.

Your problem is that you need to lookup a function by its name.
The current solution is to look it up in the scope, and store
the function in the global scope.

That causes the same token to do double duty: as a function name and
property of the global object, and as a data value in your data. I
prefer to keep those two namespaces (language/data) separate if
possible.

You could create a lookup-table:

var functionTable = {
objType1: Type1Constructor,
objType2: Type2Constructor,
...
objTypeN: typeNConstructor
};

Then instead of eval, you could do an explicit lookup:

localVar = new (functionTable[objType.value])(val1, val2, val3);
Is there another approach to creating a new instance of an object
dependant on the value of some variable?

To create new objects from a constructor, first find the constructor
function.
That is the part you are using eval for. I recommend against it, but
it might be so much easier than alternatives that you choose to stick
with it. Just keep the scope of eval down, in this case to a single
variable (which can then be replaced by "window[objType.value]" :)

Then use the "new" operator. If you know the number of arguments (or a
reasonable upper bound on them), then there is no need for eval in that.

Remember that, unlike, e.g., Java, you can use any variable to refer to
the constructor function in the "new" expression, so

function MyType(){}
var t1 = new MyType();
var x = MyType;
var t2 = new x();

is perfectly valid and there is no difference in properties and
prototype chain between the values of t1 and t2.

That is why you can separate the lookup of the constructor from
the creation of a new instance. Constructors are not types, they
are just function value like every other function.

/L
 
G

Gordon

On Jun 12, 5:03 pm, Gordon wrote:
The eval was a quick and dirty alternative to a switch
statement for each kind of object that i want to be able
to instantize. The problem is that using the eval is
screwing up the scoping rules that normally apply in
javascript that involve coming up with inelegant workarounds,

The scope used in an eval execution context is the same scope as the
execution context from which eval is called, so what you are saying
does not make sense.
such as putting stuff that I'd normally keep in the scope
of the cose I'm running in the global scope instead.

And that makes even less sense.
Of the two choices the switch statement is probably the better
one, but it adds an extra point in the code that has to be
changed should, for example, I choose to add a new object type.
It also adds n lines of code per object type, and I'd like to
find a better solution. I guess what I really want to be able
to do is something like:
var localVar = new objType.value ()
But when I try that I just get an objType.value is not a
function message.

As is should, but if you provided some context for you code you might
get a decent answer to your question. Which will be how a bracket
notation property access can be employed here. For example, if all
your constructors were globally declared functions and environment was
a web browser were no alternative means of accessing the global object
had been created those constructors could be references as members of
the object referred to by - window -. I.E.:-

var localVar = new window[objType.value]();

Here's the complete code. Bear in mind it's in a very early stage of
development, is very rough and ready, and has lots of code in the
middle of being rewritten

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/
TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<link rel="stylesheet" type="text/css" href="templates/interface/
styles/default.css" />
<!--[if ie 6]>
<link rel="stylesheet" type="text/css" href="templates/interface/
styles/fix_ie.css" />
<![endif]-->
<style type="text/css">
<!--
..fields {
border: solid 1px blue;
}
legend {
display: none;
}
..questionGrid {
width: 100%;
}
..cmsDialog {
display: none;
}
..cmsDialog ul {
list-style: none outside;
padding: 0;
margin: 0;
}
..cmsDialog label {
display: -moz-inline-box; /* For gecko */
display: inline-block; /* For Internet Explorer */
width: 75px;
}
-->
</style>
<link rel="stylesheet" href="/js/jquery/ui/themes/custom/theme.css"
type="text/css" media="screen" />
<script type="text/javascript" src="/js/jquery/jquery.js"></script>
<script type="text/javascript" src="/js/jquery/jquery.livequery.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.core.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.draggable.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.resizable.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.sortable.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.dialog.js"></
script>
<script type="text/javascript">
<!--
var dialogs = {};
/*
function QuestionRadio ()
{
}

function QuestionSelect ()
{
}

function QuestionGridRow ()
{
}
*/
function QuestionString (target, label)
{
var self = this;
self.markup = $('<li><label class="sortHandle"><input type="hidden"
name="groups['
+ target.title + ']['
+ label
+ '][type]" value="string" />'
+ label
+ '</label><input type="text" name="groups['
+ target.title + ']['
+ label
+ '][default]" />'
+ '<input type="button" class="delQ" value="Delete question"></
li>');

self.construct = function ()
{
target.questionList.append (self.markup);
target.questionList.sortable ('refresh');
};

self.construct ();
}

function QuestionText (target, label)
{
var self = this;
self.markup = $('<li><label class="sortHandle"><input type="hidden"
name="groups['
+ target.title + ']['
+ label
+ '][type]" value="text" />'
+ label
+ '</label><textarea name="groups['
+ target.title + ']['
+ label
+ '][default]"></textarea>'
+ '<input type="button" class="delQ" value="Delete question"></
li>');

self.construct = function ()
{
target.questionList.append (self.markup);
target.questionList.sortable ('refresh');
};

self.construct ();
}

function QuestionCheck (target, label)
{
var self = this;
self.markup = $('<li><label class="sortHandle"><input type="hidden"
name="groups['
+ target.title + ']['
+ label
+ '][type]" value="check" />'
+ label
+ '</label><input type="checkbox" name="groups['
+ target.title + ']['
+ label
+ '][checked]" value="1" />'
+ '<input type="button" class="delQ" value="Delete question"></
li>');

self.construct = function ()
{
target.questionList.append (self.markup);
target.questionList.sortable ('refresh');
};

self.construct ();
}

/*
function QuestionGrid (target)
{
var self = this;
self.markup = $('<li>'
+ '<table class="questionGrid">'
+ '<thead><tr><th class="sortHandle">&nbsp;</th>'
+ '</tr></thead><tbody></tbody></table>'
+ '<div class="optBar">'
+ '<input type="button" class="addQRow" value="Add question" />'
+ '<input type="button" class="addCol" value="Add column" />'
+ '<input type="button" class="delGroup" value="Delete grid" />'
+ '</div></li>');
self.questionBut = $('.addQRow', self.markup);
self.deleteBut = $('.delGroup', self.markup);
self.colBut = $('.addCol', self.markup);
self.rowCount = 0;
self.colCount = 0;

self.addQuestion = function ()
{
var thisCol = 0;
var newRow = $('<tr><td class="sortHandle"><label>test' +
(self.rowCount + 1) + '</label></td></tr>');
for (thisCol = 0; thisCol < self.colCount; thisCol++)
{
newRow.append ('<td><input type="radio" /></td>');
}
$('tbody', self.markup).append (newRow);
$('tbody', self.markup).sortable ('refresh');
return (++self.rowCount);
};
self.addColumn = function ()
{
$('thead tr', self.markup).append ('<th>&nbsp;</th>');
$('tbody tr', self.markup).append ('<td><input type="radio" /></
td>');
return (++self.colCount);
};
self.construct = function ()
{
self.questionBut.click (self.addQuestion);
self.colBut.click (self.addColumn);
target.append (self.markup);
$('tbody', self.markup).sortable ({
handle : '.sortHandle'
});
target.sortable ('refresh');
};

self.construct ();
}
*/

function QuestionGroup (target, title, subtitle)
{
var self = this;
self.questions = {};
self.title = title;
self.markup = $('<li id="'
+ title
+ '"><input type="hidden" name="groups[' + title + ']" />'
+ '<h3 class="sortHandle">' + (title || 'No title') + '</h3>'
+ '<h4>' + subtitle + '</h4>'
+ '<div class="fields"><ul class="questionList"></ul></div>'
+ '<div class="optBar">'
+ '<input type="button" class="addQ" value="Add question" />'
+ ' said:
+ '</div></li>');
self.questionList = $('.questionList', self.markup);
self.addQBut = $('.addQ', self.markup);
//self.addGridBut = $('.addGrid', self.markup);
//self.delGroupBut = $('.delGroup', self.markup);

self.addQuestion = function ()
{
// Using self in eval from here causes problems
activeTarget = self;
if (dialogs.newQ)
{
dialogs.newQ.dialog ('open');
}
else
{
dialogs.newQ = $('#cmsDgNewQ').show ().dialog ({
title : 'New Question',
modal : true,
buttons : {
'Create' : function (evt)
{
var label = $('#label', this).val ();
if (label)
{
var type = $('#qType').val ();
// The line
eval ('activeTarget.questions [label] = new ' + type +
' (activeTarget, label)');
console.log (activeTarget.questions);
}
$(this).dialog ('close');
}
}
});
}
};
self.addGrid = function ()
{
};
self.construct = function ()
{
target.append (self.markup);
self.addQBut.click (self.addQuestion);
self.questionList.sortable ({
handle : '.sortHandle'
});
};

self.construct ();
}

$(document).ready (function ()
{
var groupList = $('#cmsSurveyPreview').sortable ({
handle : '.sortHandle'
});

var groups = {};
var activeGroup;
var activeTarget;

// Prevent any IDs we're using in our editor from being assigned
$('body [@id]').each (function ()
{
groups [this.id] = true;
});

// Configure dialog overlay
$.extend ($.ui.dialog.defaults,
{
overlay : {
'background-color' : 'black',
'filter' : 'alpha(opacity=30)',
'opacity' : '0.3',
'-moz-opacity' : '0.3'
}
});
$.extend ($.ui.sortable.defaults,
{
distance : 5
});

$('#cmsAddGroup').click (function ()
{
if (dialogs.newGroup)
{
dialogs.newGroup.dialog ('open');
}
else
{
dialogs.newGroup = $('#cmsDgNewGroup').show ().dialog ({
title : 'New Question Group',
modal : true,
buttons : {
'Create' : function (evt)
{
var title = $('#groupTitle', this).val ();
var question = $('#groupQuestion', this).val ();
if ((title) && (!groups [title]))
{
groups [title] = new QuestionGroup (groupList, title,
question);
groupList.sortable ('refresh');
$(this).dialog ('close');
//console.log (groups);
}
},
'Cancel ' : function (){$(this).dialog ('close');}
}
});
}
});
/*
$('.addQ').livequery ('click', function ()
{
activeGroup = $('ul', $(this).parent ().parent ());
if (dialogs.newQ)
{
dialogs.newQ.dialog ('open');
}
else
{
dialogs.newQ = $('#cmsDgNewQ').show ().dialog ({
title : 'New Question',
modal : true,
buttons : {
'Create' : function (evt)
{
var label = $('#label', this).val ();
if (label)
{
var type = $('#qType').val ();
eval ('new ' + type + ' (activeGroup, label)');
}
$(this).dialog ('close');
}
}
});
}
});
*/
$('.addGrid').livequery ('click', function ()
{
activeGroup = $('ul', $(this).parent ().parent ());
//console.log (activeGroup);
new QuestionGrid (activeGroup);
});
$('.delGroup').livequery ('click', function ()
{
$(this).parent ().parent ().remove ();
});
$('.delQ').livequery ('click', function ()
{
$(this).parent ().remove ();
});
});
-->
</script>
</head>
<body>
<form action="<?php echo ($_SERVER ['PHP_SELF']); ?>" method="post">
<ul id="cmsSurveyPreview">
</ul>
<fieldset id="controls">
<input type="button" id="cmsAddGroup" value="Add group" />
<input type="submit" value="Done" />
</fieldset>
<div class="cmsDialog" id="cmsDgNewGroup">
<ul>
<li>
<label for="groupTitle">Title</label>
<input type="text" id="groupTitle" />
</li>
<li>
<label for="groupQuestion">Question</label>
<input type="text" id="groupQuestion" />
</li>
</ul>
</div>
<div class="cmsDialog" id="cmsDgNewQ">
<ul>
<li>
<label for="label">qType</label>
<select id="qType">
<option value="QuestionString">Single line</option>
<option value="QuestionText">Multi line</option>
<option value="QuestionCheck">Check box</option>
</select>
</li>
<li>
<label for="label">Label</label>
<input id="label" />
</li>
</ul>
</div>
</form>
<pre>
<?php
print_r ($_POST);
?>
</pre>
</body>
</html>
 
G

Gordon

Gordon said:
I have a script that creates new objects based on the value of a form
field. Basically, the code looks like this.
eval ('new ' + objType.value + '(val1, val2, val3');

Reduce the scope of eval as much as possible (preferably to nothing :).
This can be reduced to:
new (eval(objType.value))(val1, val2, val3);
(or, more readable:
var Constructor = eval(objType.value);
... new Constructor(val1, val2, val3) ...
)
objType is a select with the different types of objects you can create
as values.

Who created the objType objects? Why do they contain the names of
functions instead of the functions themselves?
There can be good reasons for it, but if it is possible to rewrite
the data so that the objType contains the actual constructor function
instead of, or in addition to, its name, then many things become
simpler.
localVar should refer to a variable local to the calling object,

What does that mean? Objects do not have variables. Scopes have
variables, and objects have properties.
but with the eval approach it ends up being the local variable for
the scope from which the eval was first executed.

That's what the code would mean without the eval too:

localVar = new (eval(objType.value))(val1,val2,val3);

assigns to the "localVar" variable in the current scope chain.
I could use a seitch statement, but this approach means I now have an
extra place where I need to change my code so I'd like to afford this
if possible.

Your problem is that you need to lookup a function by its name.
The current solution is to look it up in the scope, and store
the function in the global scope.

That causes the same token to do double duty: as a function name and
property of the global object, and as a data value in your data. I
prefer to keep those two namespaces (language/data) separate if
possible.

You could create a lookup-table:

var functionTable = {
objType1: Type1Constructor,
objType2: Type2Constructor,
...
objTypeN: typeNConstructor
};

Then instead of eval, you could do an explicit lookup:

localVar = new (functionTable[objType.value])(val1, val2, val3);
Is there another approach to creating a new instance of an object
dependant on the value of some variable?

To create new objects from a constructor, first find the constructor
function.
That is the part you are using eval for. I recommend against it, but
it might be so much easier than alternatives that you choose to stick
with it. Just keep the scope of eval down, in this case to a single
variable (which can then be replaced by "window[objType.value]" :)

Then use the "new" operator. If you know the number of arguments (or a
reasonable upper bound on them), then there is no need for eval in that.

Remember that, unlike, e.g., Java, you can use any variable to refer to
the constructor function in the "new" expression, so

function MyType(){}
var t1 = new MyType();
var x = MyType;
var t2 = new x();

is perfectly valid and there is no difference in properties and
prototype chain between the values of t1 and t2.

That is why you can separate the lookup of the constructor from
the creation of a new instance. Constructors are not types, they
are just function value like every other function.

/L

That was a big help, thanks. I'm not very familiar with eval so didn't
know you could use it like that. It seems that the scope rules are
the same after all, just not what I was expecting in the part of the
code I was working on. It does look a little nicer using the item =
new (eval (objType)) (params) syntax :) I still would rather eliminate
the eval altogether if at all possible though.
 
T

Thomas 'PointedEars' Lahn

Gordon said:
[...]
var localVar = new objType.value ()
But when I try that I just get an objType.value is not a
function message.
As is should, but if you provided some context for you code you might
get a decent answer to your question. Which will be how a bracket
notation property access can be employed here. For example, if all
your constructors were globally declared functions and environment was
a web browser were no alternative means of accessing the global object
had been created those constructors could be references as members of
the object referred to by - window -. I.E.:-

var localVar = new window[objType.value]();

Here's the complete code. Bear in mind it's in a very early stage of
development, is very rough and ready, and has lots of code in the
middle of being rewritten

[ca. 400 lines of uncommented clueless source code]

Richard's implicitly asking for "some context" was certainly not to be
misunderstood as a request for your dumping core here and letting others
do your homework, in their leisure-time, for free.

http://www.catb.org/~esr/faqs/smart-questions.html


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>, Fri,
Richard's implicitly asking for "some context" was certainly not to be
misunderstood as a request for your dumping core here and letting others
do your homework, in their leisure-time, for free.


There is no reason why others should not be allowed to make that choice.
Even for those collecting news via dial-up modem, 400 lines of code foes
not take significant time or money to download. It is observed that,
instead of mellowing with age, you are getting increasingly vicious.

Also, when you have lost your temper to an even greater degree than
usual, your spelling degenerates. The first word of that quote is not
how one should spell "Henry".

KETFOB.

However, Gordon, if you had taken sufficient heed of newsgroup FAQ 2.3,
you would have replaced those tabs by double-spaces, and kept most of
your code lines more-or-less within the recommended 72 columns.

Opera 9.5 is available.
 
H

Henry

Gordon said:
On Jun 12, 5:03 pm, Gordon wrote:
... . For example, if all your constructors were globally
declared functions and environment was a web browser were
no alternative means of accessing the global object had
been created those constructors could be references as
members of the object referred to by - window -. I.E.:-

var localVar = new window[objType.value]();

Here's the complete code.

Is this the "complete code"? And even if it were what use would
"complete code" be when all of the irrelevant material would act
to obscure the relevant?
Bear in mind it's in a very early stage of development, is
very rough and ready, and has lots of code in the middle of
being rewritten

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

As IE does not understand XHTML at all, this introduces
unanswered questions of context. That is, is this really a
non-commercial/non-public exercise aimed at user agents that
do understand XHTML or is this just the illusion of XHTML
(i.e. the document is always served as text/html to all user
agents and will actually break in the event that it ever
is interpreted as XHTML)?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
^^^^^^^^^
In a real XHTML document that META element would be insane.
<title>Untitled Document</title> ^^^^^^^^^^^^^^^^^
?

<link rel="stylesheet" type="text/css" href="templates/interface/
styles/default.css" />
<!--[if ie 6]>
<link rel="stylesheet" type="text/css" href="templates/interface/
styles/fix_ie.css" />
<![endif]-->
<style type="text/css">
<!--
.fields {
width: 75px;
}
-->
</style>

A real XHTML document should be expected to be parsed by an
XML parser, and XML parsers are explicitly allowed to strip
comments as they parse. Thus if this document ever were
interpreted as XHTML the expectation should be that all of
these CSS declarations would not appear in the resulting
document DOM.

Thus the odds are now very high that this is actually a tag
soup HTML document that will need considerable client-side
error correction and any suggestion that it is XHTML are no
more than an illusion.

<script type="text/javascript" src="/js/jquery/jquery.js"></script>
<script type="text/javascript" src="/js/jquery/jquery.livequery.js">
</script>
<script type="text/javascript" src="/js/jquery/ui/ui.core.js">
</script>
<script type="text/javascript" src="/js/jquery/ui/ui.draggable.js">
</script>
<script type="text/javascript" src="/js/jquery/ui/ui.resizable.js">
</script>
<script type="text/javascript" src="/js/jquery/ui/ui.sortable.js">
</script>
<script type="text/javascript" src="/js/jquery/ui/ui.dialog.js">
</script>

It is a strange definition of "complete code" when a huge
proportion of the code used is self-evidently missing.

But, assuming that "/js/jquery/jquery.js" actually is John
Resig's dubious library (rather than an unfortunate naming
coincidence), that does answer the XHTML/HTML question. This
document is tag soup HTML and not XHTML, because JQuery is not
capable of functioning successfully with an XHTML DOM so the
whole document will go belly up if it ever is interpreted as
XHTML by a web browser.
<script type="text/javascript">
<!--

The same comment about comments in XML applies to SCRIPT
elements as STYLE elements; the expectation should be that
if this document were exposed to an XML parser then none of
the following script would get passed the parsing stage.
var dialogs = {};
function QuestionString (target, label)
<snip>

So the constructors are defined as global function
declarations, and so they can be referenced using bracket
notation as members of the - window - object, or some
other reference to the global object.
 
G

Gordon

Gordon said:
On Jun 12, 5:03 pm, Gordon wrote:
... . For example, if all your constructors were globally
declared functions and environment was a web browser were
no alternative means of accessing the global object had
been created those constructors could be references as
members of the object referred to by - window -. I.E.:-
var localVar = new window[objType.value]();
Here's the complete code.

Is this the "complete code"? And even if it were what use would
"complete code" be when all of the irrelevant material would act
to obscure the relevant?

It is the complete extent of the code I wrote, which is as I'll be the
first to admit, at a very early stage of transitioning from a very
basic non-functional demonstration to a fully working system.

As for your second question, somebody asked for context.
As IE does not understand XHTML at all, this introduces
unanswered questions of context. That is, is this really a
non-commercial/non-public exercise aimed at user agents that
do understand XHTML or is this just the illusion of XHTML
(i.e. the document is always served as text/html to all user
agents and will actually break in the event that it ever
is interpreted as XHTML)?

Bear in mind it's in a very early stage of development, is very rough
and ready, and has lots of code in the middle of being rewritten
^^^^^^^^^
In a real XHTML document that META element would be insane.

Bear in mind it's in a very early stage of development, is very rough
and ready, and has lots of code in the middle of being rewritten
^^^^^^^^^^^^^^^^^
?

Bear in mind it's in a very early stage of development, is very rough
and ready, and has lots of code in the middle of being rewritten
<link rel="stylesheet" type="text/css" href="templates/interface/
styles/default.css" />
<!--[if ie 6]>
<link rel="stylesheet" type="text/css" href="templates/interface/
styles/fix_ie.css" />
<![endif]-->
<style type="text/css">
<!--
.fields {
width: 75px;
}
-->
</style>

A real XHTML document should be expected to be parsed by an
XML parser, and XML parsers are explicitly allowed to strip
comments as they parse. Thus if this document ever were
interpreted as XHTML the expectation should be that all of
these CSS declarations would not appear in the resulting
document DOM.



Thus the odds are now very high that this is actually a tag
soup HTML document that will need considerable client-side
error correction and any suggestion that it is XHTML are no
more than an illusion.

Bear in mind it's in a very early stage of development, is very rough
and ready, and has lots of code in the middle of being rewritten.

And editing it as one file is easier than editing it as three. The
javascript and CSS will find their own homes in their own files when
the script is closer to working.

And as the whole thing runs entirely client-side anyway the point
about needing "considerable client side correction" is pretty much
moot anyway. Normally I try to write javascript to be as unobtrusive
as possible. but this particular app is designed to run on a very
controlled environment where the browser being used and its
capabilities is well defined, the users who are going to be using it
to build HTML for surveys know absolutely nothing about HTML, and the
users don't want to be refreshing the page every time a question is
added or changed.
It is a strange definition of "complete code" when a huge
proportion of the code used is self-evidently missing.

Because it's readily-available third-party library code. I assumed
that posting the complete source code of readily-available third-party
libraries might be frowned upon.
But, assuming that "/js/jquery/jquery.js" actually is John
Resig's dubious library (rather than an unfortunate naming
coincidence), that does answer the XHTML/HTML question. This
document is tag soup HTML and not XHTML, because JQuery is not
capable of functioning successfully with an XHTML DOM so the
whole document will go belly up if it ever is interpreted as
XHTML by a web browser.

Funny, I don't remember asking for an opinion on jQuery anywhere in my
previous posts.
The same comment about comments in XML applies to SCRIPT
elements as STYLE elements; the expectation should be that
if this document were exposed to an XML parser then none of
the following script would get passed the parsing stage.

Bear in mind it's in a very early stage of development, is very rough
and ready, and has lots of code in the middle of being rewritten
<snip>

So the constructors are defined as global function
declarations, and so they can be referenced using bracket
notation as members of the - window - object, or some
other reference to the global object.

Now that was actually helpful, thank you. Creating the new items as
new window[type] produces the same results as the eval() did, which is
exactly what I wanted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top