Compare commits

..

No commits in common. "45380821ad5d42972d7209ea349a1074e2f6162c" and "ed15c8f24dfa4fdc99aecdb06f8eaa842973f119" have entirely different histories.

11 changed files with 175 additions and 302 deletions

View File

@ -3,39 +3,112 @@
<h1 style="text-align:center;">Component Sandbox</h1> <h1 style="text-align:center;">Component Sandbox</h1>
<p>ValueDouble: @inputValueDouble.ToString()</p>
<p>ValueInt: @inputValueInt.ToString()</p>
<p>ValueText: @inputValueText</p>
<p>SimpleSelectValue: @SelectedItemValue</p>
<p>SelectedValue: @SelectedValue.ToString()</p> <InputNumber
Clearable="false"
DisableMouseWheel="false"
Disabled="false"
Readonly="false"
Placeholder="Double"
Label="Double"
Required="true"
Step="0.000516"
DecimalPlaces=5
Class="m-2"
@bind-Value="@inputValueDouble">
</InputNumber>
<InputNumber
Clearable="true"
DisableMouseWheel="false"
Disabled="false"
Readonly="false"
Placeholder="Double"
Label="Integer"
Required="true"
Step="0.001"
DecimalPlaces="2"
Class="m-4"
@bind-Value="@inputValueInt">
</InputNumber>
<InputText
Label="String"
Required="true"
ErrorText="@errorText"
@bind-Value="@inputValueText">
</InputText>
<InputText
Label="Password"
IsPassword="true"
Required="true"
ErrorText="@errorText"
@bind-Value="@inputValueText">
</InputText>
<SimpleSelect <SimpleSelect
Items="@items" Label="Simple Select"
Label="Simple select"
@bind-Value=@SelectedValue ValueType="string"
/> @bind-Value="@SelectedItemValue"
Items="@SelectFieldItems">
</SimpleSelect>
@code { @code {
int SelectedValue;
List<int> items; List<SelectItem<string>> SelectFieldItems = new();
string SelectedItemValue = "";
private void FillItemsList() int counter { get; set; } = 0;
private string _inputText = string.Empty;
string inputValueText
{ {
if (items is null) items = new(); get
Random random = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < 10; i++)
{ {
int item = random.Next(); return _inputText;
items.Add(item);
} }
set
{
if (value.Length > 0) errorText = "Error!!!";
else errorText = "";
_inputText = value;
StateHasChanged();
}
}
double inputValueDouble = 12.756;
int inputValueInt = 12;
DateTime inputValueDate = DateTime.Now.AddDays(-10);
public void CounterIncrement()
{
counter++;
StateHasChanged(); StateHasChanged();
} }
string errorText = "Error!!";
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
FillItemsList(); SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 1", Value = "select item value 1", Enabled = true });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 2", Value = "select item value 2", Enabled = true });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 3", Value = "select item value 3", Enabled = true });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 4", Value = "select item value 4", Enabled = true });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 5", Value = "select item value 5", Enabled = false });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 6", Value = "select item value 6", Enabled = true });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 7", Value = "select item value 7", Enabled = true });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 8", Value = "select item value 8", Enabled = false });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 9", Value = "select item value 9", Enabled = true });
SelectFieldItems.Add(new SelectItem<string>() { DisplayedText = "Item 10", Value = "select item value 10", Enabled = true });
SelectedItemValue = SelectFieldItems[0].Value;
} }
} }

View File

@ -5,19 +5,18 @@
@typeparam NumberType @typeparam NumberType
<div class="@InputFieldClassList"> <div class="@InputFieldClassList">
<input type="text" <input type="number"
placeholder="@Placeholder" placeholder="@Placeholder"
step="@_step" step="@_step"
disabled="@Disabled" disabled="@Disabled"
readonly="@Readonly" readonly="@Readonly"
value="@_value" @onmousewheel="@OnMouseWheel"
@onkeydown=@(args => ChangeValue(args)) @onwheel="@OnMouseWheel"
@onkeydown:preventDefault="@_preventDefaultAction" @oninput=@ChangeValueAsync
@oninput=@GetValueAsync @bind-value="@Value"
@onmousewheel=@OnMouseWheel @attributes="@InputAttributes">
@onchange="@Change" </input>
@onwheel="OnMouseWheel"
@attributes="@InputAttributes" />
<span class="highlight"></span> <span class="highlight"></span>
<span class="bar"></span> <span class="bar"></span>
@ -35,10 +34,6 @@
} }
<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">

View File

@ -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,56 +22,30 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe
} }
[Parameter] [Parameter]
public bool DisableMouseWheel public bool DisableMouseWheel { get; set; } = false;
{
get;
set;
} = false;
private async Task StepUp() private async Task StepUp()
{ {
try double num = (double)Convert.ChangeType(Value, typeof(double));
{ num += _step;
double num = (double)Convert.ChangeType(Value, typeof(double)); Value = AdjustDecimalPlaces((NumberType)Convert.ChangeType(num, typeof(NumberType)));
num += _step;
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));
{ num -= _step;
double num = (double)Convert.ChangeType(Value, typeof(double)); Value = AdjustDecimalPlaces((NumberType)Convert.ChangeType(num, typeof(NumberType)));
num -= _step;
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 args) protected async Task OnMouseWheel(WheelEventArgs obj)
{ {
if (DisableMouseWheel == false) if (DisableMouseWheel==false)
{ {
if (args.ShiftKey || Disabled || Readonly) if (!obj.ShiftKey || Disabled || Readonly)
return; return;
if (args.DeltaY >= 0) if (obj.DeltaY < 0)
{ {
await StepDown(); await StepDown();
} }
@ -79,145 +53,69 @@ 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]
public EventCallback<NumberType> ValueChanged { get; set; }
public async Task GetValueAsync(ChangeEventArgs args) [Parameter]
public EventCallback<NumberType> ValueChanged { get; set; }
public async Task ChangeValueAsync(ChangeEventArgs args)
{ {
if (args.Value is not null) if (args.Value is not null)
{ {
string newVal = args.Value.ToString(); NumberType value = (NumberType)Convert.ChangeType(args.Value, typeof(NumberType));
if (!newVal.Equals("0")) if (value.ToString().Length <= 0)
{
if (newVal.ToString().Contains("-"))
newVal = "-" + newVal.ToString().Replace("-", "");
if (newVal.ToString().ToLower().Contains("e"))
newVal = "e" + newVal.ToString().Replace("e", "");
}
if (string.IsNullOrEmpty(newVal))
{
await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType((NumberType)Convert.ChangeType(null, typeof(NumberType)), typeof(NumberType)));
}
else
{
if (!newVal.Equals(_value))
await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType((NumberType)Convert.ChangeType(newVal, typeof(NumberType)), typeof(NumberType)));
}
}
}
public async Task Change(ChangeEventArgs args)
{
if (args.Value is not null)
{
Value = AdjustDecimalPlaces((NumberType)Convert.ChangeType(args.Value, typeof(NumberType)));
}
ValueChanged.InvokeAsync(Value);
}
[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; value = (NumberType)Convert.ChangeType(0, typeof(NumberType));
} }
default: await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(AdjustDecimalPlaces(value), typeof(NumberType)));
{
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)
{ {
var result = value; NumberType result = value;
if (DecimalPlaces > 0) if (Helper.NumberHasDecimalPlaces(value))
{ {
double converted = Math.Round((double)Convert.ChangeType(result, typeof(double)), DecimalPlaces); if (DecimalPlaces > 0)
return (NumberType)Convert.ChangeType(converted, typeof(NumberType)); {
decimal rounded = (decimal)Convert.ChangeType(value, typeof(decimal));
rounded = Math.Round(rounded, DecimalPlaces);
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)));
} }
protected override async Task OnAfterRenderAsync(bool firstRender) #region Lifecycle
protected override async Task OnInitializedAsync()
{ {
if (firstRender) if (DecimalPlaces > 0)
{ {
if (!DecimalPlaces.Equals(Helper.GetDecimalPlaces(Value))) Value = AdjustDecimalPlaces(Value);
{ await ValueChanged.InvokeAsync(Value);
Value = AdjustDecimalPlaces(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"))

View File

@ -4,55 +4,15 @@
@inherits InputBase; @inherits InputBase;
@if (Items is not null) <div class="@InputFieldClassList">
{ <select @bind="@Value" @oninput="@ChangeValueAsync">
<div class="@InputFieldClassList"> @if (EnableSearch)
{
<select type="textarea" style="height:0px;" @attributes=@InputAttributes> <InputText @bind-Value="@SearchText" ValueChanged=""></InputText>
</select> }
@if (IsLabel) @foreach(SelectItem<ValueType> item in Items)
{ {
<label class="label-animated">@Label</label> <option value="@item.Value">@item.DisplayedText</option>
} }
</select>
<span class="highlight"></span> </div>
<span class="bar">
</span>
<span class="input-glyph-wraper">
@if (Clearable)
{
<span class="input-glyph button">
<i class='bx bx-x-circle'></i>
</span>
}
<span class="input-glyph">
<i class='bx bx-caret-down'></i>
</span>
@if (IsError)
{
<span class="input-glyph error">
<i class='bx bx-error-circle'></i>
</span>
}
</span>
<div class="drop-down">
<div class="dropdown-menu p-2" aria-labelledby="dropdownMenuButton">
@if (EnableSearch)
{
<input type="text"
placeholder="Enter search string..."
class="dropdown-item"
@bind-value="@SearchText"
/>
}
@foreach (ValueType item in Items)
{
@if (item is not null)
{
<div class="dropdown-item" @onclick=@(()=>SetSelectedItem(@item))>@item.ToString()</div>
}
}
</div>
</div>
</div>
}

View File

@ -1,5 +1,6 @@
using Connected.Models; using Connected.Models;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using System;
namespace Connected.Components; namespace Connected.Components;
public partial class SimpleSelect<ValueType> : InputBase public partial class SimpleSelect<ValueType> : InputBase
@ -8,81 +9,37 @@ public partial class SimpleSelect<ValueType> : InputBase
public ValueType Value { get; set; } public ValueType Value { get; set; }
[Parameter] [Parameter]
public IEnumerable<ValueType> Items { get; set; } public IEnumerable<SelectItem<ValueType>> Items { get; set; }
public IEnumerable<ValueType> OriginalItems { get; set; } public IEnumerable<SelectItem<ValueType>> OriginalItems { get; set; }
[Parameter] [Parameter]
public bool EnableSearch { get; set; } = true; public bool EnableSearch { get; set; } = true;
public string SearchText { get; set; }
private string _searchText { get; set; } = string.Empty; public void FilterItems()
public string SearchText
{ {
get Items= Items.Where(item => item.Value.ToString().ToLower().Contains(SearchText.ToLower()) || item.DisplayedText.ToString().ToLower().Contains(SearchText.ToLower()));
{
return _searchText;
}
set
{
_searchText = value;
FilterItems();
}
}
private string DropDownClass { get; set; } = "drop-down";
bool DropDownClicked = false;
public void DropDownClassToggle()
{
DropDownClicked = !DropDownClicked;
if (DropDownClicked)
{
DropDownClass = "";
} else
{
DropDownClass = "drop-down";
}
StateHasChanged();
}
private async Task SetSelectedItem(ValueType item)
{
//DropDownClassToggle();
await ValueChanged.InvokeAsync(item);
}
private async Task FilterItems()
{
if (string.IsNullOrEmpty(_searchText))
{
Items = OriginalItems;
}
else
{
Items = Items.Where(item => item.ToString().ToLower().Contains(_searchText.ToLower()));
}
StateHasChanged();
} }
[Parameter] [Parameter]
public EventCallback<ValueType> ValueChanged { get; set; } public EventCallback<ValueType> ValueChanged { get; set; }
private async Task ChangeValueAsync(ChangeEventArgs args) private async Task ChangeValueAsync(ChangeEventArgs args)
{ {
await ValueChanged.InvokeAsync((ValueType)Convert.ChangeType(args.Value, typeof(ValueType))); await ValueChanged.InvokeAsync((ValueType)Convert.ChangeType(args.Value, typeof(ValueType)));
} }
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
if (base.InputAttributes is null) base.InputAttributes = new(); if (base.InputAttributes is null) base.InputAttributes = new();
if (base.Required) if (base.Required)
{ {
if (base.InputAttributes.ContainsKey("required")) base.InputAttributes.Add("required", true); if (base.InputAttributes.ContainsKey("required")) base.InputAttributes.Add("required", true);
} }
OriginalItems = Items; OriginalItems = Items;
if (_searchText.Length>0) await FilterItems();
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }
} }

View File

@ -48,11 +48,13 @@ public partial class TextInput: InputBase
private async Task ChangeValueAsync(ChangeEventArgs args) private async Task ChangeValueAsync(ChangeEventArgs args)
{ {
await ValueChanged.InvokeAsync(args.Value.ToString()); await ValueChanged.InvokeAsync(args.Value.ToString());
StateHasChanged();
} }
private async Task Clear() private async Task Clear()
{ {
await ValueChanged.InvokeAsync(string.Empty); await ValueChanged.InvokeAsync(string.Empty);
StateHasChanged();
} }

View File

@ -27,7 +27,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components" Version="7.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.*-*" /> <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.*-*" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.119" PrivateAssets="all" Condition="!Exists('packages.config')" /> <PackageReference Include="Nerdbank.GitVersioning" Version="3.5.119" PrivateAssets="all" Condition="!Exists('packages.config')" />
</ItemGroup> </ItemGroup>

View File

@ -1,7 +1,5 @@
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
@ -73,22 +71,6 @@ 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

View File

@ -0,0 +1,9 @@
namespace Connected.Models
{
public class SelectItem<ValueType>
{
public string DisplayedText { get; set; }
public ValueType Value { get; set; }
public bool Enabled { get; set; }
}
}

View File

@ -135,11 +135,11 @@ public static class Helper
} }
} }
public static bool IsNumeric(string input) public static bool IsVariableNumeric(string input)
{ {
try try
{ {
var number = Double.Parse(input); var number = Decimal.Parse(input);
return true; return true;
} }
catch catch

View File

@ -10,7 +10,6 @@ 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.
@ -36,7 +35,6 @@ 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.