Blazor - domyślna obsługa Tab vs @onkeydown:preventDefault="true"

0

Cześć,
mam w componencie input, który przechwytuje operacje na klawiaturze (onkeydown).
Dodatkowo musiałem ustawić w nim opcję @onkeydown:preventDefault="true" - aby można było automatycznie zaznaczyć fragment tekstu w tym inpucie (inaczej zaznaczony tekst nie był widoczny).

Problem jest taki, że jak ustawimy wspomnianą opcję i wejdziemy do takiego inputa to nie działa Tab -> mogę w nim pisać, ale nie mogę przejść do kolejnego inputa. Dlatego, że nie wiem ile i jakie inputy będą na danej podstronie to nie mogę ręcznie ustawić focusa na kolejnym elemencie. Chcę aby w tym inpucie po wciśnięciu Tab przeglądarka z automatu ustawiła mi kolejny element. Czy można zrobić, aby po wciśnięciu Tab input obsłużył domyślne zdarzenie?
Z góry dzięki za pomoc.

0

Czy to znaczy, że budujesz UI w pętli? Jeśli tak, to przypisz do inputa tabindex swoją wartość z pętli. Na przykład:

var i =1;
@foreach (var input in InputList) 
{ 
    <input tabindex="@i">
    i++;
}
0

@AdamWox nie, nie chodzi o tabindex tylko o fakt, że nie mogę w ogóle wyjść z pola inputa klikając tab (tab jest przechwytywany razem z innymi klawiszami z klawiatury). W componencie jest tylko jeden input, ale jak dałem dwa obiekty takiego komponentu na jednej stronie (dwa inputy) to program nie przeskakuje z jednego do drugiego gdy kliknę tab.
Jest to konsekwencja zastosowania @onkeydown:preventDefault="true" - jak to usunę z inputa to zaczyna mi działać.
Dodatkowo ważna informacja - poza klawiaturą przechwytuję również operacje onclick, onfocus, onfocusout, ale lista nie jest zamknięta jeszcze.

0

Co potrzebujesz zrobić w tym onkeydown?

0

@AdamWox chcę zrobić pole dla daty takie samo jak jest w Optimie (Ty pewnie wiesz jak to tam działa). Tzn. jak kliknę myszką to ma się zaznaczyć wybrany fragment daty a jak kliknę strzałką w lewo/w prawo to ma mi się zmienić pole daty. Dodatkowo u mnie jest opcja narzucenia jak ma się wyświetlać data RRRR-MM-DD / DD-MM-RRRR.
Musiałem ustawić @onkeydown:preventDefault="true" bo bez tego nie zaznaczał mi się fragment daty przy klikaniu strzałkami (tzn. pole się zaznaczało, ale zaznaczenie było niewidoczne dla użytkownika). Pojawił się jednak kolejny problem z tabulacją, która przestała działać gdy wspomniany parametrem jest ustawiony i chwilowo nie przychodzi mi do głowy żadne rozwiązanie :/
Na pewno muszę jeszcze poczytać o preventDefault oraz stopPropagation, bo ciągle nie jestem pewny jak to działa.

Mój input chwilowo wygląda tak:

	<input 
		type="text"
		@bind-value="@custom_date" 
		@bind-value:event="oninput" 
		@ref="ref_to_date"
		@onclick="@(async () => await OnClick())"
		@onfocus="@(async () => await OnFocus())"
		@onkeydown="@(async e => await OnKeyDown(e))"
		@onkeydown:preventDefault="true"
		@onkeydown:stopPropagation="true"
		@onfocusout="OnFocusOut"
		onkeypress = "return (event.charCode !=8 && event.charCode ==0 || (event.charCode >= 48 && event.charCode <= 57) || event.charCode == 44 || event.charCode == 46 || event.charCode == 9)"
		tabindex="1"
		maxlength="10"
		/>

W metodach OnClick, OnFocus jak rwnie OnKeyDown korzystam z funkcji do zaznaczania fragmentu tekstu (JS), tj.

function SelectPartOfText(reference, start_position, end_position) {
	reference.setSelectionRange(start_position, end_position);
}
0

To znaczy, że naciśnięcie tabulatora sam musisz oprogramować w onkeydown i przejść do następnego inputa, ale wydaje mi się, że ta gra nie jest warta świeczki.

PS.
Zawsze możesz skorzystać z takich dobroci jak DevExpress, Telerik, albo Syncfusion. Na przykład:
DatePicker - Incremental Steps

0

@AdamWox tam, gdzie nie jest to konieczne (gdzie sam dam radę coś zrobić) nie chcę korzystać z zewnętrznych narzędzi (dzięki temu sam się czegoś uczę i robię dokładnie tak jak coś zaplanowałem - to projekt domowy).

A czy jest możliwość wykonać domyślną czynność dla TAB? Tj. jakoś deaktywować preventDefalt dla TAB?
Tak jak pisałem wcześniej ja nie wiem który element będzie następny w kolejności jeśli chodzi o tabulację, bo data może być wszędzie wykorzystywana.

1

A nie było by najprościej postawić parę ifów i sprawdzać jaki klawisz został naciśnięty i tam gdzie jest tab to puścić dalej domyślnie, a tam gdzie nie ma tab to preventDefault(). Tutaj prawdopodobnie będziesz musiał skorzystać z IJSRuntime.

Tutaj Pan Jason pokazuje na przykładzie pobierania/zapisywania danych w localStorage
Modern Web Dev with Blazor and .NET 6 with Jason Taylor
Może to ciebie chociaż trochę nakieruje, bo on logikę JS trzyma w osobnym pliku BlazorDemo.js i z pomocą statycznej klasy idzie fajnie i czytelnie te funkcje wywoływać w C#.

1

@AdamWox ale ja właśnie sprawdzam jaki klawisz jest wciśnięty, tylko nie wiedziałem, jak przywrócić domyślny sposób działania dla klawisza Tab.
Ale znalazłem właśnie rozwiązanie - wystarczy skorzystać ze zmiennej dla preventDefault tak jak tutaj opisane: https://www.meziantou.net/how-to-use-event-preventdefault-in-blazor.htm
Dzięki za aktywność :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1