PDA

View Full Version : Can javascript detect which form element was just clicked on?


Gladstone
11-22-2002, 10:34 PM
As always I try very hard to answer my own questions but today I find myself a bit stumped. Allow me to present a simplified version of my scenario. I have a form with several elements in it, one of which calls a function with onblur. If the user has clicked on a navigation item on that page, then I do not want to execute that function. Clicking on any other form element is fine. I just want to detect exactly what was just clicked.

Can I do this?

I would like to do so within that function in order to step out and not execute the code if I can.

Am I clear?

TVMIA
Gladstone

chrismiceli
11-22-2002, 10:44 PM
you can add to the onClick even handler this
onClick="this.onBlur=''"

Gladstone
11-22-2002, 11:02 PM
I have no idea what you just told me. Possibly I am being dense or maybe I am not being clear with my description. Allow me to try again with a slight variation. I have a form with an element which calls a function using it's onblur event. The very first thing I want to do in that function is to alert the id or name of the item just clicked on. Can this be done?

TVMIA
Gladstone

krycek
11-22-2002, 11:19 PM
...in IE, you can use event.srcElement to tell you which element generated an event, in your case a mouse click.

I do not know if Netscape has a similar capability.

::] krycek [::

joh6nn
11-22-2002, 11:46 PM
i think that a) chrismiceli is on the right track and that, b) we need to see the page that this is on.

Gladstone
11-23-2002, 12:15 AM
Fair enough. Since it's getting late for me, I'll return Monday AM with code.

ciao:)
Gladstone

Gladstone
11-25-2002, 05:07 PM
It would be impossible for me to provide an address or even show actual code, but I figure pseudo-code should suffice to illustrate my question (Ihope):

<script language=javascript>
function showElemId(){
alert(the elment that was just clicked);
if(user did not click on a navTab){
alert("Got here");}

}
</script>
<div>
navTab1 navTab2 etc.
</div>
<form>
...lots of form elements such as..
<input id=inp1etc>
<input id=inp14 type=text onblur="showElemId()">
<input id=inp99etc>
...more form elements
</form>

My question:
Is it possible to know what element was just clicked on through an onblur event?
In other words, can I implement the second part of the function using this logic?

jkd
11-25-2002, 06:04 PM
onblur="doSomething()"

Inside doSomething():

var evt = window.event || arguments.callee.caller.arguments[0];

var target = evt.target || evt.srcElement;

Now the local variable target refers to the input onblur was called in, in IE, Opera 7, and moz.

Gladstone
11-25-2002, 06:47 PM
Thanks for this. These pieces are new to me so it will take a bit to digest. I am playing around with them now but I am still unable to actually tell the item that was clicked on. If I alert target or evt I get [object]. If I alert target.id, I get the source element's id. Using these new (to me) concepts, how can I alert the id of the target element?

ConfusedOfLife
11-25-2002, 07:52 PM
You could have simulated the same thing by using an array of flags ( assembly experiences! the dirties way probably!).

jkd

Does that target hold the name/id of the caller? I try to alert it but it just shows me "[object]", also may you elaborate on that callee.caller thing?! I've never seen that before!

jkd
11-25-2002, 08:19 PM
target is a reference to the node that was blurred. It is an instance of HTMLElement or TextNode.

Anyway, the correct way of doing events is passing them by arguments. Now, using HTML attribute event handlers, the browser needs to do something special:

<button onclick="doSomething()">click me</button>

What happens is that a wrapper function is created.

refToButton.onclick = function onclick(event) {
doSomething()
}

A method of the button is initialized to the wrapper function, and the event object is passed to it. Now, because we used doSomething() instead of doSomething(event), we need some way to get into the calling function scope and grab arguments[0], or the event object.

arguments.callee.caller.arguments[0] does just that.

I have a tutorial on it somewhere here...
http://www.javascriptkit.com/dhtmltutors/nsevents.shtml

Gladstone
11-25-2002, 08:52 PM
I feel the need to restate/refine my original question. Is it possible to alert the id of the element just clicked on (in other words just given focus) when firing an onblur event?

<html>
<head>
<script language=javascript>
function doSomething()
{
var evt = window.event || arguments.callee.caller.arguments[0];
var target = evt.target || evt.srcElement;
alert(the id of the element just given focus);//how do i do this?????
}
</script>
</head>
<body>
<form id=frmone>
<input id=inp1 tabindex=1 type=text onblur="doSomething()"><br>
<input id=inp2 tabindex=2 type=text onblur="doSomething()"><br>
<input id=inp3 tabindex=3 type=text onblur="doSomething()"><br>
</form>
</body>
</html>

I'm busily reading everything I can find on the net about arguments, caller, callee, etc. but just don't see the answer to my question.

jkd
11-25-2002, 09:16 PM
Umm, I think maybe:

var evt = window.event || arguments.callee.caller.arguments[0];

