34

I'm using the jQuery validate plugin, and would like to return a random value on success.

Right now I'm trying to use:

     var success_message = new Array ();
     success_message[0] = "Good!";
     success_message[1] = "Ok!";
     success_message[2] = "Great!";
     success_message[3] = "Perfect!";
     success_message[4] = "Nice!";
     success_message[5] = "Awesome"; 
     var i = Math.floor(5 * Math.random())

Then where I need to output the value I use:

 $(document).ready(function(){
     var validator = $(".contactform").validate({
        success: function(label) {
           label.addClass("valid").text(success_message[i])
        }
     }); //end form validate code
 });

This selects a random value but uses the same value for each success message instead of selecting a different one for each field.

Brooke.
  • 3,691
  • 13
  • 49
  • 80

4 Answers4

91

You can store the messages array and calculate the message to show as you go, like this:

var messages = ["Good!", "Great!", "Awesome!", "Super!", "Nice!"];
function getMessage() {
   return messages[Math.floor(Math.random() * messages.length)];
}

Give it a try here, then just call getMessage in your .text() call, like this:

label.addClass("valid").text(getMessage());
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • This almost works but returns the same message for each field element. – Brooke. Aug 05 '10 at 23:45
  • @BandonRandon - I was under the impression you had just one, just a moment :) – Nick Craver Aug 05 '10 at 23:47
  • @BandonRandon - Updated to be random per-element, I would suggest that you may want to go a step further and remove the used message as well, so it can't be repeated. – Nick Craver Aug 05 '10 at 23:49
  • Sorry, I should had made that clear there is one for each form element. – Brooke. Aug 05 '10 at 23:49
  • @BandonRandon - No worries, give it a try now :) – Nick Craver Aug 05 '10 at 23:50
  • 1
    Great that works! Thank you, A few more questions, If I did want to make it not repeat how would I do that? Also because it's initializing on keyup It's regenerating with each keypress or mouse click. Can I use stop() or something to stop that? – Brooke. Aug 05 '10 at 23:57
  • @BandonRandon - You would have to do a full re-validation, actually I'm not sure how you'd handle it in your case, aside from looping through the current labels, which is fairly expensive. It will re-generate every time by default, you could try `if(label.text() == '') label.text(getMessage())`, see if that stops your unwanted label-changing. – Nick Craver Aug 06 '10 at 00:03
  • I think because it's adding the class of "valid" something like this should work `function successMessage() { if(!$("label").hasclass("valid")){ return messages[Math.floor(Math.random() * messages.length)]; } }` but it dosen't – Brooke. Aug 06 '10 at 00:51
7

We can add Method to Array.

Array.prototype.getRandomVal = function(){
    return this[Math.floor(Math.random()*this.length)];
};

messages.getRandomVal();
Rakesh Kumar
  • 2,705
  • 1
  • 19
  • 33
5
function sucess() {
 message = ["Good!","Awesome!","Super!","Nice!","Great!"];
 return message[Math.floor(Math.random() * message.length)];
}

 $(document).ready(function(){
     var validator = $(".contactform").validate({ ...
              success: function(label) {
    label.addClass("valid").text(success());
 }
      }); //end form validate code
         });
Mike Sherov
  • 13,277
  • 8
  • 41
  • 62
1

A concise way of choosing a random element of the array is to use bitwise OR instead of Math.floor(). This works because bitwise operations will cause the fractional part of the number to be discarded, which achieves exactly the same result as Math.floor(). Operator precedence means that the bitwise operation happens after the multiplication. Doing bitwise OR with zero leaves the original number unaffected, except that now the fractional part is gone.

const arr = ["Good!", "Great!", "Awesome!", "Super!", "Nice!"]

const randomElement = arr[Math.random() * arr.length | 0]

console.log(randomElement)
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27