MudBlazor
MudBlazor copied to clipboard
MudDatePicker with mask jump back caret on input in Server Side
Bug type
Component
Component name
MudDatePicker
What happened?
When i develop local it not visible, but if publish on remote linux. Linux on low resources VM.
I see how every cursor jumping back if i type quickly.
<MudDatePicker Label="Date" @bind-Date="@DocDate" Editable="true" Clearable="true" Mask="@(new DateMask("dd.MM.yyyy"))" DateFormat="dd.MM.yyyy" > </MudDatePicker>
Expected behavior
In Remote ServerSide App if quickly type from keyboard date caret in field stay at end of input.
Reproduction link
https://try.mudblazor.com/snippet/cEcxOzkyxAkCxykM
Reproduction steps
- run server side app with datepicker with mask editable and clearable.
- in developer console browser set network type to slow 3g
- try quickly type from keyboard date. for example 12.12.12, result 12.12.1|2 or even worse like 1012002
Relevant log output
No response
Version (bug)
6.1.8
Version (working)
No response
What browsers are you seeing the problem on?
Firefox, Chrome, Microsoft Edge
On what operating system are you experiencing the issue?
Windows
Pull Request
- [ ] I would like to do a Pull Request
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
I think this is because mask computed on server. Better if it will be on client side.
Hi @altbodhi, the cursor jumping is due to server side latency. You can try using Cleave.js locally instead.
Hi @altbodhi, the cursor jumping is due to server side latency. You can try using Cleave.js locally instead.
Cleave.js applied to MudDatePicker is work but on enter to change date, in MudDatePicker without js masked if i type Enter it change value.
Also having this issue. Is anyone able to share an example or reference showing how to apply Cleave.js to this situation? Thanks
Same with me. I would greatly appreciate it if anyone could provide an example or reference demonstrating how to apply Cleave.js in this particular situation.
Hi, i figured out, here is a short example of how to implement it: https://github.com/csuka1219/CleaveMudDateMask
Hi, i figured out, here is a short example of how to implement it: https://github.com/csuka1219/CleaveMudDateMask
I am try to use your example with slow 3g settings but it work unstable. 1) not apply mask if reload page 2) after start mask work but value not aply to component.
For me it works well, the only problem is that i need to click out of the datepicker component's focus to bind the value to the DateTime variable, I'm working on the solution of the problem.
For me it works well, the only problem is that i need to click out of the datepicker component's focus to bind the value to the DateTime variable, I'm working on the solution of the problem.
Thanks @csuka1219 your solution is really appreciated. The masking works well for me with no cursor jumping but I also have the problem you mentioned. It does not bind until the element loses focus. In my case I need it to bind once the text is a valid date but I have not found a way to do that or access the string from blazor code. If you have any progress of tips I would be very grateful.
Hey @dennml, I think I've found a possible solution. I've added a commented line to the example, please uncomment it and give it a try. I would be grateful if You could let me know later it's solved your problem or not. The point is, I've also set the MudBlazor mask to the component. I don't think its the best way, but if you try every datepicker example on https://mudblazor.com/components/datepicker#api you'll see that none of them bind dynamically except for the masked ones.
@dennml If You want to access to the string you can override the StringValueChanged method like this:
protected override Task StringValueChanged(string value)
{
if(value.Length == 10) //or smth like this
{
//Do smth
//or you can call this method, it's set the component date value
SetDateAsync(Converter.Get(value), false);
//Or just like this
base.Date = smthStringToDate(value);
}
return base.StringValueChanged(value);
}
@csuka1219 I was trying with
protected override Task StringValueChanged(string value)
{
if (!string.IsNullOrEmpty(value))
{
if (DateTime.TryParseExact(value, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime validDate))
{
Date = validDate;
}
}
return base.StringValueChanged(value);
}
But the problem is that StringValueChanged is not invoked when I type into the MudDateField from your github sample. It is only invoked if the focus changes away from that component. If that was invoked when typing, it would set the Date value as soon as a valid date is typed. I can confirm that StringValueChanged does get invoked when typing if I set Mask like the commented line in your sample. However that causes the original issue where the caret jumps around with the mud masking; exactly the issue we're trying to avoid. This seems to indicate that StringValueChanged does not get invoked by MudBlazor when typing if Mask is null. If we could change that so it does get invoked, I think your solution with cleave.js would work perfectly.
what do you think about fix bug without any js code? maybe in datepicker has some wrong async (not synchronized) calls.
I created a new issue #7391 and raised a PR so that TextChanged and StringValueChanged will be invoked as the user types.
what do you think about fix bug without any js code? maybe in datepicker has some wrong async (not synchronized) calls.
If someone is able to address this purely in MudBlazor, I'm sure that would be the preferred solution. Is this something you're able to look into @altbodhi ?
For now I've raised a PR to help with the cleave.js approach and other useful scenarios such as the snippet I created in #7391
what do you think about fix bug without any js code? maybe in datepicker has some wrong async (not synchronized) calls.
It is my understanding that this problem is impossible to fix in C# on server side blazor. The problem is simply the nature how BSS works:
That's why the only feasible solution for masking on BSS is to do it directly on the browser in JS.
May be simply skip update input if it not equal?
@altbodhi That would be a JavaScript solution (and I wouldn't even know how to do this, because you would fight the Blazor engine), above you suggested a C# solution.
Clearly doing masking in JavaScript is the easier and cleaner way.
@csuka1219 the latest MudBlazor 6.10.0 has the new ImmediateText parameter. You may want set that to true and try again with your Cleave.js solution.
@dennml Thank you for notifying me. I have implemented it, and now it works well.
@csuka1219 -- how were you able to implement it?
I'm running into the same issue -- where my caret jumps around due to being Blazor Server-- and I've got the eventListener firing as expected and cleave-zen formats the string, but I've been completely unable to inject the value back into the input in a way that updates the MudDatePicker text box.
@matneyx Here is a working demo, but you can ask me anything if something isn't clear. https://github.com/csuka1219/CleaveMudDateMask