How to set a variable to a not modifying string expression using a variable

S

Stefan Mueller

I'd like to set a variable called 'FocusIsOn' if a button got the focus.
Because my button is dynamically created I do it like
xelement = document.createElement("input")
xelement.type = "button"
element.onfocus = function() {FocusIsOn = "Button_1"; alert(FocusIsOn)}

That works great. If the button gets the focus, I got a message box saying
'Button_1'.

However, if I set the variable 'FocusIsOn' dynamically (using a variable
'ButtonNumber') like
xelement = document.createElement("input")
xelement.type = "button"
element.onfocus = function() {FocusIsOn = "Button_" + ButtonNumber;
alert(FocusIsOn)}
it doesn't work like I wish it would.

I want that 'FocusIsOn' is set to 'Button_1' if 'ButtonNumber' is '1' and if
'ButtonNumber' is '99' to 'Button_99'.
However 'FocusIsOn' is effectively set to "Button_" + ButtonNumber.
That means, it doesn't matter which button I click, the message box always
says 'Button_' plus the actual value of 'ButtonNumber'.

Does anyone know how to set a variable like 'FocusIsOn' to a not modifying
string expression?
Stefan
 
J

Julian Turner

Stefan said:
I'd like to set a variable called 'FocusIsOn' if a button got the focus.

Presumably you intend it to be a global variable.

[snip]
However, if I set the variable 'FocusIsOn' dynamically (using a variable
'ButtonNumber') like
xelement = document.createElement("input")
xelement.type = "button"
element.onfocus = function() {FocusIsOn = "Button_" + ButtonNumber;
alert(FocusIsOn)}
it doesn't work like I wish it would.

I want that 'FocusIsOn' is set to 'Button_1' if 'ButtonNumber' is '1' and if
'ButtonNumber' is '99' to 'Button_99'.

Try the following:-

OPTION 1 - CREATE AN ATTRIBUTE

function MakeButton(nButtonNumber)
{
var xelement = document.createElement("input")
xelement.type = "button"
xelement.type = "button"
xelement.setAttribute("button_number",nButtonNumber);
xelement.onfocus = ButtonFocus;
return xelement;
}

function ButtonFocus(e)
{
var ev=e||window.event;
var e=ev.target||ev.srcElement;
var n=e.getAttribute("button_number");
FocusIsOn = "Button_" + n;
alert(FocusIsOn)
}

OPTION 2 - USE A CLOSURE

function MakeButton(nButtonNumber)
{
var xelement = document.createElement("input")
xelement.type = "button"
xelement.type = "button"
xelement.setAttribute("button_number",nButtonNumber);
xelement.onfocus = MakeFocusHandler(nButtonNumber);
return xelement;
}

function MakeFocusHandler(nButtonNumber)
{
return function()
{
FocusIsOn = "Button_" + nButtonNumber;
alert(FocusIsOn);
};
}

Julian
 
Z

Zif

Stefan said:
I'd like to set a variable called 'FocusIsOn' if a button got the focus.
Because my button is dynamically created I do it like
xelement = document.createElement("input")
xelement.type = "button"
element.onfocus = function() {FocusIsOn = "Button_1"; alert(FocusIsOn)}

That works great. If the button gets the focus, I got a message box saying
'Button_1'.

However, if I set the variable 'FocusIsOn' dynamically (using a variable
'ButtonNumber') like
xelement = document.createElement("input")
xelement.type = "button"
element.onfocus = function() {FocusIsOn = "Button_" + ButtonNumber;
alert(FocusIsOn)}
it doesn't work like I wish it would.

You have created a closure so that the value of ButtonNumber is
whatever it was when the function ended. So if you used a for loop to
create the buttons with say i=0; i<100 then ButtonNumber will be 99.
I want that 'FocusIsOn' is set to 'Button_1' if 'ButtonNumber' is '1' and if
'ButtonNumber' is '99' to 'Button_99'.
However 'FocusIsOn' is effectively set to "Button_" + ButtonNumber.
That means, it doesn't matter which button I click, the message box always
says 'Button_' plus the actual value of 'ButtonNumber'.

Does anyone know how to set a variable like 'FocusIsOn' to a not modifying
string expression?

One way is to call an external function to set the ButtonNumber value
(as per Julian's post), another is to set the ButtonNumber as part of
the button ID and not within the anonymous onclick function:


...
var oBut;
for (var i=0; i<100; i++){
oBut = document.createElement('input');
oBut.type = 'button';
oBut.value = 'Show focus';

oBut.id = 'Button_' + i;
oBut.onclick = showFocus;

// Set the rest of oBut's attributes
// Add it to the document
}
...
}

function showFocus()
{
var msgDiv = document.getElementById('msgDiv');
if(this.id) {
msgDiv.innerHTML = 'Focus is on '+this.id;
} else {
msgDiv.innerHTML = 'Focus is on an anonymous '+this.nodeName;
}
}



...

