External Javascript not working properly on macOS - timing?


#1

I’m firing an external javascript call via ‘open link’ , on each repeater item loaded.

Works great in windows on chrome, ie, firefox, but on MacOS (Safari, Chrome, macbook & iphone) the javascript only seems to fire on the last item in the repeater.

If I add in a huge wait state before the JS (like about 8 seconds) it seems to work properly, so seems like a weird timing issue.

Any way around this please? I can’t have this huge wait state.


#2

Might depend on what you’re calling with your javascript, but I would recommend using the repeater’s Loaded event instead of Item Loaded. When you point to a widget in the repeater cell in this way (anywhere external to the repeater cell or Item Loaded) it should affect all row’s instances of that widget.

If you need to do this after the initial page/repeater load (adding, removing, updating, sorting, etc.) then try placing the javascript call from a widget outside the repeater (maybe a blank dynamic panel with a Moved or Rotated event or even Click or Tap --could be any widget, the key is it can’t be hidden–although you can place it out of user view: opacity at 0%, behind another widget, inside a fixed-size dynamic panel but outside that dp’s viewable dimensions, etc.) Think of this external widget-event as a “function call”. You can use a case in the Item Loaded that tests "If [[Item.isLast]] equals “true” (or maybe with Mac you don’t need this as seems like it happens anyway; but if it is run on non-Mac systems it will be more reliable with the [[Item.isLast]] case.) So, from this last Item Load fire an event of that external widget to trigger the javascript call. Again, the approach is to call your javascript once per repeater “update” and not once per row update.


#3

Thank you very much - definitely gives me some great things to try.

My repeater is for a grid of products, (one product per repeater row). Each product has up to 5 color swatches which are displayed.

The javascript I’m firing parses a hex value from the repeater column (ex: color2) and then sets the background color directly on the element (it then does this for the remaining colors on that row).

If I call the JS from outside the repeater or on the loaded event, is there any reliable way I can ensure the correct colors will get assigned to the correct elements? Once the entire repeater has rendered all the color swatches have the same ‘data-label’ from one product to the next.

thanks again so much for pointing me in the right direction here, I’ll do some more testing as it’d be great to get this figured out so it’s reliable on Mac.


#4

Ugh… I don’t think my recommendations will work then… They actually rely on doing the same thing to all rows identically, at least in terms of function.

This is kind of getting into where prototype and “real app” blur. Also maybe getting stuck on one way to do something perseverating on why the H it won’t work the way it should work, etc. Maybe worth stepping back and reevaluating priorities of what you really need to achieve. Is it really showing exact colors or responding to catalog updates of colorways, or is it just about getting across the concept that different products can have different color sets, or those color sets can be updated? In other words, what is the least amount of work you can do to communicate or spec or test–whatever it is–with your prototype.

So some other approaches…

  • Abandon the repeater and just use straight widgets. Yes, more overhead and maintenance, but should be faster to load and respond. Might be worth it if your priority is exact color values, speed and consistency across platforms.
  • Create a dynamic panel in your repeater for the color swatches (or 5 dynamic panels per row) and manually set the color swatches. Then in Item Loaded set the proper dp state per color.
    • You could even name the states with same hex values that would be in your “color” column(s) for easy “Set Panel State to [[Item.Color]]”
    • You could run your existing proto, take screenshots of the right color swatches and just plug those images into your dp states.
    • I’ve had pretty good performance with similar dp in a repeater with 30+ states, each with a different icon/color.
    • Maybe you could “fake” your colors so instead of say, 120 different color values you can get away with 10 reused…

If you decide you need to pursue javascript, some ideas…


#5

This is awesome info, thanks so much! We’ve done exactly that for now - ditched the JS that could accept any hex value and instead using a smaller set of predefined color elements within Axure.

For posterity, the JS was setting all colors in one call - I only mention that in case it helps someone else in the future.

Greatly appreciate the advice on the other methods of injecting JS. I’d even be ok with the plugin approach.

Kind of unrelated, but I’d be curious to get your take if you don’t mind please - is there any particular Axure approach you’d take if trying to treat products in an ecommerce store as objects? i.e. your category page has multiple ‘product’ objects. You want to customize one, it passes the object to the customize page. Add to shopping cart, it passes the objects you’ve carted to the cart.

The way I approached this was with a large set of global variables for each product that stored all the attributes (price, size, color etc.) and then sets of temp variables that I populated to store info between pages in the flow.

If repeaters could be accessed across pages and written to, that would be a nicer approach but would welcome any other thoughts or ideas no matter how much of a long shot.

thank you again!


#6

Yes, the only way you can pass data between pages is via global variables. (Although RP10 is supposed to support external databases which sounds promising. I just haven’t had time to test out the beta yet.)

So, to get repeaters to share data across pages, it needs to be done with global variables. You could create a variable for every column, for instance. To “pass” changes, like objects in a cart you can set/update global variable(s) on a “shopping page” and then on a cart or checkout page, use the Page Loaded event to update/add rows using the global variable(s) values.

For repeaters, you can use a hash method to build one global variable with values from multiple rows, then parse it on the second page. See this thread for an example:


#7

That’s a neat technique, thank you for sharing!