33 Answers, 1 is accepted
To modify the posted value, you will need to wire the form submit event. When event is triggered, you can replace any unwanted character. Check this Kendo Scrathpad demo.
Regards,
Georgi Krustev
Telerik
The MaskedTextBox widget is designed to hold the whole value in one input element and that is why the placeholders are sent to the server too. A possible enhancement of current widget behavior is to strip the placeholder characters on blur. Do you mind open a UserVoice item on this subject? Thus we will gather community feedback for this functionality.
Regards,
Georgi Krustev
Telerik
To modify the posted value, you will need to wire the form submit event. When event is triggered, you can replace any unwanted character. Check this Kendo Scrathpad demo.
[/quote]
Your example only strips the placeholder chars rather than the whole mask. Why isn't there simply a property such as StripMaskBeforePost that auto-strips the mask when set to true built in? I attempted to visit the UserVoice area you linked; however, the url results in a 404 error.
Please excuse me for the incorrect UserVoice link. Here is the correct one:
http://kendoui-feedback.telerik.com/forums/127393-telerik-kendo-ui-feedback
Any feature request should be posted there as this is the best community source, which affects and forms our future road-maps.
Regards,
Georgi Krustev
Telerik
<
ul
data-role
=
"listview"
>
<
li
>
<
label
>
Home Phone:
<
input
type
=
"text"
data-role
=
"maskedtextbox"
data-bind
=
"value: homePhone, events: { change: maskStrip }"
data-mask
=
"(000) 000-0000"
/>
</
label
>
</
li
>
<
li
>
<
label
>
Cell Phone:
<
input
type
=
"text"
data-role
=
"maskedtextbox"
data-bind
=
"value: cellPhone, events: { change: maskStrip }"
data-mask
=
"(000) 000-0000"
/>
</
label
>
</
li
>
</
ul
>
var
vm = kendo.observable({
homePhone:
null
,
cellPhone:
null
,
maskStrip:
function
(e) {
var
that = e.sender,
stripped = that._unmask(that.value()),
obs = e.data,
val = that.element.data(
"bind"
);
if
(val) {
val = val.substring(val.indexOf(
'value: '
) + 7);
//remove properties before
if
(val.indexOf(
','
) > -1) val = val.substring(0, val.indexOf(
','
));
//remove properties after
obs.set(val, stripped);
}
}
});
Check out this fiddle:
http://jsfiddle.net/TaeKwonJoe/vvo95t6h/
Also I enhanced kendo.maskedtextbox.js for v2014.2.903 so that any masked textbox with a data-strip="true" attribute will do this automatically without implementing your own custom change event handler.
<
input
data-role
=
"maskedtextbox"
data-bind
=
"value: transactions.clients.details.instance.CellPhone"
data-mask
=
"(000) 000-0000"
data-strip
=
"true"
required />
As I pointed in the support thread opened on the same subject, we will add a special method that will allow to retrieve the unmasked value. The enhancement will be available in the next official release of Kendo UI due the mid of this month.
Regards,
Georgi Krustev
Telerik
Since we are going to use Telerik's MVC Razor wrapper for accessing the Kendo controls (one of the things that sold us on your package), it seemed we had no client side js script workarounds since the wrapper wires up to the view model directly and seamlessly. The only solution for MVC developers would seem to be an intentional misrepresentation of the data in the View Model (field length 14 rather than 10), and then a server side routine to strip the erroneous data before injecting it back into the database. An ugly solution indeed and I'm glad Telerik is making this a priority enhancement!
Thanks for the good news.
The method is already implemented and will be available in Q1 2015 release of Kendo UI.
I would like to clarify that MaskedTextBox will not modify its value on post. This means that the value of the widget will contain the mask characters on post, until the developer decides to modify the input element manually. This behavior is not related to UI for ASP.NET MVC, but rather is a general HTML approach related to successful controls and their post behavior.
To sum up, the widget will have a method that retrieves the unmasked value, but the widget will still post the masked value. This is related to the fact that the widget actually uses an input element that posts its value and we do not modify it during the form post. This is applicable to ASP.NET MVC too, because the Html helpers (event built-in ones) don't interfere the values that comes from the client either with regular form post or with an Ajax request.
Let me know if something is not clear.
Regards,
Georgi Krustev
Telerik
In short Georgi, I thing your company is off track and simply wrong. You're trying to follow some self imagined "best practice" for your own convenience I suspect and I don't buy your answer. If I'm wrong, feel free to explain, in detail, how so. Also, explain how an ASP.Net MVC developer is going to get the raw data entered by the user on the CLIENT side before sending it to the server because that also would be best practice.. If there's a way I'll shut up. If not, you need to rethink your position and get coding on an option switch.
01.
var $forms = $("form").has("input[data-role='maskedtextbox']");
02.
03.
$forms.submit(function () {
04.
var $maskedtextboxes = $(this).find("input[data-role='maskedtextbox']");
05.
$maskedtextboxes.each(function (index, element) {
06.
// Strip mask characters
07.
element.value = element.value.replace(/[()\s-_]/g, "");
08.
});
09.
});
I will try this later today. So you are saying this little piece of js will execute before the post back executes and passes this to the controller? if so, great!
Also, if this is true, why didn't Telerik just suggest this? Also, makes you wonder how friggin hard this would be to just add to their control with an option switch to control it. The argument that this is somehow bad practice is a joke. Do they really want us to believe that. Best practice is what gets the job done with the least amount of effort and money for development and ongoing maintenance. That's best practice! I don't want a lecture from my suppliers, I just want them to save me money.
Thanks again Bobby.
<div class="input-sm col-xs-8 col-sm-6">
@(Html.Kendo().MaskedTextBoxFor(model => model.HomeTelNum1)
.Name("HomeTelNum1")
.Mask("(999) 000-0000 &&&&&&&&&&&&&&&&&&&&")
.ClearPromptChar(true)
.HtmlAttributes(new { @type = "telnum" })
)
$(document).ready(function() {
var $forms = $("form").has("input[data-role='maskedtextbox']"); $forms.submit(function ()
{
var $maskedtextboxes = $("form").has("input[data-role='maskedtextbox']").find("input[type=telnum]");
$maskedtextboxes.each(function (index, element)
{
// Strip mask characters
element.value = element.value.replace(/[()\s-_]/g, "");
});
});});
As an aside, the code you posted is slightly incorrect (particularly the var $maskedtextboxes line) and should be more like:
$(document).ready(
function
() {
// Gets all forms that contain at least one maskedtextbox
var
$forms = $(
"form"
).has(
"input[data-role='maskedtextbox']"
);
// Update the submit function for all of the found forms
$forms.submit(
function
() {
// Find all of the maskedtextboxes (that are also of type 'telnum') contained within the form that's about to be submitted
var
$maskedtextboxes = $(
this
).find(
"input[data-role='maskedtextbox']"
).find(
"input[type='telnum']"
);
$maskedtextboxes.each(
function
(index, element) {
// Strip mask characters from each of the obtained maskedtextboxes
element.value = element.value.replace(/[()\s-_]/g,
""
);
});
});
});
I've added some more comments to help better explain what each piece of the code is doing. The way you wrote your version of the code, it would strip the mask off of all maskedtextboxes rather than just the ones within the current submitted form. I'm not sure if this is what causing the blinking you mentioned, or if it's just a general downside of the stripping.
In addition, var $maskedtextboxes = $(this).find("input[data-role='maskedtextbox']"); already finds all of the maskedtextboxes contained within the form that's about to be submitted, so you don't have to manually mark them (i.e. type="telnum") unless you are using 2+ different masks. Even then, you don't have to manually mark them unless you can't write the regex expression generically enough to handle all the masks at the same time.
Yes I'm adding the extra identifier so I can control what funnels into this function and what doesn't. This will work for tel#'s, zipcodes, etc., but in case there are other things down the road, I wanted to isolate it.
As far as "blinking"; that was the wrong word. All I was saying is that the function executes faster than the page refreshing after the post (even using ajax.beginform to isolate the affected div). So the user sees the mask disappear the moment they press submit. It's not professional looking but it will have to do.
Thanks for the updated code, and the inline comments. I'm sure this is going to help many others that stumble across this thread.
var $maskedtextboxes = $(this).has("input[data-role='maskedtextbox']").find("input[type='unmaskstandard']");
I would like to inform you that we've decided to add the "unmasking on post" functionality for the upcoming release. Thus developers that want to strip the value on post will not need to do this manually. Instead, they will just set an option that will control this behavior.
Please note that this functionality will work only for regular form posting. Scenarios where Kendo UI MVVM or AngularJS are used, the model field will be set to the masked value, because the available bindings/directives use widget's value method.
Regards,
Georgi Krustev
Telerik
We certainly have a js solution for now, but it is flawed and does not present a clean visual UX since the user can see the affects of the script running and the mask vanishing from the textboxes before the controller returns it's response and the screen refreshes.
An intrinsic control solution that leaves the display box intact but quietly returns an unmasked version to the server is indeed the ultimate solution. When is the ETA of this "upcoming release"?
The next official release is due the mid of next week (mid of March 2015).
Regards,
Georgi Krustev
Telerik
Georgi,
It's been a couple months since I last posted and the project was put aside since then for other priorities. But its back on the front burner and I'm looking to implement this change. In March you said this new feature would be added shortly. I assume its available now and our normal updates already have it available to the project. But how do we find out how this feature was implemented? Where is documentation? I've searched online and don't seem to see anything. Thanks
- http://docs.telerik.com/kendo-ui/api/javascript/ui/maskedtextbox#configuration-unmaskOnPost
- http://docs.telerik.com/kendo-ui/api/aspnet-mvc/Kendo.Mvc.UI.Fluent/MaskedTextBoxBuilder#methods-UnmaskOnPost(System.Boolean)
Regards,
Georgi Krustev
Telerik
Thanks Georgi. I saw that. I tried that yesterday. It had no effect of stripping masking characters before the value was returned to the controller. I thought that might have been something that only affected the UI.
Am I doing something wrong? I simply added it as follows but the mask was still passed back to the bound model in the controller.
@(Html.Kendo().MaskedTextBoxFor(x => Model.WorkTelNum)
.Mask("(999) 000-0000")
.ClearPromptChar(true)
.UnmaskOnPost(true)
)
The repro demo is attached to this ticket.
Regards,
Georgi Krustev
Telerik
Hmmm, you're right. Your demo worked. yet if I do the same thing in my "real world" app it doesn't. I tried adding some more complexity to your demo, like doing it inside an ajax call and more complex html page, but it still worked. I also upgraded your demo to the latest build (which it was not using). It still works. So there is something in my project that is breaking this and I don't know what it is. I'll look further. If I find the cause I'll post it here. if not, I'll take this offline and open a "ticket".
Thanks for the demo.
Hi everyone
I tested the solution provided by Georgi and i think is something good to start ..in my case i am looking for a different solution though
In my code I need to send my form by hand ( i dont have a sunimit button on the form) ...i mean i use the serializeArray function from jquery and we still receive the complete text (mask included on it)...is there any way to include a general property that a developer can access to it in all cases?. I use many different masks and i would like not to have to program a method for get the text of every MaskedText
thanks a lot for your help
>>
Please note that this functionality will work only for regular form
posting. Scenarios where Kendo UI MVVM or AngularJS are used, the model
field will be set to the masked value, because the available
bindings/directives use widget's value method.
>>
Are there any plans to change that ? I am using MVVM together with a lot of maskedtextboxes and so for me the maskedTextBoxes are useless.
I would suggest you us a custom MVVM binding if you would like to use the raw method instead of value. Here is a demo that demonstrates how to accomplish this task:
We do not have any specific plans to change the current MVVM value binding behavior when used with MaskedTextBox. The proper solution for the time being is to use the shared custom MVVM binding.
Regards,
Georgi Krustev
Telerik
Hi Georgi,
thank you for the demo. That is exactly what i needed ! Works perfect !
Have a nice day
Dirk
(function ($) {
var kendo = window.kendo,
ui = kendo.ui,
MaskedTextBox = ui.MaskedTextBox;
var extendedMaskedTextBox = MaskedTextBox.extend({
init: function (element, options) {
var self = this,
id = element.id,
name = element.name,
suffix = '_input',
input = $(kendo.template(self._inputTemplate)({ id: id, name: name }));
self.input = input;
// base call to widget initialization
MaskedTextBox.fn.init.call(this, element, options);
element = self.element;
// swap the data
input.data(element.data());
element.data({});
element.attr({ id: id + suffix, name: name + suffix });
element.after(input);
element.on('keyup', $.proxy(self.updateValue, self));
element.on('blur', $.proxy(self.updateValue, self));
// is this covered by keyup?
element.on('paste', $.proxy(self.updateValue, self));
self.updateValue();
},
updateValue: function () {
var self = this,
element = self.element,
input = self.input,
options = self.options,
unmasked = self._unmask(element.val(), 0);
if (options.postMaskedValue) {
input.val(element.val());
} else {
input.val(unmasked.replace(new RegExp(options.promptChar, "g"), ""));
}
},
_mask: function (start, end, value, backward) {
var self = this;
MaskedTextBox.fn._mask.call(self, start, end, value, backward);
self.updateValue();
},
_inputTemplate: '<
input
id
=
"#= id #"
name
=
"#= name #"
type
=
"text"
style
=
"display:none"
/>',
options: {
sourceAction: ''
}
});
ui.plugin(extendedMaskedTextBox);
}(jQuery));