DotvvmChildEventCallback
Changes
.gitignore 1(+1 -0)
src/Web/DotvvmStartup.cs 12(+12 -0)
src/Web/libman.json 10(+7 -3)
src/Web/ViewModels/DefaultViewModel.cs 12(+11 -1)
src/Web/ViewModels/SiteViewModel.cs 61(+61 -0)
src/Web/ViewModels/ToastType.cs 10(+10 -0)
src/Web/Views/Default.dothtml 4(+2 -2)
src/Web/Views/Site.dotmaster 11(+6 -5)
src/Web/Web.csproj 8(+8 -0)
src/Web/wwwroot/js/toastr/toastr.options.js 34(+34 -0)
Details
.gitignore 1(+1 -0)
diff --git a/.gitignore b/.gitignore
index 2e829e4..36d1b80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@
src/Web/wwwroot/css/bootstrap/
src/Web/wwwroot/css/font-awesome/
src/Web/wwwroot/js/jquery/
+src/Web/wwwroot/js/toastr/
# User-specific files
*.rsuser
src/Web/DotvvmStartup.cs 12(+12 -0)
diff --git a/src/Web/DotvvmStartup.cs b/src/Web/DotvvmStartup.cs
index e424b1e..5f7933a 100644
--- a/src/Web/DotvvmStartup.cs
+++ b/src/Web/DotvvmStartup.cs
@@ -52,6 +52,18 @@ namespace Web
{
Location = new UrlResourceLocation("~/wwwroot/css/site.css")
});
+
+ config.Resources.Register("Toastr", new ScriptResource
+ {
+ Dependencies = new[] { "jquery" },
+ Location = new UrlResourceLocation("~/wwwroot/js/toastr/toastr.min.js")
+ });
+
+ config.Resources.Register("ToastrCustom", new ScriptResource
+ {
+ Dependencies = new[] { "Toastr" },
+ Location = new UrlResourceLocation("~/wwwroot/js/toastr/toastr.options.js")
+ });
}
private void RegisterJavascript(DotvvmConfiguration config)
src/Web/libman.json 10(+7 -3)
diff --git a/src/Web/libman.json b/src/Web/libman.json
index 273a705..ea7e84b 100644
--- a/src/Web/libman.json
+++ b/src/Web/libman.json
@@ -7,12 +7,16 @@
"destination": "wwwroot/css/bootstrap"
},
{
+ "library": "font-awesome@4.7.0",
+ "destination": "wwwroot/css/font-awesome/"
+ },
+ {
"library": "jquery@3.7.0",
"destination": "wwwroot/js/jquery/"
},
{
- "library": "font-awesome@4.7.0",
- "destination": "wwwroot/css/font-awesome/"
+ "library": "toastr.js@2.1.4",
+ "destination": "wwwroot/js/toastr"
}
]
-}
\ No newline at end of file
+}
src/Web/ViewModels/DefaultViewModel.cs 12(+11 -1)
diff --git a/src/Web/ViewModels/DefaultViewModel.cs b/src/Web/ViewModels/DefaultViewModel.cs
index 6dd200e..16cc237 100644
--- a/src/Web/ViewModels/DefaultViewModel.cs
+++ b/src/Web/ViewModels/DefaultViewModel.cs
@@ -20,9 +20,19 @@ namespace Web.ViewModels
"Seventh",
"Eighth",
"Ninth",
- }, 2);
+ }, 1);
Wizard.ShowNavigation();
}
+
+ public void OnNextClick()
+ {
+ Wizard.OnNextClick();
+ }
+
+ public void OnPreviousClick()
+ {
+ Wizard.OnPreviousClick();
+ }
}
public class WizardNavigationViewModel
src/Web/ViewModels/SiteViewModel.cs 61(+61 -0)
diff --git a/src/Web/ViewModels/SiteViewModel.cs b/src/Web/ViewModels/SiteViewModel.cs
index a1d8eaf..a1d1afd 100644
--- a/src/Web/ViewModels/SiteViewModel.cs
+++ b/src/Web/ViewModels/SiteViewModel.cs
@@ -1,8 +1,69 @@
namespace Web.ViewModels
{
using DotVVM.Framework.ViewModel;
+ using System.Web;
+ using System;
public class SiteViewModel : DotvvmViewModelBase
{
+ #region Toastr Wrappers
+ public void ToastrError(string message, bool isSticky = false, string title = "")
+ {
+ ShowToast(ToastType.Error, message, title, isSticky);
+ }
+
+ public void ToastrInformation(string message, bool isSticky = false, string title = "")
+ {
+ ShowToast(ToastType.Info, message, title, isSticky);
+ }
+
+ public void ToastrSuccess(string message, bool isSticky = false, string title = "")
+ {
+ ShowToast(ToastType.Success, message, title, isSticky);
+ }
+
+ public void ToastrWarning(string message, bool isSticky = false, string title = "")
+ {
+ ShowToast(ToastType.Warning, message, title, isSticky);
+ }
+ #endregion
+
+ #region Private Methods
+ private void ShowToast(ToastType type, string message, string title, bool isSticky)
+ {
+ if (String.IsNullOrWhiteSpace(message))
+ return;
+
+ var encodedMessage = HttpUtility.HtmlEncode(message);
+ var encodedTitle = HttpUtility.HtmlEncode(title);
+
+
+ string javascript;
+ switch (type)
+ {
+ case ToastType.Error:
+ javascript = $"toastr.error('{encodedMessage}', '{encodedTitle}')";
+ break;
+ case ToastType.Info:
+ javascript = $"toastr.info('{encodedMessage}', '{encodedTitle}')";
+ break;
+ case ToastType.Success:
+ javascript = $"toastr.success('{encodedMessage}', '{encodedTitle}')";
+ break;
+ case ToastType.Warning:
+ javascript = $"toastr.warning('{encodedMessage}', '{encodedTitle}')";
+ break;
+ default:
+ javascript = $"toastr.info('{encodedMessage}', '{encodedTitle}')";
+ break;
+ }
+
+ Context.ResourceManager.AddStartupScript(isSticky
+ ? "Toast.setSticky()"
+ : "Toast.setStandard()");
+
+ Context.ResourceManager.AddStartupScript(javascript);
+ }
+ #endregion
}
}
src/Web/ViewModels/ToastType.cs 10(+10 -0)
diff --git a/src/Web/ViewModels/ToastType.cs b/src/Web/ViewModels/ToastType.cs
new file mode 100644
index 0000000..81d14df
--- /dev/null
+++ b/src/Web/ViewModels/ToastType.cs
@@ -0,0 +1,10 @@
+namespace Web.ViewModels
+{
+ public enum ToastType
+ {
+ Error,
+ Info,
+ Success,
+ Warning
+ }
+}
src/Web/Views/Default.dothtml 4(+2 -2)
diff --git a/src/Web/Views/Default.dothtml b/src/Web/Views/Default.dothtml
index 9cc2393..bacb2be 100644
--- a/src/Web/Views/Default.dothtml
+++ b/src/Web/Views/Default.dothtml
@@ -6,7 +6,7 @@
<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">
+ <bs:Button ButtonTagName="button" Click="{command: _root.OnPreviousClick()}" Enabled="{value: PreviousButtonEnabled}" IncludeInPage="{value: PreviousButtonVisible}" Type="Light">
Previous Button
</bs:Button>
</div>
@@ -16,7 +16,7 @@
{{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">
+ <bs:Button ButtonTagName="button" Click="{command: _root.OnNextClick()}" Enabled="{value: NextButtonEnabled}" IncludeInPage="{value: NextButtonVisible}" IsSubmitButton="true" Type="Primary">
Next Button
</bs:Button>
</div>
src/Web/Views/Site.dotmaster 11(+6 -5)
diff --git a/src/Web/Views/Site.dotmaster b/src/Web/Views/Site.dotmaster
index e90dbd7..01f350b 100644
--- a/src/Web/Views/Site.dotmaster
+++ b/src/Web/Views/Site.dotmaster
@@ -13,10 +13,10 @@
<body Visible="{value: _page.EvaluatingOnClient}">
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Demonstration</a>
- <bs:Button aria-controls="navBarToggle" aria-expanded="false" aria-label="Toggle navigation"
+ <bs:Button aria-controls="navBarToggle" aria-expanded="false" aria-label="Toggle navigation"
ButtonTagName="button"
- class="navbar-toggler"
- data-toggle="collapse" data-target="#navBarToggle"
+ class="navbar-toggler"
+ data-toggle="collapse" data-target="#navBarToggle"
Type="Link">
<span class="navbar-toggler-icon"></span>
</bs:Button>
@@ -26,8 +26,8 @@
<span class="nav-link">
Home <span class="sr-only">(current)</span>
</span>
- </li>
- </ul>
+ </li>
+ </ul>
</div>
</nav>
<main role="main" class="container">
@@ -35,6 +35,7 @@
<dot:ContentPlaceHolder ID="Body" />
</div>
</main>
+ <dot:RequiredResource Name="ToastrCustom" />
<dot:ContentPlaceHolder ID="Scripts" />
</body>
</html>
src/Web/Web.csproj 8(+8 -0)
diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj
index 92e8f93..d254708 100644
--- a/src/Web/Web.csproj
+++ b/src/Web/Web.csproj
@@ -197,9 +197,12 @@
<Compile Include="DotVvmStartup.cs" />
<Compile Include="ViewModels\DefaultViewModel.cs" />
<Compile Include="ViewModels\SiteViewModel.cs" />
+ <Compile Include="ViewModels\ToastType.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico" />
+ <Content Include="wwwroot\js\toastr\font-awesome-icons.css" />
+ <Content Include="wwwroot\js\toastr\toastr.options.js" />
<Content Include="Web.config" />
<Content Include="libman.json" />
<Content Include="wwwroot\css\bootstrap\css\bootstrap-grid.css" />
@@ -221,6 +224,9 @@
<Content Include="wwwroot\js\jquery\jquery.min.js" />
<Content Include="wwwroot\js\jquery\jquery.slim.js" />
<Content Include="wwwroot\js\jquery\jquery.slim.min.js" />
+ <Content Include="wwwroot\js\toastr\toastr.css" />
+ <Content Include="wwwroot\js\toastr\toastr.min.css" />
+ <Content Include="wwwroot\js\toastr\toastr.min.js" />
<None Include="packages.config" />
<Content Include="Views\Site.dotmaster" />
<Content Include="Views\Default.dothtml" />
@@ -338,12 +344,14 @@
<Content Include="wwwroot\css\font-awesome\fonts\fontawesome-webfont.woff" />
<Content Include="wwwroot\css\font-awesome\fonts\fontawesome-webfont.woff2" />
<Content Include="wwwroot\css\font-awesome\fonts\FontAwesome.otf" />
+ <Content Include="wwwroot\js\toastr\toastr.js.map" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\DotVVM.4.1.7\analyzers\dotnet\cs\DotVVM.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\DotVVM.4.1.7\analyzers\dotnet\cs\DotVVM.Analyzers.dll" />
</ItemGroup>
<ItemGroup>
+ <Folder Include="Models\" />
<Folder Include="wwwroot\css\scss\" />
</ItemGroup>
<PropertyGroup>
diff --git a/src/Web/wwwroot/js/toastr/font-awesome-icons.css b/src/Web/wwwroot/js/toastr/font-awesome-icons.css
new file mode 100644
index 0000000..0f40d0a
--- /dev/null
+++ b/src/Web/wwwroot/js/toastr/font-awesome-icons.css
@@ -0,0 +1,30 @@
+#toast-container > .toast {
+ background-image: none !important;
+}
+
+ #toast-container > .toast:before {
+ position: fixed;
+ font-family: FontAwesome;
+ font-size: 24px;
+ line-height: 18px;
+ float: left;
+ color: #fff;
+ padding-right: 0.5em;
+ margin: auto 0.5em auto -1.5em;
+ }
+
+#toast-container > .toast-error:before {
+ content: "\f05e"; /*fa-ban*/
+}
+
+#toast-container > .toast-info:before {
+ content: "\f129"; /*fa-info*/
+}
+
+#toast-container > .toast-success:before {
+ content: "\f00c"; /*fa-check*/
+}
+
+#toast-container > .toast-warning:before {
+ content: "\f071"; /*fa-exclamation-triangle*/
+}
src/Web/wwwroot/js/toastr/toastr.options.js 34(+34 -0)
diff --git a/src/Web/wwwroot/js/toastr/toastr.options.js b/src/Web/wwwroot/js/toastr/toastr.options.js
new file mode 100644
index 0000000..205d1ea
--- /dev/null
+++ b/src/Web/wwwroot/js/toastr/toastr.options.js
@@ -0,0 +1,34 @@
+let Toast = (function (toastr) {
+ toastr.options.closeButton = false;
+ toastr.options.debug = false;
+ toastr.options.extendedTimeOut = 1000;
+ toastr.options.hideEasing = 'linear';
+ toastr.options.hideDuration = 1000;
+ toastr.options.hideMethod = 'fadeOut';
+ toastr.options.newestOnTop = false;
+ toastr.options.onclick = null;
+ toastr.options.positionClass = 'toast-bottom-right';
+ toastr.options.preventDuplicates = false;
+ toastr.options.progressBar = false;
+ toastr.options.showDuration = 300;
+ toastr.options.showEasing = 'swing';
+ toastr.options.showMethod = 'fadeIn';
+ toastr.options.timeOut = 5000;
+
+ function standard() {
+ toastr.options.closeButton = false;
+ toastr.options.extendedTimeOut = 1000;
+ toastr.options.timeOut = 5000;
+ };
+
+ function sticky() {
+ toastr.options.closeButton = true;
+ toastr.options.extendedTimeOut = 0;
+ toastr.options.timeOut = 0;
+ };
+
+ return {
+ setStandard: standard,
+ setSticky: sticky
+ };
+})(window.toastr);