Issues with Got/Lost focus in a repeater

repeater-widget

#1

Hello,

I am having some issues with the got/lost focus even in axure. I have tried to create a very simply example, and I just want to understand how it is working.

if you trace the execution of the example, you can see that it executes many many times for each click. Does the ‘set text’ action focus on the widget as it is modifying the text or something?

Any help appreciated

focus test.rp (49.5 KB)


#2

I’m not sure what you are trying to test or get an understanding of, exactly… How a widget in a repeater gets and loses focus? When the Got Focus and Lost Focus events get triggered? I can’t see how your file tests any of that specifically, though… Could you explain in general what you are trying to do with this?

From the Axure documentation for Widgets, and Layer Order,

  • Focus: Gives a widget browser focus, moving the text cursor onto text-input widgets and highlighting clickable widgets.

  • Layer order, or “z-index,” also determines the tab order for widgets that can be navigated with the TAB key in the web browser, such as form widgets like text fields and droplists. The TAB key focuses the backmost widget first and moves progressively forward.

When you have multiple focusable widgets on a page, only one widget may be focused at a time. You can create an interactive style effect for the Focused state of a widget, so that when it receives focus it can look a certain way.

When the Tab key is pressed, the next focusable widget will receive focus and Shift+Tab focuses the previously focused widget. The “tab order” or list of focusable widgets starts from the bottommost focusable widget on your page. For example, if you had 3 text fields in a form, First Name, Last Name, Email, and want the user to be able to tab to them in order, you’d want to organize your widgets so Email is above Last Name, above First Name in your Outline pane. It is worth noting that most browsers will focus their own interactive features–part of their app chrome–such as the URL field, buttons, etc. AND the Axure prototype player will typically be part of this, depending on which panes are visible. If you want to keep the tab order focused (pun intended) on your prototype and not include the player and browser chrome, you’ll need to include a Lost Focus event on the last focusable widget (or at least the last widget you want to be focused in a Tab key press) that puts the focus on the first focusable widget, so in the example above, it would look like,

Email Text Field
Lost Focus
Focus
First Name Text Field

However, when focusable widgets are in a repeater, the tab order progresses from the first visible row to the last visible row. …Unless you have code that specifically overrides the focused widget, which you do. In your repeater, when a row’s text field gets focus–or loses focus–it edits its own row data. This causes the repeater to load all of its items (rows), which is why you see it executing a bunch of Got Focus and Lost Focus events. Any time a repeater is touched–editing row data, sorting, filtering, adding/removing rows, etc. it causes it to be completely rebuilt, which will fire the Item Loaded event for each row in the repeater.

I don’t see any value in trying to change or even track the focused widget and row via the repeater’s dataset. As soon as the Edit Row Data action is fired, the focused widget will lose focus. If you want to track which row currently has a focused widget, you could mark that row when its widget gets focus–actually, first unmark all rows, then mark “this” row. …or maybe try unmarking “this” row in the Lost Focus event. Marking and unmarking rows don’t trigger a repeater rebuild.

Additionally, I don’t think all your Wait 10ms actions are really doing anything, and you don’t need the second “Case 1” conditional case to set the text of your widget to “unfocused” --just set that text value by default.


#3

Really appreciate your reply, thanks a lot!

So, as I understand - during an item loaded event the widget is getting focus. I am still encountering some issues with my design.

I have attached a new file with some more examples relevant to what I am trying to acheive. on the page ‘text input’ you can see the widget outside of the repeater, and how on focus the label moves.

However, when I add this into a repeater, it stops working (as demonstrated on the ‘text repeater’ page).

I also tried your suggestion of using marked rows on the original example, however since this does not trigger the repeater to rebuild I cannot actually perform any action on the given repeater row.

Please see the updated file below:

focus test orig.rp (84.8 KB)


#4

No, this is not true. …Unless maybe you have a Focus action in the Item Loaded event that targets a widget in the repeater.

Yes… it’s not clear why this would be so. My best guess is that when you set text for the “Label” widget it focuses that widget. Why this would work differently in a repeater is a mystery, but clearly when you click on a text field in the repeater, it gets focus then loses focus. This does not happen if you don’t change the text of the label in the text field’s (or group’s) Got Focus event.

