I'm working on the print styling for forms in a web app which uses Kendo. In short: before printing, I append <div>
tags containing each input
's value, and hide the input
tags. The exception is the Kendo MaskedTextBox, as the mask displays the data as intended, and its raw value does not contain the mask.
It's working as intended for everything else - the input
s are hidden, and only the appended div
s are shown.
For the masked textbox, however, the input
is shown (correct), but the div
is still being appended (incorrect).
HTML structure (copied from Edge Dev Tools (F12)):
<div class="mws-form-col-2-8">
<label>Masked TextBox</label>
<span class="k-widget k-maskedtextbox" style="width: 100%;">
<input class="k-textbox" id="maskTest" name="maskTest"
value="1234567890" data-role="maskedtextbox"
style="width:100%" autocomplete="off">
<span class="k-icon k-i-warning"></span>
</span>
<script>kendo.syncReady(...)</script>
<!-- Appended div here: <div class="inputPrint">1234567890</div> -->
</div>
Print css:
input:not(.k-textbox),
span.k-widget:not(.k-maskedtextbox) {
display: none!important;
}
Javascript:
This function is bound to the window.onbeforeprint
event and is called from $(document).ready()
when the media type is "print" (Edge/Chrome can emulate css media type, which I'm using to debug this).
function beforePrint() {
// exclude input.k-textbox
$("input:not(.k-textbox)").each(function () {
// exclude input with .k-maskedtextbox parent
//if (! $(this).parents(".k-maskedtextbox").length) {
if ($(this).parents(".k-maskedtextbox").length <= 0) {
// check if the .inputPrint div already exists
if ($(this).siblings(".inputPrint").length) {
// set text of existing
$(this).siblings(".inputPrint").text($(this).val());
}
else {
// append a div displaying its value to its parent
$(this).parent().append("<div class='inputPrint'>" + $(this).val() + "</div>");
}
}
});
}
As you can see, the selector on the first line of the function (input:not(.k-textbox)
) is the same as in the css.
Display:
Masked TextBox ←- Label
╭────────────────╮
| (123) 456-7890 | ←- input
╰────────────────╯
╭────────────────╮
| 1234567890 | ←- appended div
╰────────────────╯
When I try to figure out how this could have happened by checking some things in the console, this is what I get:
$("#maskTest").is("input:not(.k-textbox)")
false
$("#maskTest").is(".k-textbox")
true
This input should not have even been included in the .each
.
$("#maskTest").parents(".k-maskedtextbox").length
1
$("#maskTest").parents(".k-maskedtextbox").length <= 0
false
If it was included, it should not have entered the first if
statement.
How is this happening, and how can I fix it?
I discovered that the Kendo MVC wrappers expand the inputs into kendo controls in the kendo.syncReady
event, which runs after $(document).ready
is complete.
So on my initial page load, the input I was checking only looked like this:
<input id="maskTest" name="maskTest" style="width:100%" value="1234567890" />