PUSHING MY LUCK -- Making KV's Side Image a Link [DONE!]

Greetings wanderer!

JS.eval ("$('body').append(\"<img id='AreaPicPane' src='" + GetFileURL(game.NewArea.AreaPic) + "' style='display:none;'/>\");")
JS.eval ("$('#AreaPicPane').insertBefore($('#statusVarsLabel')).show().width('100%');")

These two lines by KV display an image in the sidepanes, as per a previous thread:
http://textadventures.co.uk/forum/samples/topic/q5zedoe560au_ii73oamoq/adding-graphics-in-a-specific-location-gui-solved

To make the image a command link, the first line is added to, like so:

JS.eval ("$('body').append(\"<img id='AreaPicPane' src='" + GetFileURL(game.NewArea.AreaPic) + "' onclick=\"ASLEvent('HandleButtonClick', 'look');\" style='display:none;'/>\");")

HandleButtonClick ("look") is a simple function that calls a command. The problem with the above, adjusted line is the quotes around \"ASLEvent('HandleButtonClick', 'look');\" -- only double quotes or escape double quotes will work here; single quotes will not work. However, double quotes/escape double quotes throw a syntax error in the above line because they conflict with the double quotes/escape double quotes earlier on in the same line, thus confusing Quest. To get around this, the above line has been split up into two separate lines:

s = "<img id='AreaPicPane' src='" + GetFileURL(game.NewArea.AreaPic) + "' onclick=\"ASLEvent('HandleButtonClick', 'look');\" style='display:none;'/>"
JS.eval ("$('body').append(s)")

