Ever wanted to add a RegEx to your prototype? Here's instant embedded AxQuery and JavaScript without header files/plugins

advanced-prototyping

#1

Thanks to Paul, iTorrey, Gregor, nkrisc, zeroskillz, and a number of other intrepid Axure hackers, I was inspired to put together a prototype that allows for dynamic JavaScript and CSS injection from within the prototype. Instead of using AxShare plugins and includes, you can just drop in functions written with AxQuery, jQuery, and JavaScript that you can immediately call with your widgets and events. No extra files, no need for AxShare, and you don’t even have to edit a single generated file.

It looks like this:



All you do is drag the “JavaScript Engine” master into a page, hide the “JAVASCRIPT ENGINE” widget OnPageLoad, and edit the text in the shape with whatever code you want. You can then use Axure events to call any JavaScript functions you’ve written with Open Link, using “javascript:functionname();”.

As a bonus, I added CSS injection as well. The attached .rp has both a page of examples (including live phone number validation via regular expression) and a base template that you can duplicate and modify for your own use.

Feedback is welcomed!

UPDATE: Modified the JavaScript injection so “<” and “>” don’t break the code. Using .html() and other code injections should now be much easier. Also, starting the engine now only requires that you hide the widget “JAVASCRIPT ENGINE” in OnPageLoad.

ANOTHER 1.02: I’ve attached the entire thing as an Axure Library as well. Just add the library, then drag the “Javascript Engine” widget onto any page you want JS on. Hide the JAVASCRIPT ENGINE widget and you’re good to go!

UPDATE 1.03:
CSS can be auto-applied to widgets now. Make sure “Apply on load” in the style panel is checked and any widgets with classes in the name, e.g. “email field .highlight” will have the appropriate classes added on load. (Note: this means your widgets will have weird names, which makes AxQuery a little more unwieldy - if anyone knows a way to update widget names from AxQuery, I’d love to hear it so I can cut the class names out after it generates)
The library now includes a “Hidden engine” widget that is included in a 40x40 hidden DP so you can add it to your page without cluttering the view as much.
AxQuery and JavaScript 1.03.rp (91.8 KB)

AxureJS 1.03.rplib (87.7 KB)


Is antialiasing possible?
Prefilling of some fields
External Javascript not working properly on macOS - timing?
How to get RichText of a component?
#2

this is amazing! great job!


#3

Wow! I am very surprised that writing functions as text in widgets would just… work like that. Very crazy!


#4

This looks awesome, going to play around with it.

I’ve seen other approaches that work but this looks like the simplest for the user.

EDIT: Looked into what you did, very clever!


#5

Thanks! I had an epiphany this morning to structure the entire thing as a drag-and-drop master so you can literally drag JavaScript into a page and activate it with a single action to keep your OnPageLoad handler clean. Feel free to hammer it with whatever you got and let me know if anything doesn’t work.


#6

Super awesome! Can’t wait to play with it!

Colin, is it possible to load and execute multiple JS functions from a single text widget?

light_forger


#7

Thanks!

Technically I don’t believe there’s a way to run more than one function per event, but you can always just write a function to encapsulate everything into one action.


#8

Hey ColinB,

Thanks for the reply. What I meant was, can the widget holding the text, have the definition of more than one function. That is, I am wondering if you can push this technique via set/get methods, nested functions, etc. etc.

As for calling them, I agree that you will have to probably stick to one. However, you gave me an idea of chaining functions e.g., function1() fires, but within its definition it calls function(), so on and so forth.

Furthermore, (can you tell I am in uber geek mode here :slight_smile: ), it would not be far fetched in calling the function, to pass parameters which come from local and global variables. The possibilities are truly endless!

light_forger


#9

Sorry, Svetlin, I misunderstood. The widget can absolutely hold more functions. The sky’s the limit. What’s happening is that when you hide JAVASCRIPT ENGINE, it inserts a <script> tag into the page and copies the widget text into it (along with a quick hack to fix global variable access and some cleaning up to escape quotes, etc.), followed by a <style> tag that copies the CSS widget into it. It’s pretty straightforward. So far I’ve done tons of crazy things with it. The examples I’ve made so far include:

[ul]
[li]Autoplay a local video file when it’s scrolled into the view and pause when it leaves
[/li][li]Copy parameters from the URL on load (only works without sitemap due to security issues in Chrome)
[/li][li]Validate text with a regular expression and add CSS classes to the field upon error
[/li][li]Embed YouTube as Flash or HTML5 and provide mouseover play/pause and near-complete access to the YouTube API
[/li][/ul]

I’m also working on making a drag-and-drop YouTube widget that lets you just drop a small widget group onto your prototype, resize it, and edit the text to specify which video and what parameters you want. It’s going to be an experiment in encapsulating the entire JS engine in a widget group. It may or may not turn out, but it’ll look something like this:

