I have a table that is created using javascript based on what is put in a list. This works fine in Jquery 3.4, but when I upgrade to 3.5 I am seeing this break.
HTML
<h5>Questions</h5>
<table id="questionTable" class="table q">
<thead>
</thead>
<tbody id="qTable"></tbody>
</table>
<div id="questionDiv">
<input type="button" value="Add Question" onclick="AddNewQuestion()" class="btn btn-primary"/>
</div>
<hr />
<div id="questionDiv">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
Javascript
<script type="text/javascript">
$(document).ready(function () {
$(function () {
AddCurrentQuestions();
});
});
var table = document.getElementById("qTable");
var rowCount = table.rows.length;
var counter = rowCount.length;
function AddCurrentQuestions() {
var status = @Html.Raw(Json.Encode(Model.isNull));
if (status == false) {
@{ Model.QuestionList.Add(new Performance_Planning.ViewModel.QuestionViewModel.Questions());}
var questionItems = JSON.parse('@Html.Raw(Json.Encode(@Model.QuestionList))');
for (var i = 0; i < questionItems.length - 1; i++) {
var qItem = questionItems[i];
var questionDetail = qItem.Question;
//Create fields
var qTextCell = "<td><textarea id='QuestionList_" + i + "_Question' name='QuestionList[" + i + "].Question' class='Questions' /></td>";
var indexCell = "<td style='display:none'> <input name='QuestionList.Index' type='hidden' value='" + i + "' /></td>";
var removeCell = "<td align='center'><input id='btnDelLine'" + i + "type='button' value='Remove' onclick=\"removeRow('" + i + "')\" class='btn btn-primary' /></td>";
var newRow = "<tr id='qLineItem" + i + "'>" + indexCell + qTextCell + removeCell + "</tr>";
//Add row to table
$('#qTable').append(newRow);
//Add Values
$('#QuestionList_' + i + "_Question").val(questionDetail)
counter = i;
};
} else {
counter = 0;
AddNewQuestion();
}
};
function AddNewQuestion() {
@{ Model.QuestionList.Add(new Performance_Planning.ViewModel.QuestionViewModel.Questions());}
counter++;
//Create field
var indexCell = "<td style='display:none'> <input name='QuestionList.Index' type='hidden' value='" + counter + "' /></td>";
var qTextCell = "<td><textarea id='QuestionList_" + counter + "_Question' name='QuestionList[" + counter + "].Question' class='Questions' /></td>";
var removeCell = "<td align='center'><input id='btnDelLine'" + counter + "type='button' value='Remove' onclick=\"removeRow('" + counter + "')\" class='btn btn-primary' /></td>";
var newRow = "<tr id='qLineItem" + counter + "'>" + indexCell + qTextCell + removeCell + "</tr>";
$('#qTable').append(newRow);
};
function removeRow(id) {
var rowId = "qLineItem" + id;
var row = document.getElementById(rowId);
row.parentNode.removeChild(row);
};
</script>
}
What I end up seeing is that the remove button is treated as text in 3.5.1 but this doesn't occur with 3.4. I am unsure how to solve this issue or if I will need to figure out another way to write this page.
When I view the webpage and inspect the field I see it do the following:
<textarea id="QuestionList_0_Question" name="QuestionList[0].Question" class="Questions">
"</td><td align='center'><input id='btnDelLine'0type='button' value='Remove' onclick="removeRow('0')" class='btn btn-primary' /></td></tr></tbody></table>"
The textarea
element should have a separate close tag. It is not allowed to self-close. So this is not valid HTML:
<textarea />
But this is:
<textarea></textarea>
Apparently, jQuery 3.5 is more strict in this. An inspection of the 3.5 changelog reveals that this is a consequence of the security fix they applied:
The main change in this release is a security fix, and it’s possible you will need to change your own code to adapt. Here’s why: jQuery used a regex in its
jQuery.htmlPrefilter
method to ensure that all closing tags were XHTML-compliant when passed to methods. For example, this prefilter ensured that a call likejQuery("<div class='hot' />")
is actually converted tojQuery("<div class='hot'></div>").
Recently, an issue was reported that demonstrated the regex could introduce a cross-site scripting (XSS) vulnerability.The HTML parser in jQuery <= 3.4.1 usually did the right thing, but there were edge cases where parsing would have unintended consequences. The jQuery team agreed it was necessary to fix this in a minor release, even though some code relies on the previous behavior and may break. The
jQuery.htmlPrefilter
function does not use a regex in 3.5.0 and passes the string through unchanged.
One can see how before 3.5, jQuery would actually change <textarea />
to <textarea></textarea>
on the fly, thereby fixing the error you made. But now with version 3.5 jQuery no longer does that, and so your HTML remains invalid, leading to an unintended rendering where everything after <textarea />
ends up as content to that text area element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With