1. Trang chủ
  2. » Công Nghệ Thông Tin

Practical prototype and scipt.aculo.us part 20 ppsx

6 245 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 6
Dung lượng 146,96 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Imagine thateach of the text boxes has a state that’s either valid or invalid.. Both text boxes need to be valid before the form is submitted.. When the page loads, both text boxes are e

Trang 1

We don’t need a server round-trip here, though We can just as easily check whether

a field is blank on the client side We want to code defensively, catching possible user

mistakes as early as possible

We can perform this check when the form is submitted; we’ve already got a function

handling that event

function submitEntryForm(event) {

event.preventDefault();

if ($('food_type').value === '' || $('taste').value === '') {

alert('Both fields are required.');

return;

}

var updater = new Ajax.Updater(

{ success: 'breakfast_history', failure: 'error_log' },

'breakfast.php',

{ parameters: { food_type: $('food_type').value, taste: $('taste').value } }

);

}

Our handler now branches If the two fields we’re looking at are empty, we show a

message and stop; if not, we submit the form via Ajax Either way, we want to stop the

default action of the form, so we move the event.preventDefaultcall to the top of the

function (see Figure 5-8)

Figure 5-8.The validation message we expected

Trang 2

This works just like we expected But let’s try something a bit subtler Imagine that

each of the text boxes has a state that’s either valid or invalid At any point in time, it’s

either one or the other Both text boxes need to be valid before the form is submitted Let’s write a CSS rule for an invalid text box:

input#food_type.invalid,

input#taste.invalid {

border: 2px solid #900;

}

So that we aren’t too subtle, an invalid text box will be shown with a thick red border.

When the page loads, both text boxes are empty, but neither one can be called

invalid yet, because the user hasn’t had a chance to enter text But we know it’s definitely invalid if the text box receives focus, then loses focus, and is still empty That’s when we

should alert the user

There’s an event for losing focus—it’s called blur So let’s use it

function onTextBoxBlur(event) {

var textBox = event.element();

if (textBox.value.length === 0) textBox.addClassName('invalid');

else textBox.removeClassName('invalid');

}

We use Prototype’sEvent#elementmethod to figure out which element received the event The method ensures that we get an element node as the target, not a text node When a text field is blurred, we make sure it has a nonempty value If so, we add the class name to mark it as invalid If not, the field is valid, so we remove the class name We’re going to leave our submithandler the way it is, since the blurhandler won’t catch everything But let’s change it to use the new approach

function submitEntryForm(event) {

event.preventDefault();

var valid = true;

$('food_type', 'taste').each(function(box) {

if (box.value.length === 0) {

box.addClassName('invalid');

valid = false;

} else box.removeClassName('invalid');

});

if (!valid) {

alert('Both fields are required.');

return;

}

Trang 3

var updater = new Ajax.Updater( { success: 'breakfast_history',

failure: 'error_log' }, 'breakfast.php',

{ parameters: { food_type: $('food_type').value, taste: $('taste').value } });

}

Don’t forget to attach the new handler Add it to the addObserversfunction

function addObservers() {

$('entry').observe('submit', submitEntryForm);

$('toggler').observe('click', toggleEntryForm);

$('food_type', 'taste').invoke('observe', 'blur', onTextBoxBlur);

}

Remember Enumerable#invoke? Here we’re using it to call the observemethod on a

collection of two elements, passing the last two arguments in the process

Now let’s do some functional testing to make sure this works right Reload the page

in your browser

First, try clicking the submit button immediately, before focus has been given to

either text box Figure 5-9 shows the result

Figure 5-9.Both text boxes are invalid.

Works as expected! Now click inside the food_typetext box and type some text Press

Tab to change focus, and notice how the red border disappears (see Figure 5-10)

Trang 4

Figure 5-10.Only the second text box is invalid.

Now click inside the food_typetext box once again to give it focus Delete the box’s value, and then press Tab The text box should once again have a red outline, as shown in Figure 5-11

