Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI: Re-initializing a function after loading content via AJAX

I've been searching all over for an answer to this question for a few days now, and while I have found most of the answer to my problem, there's still one piece of my code that is not working as it did before adding AJAX calls.

Some background: I am creating a web app to serve as an RPG character generator. One of the first things that happens is I create jQuery UI spinner widgets to adjust stat scores. On the stop event, my code runs a function that checks the current number against a switch case to set a value to how many points are added or subtracted from an initial pool (Point-Buy system, for anyone who knows about these things):

function calcPtsLeft() {

        var ptssum = new Number();
        var ptsmax = new Number($("#maxpoints").val());

        var pbstr = pointBuy($strsc.val());
        var pbdex = pointBuy($dexsc.val());
        var pbcon = pointBuy($consc.val());
        var pbint = pointBuy($intsc.val());
        var pbwis = pointBuy($wissc.val());
        var pbcha = pointBuy($chasc.val());

        var ptssum = pbstr + pbdex + pbcon + pbint + pbwis + pbcha;

        ptsleft = ptsmax - ptssum;

        $("#ptsleft").val(ptsleft);
    };

    calcPtsLeft();

This code functioned properly, up until I decided to use AJAX calls to dynamically load various pages into a #content div. After making the AJAX call to load my character generator, my widgets didn't show up at all. I found that this was due to a delegation problem, so I collected all of my widget initialization into a function:

function initGenWidgets() {

//sets CSS for input/label items from jQuery UI set 
$("#slider input:text, #slider label, #remaining input:text, #remaining label, #charName, #charAge")
    .addClass("ui-spinner ui-spinner-input");   

//initialize jQuery UI button widget
$("button").button();

//initialize jQuery UI radio buttonset widget
$("#genderbuttons").buttonset();

//initialize jQuery UI menu widget
$("#raceradio").menu();

//initialize jQuery UI vertical tabs
$("#char-gen").tabs().addClass("ui-tabs-vertical ui-helper-clearfix");

$("#char-gen li").removeClass("ui-corner-top").addClass("ui-corner-left");

//initialize jQuery UI spinner widget for age
$("#charAge").spinner({
    icons: {
        down: "ui-icon-minus",
        up: "ui-icon-plus"
    }
});

//initialize jQuery UI spinner widget for stats
$(".statspinner").spinner({
        min : 7,
        max : 18,
        icons : {
            down : "ui-icon-minus",
            up : "ui-icon-plus"
        },
        stop: function(event, ui) {
            calcPtsLeft();
        }
    });

//initialize jQuery UI slider widget for point-buy allotment
$("#pointslider").slider({
        value: 20,
        min: 15,
        max: 40,
        step: 5,
        slide: function(event, ui) {
            $("#maxpoints").val(ui.value);
            calcPtsLeft();
        }
    });
};

I now make the AJAX call as follows:

//function to load php files into content div
function loadContent($page){
    $("#content").load($page+' > *', function(response, status){
            success: initGenWidgets();
    });
};

//nav links load files into content div
$(".menulink").on("click", function(e){
    e.preventDefault();
    loadContent($(this).attr("href"));
});

Everything seems to load fine, but when I test the widgets, it seems that my spinners no longer execute the calcPtsLeft() function on stop. The slider works to update the #ptsLeft value after I slide it (going to fix that later), but the spinners do not update the value at all.

What am I doing wrong here, or not doing at all here? Any help would be greatly appreciated.

like image 219
amthomas2112 Avatar asked Jan 26 '26 16:01

amthomas2112


1 Answers

jQuery .load():

Script Execution

When calling .load() using a URL without a suffixed selector expression, the content is passed to .html() prior to scripts being removed. This executes the script blocks before they are discarded. If .load() is called with a selector expression appended to the URL, however, the scripts are stripped out prior to the DOM being updated, and thus are not executed. An example of both cases can be seen below

A small but important segment of the docs for .load()! If you really wanted to execute them, you'll probably have to do some sort of eval(), or discard the .selector

Example:

Here, any JavaScript loaded into #a as a part of the document will successfully execute.

$( "#a" ).load( "article.html" );

However, in the following case, script blocks in the document being loaded into #b are stripped out and not executed:

$( "#b" ).load( "article.html #target" );

Possible Solution

Well, after testing - I decided to actually take the step of adding the functions to the window, simply because it's the best way of carrying across functions & methods via many scripts. This, hopefully fixes have undefined functions being declared, because you're in a different script & namespace.

Main.php

<script>

    //Create Rgp Object
    var Rgp = {
       calcPtsLeft : function() {
            console.log( 'Calculate Points' );
       },
       addPoints : function() {
            //Some addPoints Function
       }
    }; 

    //Add Object to Window      
    window.Rgp = Rgp;

    $('#begin').on('click', function() {
        $("#content").load( 'someScript.js', function( response, status ){
            success: initGenWidgets();
        });
    });

</script>

someScript.js

<script>
function initGenWidgets() {
   $("#pointslider").slider({
       value: 20,
       min: 15,
       max: 40,
       step: 5,
       slide: function(event, ui) {
            $("#maxpoints").val(ui.value);
            Rgp.calcPtsLeft(); //Prints 'Calculate Points'
       }
   });
}
</script>
like image 108
MackieeE Avatar answered Jan 28 '26 06:01

MackieeE



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!