Grow your CSS skills. Land your dream job.

Prefill Your Own Forms in Dev

Published by Chris Coyier

There is a good chance there is a bunch of forms on the websites you work on. Login and signup forms, payment forms, contact forms, comment forms, etc. It's a good idea to test these forms. Certainly automated tests are a good idea. Backend tests that process the form data and test the results. Frontend tests that test the functions there are doing what you expect.

But then there is manual testing. Like, I want to test this with my eyeballs and my keyboard and mouse and emotions and stuff. That's probably the most common type of testing for designers. Certainly just filling out the forms by hand is a good idea, but doing that over and over gets so tedious you (gasp) might just not do it very often.

Perhaps we can just toss a little bit of code on our sites to prefill them when we need.

Prefill from the Template

One possibility is to prefill all the time from the template itself. For instance, you could check if you're on the development domain and then prefill the value. Like:

<?php
if ($_SERVER['HTTP_HOST'] == "mysite.dev") {
   $prefill = true;
}
?>

<input type="text"
       name="name"
       id="name"
       <?php if ($prefill) { ?>
       value="Chris Coyier"
       <?php } else { ?>
       value=""
       <?php } ?>
>

Or the Rails-y way:

<input type="text" 
  name="name" 
  id="name" 
  <% if Rails.env.development? %>
  value="Chris Coyier"
  <% else %>
  value=""
  <% end %>
>

The problem with this is that you always see the form filled in on development, which isn't how your users encounter it. I prefer to leave the form how the users see it, then optionally fill it in on-demand.

Prefilling with JavaScript

Using the same test-if-development stuff as above, we can insert a new script onto the page to do the prefilling.

<?php if ($_SERVER['HTTP_HOST'] == "mysite.dev") { ?>
  <script src="/assets/development/form-prefiller.js"></script>
<?php } ?>

There are a couple of ways you could go about it:

  • Automatically prefill fields it finds
  • Insert some buttons to prefill
  • Just have some public functions you can manually call from the console

There isn't much advantages to using JavaScript if you're going to auto-prefill. For the purposes of this demo, I'll make buttons. In reality, I just leave it to the console.

A very simple version of the script might be like:

var PrefillMachine = {
  
  prefillCorrectly: function() {
    $("#name").val("Chris Coyier");
  }

}

Then anytime you're on the page with the form, you just open the console and type:

PrefillMachine.prefillCorrectly();

Or if you had some buttons on the page:

var PrefillMachine = {
  
  init: function() {
    this.bindUIActions();
  },
  
  bindUIActions: function() {
    // Probably even best to insert this button with JS
    $("#prefill-correct").on("click", this.prefillCorrectly);
  },
  
  prefillCorrectly: function() {
    $("#name").val("Chris Coyier");
  }

}

PrefillMachine.init();

Prefill Values and Types

It's one thing to just prefill some set values, but you might want to randomize it a bit. For instance, it doesn't help much to prefill the same username over and over on a signup form, because your system will likely reject it as a duplicate. So let's randomize a bit!

In our PrefillMachine object, we can make a function to give us a random string:

_makeId: function()  {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i=0; i < 5; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  return text;
},

When we call that, it will give us stuff like eQthY, Jv1ea, or Cmy4g. Pretty unlikely to repeat.

So if we're prefilling a name and username, for instance, we might make our prefilling function be like:

