DotvvmChildEventCallback

Add Wizard

6/28/2023 8:32:31 AM

Details

diff --git a/src/Web/ViewModels/DefaultViewModel.cs b/src/Web/ViewModels/DefaultViewModel.cs
index 4dab284..6dd200e 100644
--- a/src/Web/ViewModels/DefaultViewModel.cs
+++ b/src/Web/ViewModels/DefaultViewModel.cs
@@ -1,7 +1,97 @@
 namespace Web.ViewModels
 {
+    using System;
+    using System.Collections.Generic;
+
     public class DefaultViewModel : SiteViewModel
     {
-        
+        public WizardNavigationViewModel Wizard { get; set; }
+
+        public DefaultViewModel()
+        {
+            Wizard = new WizardNavigationViewModel(new List<string>
+            {
+                "First",
+                "Second",
+                "Third",
+                "Fourth",
+                "Fifth",
+                "Sixth",
+                "Seventh",
+                "Eighth",
+                "Ninth",
+            }, 2);
+            Wizard.ShowNavigation();
+        }
+    }
+
+    public class WizardNavigationViewModel
+    {
+        public int MinimumStep { get; set; }
+        public bool NextButtonEnabled { get; set; }
+        public bool NextButtonVisible { get; set; }
+        public double Percentage => ((float)Step / Total) * 100.0;
+        public int PreviousStep { get; set; }
+        public bool PreviousButtonEnabled { get; set; }
+        public bool PreviousButtonVisible { get; set; }
+        public int Step { get; set; }
+        public string Title => Titles[Step - 1];
+        public string[] Titles { get; set; }
+        public int Total => Titles.Length;
+        public bool NavigationVisible { get; set; }
+
+        public WizardNavigationViewModel(List<string> titles) : this(titles, 1)
+        {
+        }
+
+        public WizardNavigationViewModel(List<string> titles, int minimumStep)
+        {
+            if (titles == null)
+                throw new ArgumentNullException($"{nameof(titles)} is required.");
+
+            if (titles.Count == 0)
+                throw new ArgumentOutOfRangeException($"{nameof(titles)} is empty.");
+
+            MinimumStep = minimumStep;
+            NextButtonVisible = true;
+            PreviousButtonVisible = true;
+            Step = 1;
+            Titles = titles.ToArray();
+
+            if (Total > 1)
+                NextButtonEnabled = true;
+        }
+
+        public void HideNavigation() => NavigationVisible = false;
+
+        public void OnNextClick()
+        {
+            if (Step >= Total)
+                return;
+
+            PreviousStep = Step;
+            Step++;
+            SetButtonStatus();
+        }
+
+        public void OnPreviousClick()
+        {
+            if (Step <= MinimumStep)
+                return;
+
+            PreviousStep = Step;
+            Step--;
+            SetButtonStatus();
+        }
+
+        public void ShowNavigation() => NavigationVisible = true;
+
+        #region Private Methods
+        private void SetButtonStatus()
+        {
+            NextButtonEnabled = Step < Total;
+            PreviousButtonEnabled = Step > MinimumStep;
+        }
+        #endregion
     }
 }
diff --git a/src/Web/Views/Default.dothtml b/src/Web/Views/Default.dothtml
index 7ad9284..9cc2393 100644
--- a/src/Web/Views/Default.dothtml
+++ b/src/Web/Views/Default.dothtml
@@ -2,6 +2,32 @@
 @masterPage Views/Site.dotmaster
 
 <dot:Content ContentPlaceHolderID="Body">
-    <h1>Bootstrap starter template</h1>
-    <p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
+    <div DataContext="{value: Wizard}">
+        <div class="container mt-3" IncludeInPage="{value: NavigationVisible}">
+            <div class="row">
+                <div class="col-md-2">
+                    <bs:Button ButtonTagName="button" Click="{command:  OnPreviousClick()}" Enabled="{value: PreviousButtonEnabled}" IncludeInPage="{value: PreviousButtonVisible}" Type="Light">
+                        Previous Button
+                    </bs:Button>
+                </div>
+                <div class="col-md-8">
+                    Step {{value: Step}} out of {{value: Total}}.
+                    <bs:ProgressBar Color="Info" VisualStyle="AnimatedStriped" Value="{value: Percentage}" />
+                    {{value: Percentage.ToString("#.##")}}% Complete
+                </div>
+                <div class="col-md-2">
+                    <bs:Button ButtonTagName="button" Click="{command: OnNextClick()}" Enabled="{value: NextButtonEnabled}" IncludeInPage="{value: NextButtonVisible}" IsSubmitButton="true" Type="Primary">
+                        Next Button
+                    </bs:Button>
+                </div>
+            </div>
+        </div>
+        <div class="container mt-3">
+            <div class="row">
+                <div class="offset-md-2 col-md-8">
+                    <h4 class="lead">{{value: Title}}</h4>
+                </div>
+            </div>
+        </div>
+    </div>
 </dot:Content>