Persist Repeater cell / row content when adding a new row

Hey folks,

I am new to Axure and especially Repeaters, started two weeks ago so please bear with me.
It’s downright an amazing tool so far but I haven’t quite managed to make the content of each row (or cell) in a repeater maintain its content.

Here’s what’s going on (prototype attached):

  • I am using a button to add new rows to the Repeater
  • I am keeping a record of the number of rows through a global variable ‘repRowCount’. OnPageLoad it is initialised with 1 because there is 1 row on the Repeater by default
  • when the button is pushed, the global Var get updated with [[LVAR1.itemCount]] where LVAR1 is the repeater widget
  • I am using the Repeater as a bit of a layout component in such a way that it pushes down the content below. Hence the clunky workaround when adding a new row. I hide the Repeater, then add a row, and then show the Repeater again. This seems necessary in order to be able to push content below.

So hopefully you can nudge me into the right direction of making row contents persistent. I am aware the every time I add a row, the entire Repeater refreshes/reloads.

Thanks a lot
PersistRow.rp (56.8 KB)

Btw, I posted this in Axure RP 9 because that’s the version that I currently have to work with. My client is planning on upgrading soon, though, so I’d be happy to see an Axure RP 10 solution, as well :slight_smile:

First off, welcome to Axure! Congratulations on trying to tackle repeaters–they are powerful but probably take the most time to learn of any Axure feature. You can refer to the Axure RP9 Documentation for Repeaters, and search this forum for specific repeater questions–you’ll find tons of posts.

If you want data to be persistent in a Repeater, you need to have columns to store this data in your repeater’s datasheet (see the DATA section in the STYLE panel when your Repeater widget is selected.)

In your example, you’d probably want a column for Name (or separate columns for “GivenName” and “Surname” which could be concatenated) and a column for the “Type” list selection. Typically with lists like this, the entry form–text field, droplist, and “Add Owner” button–would be outside the repeater; or one row (usually first or last row) serves as a “data entry” row, including the “Add Row” button. When the data entry is inside the repeater but the “submit button” is outside the repeater, it just won’t work (or the code to make it work would be so unwieldy it wouldn’t be worth it.)

See Page 2 of this updated RP file
PersistRow.rp (84.7 KB)

  • I moved the input fields outside of the repeater
  • Inside the repeater, I changed the text field and droplist widgets to rectangles
    • If you need to edit rows in the repeater, you can keep these as text fields, or create a dynamic panel with 2 states: one for read-only and one for editing. Create an Edit button in the repeater row to change states …or maybe just clicking on the read-only row could change states. In the edit state you could add an “Update” button for the user to submit the edits and change states back to read-only.
  • The repeater datasheet has three columns
    • Name
    • Surname
    • Type
  • Look at the repeater’s Item Loaded event to see how the rows get built
    • The data in each column is available via the repeater’s Item variable
    • Set Text row_person to "[[Item.Name]] [[Item.Surname]]"
    • Set Text row_type to "[[Item.Type]]"
    • I also added a conditional case to set the count value for “Amount of owners” so that when the last row of the repeater is loaded it uses the repeater’s built in .itemCount property to report how many rows (owners) are present. This makes your counter automatic and you don’t have to try to calculate it via global variable and in several different actions/places (Add Owner button, delete row buttons, etc.)
  • I demonstrate another method to automatically move content below the repeater. I came up with this years ago to avoid “clunkiness” for growing repeater lists or any content that changes size
    • I wrapped the repeater in a dynamic panel (right-click the repeater, choose Create Dynamic Panel)
    • (I kept the default style option for dynamic panels of “Fit to Content”)
    • I grouped everything below the repeater (group named “Data Entry Group”)
    • I added an interaction event, Resized with action to `Move Data Entry Group to ( ,[[This.bottom + 20]])
    • So, whenever the repeater changes height (e.g., rows added or deleted) the dynamic panel automatically changes height to accommodate, and any time the dynamic panel changes size it thus moves everything accordingly, keeping a 20px margin
  • I also added titles for the repeater columns, keeping these outside of the repeater, but inside the dynamic panel.
    • I added ability to sort the repeater list by column, to demonstrate how the repeater can be changed/controlled and still have the row data be persistent.
    • Note that any time a repeater adds/deletes/sorts/filters etc. the repeater’s Item Loaded event gets triggered.
    • I have the dynamic panel hide itself when loaded because the “title row” itself looked odd (note that a blank repeater (no rows in its datasheet) will show up in the editor with one “blank” row, but it would not show at all in the browser) Of course feel free to delete this Loaded event and/or style things as you need.
  • Look at the “Add owner” button’s cases and the Add Rows action to see how data gets set in the repeater
    • Case 1 tests if the text field is non-empty and if the Type droplist is not the default “please select” --and if so adds a row, clears the entries and focuses the text field for the next entry.
      • Add Rows uses these expressions to set the data–splitting the DataEntry_Name value into first and last names and transferring the selected list option for Type.
      • The Name column is set using a local variable, LVAR1 which points to the text on widget DataEntry_Name. The expression keeps everything before the last space:
        [[LVAR1.substr(0, LVAR1.lastIndexOf(' '))]]
        • “Adam Ant” would result in “Adam”
        • “Buford T. Justice” would result in “Buford T.”
        • “Carl” would result in “” (blank; no value because there is no space; however the Surname would get set to “Carl”, as below)
        • "Dilbert " would result in “Dilbert”
      • LIkewise, everything after the last space is retrieved with the expression,
        [[LVAR1.substr(LVAR1.lastIndexOf(' ') + 1)]]
        • “Adam Ant” would result in Surname getting set to “Ant”
    • Case 2 handles a blank text field by focusing it (I also created a “Focused Style” for it)
    • Case 3 handles the default droplist

Hi and thanks for the reply, that looks really promising. Super busy days and I’ve only found time to briefly glance, sorry for that.
I think I’ve already figured it out by myself and am pleased with the outcome. Super powerful, albeit also quite complicated to set up.

I’ll try to get back to this and post my self-made solution here once I find some more time :slight_smile:

Just a quick update: I think I’ve cracked repeaters now and love them. So versatile, so dynamic. And once you’ve gotten a hang of it, they are not that complicated, after all. Great feature to have and something that really sets Axure apart.