3
\$\begingroup\$

I'm working on avoiding JavaScript that either directly modifies the DOM a ton, contains a ton of anonymous functions, or is encapsulated in giant $(document).ready... blocks.

This is one of my first attempts at writing a section of my project in a better way. The code is commented and organized fairly well, so it should be easy to understand how it functions. My main question is: Am I going about this the right way?

// Object literal for handling all aspects of adding a company
var addCompany = {

  // Initialize object
  init: function() {

    // Save elements references
    addCompany.elements = {
      openForm: $('#add-company-btn'),
      form: $('#add-company-form'),
      usernameField: $('#username'),
      usernameErrorField: $('#username-error div'),
      passwordField: $('#password'),
      passwordErrorField: $('#password-error div'),
      password2Field: $('#password2'),
      password2ErrorField: $('#password2-error div'),
    };

    // Run on click 
    addCompany.elements.openForm.click(
      addCompany.focusFirst
    );

    // Run on focus
    addCompany.elements.form.submit(
      addCompany.validate
    );
  },

  // Focus the first input field 
  focusFirst: function() {
    setTimeout(function(){
      addCompany.elements.usernameField.focus();
    }, 0);
  },

  // Validate the form
  validate: function() {

    // Store the error tests
    var noUsername = (addCompany.elements.usernameField.val().trim() === ''),
        noPassword = (addCompany.elements.passwordField.val().trim() === ''),
        differentPasswords = (addCompany.elements.passwordField.val() !== addCompany.elements.password2Field.val());

    // Return the results of running the tests
    return addCompany.handleError(addCompany.elements.usernameErrorField, noUsername) &&
           addCompany.handleError(addCompany.elements.passwordErrorField, noPassword) &&
           addCompany.handleError(addCompany.elements.password2ErrorField, differentPasswords);
  },

  // Given an error, handle the display of error fields
  handleError: function(error_field, error) {
    if(error) {
      error_field.show();
      return false;
    } else {
      error_field.hide();
      return true;
    }
  }
};
\$\endgroup\$
2
\$\begingroup\$

You are going very well. There is nothing wrong with it, except there are some things that can be further improved. To improve it you can further do:

  1. addCompany should be in pascal case i.e. AddCompany
  2. Try to use this i.e. use this.something instead of using addCompany.something everytime.
  3. Module name should be noun instead of word. You may use Company instead of addCompany
  4. You can make the private properties using the following version of Modular Pattern:

    var Company = function () {
    
    // ------- Start #PrivateSection ------
    
    // Save elements references
    var elements = {
      openForm: $('#add-company-btn'),
      form: $('#add-company-form'),
      usernameField: $('#username'),
      usernameErrorField: $('#username-error div'),
      passwordField: $('#password'),
      passwordErrorField: $('#password-error div'),
      password2Field: $('#password2'),
      password2ErrorField: $('#password2-error div'),
    };
    
    
    // Given an error, handle the display of error fields
    var handleError = function(error_field, error) {
      if(error) {
        error_field.show();
        return false;
      } else {
        error_field.hide();
        return true;
      }
    }
    
    // ------- End #PrivateSection --------
    
    
    // Public Properties and methods
    return {
      // Initialize the object
      init : function () {
        bindUI();
      },
    
      // All the event bindings to go here.
      bindUI : function () {
        // Run on click 
        addCompany.elements.openForm.click(
          addCompany.focusFirst();
        );
    
        // Run on focus
        addCompany.elements.form.submit(
          addCompany.validate
        );
      },
    
      // Focus some element
      focusElement: function( el ) {
    
        var toFocus;
    
        // If no value provided
        if ( typeof el == "undefined" ) {
          // Focus the first element
          toFocus = elements.usernameField;
        } else {
          // Focus the provided element element
          toFocus = el;
        }
    
        toFocus.focus();
      },
    
      // Validate the form
      validate: function() {
    
        // Store the error tests
        var noUsername = (addCompany.elements.usernameField.val().trim() === ''),
            noPassword = (addCompany.elements.passwordField.val().trim() === ''),
            differentPasswords = (addCompany.elements.passwordField.val() !== addCompany.elements.password2Field.val());
    
        // Return the results of running the tests
        return handleError(elements.usernameErrorField, noUsername) &&
               handleError(elements.passwordErrorField, noPassword) &&
               handleError(elements.password2ErrorField, differentPasswords);
      }
    
    };
    };
    

And then to use it,

var c = new Company();
c.init();
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.