kosbou
kosbou

Reputation: 3999

jQuery more than once function called

I am creating an mobile app and I am calling the function getItem passing data-trnote val.

function getTitles() {
    $(document).ready(function(e){
        var list = $('#recent'),
            items = [];
        $.mobile.notesdb.transaction(function(t) {
            t.executeSql('SELECT buildingcode, buildingaddress FROM buildings ORDER BY buildingaddress ASC', [], function(t, result) {
                var i,
                    len = result.rows.length,
                    row;
                if (len > 0 ) {
                    for (i = 0; i < len; i += 1) {
                        row = result.rows.item(i);
                        items.push('<li><a href="#display" data-trnote="' + row.buildingcode + '">' + row.buildingaddress + '........' + row.buildingcode + '</a></li>');
                    }
                    list.html(items.join('\n'));
                    list.listview('refresh');
                    $('a', list).live('click', function(e) {
                        getItem($(this).attr('data-trnote'));
                    });
                    $('#entries').show();
                } else {
                    $('#entries').hide();
                }
            })
        });
    });
}

The getItem code is as follows:

function getItem(buildingcode) {
alert(buildingcode);
    $(document).ready(function(){
        var list = $('#recentflats'),
            items = [];
        $.mobile.notesdb.transaction(function(t) {
            t.executeSql('SELECT buildingaddress, buildingcode FROM buildings WHERE buildingcode = ?',[buildingcode], function(t, resultbuilding) {
                var myrow;
                myrow = resultbuilding.rows.item(0);
                $('#display h1').text(myrow.buildingaddress);
            })
        });
        $.mobile.notesdb.transaction(function(t) {
            t.executeSql('SELECT DISTINCT flatdescription, flatname, buildingcode FROM bill WHERE buildingcode = ?',[buildingcode], function(t, resultflat) {
                var i,
                    len = resultflat.rows.length,
                    row;
                if (len > 0 ) {
                    for (i = 0; i < len; i += 1) {
                        row = resultflat.rows.item(i);
                        items.push('<li><a href="#displayflat" data-flat="' + row.flatname + '" data-description="' + row.flatdescription + '">' + row.flatdescription + '...' + row.flatname + '</a></li>');
                    }
                    list.html(items.join('\n'));
                    list.listview('refresh');
                    $('a', list).live('click', function(e) {
                        getItem1($(this).attr('data-flat'), $(this).attr('data-description'));
                    });
                    $('#entriesflat').show();
                } else {
                    $('#entriesflat').hide();
                }
            })
        });
    });
}

both functions create dynamic listviews.

The getTitles function displays the buildings of a company while getItem displays the flats of the selected building.

I include alert(buildingcode); to find out the problem but I cannot understand what is the wrong.

The first time everything is ok. When I go back to getTitles and forward to getItem the alert displays twice... when I go back and forward the alert display 3 times and so go on 4 times... 5 times...

and all the code from this point repeated as the alert...

What is wrong?

Upvotes: 0

Views: 834

Answers (3)

Clarence Liu
Clarence Liu

Reputation: 4019

I believe you're placing your tags inside the div[data-role="page"] right? Since jQM pulls in everything in that div via AJAX your JS will all re-run whenever the page is loaded.

Even using live won't help if you're attaching multiple live events, the solution is to properly use jQM's pageinit event to run your code only once. Encapsulating event handlers is tricky, I suggest using the on event handler.

Anyways you can't just jump into jQuery mobile with no understanding about how jQM works, you're using document.ready and using global selectors which as you can imagine will blow up when you have several pages loaded in one DOM. look at a similar question here for a more detailed overview: https://stackoverflow.com/a/9085014/737023

Upvotes: 0

ShankarSangoli
ShankarSangoli

Reputation: 69915

I think it is the click handler using live. live attachs event handler on the document or body and listens to the selector which we pass. Whenever you call getTitles it will attach a new handler.

Looking at your code there is no need of using live just use click handler it will work fine.

Change this inside getTitles

    $('a', list).click(function(e) {
        getItem($(this).attr('data-trnote'));
    });

Same inside getItem method

    $('a', list).click(function(e) {
         getItem1($(this).attr('data-flat'), $(this).attr('data-description'));
    });

Upvotes: 1

Augustus Kling
Augustus Kling

Reputation: 3333

Your call to live assigns a new event handler on each call of your function. Remove your old handler before attaching the new one:

$('a', list).die('click');
$('a', list).live('click', …);

Alternatively, your should be able to use click instead of live.

Upvotes: 1

Related Questions