prefillCorrectly: function() {

  var id = this._makeId();

  $("#name").val("name_" + id);
  $("#username").val("username_" + id);

  ...

We're just prefixing those randomized values so they would be easy to find in a database if we wanted to wipe them out or something.

Testing an email address? Perhaps use that randomized value as an extension to a gmail address. That way it's unique, but you'll still get the email.

$("#email").val("chriscoyier+" + id + "@gmail.com");

What about checkboxes, radios, and selects? Might be nice to randomize the choices there. We can make a super quick random number generator:

_rand: function(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

Then say there was a radio button group with two choices, we could turn them both off, select one at random, and turn it back on:

$("input[name='radio-choice']")
 .prop("checked", false)
 .eq(this._rand(0, 1))
 .prop("checked", true);

Similarly easy with a select:

$("#select-choice")
  .find("option")
  .prop("selected", false)
  .eq(this._rand(0, 2))
  .prop("selected", true);

Randomize a street address?

$("#address").val(this._rand(1000, 9000) + " Super St.");

You get the picture.

Prefilling Incorrectly

Perhaps just as useful as prefilling a form correctly, you can test error states by prefilling incorrectly. Just make another function for doing that:

prefillIncorrectly: function() {

  // Empty should be invalid
  $("#name").val("");
  $("#username").val("");

  // Space should make invalid
  $("#email").val("jim @jim.com");

  // Force them not to match AND one is blank.
  $("#pw").val("123");
  $("#pw-repeat").val("");

  // Turn both off.
  $("input[name='radio-choice']")
   .prop("checked", false);

  // Not enough numbers
  $("#cc").val("424242424242");
  // Values are wrong
  $("#exp-1").val("50");
  $("#exp-2").val("02");
  $("#cvv").val("abc");

  // Left unchecked
  $("#agree-terms").prop("checked", false);

},

Then call it as you will. Then you can submit and see if your error-handling system is working properly.

You could probably even use all this as part of an end-to-end testing kinda thing, but I'll leave that for smarter folk.

Demo

Here's an example of everything:

See the Pen pzKtx by Chris Coyier (@chriscoyier) on CodePen.


Thanks to Tim Sabat for introducting me to this idea. He came up with it and implemented it on CodePen for us to make testing for all of us easier.

Comments

  1. Interesting idea Chris! Although I personally don’t like to mess up the page I’m working on with PHP tags, and dev script inclusions.

    If working on Chrome (perhaps Firefox allows it too), you can save code snippets in DevTools (Sources > Snippets), then you can run them (right click > Run). It keeps the code clean, and make good use of the DevTools by adding, you know… a developper tool. :P

    Also regarding form filling, there are a couple of browser extensions to do it in a single click, like this one.

    • It can be fine for developing only on desktop but on a typical mobile the plugin is not an option. If you’re developing a form you’re most likely going to know exactly what data it will accept and if there are fields that appears only under some circustances or behaves differently in certain cases,

      setting up a bunch of jQuery selectors will be a lot faster than learning a plugin structure only for the desktop with the hope that it will address every need.

    • also if you think about big teams of developers, once you’ve committed the js file and template that includes it all the devs will have it available on all platform, a plugin would require to go to every single computer (and browser) to install and configure it

  2. I’ve been using this bookmarklet for years https://github.com/dsheiko/autofill. It serves me well

    • Branden

      This is my preferred method as well.

      Bookmarklet in combination with ChanceJS to generate random data.

    • Matt

      Dimitry, Very useful bookmarklet, thanks

      Branden, combining with chanceJS sounds like a perfect solution. It would be great if you could find the time to detail how you do the actual ‘combining’ for those of us less proficient! Either way, very useful cheers.

    • Dan

      That’s excellent! I’m surprised that I had never heard of that before.

      It’s easy enough to modify if you want it to do more. And you can pass the link around to just the developers involved.

      Thanks for sharing.

  3. Personally I’d still prefer to fill the forms out by hand each time – I’m a pretty fast typist!

  4. This is awesome. Thanks Chris!

    I work with Gravity Forms a lot, so am refactoring to make this a bit more generic. e.g.

    jQuery(".gfield_checkbox [type=checkbox]")
         .prop("checked", false)
         .eq(this._rand(0, 1))
         .prop("checked", true);
    
  5. Nice, I did the same for my company website in order to develop faster the post-booking page using the jQuery approach.
    One can be really fast typer to fill out 10 input fields, 4 select menus and a couple of checkboxes, but nothing can beat the a single click in term of speed. And it’s more significant if the operation has to be repeated tons of time, it’s the kind of philosophy that runs projects like grunt.js, “if you have to do it more than once, automate”.
    There are also plugins for chrome that do this but a JS solution is more effective if we think also about mobile, retyping the same form on the desktop with your physical keyboard is one thing, but try it on an iPhone or Android smartphone with autocorrect enabled, you’ll get crazy pretty fast.

  6. Jeff Home

    Bookmarklets are ideal (to prevent polluting the source), or you can craft a userscript (native support in Chrome, supported via GreaseMonkey in Firefox, supported via the likes of CreamMonkey for Safari and Violet Monkey for Opera).

    Personally I would never add development specific branches in code that will end up in production – the risk of something being missed or abused is just too much for the areas I work in.

  7. Maria

    I have been working on a chrome extension Formbot which fits perfectly with form prefilling. You could let it generate random data or set specific data for different types of inputs.

  8. I use LastPass and it has a form fill button, one of which I’ve set up for testing (complete with fake/testing Visa) so I just click that button. It doesn’t take care of checkboxes and radio buttons though. Clever solution.

  9. Too much effort :-p

    But very helpful :-)

  10. Arpita

    You some times make me think that why dint I thought that way earlier. Your Ideas are so clean and down to earth

    Thank you.

  11. If you use a templating language like Laravel Blade/Mustache/Handlebars/Django you could pass in a value to the form and just remove that data from the production environments model.

    <form method="POST">
        <input id="first-name" name="first-name" placeholder="First Name" value="{{ test.name.first }}">
        <input id="last-name" name="last-name" placeholder="Last Name" value="{{ test.name.last }}">
    </form>
    

    If the model value for test is empty, then nothing is rendered and the value string is empty as far as the browser is concerned.

  12. I’m a huge fan of the Formlet Firefox add-on. Manually fill the form out once, and then Formlet saves the form data to a bookmarklet. The bookmarklet is completely portable vanilla javascript. IOW, the add-on is not required to execute the bookmarklet, so you can send it to a colleague, etc.

    It does all form elements like checkboxes, radios, textarea, and whatnot. No messing about in the code, and it’s a huge time saver.

  13. John

    I use the chrome extension FormFiller (https://chrome.google.com/webstore/detail/form-filler/bnjjngeaknajbdcgpfkgnonkmififhfo). I prefer to use that because I don’t have to write any extra code that gets committed into source control.

  14. I wrote up a gist for this a few projects ago, using the ten most common boys’ and girls’ names and 20 most common surnames, a made up Twitter handle, plus a profile photo from http://www.fillmurray.com and some lipsum from http://json-lipsum.appspot.com. Saved me loads of time but got me a worried query from the client who wondered where all these people had come from.

    https://gist.github.com/chris5marsh/8455299

  15. خرید وی پی ان

    You some times make me think that why dint I thought that way earlier. Your Ideas are so clean and down to earth

    Thanks

  16. Very cool. We often use a cookie to turn on dev specific settings like this. So, you could wrap the prefiller.js with a check to see if there is a cookie called debug==tru.

  17. Max
    Permalink to comment#

    FormFiller looks really promising. Simple and concise! Thanks for the write-up, Chris! Amazing and interesting as usual.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".