Getting and assigning form element values in a Javascript Module Pattern

Hello my friends:

Almost all of the code examples I have seen regarding Module Pattern are examples of hard coded values. How do I assigned and get the values from form elements using a module without calling the anonymous function?

Here is my problem:

I need to access all of the elements in a form using a Module pattern. In a nutshell, I want to avoid repetitive code and use only a single module for organization purposes. How do I do this without calling the Anonymous function from the module it self:

Instead of writing like this: FormData.LastName() I want to simply have it look like this: FormData.LastName

Below is an example I tried:

   'use strict';
    
    FormData = (function() {
    
      //Get form elements.
        var formElement = document.forms.signup;
    
        return {
            // Return last name value from form.
            LastName: function(){
                return formElement.lName.value;
            },
           
           //Return form submit button.
            SendBtn: function(){
                return formElement.submitSignupForm;
            }
        };
    
    })();

I call the module like this: Again, the goal is to eliminate exposing form data as Global elements in code.

FormData.SendBtn().addEventListener('click', function(e){

    document.getElementById('result').innerHTML = FormData.LastName();

    e.preventDefault();
}, false);

It sounds like you are wanting to instead populate an object with data, so that you can then retrieve the appropriate values for each key.

Another technique is to use a getter, which seems to be closer to what you desire, but isn’t as fully supported across web browsers as of yet.x

Hello Paul:

I tried the following two variations using getter as described on the link you provided but I am still not able to get the form values:

FormData = (function() {

    var element = document.forms.signup.elements;

    var obj = { name: "" }

    Object.defineProperty(obj, "combineName", { 
        get: function () { 
            return this.name = element.fName.value + " " + element.lName.value;; 
        } });

    return {

        FullName: obj.combineName
    }

})();

var submit = document.getElementById('submitSignupForm');

submit.addEventListener('click', function(e){

    document.getElementById('result').innerHTML = FormData.FullName;

    e.preventDefault();
})

Variation #2:

FormData = (function() {

    var element = document.forms.signup.elements;

    var obj = {
        get combineName () {
            return element.fName.value + " " + element.lName.value;
        }
    };

    return {
        FullName: obj.combineName
    }

})();

If I simply hard code the values like below it works:

FormData = (function() {

    var element = document.forms.signup.elements;

    var obj = { name: "" }

    Object.defineProperty(obj, "combineName", { 
        get: function () { 
            return this.name = "Donald Draper"
        } });

    return {

        FullName: obj.combineName
    }

})();

Using a computed getter is only effective the first time that you access it. If you want it to update based on changed information, you will need to use a function as per normal.

For the sake of interest, why are you wanting to disguise this behaviour? Surely it’s easier to use the click event to update fullName somewhere, even in a hidden field in the form itself.

Because I need to encapsulate the entire process: Meaning getting the user input. I need to create a module that I can access from anywhere to get the form data but I do not want to make this Global:

  1. Use a Module Pattern to encapsulate the form values. If I need a value from the form I go to the Module.
  2. Keeps the entire process in a single place, I do not want to do getDocumentById over ad over, just call a member from the module.

Seems like you’ve already achieved all those in your original post. And from what I gather, the only thing you don’t like about it… for aesthetic reasons?.. is the parentheses after LastName().

You are right: But I would rather represent the data as a variable then a method. What I mean is, it looks confusing for the first look.

Name() looks like a function.

There is an easy solution here. Use a hidden input for the full name and have changes to the first and last name update that full name.

Paul can you please provide me an example or a link?

Thanks

Will do when I get home in around 4 hours

Okay, a nice example is with the following simplified form:

<form id="personalDetails">
    First name: <input type="text" name="firstName">
    Last name: <input type="text" name="lastName">
    <input type="hidden" name="fullName">
</form>

You’ll see that there’s a separate hidden input field, that we’ll use for the fullName. The benefit of this is that you can access form.elements.fullName.value just as you would for other fields in the form, and the fullName will be submitted with the form too.

The main work is done by an updateFullName function.

function updateFullName() {
    var form = this.form,
        elements = form.elements;
    elements.fullName.value = elements.firstName.value + ' ' + elements.lastName.value;
}

And we tell the first and last name fields to update the hidden one as follows:

var form = document.getElementById('personalDetails');
form.elements.firstName.onchange = updateFullName;
form.elements.lastName.onchange = updateFullName;

Now whenever someone changes the first or last name field, the fullname will update itself too.

Thank you very much Paul. Now I have something to work with.
Thanks again!

One of the things to bear in mind here is that you should not ordinarily rely on JavaScript working. For example, instead of starting with a hidden field, you could instead have a standard text field for the fullname and then have JavaScript replace that with a hidden field when the scripting takes over the task. That will allow the form to work under almost all conditions.

The server still has a job to do though, of checking the fullname too. If it’s empty then the server itself should create the fullname from the first and last parts.

The first line of defense is to assume that JavaScript isn’t working and to figure out how things will work under those conditions. Then once you have that in place you can use JavaScript to improve the user experience.

When you’re not doing a JavaScript-only app, the above is a good and safe approach to take.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.