Last active
December 17, 2015 16:01
-
-
Save andrewbranch/9935630 to your computer and use it in GitHub Desktop.
A nice notification pattern for MVC .NET, along with a better theme for alertify.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@* displays the flash messages via alertify plugin *@ | |
@section head { | |
<script> | |
$(document).ready(function() { | |
var flashes = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Html.Flash(), Newtonsoft.Json.Formatting.None)); | |
for (var i = 0; i < flashes.length; i++) { | |
alertify.log(flashes[i].text, flashes[i].class, 10000); | |
} | |
}); | |
</script> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web.Mvc; | |
using App.Utilities; | |
namespace App.Helpers | |
{ | |
public static class ActionResultExtensions | |
{ | |
public static WrappedActionResultWithFlash<RedirectResult> WithFlash(this RedirectResult instance, object arguments) | |
{ | |
return Flash(instance, ToDictionary(arguments)); | |
} | |
public static WrappedActionResultWithFlash<RedirectResult> WithFlash(this RedirectResult instance, IDictionary<string, string> arguments) | |
{ | |
return Flash(instance, arguments); | |
} | |
public static WrappedActionResultWithFlash<RedirectToRouteResult> WithFlash(this RedirectToRouteResult instance, object arguments) | |
{ | |
return Flash(instance, ToDictionary(arguments)); | |
} | |
public static WrappedActionResultWithFlash<RedirectToRouteResult> WithFlash(this RedirectToRouteResult instance, IDictionary<string, string> arguments) | |
{ | |
return Flash(instance, arguments); | |
} | |
public static WrappedActionResultWithFlash<ViewResult> WithFlash(this ViewResult instance, object arguments) | |
{ | |
return Flash(instance, ToDictionary(arguments)); | |
} | |
public static WrappedActionResultWithFlash<ViewResult> WithFlash(this ViewResult instance, IDictionary<string, string> arguments) | |
{ | |
return Flash(instance, arguments); | |
} | |
private static WrappedActionResultWithFlash<TActionResult> Flash<TActionResult>(TActionResult instance, IDictionary<string, string> arguments) where TActionResult : ActionResult | |
{ | |
return new WrappedActionResultWithFlash<TActionResult>(instance, arguments); | |
} | |
private static IDictionary<string, string> ToDictionary(object arguments) | |
{ | |
if (arguments == null) | |
{ | |
return new Dictionary<string, string>(); | |
} | |
return arguments.GetType() | |
.GetProperties() | |
.Where(p => p.CanRead && p.GetIndexParameters().Length == 0) | |
.ToDictionary(p => p.Name, p => p.GetValue(arguments, null).ToString()); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#alertify, | |
.alertify-logs .alertify-log { | |
-webkit-transition: all 350ms ease; | |
-moz-transition: all 350ms ease; | |
-ms-transition: all 350ms ease; | |
-o-transition: all 350ms ease; | |
transition: all 350ms ease; | |
} | |
.alertify, .alertify-log { | |
font-family: inherit; | |
} | |
.alertify { | |
background: #fefefe; | |
background: rgba(253, 253, 253, 0.98); | |
border: 8px solid #222; | |
border: 8px solid rgba(0, 0, 0, .9); | |
border-radius: 0; | |
box-shadow: 0 3px 3px rgba(0, 0, 0, .3); | |
-webkit-background-clip: padding; /* Safari 4? Chrome 6? */ | |
-moz-background-clip: padding; /* Firefox 3.6 */ | |
background-clip: padding-box; /* Firefox 4, Safari 5, Opera 10, IE 9 */ | |
} | |
.alertify-text { | |
-webkit-border-radius: 0; | |
border-radius: 0; | |
-webkit-box-shadow: none; | |
-moz-box-shadow: none; | |
box-shadow: none; | |
-webkit-transition: none; | |
-moz-transition: none; | |
-ms-transition: none; | |
-o-transition: none; | |
transition: none; | |
height: 34px; | |
padding: 6px 12px; | |
font-size: 14px; | |
line-height: 1.428571429; | |
color: #555; | |
vertical-align: middle; | |
background-color: #fff; | |
border: 1px solid #ccc; | |
background-image: none; | |
} | |
.alertify-text:focus { | |
border-color: #66afe9; | |
outline: 0; | |
} | |
.alertify .alertify-button, | |
.alertify .alertify-button:hover, | |
.alertify .alertify-button:active { | |
outline: 0; | |
-webkit-border-radius: 0; | |
border-radius: 0; | |
background-image: none; | |
background: white; | |
text-shadow: none; | |
display: inline-block; | |
padding: 6px 12px; | |
margin-bottom: 0; | |
font-size: 14px; | |
font-weight: normal; | |
line-height: 1.428571429; | |
text-align: center; | |
white-space: nowrap; | |
vertical-align: middle; | |
-webkit-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
-o-user-select: none; | |
user-select: none; | |
border: 1px solid #cacaca; | |
color: #555; | |
-webkit-box-shadow: 0 2px 3px rgba(0,0,0,.02); | |
-moz-box-shadow: 0 2px 3px rgba(0,0,0,.02); | |
box-shadow: 0 2px 3px rgba(0,0,0,.02); | |
} | |
.alertify-cover { | |
filter: alpha(opacity=70); | |
opacity: .7; | |
} | |
/* Default buttons */ | |
.alertify-button:focus { | |
border-color: #66afe9; | |
} | |
.alertify .alertify-button:hover { | |
-webkit-box-shadow: none; | |
-moz-box-shadow: none; | |
box-shadow: none; | |
border-color: #ddd; | |
color: #888; | |
} | |
.alertify .alertify-button:active { | |
-webkit-box-shadow: 0 2px 3px rgba(0,0,0,.05) inset; | |
-moz-box-shadow: 0 2px 3px rgba(0,0,0,.05) inset; | |
box-shadow: 0 2px 3px rgba(0,0,0,.05) inset; | |
} | |
/* Danger buttons */ | |
.alertify-button.alertify-button-danger { | |
-webkit-box-shadow: 0 3px 3px rgba(0, 0, 0, .07); | |
-moz-box-shadow: 0 3px 3px rgba(0, 0, 0, .07); | |
box-shadow: 0 3px 3px rgba(0, 0, 0, .07); | |
background: #db5151; | |
color: white; | |
border-color: #b17d7d; | |
} | |
.alertify-button.alertify-button-danger:hover { | |
background: #ec6262; | |
border-color: #c28e8e; | |
color: white; | |
} | |
.alertify-button.alertify-button-danger:focus { | |
border-color: white; | |
} | |
.alertify-button.alertify-button-danger:active { | |
background: #EC6252; | |
color: white; | |
box-shadow: 0 2px 3px rgba(0,0,0,.15) inset; | |
} | |
.alertify-log { | |
background: #222; | |
background: rgba(0, 0, 0, .85); | |
padding: 15px; | |
border-radius: 4px; | |
color: white; | |
text-shadow: none; | |
max-height: 100%; | |
} | |
.alertify-log a { | |
color: #69c; | |
text-decoration: none; | |
} | |
.alertify-log a:hover { | |
color: #8be; | |
text-decoration: none; | |
} | |
.alertify-log-error { | |
background: rgba(150, 20, 20, .95); | |
} | |
.alertify-log-error a { | |
color: #f99; | |
} | |
.alertify-log-error a:hover { | |
color: #fcc; | |
} | |
.alertify-log-success { | |
background: rgba(30, 110, 20, .85); | |
} | |
.alertify-log-success a { | |
color: #ac9; | |
} | |
.alertify-log-success a:hover { | |
color: #cfb; | |
} | |
.alertify-inner { | |
font-size: 14px; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* don't remember if I changed anything in here or not... */ | |
.alertify, | |
.alertify-show, | |
.alertify-log { | |
-webkit-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275); | |
-moz-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275); | |
-ms-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275); | |
-o-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275); | |
transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275); /* easeOutBack */ | |
} | |
.alertify-hide { | |
-webkit-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
-moz-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
-ms-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
-o-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045); /* easeInBack */ | |
} | |
.alertify-log-hide { | |
-webkit-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
-moz-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
-ms-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
-o-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045); | |
transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045); /* easeInBack */ | |
} | |
.alertify-cover { | |
position: fixed; z-index: 99999; | |
top: 0; right: 0; bottom: 0; left: 0; | |
background-color:white; | |
filter:alpha(opacity=0); | |
opacity:0; | |
} | |
.alertify-cover-hidden { | |
display: none; | |
} | |
.alertify { | |
position: fixed; z-index: 99999; | |
top: 50px; left: 50%; | |
width: 550px; | |
margin-left: -275px; | |
opacity: 1; | |
} | |
.alertify-hidden { | |
-webkit-transform: translate(0,-150px); | |
-moz-transform: translate(0,-150px); | |
-ms-transform: translate(0,-150px); | |
-o-transform: translate(0,-150px); | |
transform: translate(0,-150px); | |
opacity: 0; | |
display: none; | |
} | |
/* overwrite display: none; for everything except IE6-8 */ | |
:root *> .alertify-hidden { | |
display: block; | |
visibility: hidden; | |
} | |
.alertify-logs { | |
position: fixed; | |
z-index: 5000; | |
bottom: 10px; | |
right: 10px; | |
width: 300px; | |
} | |
.alertify-logs-hidden { | |
display: none; | |
} | |
.alertify-log { | |
display: block; | |
margin-top: 10px; | |
position: relative; | |
right: -300px; | |
opacity: 0; | |
} | |
.alertify-log-show { | |
right: 0; | |
opacity: 1; | |
} | |
.alertify-log-hide { | |
overflow: hidden; | |
-webkit-transform: translate(300px, 0); | |
-moz-transform: translate(300px, 0); | |
-ms-transform: translate(300px, 0); | |
-o-transform: translate(300px, 0); | |
transform: translate(300px, 0); | |
opacity: 0; | |
} | |
.alertify-dialog { | |
padding: 25px; | |
} | |
.alertify-resetFocus { | |
border: 0; | |
clip: rect(0 0 0 0); | |
height: 1px; | |
margin: -1px; | |
overflow: hidden; | |
padding: 0; | |
position: absolute; | |
width: 1px; | |
} | |
.alertify-inner { | |
text-align: center; | |
} | |
.alertify-text { | |
margin-bottom: 15px; | |
width: 100%; | |
-webkit-box-sizing: border-box; | |
-moz-box-sizing: border-box; | |
box-sizing: border-box; | |
font-size: 100%; | |
} | |
.alertify-buttons { | |
} | |
.alertify-button, | |
.alertify-button:hover, | |
.alertify-button:active, | |
.alertify-button:visited { | |
background: none; | |
text-decoration: none; | |
border: none; | |
/* line-height and font-size for input button */ | |
line-height: 1.5; | |
font-size: 100%; | |
display: inline-block; | |
cursor: pointer; | |
margin-left: 5px; | |
} | |
@media only screen and (max-width: 680px) { | |
.alertify, | |
.alertify-logs { | |
width: 90%; | |
-webkit-box-sizing: border-box; | |
-moz-box-sizing: border-box; | |
box-sizing: border-box; | |
} | |
.alertify { | |
left: 5%; | |
margin: 0; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using App.Models; | |
using System; | |
using System.Collections.Generic; | |
using System.Data.Entity; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Mvc; | |
using App.Helpers; | |
namespace Big.Controllers | |
{ | |
public class LocationsController : Controller | |
{ | |
private AppContext context; | |
public LocationsController() { | |
this.context = new AppContext(); | |
} | |
public ActionResult Edit(int id) { | |
return View(context.Locations.Find(id)); | |
} | |
[HttpPut] | |
public ActionResult Edit(Location location) { | |
if (ModelState.IsValid) { | |
context.Entry(location).State = EntityState.Modified; | |
context.SaveChanges(); | |
return RedirectToAction("Index").WithFlash(new { success = String.Format("Changes to “{0}” saved.", location.Name) }); | |
} else { | |
return View(location); | |
} | |
} | |
protected override void Dispose(bool disposing) { | |
context.Dispose(); | |
base.Dispose(disposing); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web.Mvc; | |
namespace App.Utilities { | |
public class FlashStorage | |
{ | |
public static readonly string Key = typeof(FlashStorage).FullName; | |
public FlashStorage(TempDataDictionary backingStore) | |
{ | |
if (backingStore == null) | |
{ | |
throw new ArgumentNullException("backingStore"); | |
} | |
BackingStore = backingStore; | |
} | |
public TempDataDictionary BackingStore { get; private set; } | |
public IEnumerable<KeyValuePair<string, string>> Messages | |
{ | |
get | |
{ | |
try | |
{ | |
object value; | |
if (!BackingStore.TryGetValue(Key, out value)) | |
{ | |
return new List<KeyValuePair<string, string>>(); | |
} | |
return (IEnumerable<KeyValuePair<string, string>>)value; | |
} | |
finally | |
{ | |
BackingStore.Remove(Key); | |
} | |
} | |
} | |
public void Add(string type, string message) | |
{ | |
if (string.IsNullOrWhiteSpace(message)) | |
{ | |
return; | |
} | |
IList<KeyValuePair<string, string>> messages; | |
object temp; | |
if (!BackingStore.TryGetValue(Key, out temp)) | |
{ | |
messages = new List<KeyValuePair<string, string>>(); | |
BackingStore.Add(Key, messages); | |
} | |
else | |
{ | |
messages = (IList<KeyValuePair<string, string>>)temp; | |
} | |
var item = messages.SingleOrDefault(p => p.Key.Equals(type, StringComparison.OrdinalIgnoreCase)); | |
if (!string.IsNullOrWhiteSpace(item.Value)) | |
{ | |
messages.Remove(item); | |
} | |
messages.Add(new KeyValuePair<string, string>(type, message)); | |
BackingStore.Keep(Key); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Where is the implementation for Html.Flash() ?