features/rewrite/numberinput #7
@ -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 (!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