Merge pull request 'FormWizard - working example' (#11) from features/rewrite/formwizard into features/rewrite/main

Reviewed-on: #11

Needs a couple minor fixes (Unfinished -> InProgress, style modifications and such).
Merging regardless due to timeframes.
features/rewrite/timepicker
Matija Koželj 2 years ago
commit 8dbf672d64

@ -1,49 +1,30 @@
@page "/" @page "/"
@using Connected.Models; @using Connected.Models;
<h1 style="text-align:center;">Component Sandbox</h1>
<p>SelectedValue: @SelectedValue.ToString()</p>
<RadioGroup Name="Group1">
<Radio Id="radio1" Label="Group 1, Radio 1"></Radio>
<Radio Id="radio2" Label="Group 1, Radio 2"></Radio>
<Radio Id="radio3" Label="Group 1, Radio 3"></Radio>
<Radio Id="radio4" Label="Group 1, Radio 4"></Radio>
<Radio Id="radio5" Label="Group 1, Radio 5" Disabled=true></Radio>
</RadioGroup>
<RadioGroup Name="Group2" Disabled=true>
<Radio Id="radio21" Label="Group 2, Radio 1"></Radio>
<Radio Id="radio22" Label="Group 2, Radio 2"></Radio>
<Radio Id="radio23" Label="Group 2, Radio 3"></Radio>
<Radio Id="radio24" Label="Group 2, Radio 4"></Radio>
<Radio Id="radio25" Label="Group 2, Radio 5"></Radio>
</RadioGroup>
@code {
int SelectedValue; <h1 style="text-align:center;">Component Sandbox</h1>
List<int> items; <FormWizard Id="Wizard1">
<FormWizardStep Name="Step1">
Step1
</FormWizardStep>
<FormWizardStep Name="Step2">
Step2
</FormWizardStep>
<FormWizardStep Name="Step3">
Step3
</FormWizardStep>
<FormWizardStep Name="Step4">
Step4
</FormWizardStep>
</FormWizard>
private void FillItemsList()
{
if (items is null) items = new();
Random random = new Random(DateTime.Now.Millisecond); <TextInput @bind-Value="@value"></TextInput>
for (int i = 0; i < 10; i++) @value
{
int item = random.Next();
items.Add(item);
}
StateHasChanged();
}
protected override async Task OnInitializedAsync()
{
FillItemsList();
}
@code {
public string value = string.Empty;
} }

@ -0,0 +1,5 @@
<h3>Chip</h3>
@code {
}

@ -0,0 +1,4 @@
namespace Connected.Components;
public partial class Chip
{
}

@ -0,0 +1,23 @@
<CascadingValue Value="this">
<section id="@Id" class="@ClassList" style="@StyleList">
<div class="form-outer">
@ChildContent
</div>
<div class="btn-box text-right my-5 d-flex justify-space-between">
<button type="button" href="#" class="btn btn-secondary" aria-pressed="true" disabled="@WizardFinished">Cancel</button>
<div>
<button type="button" @onclick="PreviousSlide" class="btn btn-core mr-2" aria-pressed="true" disabled="@WizardFinished"><i class='bx bx-chevron-left'></i>@PreviousBtnText</button>
<button type="button" @onclick="NextSlide" class="btn btn-core mr-2" aria-pressed="true" disabled="@WizardFinished">@NextBtnText<i class='bx bx-chevron-right'></i></button>
</div>
</div>
<div class="dots d-flex justify-center gap-3">
@foreach (var step in Steps)
{
<div class="dot @step.DotClass"></div>
}
</div>
</section>
</CascadingValue>

@ -0,0 +1,229 @@
using Connected.Enums;
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace Connected.Components;
public partial class FormWizard
{
/// <summary>
/// Text shown inside the button
/// Options: any string variable
/// Default: string.Empty
/// </summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public List<FormWizardStep> Steps { get; set; } = new();
[Parameter, EditorRequired]
public string Id { get; set; }
private string NextBtnText = "Next";
private string PreviousBtnText = "Previous";
private bool WizardFinished { get; set; } = false;
private FinishedState FinishedState { get; set; } = FinishedState.Unfinished;
[Parameter]
public int ActiveIndex
{
get
{
return _activeStepIndex;
}
set
{
if (value <= StepCount || value >= 0) //if value is greater than total StepCount or less than 0 first element becomes the active alament
{
_activeStepIndex = value;
}
}
}
private int _activeStepIndex = 0;
private int PreviousIndex
{
get
{
if (ActiveIndex>0)
return ActiveIndex - 1;
return ActiveIndex;
}
}
private int NextIndex
{
get
{
try
{
if (ActiveIndex < StepCount-1)
return ActiveIndex + 1;
return ActiveIndex;
} catch
{
return ActiveIndex;
}
}
}
private int StepCount
{
get
{
return Steps.Count;
}
}
private void NextSlide()
{
if (NextBtnText.ToLower().Equals("finish"))
{
FinishedState = FinishedState.Finished;
Steps[ActiveIndex].Completed = true;
WizardFinished = true;
}
if (FinishedState.Equals(FinishedState.Unfinished))
{
/*if (ActiveIndex < StepCount)
{
Steps[ActiveIndex].Completed = true;
ResetValuesForChild(ActiveIndex);
if (ActiveIndex < StepCount)
ResetValuesForChild(NextIndex);
if (ActiveIndex > 0)
ResetValuesForChild(PreviousIndex);
ActiveIndex = NextIndex;
Steps[ActiveIndex].Active = true;
Steps[PreviousIndex].IsPrevious = true;
if (ActiveIndex != NextIndex)
Steps[NextIndex].IsNext = true;
else Steps[NextIndex].IsNext = false;
if (ActiveIndex == NextIndex)
NextBtnText = "Finish";
else
NextBtnText = "Next";
StateHasChanged();
}*/
Steps[ActiveIndex].Completed = true;
Steps[ActiveIndex].Active = false;
Steps[PreviousIndex].IsPrevious = false;
Steps[ActiveIndex].IsNext = false;
ActiveIndex = NextIndex;
Steps[ActiveIndex].IsNext = true;
Steps[ActiveIndex].Active = true;
Steps[PreviousIndex].IsPrevious = true;
if (ActiveIndex == NextIndex)
NextBtnText = "Finish";
else
NextBtnText = "Next";
}
}
private void PreviousSlide()
{
if (ActiveIndex > 0)
{
//Steps[ActiveIndex].Completed = true;
Steps[ActiveIndex].Active = false;
Steps[PreviousIndex].IsPrevious = false;
Steps[ActiveIndex].IsNext = false;
ActiveIndex = PreviousIndex;
Steps[ActiveIndex].IsNext = true;
Steps[ActiveIndex].Active = true;
Steps[PreviousIndex].IsPrevious = true;
if (ActiveIndex == NextIndex)
NextBtnText = "Finish";
else
NextBtnText = "Next";
}
if (ActiveIndex==0)
{
ResetAllChildren();
Steps[ActiveIndex].Active = true;
}
}
[Parameter]
public string Class { get; set; } = string.Empty;
private string ClassList
{
get
{
return new CssBuilder("form-wizard")
.AddClass(Class)
.Build();
}
}
[Parameter]
public string Style { get; set; } = string.Empty;
private string StyleList
{
get
{
return new StyleBuilder()
.AddStyle(Style)
.Build();
}
}
private void ResetValuesForChild(int ChildIndex)
{
Steps[ChildIndex].Active = false;
Steps[ChildIndex].IsNext = false;
Steps[ChildIndex].IsPrevious = false;
}
private void ResetAllChildren()
{
foreach (var step in Steps)
{
step.Active = false;
step.IsNext = false;
step.IsPrevious = false;
}
}
private void InitializeSteps()
{
ResetAllChildren();
Steps[ActiveIndex].Active = true;
if (ActiveIndex!=0)
{
Steps[ActiveIndex].IsNext = true;
Steps[PreviousIndex].IsPrevious= true;
}
StateHasChanged();
}
protected override async Task OnParametersSetAsync()
{
if (Steps is not null)
Steps.Clear();
await base.OnParametersSetAsync();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
InitializeSteps();
}
await base.OnAfterRenderAsync(firstRender);
}
}

@ -0,0 +1,3 @@
<div class="@ClassList" style="@StyleList">
@ChildContent
</div>

@ -0,0 +1,99 @@
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
namespace Connected.Components;
public partial class FormWizardStep
{
#region Parameters
[CascadingParameter]
public FormWizard Parent { get; set; }
[Parameter, EditorRequired]
public string Name { get; set; }
/// <summary>
/// Text shown inside the button
/// Options: any string variable
/// Default: string.Empty
/// </summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }
/// <summary>
/// User defined custom class added on top of default generated classes
/// Options: any user defined string with class names divided by space
/// Default: string.Empty
/// </summary>
[Parameter]
public string Class { get; set; } = string.Empty;
/// <summary>
/// User defined custom style
/// Options: any valid CSS style
/// Default: string.Empty
/// </summary>
[Parameter]
public string Style { get; set; } = string.Empty;
public bool Active { get; set; } = false;
public bool IsNext { get; set; } = false;
public bool IsPrevious { get; set; } = false;
public bool Completed { get; set; } = false;
public string DotClass
{
get
{
return new CssBuilder("dot")
.AddClass("completed",Completed)
.AddClass("next", Active)
.Build();
}
}
#endregion
#region Styling
public string StyleList
{
get
{
return new StyleBuilder()
.AddStyle("display","none", (!Active && !IsNext && !IsPrevious)) //Workarround for more than 2 steps where steps didnt hide after
.AddStyle(Style)
.Build();
}
}
/// <summary>
/// Generated class list for button based on user parameters
/// </summary>
public string ClassList
{
get
{
return new CssBuilder("form-step")
.AddClass("next", IsNext)
.AddClass("previous", IsPrevious)
.AddClass(Class)
.Build();
}
}
#endregion
#region Lifecycle
protected override async Task OnInitializedAsync()
{
Parent.Steps.Add(this);
await base.OnInitializedAsync();
}
#endregion
}

@ -75,21 +75,11 @@ public partial class ToggleGlyphButton: Button
#region Styling #region Styling
public string StyleList
{
get
{
return new StyleBuilder()
.AddStyle(base.Style)
.Build();
}
}
/// <summary> /// <summary>
/// Generated class list for button based on user parameters /// Generated class list for button based on user parameters
/// </summary> /// </summary>
public string ClassList public new string ClassList
{ {
get get
{ {
@ -102,19 +92,6 @@ public partial class ToggleGlyphButton: Button
} }
} }
/// <summary>
/// Generated class list for button based on user parameters
/// </summary>
public string ContentClassList
{
get
{
return new CssBuilder("")
.AddClass(base.ContentClass)
.Build();
}
}
#endregion #endregion
} }

@ -0,0 +1,10 @@
using System.ComponentModel;
namespace Connected.Enums;
public enum FinishedState
{
[Description("unfinished")]
Unfinished,
[Description("finished")]
Finished
}
Loading…
Cancel
Save