Trying to Set the Index of a td in jQuery - javascript

In the process of creating a tile-swap puzzle game for my jQuery class. Right now I'm working on trying to make the clicked tile switch with the blank tile (I'll figure out how to limit it to adjacent tiles afterwards). I've stored indexes of both indexes in new variables, but I can't figure out how to assign a variable as the td elements index.
$(document).ready(function(){
$('img').click(function(){
var tileSelected = $(this); //grab the clicked tiles index
var tileIndexOld = $("img").index(tileSelected);
var blankTile = $("#blank"); //grab the blank tiles index
var blankIndexOld = $("img").index(blankTile);
var tileIndexNew = blankIndexOld; //swap tile and blank indexes
var blankIndexNew = tileIndexOld;
$(this).attr("index", tileIndexNew);
$("#blank").attr("index", blankIndexNew);
});
});
I've also tried doing things like $(tileSelected).index(tileIndexNew); and $(this).index() = tileIndexNew; etc. I just can't seem to figure out how to overwrite with the new index.
Edit:
Okay, I've been shown the wickedness of my (attempted) index swapping ways! Still working on the solution, but I'm changing tracks and focusing on altering the src's as suggested by Starscream1984. I'll update again once I've got it figured out, many thanks to all!
Solution:
After trying it three different ways (with multiple sub-variations) this is what I ended up with:
$(document).ready(function(){
$("td").click( function(){
var tileVertical = $(this).index(); //get clicked tiles vertical position via its td
var tileHorizontal = $(this).parent().index(); //get clicked tiles horizontal position via its tr
var blankTile = $("#blank").parent(); //getting the td that contains the blank tile
var blankVertical = blankTile.index(); //get blank tiles vertical position (via its td)
var blankHorizontal = blankTile.parent().index(); //get blank tiles horizontal position via its tr
if( Math.abs(blankVertical - tileVertical) + Math.abs(blankHorizontal - tileHorizontal) == 1) //check if clicked tile is adjacent to the blank tile
{
blankTile.empty().html( $(this).html() ); //put the tile html into the blank slot
$(this).html("<img id='blank' src='blank.jpeg' width='200px' />"); //fill the tile slot with the blank, ID IS CRITICAL!!!!
} //function will only run once if id is omitted from this tag!!!
return 1;
});
});
My original approach tried to use the index as a quick and dirty variable to swap out. What I discovered was that the index in this case is simply more like a map with x and y coordinates. It was the inner html of the table cell that needed to be swapped, not the index itself.

You need to move the elements around using jQuery DOM modification methods. This solution assumes that each tile is contained in a DIV in the grid.
$('img').click(function(){
var tileSelected = $(this);
var parentSelected = tileSelected.parent();
var blankTile = $("#blank");
var blankParent = blankTile.parent();
parentSelected.append(blankTile);
blankParent.append(tileSelected);
});

A)
$('img').each(function(index, elem){
console.log(index);
});
B)
$('img').click(function(){
var index = $(this).index();
//or
//var index = $('img').index($(this));
console.log(index);
});
Are the right ways. So your code seems to be correct. Are you sure that all imgages exists at the moment you run the function? Do you noticed that your selector find all img in DOM?

If you want to assign an index variable for the td, one approach to do it dinamically is the following:
$(document).ready(function(){
var tdArray = $("td");//grabs all td elements
for(i = 0; i < tdArray.length; i++){
$(tdArray[i]).attr('data-index',i);//adds a data-index attribute on each one
}
});
You could then handle a click event like this:
$("td").click(function(){
alert($(this).attr('data-index'));
});
To keep track of your blank tile, you could simple assign its data-index to a global variable.

Related

Need help shortening down function that creates a lot of elements in array