The .rp file attached to the first post has a page of examples that show a few basic tricks too. I can also provide any of the above if you like.


#10

Awesome job. This opens a whole new door of possibilities! I still can’t believe this approach works!

On an unrelated note, I am working on something JS related, and was trying to find a method in the many APIs the language offers that checks if one <div> is stacked on top of another. I am not merely trying to figure out if the z-indices match. I want to find out if the surface of one <div> covers another (both are of the same size).

One method that comes to mind is to check if the obj.style.left and obj.style.top match for both <div>s. Are you aware of another method? That and I have to figure out how to convert this to AxureQuery. I am thinking:

[i]if (($("[data-label=div1]").css(“left”) == $("[data-label=div2]").css(“left”)) && ($("[data-label=div1]").css("
top") == $("[data-label=div2]").css(“top”))) {

// do awesome stuff e.g., set z-index of one to a different value

}[/i]

That assumes the <div>s are absolutely positioned, and I don’t know how Axure currently handles this on the back end. Any leads would be helpful!

light_forger


#11

As far as I can tell, your approach should work if you’re looking to check whether two same-size panels are in the same exact location. I don’t think there’s anything in JS, jQuery, or AxQuery that does that explicitly.

I’m still trying to find the exposed methods in AxQuery, so I can’t say exactly what lets you access the x and y coordinates yet. I rely a lot on $axure(’@widgetname’).jQuery() to access those sorts of things.

Note that if you’re using this JS engine, double-slash comments will break it. I’m not sure why yet, but I’m hoping to track it down.

(P.S. - new update to the JS Engine lets you automatically apply CSS styles to widgets by naming them things like “widget .highlight .shadow”)


#12

Hey ColinB,

Thanks! As per your comment, I noticed there are 2 objects: one is $axure and the other $ax. My guess is that $ax is for the internal API since many of the .js files in ‘resources/scripts’ (of the generated proto) have function calls referencing it. I am not sure if the $ax function can be exposed at the user level (see events.js for example).

In regards to your ‘$axure(’@widgetname’).jQuery()’, I am assuming that you can then start chaining function calls after the ‘jQuery()’ part e.g. …‘jQuery().css()’

Didn’t know that // broke. I guess /* comment */ should work.

By the way, I found this API | Axure, but it seems to be targeting the documentation process only.

light_forger


#13

As far as I can tell, yes. $axure is publicly exposed and $ax is internal. I can’t remember half of the weird experiments I’ve run to try and probe the API.

Yes, you can chain functions after .jQuery(), as it returns the jQuery object for the div of the widget. You could do $axure(’@widget’).jQuery().attr(‘html’).replace(‘apple’,‘banana’).replace(‘hot’,‘cold’).substring(0,12) if you wanted. It’s pure jQuery and JavaScript from there on out. It’s often useful to assign it to a variable so you can quickly use varname.attr() and so on.

I would LOVE to have a proper API documentation for AxQuery, because right now I’m trying to find out how to programmatically change the name of a widget in a way that sticks. It’s easy enough to change its data-label attribute via jQuery, but AxQuery seems to have indexed the object by its original name anyway. If I have a widget called “apple” and I use jQuery to change its data-label to “banana”, $axure(’@banana’) won’t work, but $axure(’@apple’) will. It’s frustrating.


#14

Nice Job. Including the “Bugfix” for public.function.getGlobalVar is really nice.
JavaScript always need a lot of testing in Axure. I did a “JavaScript-Playground”. Absolutely simple, just executing the code in the field on unfocus. I use is a lot when i try to make things work… No need to rebuild the prototype… while testing.

It does not include the bugfix… $ax.getGlobalVar will not work here. It might be useful in combination with your $head.append() solution.

Enjoy.
js_testing_2share.rp (60.6 KB)


#15

Thanks, Gregor. That’s a good way to test quickly. JavaScript in Axure tends to be pretty finicky, so this will help. Now I just wish there was a way to autoformat my code like a good IDE would so I can keep track of my brackets and parentheses.

May I include your quick tester as a widget in the AxureJS library, with credit to you?


#16

of course you can add it. whatever i share here is free to use.


#17

js.rplib (61.1 KB)you can also add this one…


#18

Thanks! I was thinking about adding header file injection as another feature. I’ll probably do something similar to your approach, only separated to have one each for the JS and CSS sides.

(I also realized from your tester that the DP has an OnLoad event which I can use to automatically launch the JS widget! Double thanks!)


#19

Hi Colin,
that is a great approach!
Unfortunately the regex functions for phone number do not work when I download your example file. I tested it in FF 31 and Chrome 38. Any ideas why they don’t work?
The other functions work fine.


#20

I’m not sure why it isn’t working. I just now downloaded and tested in FF 33 and Chrome 38 and it worked fine in both. Did you change any global Axure settings to something other than default? I really don’t know what would cause it to fail when the other functions work fine.