MC9000
MC9000

Reputation: 2423

how do i reference newly created elements in jquery?

I devised a page that sends an AJAX request to retrieve a table of x rows and x columns into a DIV tag on an HTML page (ASPX page actually), but now, I have no way to access the newly created table elements via JQuery. The jQuery website mentions that you can attach events to all the newly created elements in a container, but there is no working example on how to achieve this.

Here's the code:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="tiler.aspx.vb" Inherits="TestJquery.tiler" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="tiler.css" rel="stylesheet" />
    <script type="text/javascript" src="Scripts/Jquery-1.10.2/jquery-1.10.2.js"></script>
    <script type="text/javascript" src="Scripts/JqueryUI/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.js"></script>
    <script type="text/javascript" src="Scripts/tiler.js"></script>
</head>
<body>
    <div id="options">
            <input type="button" id="btnSubmit" value="Update Grid" />&nbsp;
            Tile Size:<select id="cboTileSize">
                <option value="19.6850393701">19.7&quot; (50cm)</option>
                <option  value="24" selected="selected">24&quot; (61cm)</option>
            </select>
            Grid Size:<select id="cboGridSize" >
                <option value="2,2">2 X 2 tiles</option>
                <option value="3,4" selected="selected">3 X 4 tiles</option>
                <option value="4,4">4 X 4 tiles</option>
                <option value="4,5">4 X 5 tiles</option>
            </select>
             Dimensions:<span id="dims"></span>
    </div>
    <div id="dd">
        <div id="dropgrid">
<!-- table will be inserted here -->
        </div>
        <div id="dragfrom">
            <div class="idrg">
                <img src="images/TC-Colorblox-Berry.jpg" id="TC-Colorblox-Berry" alt="50" />
                <div class='idscr'>Stock:&nbsp;<span class="avail">50</span>/<span class="stock">50</span></div>
            </div>
            <div class="idrg">
                <img src="images/TC-Coordination2-Concur.jpg" id="TC-Coordination2-Concur" alt="25" />
                <div class='idscr'>Stock:&nbsp;<span class="avail">25</span>/<span class="stock">25</span></div>
            </div>
            <div class="idrg">
                <img src="images/TC-Ground-DarkGrey.jpg" id="TC-Ground-DarkGrey" alt="5" />
                <div class='idscr'>Stock:&nbsp;<span class="avail">5</span>/<span class="stock">5</span></div>
            </div>
            <div class="idrg">
                <img src="images/TC-Plexus-Lavender.jpg" id="TC-Plexus-Lavender" alt="50" />
                <div class='idscr'>Stock:&nbsp;<span class="avail">50</span>/<span class="stock">50</span></div>
            </div>

        </div>
    </div>


</body>
</html>

The auto-generated table fits inside the "dropgrid" DIV.

Here's the script:

var currentImage = null;