I have a file with 170 images. These images are displayed on my website and the user can slide to see different pictures. This code works but I'm looking for a more efficient way to do what I did below.
var imgCo2 = new Array(); //create new array containing all elements below
imgCo2[0] = 'co2_model/0.jpg'; //string is this element of the array. string goes to local image located in file co2_model
imgCo2[1] = 'co2_model/1.jpg';
imgCo2[2] = 'co2_model/2.jpg';
imgCo2[3] = 'co2_model/3.jpg';
imgCo2[4] = 'co2_model/4.jpg';
imgCo2[5] = 'co2_model/5.jpg';
imgCo2[6] = 'co2_model/6.jpg';
imgCo2[7] = 'co2_model/7.jpg';
imgCo2[8] = 'co2_model/8.jpg';
imgCo2[9] = 'co2_model/9.jpg';
This repeats up to 171 and then I have a similar array with different images that goes to 150. This code is used for a an img slider. The slider code is below.
$(document).on('input change', '#slider', function() {//listen to slider changes
var v=$(this).val();//getting slider val
$('#sliderStatus').html( $(this).val() );
$("#imgTemp").prop("src", imageTemp[v]);
});
if you image name is not changing did you consider doing something like this
$(document).on('input change', '#slider', function() {//listen to slider changes
var v=$(this).val();//getting slider val
$('#sliderStatus').html( $(this).val() );
$("#imgTemp").prop("src", `co2_model/${v}.jpg`);
});
in this case you will not need an array at all
Question not closed yet so I'll put the code below. Wasn't as hard as I thought
var imgCo2 = new Array();
var i;
for (i= 0; i!=172; i++){ //the 172 is manually put(amount of images in the file starting from 0)
imgCo2[i]= 'co2_model/'+i+'.jpg'
}

How to find child element using variable selector within parent built with incrementing variable

Trying to add an incrementing class name to an element (rows in an ajax cart), while doing the same to one of it's child elements (images within each cart row).
After the items are numbered, show the matching image that has the same number in class name.
ex. cartitem-1 shows cartimage-1
var itemCount=0;
var imgCartCount=0;
if ($('.ajax-cart-row').length) {
// itemize cart rows
$('.ajax-cart-row').each(function() {
itemCount++;
var cartItemNumber = 'cartitem-'+itemCount;
$(this).addClass(cartItemNumber);
$(this).val(itemCount);
console.log('cart numbers loaded');
});
// itemize images in cart
$('.ajax-cart-row img').each(function() {
IMGCount++;
var cartImgs = 'cartimg-'+IMGCount;
$(this).addClass(cartImgs);
$(this).val(IMGCount);
$(this).closest('.ajax-cart-row').find('[class*='+cartImgs+']').show();
console.log('image numbers added');
});
}
edit: There are multiple cartitem-# img elements without any individual classes/ids/filenames to go by. That's what this is for hopefully.
Hopefully I'm not just sleep deprived here... Thanks in advance
I'm not sure exactly what you're going for, or what is wrong with your code (except that "show" simply ensures that the element is not hidden - maybe your images are hidden by default?). See if something like this makes any difference:
var itemCount=0;
if ($('.ajax-cart-row').length) {
// itemize cart rows
$('.ajax-cart-row').each(function() {
itemCount++;
var cartItemNumber = 'cartitem-'+itemCount;
var cartRow = $(this);
cartRow.addClass(cartItemNumber);
cartRow.val(itemCount);
console.log('cart numbers loaded');
// add class to the image subelements (assumes only one, or that the same class is added to all img children of cartitem-#)
var imageIdx = 0;
cartRow.find("img").each(function() {
imageIdx++;
var cartImgs = 'cartimg-'+imageIdx;
var cartImg = $(this);
cartImg.addClass(cartImgs);
cartImg.val(itemCount);
if (imageIdx === itemCount) {
cartImg.show();
}
console.log('image numbers added');
});
});
}
This should ensure that all img children of an itemized .ajax-cart-row will receive the same index in the class name as the row received (i.e. all img tags within cartitem-1 will receive a the cartimg-1 class). I hope that is what you are looking for.

add different background-image to elements from json array

Everything is working, but when I want to add background-image, to different elements, it's just putting last image from array, and set css backgorund to all of them with that last image.
$.get('con.php',function(data) {
var data = JSON.parse(data);
for(i = 0; i < data.length; i++) {
var div = "<div class='nemkec-dev' id='"+data[i].id+"'>"+"<h1>"+ data[i].text+"</h1>"+"<p>"+
data[i].text2+"</p>"+"<img src='images/"+data[i].image+"'/>"+"</div>";
$('body').append(div);
var image = data[i].image;
}
$.each(data, function(i, dat) {
$('.nemkec-dev').css('background-image','url(images/'+dat.image+')');
});
It shows image as element. But, when I want to set css rule it's not working.
Just appending last-image to all for background.
When creating var div you can create an inline style var div = "<div style='background-image: url(images/"+data[i].image+")'...
I am pretty sure you want to iterate over $('.nemkec-dev') elements. What you are doing now is iterating over background images and setting background image for all of .namkec-dev divs at once. So natural outcome is that after this script ends you have all .nemkec-dev elements with the last background image.
You can go with Michael Coker solution and use them in line with other variables, or do something like this:
var i = 0;
$('.nemkec-dev').each(function() {
$(this).css('background-image', data[i].image);
i++;
});

jQuery UI Draggable: Get drag offset of A LOT of dynamically created elements

I'm creating a <table> element in the DOM and using javascript to dynamically append many cells to it. For the sake of explanation let's say I create 10 rows with 10 fields per row. I'm using simple counters to assign unique IDs for the div containers inside of those fields. Easy enough. This is what I get:
<table>
<tr><td><div id="field0"><div id="handle0"></div></div></td></tr>
.....
<tr><td><div id="field99></div id="handle99"></div></div></td></tr>
</table>
Note that the numbers 0-99 are what is dynamically appended to each element ID.
I now want to go ahead and attach the jQueryUI .draggable function to each handle and retrieve the coordinates of each handle relative to each surrounding parent div like so:
for (var counter = 0; counter < 100; counter++) {
var dragHandle = $('#handle' + counter);
var dragField = $('#field' + counter);
dragHandle.draggable({
containment: dragField,
scroll: false,
drag: function () {
var offset = $(this).offset();
var xPos = (offset.left) - $(this).offsetParent().offset().left;
var yPos = (offset.top) - $(this).offsetParent().offset().top;
console.log(xPos);
console.log(yPos); // These add up?!
}
});
}
Now, the functions work, the table gets properly initialized and all of the individual handles in the table are now draggable.
The problem is that the xPos and yPos values that are returned by the above function are not the correct coordinates relative to each field but instead they add up.
I feel like I'm missing something terribly obvious and would really appreciate if someone could help.
Edit: The example above uses console.log for simplification. My original script performs more complex computations in the on drag event. I won't be able to use a class selector to go through all of the elements like someone suggested in the comments because I need to retrieve unique offset and position values for each unique handle ID relative to its unique containment ID.
var xPos=(offset.left)-$(this).position( ).left
var yPos=(offset.top)-$(this).position( ).top
Instead of offsetParent you can modify.
var xPos = (offset.left) - $(this).parent().offset().left;
var yPos = (offset.top) - $(this).parent().offset().top;

Dynamic Table Width

I have a table cell in which other tables are displayed (with background colors). The inner tables aren't always shown; they can be hidden via a button (change class with jQuery). Now I want the outer cell to always be filled with color. That means if only one table is displayed, its width should be 100%. When two are displayed, each width should be 50%, and so on.
How am I supposed to solve this?
Here's an example:
...
<td>
<table class="show"><tr><td></td></tr></table>
<table class=""><tr><td></td></tr></table>
<table class="show"><tr><td></td></tr></table>
</td>
...
In this case, the width should be 50%
You can change the width value with Jquery.
var count_table = $(".show").length; // count ".show" elements
$(".show").each(function{ // iteration on each ".show"
var width = 100/count_table; // % value of new width
$(this).css("width", width+"%"); // CSS modification
});
This code is just adapted for one TD element. You need to iterate on each "td" too.
(I hope I answered your problem)
To change the width of your elements you can use jquery.
Here's the page explaining how.
Here is another way: http://jsfiddle.net/ypJDz/1
A bit too complicated for what you need, but a great deal of possibility to expand.
function resizeTables() {
var baby = $("td > table.show"),
amount = baby.length,
mother = $("body");
baby.width(function () {
var w = mother.width() / amount;
return w;
});
}
resizeTables();
$("button").click(function () {
var $this = $(this),
ID = $this.index() + 1;
$("td > table:nth-child(" + ID + ")").toggleClass("show");
resizeTables();
});

Categories