It's possible through Fisher-Yates Algorithm of shuffling. Here's the link to the visualisation. Here's the function. You just need to pass an array to it :
function shuffle(array) {
var copy = [],
n = array.length,
i;
// While there remain elements to shuffle…
while (n) {
// Pick a remaining element…
i = Math.floor(Math.random() * n--);
// And move it to the new array.
copy.push(array.splice(i, 1)[0]);
}
return copy;
}
There are two ways of doing this :
Method 1 - Shuffle the elements already in DOM
You could keep elements in DOM, take it out throught jQuery, shuffle it and put it back. Note that for styling purposes, you'll have to add data-role=none
to your inputs
so that this can be styled later. JS code :
$(document).on("pageinit", "#test", function () {
//get all the elemnets inside grid view and clone it
var $el = $(".ui-grid-b").children("div").clone().get();
//shuffle the elements
var $shuffledEl = shuffle($el);
//loop through the elements to set the class for that element depending on their index - this might be reduced to lesser lines if two tile grid is used
var i = 0;
for (; i < $shuffledEl.length; i++) {
var cl = "";
if ([0, 3].indexOf(i) !== -1) {
cl = "ui-block-a";
} else if ([1, 4].indexOf(i) !== -1) {
cl = "ui-block-b";
} else {
cl = "ui-block-c";
}
$($shuffledEl[i]).attr("class", cl);
}
//clear out the old stuff and add the shuffled elements
$(".ui-grid-b").html($($shuffledEl));
//refresh the radiobuttons
$(this).find("input").checkboxradio().checkboxradio("refresh");
});
Demo : http://jsfiddle.net/hungerpain/nJbCt/
Method 2 - Shuffle the elements before inserting to DOM
This way you wont be needed to have any HTML to start with.
$(document).on("pageinit", "#test", function () {
//6 elements - so 6 items in array
var numbers = shuffle([1, 2, 3, 4, 5, 6]);
var i = 0;
//create the skeletal element - <div><input><label></div>
var $div = $("<div/>").append($("<input/>", {
"type": "radio",
"name": "cell"
}), $("<label/>"));
//loop through shuffled numbers
for (; i < numbers.length; i++) {
//define class based on index - can be reduced if 2 tile grid is used
var cl = "";
if ([0, 3].indexOf(i) !== -1) {
cl = "ui-block-a";
} else if ([1, 4].indexOf(i) !== -1) {
cl = "ui-block-b";
} else {
cl = "ui-block-c";
}
//clone the div el
var $clone = $div.clone().attr("class", cl);
//add the attributes and values on the fly - dynamic
$clone.find("input").attr({
"id": "cell_" + numbers[i],
"value": numbers[i]
});
$clone.find("label").attr({
"for": "cell_" + numbers[i]
}).html(numbers[i]);
//add the clone to DOM
$clone.appendTo(".ui-grid-b");
}
//refresh the styles of the complete page
$(this).trigger("create");
});
Demo : http://jsfiddle.net/hungerpain/7QGVJ/
Caveats in using a three column grid
You'll have to add ui-block-*
in a hard-coded kinda way. I dunno if there's a better way to this but any way would be too hacky. Look at this code,
if ([0, 3].indexOf(i) !== -1) {
cl = "ui-block-a";
} else if ([1, 4].indexOf(i) !== -1) {
cl = "ui-block-b";
} else {
cl = "ui-block-c";
}
Checking for a particular index is..erm..doesnt quite settle with me. A better way would be to use a two column grid, where you can check for even and odd i
. This gives us a more generic way to handle this.
if (i % 2 === 0) {
cl = "ui-block-a";
} else
cl = "ui-block-c";
}
Hope this helps!