$(document).ready(function () {
    $('.idrg').draggable({
        containment: '#dd',
        cursor: 'pointer',
        opacity: 0.8,
        start: function () {
        },
        stop: function () {
        }
    });


    $('td').droppable({
        hoverClass: 'tdHov',
        containment: '#dd',
        drop: function (event, ui) {
            var draggedDiv = ui.draggable; //div container holding img
            var draggedDivPic = draggedDiv.find('img'); //img inside div
            var dropToPic = $(this).find('img'); //reference to IMG tag inside TD
            var avail = draggedDiv.find('.idscr .avail');
            var available = parseInt(avail.text());

            if (available > 0) {
                // first, get the current imageID from the TD, if any (so we can decrement that image's count)
                if (dropToPic.attr('src') == 'Images/bgc.png') {
                    dropToPic.attr('src', draggedDivPic.attr('src')).attr('alt', draggedDivPic.attr('id')); //assign SRC & ALT(product SKU)
                }
                else {
                    // there's an existing pic, so find it's ID and current 'avail' span tag value and decrement.

                    //find the ID in the ALT of the current image first
                    var currentImgID = '#' + dropToPic.attr('alt');
                    // find the parent div and set to a  variable
                    var DivParentOfImg = $(currentImgID).parent(); //why is this undefined

                    //get the value of the available span
                    var avail2 = DivParentOfImg.find('.idscr .avail');
                    var available2 = parseInt(avail2.text());
                    available2 += 1;
                    avail2.text(available2); //set the new value

                    //put the new pic in
                    dropToPic.attr('src', draggedDivPic.attr('src')).attr('alt', draggedDivPic.attr('id')); //assign SRC & ALT(product SKU)
                };


            };
            //decrement count on this pic
            available -= 1;
            if (available < 0) { available = 0 };
            avail.text(available); //set the new count


        }
    })
        .dblclick(function () {
            var dropToPic = $(this).find('img'); //reference to IMG tag inside TD

            if (dropToPic.attr('src') == 'Images/bgc.png') {
                //no image was ever dropped here, so no count to increment
                //clears td tile image - actually, replaces w/ blank image
                dropToPic.attr('src', 'Images/bgc.png').attr('alt', '');
            } else {
                //find the ID in the ALT of the current image first
                var currentImgID = '#' + dropToPic.attr('alt');
                // find the parent div and set to a  variable
                var DivParentOfImg = $(currentImgID).parent(); //why is this undefined

                //get the value of the available span
                var avail2 = DivParentOfImg.find('.idscr .avail');
                var available2 = parseInt(avail2.text());
                available2 += 1;
                avail2.text(available2);

                //clears td tile image - actually, replaces w/ blank image
                dropToPic.attr('src', 'Images/bgc.png').attr('alt', '');
            };
        })
    .click(function () {
        //reserve for extra image manipulation
    });

    $('#btnSubmit').click(function () {
        var dimselection = $("#cboGridSize option:selected").val();
        var postData = { "method": "GetTable", "strDims": dimselection };

        //got sick of screwing around with WCF and getting nowhere - using simple aspx page instead of webservice for now
        $.post("/services.aspx", postData, function (data) {
            $("#dropgrid").html(data);
        });
    });




});

Basically, the user drags tiles from the right hand side into the grid(table) and the jQuery code works if the table is already there, but not if it's generated. The table looks like:

<table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td></tr><tr><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td></tr><tr><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td></tr><tr><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td><td><img alt="" src="Images/bgc.png"></td></tr></tbody></table>

Basically, the code determines when a tile is hovering over a table cell, when the mouse is released, the image (IMG) inside the TD is changed to that image and the ALT tag contains the SKU (it's a work in progress). Ultimately, a pattern is created by the user and the table is AJAXed to another webservice that stitches the images together (resizes, saves to PDF, and a few other things).

Anyway, the syntax for accessing dynamically created elements confuses me.

Upvotes: 1

Views: 428

Answers (1)

MonkeyZeus
MonkeyZeus

Reputation: 20747

The .on() syntax can be confusing but check out this JSFiddle. I will follow up with an explanation shortly.

$(document).ready(function(){

    // This code says "listen for a click to occur on a button anywhere withing the current document"
    $('input[type="button"]').on('click', function(){
        alert($(this).val());
    });

    // This code says "Listen for any button within #mydiv to get clicked"
    // So anytime you are in the area of #mydiv it will listen for a click and check if it occurred on a button
    $('#mydiv').on('click', 'input[type="button"]', function(){
        alert($(this).val());
    });

});

UPDATE

$.post("/services.aspx", postData, function (data) {
    $("#dropgrid").html(data);

    $("#dropgrid").find('td').droppable({
        hoverClass: 'tdHov',
        etc: '........'
    });

    // If the code above doesn't work then try this
    $("#dropgrid").find('td').each(function(){
        $(this).droppable({
            hoverClass: 'tdHov',
            etc: '........'
        });
    });
});

Upvotes: 1

Related Questions