Number Input - mousewheeel fix, prevent of enetering flase characters
This commit is contained in:
		
							parent
							
								
									ed15c8f24d
								
							
						
					
					
						commit
						1fd0028557
					
				| @ -5,18 +5,18 @@ | ||||
| @typeparam NumberType | ||||
| 
 | ||||
| <div class="@InputFieldClassList"> | ||||
|     <input type="number" | ||||
|     <input type="text" | ||||
|            placeholder="@Placeholder" | ||||
|            step="@_step" | ||||
|            disabled="@Disabled" | ||||
|            readonly="@Readonly" | ||||
|            @onmousewheel="@OnMouseWheel" | ||||
|            @onwheel="@OnMouseWheel" | ||||
|            @oninput=@ChangeValueAsync | ||||
|            @bind-value="@Value" | ||||
|            @attributes="@InputAttributes"> | ||||
|            </input> | ||||
| 
 | ||||
|            @onkeydown=@(args => ChangeValue(args)) | ||||
|            @onkeydown:preventDefault="@_preventDefaultAction" | ||||
|            @oninput=@GetValueAsync | ||||
|            @onmousewheel=@OnMouseWheel | ||||
|            @onwheel="OnMouseWheel" | ||||
|            @bind-value="@_value" | ||||
|            @attributes="@InputAttributes" /> | ||||
|      | ||||
|     <span class="highlight"></span> | ||||
|     <span class="bar"></span> | ||||
| @ -34,6 +34,10 @@ | ||||
|     } | ||||
|     <span class="input-glyph-wraper"> | ||||
|         <span class="input-glyph"> | ||||
|             <span style="display:inline-block"> | ||||
|                 <Glyph Width=16 Height=16 SVG="@Icons.Material.Outlined.KeyboardArrowUp" Click="StepUp" /> | ||||
|                 <Glyph Width=16 Height=16 SVG="@Icons.Material.Outlined.KeyboardArrowDown" Click="StepDown"></Glyph> | ||||
|             </span> | ||||
|             @if (Clearable && Value.ToString().Length > 0) | ||||
|             { | ||||
|                 <span class="input-glyph button" @onclick="Clear"> | ||||
|  | ||||
| @ -3,11 +3,11 @@ using Connected.Utilities; | ||||
| using Microsoft.AspNetCore.Components; | ||||
| using Microsoft.AspNetCore.Components.Web; | ||||
| using System.Numerics; | ||||
| using static Connected.Colors; | ||||
| 
 | ||||
| namespace Connected.Components; | ||||
| public partial class NumberInput<NumberType>:InputBase where NumberType : INumber<NumberType> | ||||
| { | ||||
| 
 | ||||
| 	private double _step =1; | ||||
| 	[Parameter] | ||||
| 	public double Step {  | ||||
| @ -22,30 +22,56 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe | ||||
| 	} | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public bool DisableMouseWheel { get; set; } = false; | ||||
| 	public bool DisableMouseWheel | ||||
| 	{ | ||||
| 		get; | ||||
| 		set; | ||||
| 	} = false; | ||||
| 
 | ||||
| 	private async Task StepUp() | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			double num = (double)Convert.ChangeType(Value, typeof(double)); | ||||
| 			num += _step; | ||||
| 		Value = AdjustDecimalPlaces((NumberType)Convert.ChangeType(num, typeof(NumberType))); | ||||
| 			if (DecimalPlaces > 0) | ||||
| 				num = Math.Round(num, DecimalPlaces); | ||||
| 			Value = (NumberType)Convert.ChangeType(num, typeof(NumberType)); | ||||
| 			if (IsError) ErrorText = string.Empty; | ||||
| 		} | ||||
| 		catch | ||||
| 		{ | ||||
| 			ErrorText = "Error with step up!"; | ||||
| 			Value = default(NumberType); | ||||
| 		} | ||||
| 		await ValueChanged.InvokeAsync(Value); | ||||
| 	} | ||||
| 
 | ||||
| 	private async Task StepDown() | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			double num = (double)Convert.ChangeType(Value, typeof(double)); | ||||
| 			 | ||||
| 			num -= _step; | ||||
| 		Value = AdjustDecimalPlaces((NumberType)Convert.ChangeType(num, typeof(NumberType))); | ||||
| 			if (DecimalPlaces > 0) | ||||
| 				num = Math.Round(num, DecimalPlaces); | ||||
| 			Value = (NumberType)Convert.ChangeType(num, typeof(NumberType)); | ||||
| 			if (IsError) ErrorText = string.Empty; | ||||
| 		} catch | ||||
| 		{ | ||||
| 			ErrorText = "Error with step down!"; | ||||
| 			Value = default(NumberType); | ||||
| 		} | ||||
| 		await ValueChanged.InvokeAsync(Value); | ||||
| 	} | ||||
| 	protected async Task OnMouseWheel(WheelEventArgs obj) | ||||
| 	protected async Task OnMouseWheel(WheelEventArgs args) | ||||
| 	{ | ||||
| 		if (DisableMouseWheel==false) | ||||
| 		if (DisableMouseWheel == false) | ||||
| 		{ | ||||
| 			if (!obj.ShiftKey || Disabled || Readonly) | ||||
| 			if (args.ShiftKey || Disabled || Readonly) | ||||
| 				return; | ||||
| 			if (obj.DeltaY < 0) | ||||
| 			if (args.DeltaY >= 0) | ||||
| 			{ | ||||
| 				await StepDown(); | ||||
| 			} | ||||
| @ -53,69 +79,136 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe | ||||
| 			{ | ||||
| 				await StepUp(); | ||||
| 			} | ||||
| 		} else | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private string _value; | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public NumberType Value | ||||
| 	public NumberType? Value | ||||
| 	{ | ||||
| 		get; | ||||
| 		set; | ||||
| 		get | ||||
| 		{ | ||||
| 			if (string.IsNullOrEmpty(_value)) return default(NumberType); | ||||
| 			return (NumberType)Convert.ChangeType(_value, typeof(NumberType)); | ||||
| 		} | ||||
| 		set | ||||
| 		{ | ||||
| 			_value = value.ToString(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public int DecimalPlaces { get; set; } =0; | ||||
| 
 | ||||
| 
 | ||||
| 	[Parameter] | ||||
|    public EventCallback<NumberType> ValueChanged { get; set; } | ||||
| 
 | ||||
| 	public async Task ChangeValueAsync(ChangeEventArgs args) | ||||
| 	public async Task GetValueAsync(ChangeEventArgs args) | ||||
|     { | ||||
| 		if (args.Value is not null) | ||||
| 		{ | ||||
| 				NumberType value = (NumberType)Convert.ChangeType(args.Value, typeof(NumberType)); | ||||
| 				if (value.ToString().Length <= 0) | ||||
| 			string newVal = args.Value.ToString(); | ||||
| 			if (!newVal.Equals("0")) | ||||
| 			{ | ||||
| 
 | ||||
| 					value = (NumberType)Convert.ChangeType(0, typeof(NumberType)); | ||||
| 				if (newVal.ToString().Contains("-")) | ||||
| 					newVal = "-" + newVal.ToString().Replace("-", ""); | ||||
| 				if (newVal.ToString().ToLower().Contains("e")) | ||||
| 					newVal = "e" + newVal.ToString().Replace("e", ""); | ||||
| 			} | ||||
| 				await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(AdjustDecimalPlaces(value), typeof(NumberType))); | ||||
| 			if (string.IsNullOrEmpty(newVal)) | ||||
| 			{ | ||||
| 				await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(AdjustDecimalPlaces((NumberType)Convert.ChangeType(null, typeof(NumberType))), typeof(NumberType))); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (!newVal.Equals(_value)) | ||||
| 					await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(AdjustDecimalPlaces((NumberType)Convert.ChangeType(newVal, typeof(NumberType))), typeof(NumberType))); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	[Parameter] public EventCallback<KeyboardEventArgs> OnKeyDown { get; set; } | ||||
| 
 | ||||
| 	private bool CheckKey(string key) | ||||
| 	{ | ||||
| 		bool result; | ||||
| 		if (Helper.IsNumeric(key)) return true; | ||||
| 		switch (key.ToLower()) | ||||
| 		{ | ||||
| 			case "backspace": | ||||
| 			case "delete": | ||||
| 			case "arrowleft": | ||||
| 			case "arrowright": | ||||
| 			case "-": | ||||
| 				//case "e": | ||||
| 				{ | ||||
| 					result = true; | ||||
| 					break; | ||||
| 				} | ||||
| 			default: | ||||
| 				{  | ||||
| 					result = false; | ||||
| 					break; | ||||
| 				} | ||||
| 		} | ||||
| 
 | ||||
| 		if ((key.Equals("-") || key.Equals("-")) && _value.Contains(key)) result = false; | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
| 	private bool _preventDefaultAction = true; | ||||
| 	public async Task ChangeValue(KeyboardEventArgs args) | ||||
| 	{ | ||||
| 		_preventDefaultAction= true; | ||||
| 		if (args is not null) | ||||
| 		{ | ||||
| 			var key = args.Key.ToString().ToLower(); | ||||
| 			if (CheckKey(key)) | ||||
| 			{ | ||||
| 				_preventDefaultAction = false; | ||||
| 
 | ||||
| 				await OnKeyDown.InvokeAsync(args); | ||||
| 			} | ||||
| 		} else | ||||
| 		{ | ||||
| 			args.Key = null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private NumberType AdjustDecimalPlaces(NumberType value) | ||||
| 	{ | ||||
| 		NumberType result = value; | ||||
| 		if (Helper.NumberHasDecimalPlaces(value)) | ||||
| 		{ | ||||
| 		var result = value; | ||||
| 		if (DecimalPlaces > 0) | ||||
| 		{ | ||||
| 				decimal rounded = (decimal)Convert.ChangeType(value, typeof(decimal)); | ||||
| 				rounded = Math.Round(rounded, DecimalPlaces); | ||||
| 				result = (NumberType)Convert.ChangeType(rounded, typeof(NumberType)); | ||||
| 			} | ||||
| 			double converted = Math.Round((double)Convert.ChangeType(result, typeof(double)), DecimalPlaces); | ||||
| 			return (NumberType)Convert.ChangeType(converted, typeof(NumberType)); | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
| 	private async Task Clear() | ||||
| 	{ | ||||
| 		_value = string.Empty; | ||||
| 		await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(0, typeof(NumberType))); | ||||
| 	} | ||||
| 
 | ||||
| 	#region Lifecycle | ||||
| 
 | ||||
| 	protected override async Task OnInitializedAsync() | ||||
| 	protected override async Task OnAfterRenderAsync(bool firstRender) | ||||
| 	{ | ||||
| 		if (DecimalPlaces > 0) | ||||
| 		if (firstRender) | ||||
| 		{ | ||||
| 			if (!DecimalPlaces.Equals(Helper.GetDecimalPlaces(Value))) | ||||
| 			{ | ||||
| 				Value = AdjustDecimalPlaces(Value); | ||||
| 			await ValueChanged.InvokeAsync(Value); | ||||
| 				StateHasChanged(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	#region Lifecycle | ||||
| 	protected override async Task OnParametersSetAsync() | ||||
| 	{ | ||||
| 		if (typeof(NumberType).Name.ToLower().Contains("int")) | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| using Connected.Utilities; | ||||
| using Microsoft.AspNetCore.Components; | ||||
| using static Connected.Colors; | ||||
| using static System.Net.Mime.MediaTypeNames; | ||||
| 
 | ||||
| namespace Connected.Models; | ||||
| public class InputBase : ComponentBase | ||||
| @ -71,6 +73,22 @@ public class InputBase : ComponentBase | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/// <summary> | ||||
| 	/// Fired when the text value changes. | ||||
| 	/// </summary> | ||||
| 	[Parameter] public EventCallback<string> TextChanged { get; set; } | ||||
| 	public string Text { get; set; } | ||||
| 
 | ||||
| 	protected virtual async Task SetTextAsync(string text) | ||||
| 	{ | ||||
| 		if (Text != text) | ||||
| 		{ | ||||
| 			Text = text; | ||||
| 			await TextChanged.InvokeAsync(text); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	private string _helperText = string.Empty; | ||||
| 	[Parameter] | ||||
| 	public string HelperText | ||||
|  | ||||
| @ -135,11 +135,11 @@ public static class Helper | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static bool IsVariableNumeric(string input) | ||||
| 	public static bool IsNumeric(string input) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			var number = Decimal.Parse(input); | ||||
| 			var number = Double.Parse(input); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch | ||||
|  | ||||
| @ -10,6 +10,7 @@ namespace Connected.Utilities; | ||||
| public struct StyleBuilder | ||||
| { | ||||
| 	private string stringBuffer; | ||||
| 	private string style; | ||||
| 
 | ||||
| 	/// <summary> | ||||
| 	/// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. | ||||
| @ -35,6 +36,7 @@ public struct StyleBuilder | ||||
| 	/// <param name="prop"></param> | ||||
| 	/// <param name="value"></param> | ||||
| 	public StyleBuilder(string prop, string value) => stringBuffer = $"{prop}:{value};"; | ||||
| 	public StyleBuilder(string style) : this() => this.style = style; | ||||
| 
 | ||||
| 	/// <summary> | ||||
| 	/// Adds a conditional in-line style to the builder with space separator and closing semicolon. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 stm
						stm