The problem here is that, for some reason, the image will no longer print. A msg (s) script will fix this, but will also trigger the known Quest bug that arises when something is printed from the Init UI tab upon reloading a saved game (which is what JS.eval ("$('body').append... fixed in the first place, i.e., it "magically" displayed the image without throwing the printing bug).

If you're still reading and understanding this, you must be KV or mrangel! How do I display the image and get the ASLEvent to make the link work, but without triggering the printing bug?


K.V.

Maybe change the 2nd line:

JS.eval ("$('body').append(\""+s+"\");")

K.V.

The way you have it, the s will be treated as a Javascript variable, which it isn't. It's a Quest variable.

JS VARIABLE (BAD): JS.eval ("$('body').append(s)")

QUEST VARIABLE (GOOD): JS.eval ("$('body').append(\"" + s + "\");")


s = "<img id='AreaPicPane' src='" + GetFileURL(game.NewArea.AreaPic) + "' onclick=\"ASLEvent('HandleButtonClick', 'look');\" style='display:none;'/>"
JS.eval ("$('body').append(\"" +s+ "\")")
JS.eval ("$('#AreaPicPane').insertBefore($('#statusVarsLabel')).show().width('100%');")

Hmm...the image is not displayed. I also tried single quotes here:

JS.eval ("$('body').append('" +s+ "')")

I tried replacing both instances of s with game.s -- no change.


K.V.

Hrmm...

Try this:

s = "<img id='AreaPicPane' src=\"" + GetFileURL(game.NewArea.AreaPic) + "\" onclick=\"ASLEvent('HandleButtonClick', 'look');\" style='display:none;'/>"
JS.eval ("$('body').append(\"" +s+ "\")")
JS.eval ("$('#AreaPicPane').insertBefore($('#statusVarsLabel')).show().width('100%');")

EDIT

The url will contain backslashes, so I changed the single quotes in src to escaped double quotes. (Fingers crossed.)


Unfortunately, no luckie. Amazing how this problem arises because of a mere inability to take single quotes around ASLEvent().


K.V.

Curses!

...and I bet your error in the HTML Tools console is completely vague?


Forgot that I could check that! It says:

Uncaught SyntaxError: Unexpected identifier


Try following through what each string is

s = "<img id='AreaPicPane' src=\"" + GetFileURL(game.NewArea.AreaPic) + "\" onclick=\"ASLEvent('HandleButtonClick', 'look');\" style='display:none;'/>"
JS.eval ("$('body').append(\"" +s+ "\")")
JS.eval ("$('#AreaPicPane').insertBefore($('#statusVarsLabel')).show().width('100%');")

So, the Quest variable s comes out looking like:
<img id='AreaPicPane' src="http://some.url.here/whatever.jpg" onclick="ASLEvent('HandleButtonClick', 'look');" style='display:none;'/>

so the Javascript code the borwser is trying to interpret is:
$('body').append("<img id='AreaPicPane' src="http://some.url.here/whatever.jpg" onclick="ASLEvent('HandleButtonClick', 'look');" style='display:none;'/>")

If you've got multiple levels of interpolation, you want multiple levels of escaping.

Off the top of my head:

JS.eval("$('<img id=\"AreaPicPane\" src=\"" + GetFileURL(game.NewArea.AreaPic) + "\" onclick=\"ASLEvent(\\'HandleButtonClick\\', \\'look\\');\" style=\"display:none;\"/>').insertBefore('#statusVarsLabel').show().width('100%');")

Then the line being evaluated by JS is:
$('<img id="AreaPicPane" src="http://some.url.here/image.jpg" onclick="ASLEvent(\'HandleButtonClick\', \'look\');" style="display:none;"/>').insertBefore('#statusVarsLabel').show().width('100%');
so the HTML it's adding is:
<img id="AreaPicPane" src="http://some.url.here/image.jpg" onclick="ASLEvent('HandleButtonClick', 'look');" style="display:none;"/>

(Note: HTML attributes should always use double quotes. Current browsers will mostly accept single quotes, but you shouldn't count on this behaviour)


K.V.

That works when I test it, mrangel.

Thank you! (I'd have never thought of trying double-escaping the single quotation marks!)


In some cases, jQuery object notation might result in less complex quoting. I don't know if it'll be easier here, but I can try it.

The JS would be:

$('<img>', {
  id: 'AreaPicPane',
  src: 'insert-url-here',
  onclick: 'ASLEvent(\'HandleButtonClick\', \'look\');'
}).insertBefore('#statusVarsLabel').width('100%');

or to avoid putting backslashes in at this stage:

$('<img>', {
  id: 'AreaPicPane',
  src: 'insert-url-here',
  onclick: "ASLEvent('HandleButtonClick', 'look');"
}).insertBefore('#statusVarsLabel').width('100%');

So the version you have in Quest would be:

JS.eval("$('<img>', {id: 'AreaPicPane',src: '"+GetFileURL(game.NewArea.AreaPic)+"',onclick: 'ASLEvent(\\'HandleButtonClick\\', \\'look\\');'}).insertBefore('#statusVarsLabel').width('100%');")

or

JS.eval("$('<img>', {id: 'AreaPicPane',src: '"+GetFileURL(game.NewArea.AreaPic)+"',onclick: \"ASLEvent('HandleButtonClick', 'look');\"}).insertBefore('#statusVarsLabel').width('100%');")

(Note: I removed the display: none style rule which hides the element before immediately calling .show() on it. I only looked at the last couple of posts in this thread, so don't know if there's some explanation earlier on of why you're doing that. You can put it back in if you prefer)

So... three options. Use whichever seems most readable to you.


@KV:

(I'd have never thought of trying double-escaping the single quotation marks!)

I'm not double escaping them.
There are two characters that need escaping in a Quest string to survive the transition to Javascript: A double quote, and a backslash.


I tried mrangel's first method -- it works, but the same printing bug on reload persists. How do you guys print something on game reload without triggering that bug?

You probably just clear the screen before you save, huh?


This line is "special" because it "magically" displays the side image without triggering the print bug on reload (splitting things up into 2 lines triggers the print bug again):

JS.eval ("$('body').append(\"<img id='AreaPicPane' src='" + GetFileURL(game.NewArea.AreaPic) + "' style='display:none;'/>\");")

How do I futz with the quotes so that I can add this bit to the above line:

onclick=\"ASLEvent('HandleButtonClick', 'look');\"

How do I futz with the quotes so that I can add this bit to the above line:

onclick=\\\"ASLEvent('HandleButtonClick', 'look');\\\"


Or do it later; after you've created the image, you could do:
JS.eval("$('AreaPicPane').on('click', function () { ASLEvent('HandleButtonClick', 'look'); });")

(not sure what the bug is that your line "magically" fixes; wouldn't putting it directly in the sidebar be less glitch-prone in any case?)


onclick=\\\"ASLEvent('HandleButtonClick', 'look');\\\"

That works! All 3 things work simultaneously -- the image displays, the image link works, and there is no printing bug on game reload. Haven't tried the second solution yet. So just keep adding escape backslashes until the code is accepted?

(not sure what the bug is that your line "magically" fixes...

The known Quest bug that is "magically" fixed is when you have any script that prints or does JS.addText placed in the Init UI tab -- it will work fine in a new game, but in a reloaded game, text will start printing at the beginning of the old text thread instead of at the end. I like to carry the old text thread over to a saved game instead of clearing it so that the player can see what he was doing before.

wouldn't putting it directly in the sidebar be less glitch-prone in any case?)

What I'm dealing with now is KV's adding a (secondary) image to the right-side panes. I think you are referring to the (left) side navigation menu that slides out -- sorry for the confusion, that was a different topic!

I will put out a demo of my progress thus far so that everyone can see all the work/contribution that has been put into this...


Second solution works too:

JS.eval ("$('#AreaPicPane').on('click', function () {ASLEvent('HandleButtonClick', 'look');});")

K.V.

I want to remember that issue with printing from inituserinterface being fixed...

Seems like mrangel fixed something with the divOutputAlign element count (or something like that).

Am I dreaming that? Or did the fix get lost during the update to 5.8?


K.V.

I was thinking of this, which was close:

http://textadventures.co.uk/forum/quest/topic/ik0dbblaq0o5fdqq7nuwia/js-function-to-find-the-last-divoutputalign-in-a-saved-game-solved#2909e2da-ec2d-4ac0-a169-74e958a4bbf9


This is the bit that seems to be throwing things off:

var _divCount = -1; 

function getDivCount() {
    if (_divCount < 1) {
        _divCount = parseInt($("#outputData").attr("data-divcount")) || 0;
    }
    return _divCount;
}

function setDivCount(count) {
    _divCount = count;
    $("#outputData").attr("data-divcount", _divCount);
}

And I am about to see if changing it to this fixes it:

var _divCount = -1;
if (typeof ($("#outputData").attr("data-divcount")) != 'undefined') {
    setDivCount($("#outputData").attr("data-divcount"));
}

function getDivCount() {
    if (_divCount < 1) {
        _divCount = parseInt($("#outputData").attr("data-divcount")) || 0;
    }
    return _divCount;
}

function setDivCount(count) {
    _divCount = count;
    $("#outputData").attr("data-divcount", _divCount);
}

If it works, it can't be added to a game, as far as I can tell. It will need to be in playercore.js to work.


K.V.

That didn't work.

Now I'm thinking it may have to do with the _outputSections variable...


Nope.


K.V.

The data-divcount attribute is either not being saved or it's being reset.

function getDivCount() {
    if (_divCount < 1) {
	console.log("data-divcount: "+$("#outputData").attr("data-divcount"));  // TESTING
        _divCount = parseInt($("#outputData").attr("data-divcount")) || 0;
    }
    return _divCount;
}

function setDivCount(count) {
    console.log("count: "+count); // TESTING
    _divCount = count;
    $("#outputData").attr("data-divcount", _divCount);
    console.log("data-divcount: "+$("#outputData").attr("data-divcount"));  // TESTING
}

Before saving:

playercore.js:699 data-divcount: 0
playercore.js:696 count: 1
playercore.js:699 data-divcount: 1
playercore.js:696 count: 2
playercore.js:699 data-divcount: 2
playercore.js:696 count: 3
playercore.js:699 data-divcount: 3
playercore.js:696 count: 4
playercore.js:699 data-divcount: 4
playercore.js:696 count: 5
playercore.js:699 data-divcount: 5
playercore.js:696 count: 6
playercore.js:699 data-divcount: 6
playercore.js:696 count: 7
playercore.js:699 data-divcount: 7
playercore.js:696 count: 8
playercore.js:699 data-divcount: 8
playercore.js:696 count: 9
playercore.js:699 data-divcount: 9
playercore.js:696 count: 10
playercore.js:699 data-divcount: 10

Saved game after loading and taking 1 turn (with msg in inituserinterface):

playercore.js:699 data-divcount: 0
playercore.js:696 count: 1
playercore.js:699 data-divcount: 1
playercore.js:696 count: 2
playercore.js:699 data-divcount: 2

Saved game after loading and taking 1 turn (WITHOUT msg in inituserinterface):

playercore.js:699 data-divcount: 0
playercore.js:689 data-divcount: 9
playercore.js:696 count: 10
playercore.js:699 data-divcount: 10

K.V.

Okay... data-divcount is being saved correctly. Here's the line in my saved file:

<div id="outputData" style="display: none" data-divcount="9" data-currentdiv="#divOutputAlign9"></div>

Hrmm...

Why does InitInterface call getDivCount?


K.V.

...and SOLVED?

If you add this code FIRST in your game.inituserinterface, the issue with adding text from that same script should not effect you ever again (hopefully):

// Edited
if (not game.timeelapsed = 0) {
  JS.eval ("setCurrentDiv($(\"#outputData\").attr(\"data-currentdiv\"));setDivCount(parseInt($(\"#outputData\").attr(\"data-divcount\")));")
}

If that works, should that go into the next beta?


K.V.

I'm still trying to make it break something.

...and I don't know that Pixie is inclined to add anything else until after the official release of 5.8. (In fact, I've promised him twice that I'd stop coming up with stuff, but... I am a code junkie.)


Anyway, try to break it with me. I'm going to modify the InitInterface function so this doesn't have to be added to game.inituserinterface and see how that works out.

I have added my code just after this line in InitInterface:

    JS.getDivCount ()

Here's my addition:

    // Added by KV to fix the issue when adding text from inituserinterface
    if (not game.timeelapsed = 0) {
      JS.eval ("setCurrentDiv($(\"#outputData\").attr(\"data-currentdiv\"));setDivCount(parseInt($(\"#outputData\").attr(\"data-divcount\")));")
    }

Testing it on your map game is the best test I can think of, and I've lost all my files during my recent war with the Windows 10 version 1803 update.


K.V.

This is working perfectly on my end. (I can even add the sidenav stuff in with a msg() in inituserinterface with no issues in a loaded saved game (no issues in a new game, either).)

How 'bout you, Dcoder?


NOTE

You still have to add a 2 second timeout to have anything actually show up in the divOutput element itself in a loaded saved game, but this was expected behavior. We must give Quest time to load the element first.


K.V.

I think that side image idea came from CheeseMyBaby, just to give credit where credit is due.


Wow, InitInterface is a long function. I guess I should install beta 8 first...


K.V.

I'm testing it from beta 8 on one machine and 5.7.2 on another. Works good in both, as far as I can tell so far.

(Finally got all the Windows updates installed! Whew!!! That only took TWO DAYS, and the only change I noticed was my desktop background was changed to BRIGHT PINK. Gee, wow, thanks for that kick in the groin after I was down! I picture someone at Microsoft saying, "ha! And THEN, we can change his desktop from Kate Upton in a bikini to a HOT PINK solid background. He'll be PISSED!!! Bwahahahahaha!!!"))


PS

It works fine in game.inituserinterface. I just added it to InitInterface in Core.aslx to save myself the trouble of always having to remember to add it to each new game.


K.V.

PPS

I sent Pixie a link to this, but it's easy to add to a game. Like I say, I really don't think he wants to add any more potential problems changes to Quest 5.8.0, even if they do seem to work well at first. (Of course, this is just me thinking, which admittedly hurts a little and usually exacerbates things for everyone involved.)


Preliminary testing -- messaging from Init UI, like you said, seems to work fine.

The only problem I noticed so far is that on game reload, after moving the player around a few times, my map game slows down tremendously, like the game's resources have been stretched thin or something. Doesn't happen in a new game.

I can send you my latest game update if you want...

...and I don't know that Pixie is inclined to add anything else until after the official release of 5.8. (In fact, I've promised him twice that I'd stop coming up with stuff, but... I am a code junkie.)

I can just hear Pixie telling you to "STOP FIXING STUFF!" :D


K.V.

That lag was from my GridImageLib stuff. (I fixededed it.)


Well, I have finished a new version of my Map Demo replete with all of the new features that you guys have helped me out with. As soon as the webplayer is updated from 5.7 to 5.8 (which might be a while), I will upload my demo and share!


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums