Minification of Javascript and increasing performance - javascript

Here is my code for the html:
<div class="board">
<table id="mastermind_table_one">
<tr id="one">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<table id="mastermind_table_two">
<tr id="two">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<table id="mastermind_table_three">
<tr id="three">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
Here is my code for the Javascript:
$('.next_round').click(function() {
var count = 3;
var counter = setInterval(timer, 1000);
function timer() {
count = count - 1;
if (count === 0) {
$('#mastermind_table_two').each(function() {
$(this).find('td').each(function() {
$(this).css("background-color", setRandomColor);
})
})
clearInterval(counter);
}
})
I am building a game in which when the "next_round" button is clicked, all the empty tds are filled with a random background color (there's more code, such as setRandomColor function, but it's not relevant to the question).
I have ten mastermind_tables total, and that is where the problem lies. I am repeating this code for each table. Does anyone know how I can have this listed just once and move to the next td when I click "next_round"?
i.e. the js code above is specific to mastermind_table_two. How can I have it be dynamic and move to the next td once the previous one is executed?

UPDATED
My mistake, must have readed your question in the worng way
Try this, its a bit of a hacky but might fit into your needs
$('.next_round').click(function () {
$('[id^=mastermind_table_]').each(function () {
$(this).addClass("notTreated");//a fake class just to control
});
var counter = setInterval(timer, 1000);
function timer() {
var currenttable;
if ((currenttable = $(".notTreated").first()) == null) {
clearInterval(counter);
return;
}
$(currenttable).find('td').each(function () {
$(this).css("background-color", setRandomColor);
});
//after treat this table, removes the fake class
$(currenttable).removeClass("notTreated");
}
});

Related

tr on click change to different tr

Using Jquery, I have a table and on clicking the table row i want td to change to textbox or dropdown.
After entering the values of textbox i want those values to be updated to that table row on which it was clicked. I have got it partially.
Please help me with this.
This is my html code:
<table id="myTable" >
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
This is my script:
$(document).ready(function () {
$("#myTable").children("tbody").children("tr").children("td").click(function () {
$(this.parentNode).replaceWith('<tr><td ><textarea></textarea></td><td ><textarea></textarea></td><td ><textarea></textarea></td></tr>').appendTo($(this)).val().select().blur(function () {
var newText = $(this).val();
$(this).parent().text(newText);
});
});
});
Try something like this. I don't check if it compile, it is just an idea:
$("#myTable").children("tbody").children("tr").children("td").click(function () {
var cell1Text = $(this).find('.cell1').text();
$(this.parentNode).replaceWith('<tr><td><textarea class="cell1">'+cell1Text+'</textarea></td>...</tr>').appendTo($(this)).val().select().blur(function () {
var newText = $(this).val();
$(this).parent().text(newText);
});
})
.blur(function () {
var cell1Val = $(this).find('.cell1').val();
$(this.parentNode).replaceWith('<tr class="cell1">'+cell1Val+'<td ></td>...</tr>').appendTo($(this)).val().select().blur(function () {
var newText = $(this).val();
$(this).parent().text(newText);
});
});

How to keep adding data to next table column

This Fiddle Example shows a comparison table that dynamically shows information in a column when a button is clicked. Once the table is filled up, I want to start the whole process again. But as the example shows, the buttons are stuck at adding information to th:nth-child(2) and td:nth-child(2) during the second time instead of moving on to the next column like during the first time.
I'm guessing this part needs some change if( allCells === fullCells ) { to keep information being added to next columns.
HTML
<div class="area">
<button>Gah</button>
</div>
<div class="area">
<button>Kaj</button>
</div>
<div class="area">
<button>Fdw</button>
</div>
<div class="area">
<button>ffdf</button>
</div>
<table>
<thead>
<tr>
<th>Placeholder</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Age</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Name</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Race</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Nationality</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Education</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Language</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Code:
$(function() {
$('.area').each(function(){
var area = $(this),
filltable ='',
button = $(this).find('button'),
buttontext = button.text();
button.on("click",function(){
var allCells = $('table').find('th,td').length;
var fullCells = $('table').find('th,td').filter(function() {
return $(this).text() != '';
}).length;
if( allCells === fullCells ) { // If table is full
$('table').find('th,td').not(':first-child').removeClass('addinfo');
filltable();
}
else { // If table isn't full
filltable = function(){
var i = $('th.addinfo').length !== 0 ? $('th.addinfo:last').index() : 0;
console.log( i );
i + 2 > $('th').length ||
$('th,td').filter(':nth-child(' + (i + 2) + ')')
.addClass( 'addinfo' ).html(buttontext);
}
filltable();
}
}); // end button on click function
});
});
Please see the attached link for demo. I have created a function name cleartable() which clears the table if its full and have used your old filltable() function to repopulate. There is repetition of code which you will have to clean up.
th:nth-child(2) identifies second child of th.
td:nth-child(2) identifies second column.
Similarly if you wanted to do something with let say second row, you can use tr:nth-child(2).
I hope this helps you understand a little about parent-child relationship in jquery.
JSFIDDLE DEMO
function clearTable() {
$('table th:nth-child(2)').html('');
$('table th:nth-child(3)').html('');
$('table th:nth-child(4)').html('');
$('table td:nth-child(2)').html('');
$('table td:nth-child(3)').html('');
$('table td:nth-child(4)').html('');
}
http://jsfiddle.net/jqVxu/1/
I think you'd better to count th only. count all td and th make me confused.
$(function () {
function filltable(buttontext) {
var i = $('th.addinfo').length !== 0 ? $('th.addinfo:last').index() : 0;
i + 2 > $('th').length || $('th,td').filter(':nth-child(' + (i + 2) + ')')
.addClass('addinfo').html(buttontext);
}
$('.area').each(function () {
var area = $(this),
button = $(this).find('button'),
buttontext = button.text();
button.on("click", function () {
var allCells = $('table').find('th').length-1;
var fullCells = $('table th.addinfo').length;
console.log(allCells, fullCells);
if (allCells === fullCells) { // If table is full
$('table .addinfo').removeClass('addinfo');
filltable(buttontext);
} else { // If table isn't full
filltable(buttontext);
}
});
});
});

How to find empty table column, including `th` and inject data into it

Updated Fiddle Example:
How would you find an empty table column,including th in the fiddle so that when you click on a button it'll inject data into that column only. For example, when you click on "X" it'll add data to the first empty column,"G" will add data to the second empty....When the table is full, start from the second child column (because the first column is some sort of title column) and replace old data in that column.
Just a guess:
columnTh = $("table th");
columnIndex = columnTh.index() + 1;
columnIndex.each(function(){
if ($(this).html() == '' && $('table tr td:nth-child(' + columnIndex + ')').html() == ''){
// add data
}
But how can I check if the whole table is full so that the button will add data to the first column again?
HTML:
<div class="area">
<select>
<option>Choose</option>
<option>R</option>
<option>T</option>
</select>
<div class="show">
</div>
</div>
<div class="area">
<select>
<option>Choose</option>
<option>X</option>
<option>G</option>
</select>
<div class="show">
</div>
</div>
<table>
<thead>
<tr>
<th>Placeholder</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Age</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Name</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Race</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Nationality</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Education</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Language</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
JS Code
$(function (){
$('.area').each(function(){
var area = $(this),
selectbox = area.find('select'),
show = area.find('.show'),
dialog_open = $(this).find(".dialog_open");
selectbox.change(function(){
selectbox = $(this).find('option:selected').text();
show.html('<button class="dialog_open">'+selectbox+'</button>')
});
var foo = function() {
var dialog_open_text = $(this).find(".dialog_open").text();
$('table td').html(dialog_open_text); // ****Need help in this part*****
};
show.one( "click",dialog_open, foo );
});
});
Here is how to check that the table is full:
var allCells = $('table').find('th,td').length;
var fullCells = $('table').find('th,td').filter(function() {
return $(this).text() != '';
}).length;
if( allCells === fullCells ) { // if true table is full, not full otherwise
//do something table is full
} else {
//table is not full
}
If the first select indicates the column # you're targeting and the second select indicates the content to put in the cells of the column, then you may use the following logic inside the function foo:
var colN = $('select').first().val(),
colCont = $('select').last().val(),
allColumns = $('table').find('th:eq(' + (colN - 1) + '),td:eq(' + (colN - 1) + ')').length,
fullColumns = $('table').find('th:eq(' + (colN - 1) + '),td:eq(' + (colN - 1) + ')').filter(function() { return $(this).text() != ''; }).length;
Then you can check to see if the targeted column is full or not:
if( allColumns === fullColumns ) {
//all cells in target column full
} else {
//not all cells in target column are full
}
You can empty everything but the first column this way:
$('table').find('th,td').not(':first-child').empty();
And here's how to fill a column:
$('td').filter(':nth-child(' + colN + ')').html(dialog_open_text);

Highlight repeating strings

I have up to three almost-identical divs that contain tables of usernames. Some names may be repeated across the three divs. I'd like to highlight the names that are repeated. The first occurrence of the user should not be colored, the second occurrence should have an orange background and the third should have a red background. The divs go from left to right in order so the first div should not have any highlighted usernames.
My HTML looks like:
<div class="col-md-4">
<table class="table table-striped">
<tr>
<th>2/26/2014</th>
</tr>
<tr>
<td>user1</td>
</tr>
<tr>
<td>user2</td>
</tr>
<tr>
<td>user5</td>
</tr>
<tr>
<td>user17</td>
</tr>
</table>
</div>
<div class="col-md-4">
<table class="table table-striped">
<tr>
<th>2/27/2014</th>
</tr>
<tr>
<td>user13</td>
</tr>
<tr>
<td>user5</td>
</tr>
<tr>
<td>user7</td>
</tr>
</table>
</div>
<div class="col-md-4">
<table class="table table-striped">
<tr>
<th>2/28/2014</th>
</tr>
<tr>
<td>user5</td>
</tr>
<tr>
<td>user45</td>
</tr>
<tr>
<td>user1</td>
</tr>
</table>
</div>
I know that the username table cells will be selected with $('table.table td') (if I use jQuery) but I'm not sure what to do from there.
Please let me know if you have any questions.
Thank you.
Is this what you want?
I created a map to store text-occurrence pairs. Each time the text is repeated, the counter associated with it gets incremented. If the counter climbs to a certain value, the background will be set to another color. Give it a shot!
DEMO
var map = new Object();
$('td').each(function() {
var prop = $(this).text()
var bgColor = '#FFFFFF';
if (map[prop] > 1) {
bgColor = '#FF0000';
} else if (map[prop] > 0) {
bgColor = '#FF7F00';
}
$(this).css('background', bgColor);
if (map.hasOwnProperty(prop)) {
map[prop]++;
} else {
map[prop] = 1;
}
});
You could try something like this but I didn't test it
$('td').each(function(){
var text = this.html();
$('td:contains("'+text+'"):nth-child(2)').css({'background':'orange'});
$('td:contains("'+text+'"):nth-child(3)').css({'background':'red'});
});
Edit:
Not particularly elegant but it seems to work
http://jsfiddle.net/63L7L/1/
var second = [];
var third = [];
$('td').each(function(){
var text = $(this).html();
second.push($("td").filter(function() {
return $(this).text() === text;
})[1])
third.push($("td").filter(function() {
return $(this).text() === text;
})[2])
});
$(second).each(function(){
$(this).css({'background':'red'});
});
$(third).each(function(){
$(this).css({'background':'orange'});
});
With pure Javascript (ECMA5)
CSS
.orange {
background-color:orange;
}
.red {
background-color:red;
}
Javascript
Array.prototype.forEach.call(document.querySelectorAll('.table-striped td'), function (td) {
var textContent = td.textContent;
if (this.hasOwnProperty(textContent)) {
td.classList.add(++this[textContent] === 2 ? 'orange' : 'red');
} else {
this[textContent] = 1;
}
}, {});
On jsFiddle

Changing adjacent cells in table when an event is triggered in JQuery

I'm trying to make a game of lights out. I can get the lights to toggle on and off when i click them, but i am having trouble thinking up logic to make the adjacent one come one as well. For example if i click an edge of the table, I should see the three lights adjacent to the light i clicked, become lit. I'm thinking maybe it has something to do with the "this" bound in my click method, Maybe the "this" is only referencing the one i clicked on and not the adjacent ones. I need to know, perhaps how to get it to reference the adjacent ones?
<html>
<head>
<title>Lights Out!</title>
<script type="text/javascript" src="jquery-1.4.js"></script>
<script type= "text/javascript">
var gameBoard = new Array(getTdCount())
function lightStatus(position)
{
//if light is on
if(gameBoard[position] ==true)
{
//set the original status back to false
gameBoard[position] = false;
return false
}
//turn on light
gameBoard[position]=true;
return gameBoard[position]
}
function getTdCount()
{
return $("td").length;
}
function getTrCount()
{
return $("tr").length;
}
function switchLights( obj, num )
{
if(lightStatus(num))
{
$("img", obj).attr('src', 'on.png')
}
else
{
$("img", obj).attr('src', 'off.png')
}
}
$(document).ready(function()
{
$("#board tr td").hover(function()
{
$(this).css('border-color', '00FFCC');
},
function()
{
$(this).css('border-color', 'black')
})
var $offProtoType = $('#offprototype').css('display', 'block').removeAttr('id')
$('td').append($offProtoType)
$tds = $('#board tr td');
$tds.click(function()
{
var num = $tds.index(this) + 1;
switchLights(this, num)
})
});
</script>
<style type="text/css">
td
{
border-style:solid;
border-color:black;
background-color:black;
float:left;
}
body
{
background-color: grey;
color: green;
}
</style>
</head>
<body>
<img style = "display:none" id="offprototype" src ="off.png">
<img style = "display:none" id="onprototype" src ="on.png">
<h1 align="center">Lights Out<h1>
<table id="board" border="3" bgcolor="black" align="center">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<input type="button" value="Shuffle" onclick="change()"/>
</body>
</html>
Use $(this).next() and $(this).prev() to get a reference to the next & previous.
You can use $(this).index() to obtain the position of the 'this' among its siblings; so use something like the following for abobe and below.
var pos = $(this).index();
var prevRow = $(this).parent().prev('tr');
var above = prevRow && prevRow.children().slice(pos);
var nextRow = $(this).parent().next('tr');
var below = prevRow && prevRow.children().slice(pos);
Probably the easiest thing to do is take a look at http://jqueryminute.com/finding-immediately-adjacent-siblings/ if you want just the siblings. If you want the whole row then you can use parent to select the parent element of the cell which should be the row.

Categories

Resources