Nested Dynamic Panel in Repeater with Repeater Item Interactions - Unexpected Behavior

Hello, I am new to the forums but not to Axure. I am however new to the Repeater widget and am learning how to use it.

I work for a company creating a web platform for processing medical payments. In our prototype, the user can click an icon to upload a file. Each uploaded file is represented by a thumbnail icon. The user can arbitrarily delete one of the uploaded files by clicking “remove” beneath the icon, which should delete the row from the repeater, removing the file preview thumbnail and adjusting the other icons to fill the space dynamically. The last row of the repeater is always the upload icon (add a new file).

The initial view is an empty dataset. I am using this code on the Repeater Item Interactions:

if "[[Item.isLast]]" equals "1"
Set Thumbs to State 1
Else If True
Set Thumbs to [[Math.floor(Math.random()*10)+1]]

This checks to see if the current row is the last row, and if so, sets the dynamic panel to the upload icon. If not, a random thumbnail icon is selected to represent an uploaded file.

Before the “file” is “uploaded,” I’m also throwing up a dummy lightbox file selection dialogue. Because I only want this to occur when a file is added, not removed, I’m using a global variable called Unset.

I have two problems - firstly, none of this works very well. The repeater occasionally sets the dynamic panel to State 1 (file upload) even if the row is not the last row in the dataset. Also, when a file is deleted, sometimes it works correctly, and the other files remain unchanged. Other times, the existing files randomize. The lightbox will show up once when a file is removed. Then on subsequent removals it will not show up.

The other issue is that in this prototype, which is a 7 step submission process, the user needs to be able to revisit a page in order to see the values entered. So I need to store the selected files in a global variable on page exit, and populate the repeater from this variable on page load. I have no idea how to do this!

I’m attaching the file for reference. I appreciate any help or pointers. Thanks!
Prototype.rp (2.32 MB)



i would rather use a panel with two states and different functions (add/remove) instead of the variable, but i think that is a question of taste.

you seem to come from the visual basic edge. if you are also familiar with javascript you might find some information here repeater data like global var and here https://github.com/itorrey/EpiPen/tree/global_repeater

it is not possible to populate the value of a repeater from one page to an other. it is not possible to build arrays in axure, it is not possible to dynamically produce global variables.

it is possible to use javascript. in javascript it is possible to write any value to a global var. to read a global variable in javascript axure has to be hacked (getGlobalVariable looks like a public function but it is not) the javascript injector from @ColinB Ever wanted to add a RegEx to your prototype? Here’s instant embedded AxQuery and JavaScript without header files/plugins. has this code included.

if you dont want to use the library from Colin you will need this:
$axure.internal(function($ax){
$ax.public.getGlobalVariable = $ax.getGlobalVariable = function(name) {
return $ax.globalVariableProvider.getVariableValue(name);
};

please take in reconcideration, that the two approaches in the make repeater global are completely different. the first approach uses axure functions to manipulate the repeater from javascript, the second one takes the complete repeater data and copies it to an other repeater (it stays on one page, I wanted to extend this example but i dind’t find the time).

hmmm… what else do you might need to know. you might want to cause an event in axure if javascript finished something…
i usually use the onMove event: $axure("@widget").moveBy(0, 0, {}) this @xyz is called axquery. it can be used to access axure widgets from javascript. the second way is the data-label: $axure("[data-label=widget]").moveBy(0, 0, {})

Hi Gregor, thanks for your reply. My first problem though is that my existing code doesn’t work. The repeater occasionally sets the dynamic panel to State 1 even if the row is not the last row in the dataset. Also, when I delete a row, sometimes it works correctly, and the other rows remain unchanged. Other times, the existing rows randomize. I can’t figure out why the entered dataset doesn’t stay fixed when I delete a row. Unless… is OnItemLoad called on every row every time the repeater dataset changes? If this is the case I guess I would have to change my approach entirely. But this doesn’t make sense to me.



you try to place all the logic to the repeater onItemLoad event.

+.onClick(){this.mark; lightbox.show}
-.onClick(){this.remove}

lightbox.onClick(repeaterMarked.update(random);repeater.addRow(blank); lightbox.hide)

will make your life easier.

Thanks. I have incorporated your suggestions but the problem persists.
Untitled.rp (1.14 MB)

have a look here.
Untitled2.rp (65.4 KB)

Wow! Thanks so much. I was digging around the forums and I came across this:

Iterating through a repeater and updating rows

Every time a row is added the filter reloads and OnItemLoad fires for each item.

This is why my original approach did not work. I assumed that when a new row was added, OnItemLoad would fire for that item only, because the other rows were already loaded.

As for making the selections persistent, I guess I need to look into a javascript solution. I have experience with JS but mainly implementing existing code in PHP. Is there example Axure file somewhere that shows how this works:

  1. Initial state on page A, empty repeater
  2. User adds/removes rows
  3. Data is stored in Javascript array
  4. User clicks “save,” navigates to page B
  5. User returns to page A
  6. Javascript array is retrieved
  7. Repeater is populated with saved values

?

Thanks again Gregor for all your help!

as i said i didn’t have a closer look to the solution. i guess that saving the EpiPen solution data to a global variable could make it acessable to an other page.

in the example/js/repeater.js could be solution.