1

I have a series of buttons loaded from a JSON, which in turn should disappear and append other buttons on click.

Like so (the first level of buttons is already on the page and reacting properly to other events like hover):

    ...
     $(document).on('click', "#subcategoryButtons button", function () {
            getTemplate('imgMenu.html');
            var entryIndex = this.id[0];
            var subentryIndex;
            if (this.id[1] === '0')
            {
                subentryIndex = this.id.slice(-1);
            }
            else
            {
                subentryIndex = this.id.slice(-2);
            }
            var imgs = data.category[entryIndex].subcategory[subentryIndex].imgs;
            $.each(imgs, function (imgIndex)
            {
                var imgName = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgName;
                var imgId = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgId;
                $('#imgButtons span').append('<button id="' + imgId + '">' + imgName + '</button>');
            });
        });
    }
    ;
...

This is the content of the template being loaded:

<div id="imgSpace">
    <aside id="overlayRight">
        Right Overlay space
    </aside>
    <div id="overlayBottom">
        Bottom Overlay
    </div>
</div>
<nav id="imgButtons" class="resizable">
    <span></span>
</nav>

Here's the getTemplate code:

function getTemplate(templateUrl)
    {
        $.get('templates/' + templateUrl, function (content)
        {
            if (templateUrl === 'leftMenu.html')
            {
                $('#leftMenu').html(content);
            }
            else
            {
                $('#main').html(content);
            }
        });
    }

Even though it should append the buttons to the #imgButtons span, it seems as if it cannot select any of the elements in the template just loaded. If I try to append the buttons to another part of the page (say like the left menu, which is not recently loaded) or instead of getting a template I simply clear out the HTML in the main, the attachment works. So it appears that the issue is how to select elements that have been loaded. Any help would be greatly appreciated.

Thanks to everyone who pointed me in the right direction. In the end I didn't use Ajax but deferred.done like so:

 $(document).on('click', "#subcategoryButtons button", function () {
            var entryIndex = this.id[0];
            var subentryIndex;
            if (this.id[1] === '0') {
                subentryIndex = this.id.slice(-1);
            } else {
                subentryIndex = this.id.slice(-2);
            }
            var imgs = data.category[entryIndex].subcategory[subentryIndex].imgs;
            $('main').html('');
            $.get("templates/imgMenu.html", function (content)
            {
                $('#main').html(content);
            }).done(function () {
                $.each(imgs, function (imgIndex) {
                    var imgName = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgName;
                    var imgId = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgId;
                console.log(entryIndex);
                $('#imgButtons span').append('<button id="' + imgId + '">' + imgName + '</button>');
                });
            });
        });
    }
    ;
Asinus Rex
  • 535
  • 9
  • 29

2 Answers2

3

You're using the wrong selector #imgButtons button should be #imgButtons span to select the span in #imgButtons

Also your template is loaded asynchronously so you'll have to wait until it is loaded (via a callback function) to manipulate it. something like

 $(document).on('click', "#subcategoryButtons button", function () {
        getTemplate('imgMenu.html', callback);
        function callback(){
            var entryIndex = this.id[0];
            var subentryIndex;
            if (this.id[1] === '0')
            {
                subentryIndex = this.id.slice(-1);
            }
            else
            {
                subentryIndex = this.id.slice(-2);
            }
            var imgs = data.category[entryIndex].subcategory[subentryIndex].imgs;
            $.each(imgs, function (imgIndex)
            {
                var imgName = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgName;
                var imgId = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgId;
                $('#imgButtons span').append('<button id="' + imgId + '">' + imgName + '</button>');
            });
        }
    });
    ...
function getTemplate(templateUrl, callback)
{
    $.get('templates/' + templateUrl, function (content)
    {
        if (templateUrl === 'leftMenu.html')
        {
            $('#leftMenu').html(content);
        }
        else
        {
            $('#main').html(content);
        }
        callback();
    });
}
Musa
  • 96,336
  • 17
  • 118
  • 137
  • Thanks! It must have slipped while trying things out, I´ll correct it in the question. The issue is that no matter what selector I use, if it is in the newly loaded template I cannot access it. – Asinus Rex Oct 11 '14 at 15:28
  • @AsinusRex I suspected that this might not be the actual issue, the load template probably be the async action since you have told that you used `$.get`, therefore the element may not be present at the time when you are selecting. – code-jaff Oct 11 '14 at 15:32
  • I've tried putting the appending part in another function, how can I make it wait until the template is loaded before it attempts to append? – Asinus Rex Oct 11 '14 at 15:35
0

let's make a bit modification on your code, use promises - the jqxhr object returned by the ajax method implements the promise interface, therefore you could make use of it.

function getTemplate(templateUrl)
{
    return $.get('templates/' + templateUrl, function (content)
    {
        if (templateUrl === 'leftMenu.html')
        {
            $('#leftMenu').html(content);
        }
        else
        {
            $('#main').html(content);
        }
    });
}

use it in this way

$(document).on('click', "#subcategoryButtons button", function (e) {
    getTemplate('imgMenu.html').then(function () {
        var entryIndex = this.id[0];
        var subentryIndex;
        if (this.id[1] === '0') {
            subentryIndex = this.id.slice(-1);
        } else {
            subentryIndex = this.id.slice(-2);
        }
        var imgs = data.category[entryIndex].subcategory[subentryIndex].imgs;
        $.each(imgs, function (imgIndex) {
            var imgName = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgName;
            var imgId = data.category[entryIndex].subcategory[subentryIndex].imgs[imgIndex].imgId;
            $('#imgButtons span').append('<button id="' + imgId + '">' + imgName + '</button>');
        });
    });
});
code-jaff
  • 9,230
  • 4
  • 35
  • 56
  • I tried your code but no luck so far. Thanks for the promise() resource, it seems to be exactly what I need here, but I think I'm using it wrong: – Asinus Rex Oct 11 '14 at 15:59