I'm using a custom, JSF/Primefaces based framework for my web application. Since it's setting a tad too many title attributes, I'm manually removing them all and then, also manually, set them at only a few selected places.
I'm using a MutationObserver to do so and it's working fine in most places. My general approach looks like that:
var column_index_filedownload_filename = 0;
var column_index_filedownload_button = 1;
// look for specific element on my page
var downloadTable = document.querySelector('#download-table');
if (downloadTable) {
// if found, get element of interest - here a table where we want to set the
// title of a button that is present in one column, to the value of another column
var table = downloadTable.querySelector("table");
// header is a row too, we want to check if the table has at least one other row
if (table.rows.length > 1) {
// setting the tooltips of the table as it is on page load
for (var i = 1, row; row = table.rows[i]; i++) {
var filename = row.cells[column_index_filedownload_filename].textContent;
row.cells[column_index_filedownload_button].setAttribute("title", "Downloading " + filename.trim());
}
// in case the table gets sorted, filtered, ..., new rows will
// be displayed and we have to set tooltips again
var observer = new MutationObserver(function( mutations ) {
mutations.forEach(function( mutation ) {
var newNodes = mutation.addedNodes;
if( newNodes !== null ) {
var $nodes = $( newNodes );
$nodes.each(function() {
var isItARow = this.querySelector("td");
if (isItARow) {
var filename = this.cells[column_index_filedownload_filename].textContent;
this.cells[column_index_filedownload_button].setAttribute("title", "Downloading " + filename.trim());
}
});
}
});
});
var config = {
attributes: true,
childList: true,
subtree: true,
characterData: true
};
observer.observe(table, config);
}
}
Now one case where this is not working properly is a page that includes a table that is not rendered if it is empty. The table looks like that:
<div class="upload-div ui-g">
<div class="ui-g-12">
<myframework:dataTable id="fileTable"
value="#{myBean.fileList}" var="file"
rendered="#{!myBean.fileList.isEmpty()}">
<myframework:column id="fileNameColumn" headerText="File Name" width="50%">
<myframework:outputText value="#{file.name}" id="fileNameText" />
</myframework:column>
<myframework:column id="removeFileColumn" headerText="Remove File" width="50%">
<myframework:actionButton id="removeFileColumn"
actionListener="#{myBean.resetFile(file)}"
update="sendForm:uploadJPanel:uploadPanel" />
</myframework:column>
</myframework:dataTable>
</div>
</div>
So basically, at the start, the list of files to upload is empty -> the table isn't shown. I select some files to upload -> the table displays them. I reset my choice -> table's empty again. Now normally, I'd expect my MutationObserver to catch the case that the panel that contains the list gets updated and now displays the table since the file list isn't empty anymore, but the rows never show up within the mutation.addedNodes. Even simply checking for the table isn't working, even though I can clearly see the table onscreen and under the uploadDiv within my DOM:
var table = document.querySelector(".upload-div").querySelector("table");
if (table) {
console.log("Table found!"); // Never shows up
}
I'm running out of ideas here. I tried listening on all attribute changes, but of course it can't work if JS simply won't find the table within the div, even if it is there according to the DOM. Any idea where I went wrong?
Aucun commentaire:
Enregistrer un commentaire