ilyo
ilyo

Reputation: 36411

Get location of div on grid

I am making a board game I am looking for a better way to manage the pieces on the board. What I have now is a way to place them on a board from coordinates. This is the JSON object that stores the player data:

"players" : {
    "1" : {
        "id" : 1,
        "name": "ilya",
        "units" : [
            {
                "id" : 1,
                "row" : 1,
                "square" : 2
            },{
                "id" : 2,
                "row" : 2,
                "square" : 1
            },{
                "id" : 3,
                "row" : 3,
                "square" : 1
            }
        ]
    },

And I simply place them by creating a div and appending it to the corresponding board square div and move them around with jquery-ui:

$('<div/>', {
    class: 'draggable player' + player + ' unit unit' + unit,
}).appendTo('.row' + row + ' .square' + square + ' .unitPosition');

row and square are a table and unitPosition is a helper class within square

Now to get back the data after the player has moves I can get back the row and square classes and extract their numbers, but it seems to me a very inefficient way. Is there a better way to manage such a grid and store the location data of each piece/unit?

by popular request, this is the html (shortened for the example):

<div id="board">
    <div class="clearfix row row1">
        <div class="square square1">
            <div class="unitPosition"></div>
        </div>
        <div class="square square2">
            <div class="unitPosition"></div>
        </div>
        <div class="square square3">
            <div class="unitPosition"></div>
        </div>
    </div>
    <div class="clearfix row row2">
        <div class="square square1">
            <div class="unitPosition"></div>
        </div>
        <div class="square square2">
            <div class="unitPosition"></div>
        </div>
        <div class="square square3">
            <div class="unitPosition"></div>
        </div>
    </div>
</div>

the board: enter image description here

Upvotes: 2

Views: 383

Answers (2)

charlietfl
charlietfl

Reputation: 171690

in order to update the data object it would make it a little simpler if you change units to an object instead of array using the id as key for each element

"players" : {
    "1" : {
        "id" : 1,
        "name": "ilya",
        "units" : {
            1: {
                "id" : 1,
                "row" : 1,
                "square" : 2
            },
            2:{
                "id" : 2,
                "row" : 2,
                "square" : 1
            }        
    }

You can use index() method to get row and cell indexes. Using data- attributes for each element will help a lot.

When you read the data you can find the cell using eq() based on the values of row and squre in your data.

var $cell = $('tr').eq( row ).find('td').eq( square);
$('<div data-player="'+player.id+'" data-unit_id="'+unit+'"/>', {
    class: 'draggable player' + player + ' unit unit' + unit,
}).appendTo($cell);

When you drop the unit in a new square:

/* pseudo code, not sure what your drop/append code looks like*/

var $cell= /* your logic to define the cell being placed in*/
var square= $cell.index();
var row= $cell.parent().index();
/* read player and unit from "data-" attributes of DIV*/
var unit= $(this).data('unit_id'), player= $(this).data('player');

Now with revised data structure it is very easy to update the main object players:

players[player].units[unit].row=row;
players[player].units[unit].square=square;

Simple Cell/Row Index demo: http://jsfiddle.net/buh4h/

API References:

http://api.jquery.com/index/

http://api.jquery.com/eq/

Upvotes: 2

bfavaretto
bfavaretto

Reputation: 71939

We don't know much about your code, but you seem to want to have a way to attach data to HTML elements, without having to rely on classes, and extracting numbers from class names.

You could add data- attributes to each table cell and player divs to separate the data, instead of (or in addition to) using classes. Your HTML would become something like this:

<table>
    <tr>
        <td data-row="1" data-col="1">
            <div data-player="1"></div>
        </td>
        <!-- etc -->
    </tr>
    <!-- etc -->
</table>

Then you can retrieve those values with jQuery by reading those attributes, or using the .data() method:

// Assuming you're inside an event handler and "this" is a td
var row = $(this).attr('data-row');
// or
var row = $(this).data('row');

Upvotes: 1

Related Questions