I had originally posted this question without posting the full algorithm. Here is the whole thing.
I have an HTML page like this:
<table id="inputTable">
<tr>
<td>Label1</td>
<td><input type="text" value="" id="inputA1"></td>
<td><span id="inputA1ErrMsg"/></span></td>
<td><input type="text" value="" id="inputA1_"></td>
<td><span id="inputA1ErrMsg_"/></span></td>
</tr>
<tr>
<td>Label1</td>
<td><input type="text" value="" id="inputA2"></td>
<td><span id="inputA2ErrMsg"/></span></td>
<td><input type="text" value="" id="inputA2_"></td>
<td><span id="inputA2ErrMsg_"/></span></td>
</tr>
<tr>
<td>Label1</td>
<td><input type="text" value="" id="inputA3"></td>
<td><span id="inputA3ErrMsg"/></span></td>
<td><input type="text" value="" id="inputA3_"></td>
<td><span id="inputA3ErrMsg_"/></span></td>
</tr>
// ... repeat all the way up to A15.
<tr>
<td>Label1</td>
<td><input type="text" value="" id="inputB1"></td>
<td><span id="inputB1ErrMsg"/></span></td>
<td><input type="text" value="" id="inputB1_"></td>
<td><span id="inputB1ErrMsg_"/></span></td>
</tr>
<tr>
<td>Label1</td>
<td><input type="text" value="" id="inputB2"></td>
<td><span id="inputB2ErrMsg"/></span></td>
<td><input type="text" value="" id="inputB2_"></td>
<td><span id="inputB2ErrMsg"/></span></td>
</tr>
// ... so on up to E1.
</table>
I want my JavaScript to do three things:
It takes input
input*5
and sums up it up. If it is less than 20, show the next input.inputA5 + inputB5 < 20
than show input forinputC*
In the same way, do it for
input*5_
. If it is less than 5, show the next set of input.inputA5_ + inputB5_ < 20
then show input forinputC*_
which isinputC1_
,inputC2_
,inputC3_
... else we hide it.
- Now if, let's say, they enter 20 for
inputA5
and 20 forinputA5_
, then it would not only hide the input but the entire row.
To make it easier I added class = "inputTrigger"
to each of input*5
and inputTrigger_
to each of input*5_
.
jQuery
$("inputTable").on("change", "inputTrigger", function() {
inputChange(this.id, indexArray.indexOf(this.id.replace("input", "").replace("5", "")); // so we can get if it is A, B, C, D
});
My functions:
var indexArray = { 'A', 'B', 'C', 'D', 'E'};
function getTotal(id, index) {
var total = 0;
var len = indexArray.length;
for (var i = 0; i != len; ++i) {
total += parseFloat($(input + indexArray[i] + "5").val());
}
return total;
}
function inputChange(id,currentIndex) {
var nextIndex, total, isShow, MAX_INDEX;
nextIndex = +currentIndex + 1;
MAX_INDEX= '5';
if (nextIndex < MAX_INDEX) {
total = parseFloat(getTotal(id, currentIndex));
if (nextIndex === 1) {
nextIndex += 1;
}
isShow = (total < 20.0 && document.getElementById(id).value > 0.0);
showOrHideInput(isShow, nextIndex, resetValue);
inputChange(id, nextIndex);
}
}
function showOrHideInput(isShow, nextIndex) {
var id1 = $("#input" + nextIndex + "1");
var id2 = $("#input" + nextIndex + "2");
var id10 = .....
var id1Other = $("#input" + nextIndex + "1_");
var id2Other = $("#input" + nextIndex + "2_");
var id10Other = ....
if (isShow) {
if (id1.length) {
id1.show();
}
// ... so on up to id10
}
else {
if (id1.length) {
id1.hide();
}
// .. so on up to id10
}
showOrHideRows(isShow, id1, id1Other);
showOrHideRows(isShow, id2, id2Other);
showOrHideRows(isShow, id3, id3Other);
// ... up to id10.
}
function showOrHideRows(isShow, id, idOther) {
if (isShow) {
id.closest("tr").show();
} else {
if (!idOther.is(":visible")) {
id.closest("tr").hide();
}
}
}
I know my function works but it seems really slow on IE 8 and 9, and sometimes causes a memory leak. I have analyzed the speed with dynaTrace
and showOrHideInput
takes over 800 ms.
- What is the fastest way to tell if a jQuery element is visible? It seems
is(":visible")
has performance hit. - What is the best way to hide the first ancestor table row (in terms of performance)?
.is(':visible')
. \$\endgroup\$