dom-to-image
dom-to-image copied to clipboard
Checkbox and select Element values don't show their selected values
Use case: description, code
In a form, the <input =type="checkbox"/>
and <select/>
elements don't show the selected values.
Change the selected check boxes, and select in the dropdown, then click the Test Button
in the demo to see the behavior
codepen
Expected behavior
The rendered image would display the selected form elements
Actual behavior (stack traces, console logs etc)
Whatever the elements loaded with are displayed
Library version
2.5.2
Browsers
- [ x] Chrome 49+
- [x ] Firefox 45+
Please fix this.
I have a hacky workaround for this if any one is interested. It seems to be rendering an element based on its attributes but not its properties. My workaround is to update an element's attribute to match its property before it's rendered using the filter function:
domtoimage.toPng(ment,{
filter:function(node){
if(node.nodeType===1 && node.tagName==="INPUT" &&
(""+node.type).toLowerCase() === "checkbox"){
if(node.checked){
node.setAttribute('checked', true);
}else{
node.removeAttribute('checked');
}
}
return true;
}
})
http://codepen.io/anon/pen/ZKXogq?editors=1111
Works for checkboxes and I assume for selects too.
@JoolsCaesar could you give an example on how to do this for select lists?
@nattu1989, there's a working example in the codepen
else if(node.tagName==="SELECT" && node.selectedIdx!=-1){
var options = node.childNodes; // Assumption!
var optionCount = 0;
var selectedIdx = node.selectedIndex;
for(var i=0; i<options.length; i++){
var option = options[i]; // Maybe not an option
if(option.tagName==="OPTION"){
if(optionCount === selectedIdx)
{
options[i].setAttribute('selected', true);
}
else
{
options[i].removeAttribute('selected');
}
optionCount++;
}
}
}
If you're only doing it for select elements, change that else if
to and if
and bung a node.nodeType===1 &&
at the front of the condition. You could probably tidy up that indexing stuff as well with getElementsByTagName. Something like (untested!):
if(node.nodeType===1 && node.tagName==='SELECT' ){
var options = node.getElementsByTagName('OPTION');
var selectedIdx = node.selectedIndex;
for(var i=0; i<options.length; i++){
if(i === selectedIdx){
options[i].setAttribute('selected', true);
}else{
options[i].removeAttribute('selected');
}
}
}
Similar to other comment I do as follow for select
elements using React:
ref.current.querySelectorAll('option').forEach(option => {
if (option.selected) {
option.setAttribute('selected', 'selected')
} else {
option.removeAttribute('selected')
}
})