Jump to content
Larry Ullman's Book Forums

Chapter 10 Working With Forms


Recommended Posts

I am going through chapter 10 and I have run into a problem with focus and blur events on multiple form elements. I have a function which adds multiple events and handlers to elements.

 

function addPlaceholderHandlers(elem) {
'use strict';

elem.onfocus = setOpacity;
elem.onkeydown = removePlaceholder;
elem.onblur = addPlaceholder;

} // end of addPlaceholderHandlers function

 

Then I run the following code in window.onload

 

window.onload = function() {
'use strict';

var elements = document.getElementById('caseEval').childNodes;
for (var i = 0, count = elements.length; i < count; i++) {
var element = elements[i];

addPlaceholderHandlers(element);
}
};

 

 

The onkeydown is the only code that actually runs, and I suspect that this is so because the focus and blur events do not bubble. The obvious solution is to use the addEventHandler and set the phase to true to "capture" the event, however, I am not aware that IE has an equivalent for phase. Aside from referencing each individual element, adding the event to each element, and then setting an event handler for each individual element, is there a better alternative for selecting multiple elements when using the focus and blur?or should I change my event handlers to something other then:

 

function removePlaceholder(evt) {
'use strict';

// get reference to the event
if (!evt) evt = window.evt;

// element triggering the event
var target = evt.target || evt.srcElement;

if (target.value === target.defaultValue) {
target.value = '';
}

target.style.color = '#000';

} // end of removePlaceholder function

 

I would just like to add that I absolutely love this book and the support in this forum. I have never done any programming until three or so weeks ago, and I didn't even know what HTML was just a few weeks prior to that. I feel that this book is so well written, concise in its examples, and relevant that it should be in every beginners and maybe some intermediate programmer's bookshelf. You have definitely gained a lifelong reader.

Link to comment
Share on other sites

I was thinking about using the label like this (var form = document.getElementById('caseEval'); form.getElementsByTagName('label') ) and moving it dynamically into the text box, so that users w/out Javascript would have the same functionality with the form, although, I am not sure that that would solve my phase problem. I have so many ideas, just difficulty executing them. The code you requested is below. It seems repetitive, but I don't know how else to reference target and event.

 

As always, very grateful for your time and help.

 

 

function setOpacity(evt) {
'use strict';

if (!evt) evt = window.evt;

// prevent default behavior
if (evt.preventDefault) {
evt.preventDefault();
} else {
evt.returnValue = false;
}

// get reference to element triggering the event
var target = evt.target || evt.srcElement;

// set opacity of target element text
if ( target.value === target.defaultValue) {
target.style.color = '#c8c8c8';
target.style.backgroundColor = '#fff';
target.setSelectionRange(0,0);
}

 

function addPlaceholder(evt) {
'use strict';

if (!evt) evt = window.evt;

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

if ( (target.value === '') || (target.value === target.defaultValue) ) {
target.value = target.defaultValue;
target.style.color ='#7a7a7a';
target.style.backgroundColor = '#e9e9e9';
}

} // end of addPlaceholder function

Link to comment
Share on other sites

I whipped up a real quick script for testing the three events with form input elements.

 

<!DOCTYPE html>
<html lang="en">

 <head>

   <meta charset="UTF-8">

   <title>JS event test</title>

 </head>

 <body>

   <form>

  <input type="text" id="1">

  <br>

  <input type="text" id="2">

  <br>

  <input type="text" id="3">

   </form>

   <div id="output"></div>

   <script>

  var inputs = document.getElementsByTagName('input');

  var output = document.getElementById('output');

  for (var i = 0; i < inputs.length; i++) {

    inputs[i].onblur = blurMe;

    inputs[i].onfocus = focusMe;

    inputs[i].onkeydown = keyDownMe;

  }

  function blurMe() {

    output.innerHTML += this.getAttribute('id') + ': Blurred<br>';

  }

  function focusMe() {

    output.innerHTML += this.getAttribute('id') + ': Focused<br>';

  }

  function keyDownMe() {

    output.innerHTML += this.getAttribute('id') + ': Key down<br>';

  }

   </script>

 </body>

</html>

 

The HTML is far from valid and the the JS is sloppy, but I wrote the code that way for the sake of simplicity.

Anyway, something that's worth noting is that if you tab from one input to the next, the tab key triggers a key-down event in that input before firing the blur event for the same input.

Anyway, you might want to create a similar logging-type function for your events and first ensure whether the events are not being triggered or if they are being triggered, but then the code isn't doing anything/what you want.

 

Please report back the results.

I apologize for not looking at your code in detail, but it's late here and gotta get to bed.

If you can't resolve the issue soon, I'll take a closer look at your code later.

Thanks.

Link to comment
Share on other sites

Thank you for your help. I set up a similar event testing function, and it turns out that the keydown was creating some issues, since it was not firing when I expected. BTW, the reason "nothing was working" was because I didn't start my server. I was so preoccupied with trying to get this to work, that I ignored the simple things. I remembered that Larry wrote to just step away, eat an apple...and then come back fresh, and all of a sudden everything was making sense. Thank you for all your help yet again.

Link to comment
Share on other sites

 Share

×
×
  • Create New...