Figure 5-11.Both text boxes are once again invalid.

You might consider all this redundant, since the server validates the data itself, but keep in mind that the client-side and server-side validations serve different purposes The server is validating the data so that it can let the client know if the request was

suc-cessful; this is useful no matter how the breakfast log entry gets posted The client is

validating the data so that it can present a helpful and humane UI The two are not at odds with one another

Also, remember that client-side validation is not a replacement for server-side valida-tion Ideally, you’d do both, but validating data on the server is essential You’re in control

of the server; you’re not in control of the client

Trang 5

Cleaning It Up

We could leave it like this, but if you’re code-compulsive like I am, you’ve probably

noticed several redundant lines of code The check we’re doing inside submitEntryFormis

nearly identical to the one we’re doing inside onTextBoxBlur By changing the way we

observe the form, we can easily combine these checks into one

First, we’ll write a function that checks one text box for validity:

function validateTextBox(textBox) {

if (textBox.value.length === 0) {

textBox.addClassName('invalid');

return false;

} else {

textBox.removeClassName('invalid');

return true;

}

}

We’ll use the return value of this function to indicate whether the text box in question

is valid or invalid—trueis valid; falseis invalid

Now we’ll write a function that checks the entire form for empty text boxes:

function validateForm(form) {

var textBoxes = Form.getInputs(form, 'text');

return textBoxes.all(validateTextBox);

}

The highlighted part introduces a new method: Form.getInputs It accepts a form

ele-ment as the first parameter and returns all of the inputelements contained within The

second argument is optional; if present, it will return only inputs of the given type Here

we want the form’s text boxes, so the second argument is "text"

Form.getInputsis also available as an instance method on formelements (e.g.,

form.getInputs('text');)

The second line gets a little tricky Instead of using Array#eachto iterate over the text

boxes, we’re using Array#all Since validateTextBoxreturns a Boolean, we can look at the

return values to figure out whether all text boxes are valid If so, the statement (and thus

the validateFormfunction) returns true; if not, false

So, this function doesn’t just mark our text boxes; it also returns a “good data/bad

data” Boolean value If the function returns false, we’ll know not to submit the form

Now we can simplify the code in submitEntryForm:

Trang 6

function submitEntryForm(event) {

event.preventDefault();

if (!validateForm('entry')) return;

var updater = new Ajax.Updater(

{ success: 'breakfast_history', failure: 'error_log' },

'breakfast.php',

{ parameters: { food_type: $('food_type').value, taste: $('taste').value } } );

}

Our new code does the same task more succinctly If validateFormreturns false, we bail on the form submission so that the user can correct the errors (which have been helpfully outlined in red) Otherwise we proceed as planned

As a last step, we can rewrite the onTextBoxBlurfunction and save a couple lines

of code:

function onTextBoxBlur(event) {

return validateTextBox(event.target);

}

We’ve done more than clean up our code in this section; we’ve also eliminated redundancy Furthermore, the new code will continue to work even if we add extra text boxes to the form later on Make your code as flexible as possible—it will save time in the long run

Custom Events

I’ve saved the best part for last Native browser events are purely reactive; they’re trig-gered by user action Wouldn’t it be great if we could harness the event model and use it

to make our own events?

Let’s go back to our fantasy football example Imagine being able to trigger an “event”

in your code whenever the user changes his lineup, or whenever the lead changes in a

game You’d also be able to write code that listens for those kinds of events and calls

han-dlers accordingly

If I were to get academic on you, I’d call this an event-driven architecture I could also

call it a publish/subscribe model (or pub/sub for short) No matter what I call it, the key

idea is the decoupling of publisher and subscriber The code that responds to these kinds

of events doesn’t need to know how the event was triggered—the object sent along with

the event will contain all the necessary information

I wouldn’t be telling you any of this, naturally, if it were a pipe dream Prototype introduced support for custom events in version 1.6 Using Prototype, you can fire

Ngày đăng: 03/07/2014, 01:20

TỪ KHÓA LIÊN QUAN