How to Get rowID in rowattr block of jqgrid? - javascript

I am having jqgrid this way,
<div id="dialogLoading" style="position:absolute;z-index:1005">
<img src="http://blog.teamtreehouse.com/wp-content/uploads/2015/05/InternetSlowdown_Day.gif" />
</div>
<table id="list"></table>
$(function () {
var blueArray = [];
for (var i=1;i<=4000;i++) {
blueArray.push(i);
}
var greenArray = [];
for (var i=4000;i<=6000;i++) {
greenArray.push(i);
}
var redArray = [];
for (var i=6000;i<=8000;i++) {
redArray.push(i);
}
var yellowArray = [];
for (var i=8000;i<=10000;i++) {
yellowArray.push(i);
}
"use strict";
var getGridData = function(n) {
var data = [], i;
for (i = 0; i < n; i++) {
data.push({
id: (i + 1)*10,
aa: "aa" + i, // colunn 1
bb: "bb" + (i%3), // colunn 2
cc: "cc" + (i%5), // colunn 3
dd: "dd" + (i%7), // colunn 4
ee: "ee" + (i%11), // colunn 5
ff: "ff" + (i%13), // colunn 6
gg: "gg" + (i%17), // colunn 7
hh: "hh" + (i%19), // colunn 8
ii: "ii" + (i%23), // colunn 9
jj: "jj" + (i%29), // colunn 10
kk: "kk" + (i%31), // colunn 11
ll: "ll" + (i%37), // colunn 12
mm: "mm" + (i%41) // colunn 13
});
}
return data;
},
$grid = $("#list"),
gridData,
startTime,
measureTime = false,
timeInterval;
gridData = getGridData(10000);
startTime = new Date();
$grid.jqGrid({
data: gridData,
colModel: [
{ name: "aa", label: "c01" },
{ name: "bb", label: "c02" },
{ name: "cc", label: "c03" },
{ name: "dd", label: "c04" },
{ name: "ee", label: "c05" },
{ name: "ff", label: "c06" },
{ name: "gg", label: "c07" },
{ name: "hh", label: "c08" },
{ name: "ii", label: "c09" },
{ name: "jj", label: "c10" },
{ name: "kk", label: "c11" },
{ name: "ll", label: "c12" },
{ name: "mm", label: "c13" }
],
cmTemplate: { width: 100, autoResizable: true },
iconSet: "fontAwesome",
rowNum: 10000,
rownumWidth: 40,
//rowList: [20, 100, 1000, 10000, "100000:All"],
viewrecords: true,
rownumbers: true,
//toppager: true,
//pager: true,
shrinkToFit: false,
rowattr: function (rd) {
var rowIds = $("#list").jqGrid('getDataIDs');
console.log(rowIds);
if(blueArray.indexOf(rowIds) > -1)
return {"class": "blue"}
else if(greenArray.indexOf(rowIds) > -1)
return {"class": "green"}
else if(redArray.indexOf(rowIds) > -1)
return {"class": "yellow"}
else
return {"class": "one"}
},
loadComplete: function () {
closeDialogLoading();
if (measureTime) {
setTimeout(function () {
alert("Total loading time: " + timeInterval + "ms");
}, 50);
measureTime = false;
}
},
autoencode: true,
caption: "Shows the performance of resizing. Make double-click on the column resizer"
}).jqGrid("gridResize");
timeInterval = new Date() - startTime;
setTimeout(function () {
alert("Total time: " + timeInterval + "ms");
}, 50);
function openDialogLoading(){
$("#dialogLoading").css("display", "");
}
function closeDialogLoading(){
$("#dialogLoading").hide();
}
});
css:
.one { background:red; }
.blue { background:blue; }
.green { background:green; }
.yellow { background:yellow; }
I am trying to chaNge the row color of the jqgrid comparing each rowid with an array of values.
Here is the logic for that,
rowattr: function (rd) {
var rowIds = $("#list").jqGrid('getDataIDs');
console.log(rowIds);
if(blueArray.indexOf(rowIds) > -1)
return {"class": "blue"}
else if(greenArray.indexOf(rowIds) > -1)
return {"class": "green"}
else if(redArray.indexOf(rowIds) > -1)
return {"class": "yellow"}
else
return {"class": "one"}
the problem here is, rowIds are getting as empty []. so always my condition i going to else and red color is shown on each row's.
I need to check if rowid is exists in blueArray,greenArray e.t.c if its is true paint that row with the corresponding color.
In my example my bluearray has values from 1 to 4000. So all these records from 1 to 4000 have to be painted in blue.
My logic inside rowattr: block is not working as i am getting rowid as empty[].
How to get rowid inside rowattr: function (rd) {} block of jqrid?
The above logic working is fine in loadcomplete and gridcomplete events but it is blocking entire ui and taking hell lot of time to load grid.
Can anyone help me in this issue?
Thanks

You need just use rd.id inside of rowattr:
rowattr: function (rd) {
if (blueArray.indexOf(rd.id) > -1) {
return {"class": "blue"};
} else if (greenArray.indexOf(rd.id) > -1) {
return {"class": "green"};
} else if (redArray.indexOf(rd.id) > -1) {
return {"class": "red"};
} else {
return {"class": "one"};
}
}
the demo uses the code, but it's really slowly because you create 13x10000 cells in the grid. I recommend to open the demo only in Chrome where it takes still about 15 sec.
I strictly recommend to use local paging. Look at almost the same demo where the page size is 25 instead of absolute unneeded 10000. It works really quickly. One can jump on the page 200 or 300 to see another colors.

Related

JavaScript - How to make matching game cards stay flipped over after click

I found this matching game on codepen.io that I am using in corporation with a trivia spinner - thanks #Malky.kid - The idea is once they get to the matching game they have 10 clicks to match as many as they can but the cards MUST stay flipped over.
This is for a project and the odds of winning has to do with chance not skill.
(function(){
var Memory = {
init: function(cards){
this.$game = $(".game");
this.$modal = $(".modal");
this.$overlay = $(".modal-overlay");
this.$restartButton = $("button.restart");
this.cardsArray = $.merge(cards, cards);
this.shuffleCards(this.cardsArray);
this.setup();
},
shuffleCards: function(cardsArray){
this.$cards = $(this.shuffle(this.cardsArray));
},
setup: function(){
this.html = this.buildHTML();
this.$game.html(this.html);
this.$memoryCards = $(".card");
this.binding();
this.paused = false;
this.guess = null;
},
binding: function(){
this.$memoryCards.on("click", this.cardClicked);
this.$restartButton.on("click", $.proxy(this.reset, this));
},
// kinda messy but hey
cardClicked: function(){
var _ = Memory;
var $card = $(this);
if(!_.paused && !$card.find(".inside").hasClass("matched") && !$card.find(".inside").hasClass("picked")){
$card.find(".inside").addClass("picked");
if(!_.guess){
_.guess = $(this).attr("data-id");
} else if(_.guess == $(this).attr("data-id") && !$(this).hasClass("picked")){
$(".picked").addClass("matched");
_.guess = null;
} else {
_.guess = null;
_.paused = true;
setTimeout(function(){
$(".picked").removeClass("picked");
Memory.paused = false;
}, 600);
}
if($(".matched").length == $(".card").length){
_.win();
}
}
},
win: function(){
this.paused = true;
setTimeout(function(){
Memory.showModal();
Memory.$game.fadeOut();
}, 1000);
},
showModal: function(){
this.$overlay.show();
this.$modal.fadeIn("slow");
},
hideModal: function(){
this.$overlay.hide();
this.$modal.hide();
},
reset: function(){
this.hideModal();
this.shuffleCards(this.cardsArray);
this.setup();
this.$game.show("slow");
},
// Fisher--Yates Algorithm -- https://bost.ocks.org/mike/shuffle/
shuffle: function(array){
var counter = array.length, temp, index;
// While there are elements in the array
while (counter > 0) {
// Pick a random index
index = Math.floor(Math.random() * counter);
// Decrease counter by 1
counter--;
// And swap the last element with it
temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
return array;
},
buildHTML: function(){
var frag = '';
this.$cards.each(function(k, v){
frag += '<div class="card" data-id="'+ v.id +'"><div class="inside">\
<div class="front"><img src="'+ v.img +'"\
alt="'+ v.name +'" /></div>\
<div class="back"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/codepen-logo.png"\
alt="Codepen" /></div></div>\
</div>';
});
return frag;
}
};
var cards = [
{
name: "php",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/php-logo_1.png",
id: 1,
},
{
name: "css3",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/css3-logo.png",
id: 2
},
{
name: "html5",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/html5-logo.png",
id: 3
},
{
name: "jquery",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/jquery-logo.png",
id: 4
},
{
name: "javascript",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/js-logo.png",
id: 5
},
{
name: "node",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/nodejs-logo.png",
id: 6
},
{
name: "photoshop",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/photoshop-logo.png",
id: 7
},
{
name: "python",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/python-logo.png",
id: 8
},
{
name: "rails",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/rails-logo.png",
id: 9
},
{
name: "sass",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/sass-logo.png",
id: 10
},
{
name: "sublime",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/sublime-logo.png",
id: 11
},
{
name: "wordpress",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/wordpress-logo.png",
id: 12
},
];
Memory.init(cards);
})();
see game here
The only difference to this is that the cards stay flipped over - if they match cards they should still show that they are matched - it highlights green for a second. The cards flip back over after you select two cards ONLY if they do not match. If they do match they stay facing up but I need it always facing up. Thanks

How classify numeric values inputs in categories?

I want to create an optimized way to classify a value in certain labels.
Example
Input: 12.2, 61, 77.7
Output: "bad", "poor", "good"
I create a simple if, but maybe exist a better way
let output = null;
if (rating <= 60){ output = 'bad'}
if (rating > 60){ output = 'poor'}
if (rating > 70){ output = 'good'}
if (rating > 90){ output = 'excellent'}
You could use Array#some and iterate through an array of objects for the rating. The advantage is a good maintainable object.
ratings = [
{ value: 60, label: 'bad' },
{ value: 70, label: 'poor' },
{ value: 90, label: 'good' },
{ value: Infinity, label: 'excellent' }
]
function rating(v) {
var ratings = [{ value: 60, label: 'bad' }, { value: 70, label: 'poor' }, { value: 90, label: 'good' }, { value: Infinity, label: 'excellent' }],
label;
ratings.some(function (a) {
if (v <= a.value) {
label = a.label;
return true;
}
});
return label;
}
console.log([12.2, 61, 77.7].map(rating));
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6 with Array#find
var ratings = [{ value: 60, label: 'bad' }, { value: 70, label: 'poor' }, { value: 90, label: 'good' }, { value: Infinity, label: 'excellent' }],
rating = v => ratings.find(a => v <= a.value).label;
console.log([12.2, 61, 77.7].map(rating));
.as-console-wrapper { max-height: 100% !important; top: 0; }
One better way is to creatively use switch:
var output = null;
var rating = parseInt(prompt("Rating?"));
switch (true) {
case (rating <= 60):
output = 'bad';
break;
case (rating > 90):
output = 'excellent';
break;
case (rating > 70):
output = 'good';
break;
case (rating > 60):
output = 'poor';
break;
}
console.log(output);
Here, the correct organisation of the lines are very important.
One fast way of doing this if you are fine your memory.
var limits = [60,70,90,100],
rates = ["bad","poor","good","excellent"],
grades = limits.reduce((g,c,i,a) => i ? g.concat(Array(c-a[i-1]).fill(rates[i]))
: g.concat(Array(c).fill(rates[0])),[]),
notes = [12.2, 61, 77.7, 89.5];
notes.forEach(n => console.log(grades[Math.round(n)]));

Emptying the following cell of row having the same data using jquery

I have this simple fiddle:
http://jsfiddle.net/anilca/kbfssbd4/
var dataArr = [
{ DayNum: 0, Day: "Sunday", Group: "A" },
{ DayNum: 1, Day: "Sunday", Group: "B" },
{ DayNum: 2, Day: "Sunday", Group: "C" },
{ DayNum: 3, Day: "Monday", Group: "B" },
{ DayNum: 4, Day: "Monday", Group: "A" },
{ DayNum: 5, Day: "Tuesday", Group: "C" },
{ DayNum: 6, Day: "Tuesday", Group: "B" }
];
var grid = $("#grid").kendoGrid({
dataSource: {
data: dataArr,
sort: [
{ field: "DayNum", dir: "asc" },
{ field: "Group", dir: "asc" }
],
schema: {
model: {
fields: {
DayNum: { type: "number" },
Day: { type: "string" },
Group: { type: "string" }
}
}
}
},
selectable: true,
columns: [
{
field: "Day",
title: "Day"
},
{
field: "Group",
title: "Group"
}
]
}).data("kendoGrid");
I want to show empty cells for Day column for the row after the first appearance of the appropriate day. I mean my aim is to have the following screenshot without manipulating the data:
I thinks it's possible to do that using jquery after building the kendo grid. But I couldn't find out how to do it.
Thanks in advance,
I would do it using schema.parse method. This method manipulates the data but doesn't changes it, which is good. And no jQuery needed:
parse: function(data) {
var lastDay = "";
for (var i = 0; i < data.length; i++) {
if (lastDay == "" || data[i].Day != lastDay) {
lastDay = data[i].Day;
}
else {
data[i].Day = "";
}
}
return data;
}
Updated Fiddle.
UPDATE:
Yeah, I was wrong when I said that the parse doesn't changes the data. IN fact it changes. What you can do is to create dummy property and manipulate it:
parse: function(data) {
var lastDay = "";
for (var i = 0; i < data.length; i++) {
if (lastDay == "" || data[i].Day != lastDay) {
lastDay = data[i].Day;
data[i].DayText = data[i].Day;
}
else {
data[i].DayText = "";
}
}
return data;
}
See that I'm using(and creating) DayText this time. Your first column definition changes to:
{
field: "DayText",
title: "Day"
}
So it keeo the Day property as is. Fiddle.
I threw a jQuery-each function at the end that seems to do the trick, try adding it to the bottom of your javascript:
var day = ""; // holds latest day value
// for each row...
$('tr').each(function(){
var thisDay = $(this).find('td:first').html(); // grab the text from the first column
if (thisDay == day) // if its the same as last time
{
$(this).find('td:first').html(''); // hide it
}
day = thisDay; // hold onto this day
});

JavaScript: Get the color object in a array

I'm trying to get only the color values from the array and set the necessary css class.
$(document).ready(function() {
$('.kalendar').kalendar({
events: [
{
title:"National Holiday",
start: {
date: 20140815,
time: "12.00"
},
end: {
date: "20140815",
time: "12.00"
},
color: "red"
},
{
title:"State Holiday",
start: {
date: 20140818,
time: "12.00"
},
end: {
date: "20140818",
time: "12.00"
},
color: "blue"
}
]
});
});
now when i try this code, they all end up having a blue color. what am i doing wrong here?
for (var j = 0; j < this.options.events.length; j++) {
var thiscolor = this.options.events[j];
if (thiscolor.color == 'red') {
$day.addClass('red-events');
} else if (thiscolor.color == 'blue') {
$day.addClass('blue-events');
}
}

Sorting json array

function demo() {
var test = [{
level: 19,
title: "hello1"
}, {
level: 2,
title: "hello2"
},
{
level: 5,
title: "hello5"
}];
I want to sort this array but can't find a way to do so.
You can create a custom sorting function:
// Sort by level
test.sort(function(a, b) {
return a.level - b.level;
});
Resulting object:
[
{"level":2,"title":"hello2"},
{"level":5,"title":"hello5"},
{"level":19,"title":"hello1"}
]
You can create a sort function like:
function sortBy(prop){
return function(a,b){
if( a[prop] > b[prop]){
return 1;
}else if( a[prop] < b[prop] ){
return -1;
}
return 0;
}
}
//Usage
var test = [{
level: 19,
title: "hello1"
}, {
level: 2,
title: "hello2"
},
{
level: 5,
title: "hello5"
}].sort( sortBy("level") );
Please check below code ,
<script type="text/javascript">
var test = [
{ level: 19, title: "hello1" },
{ level: 2, title: "hello2"},
{ level: 5, title: "hello5" }
];
// Before Sorting
document.write("<b>Before Sorting </b><br/>");
for (var n = 0; n < test.length; n++) {
document.write(test[n].level + ' ' + test[n].title+ '<br>');
}
// ascending order
function SortByLevel(x,y) {
return x.level - y.level;
}
function SortByTitle(x,y) {
return ((x.title == y.title) ? 0 : ((x.title> y.title) ? 1 : -1 ));
}
// Call Sort By Name
test.sort(SortByTitle);
document.write("<br/><b>After Sorting </b> <br/>");
for(var n=0;n<test.length;n++){
document.write(test[n].level + ' ' + test[n].title+ '<br>');
}
</script>

Categories

Resources