I’m having some problem handling the JS onClick event and Dojo.
Waht i’m trying to achieve is to somehow edit data from the first cell inline.
Consider this HTML:
<table class="datatable" id="officestable" name="officestable">
<tr>
<td>xxxxx</td>
<td>
<button id="officeeditbtn3" data-dojo-type="dijit.form.Button" type="button" data-dojo-props="iconClass:'advanEditIcon',onClick: function() { editOfficeFieldInline(this, 3); }">Edit</button>
<button id="officeconfigbtn3" data-dojo-type="dijit.form.Button" type="button" data-dojo-props="iconClass:'advanConfigIcon',onClick: function() { configOffice(this, 3); }">Config</button>
<button id="officeremovebtn3" data-dojo-type="dijit.form.Button" type="button" data-dojo-props="iconClass:'advanRemoveIcon',onClick: function() { removeOffice(this, 3); }">Remove</button>
</td>
</tr>
To handle all this i have the following (relevant) methods in javascript.
function editOfficeFieldInline(buttonElem, officeid) {
var table = document.getElementById("officestable"); //get table
var operationsCell = buttonElem.domNode.parentNode; // get second cell where button are
var trline = operationsCell.parentNode; // get tr element
var dataCell = trline.firstChild; // get cell where data is to be edited
var currentContent = dataCell.innerHTML; // ... self explainable...
var tdcellHTML;
tdcellHTML = "<input id=\"editofficebox\" type=\"text\">"; // adding an input placeholder
dataCell.innerHTML = tdcellHTML; // replace cell content with edit box
// attach dijit to pre-created edit box
var editofficebox = new dijit.form.TextBox({
value: currentContent,
style: {
width: "190px",
}
},
"editofficebox");
addSaveCancelButtons(table,
operationsCell,
function(){
// 'save' actions
// save new data using ajax (working!)
saveOfficeName(officeid, dataCell, currentContent, operationsCell);
},
function(){
// 'cancel' actions
destroyOfficeFieldInline(table, false);
setCellVal(dataCell, currentContent);
}
);
}
function addSaveCancelButtons(table, operationsCell, saveAction, cancelAction) {
operationsCell.innerHTML += "<button id=\"savebutton\">Save</button>";
operationsCell.innerHTML += "<button id=\"cancelbutton\">Cancel</button>";
var savebutton = new dijit.form.Button({
iconClass: "advanSaveIcon",
onClick: saveAction
},
"savebutton");
var cancelbutton = new dijit.form.Button({
iconClass: "advanCancelIcon",
onClick: cancelAction,
},
"cancelbutton");
}
// this is a generic function. parameters are not really needed in this case
function destroyOfficeFieldInline(tableElement, bNew) {
dijit.byId("editofficebox").destroy();
destroySaveCancelButtons();
if (bNew) {
destroyNewRow(tableElement);
}
}
function destroySaveCancelButtons() {
dijit.byId("savebutton").destroy();
dijit.byId("cancelbutton").destroy();
}
function setCellVal(cell, val) {
cell.innerHTML = val;
}
Now, the code works for the first time.
But somehow, if I click “cancel” after clicking “edit”, then pressing “edit” again will do nothing. The dynamic fields will not be created again.
I’m guessing that something is not being cleaned up correctly, but i ran out of ideas…
What’s wrong with this code?
PS.I’m open to alternative ways to achieve this…
[EDIT]
I found that these seem to be the offending lines of code:
operationsCell.innerHTML += "<button id=\"savebutton\">Save</button>";
operationsCell.innerHTML += "<button id=\"cancelbutton\">Cancel</button>";
As soon as the first one is executed, all buttons within the cell lose their event listeners, namely, onclick.
Anyone knows the reason for this?
Ok. Just figured out what was going on (with the help from Dojo community) so i came back here to share the solution.
The innerHTMl was (supposedly) appended with the new button tags, but in fact it was being replaced, because of the way the += operator works.
When replaced, the original contents were destroyed, and then recreated, but this time without its event listeners / events.
So, the solution is to use the dijit placeAt method: