Validation interaction not working as intended


#1

I am having a problem with a validation interaction that I had developed and I’m at a loss on how to troubleshoot it and hoping the community can help. The individual interactions all work, but when you try and do them one after the other they stop working. I used Key Up so that each key stroke is validated. The only one that is consistent in validating is Symbol, lower case, upper case and numbers only work if they are the first character. When I review the console after the first key stroke the next validation says “No condition met”. Can someone please review my file and give me some insight on what is happening?

password-validation.rp (474.4 KB)


#2

Good password validation can be difficult. You’ve got a good start here, but some of your conditional logic is flawed and obviously doesn’t work the way you think it does.

I’m not sure why you have some validation done on Lost Focus and others on Key Up …for example, I would want to know as soon as possible that I’ve entered at least 12 characters, and not only after I click somewhere else. But, if you have certain validation rules or requirements, you can do it this way …just not the best usability.

I’m not sure why you have additional logic conditions in some of your cases, like “and text on this is alpha”. What purpose are you trying to achieve here? Because you have a validation constraint of including both alpha chars and numeric chars, this doesn’t make sense. As soon as a user enters any digit, special char, or any other non-alpha char this would equate to false, and that is not what you want.

You have set some rules to show when password requirements are met, but not when they are lacking. So, if a user enters a digit, the “Must include at least one number” requirement can go green, but if they later delete that number (like backspace over it) that requirement should go red. (…And your logic in the “numeric” case, If text on This is numeric, tests if the text contains only numeric chars, so as soon as it contains a non-numeric char it would equate to false. Also, it is not obvious, but a space char is considered “numeric” so if a user presses the spacebar key then “is numeric” equates to true. Most password schemes don’t allow for spaces, and even if they do, it wouldn’t be considered a number.)

See this post for an example of how you can test for validation conditions and change individual constraint messages (e.g., show green check for "met" or red X for "not met" conditions.)

I’ve applied this logic to your code in this updated .rp file. See the “Login (1)” page.
password-validation.rp (883.4 KB)

At a high level, the Key Up event on +new tests its text value against each individual requirement in a series of “If—Else If” conditions, changing it to green when met and red when not met. For example, the first set of two conditions test for a length of at least 12 chars:
image

The post I linked to above goes into logic details for most of the conditional cases.

I disabled the new and confirm password fields by default. The new password field is enabled when the current password is filled out. Ideally, you’d have an existing password to test against, but for now it accepts anything more than 3 characters (let’s say old passwords could have been 4+ chars) …of course, change this as you need. When all requirements are met for the new password, the confirm password field is enabled (see details below.)