<div id="msgDiv"></div>


[...]

Incidentally, the idea of Julian's of setting a custom attribute is
not supported by all browsers. It is much better to use a standard
attribute such as id or (for an input element) the name
 
J

Julian Turner

Zif said:
Incidentally, the idea of Julian's of setting a custom attribute is
not supported by all browsers. It is much better to use a standard
attribute such as id or (for an input element) the name

I would second that.

Julian
 
S

Stefan Mueller

Thanks a lot for your suggestions and solutions.

Today I tried a different approach:

1. Store the command to a string variable
xelement = document.createElement("input")
xelement.type = "button"
var tempeval = "xelement.onfocus = function() {FocusIsOn = 'Button_" +
ButtonNumber + "'}"

2. Execute the string variable
eval(tempeval)

I think this is quite easy and it works.

Many thanks again
Stefan
 
R

RobG

Stefan said:
Thanks a lot for your suggestions and solutions.

Today I tried a different approach:

1. Store the command to a string variable
xelement = document.createElement("input")
xelement.type = "button"
var tempeval = "xelement.onfocus = function() {FocusIsOn = 'Button_" +
ButtonNumber + "'}"

xelement.id = 'B' + ButtonNumber;
xelement.onfocus = function (){
FocusIsOn = 'Button_' + this.id.replace(/B/,'');
};

Avoids eval and closure (and hence IE memory issues).

If you are using the id attribute already and can't easily trim some
string from it to get the number, then use name, or class, or any
suitable standard attribute.
2. Execute the string variable
eval(tempeval)

Then why not:

eval("xelement.onfocus = function() {FocusIsOn = 'Button_"
+ ButtonNumber + "'}");

But it's a kludge purely to avoid an inconvenient closure.
I think this is quite easy and it works.

That 'it works' is not sufficient - using eval is almost never
necessary, and is not needed here.

While 'eval' is very powerful it is extremely wasteful of browser
resources. It requires, more or less, that the browser create a new
environment, add the all variables from the current scope, compile and
execute the script, collect garbage then export the variables back into
the original environment. It can't be cached for optimisation, and is
almost impossible to debug if errors occur.

A thread you may like to read:

<URL:http://groups.google.co.uk/group/co...hy+is+eval+evil&rnum=1&hl=en#8e37f4c9436436ad>

And a blog:
<URL:http://blogs.msdn.com/ericlippert/archive/2003/11/01/53329.aspx>


Google 'javascript eval is evil' for plenty more.
 
Z

Zif

RobG said:
xelement.id = 'B' + ButtonNumber;
xelement.onfocus = function (){
FocusIsOn = 'Button_' + this.id.replace(/B/,'');
};

Avoids eval and closure (and hence IE memory issues).

So does:

xelement.onfocus = new Function(
'FocusIsOn = "Button_' + i + '";'
);

[...]
 
Z

Zif

RobG said:
xelement.id = 'B' + ButtonNumber;
xelement.onfocus = function (){
FocusIsOn = 'Button_' + this.id.replace(/B/,'');
};

Avoids eval and closure (and hence IE memory issues).

So does:

xelement.onfocus = new Function(
'FocusIsOn = "Button_' + ButtonNumber + '";'
);

[...]
 
S

Stefan Mueller

Wow, and I thought using 'eval' is a smart solution.
Thanks a lot for your explanation. So I know now not using 'eval' anymore.

I don't like to use the Id or name because than the onfocus statement is
still dynamic and the Id and name not always have to be the same as the
'FocusIsOn' has to be set to.

So I do now
xelement.onfocus = new Function('FocusIsOn = "Button_' + ButtonNumber +
'"');

But what do I do here? Do I really create for each onfocus a new function.
If yes, is that really better than 'eval'? Why is the 'F' in function a big
letter?
How does the stored onfocus statement look like? With 'eval' the statement
was static like I would it have hard coded
xelement.onfocus = function() {FocusIsOn = "Button_43"}

Stefan
 
S

Stefan Mueller

Me again.
After further testing I figured out that the solution with
xelement.onfocus = new Function('FocusIsOn = "Button_' + ButtonNumber +
'"')
does not work if I have several events like
xelement.onfocus = new Function('FocusIsOn = "Button_' + ButtonNumber +
'"')
xelement.onmouseover = new Function('if (FocusIsOn = "Button_' +
ButtonNumber + '") {alert("message 1")})')
xelement.onmouseout = new Function('if (FocusIsOn = "Button_' +
ButtonNumber + '") {alert("message 1")})')

Therefore I use now Rob's solution which works perfect
xelement.onfocus = function() {FocusIsOn = this.id}
xelement.onmouseover = function() {if (FocusIsOn = this.id)
{alert("message 1")}}
xelement.onmouseout = function() {if (FocusIsOn = this.id) {alert("message
2")}}

Thanks again
Stefan
 

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

No members online now.

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,831
Latest member
HealthSmartketoReviews

Latest Threads

Top