The next step is for FormHandler to listen for the
submit
event on the <form>
element and run a callback when it occurs.
To make the FormHandler module more reusable,
you will not hardcode the submit
handler code. You will instead
write a method that accepts a function argument, adds the
submit
listener, and then calls the function
argument inside that listener.
First, add a prototype method called addSubmitHandler to formhandler.js.
... if (this.$formElement.length === 0) { throw new Error('Could not find element with selector: ' + selector); } } FormHandler.prototype.addSubmitHandler = function () { console.log('Setting submit handler for form'); // More code will go here }; App.FormHandler = FormHandler; ...
Instead of using the addEventListener method as you did with Ottergram, you will use jQuery’s on method. It is similar to addEventListener but provides added conveniences. For now, though, you will use it the same way you would use addEventListener. (You will take advantage of some of the extra conveniences in the next chapter.)
... if (this.$formElement.length === 0) { throw new Error('Could not find element with selector: ' + selector); } } FormHandler.prototype.addSubmitHandler = function () { console.log('Setting submit handler for form');// More code will go herethis.$formElement.on('submit', function (event) { event.preventDefault(); }); }; ...
The on method accepts the name of the event and a callback to run when the event is triggered. Its callback should expect to receive the event object. You called event.preventDefault to ensure that submitting the form does not take the user away from the CoffeeRun page. (You did the same thing with the thumbnail links in Ottergram.)
When the form is submitted, your code should read the user input
from the form, then do something with that
data. In the submit
handler in formhandler.js, create a new variable named
data
. Assign it an object literal. It will
hold the value
of each element of the form.
... FormHandler.prototype.addSubmitHandler = function () { console.log('Setting submit handler for form'); this.$formElement.on('submit', function (event) { event.preventDefault(); var data = $(this).serializeArray(); console.log(data); }); }; ...
Inside your submit
handler callback, the this
object is a reference to the form
element.
jQuery provides a convenience method (serializeArray)
for getting the values from the form. In order to use serializeArray,
you need to “wrap” the form using jQuery. Calling $(this)
gives you
a wrapped object, which has access to the serializeArray
method.
serializeArray returns the form data as an array of objects. You are assigning that to a temporary variable named data and logging it to the console. To get an idea of what serializeArray looks like, save your file and run the following code in the console:
var fh = new App.FormHandler('[data-coffee-order="form"]'); fh.addSubmitHandler();
Next, fill out the form with some test data and click the Submit
button. You should see the array printed to the console.
Click the
next to a couple of the Object
items in the array.
You should see something like Figure 10.4.
You can see that each object in the array has a key that corresponds to the name
attribute of a <form>
element and the user-supplied value
for that element.
Now you can iterate through the array and copy the values from each element. Add a call to the forEach method to serializeArray in formhandler.js and pass it a callback. As the callback is run for each object in the array, it will use the object’s name and value to create a new property on the data object.
... FormHandler.prototype.addSubmitHandler = function () { console.log('Setting submit handler for form'); this.$formElement.on('submit', function (event) { event.preventDefault(); var data =$(this).serializeArray();{}; $(this).serializeArray().forEach(function (item) { data[item.name] = item.value; console.log(item.name + ' is ' + item.value); }); console.log(data); }); }; ...
To see this in action, save your changes and run your test code again in the console before filling out the form:
var fh = new App.FormHandler('[data-coffee-order="form"]'); fh.addSubmitHandler();
When you fill out the form and click the Submit button, you should see that the information you entered is copied to the data object and logged to the console (Figure 10.5).
Now that you have the form data as a single object, you need to pass that object to your Truck instance’s createOrder method. But FormHandler has no access to the Truck instance. (And it would do no good to create a new Truck instance here.)
You can solve this by making addSubmitHandler accept a function parameter, which it can call inside the event handler.
In formhandler.js, add a parameter called fn
.
... FormHandler.prototype.addSubmitHandler = function (fn) { console.log('Setting submit handler for form'); this.$formElement.on('submit', function (event) { event.preventDefault(); ...
The submit
handler callback will be called
any time the form’s submit
event is triggered
in the browser. When that happens, you want the
fn
function to be called.
Call fn
inside the submit
handler callback in formhandler.js and pass it the data
object
that contains the user input.
... FormHandler.prototype.addSubmitHandler = function (fn) { ... console.log(data); fn(data); }); }; ...
Now, when a FormHandler instance is created, any callback can be passed to addSubmitHandler. From then on, when the form is submitted, the callback will be invoked and will be passed whatever data the user entered into the form.
18.116.49.247