Your algorithm to increment the "N requirements met" counter uses a global variable, "Met", but you never increment the variable, you only increment the text value of the counter, so it always equates to 1. So, you should either increment the global variable first, ([[Met + 1]] and then set the value of the counter to the variable, (Set Text +met-requirements to value of [[Met]]) or just increment the counter directly without needing a global variable. I did the latter in the file above.

I moved the counter increments to the constraints dynamic panels, so any time they change state they handle the resulting counter change (so changing from red to green increments the counter; green to red decrements the counter.) This method is more reliable for ensuring the count is correct. Also, any time an individual requirement is met/unmet–triggering it to change state–it fires the Rotated event of +requirements. I’m using this event as a “listener” or “handler” –a kind of built-in sub-routine that changes its state to “met” or “not-met” depending on how many requirements have been met. Then, whenever it changes to “met” the confirm password field is enabled (and counter values set to match.) Note that I made these changes first only on the +length requirement, tested that it worked correctly, then copied the whole Panel State Changed event and pasted to each of the other requirement panels.

(Because you really have just one counter and one description, you could save some overhead by styling this once, instead of creating a dynamic panel with 2 states and duplicates of everything. You could set a “selected” interaction state that has green text, then set it to “selected” when all requirements are met. Or, you could use “rich text” to set the color.)

I added a Panel State Changed event to +requirements so that when it changes (especially from not-met to met) the "green counter" in the "not-met" state matches "+met-requirements" red counter. Also, when all requirements are met it enables the +confirm text field.

I moved the "Enable +ok" action and condition to the Key Up event of the +confirm text field, and added tests for matching text values as well as all conditions met.


There are further considerations you may need to take into account, depending on needed specificity, like handling invalid characters (e.g., most passwords can’t have spaces or commonly used logic symbols, like ‘&’ or escape sequences, like ‘/{’ ). You can work with your client, dev and/or quality partners on details.

If you want to include functionality for the "view" eye icon in a password field, to show masking chars (like bullets or asterisks) by default and actual chars when "view" is on, then you can make a dynamic panel from the existing password field, name the state something like, "hidden", duplicate the state and name that something like, "shown", go back to "hidden" state, right-click the text field and select "Input Type : Password". Then add a Panel State Changed event that copies the text value of the text field in the current state to the text field in the new state. Do the same for the +confirm text field.


#3

I appreciate your feedback on my issue and I will rework the interactions. I don’t pretend to be the most efficient at designing the interactions so your feedback is very helpful. I had hoped when I made this post that it would be you that would respond. Thank you very much, I’ll let you know how it goes.


#4

I just finished implementing your suggestions and it all works. Thank you very much!


#5

I’m feeling a bit lost on how to troubleshoot it. The individual interactions within the validation work fine on their own, but when I try to use them consecutively, they stop functioning properly. I utilized the Key Up event to validate each keystroke entered. Strangely, the Symbol validation is the only one consistently working, while the validations for lowercase letters, uppercase letters, and numbers only work if they are the first character entered. Thanks in advance


#6

If you can post an example .rp file it will really help! Otherwise your fellow Axure users (like me) have no idea what might be happening or where bugs might be in your prototype.

In general, yes, troubleshooting and debugging in Axure can be very difficult and confusing. It would be great if it had better tools for this. Some things I’ve found helpful in general…

With multiple conditional cases, pay attention to “IF” versus “ELSE IF” cases.

  • These mistakes are very common, and can drastically change the interaction logic and results.
    …and I swear the default Axure gives me is almost always not what I want…
  • You can right-click any conditional case to change it between “If” and “Else If”
  • As an example, let’s say you create a simple action event for a button, and it works great, like,
    image
    …and then you enable cases and add a case, by default it will be an “Else If” condition, like,
    image
    …it won’t work, because Case 2 literally means, “Else if true is not true and is selected of Checkbox1 is true” which is logically impossible, so Case 2 would never get triggered. You’d need to change Case 2 to an “If” so it will always get evaluated, in addition to Case 1.

With multiple conditional cases, it can help to isolate one case at a time

  • For example, you can select all cases except the first one, delete or cut them, preview and test in the browser. Fix anything needed and once working well, go back to editor and undo the delete or paste the cut cases. Repeat with the first two cases included only, etc. …Or if needed, test each case individually to ensure they can work in isolation, then start combining them to find the problem.
    • Or, to be sure you don’t accidentally lose cases, events or actions, you can
      • Duplicate the widget, make changes to it or the original only, test, then keep what works.
      • Or, select and copy (or cut) the whole event or just some of the cases, then click the “New Interaction” button and the “Paste” button for an event you’d never use for this, like Moved or Rotated. I prefer this as it is easier to drag cases back and forth between events in the same widget.
      • Or, you can add an extra condition to a case to logically block it out, just something to ensure it will never get triggered, like, "1" equals "2" or "SKIP" equals "TRUE", e.g,

        image

With expressions and local variables, verify your references, pointers, spelling, and syntax

  • For example, does [[LVAR1]] point to the correct widget? Does it point to what you need, such as the whole widget, the text value of a widget, etc?
  • Spelling and syntax correct? For built in functions like [[LVAR1.substring()]] it is often very helpful to search the web or a trusted dev site like mozilla.org for things like, “javascript substring” or “javascript get first character of a string”

Preview your prototype and show the Console with Trace on

  • At the top right of your browser page, click the Console button
    image
  • Then ensure the Trace is on, and use your prototype. You’ll see which interactions and cases are getting triggered, e.g.,
    image
    …Hmm, why isn’t Case 2 getting called?

With complex expressions, math, string manipulation, etc. it can help to temporarily add an action to also show it in a global variable, or text of some widget

  • This can help verify the result is what you expect, find syntax errors, and so forth, e.g., cut & paste the expression used in a conditional case to set the value of a variable…
    image

When you have problems with using global variables in calculations, string transformations, etc., or repeater updates, or animation sequences, it can help to temporarily add Wait actions

  • This can slow things down so you can inspect the progress in the Console.
  • A brief pause, like Wait 10 ms is sometimes necessary to ensure a global variable is completely set before you try to get it or refer to its value.
  • A brief pause of at least 50 ms is sometimes required when performing multiple repeater actions, like Edit Row Data followed by Add Filter
  • A brief pause can also help ensure the actions of one case are performed after actions in another case when you have multiple “If” conditions.