I like the temperature converter one because it immediately introduces some of the more fuzzy design questions and annoying details that pop up when you implement data binding.
Such as: when exactly should the other side update? When the user switches focus (where to?) or on every keystroke? Does it make sense to a user that they temporarily see the Fahrenheit value for 2°C if they really want to type in 20°C? What happens if they type an invalid value (or clear the box, which they often have to do)? What happens if they type an incorrect value and then type something into the other field?
Etc etc.
I think there are a lot of interesting tensions between a "formally correct" system and one that feels usable and intuitive to use. Especially with bidirectional data flow, they show up quickly.
These are some good UX questions, none of which have a really clear answer.
I think most of your 'when should the fields update' type of questions, have already been solved in Google Translate web UI. There, you can only update the left-sided input field. So there becomes this simple flow of: 1) decide which language you're translated from. 2) edit that value. 3) the UI picks up that a keystroke has not occurred in the last X seconds 4). The right-hand side field updates.
That was kind of his point though. In order to deactivate one side you have to program that in the UI. Also, if you provide this kind of forced directionality to the two temperatures, you now how to make the units toggle on each side ( otherwise you can only convert from one fixed choice to the other - eg. C to F but not F to C ).
As soon as you start asking these questions, the UI requirements change.
Good point. This in turn shows the risk of endless event propagation loops: So you decide to solve the formatting problem by using floor() and only showing the integer parts.
So now when the user enters 72°F, it shows 22°C. However, in a naive implementation, updating the celsius field would trigger a change in the other direction as 22°C converted back would round to 71°F. But 71°F rounds to 21°C, triggering another change, etc etc.
Vuejs has a interesting and great way to avoid such feedback loops even in the presence of 2-way data binding. Most importantly you wouldn't use any watchers/effects to trigger logic on property-updates, but rather you use what they call computed property, which can do conversion on the fly, in both directions, giving different behavior on read and write.
Repeat for fahrenheit. Now i've seen shorter examples but most of them are very coupled to the UI, with each event on textbox writing directly to the other textbox attributes, this property can be bound to any number of textboxes and sliders without any additional code to keep them in sync. Similar techniques can be used for more complex synchronizations with conversions, like a date picker that allows both text-input and clicking a calendar.
I suspect a temperature converter should actually be modelled as a slider, with two labels showing both temperatures.
The user must drag the slider to find the temperature they have, and read the converted version. May be the slider is marked with different axis top and bottom (may be top is Celsius and bottom is Fahrenheit).
Comments
I like the temperature converter one because it immediately introduces some of the more fuzzy design questions and annoying details that pop up when you implement data binding.
Such as: when exactly should the other side update? When the user switches focus (where to?) or on every keystroke? Does it make sense to a user that they temporarily see the Fahrenheit value for 2°C if they really want to type in 20°C? What happens if they type an invalid value (or clear the box, which they often have to do)? What happens if they type an incorrect value and then type something into the other field? Etc etc.
I think there are a lot of interesting tensions between a "formally correct" system and one that feels usable and intuitive to use. Especially with bidirectional data flow, they show up quickly.
These are some good UX questions, none of which have a really clear answer.
I think most of your 'when should the fields update' type of questions, have already been solved in Google Translate web UI. There, you can only update the left-sided input field. So there becomes this simple flow of: 1) decide which language you're translated from. 2) edit that value. 3) the UI picks up that a keystroke has not occurred in the last X seconds 4). The right-hand side field updates.
That was kind of his point though. In order to deactivate one side you have to program that in the UI. Also, if you provide this kind of forced directionality to the two temperatures, you now how to make the units toggle on each side ( otherwise you can only convert from one fixed choice to the other - eg. C to F but not F to C ).
As soon as you start asking these questions, the UI requirements change.
Sure, it doesn't remove all complexity. But I think it would result in a more intuitive interface all round.
It’s also good for data formatting. You don’t want to see 22.2222222C for 72F. Ideally when you adjust one, the values are internally consistent.
Good point. This in turn shows the risk of endless event propagation loops: So you decide to solve the formatting problem by using floor() and only showing the integer parts.
So now when the user enters 72°F, it shows 22°C. However, in a naive implementation, updating the celsius field would trigger a change in the other direction as 22°C converted back would round to 71°F. But 71°F rounds to 21°C, triggering another change, etc etc.
Vuejs has a interesting and great way to avoid such feedback loops even in the presence of 2-way data binding. Most importantly you wouldn't use any watchers/effects to trigger logic on property-updates, but rather you use what they call computed property, which can do conversion on the fly, in both directions, giving different behavior on read and write.
Repeat for fahrenheit. Now i've seen shorter examples but most of them are very coupled to the UI, with each event on textbox writing directly to the other textbox attributes, this property can be bound to any number of textboxes and sliders without any additional code to keep them in sync. Similar techniques can be used for more complex synchronizations with conversions, like a date picker that allows both text-input and clicking a calendar.An interesting solution would account for the precision of the user input when formatting other fields, with different results for 72 and 72.000
https://xkcd.com/2585/
I suspect a temperature converter should actually be modelled as a slider, with two labels showing both temperatures.
The user must drag the slider to find the temperature they have, and read the converted version. May be the slider is marked with different axis top and bottom (may be top is Celsius and bottom is Fahrenheit).
you don’t need a slider, just look at a photograph of a thermometer with both scales on it
The slider is there so that you can get an accurate reading without having to use your mouse as the slider or eyeball the scale.
Reminds me of the principles brought up in this talk by Sean Parent:
https://youtu.be/0WlJEz2wb8Y
The temperature converter is a good example of an “implies” relationship, which Sean argues is difficult to model in UIs.
Honestly I think a label, 1 textbox, and 2 buttons- 1 "convert to F" and 1 "convert to C" is just so much simpler.
Or even 2 completely separate pages, 1 for C and 1 for F.
it's simpler and might even be a better UX, but that's not the point of this exercise
I think the point is stated as making the best ux for "bidirectional data flow."
That doesn't mean it has to be reactive.