Vaia Vaia - 1 month ago 10
Javascript Question

JavaScript doesn't recognize my function when loading content async?

I want to have a "read more"-click function on a text. I'm dynamically loading a Wikipedia text for a specific keyword and have this function:

function setText(text, lang, full) {
setTimeout(function () { $('#loading').fadeOut('fast'); }, 300);
var mylang = '<?= $_SESSION['lang']; ?>';
if (mylang != 'en' && lang == 'en')
var AppendText = '<span class="db f09 grey mt10"><?= __('TEXT_ONLY_ENGLISH'); ?></span>';

console.log(lang);

if (full) {
$('#text').html('<?= __('EMPTY'); ?>');
setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
} else if (text) {
// Full Text
function fullText() {
console.log('yes');
setText(text, lang, 1);
}

text = text.length > length ? text.substring(0, length - 3) +
'... <a class="cp" onclick="fullText()"><?= __('MORE') ?></a>' : text;
$('#text').html(text).append(AppendText);
setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
}
};


As you can see in the
else if
part I defined the
fullText()
function set to onclick on the anchor tag. I always get the message
fullText is not defined
when I click on it.
I just want to re-call the same
setText()
function with the variable
full
set to
1
, so the full text will be displayed instead of


Sometext... (more)


Is this possible without using
ajax
? What options do I have?

PS: I also already tried calling
setText()
itself instead of
fullText()
but that won't be recognized as a defined function either.

Answer

With the onclick attribute you can only reference functions that are in the global scope. To get around this, you can attach an event handler dynamically instead of using the onclick attribute.

To get that done, I would suggest some changes, that lead to the following code:

function setText(text, lang, full) {
    setTimeout(function () { $('#loading').fadeOut('fast'); }, 300);
    var mylang = '<?= $_SESSION['lang']; ?>';
    // change 1: define an element with jQuery 
    var $appendText = $('<span>');
    if (mylang != 'en' && lang == 'en')
        $appendText.addClass('db f09 grey mt10').text('<?= __('TEXT_ONLY_ENGLISH')?>');

    console.log(lang);

    if (full) {
        // change 2: use text(), not html()
        $('#text').text('<?= __('EMPTY'); ?>');
    } else if (text) {
        // Full Text
        // Change 3: define link as jQuery element:
        var $link = $('<a>');
        if (text.length > length) {
            text = text.substring(0, length - 3);
            $link.addClass('cp').text('<?= __('MORE') ?>');
            // Change 4: attach click handler here:
            $link.click(function fullText() {
                console.log('yes');
                setText(text, lang, 1);
            });
        }
        // Change 5: append these jQuery elements, which can be empty:
        $('#text').text(text).append($link).append($appendText);
    }
    // Change 6: move this out of the if-block, as it is the same for both cases:
    setTimeout(function () { $('#text').fadeIn('fast'); }, 500);
};

Note that you did not provide the definition of the variable length, but I assume it is available to the function.