virtual-dom
virtual-dom copied to clipboard
Phantom pattern on reused input field
When switching between two forms, if the structure of the HTML is similiar enough, the virtual DOM will reuse the existing input elements and change the properties/attributes around.
Attributes that do not exist in the current version don't seem to get removed, but they are assigned null value. A required property will be false, a number property will be 0. String properties get the empty string. Empty pattern strings don't validate though. So you end up with a phantom pattern on your input field that will prevent validation.
The problem shows up in current Firefox and Chrome.
A simple example that shows the problem when cut and pasted to elm-lang.org/try
https://gist.github.com/grmble/c15e9258a90e1a8bfb9417cae6d0af55
If you click "Show Demo 2" and then "Show Demo 1", the input field has a permanent red border.
Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!
Here is what to expect next, and if anyone wants to comment, keep these things in mind.
After digging some more, the immediate problem seems to be the property handling in applyFacts. It's just domNode[key] = value; And the value in this case is an empty string.
So this gives instant relief:
@@ -395,7 +395,13 @@ function applyFacts(domNode, eventNode, facts)
break;
default:
- domNode[key] = value;
+ // phantom pattern on reused input field
+ // https://github.com/elm-lang/virtual-dom/issues/122
+ if (key === 'pattern' && value === '' && domNode.tagName === 'INPUT') {
+ domNode.removeAttribute('pattern');
+ } else {
+ domNode[key] = value;
+ }
break;
}
}
Of course, it could also be handled at the diffing stage by arranging for attribute removal instead of setting the property.
Even easier: don't set the pattern property, set the attribute.
Explanation: The behaviour for properties is as described above. For attributes, the virtual DOM uses setAttribute and removeAttribute. Which is the exactly what is needed to not trigger the bug.
I was able to repro a similar issue here: https://ellie-app.com/yQH4jpWvPDa1
Basically if you click "hello", it goes the the href (appends the #/test which is fine) and fires the Clicked message. Then if you click "world" it should just change back to "hello", but because the href attribute is still on the element (just empty), it navigates away from the page.