Getting jQuery Validation plug-in to work with requirejs

I’ve created a form on WordPress-powered site. It’s currently using RequireJS to add two buttons to a page element, but I’d also like Require to control some things in the jQuery Validation plug-in. The adding of the buttons work fine, but sadly, the validation is not working.

The form looks like this in the HTML:

Read More
  <form id="contact" method="get" action="">
    <fieldset id="contact-form-fields">
      <p>
        <label for="form_name" class="form-titles">Name</label>
        <input name="form_name" id="form_name" type="text" placeholder="Name" aria-required="true" class="required"> 
      </p>
      <p>
        <label for="form_email" class="form-titles">Email</label>
        <input name="form_email" id="form_email" type="text" placeholder="Email" aria-required="true" value="">  
      </p>
      <p>
        <label for="msg_text" class="form-titles">Email</label>
        <textarea tabindex="-8" rows="10" placeholder="Type your awesome message here." class="placeholder" name="msg_text" id="msg_text" aria-required="true" class="required"></textarea>
      </p>
    </fieldset>
    <input type="submit" value="Send Your Message" name="submit" class="button">
  </form>

RequireJS is attached to the page like this:

<script data-main="http://livetest.kaidez.com/wp-content/themes/kaidez-2012/js/config.js" src="http://livetest.kaidez.com/wp-content/themes/kaidez-2012/js/require-jquery.js"></script>

The above-mentioned config.js file looks like this:

require.config({
  baseUrl: "http://livetest.kaidez.com/wp-content/themes/kaidez-2012/js",

  deps: ['scripts'],

  paths: {
    jquery: "jquery",
    jqueryValidate: "jquery-validate.min" 
  },

  shim: {
    jquery: {
      exports: "jquery"
    },
    jqueryValidate: {
      deps: ["jquery"]
    }
  }
});

config.js says it has a dependency called scripts.js, which looks like this:

// code that adds buttons to the page
require(['jquery'], function ($) {

  var header = document.getElementById("masthead"),
    $navMenu = $("#site-navigation-list"),
    $searchBox = $("#searchform"),
    menuButton = document.createElement("div"),
    searchButton = document.createElement("div"),
    showMenus;

  $(menuButton).attr("id", "menu");
  $(searchButton).attr("id", "search");

  header.appendChild(searchButton);
  header.appendChild(menuButton);

  showMenus = function(btn,el) {
    $(btn).click(function() {
      if (el.is(":visible") ) {
        el.slideUp({
          complete:function(){
            $(this).css("display","");
          }
        });
       } else {
         el.slideDown();
       }
    });
  };

  showMenus(menuButton, $navMenu);
  showMenus(searchButton, $searchBox);

});

//code that controls jQuery Validate
require(["jquery", "jqueryValidate"], function($, jqueryValidate) {
  $("#contact").validate({
    rules: {
      form_email: {
        required: true,
        number: true
      }
    }
  });
}); 

Looking at other posted questions, jsFiddles, etc and I can’t seem to find an answer. I think my error is in my RequireJS settings but I’m not sure. Working dev environment code is here. Any help is appreciated.

Related posts

Leave a Reply

1 comment

  1. I believe that I’ve found an answer to my own question. The TL;DR answer is:

    RequireJS can be added to work in WordPress but if you install jQuery-dependent plugins via WP-Admin, there’s a VERY good chance that you’ll load jQuery core a second time, which is not good.

    The long answer…here we go:

    I was trying to use two RequireJS modules to manage form validation with some help from the jQuery Validation plugin (the above-mention code to add buttons doesn’t matter). I got this to work with the following code:

    The contact form looks like this in the HTML:

    <p id="success-msg" style="display:none">Your message has been sent successfully.</p>
    <!-- The tag above appears if the form goes through-->
      <form id="contact" method="post">
        <fieldset>
          <div class="left">
            <input name="form_name" id="form_name" type="text" placeholder="Your Name"> 
          </div>
          <div>
            <input name="form_email" id="form_email" type="text" placeholder="Your Email" class="required email">  
          </div>
          <textarea tabindex="-8" rows="10" placeholder="Type your awesome message here." class="placeholder" name="msg_text" id="msg_text" ></textarea>
        </fieldset>
        <input type="submit" value="Send Your Message" name="submit" class="button">
      </form>
    

    RequireJS is referenced in the HTML like this:

    // both require.js and config.js are stored in a directory called 'js' in a child theme
    <script src="<?php echo get_stylesheet_directory_uri(); ?>/js/require.js" data-main="<?php echo get_stylesheet_directory_uri(); ?>/js/config.js"></script>
    

    config.js looks like this:

    requirejs.config({
      baseUrl: "http://yourdomain.com/wp-content/themes/yourTheme/js",
    
      deps: ["form"], // lists 'form.js' as a dependency, where our form code will be
    
      paths: {
        /*
         * Referencing the 'wp-includes/js/'
         * directory in WP. jQuery was pre-installed 
         * but Validation was manually added.
         */
        jquery: "http://yourdomain.com/wp-includes/js/jquery/jquery",
        val: "http://yourdomain.com/wp-includes/js/validate"
      },
    
      shim: { 
      jquery: {
        exports: 'jquery'
      },
      val: {
        deps: ['jquery'],
        exports: 'jquery'
      }
    },
    
      waitSeconds: 20
    });
    

    The above-mentioned form.js file looks like this:

    define("form", ["jquery", "val"], function($) {
    
    $("#contact").submit(function(event) {
      var name = $("#form_name").val();
      var email = $("#form_email").val();
      var text = $("#msg_text").val();
      var dataString = 'name='+ name + '&email=' + email + '&text=' + text;
    
      event.preventDefault();
    
        if($("#contact").valid()){
          $.ajax({
          type: "POST",
          url: "http://yourdomain.com/wp-content/themes/yourTheme/email.php",
          data: dataString,
          success: function(){
            $("#contact").fadeOut(100);
            $('#success-msg').fadeIn(100);
          }
        });
    
        return false;
        }
      });
    });
    

    And just for clarity, the PHP that sends out an email after a successful form submission (email.php) looks like this.

    <?php
    
    if($_POST){
      $name=$_POST['name'];
      $email=$_POST['email'];
      $text=$_POST['text'];
    
      //send email
      mail("your@email.com", "your subject",
      $text, "From:" . $email);
    }
    
    ?>
    

    The good news is that everything above works as is. The bad news shows up if you use WordPress to install a jQuery-dependent plugin. Due to the WordPress architecture, plugins like this will automatically install jQuery core unless it’s already installed via functions.php or some other WP internal method. Calling jQuery via RequireJS like I did won’t stop this.

    I tried a lot of different methods to fix this using wp_deregister_script(), wp_enqueue_script(), etc. but had no luck. This works fine for the personal project I’m working on but it’s probably not good for a client project.

    There is a WordPress ticket to add AMD functionality to WordPress with the goal of calling different versions of jQuery. (read it here). Hopefully this issue will be addressed if there’s follow-thru on the ticket. Until then, I’m pretty sure that this is how it is, for now.