mithril.js: input checkbox checked attribute rendered incorrectly or cached incorrectly
In the following example, a checkbox’s checked attribute is binded to a boolean (isLightOn) and an onclick handler is attached to toggle this bit. We display this - isLightOn - value separately as well to make sure we bind the correct value to the checked attribute.
This works fine, clicking the checkbox on and off toggles the bit correctly.
Then we intoduce a bit to switch off the light and disable toggling. This correctly sets isLightOn to false and the checkbox checked attribute nicely follows this setting.
Now clicking the checkbox correctly handles to not switch the light flag on, at the same time the checkbox checked attribute is rendered incorrectly because the checkbox is marked as ‘checked’.
The only way to correct the rendering in this case is to assign a new key to the same checkbox and then the redraw will be correct. Uncomment this in the toggleLightOnOff() to test.
<head>
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.0/mithril.js"></script>
</head>
<body>
<div id="content"></div>
<script>
var app = {
model: function() {
var self = this;
self.key = 0;
self.isTogglingEnabled = true;
self.isLightOn = false;
self.toggleLightOnOff = function() {
if (self.isTogglingEnabled === true) {
self.isLightOn = !self.isLightOn;
}
//self.key = self.key + 1; // enabling this line will solve the rendering issue!!!!!
}
self.disableToggling = function() {
self.isTogglingEnabled = false;
self.isLightOn = false;
}
},
view: function(c) {
return [
m("div", [
m("div", [
m("div", "1. toggle the checkbox and see how isLightOn changes."),
m("input", { key: c.model.key, type: "checkbox", onclick: c.model.toggleLightOnOff, checked: c.model.isLightOn }),
m("div", "isLightOn = " + c.model.isLightOn ),
m("hr"),
m("div", "2. disable toggling and see that checkbox checked state and the isLightOn is no longer in sync"),
m("div", "isTogglingEnabled = " + c.model.isTogglingEnabled),
m("input[type=button]", { value: "Disable Toggling", onclick: c.model.disableToggling }),
])
])
];
},
controller: function() {
var self = this;
window.model = self.model = new app.model();
}
};
m.module(document.getElementById('content'), app);
</script>
</body>
</html>
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 49 (39 by maintainers)
Commits related to this issue
- #691 sync input if user-set DOM value — committed to MithrilJS/mithril.js by lhorie 8 years ago
IIRC the snippet in db17958f0b96204ee8d97c882323d93c32564be2 used to exist to deal w/ this issue
This is not really a Mithril issue. It’s basic HTML and Javascript.
Try this http://jsbin.com/qayiyo/1/edit?js,output
Checked is a funny property. In HTML you don’t set it to true or false:
<input type=checkbox checked>It exists or it doesn’t exist. Mithril puts HTML attributes inline –checked=falseis still “checked” from the HTML point of view.In JS it’s boulean:
document.getElementsByTagName('input')[0].checked=falseBut in your example, if you set it in your toggleLightOnOff function, the HTML is redrawn later and “checked” would be added the input tag anyway.I think you want to “disable” the checkbox. See the jsbin example.