Knockout and jQuery - Tag Cloud of Fiddles

by johnpapa

HTML

<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.js"></script>
<script src="https://raw.github.com/DukeLeNoir/jQCloud/master/jqcloud/jqcloud-1.0.0.js"></script>
<link rel="stylesheet" href="https://raw.github.com/DukeLeNoir/jQCloud/master/jqcloud/jqcloud.css">
<!-- Your fiddle needs a title for the API to list it -->
<div>
User:<input data-bind="value: user"/> 
</div>
<div>
Limit:<input data-bind="value: limit"/> 
</div>
<button data-bind="click:getFiddles">Go</button>

<table class="table table-striped table-bordered table-condensed" style="display:none">
    <thead><th>Word</th><th>Count</th></thead>
    <tbody data-bind="foreach: tags">
        <tr>
            <td data-bind="text:text"></td>
            <td data-bind="text:weight"></td>
        </tr>
    </tbody>
</table>

<div id="wordcloud" style="width: 550px; height: 350px; position: relative;"></div>


<div style="display:none" data-bind="text:debugInfo"></div>

CSS

body {margin: 10px;}

JavaScript

var Word = function() {
    var self = this;
    self.text = ko.observable();
    self.weight = ko.observable();
    self.link = ko.observable();
};

// Create a function on the Array prototype
Array.prototype.inArray = function(searchFor, property) {
    var retVal = -1;
    var self = this;
    for(var index=0; index < self.length; index++){
        var item = self[index];
        if (item.hasOwnProperty(property)) {
            if (item[property].toLowerCase() === searchFor.toLowerCase()) {
                retVal = index;
                return retVal;
            }
        }
    };
    return retVal;
};

var vm = (function() {
    var
        self = this,
        user = ko.observable('johnpapa'),
        limit = ko.observable(250),
        fiddles = ko.observableArray(),
        sortFunction = (function(a, b) {
            var textA = a.text.toLowerCase(),
                textB = b.text.toLowerCase(),
                weightA = a.weight,
                weightB = b.weight;
            var val = textA < textB  ? -1 : textA > textB ? 1 : 0;
            if (val === 0) {
                val = weightA < weightB ? -1 : weightA > weightB ? 1 : 0;
            }
            return val;
        }),
        words = [], //ko.observableArray(),
        updateWords = function(text){
            var 
                rawWords = text.split(/\b/),
                underlyingArray = words,
                pattern=/^[a-zA-Z]/;
            
            for (var i = 0; i < rawWords.length; i++) {
                var w = rawWords[i].trim().toLowerCase();
                if(w.length > 2 && pattern.test(w)){
                    var j = underlyingArray.inArray(w, 'text');
                    if (j >= 0) {
                        //underlyingArray[j].weight((underlyingArray[j].weight() || 0) + 1);
                        underlyingArray[j].weight = (underlyingArray[j].weight || 0) + 1;

                    }
                    else {
                        //underlyingArray.push(new...