Using Javascript

Hello. I’m new to Axure and I’m trying to solve a problem using javascript. This may not be the best way so please let me know.
I’m trying to make a somewhat flexible prototype where I need to cycle through several images that are hosted in google drive.
My main question is if it’s possible to change / set the image of an image widget using javascript. I’ve got a javascript file that loads great and it has an array of the links to the images. I’d like to set all of the images via this array when the page loads.
Is this possible? Is there a better way to do this in Axure? I know I could probably manually set the images to links (haven’t tried that yet) but doing that feels less flexible then I think I’d like. I predict needing to expand and change the links frequently and that seems easier / better in the js file.
Thanks!

Any reason you can’t just download the images and import them into Axure? That would be much, much easier.

Yes. Change the value of the src attribute of the image tag.

How do I access a widget and its properties in javascript? Or are you saying I’d change the src inside of Axure?

You’re not accessing the widget, you’re just doing regular old vanilla DOM manipulation.

Assuming your image widget is named myImage:

document.querySelector('[data-label="myImage"] > img').src = '/new/image/path'

You said you have an array of URLs, you could add a bunch of image widgets named myImage and do something like:

var urls = ['url1', 'url2', 'url3']
var imgs = document.querySelectorAll('[data-label="myImage"] > img');
// I'm assuming you've placed as many image widgets as you have URLs in your array
// If you don't have enough URLs, you'll just get some blank images
imgs.forEach((img, i) => {
  img.src = urls[i]
})

thanks for the help! unfortunately I’m getting an error in the console when I try to run the above for even just one image (not using arrays). Any ideas on why?

Uncaught DOMException: Failed to execute ‘querySelector’ on ‘Document’: ‘[data-label=“myImage”] > img’ is not a valid selector.
at loadImage (:1:5381)
at :1:1

Those are “smart quote” in your code there. Note the difference:

“” vs ""

Were they present in the code you entered? It could just be the forums doing the formatting too.

Paste exactly the code you entered. What browser did you use?

I think I got the above error sorted out but the image doesn’t update on the page. The src url is correct (unless I can’t do this using an external URL and the image has to be local?).

Here’s what I’ve got:
function loadImage() {

var el = document.querySelector('[data-label="myImage"]');
console.log('src pre : ' + el.src);
el.src = 'https://drive.google.com/file/d/1woV2imW5Jcz5Vf1sMB4wSWgM-zgUwdD-/preview';

}

I don’t get any errors but the widget doesn’t update. I’m currently calling this OnClick and I’m using a standard Image widget.

I’ve run into the issue before with the quotes. Which version should I be using? I’m using Chrome.

Here’s the problem: '[data-label="myImage"]' is the div containing the img, so you’re setting the src attribute of the div, which does nothing. That’s why my selector specified a direct img descendent of the element with the data label. If you add an image in Axure and look at the generated markup you’ll see this. You need to directly modify the img element, but to target it we need to select its parent (which has the data-label we can select on) because the id of the img is not static in the generated markup.

Regarding quote: you should be using regular single or double quote:

' or "

if you’re using a text editor, make sure its plain text. TextEdit on Mac should be fine as well as Notepad on Windows.

As for double versus single, it doesn’t really matter until you’re nesting quotes within quotes.

If you use the correct selector and resolve the quote issue I think you should be good to go.

Here’s more info on different quote characters: https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html The first two are what you want.

A couple things:
I’m using VsCode and then pasting from there directly into my script in Axure. It loads the javascript fine.
I made sure I’ve got all the regular quotes (double and single) not the ”smart quotes”.
I’m running my preview in Chrome and I’m back to getting an error when I try the following:

function loadImage() {

document.querySelector('[data-label="myImage"] > img').src = 'https://drive.google.com/file/d/1woV2imW5Jcz5Vf1sMB4wSWgM-zgUwdD-/preview'

}

