fix(module: input): preserve focus and caret position for input password when visibility is toggled (#1377)

* set focus when the password button is clicked

* add methods for selection

* set selectionStart after Focus

* fix typescript

* set selectionEnd as well

* fix a stupid if-condition-bug

* remove checks for element

* add selectionStart to getDomInfo

* get selectionStart from Element

* delete unneeded js method

Co-authored-by: mihails.kuzmins <mihails.kuzmins@daytongroup.lv>
Co-authored-by: James Yeung <shunjiey@hotmail.com>
This commit is contained in:
MihailsKuzmins 2021-04-18 11:06:06 +03:00 committed by GitHub
parent 1a10f34029
commit c0f8859914
5 changed files with 36 additions and 3 deletions

View File

@ -26,5 +26,8 @@ namespace AntDesign.Core.Extensions
}
#endif
}
public static ValueTask SetSelectionStartAsync(this IJSRuntime jSRuntime, ElementReference target, int selectionStart) =>
jSRuntime.InvokeVoidAsync(JSInteropConstants.SetSelectionStart, target, selectionStart);
}
}

View File

@ -45,5 +45,8 @@ namespace AntDesign.JsInterop
[JsonPropertyName("clientWidth")]
public int ClientWidth { get; set; }
[JsonPropertyName("selectionStart")]
public int SelectionStart { get; set; }
}
}

View File

@ -106,6 +106,8 @@ namespace AntDesign
public static string SetDomAttribute => $"{FUNC_PREFIX}setDomAttribute";
public static string SetSelectionStart => $"{FUNC_PREFIX}setSelectionStart";
#region Draggable Modal
public static string EnableDraggable => $"{FUNC_PREFIX}enableDraggable";

View File

@ -27,6 +27,7 @@ export function getDomInfo(element) {
result["clientLeft"] = dom.clientLeft || 0;
result["clientHeight"] = dom.clientHeight || 0;
result["clientWidth"] = dom.clientWidth || 0;
result["selectionStart"] = dom.selectionStart || 0;
var absolutePosition = getElementAbsolutePos(dom);
result["absoluteTop"] = Math.round(absolutePosition.y);
result["absoluteLeft"] = Math.round(absolutePosition.x);
@ -672,4 +673,14 @@ export function setDomAttribute(element, attributes) {
for (var key in attributes) {
(dom as HTMLElement).setAttribute(key, attributes[key]);
}
}
}
export function setSelectionStart(element, position) {
if (position >= 0) {
let dom = getDom(element);
if (position <= dom.value.length) {
dom.selectionStart = position;
dom.selectionEnd = position;
}
}
}

View File

@ -1,4 +1,7 @@
using Microsoft.AspNetCore.Components;
using System;
using AntDesign.Core.Extensions;
using AntDesign.JsInterop;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
namespace AntDesign
@ -40,7 +43,18 @@ namespace AntDesign
builder.OpenComponent<Icon>(i++);
builder.AddAttribute(i++, "class", $"{PrefixCls}-password-icon");
builder.AddAttribute(i++, "type", _eyeIcon);
builder.AddAttribute(i++, "onclick", CallbackFactory.Create(this, ToggleVisibility));
builder.AddAttribute(i++, "onclick", CallbackFactory.Create<MouseEventArgs>(this, async args =>
{
var element = await JsInvokeAsync<HtmlElement>(JSInteropConstants.GetDomInfo, Ref);
IsFocused = true;
await this.FocusAsync(Ref);
ToggleVisibility(args);
if (element.SelectionStart != 0)
await Js.SetSelectionStartAsync(Ref, element.SelectionStart);
}));
builder.CloseComponent();
builder.CloseElement();
});