An Input Conflict occurs when two user inputs are invalid given each others values, but valid if considered in isolation. This is distinct to an input that is internally invalid, which is invalid irrespective of any other input value. An internally invalid input must be updated in order to be accepted, whereas a conflicting input may be repaired by updating its conflicting counterpart.
There are three solutions to an input conflict. You may reject the conflict, correct the conflict, or accept the conflict. To reject an input conflict, an application would simply fail to update an input if the new value would cause a conflict. The user would then be incapable of making a conflicting edit. Conversely, to correct an input conflict, an application would update the value of the conflicting counterpart to be valid given the users edit. Finally, to accept an input conflict, an application would allow its state to become invalid, at least temporarily.
Rejecting the conflicting input is the worst option for the user’s experience. The user may not immediately realize that their input was rejected, and if they do, they may not understand why their edit did not work. Rejecting an input conflict requires that a user realize a problem for which there is often no indication, and to correct the problem despite there often not being any feedback on the cause of the issue.
Similarly, fixing an input conflict causes side-effects that the user may not realize or want. It also creates issues for the implementation of Reversibility, like an undo operation, as both the user edit and the input conflict fix should be reversed, which the application likely does not do by default. If the conflict is to be fixed, an entirely new input component should be built which combines the inputs and Telegraphs the side-effect.
Accepting the conflicting input is the most intuitive outcome for the user, as it simply allows for the edit that the user intended to make. It also creates an opportunity for the application to explain to the user precisely why the inputs are invalid, giving the user the opportunity to fix the issue as they see fit, either by reversing their edit, changing their edit, or fixing the conflicting counterpart. Automatic fixes may then be offered to the user in order to simplify the process, but since these fixes are offered as a seperate user action, they will be fully intended and understood by the user.
A user wishes to order a pizza in an app. They start by inputting a coupon for a discount on two large pizzas. At first, the coupon is invalid, as they have not yet selected two large pizzas, but the coupon is still accepted, as it is presumed that they will do so. If the user is about to finalize their purchase without the coupon being valid, they may be warned that the coupon will not apply, but even then the purchase should be accepted.
If the app didn’t allow a coupon to be applied if it is not yet compatible with the user’s pizza selection, many user experience issues would occur. The user would have to input the coupon code before the app would refuse to apply the coupon, at which point the user would need to back out of the coupon application page to select their pizzas, wasting time. Once the two pizzas are selected and the coupon is applied, the user would then not be able to remove a pizza from their cart, as that would conflict with the applied coupon. Therefore, if the user wanted to remove a pizza, they would first have to add a pizza, then remove the one they no longer wanted. This process becomes even more complicated if the coupon requires toppings.
The issue with rejecting the coupon until it is compatible with a user’s cart is that the user will almost always want to fix the conflict outside of their current input. When a user is warned that the coupon is not yet valid, it is far more likely that they will want to fix the issue by keeping the coupon and changing their cart. We don’t know, for certain, what changes they will want to make to their cart in the future, but we do know that they intended to submit this coupon. If we reject any conflicting state, we force the user to back out of their curring input, immediately make changes that they always intended to make, and resubmit the now valid input that they had already prepared. Such a process will always take longer, and will be exceedingly frustrating for the user.
When a tweet is too long, Twitter does not block further typing. They simply warn the user that the text has gone over the limit while allowing the words to continue. They do this because it is unlikely that the user intends to cut off their thought in the middle of a sentence. More often than not, the user will cut unnecessary filler words for space, which is easier to do once they have determined the size of their overflow.
In this example, the conflicting input is not an entire form or item, but the individual letters of the text box. The 281st character is in conflict with the 280 that came before it, but it can be made valid by removing one of those prior characters. The input conflict problem affects inputs both big and small, but the rule remains the same.
An input which is valid when judged in isolation to the rest of the system should be accepted, even if only with a provisional status, so that any external validation may be dealt with externally. A form, therefore, should be accepted if there are no validation issues with the form element inputs when considered amoungst themselves and relative to each other. An input that is internally invalid, that being an input that cannot be rendered valid through external changes alone, may still be rejected outright, as the user can correct the problem without accessing the rest of the program.