var related = evt.relatedTarget || evt.toElement;

alert(related.id)

whammy
11-25-2002, 11:48 PM
I would ask the best question:

What are you trying to accomplish (not in code, in English)?

:)

Gladstone
11-26-2002, 12:00 AM
I want to alert the id of the element just clicked on when firing an onblur event from some other element.

I've been looking really hard at the event object today (thanks jkd) and am now thinking it can't be done.

gladstone

whammy
11-26-2002, 12:02 AM
<form id="blah" action="javascript://">
<input type="button" id="mybutton" onclick="alert(this.id)" />
</form>

That alerts "mybutton" when I click on it... isn't that all you need? Forgive me if I'm being dense, I'm trying to get to the root of your dilemma - I figure if you can alert that, you should be able to pass it to a function with no problem. :)

:confused:

If I read your post the OTHER way I interpreted it, you want to see if something else was clicked previously, and execute a function or not depending on that variable?

If so you should be able to change some global variable in order to NOT let the function in question execute...

That's why I was asking "what are you trying to accomplish?" but you still haven't said it in English (not code, remember?) :D

P.S. I reread the post again and it sounds like my second interpretation is correct... what you can do is set a global variable to true, and if someone clicks on the "navtab", then set that global variable to false (or vice-versa).

In the function, only execute it if the global variable is still true. I think that something like this is what you're getting at. I think that ConfusedOfLife is thinking along the same lines, with his "array of flags" statement. :)

Gladstone
11-26-2002, 01:21 AM
I understand what you mean now and will attempt to describe what I'm working on.

It consists of a form with many elements. So many that the form is divided up into sections which the user "sees" through the use of navigational aids (toggling visibility for the different divs). As the user tabs through the form elements, that tab sequence can/will vary depending on user actions. This is handled by onblur="GoToNext" function. This function sets focus to the appropriate field according to user actions. There are circumstances where the user may click on a navigation aid which toggles visibility for part of the form making "GoToNext" function unable to set focus because the field is now invisible. My thoughts were just to detect that the user had clicked on this navigation aid and so not execute that function.

I see an unattractive solution in wrapping each/every set focus routine with conditions like if (visible) and such, but wanted to try this first.

I hope this makes things more clear rather than less.

whammy
11-26-2002, 01:24 AM
If the tab sequence varies, I think you may need to define a global variable? It might not be pretty, but it would be simple. Simplicity is good... I dunno, I think you are overthinking this.

Step back for a minute, and look for a simple solution. "Step away from the computer". This kind of thing shouldn't be too hard.

From everything you're saying, it looks like you are too dependent upon user actions in every step of the process, rather than doing things simply?

Just my two cents again... but something like this should be simple... maybe you are trying to make it too elegant?

If you are trying to do THAT much with javascript, perhaps you should resort to the old standby:

onsubmit=return functionname()

to make sure they have filled out all fields correctly. I know that onblur() has serious flaws if you try to use the same function with multiple fields.

what's wrong with just returning a boolean value on submit?

glenngv
11-26-2002, 01:43 AM
Originally posted by Gladstone
There are circumstances where the user may click on a navigation aid which toggles visibility for part of the form making "GoToNext" function unable to set focus because the field is now invisible.

Why not check if the field is visible before setting focus to it?
Will that solve your problem?

whammy
11-26-2002, 01:45 AM
It looks like everyone is guessing here... do you have any more complete example code, or an English explanation? If Glenn is guessing like I am there is a problem! :)

ConfusedOfLife
11-26-2002, 12:21 PM
Why don't you post the whole code?! We'll solve it for you dear!!

Gladstone
11-26-2002, 04:29 PM
I will try to answer several questions with one reply.

whammy,
I too am a big fan of simplicity. Unfortunately I have inherited this baby and don't have the luxury of time to rethink/rewrite it's core methods. All I need to do is keep it as bug free as possible until the dotnet version is ready. explanantion: dynamically controlling the tab order is a "feature", providing the user with the ability to complete the entire form without ever reaching for the mouse.

glenngv,
You are correct. and that is what I've decided to do. It was not my first choice for a solution though, since there are so many places where I will have to insert that logic. I just was looking for a way to avoid the function call altogether.

ConfusedOfLife,
Sorry, it's way, way, way too big to do that!

All,
Please let me say that you all are the best people. This forum is the best too. I know what I am going to do as a "workaround" until time allows the elegant solution. The coolest thing about this thread for me was the input from jkd which caused me to study the event object. I'm a bit smarter now and so extend mega thanks to everyone who took the time to interact with me. :D :p :thumbsup:

your friend,
Gladstone

whammy
11-26-2002, 11:59 PM
glenngv is da man (so is jkd!). :)

I totally agree about the people on this forum - I have learned so much from them over the years, it's incredible. And I continue to learn. :thumbsup: