JavaScript DSL Because I’m Tired of Writing If.. If…If…

A little while ago a co-worker had expressed a dream of his to create some kind of language agnostic standard for validation. Without actually listening to what he meant by that, I set forth on doing this for JavaScript. I wanted to Lisp it up, as I am that kind of zealot. The idea was simple, provide a list like structure for describing the validation needs, but not make it a complete cluster *($#. I got the first part, not sure about the second. Essentially I wanted something like this:

 var rules =
    ('Username',
      ('is not empty' 'Username is required.')
      ('is not longer than' 7 'Username is too long.'))

Where ‘Username’ is the name of the property needing the validation, and the ‘7’ is the maximum length, and the last part is the error. But, seeing as this was JavaScript, I had to do something a little more rigid.

Now for what the rules would look like:

 var rules =
    ['Username',
      ['is not empty', 'Username is required.'],
      ['is not longer than', 7, 'Username is too long.']],
    ['Name',
      ['is not empty', 'Name is required.']],
    ['Password',
      ['length is between', 4, 6, 'Password is not acceptable.']]];

As you can see, the rules turn out to be very readable. On top of that, since it is only a list, converting a json based array to the rules should be pretty easy. The advantage of that would be the ability for a server response to contain the rules at which time the interpreter would match them to the methods. Thus providing a way to help with consistency of error messages, and constant values like in the password rule above. Something that is a pain in the #@@ some… all of the time.

The structure is fairly simple. [Property name [[validation need][extra parameters][error]…..[validation need][extra parameters][error]]] Essentially every property that is going to be validated can have n number of validation methods “attached” to it. Now one catch is that the object being validated has to have a matching “Property name”. Kind of falls into the “opinionated programming” side of things.

For this example, there will be three fairly generic validation methods. The methods either return null, or an error message. Over simplistic much?

 function isNotEmpty(toCheck, propertyName, error, rest) {
    return toCheck[propertyName] === '' ? error : null;
  };

  function isNotLongerThan(toCheck, propertyName, error, rest) {
    return toCheck[propertyName].length > rest[0] ? error : null;
  };

  function isBetween(toCheck, propertyName, error, rest) {
    var length = toCheck[propertyName].length;
    return (length < rest[0] || length > rest[1]) ? error : null;
  };

And here is an example of how to attach the english to methods:

 var methods = [
    ['is not empty', isNotEmpty],
    ['is not longer than', isNotLongerThan],
    ['length is between', isBetween]];

I created a pseudo method look up table to match a much more “english” name for the validation method needed. Not exactly brilliant, and is sort of cheating. What would be nice is to actually read the english, break it down, and create the functions on the fly. BUT this works for now. That whole english breakdown I’ll attack at some point. After all, this was a sort of thought experiment.

The interpreter takes in the rules, matches the method, and send the extra values if needed. For example,

   ['length is between', 4, 6, 'Password is not acceptable.']

Is matched to:

  isBetween(toCheck, propertyName, error, rest)

Where “rest” is the 4 and 6. Rest is a carryover from Commmon Lisp’s &rest. It’s a collection of things that will be broken down by the validation method. Just think of them as optional values.

 var length = toCheck[propertyName].length;
  return (length < rest[0] || length > rest[1]) ? error : null;

There are two parts to the interpreter, but the first part is merely rolling through the rules, and making a call to this:

  src.site.validation.validationInterpreter.createAValidationCall = function(propertyName, methods, innerRule, find, car, cdr, peek, sink) {

 //Find the method that matches the english phrase
    var methodPair = find(methods, function(method) {
        return car(method) === car(innerRule);
    });

 //In Closure the find method returns the whole matched "row", so I need the method which is the second column.
    var methodToUse = peek(methodPair);

    return function(obj) {
        var error = peek(innerRule);                           //error is the last index
        var values = sink(cdr(innerRule));                     //get everything but the error  
        return methodToUse(obj, propertyName, error, values);  //construct the validation call
    };
};

car, cdr, sink, peek? The *(&^ are those? First two are carry overs from Common Lisp too. Car is just taking the first item of a list, if there is one.

  (car '(1 2 3)) ;;  1

Cdr returns a new list that is everything but the first item.

  (cdr '(1 2 3)) ;; '(2 3)

Haskell refers to them as Head and Tail. Clojure has First, and Rest. ect. ect. ect.

sink is used to get all but the last item in the list. Everything but the kitchen sink. Eh? Eh? Sigh. (The code for them can be seen here.).

peek is actually just a parameter cover for the goog.array.peek method. It gets the last element of an array. Remember, the structure is very specific. [validation need][extra parameters][error] Because of this, it’s easy to break down each rule into its respective parts using simple array manipulation.

Now at this point I only have created the method list creator (“Interpreter”), and haven’t created anything for running the validation. However, the code below is a rough estimate of how that would work.

 var result = interpret(rules, methods);

 var toValidate = {'Username': '12345678', 'Name': '', 'Password': '123'};
  for(var i = 0; i < result.length; i++) { something.innerText += '\n' + result[i](toValidate); };

The glaring issue with that is that I’m not removing empty strings. Other than that, it works. The working example is in the example folder for this repository. The removal would be nothing more than using a map -> filter type method chain.

 var validationMesssages = goog.array.map(result, function(item) { return item(toValidate); };
  return goog.array.filter(validationMesssages, function(message) { return !goog.string.isEmptySafe(message); });

Or something like that… probably not exactly like that unless you’re in with the Closure, or are stuck with Jsomethingry.

jQuery Validate Date/Check If Is Date

Far as I can tell, and that’s pretty far even though I do wonder if you can actually measure telling in distance, there isn’t a method directly used for validating a date in jquery. I find this rather odd. Not odd like how people keep watching Uwe Bol movies, more like odd that no one has tried to make a time machine to prevent them from ever appearing.

Anyways, bad movies… horrible movies… worst movies of all time aside, there is a date checking method, just not directly in jquery. It’s actually in the jquery.ui.datepicker.js file which is part of the UI files. Basically I grabbed that file and used the parseDate method on it coupled with a try catch. After all, a failure in the parseDate method throws an exception, and we don’t like those. No we don’t. (Which begs the question as why it throws an exception instead of just returning a null date.)

function isValidDate(controlName, format){
    var isValid = true;

    try{
        jQuery.datepicker.parseDate(format, jQuery('#' + controlName).val(), null);
    }
    catch(error){
        isValid = false;
    }

    return isValid;
}

Very simple, and it works. You could ask why I didn’t just roll my own date method, and then I would ask you how ambitious do you think I am? Then you would punch me because I answered your question with a question like a complete tool bag. Then I would cry. And THEN I would answer your original question. Fact is, I trust that the method created for the DatePicker is in fact well tested, otherwise the whole jquery thing just isn’t worth trusting seeing as it’s a part of their core library. And that I just refuse to believe.

jQuery: Find a Form Action Using Jquery

This is pretty useful for people trying to pass in a generated action to a javascript file.  Eh?

SKIP IF YOU DON’T CARE ABOUT A REASON FOR USING THIS:

Say you are using the jQuery post method to send things back to the server but all the code for that is in a seperate javascript file.  Well you can’t really do this:

jQuery.ajax({
      type:'POST',
      url: <%= someMethodForCreatingAUrl('controller', 'action') %>,
      dataType:'json',
      data:{
        email: user.userName,
        password: user.password
      },
      success: function(result){
        onSuccess(result);
      },
      error:function (xhr, ajaxOptions, thrownError){
        alert(xhr.status);
      }
    });

if that is in the javascript file.

What you can do is this on the html file:

  <form id="formCreateUser" name="formCreateUser" method="post" action="${someMethodForCreatingAUrl('controller', 'action')}">

And in the javascript file:

ANSWER:

  var formAction = jQuery(ELEMENT_LOGIN_FORM).attr('action');

And there you go. You have the action.

jQuery Modal Dialog : Hide That Stupid X Button / Windows Close Button

This is quick one, so hold on to your… whatever.

Want to get rid of that X at the top right of the modal “Control”? Well here it is: (The bold part, moron)

     jQuery('#WaitingDiv').dialog({
          autoOpen: false,
          bgiframe: false,
          height: 150,
          width: 200,
          modal: true,
          open: function(event, ui) { jQuery('.ui-dialog-titlebar-close').hide(); }
        });

And that’s really it. Just thought I’d pass that on to you, the consumer.

On a side note, the big movie thing is the canceling of Spiderman 4 or at least going in a new direction. As much as I don’t care, it might lead to my dream come true:

A spiderman movie based on the SNES classic: Spider-Man & Venom: Maximum Carnage. Uwe Boll, are you out there?

jQuery – Check All Checkboxes Toggle Method Thingy

So here’s a quick on for all you boys and girls… and anything else I might have missed.
Say you want to check all check boxes in a grid or whatever, but you want it to toggle. So if if it’s time to check all, all get checked and then the next time the button is clicked it will uncheck. Now you could do this in three methods, maybe two but that’s why you’re a mouth breather.

Special people like me do it in one.

    function toggleCheckboxes(buttonId, checkBoxNamePrefix, checked)
    {
      //Get all checkboxes with the prefix name and check/uncheck
      jQuery('[id*=' + checkBoxNamePrefix + ']').attr('checked', checked);

      //remove any click handlers from the button
      //  Why?  Because jQuery(buttonId).click() will just add another handler
      jQuery(buttonId).unbind('click'); 

      //Add the new click handler
      jQuery(buttonId).click(
        function() {
          toggleCheckboxes(buttonId, checkBoxNamePrefix, !checked);
        }
      );
    }

And POW! What? You want to know how to use it? Fine, but only because I’m nice.

   jQuery('#buttonName').click(
     function() {
       toggleCheckboxes('#buttonName', 'someCheckBoxName', true);
     }
   );

And in case you were still wondering why I used .unbind and didn’t understand the comment, it’s because using just .click will add another handler to the button. So next click you will get both check and uncheck all. Kind of hurts the effectiveness.

And there you have it. Once again I have filled your life with meaning. Couldn’t be easier. Or maybe it could but that’s not my problem now is it? Go back to doing something useful.

jQuery Grab Bag – Whole bunch of jQuery Functionality

You could look at this post as a self serving block that I will use to save stuff I don’t want to remember later.

Or you could see it as a knowledge transfer that you the reader can learn from because I am a generous and giving tool.

Whatever, I really don’t care. I won’t sleep any differently. I just don’t feel like making 1000 posts of jquery stupidity.

I’ll add more as I come across them.

Checkbox

How To Check a CheckBox

  jQuery('#CheckBoxId').attr('checked', false);

How To Know if a Checkbox is Checked

  jQuery('#CheckBoxId').is(':checked')

How To Find a Bunch of Like Named Checkboxes that are Checked

  jQuery('[id*=someCheckBox_]:checked');

Drop Down Lists

How to Add an Item/Option to a Drop Down List

 jQuery('#DropDownListId').append(jQuery('<option>').val(1).html("SomeText"));

Odd Note: Apparently jquery is smart enough to set the attributes on the option AND close the option with </option>

How to Remove an Item/Option from a Drop Down List

  jQuery('#DropDownListId option[value=\'3\']').remove();

How to Sort a Drop Down List by Option Text

  var sortedList = jQuery('#someDropDownList option').sort(
    function (first, second) {
      return first.text == second.text ? 0 : first.text < second.text ? -1 : 1;
    }
  );

  jQuery('#someDropDownList').html(sortedList);

Elements

How to Filter Out an Element in a List

  someElementList.filter('[id=someId]');

Example:

  //Uncheck all id like someId_ and check only where id = someId_1
  var someElementList = someElement.children('[id*=someId_]');
  someElementList.attr('checked', false);
  someElementList.filter('[id=someId_1]').attr('checked', true);

How To Find an Element Based on a Like Name/Using Wildcards

  jQuery('#SomeTable').children('tr[id*=SomeRowId]');

How To Know if a Something is Hidden

  jQuery('#CheckBoxId').is(':hidden')

Possible Use:

 function showOrHide(element) {
    if(jQuery(element).is(':hidden')) {
      jQuery(element).show();
    }
    else {
      jQuery(element).hide();
    }
  }

How to Disable an Input/Select

  jQuery('#DropDownListId').attr('disabled', 'disabled');

How to Enable an Input/Select

  jQuery('#DropDownListId').removeAttr('disabled');

How to Know if an Element Exists

  jQuery('#ElementId').length > 0

Possible use:

  function elementExists(elementId) {
    return jQuery(elementId).length > 0;
  }

String

How To Remove the First Character from a String

  someString.substring(1, someString.length)

Tables

How to Add a Row to a Table

  jQuery('#TableId > tbody:last').append('<tr>...</tr>')

How to Remove a Table Row

  jQuery('#TableId > tbody:last').children(someSortOfRowId).remove();

Methods

How to Post With a Link

  function postToUrl(path, params)
  {
    var method = "post"; 

    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);
    for(var key in params)
    {
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", params[key]);
        form.appendChild(hiddenField);
    }
    document.body.appendChild(form);    

    form.submit();
  }

Use:

<a href="javascript:postToUrl('/SomeController/SomeAction/', { 'id', '1' })">link</a>

jQuery: Find All Checked Checkboxes

So this is sort of a repeat of another post, but I figured it has some use on its own.

Say you have this:

  <div>
    <input type="checkbox" name="JqueryIdList" value="1"  />
    <input type="checkbox" name="JqueryIdList" value="2" />
    <input type="checkbox" name="JqueryIdList" value="3" />
    <input type="checkbox" name="JqueryIdList" value="4" />
  </div>
  <div onclick="getIds('JqueryIdList');">
    CLICK
  </div>

And you need the getIds method to find all the checked checkboxes from that markup. Well it’s actually fairly simple, or at least it wil be once I enlighten you. I should get paid for this…

  function getIds(checkList)
  {
    var idList = new Array();
    var loopCounter = 0;
    //find all the checked checkboxes
    jQuery("input[name=" + checkList + "]:checked").each
    (
      function()
      {
        //fill the array with the values
        idList[loopCounter] = jQuery(this).val();
        loopCounter += 1;
      }
    );
    ...
  }

The important part is this:

 jQuery("input[name=" + checkList + "]:checked").

As you can see, it is very simple. Give it the name of the checkboxes, add on the “:checked” and boom you have a list of checked checkboxes. Could it be more simple? I think not.

jQuery: Holy Smokes I Like This Link

Good old Stackoverflow. Wasn’t sure how to post this without looking like I’m trying to get search engine hits. However, wanted to pass this one on anyhow.

How to center a div using jQuery.

Have used it. Works brilliantly. Although the:

  this.css("position","absolute");

May be overkill since any “pop up” div I create already has that in the style where personally I think it should be.

How does it work? Well break down the “top” part:

  this.css("top", ( jQuery(window).height() - this.height() ) / 2+jQuery(window).scrollTop() + "px");

To

   jQuery(window).height() - this.height() ) / 2

But why not just divide the height by 2? Well say the height of the window is 800 and your item is 600 high. If you just placed the item at 800 / 2, the bottom of the item would end up 1000. (800/2 = 400… 600 tall item + 400 starting point = 1000). So subtracting the item’s height from the window height and THEN dividing by two ensures that that item, provided it is no taller than the window, will end up within the 800 tall window.

  + jQuery(window).scrollTop()

Now what if the user has scrolled the widow down? Well adjust for that. using the scrollTop(), the item can be started at the correct point adjusted with the scroll. Nice huh?

Javascript: Scope and Learning Something New Everyday.

Course for me it doesn’t take much to learn something new, but let’s not get into that.

So pop quiz, and one that doesn’t involve a hostage and shooting.

jQuery(document).ready
(
  function()
  {
    for(var loopCounter = 0; loopCounter < 3; loopCounter++)
    {
      var tempThing = loopCounter;
      alert('in' + tempThing); 

      jQuery(".someButton").click
      (
        function()
        {
          alert('out' + tempThing);
        }
      );
    }
  }
);
....
  <button class="someButton">click!</button>

What happens when you click that button? Well for one it will alert three times but what will it print out?

The first alert (in the loop) does what you would expect. It gives 0, 1, 2. But what about the button click? Well that’s a little different. It gives 2, 2, 2… Wait what? The f— is that? That makes no real sense.

Given that this was C#, it would output 0, 1, 2 because we would know that every loop the tempThing field is a new field. Sure it has the same name in code, but every iteration would create a new space in memory for a new tempThing. And then with closures, a reference would be made to that tempThing so that when the method actually runs, the values are what they should be. Javascript does something a little different. Go figure, right? Can’t do anything like anyone else… anyone else being C#.

Now what does happen is it does give you the correct value of tempThing. What you didn’t know (Assuming you didn’t know because if you are reading this you either are really bored or don’t know… or both) is that tempThing is global to that method. Turns out variables are global to the current scope no matter if in a loop or not. tempThing, no matter where in that function is created/instantiated/ect is the same tempThing through out the method. So what’s happening is that the first time in the loop it’s being created and every iteration after it’s just being updated with the current loopCounter value.

How do you solve this? Well you have to make a method to create a method to set the value. AWESOME!!111

jQuery(document).ready
(
  function()
  {
    for(var loopCounter = 0; loopCounter < 3; loopCounter++)
    {
      alert('in' + tempThing); 

      jQuery(".someButton").click
      (
        createReturnMethod(loopCounter)
      );
    }
  }

);

//This is used to create a new method scope so that
//tempThing is unique to each call.
function createReturnMethod(loopCounter)
{
  var tempThing = loopCounter;

  return function(event)
  {
    alert('out' + tempThing);
  };
}

As you can see, I created a method to create a method to be run on click. Because tempThing is now in the second method’s scope, it will be different for every time this method is called. Magic!

Here’s a thought, if only you can prevent forest fires then you really should get on that. People have lost a lot of money because of your slacking.

jQuery Whack-A-Mole… Timer, Hide, Slide, and Fun

So I’ll just straight up file this under “I really shouldn’t have” and not bother asking for forgiveness. For some reason I had it in my mind I wanted to see if I could take the stuff I learned from this guy and this guy and see if I could make a simple Whack A Mole game with just jquery and the three include files. (jquery, jquery UI, and jquery Timer) Not thinking of the massive consequences such a thing might bring, I pushed on in the name of science.

So with no further build up or stupidity (I used that all up in building this game) I give you jQuery WHACK A MOLE which oddly enough has somehow clawed it’s way into my hosting here. So if you’re foolish enough to actually want to know how it works, there are plenty of comments in the script files. Just don’t blame me for any loss of intelligence.

I might actually take this to the next horrifying level and make it an mvc application. Not sure I… no… THE WORLD can take it.