Add values to a repeater row pulling filtered values from another repeater or table

repeater-widget

#1

I am trying to create a prototype where the user can add a row to a repeater widget and several of the values in the row are pulled in from another repeater based on the a key value entered in the row.

Example: Repeater A named Labor Distribution has a field for an account number, the account name, a fund number, and the name of the fund. I want to enter the account number in the new row I have added and have the other 3 values retrieved from Repeater B or table based on account number I have typed in.

So that when the user clicks on Update row for the repeater the values are added to Repeater A.

Thanks for any help. I did see the forum on using two repeaters to create a relational database however I haven’t been able to get that solution to work for what i am trying to do.


#2

You can do this, but the solution isn’t straight forward. Axure doesn’t provide a built-in way to query specific rows in a repeater (e.g., a property like [[MyRepeater.Row.3.Column1]] or a “Get Column Value” action.) Instead, you can devise a “listener method” in which you set up a way to identify a “target” row–maybe it is “the third row” or maybe it is “the row with account number 69”–and then “ping” a widget in the repeater, so each and every instance (row) “listens” to the ping and responds if it is the target row.

If the discussion below is too complicated or you can’t get it to work, I’d be happy to demonstrate it for you if you can upload a sample .rp file with your repeaters set up.

I have used two ways to create a “repeater listener method”:

  1. Utilize an otherwise unused event for a widget in repeaterB, like Moved or Rotated.
    A. Clicking an “Update Row” button in repeaterA can set the “target” and initiate the “ping” …something like,

Set Variable Value OnLoadVariable (or whatever global variable) equal to text on MyInputField
Add Row to This, column AccountNumber, to OnLoadVariable
Move textWidgetName by (0, 0) //Just some widget in repeaterB; it doesn’t actually get moved, just a way to trigger the Moved event. You can also call “Fire Event Moved for textWidgetName”

*Keep in mind that “moving” a widget in a repeater will move every row’s instance of that widget (in very rapid succession from row 1 to row N) so you’ll need a way to test each row to see if it is a target row.

B. For this widget in repeaterB, (maybe it holds the text for “AccountName”) set up a way to “listen to the ping” via a Moved action which updates your new row in repeaterA, but only if it is the target row. Use a conditional case to test if it is the target row:

If [[Item.AccountNumber]] equals value of OnLoadVariable
Update Rows
in RepeaterA where [[TargetItem.AccountNumber == OnLoadVariable]]
set column AccountName equal to [[Item.AccountName]]
set column FundNumber equal to [[Item.FundNumber]]
set column FundName equal to [[Item.FundName]]

  1. An alternate approach, instead of using an event like Moved is to use the Update Rows action and a column specifically for the purpose of returning a value or data from the repeater dataset (or states of any widget therein.) The basics are the same as approach 1, but the code to handle things is in the repeater’s Item Loaded event, instead of a widget in the repeater.
    A. To use the data in a row with account number of 1002, call something like,

Update Rows
in repeaterB
[[TargetItem.AccountNumber == ‘1002’]]
set column DataReturn equal to “true”]]

B. In the Item Loaded event in repeaterB, set up a conditional case to “return the data” when the value of the column named DataReturn is “true”. In your case, this means updating the newly added row (or any row with a matching account number):

If [[Item.DataReturn]] equals “true”
Update Rows
in RepeaterA where [[TargetItem.AccountNumber == Item.AccountNumber]]
set column AccountName equal to [[Item.AccountName]]
set column FundNumber equal to [[Item.FundNumber]]
set column FundName equal to [[Item.FundName]]
Update Rows
This row
set column DataReturn equal to “false”

Approach 1 is more commonly used–I learned it from the infamous Gregor on this forum many years and RP versions ago RP6?–and you’ll find many forum threads describing this. It is pretty much a hack, is limited in its scale (only so many unused events; and if you later need to actually move a widget for real it can break) …but it does work.

I devised the second approach (and it may not be original) a few years ago to help a broader team understand and collaborate easier on a team project. It feels more “official” --less of a hack–and makes the act of “calling a target row” easier, as well as making the code more visible as it is in Item Loaded and not hidden in a random event of some widget. It should be more extensible/scalable as you can add additional columns and cases for different types of “returns” or actions.


