Double Exclamation Mark JavaScript Notation

I find this to be a terribly obscure way to do a type conversion. The double exclamation mark in JavaScript basically means convert to Boolean, invert, then invert again. I documented this on my blog for quick reference as I keep running into it.

So you’re converting a value to a boolean, then inverting it, then inverting it again. Take a look at the three examples below that mean the same thing starting with the double exclamation mark.

// Really Confusing:
site.enable = !!webId;

// Less Confusing:
site.enable = (webId != 0) ? true : false;

// Easiest to understand in my opinion:
site.enable = (webId != 0);


Limiting TextArea Characters In Internet Explorer

In my last project I ran into an annoying nuance of IE9 but turned out to be IE (Internet Explorer) in general.  IE does not like to acknowledge the maxLength property that you can set on a <textarea> tag.  In FireFox as well as in Chrome you could set this property to the desired length and the browser would acknowledge this and stop user input at the desired length.  Take a look at the following snippet.

<textarea id="limitChars" rows="5" cols="86" maxlength="1000">

In this snippet, the attribute to look at is maxlength=”1000″.  Make sure you have this set as it works well in FireFox and in Chrome.  Now, let’s talk about Internet Explorer.  From my project it looks like IE7, IE8, IE9, and IE10 don’t care about the maxlength attribute and will let the user keep typing long beyond what you desire.  So there are two pieces to this puzzle that I found fit my likings best.  The first is we bind the <textarea> to the keyup event like so.

$('# limitChars').keyup(function () {
     //Code
});

In binding the textarea to this keyup event it will be fired on every keystroke.  So inside of this event we now just have to check the length of characters in the texarea and either do nothing or we will cut it down.  So let’s add the code in the middle.

$('#limitChars').keyup(function () {
     //Get the value of the textarea.
     var valueOfInput = $("#limitChars").val();

     //Check and see if its over our desired limit.

     if (valueOfInput.length > 1000) {
          //We reset the characters they have typed and cut it off to 1000.

          $("#limitChars").html(valueOfInput.substr(0, 1000));
     }
});

It causes a bit of weird behavior when they get to the limit but up until that limit it works quite well.


KoGrid with KnockoutJS Simple Grid Set Up

Recently we took a look at implementing KoGrid which utilizes KnockoutJS.  This is a brief set up that I go going by pulling a data set from our controller.  First let’s look into the JavaScript and how all this happens.  Let’s look at the document initialization method first.

$(function () {
    var $scvm = new ConfigsViewModel();  //Create New Instance of our ViewModel
    $scvm.LoadConfigurations();  //Calls the load function in our ViewModel
});

This is all pretty straight forward.  So let’s take a bit deeper look into the ConfigsViewModel().  In here we will create our observableArray() and load our data.

var ConfigsViewModel = function () {
var self = this;

    //#region Observables
    self.ConfigurationsMin = ko.observableArray();
    //#endregion

    self.LoadConfigurations = function () {
        $.post("/Config/Search", function (data) {
            var viewModel = {
                ConfigurationsMin: ko.observableArray(JSON.parse(data))
            };

            //Activates knockoutjs so the browser knows what to do with data-bind in markup html.
            ko.applyBindings(viewModel); 
        });
    };
};

Here you can see the LoadConfigurations function that gets call when the dom loads.  Within this function it’s doing an Ajax post which returns a serialized result.


JavaScriptSerializer s = new JavaScriptSerializer();
string json = s.Serialize(results);

return json;

Since we are serializing the results we do a quick JSON.parse which will split the data out into a JSON object that the grid will recognize.  This is all relatively simple and gets a start to pull data back.  Now let’s look at the mark up of the grid.

Here is the whole mark up and we will dig into it.

<div id="table_words" class="someStyles" data-bind="koGrid: { 'data': ConfigurationsMin }">
</div>

There are a few key points for this intro into KoGrid.  First, you can see using the data-bind element we are signaling koGrid which has an element called data.  Here we assign data with the observableArray of ConfigurationsMin.  If you remember, we created and applied our data to this object. ConfigurationsMin: ko.observableArray(data).  This is the bare bones of KoGrid and knockout; but it gets a grid up and running with doing an Ajax call to get some data to populate the grid with.


Why does YUI Minify fail on char and browsers do not in JavaScript

This weeks 30 second question. Why does YUI Minify fail on char and browsers do not in JavaScript?

In JavaScript the following line of code works on all browsers that I have seen:

var char = 15;

However, the YUI minifier chokes on this line of code. Why is this? And should that line not work on browsers? i.e. why are browsers allowing that line to work?

Let’s start out with Reserved words in Javascript.  These words are words that you cannot use as variable or function names as they hold special meanings and instruction to the language.  If you haven’t guess by now, ‘char’ is a reserved keyword in JavaScript.  So in the above example we are trying to use a keyword as a variable name which causes the YUI Minify to throw a fit.  To give you an example, open up this link and plug in the following and click compress.

http://www.refresh-sf.com/yui/

var char = 15

You will be prompted with the error below.

[ERROR] 1:10:missing variable name

[ERROR] 1:0:Compilation produced 1 syntax errors.

org.mozilla.javascript.EvaluatorException: Compilation produced 1 syntax errors.
	at com.yahoo.platform.yui.compressor.YUICompressor$1.runtimeError(YUICompressor.java:154)
	at org.mozilla.javascript.Parser.parse(Parser.java:392)
	at org.mozilla.javascript.Parser.parse(Parser.java:337)
	at com.yahoo.platform.yui.compressor.JavaScriptCompressor.parse(JavaScriptCompressor.java:312)
	at com.yahoo.platform.yui.compressor.JavaScriptCompressor.<init>(JavaScriptCompressor.java:533)
	at com.yahoo.platform.yui.compressor.YUICompressor.main(YUICompressor.java:131)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at com.yahoo.platform.yui.compressor.Bootstrap.main(Bootstrap.java:21)

That answers the first part of the question, now onto the second part of the question.  Why do browsers still allow this code snippet to work?  Well, the keyword char is not actually used by the JavaScript language.  So yes it’s labeled as a reserved keyword, but it is never been used as one. Browsers run their own compilers for JavaScript and tend to have more of a lenient stance on this subject.  They want to allow as much of the JavaScript execute as they possibly can.  So since there is not a repercussion of using this keyword, the browsers don’t take it into account as an issue.  The YUI Minify is a more standards compliant engine that will follow standards, hence why it blows up when you try to use a keyword it recognizes as a word that’s off limits.


JavaScript Closures

A JavaScript Closure is formed by returning a function object that was created within an execution context of a function call from that function call and assigning a reference to that inner function to a property of another object. Or by directly assigning a reference to such a function object to, for example, a global variable, a property of a globally accessible object or an object passed by reference as an argument to the outer function call.

In the example below you will notice that the globalVar has access to the exampleConcatReturn. However, it does not have access to the finishStringArg as that is seen as basically a private variable that cannot be accessed outside that function.

function exampleClosure(stringArg1, stringArg2) {
    var finishStringArg = "!";
    function exampleConcatReturn(innerArg) {
        return (stringArg1 + stringArg2 + innerArg + finishStringArg);
    }

    return exampleConcatReturn;
}

var globalVar = exampleClosure("Adam ", "Drummond "); /*stringArg1 = "Adam" and stringArg2 = Drummond*/

//Call to the function
alert(globalVar("Was Here")); /* innerArg = "Is Coding" */

/* would return Adam Drummond Was Here!*/

Another example is as follows.  This was based from Mozilla’s developers area.  I think it really does a great job in showing how the privateCounter is only used from within.  Also, you will take notice that you can create numerous functions off of the main makeCounter function and they will stay separate of each other.

var makeCounter = function () {
    var privateCounter = 0;
    function changeBy(val) {
        privateCounter += val;
    }
    return {
        increment: function () {
            changeBy(1);
        },
        decrement: function () {
            changeBy(-1);
        },
        value: function () {
            return privateCounter;
        }
    };
};

var Counter1 = makeCounter();
var Counter2 = makeCounter();

alert(Counter1.value()); /* Alerts 0 */

Counter1.increment();
Counter1.increment();

alert(Counter1.value()); /* Alerts 2 */

Counter1.decrement();

alert(Counter1.value()); /* Alerts 1 */

alert(Counter2.value()); /* Alerts 0: Notice that it doesn’t get affected by Counter1 */

As seen in this example, you have Counter1 and Counter2.  Take a look at the incrementing and decrementing of Counter1 and at the end, Counter2 is still in the same state as when it was created.


StackOverflow Profile