Based on this from the chrome console, it should be working to find the element right…
<div id=“u21” class=“ax_default image” data-label=“myImage” style=“cursor: pointer;”>

<img id=“u21_img” class="img " src=“images/vocab_questions/myimage_u21.svg” tabindex=“0”>

<div id=“u21_text” class="text " style=“display:none; visibility: hidden”>

<p></p>

</div>

</div>

I tried exactly what you pasted here and it works fine (well except that Google Drive is blocking the image from loading, but that’s a separate issue).

I can’t see anything obviously wrong with what you tried and it works for me. Are you getting exactly the same error that you posted previously?

yes. Same error. It seems querySelector just seems to not want to work. It may be with how I’m loading in the javascript. I’ve been reading a lot about using javascript in Axure but I’m still fuzzy on how to “load” javascript. Anything you’d recommend? I currently found a tutorial project and have modified that a bit for using javascript but I’m wondering if I should just start from scratch. How would you recommend getting started with some basic javascript in Axure?

Thanks again for all your help!

See if this works for you: img-replace.rp (45.3 KB)

Load the preview then click the image widget.

What version of Chrome are you using?

It Works!!! Thank you so much!
I’ll take a look at the two projects and see where I’ve gone wrong.

One thing I’m struggling with is figuring out how best to make use of javascript in axure. Can I have a single widget with my script in it and several functions? I think that’s where I’ve gone wrong. I’m wondering how I correctly set that up in Axure. Would you suggest having a widget and OnLoad or OnClick it runs “javascript:void(
my script here
)”?
If so, what’s the syntax for that? Do I have to include the tags?
As I’m sure you can see, I’m new to all this.

Thank you!

Mostly we’re not loading and running the script when the document loads like you would expect if you had added it with a <script> tag, as one would normally do. We’re actually running the the script using the javascript: URL scheme (the same way bookmarklets work).

You can do this from anywhere in Axure, it really doesn’t matter. Anywhere you could put an Open Link action you can do so.

The reason I wrapped it in a call to void() is that Firefox doesn’t like it when whatever you called returns something other than null. You can also just tack throw new Error() on the end to interrupt execution as well to prevent Firefox from replacing your page with just “[Object object]”. You’ll have to use the latter method if you’re using more than one statement that can’t be passed to void().

If you want to define these functions ahead of time, do so in a widget’s OnLoad event so that when you call them from elsewhere they’re already defined.

Do post again when you figure out what was wrong, I’m very curious :slight_smile: My theory is that your OS is replacing the quotes with smart quotes in Axure when you paste it. VSCode would (rightly) not allow that.

So where I’m still confused is with the javascript URL scheme and how I can use that to call other functions. For example, this demo project I’ve been messing around with has a widget called “script” where several functions are defined. I can then use the OpenLink action on any widget to call that function using “javascript:function();” When I try recreating this in my own empty project, the widget doesn’t see the functions. I’m obviously missing something crucial.

Here’s the javascript portion from the sample project I’ve been trying to learn things from.Axure Javascript Engine Only.rp (53.0 KB)

Ah, this old beast. As far as I know it works, but I’ve never used it myself. It does some behind-the-scenes action to take the script you enter and execute it. I can’t tell you how it works or whether it does. Conceptually though, what you want is perfectly achievable using the method I mentioned above. For example, on one widget:

OnLoad
Open link: javascript:void(function myfunc(){alert('hello')})

And on another widget:

OnClick
Open link: javascript:void(myfunc())

Just make sure the definition comes before the call.

Thank you so much for taking the time to help me out! I love learning new things by just diving in and pulling from various sources and people like you that take the time to help out are GREAT!

I’m not sure what, but I must be doing something crazy wrong. I can’t get the above to work. I’ve tried typing, I’ve tried copying and pasting what you wrote above. I get an error saying the function isn’t defined. That’s the part I always run into. How to make the function call available.

img-replace v1.1.rp (47.3 KB)