Basic repeater question, finding an item
#3

repeater lookup.rp (189.9 KB)

I have uploaded my example rp. Per your reply, I would appreciate help with the execution of the lookup. Thank you


#4

I added a solution to your file. I chose to use the second approach I outlined above, using the “Update Rows” approach to let Repeater B return (or “export”) its data to Repeater A.

repeater lookup.rp (256.1 KB)

Here is the high level overview:

  • User clicks “+ Add a Row” button
  • (User enters data in first 4 columns)
  • User enters a number in the fifth column, Cost Object and then either Enter, Tab, or clicks away from field such that it loses focus. This triggers a “secret” submit button to be fired.
  • The submit button updates the row (actually any rows) in Repeater B with a “IONumber” matching the Cost Object number. The update sets a new column, “ReturnData” to a value of “true”.
  • When a row in Repeater B has a value of “true” in the “ReturnData” column, it updates the corresponding row in Repeater A (any row with a “CO” column value matching “IONumber”). You can see this in the Item Loaded event of Repeater B.

I’m not sure I understand your request for “user clicks on Update row” and additional request in your file for “is there any other way to update rows …without having to click on a widget” --and/or I’m not sure of the desired user experience–should users be able to enter data in the last three columns manually as well as via “lookup” from Repeater B? (I assumed so as the last three columns have text input fields, and the “Update Rows” button already sets all the data for “This” row based on the text fields’ values.) At any rate, I added a method for users to enter data in the Cost Object column and then either hit Enter or Tab (on keyboard) or otherwise click away from this text field to trigger the “search and return” of data from Repeater B.

  • This is done by creating a widget and assigning it as the “submit button” for the “CostObj” text field widget in Repeater A. (To do this, right-click a text field and choose “Assign submit button”; this results in the button’s Click or Tap event being triggered when user hits the keyboard Enter key.
  • I added a Lost Focus event for this text field which tests if the value is non-empty and if so fires the submit button. This enables the Tab key to do same as Enter key.
  • I used a hotspot, named “submitCostObj” as the widget for the submit button. This keeps it non-visible. (I kept a little bit peeking out from behind “CostObj” just to make it easier to find–you can resize it so it is completely behind “CostObj” if you want. --You can’t hide it by setting it to “hidden” because then its code won’t be usable.
  • For the most part the hotspot does the same thing as the Update button. I thought the “lookup” feature seemed different enough from merely updating the row, but you could easily paste code from this hotspot to the Update Row widget and assign the latter as the submit button if that makes more sense for your user experience.

Since there is a lot going on, missing widgets and variables (presumably from your copying out just a limited sample here), and I didn’t quite understand the whole user flow, I duplicated your page and changed a few things to help me use and test this.

  • I added a Focused Style for the text fields in Repeater A and set the first column’s field to focused when adding a new row. (this just helps me know what is focused so I can tab over to the Cost Object column and enter a number.)
  • I added Set Text actions for the last three columns in Repeater A. Otherwise, no way to show the data “imported” from Repeater B.
    • If you want to show these column’s data only when adding new rows and/or importing from Repeater B, then you could add another column to Repeater A to control that.
  • I removed the actions in the LOADED event of Repeater A as they conflicted with my solution. (Also, I don’t think they did what you intended, and shouldn’t be needed. But, if you do need something like this you could add things back in.)
  • I removed the Filter action in the LOADED event of Repeater B as it referred to a missing global variable and thus “filtered out” the entire repeater.
  • I added a Selected Style to the background widget in Repeater B, just to show when a row was “hit” --to make sure my code was calling the correct row.
  • I added a RESIZED event to the “GP_LabDist” dynamic panel, with a Move action to automatically move the widgets below it when rows were added/deleted from Repeater A.

#5

Thank you for your response. Your solution does exactly what I was looking for. We want our end user to be able to look up values and simulate what we are designing for our Fiori Mendix project. I am a novice to Axure and you have provided me with some advance scripting that will help me in future designs.