Number Input - mousewheeel fix, prevent of enetering flase characters
This commit is contained in:
		
							parent
							
								
									ed15c8f24d
								
							
						
					
					
						commit
						1fd0028557
					
				| @ -5,18 +5,18 @@ | |||||||
| @typeparam NumberType | @typeparam NumberType | ||||||
| 
 | 
 | ||||||
| <div class="@InputFieldClassList"> | <div class="@InputFieldClassList"> | ||||||
|     <input type="number" |     <input type="text" | ||||||
|            placeholder="@Placeholder" |            placeholder="@Placeholder" | ||||||
|            step="@_step" |            step="@_step" | ||||||
|            disabled="@Disabled" |            disabled="@Disabled" | ||||||
|            readonly="@Readonly" |            readonly="@Readonly" | ||||||
|            @onmousewheel="@OnMouseWheel" |            @onkeydown=@(args => ChangeValue(args)) | ||||||
|            @onwheel="@OnMouseWheel" |            @onkeydown:preventDefault="@_preventDefaultAction" | ||||||
|            @oninput=@ChangeValueAsync |            @oninput=@GetValueAsync | ||||||
|            @bind-value="@Value" |            @onmousewheel=@OnMouseWheel | ||||||
|            @attributes="@InputAttributes"> |            @onwheel="OnMouseWheel" | ||||||
|            </input> |            @bind-value="@_value" | ||||||
| 
 |            @attributes="@InputAttributes" /> | ||||||
|      |      | ||||||
|     <span class="highlight"></span> |     <span class="highlight"></span> | ||||||
|     <span class="bar"></span> |     <span class="bar"></span> | ||||||
| @ -34,6 +34,10 @@ | |||||||
|     } |     } | ||||||
|     <span class="input-glyph-wraper"> |     <span class="input-glyph-wraper"> | ||||||
|         <span class="input-glyph"> |         <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) |             @if (Clearable && Value.ToString().Length > 0) | ||||||
|             { |             { | ||||||
|                 <span class="input-glyph button" @onclick="Clear"> |                 <span class="input-glyph button" @onclick="Clear"> | ||||||
|  | |||||||
| @ -3,11 +3,11 @@ using Connected.Utilities; | |||||||
| using Microsoft.AspNetCore.Components; | using Microsoft.AspNetCore.Components; | ||||||
| using Microsoft.AspNetCore.Components.Web; | using Microsoft.AspNetCore.Components.Web; | ||||||
| using System.Numerics; | using System.Numerics; | ||||||
| using static Connected.Colors; |  | ||||||
| 
 | 
 | ||||||
| namespace Connected.Components; | namespace Connected.Components; | ||||||
| public partial class NumberInput<NumberType>:InputBase where NumberType : INumber<NumberType> | public partial class NumberInput<NumberType>:InputBase where NumberType : INumber<NumberType> | ||||||
| { | { | ||||||
|  | 
 | ||||||
| 	private double _step =1; | 	private double _step =1; | ||||||
| 	[Parameter] | 	[Parameter] | ||||||
| 	public double Step {  | 	public double Step {  | ||||||
| @ -22,30 +22,56 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	[Parameter] | 	[Parameter] | ||||||
| 	public bool DisableMouseWheel { get; set; } = false; | 	public bool DisableMouseWheel | ||||||
|  | 	{ | ||||||
|  | 		get; | ||||||
|  | 		set; | ||||||
|  | 	} = false; | ||||||
| 
 | 
 | ||||||
| 	private async Task StepUp() | 	private async Task StepUp() | ||||||
|  | 	{ | ||||||
|  | 		try | ||||||
| 		{ | 		{ | ||||||
| 			double num = (double)Convert.ChangeType(Value, typeof(double)); | 			double num = (double)Convert.ChangeType(Value, typeof(double)); | ||||||
| 			num += _step; | 			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); | 		await ValueChanged.InvokeAsync(Value); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private async Task StepDown() | 	private async Task StepDown() | ||||||
|  | 	{ | ||||||
|  | 		try | ||||||
| 		{ | 		{ | ||||||
| 			double num = (double)Convert.ChangeType(Value, typeof(double)); | 			double num = (double)Convert.ChangeType(Value, typeof(double)); | ||||||
|  | 			 | ||||||
| 			num -= _step; | 			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); | 		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; | 				return; | ||||||
| 			if (obj.DeltaY < 0) | 			if (args.DeltaY >= 0) | ||||||
| 			{ | 			{ | ||||||
| 				await StepDown(); | 				await StepDown(); | ||||||
| 			} | 			} | ||||||
| @ -53,69 +79,136 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe | |||||||
| 			{ | 			{ | ||||||
| 				await StepUp(); | 				await StepUp(); | ||||||
| 			} | 			} | ||||||
|  | 		} else | ||||||
|  | 		{ | ||||||
|  | 			return; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private string _value; | ||||||
| 
 | 
 | ||||||
| 	[Parameter] | 	[Parameter] | ||||||
| 	public NumberType Value | 	public NumberType? Value | ||||||
| 	{ | 	{ | ||||||
| 		get; | 		get | ||||||
| 		set; | 		{ | ||||||
|  | 			if (string.IsNullOrEmpty(_value)) return default(NumberType); | ||||||
|  | 			return (NumberType)Convert.ChangeType(_value, typeof(NumberType)); | ||||||
|  | 		} | ||||||
|  | 		set | ||||||
|  | 		{ | ||||||
|  | 			_value = value.ToString(); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	[Parameter] | 	[Parameter] | ||||||
| 	public int DecimalPlaces { get; set; } =0; | 	public int DecimalPlaces { get; set; } =0; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	[Parameter] | 	[Parameter] | ||||||
|    public EventCallback<NumberType> ValueChanged { get; set; } |    public EventCallback<NumberType> ValueChanged { get; set; } | ||||||
| 
 | 
 | ||||||
| 	public async Task ChangeValueAsync(ChangeEventArgs args) | 	public async Task GetValueAsync(ChangeEventArgs args) | ||||||
|     { |     { | ||||||
| 		if (args.Value is not null) | 		if (args.Value is not null) | ||||||
| 		{ | 		{ | ||||||
| 				NumberType value = (NumberType)Convert.ChangeType(args.Value, typeof(NumberType)); | 			string newVal = args.Value.ToString(); | ||||||
| 				if (value.ToString().Length <= 0) | 			if (!newVal.Equals("0")) | ||||||
| 			{ | 			{ | ||||||
| 
 | 				if (newVal.ToString().Contains("-")) | ||||||
| 					value = (NumberType)Convert.ChangeType(0, typeof(NumberType)); | 					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) | 	private NumberType AdjustDecimalPlaces(NumberType value) | ||||||
| 	{ | 	{ | ||||||
| 		NumberType result = value; | 		var result = value; | ||||||
| 		if (Helper.NumberHasDecimalPlaces(value)) |  | ||||||
| 		{ |  | ||||||
| 		if (DecimalPlaces > 0) | 		if (DecimalPlaces > 0) | ||||||
| 		{ | 		{ | ||||||
| 				decimal rounded = (decimal)Convert.ChangeType(value, typeof(decimal)); | 			double converted = Math.Round((double)Convert.ChangeType(result, typeof(double)), DecimalPlaces); | ||||||
| 				rounded = Math.Round(rounded, DecimalPlaces); | 			return (NumberType)Convert.ChangeType(converted, typeof(NumberType)); | ||||||
| 				result = (NumberType)Convert.ChangeType(rounded, typeof(NumberType)); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private async Task Clear() | 	private async Task Clear() | ||||||
| 	{ | 	{ | ||||||
|  | 		_value = string.Empty; | ||||||
| 		await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(0, typeof(NumberType))); | 		await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(0, typeof(NumberType))); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	#region Lifecycle | 	protected override async Task OnAfterRenderAsync(bool firstRender) | ||||||
| 
 |  | ||||||
| 	protected override async Task OnInitializedAsync() |  | ||||||
| 	{ | 	{ | ||||||
| 		if (DecimalPlaces > 0) | 		if (firstRender) | ||||||
|  | 		{ | ||||||
|  | 			if (!DecimalPlaces.Equals(Helper.GetDecimalPlaces(Value))) | ||||||
| 			{ | 			{ | ||||||
| 				Value = AdjustDecimalPlaces(Value); | 				Value = AdjustDecimalPlaces(Value); | ||||||
| 			await ValueChanged.InvokeAsync(Value); | 				StateHasChanged(); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	#region Lifecycle | ||||||
| 	protected override async Task OnParametersSetAsync() | 	protected override async Task OnParametersSetAsync() | ||||||
| 	{ | 	{ | ||||||
| 		if (typeof(NumberType).Name.ToLower().Contains("int")) | 		if (typeof(NumberType).Name.ToLower().Contains("int")) | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| using Connected.Utilities; | using Connected.Utilities; | ||||||
| using Microsoft.AspNetCore.Components; | using Microsoft.AspNetCore.Components; | ||||||
|  | using static Connected.Colors; | ||||||
|  | using static System.Net.Mime.MediaTypeNames; | ||||||
| 
 | 
 | ||||||
| namespace Connected.Models; | namespace Connected.Models; | ||||||
| public class InputBase : ComponentBase | 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; | 	private string _helperText = string.Empty; | ||||||
| 	[Parameter] | 	[Parameter] | ||||||
| 	public string HelperText | 	public string HelperText | ||||||
|  | |||||||
| @ -135,11 +135,11 @@ public static class Helper | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public static bool IsVariableNumeric(string input) | 	public static bool IsNumeric(string input) | ||||||
| 	{ | 	{ | ||||||
| 		try | 		try | ||||||
| 		{ | 		{ | ||||||
| 			var number = Decimal.Parse(input); | 			var number = Double.Parse(input); | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 		catch | 		catch | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ namespace Connected.Utilities; | |||||||
| public struct StyleBuilder | public struct StyleBuilder | ||||||
| { | { | ||||||
| 	private string stringBuffer; | 	private string stringBuffer; | ||||||
|  | 	private string style; | ||||||
| 
 | 
 | ||||||
| 	/// <summary> | 	/// <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. | 	/// 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="prop"></param> | ||||||
| 	/// <param name="value"></param> | 	/// <param name="value"></param> | ||||||
| 	public StyleBuilder(string prop, string value) => stringBuffer = $"{prop}:{value};"; | 	public StyleBuilder(string prop, string value) => stringBuffer = $"{prop}:{value};"; | ||||||
|  | 	public StyleBuilder(string style) : this() => this.style = style; | ||||||
| 
 | 
 | ||||||
| 	/// <summary> | 	/// <summary> | ||||||
| 	/// Adds a conditional in-line style to the builder with space separator and closing semicolon. | 	/// 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