I added a few test pages to your file to test this stuff further…
focus test orig.rp (168.3 KB)

  • The “Text Field” page just has a basic text field widget, styled with a Focused Style. When it gets focus it sets the OnLoadVariable global variable to “Text Field got focus”.
  • The “Multiple Text Fields” page has three text field widgets to show how tab order can work.
    • In the past, I’ve been able to keep the tab focus on the page (and not the browser chrome) by adding a Lost Focus event to the last (top-most) widget, but this doesn’t seem to work properly anymore–browsers tend to change the way these things behave. Now–for me at least, on Windows 11 with latest Google Chrome browser–the “re-focus” works in that the first widget is shown focused, but the focus also shifts to the prototype player/browser chrome also, and further tab keypresses move the focus among the browser controls, not the prototype widgets.
    • I made an adjustment to work around this by adding a Page Key Down event that tests if the key pressed down is the Tab key and the selection state of the last field widget is true, and if so, sets focus on the first field widget. Axure doesn’t have a .focused property, nor ability to test which widget is focused, so I used the selection state of the text field instead. When a text field is focused it selects itself (and deselects the others; unfortunately you can’t assign a selection group to a text field widget either.)
  • The “Custom Text Fields” page is similar to above but I use your custom Medium-styled text fields with floating labels. The text field groups get and lose focus as I would expect.
  • The “Repeater with Custom Fields” page is similar to yours, but I modified a few things to eliminate possible confounds with the Got Focus and Lost Focus events.
    • I use the Label column to set the text field’s label, and named the unused column to “Value” and use that to set the text field value.
    • I also assigned the focus events directly to the text field widget and not the group. (I also tested ungrouping everything but that had no discernable effect.)
    • I thought this was a good solution, but it doesn’t seem to be that reliable… When updating the row–to track new values entered–the label doesn’t behave as expected. …I have no idea why not.
  • The “Repeater with Custom Fields 2” page takes a different approach…
    • I placed the Label behind the text field so that it won’t interfere with clicking on the text field.
    • I created a Selected Style for the Label widget, styling it as you did for the focused state. This makes it so you don’t have to keep resetting the text value with rich text every time the field gets or loses focus. I then assigned a Selected action that moves itself to the top of the text field and brings it to front. Likewise, an Unselected action moves it to the middle of the text field and sends it to back.
      • These are now more simple… When it gets focus, a text field sets its label selection state to “true” (which in turn triggers it to move). When it loses focus and the text field is empty it unselects its label, otherwise it leaves it as selected.
    • The selected label looks a little odd as there is extra padding to the right of the text. I think this is due to the repeater initially setting the text value in the larger font.
  • The “Repeater with Custom Fields 3” page changes the approach a little more… This seems to be working pretty well.
    • I duplicated the Label widget to “Label-Active”, styled it with smaller font size and black color, placed it where it should be, and set it to hidden by default.
    • When the text field is focused or its value is not empty, it shows Label-Active and hides the default label, and visa-versa when it loses focus.
    • I threw in the ability to mark/unmark rows as they get/lose focus.

#5

I’ve been diving into a project that involves a dynamic navigation menu. I’m facing a perplexing situation where, upon clicking a menu item, the corresponding submenu opens up, but it seems to trigger multiple times with a single click. It’s almost like the action is caught in a loop. I’ve tried tweaking the interaction conditions and triggers, but I’m still stumped. Could this be related to how the focus shifts between the menu items?


#6

…Could be. Practically impossible to say without seeing the code. Could you post your .rp file here? Are you using Got Focus and Lost Focus events for this, and/or is your menu a repeater? …Wondering why you posted in this thread vs starting a new one…

Debugging Axure prototypes can be tricky… In general, you’ll want to preview the prototype, show the Console and start the Trace, so you can see what events and actions are happening in real time. I’d start by simplifying everything–basically removing events, actions, and complexity until it works correctly, then slowly adding functionality back in until it breaks. I’ll often cut out whole events and/or actions, refresh the prototype in the browser, test, then cut more or add some back in depending on results. In the editor, I can paste a set of previously cut events or actions, or Edit > Undo (Ctrl+Z) to put them back. If my code is more complex, or I need to do a series of cuts, I’ll sometimes cut a block of code and paste to an unused event; e.g., select 3 or 4 actions in a Click or Tap event, click the “New Interaction” button, then the “Paste” button to the right of Rotated --such that I don’t lose this code, but it won’t be called. Another little debug trick is to add a conditional case that always evaluates false, thus blocking an event, like, If "true equals "false" so the existing event won’t be triggered. You can do this as well for existing conditional cases by just adding an additional “always false” condition.

If your menu is or has repeater, your code might inadvertently trigger a “rebuild” --as in another filter, sort, or add rows action. If so, does the repeater’s Item Loaded event have any actions that call the same repeater?

And/or… does showing the submenu–or any of its components–have any conditions, events, or actions which might trigger the same event or action? …Depending on how you show or open the submenu, such as a Show/Hide, dynamic panel state change, selection state change, repeater filter, etc.