minor css adjustments, finished quote form for now, will tweak ui later
This commit is contained in:
parent
dfa5277e8c
commit
1dea16708b
@ -6,7 +6,7 @@
|
||||
<generator class="identity" />
|
||||
</id>
|
||||
|
||||
<property name="Name" column="category_name" not-null="true" length="255"/>
|
||||
<property name="Name" column="category_name" not-null="true" length="255" unique="true"/>
|
||||
<property name="Created" column="created" not-null="true" />
|
||||
</class>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Iesi.Collections.Generic;
|
||||
using Portoa.Persistence;
|
||||
|
||||
@ -69,6 +70,13 @@ namespace VideoGameQuotes.Api {
|
||||
}
|
||||
|
||||
public static class QuoteExtensions {
|
||||
private static readonly Regex urlFriendlyRegex = new Regex(@"[^A-Za-z0-9_-]");
|
||||
|
||||
public static string GetUrlFriendlyText(this Quote quote) {
|
||||
var text = urlFriendlyRegex.Replace(quote.Text.Replace(" ", "_").Replace("\n", ""), "");
|
||||
return text.Substring(0, Math.Min(text.Length, 50));
|
||||
}
|
||||
|
||||
public static string GetHumanReadableTimeSinceCreated(this Quote quote) {
|
||||
var timespan = DateTime.UtcNow.Subtract(quote.Created);
|
||||
if (timespan.TotalDays >= 365) {
|
||||
|
@ -3,6 +3,10 @@ using Portoa.Persistence;
|
||||
|
||||
namespace VideoGameQuotes.Api {
|
||||
public class Vote : Entity<Vote, int> {
|
||||
public Vote() {
|
||||
Created = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public virtual User Voter { get; set; }
|
||||
public virtual Quote Quote { get; set; }
|
||||
public virtual DateTime Created { get; set; }
|
||||
|
@ -30,7 +30,6 @@ namespace VideoGameQuotes.Web.Controllers {
|
||||
public ActionResult Submit(QuoteSubmitModel model) {
|
||||
if (!ModelState.IsValid) {
|
||||
ResetModel(model);
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
@ -41,26 +40,13 @@ namespace VideoGameQuotes.Web.Controllers {
|
||||
Text = model.QuoteText
|
||||
};
|
||||
|
||||
//categories
|
||||
if ((model.CategoryIds != null && model.CategoryIds.Count > 0)) {
|
||||
//modifying systems, so remove errthing
|
||||
quote.ClearCategories();
|
||||
|
||||
if (model.CategoryIds != null && model.CategoryIds.Count > 0) {
|
||||
quote.ClearCategories();
|
||||
foreach (var categoryId in model.CategoryIds) {
|
||||
quote.AddCategory(quoteService.GetCategory(categoryId));
|
||||
}
|
||||
}
|
||||
|
||||
//if (!string.IsNullOrEmpty(model.SystemName)) {
|
||||
// game.AddSystem(new GamingSystem {
|
||||
// Name = model.SystemName,
|
||||
// Abbreviation = model.SystemAbbreviation,
|
||||
// ReleaseDate = model.SystemReleaseDate
|
||||
// });
|
||||
//}
|
||||
}
|
||||
|
||||
if (quote.Game == null) {
|
||||
ResetModel(model);
|
||||
return View(model);
|
||||
@ -68,7 +54,7 @@ namespace VideoGameQuotes.Web.Controllers {
|
||||
|
||||
quote = quoteService.SaveQuote(quote);
|
||||
|
||||
return RedirectToAction("Quote", new { id = quote.Id });
|
||||
return RedirectToAction("Quote", new { id = quote.Id, text = quote.GetUrlFriendlyText() });
|
||||
} catch (Exception e) {
|
||||
ModelState.AddModelError("save", e.Message);
|
||||
ResetModel(model);
|
||||
|
@ -41,7 +41,7 @@ namespace VideoGameQuotes.Web {
|
||||
routes.MapRoute("contact", "contact", new { controller = "Home", action = "Contact" });
|
||||
routes.MapRoute("submit", "submit", new { controller = "Quote", action = "Submit" });
|
||||
routes.MapRoute("create-category", "category/create", new { controller = "Quote", action = "CreateCategory" });
|
||||
routes.MapRoute("individual-quote", "q/{id}/{*text}", new { controller = "Quote", action = "Quote" }, new { id = @"\d+" });
|
||||
routes.MapRoute("individual-quote", "quote/{id}/{*text}", new { controller = "Quote", action = "Quote" }, new { id = @"\d+" });
|
||||
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,15 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc.Html;
|
||||
using Portoa.Web.Util;
|
||||
using VideoGameQuotes.Api;
|
||||
using VideoGameQuotes.Web.Validation;
|
||||
|
||||
namespace VideoGameQuotes.Web.Models {
|
||||
public class QuoteSubmitModel {
|
||||
[Required, DisplayName("Quote")]
|
||||
[NonEmptyText(ErrorMessage = "Quote text must be non-empty"), DisplayName("Quote")]
|
||||
public string QuoteText { get; set; }
|
||||
[DisplayName("Categories")]
|
||||
public IList<int> CategoryIds { get; set; }
|
||||
@ -101,7 +99,7 @@ namespace VideoGameQuotes.Web.Models {
|
||||
);
|
||||
}
|
||||
|
||||
public string MakeCategoryTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 8) {
|
||||
public string MakeCategoryTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 5) {
|
||||
return MakeTable(
|
||||
"category-checkbox-table",
|
||||
cellsPerRow,
|
||||
|
13
Src/VideoGameQuotes.Web/Validation/NonEmptyText.cs
Normal file
13
Src/VideoGameQuotes.Web/Validation/NonEmptyText.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace VideoGameQuotes.Web.Validation {
|
||||
public class NonEmptyText : ValidationAttribute {
|
||||
public override bool IsValid(object value) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !string.IsNullOrWhiteSpace(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
@ -85,6 +85,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Controllers\HomeController.cs" />
|
||||
<Compile Include="Validation\NonEmptyText.cs" />
|
||||
<Compile Include="Security\IsValidUserAttribute.cs" />
|
||||
<Compile Include="Controllers\QuoteController.cs" />
|
||||
<Compile Include="Services\QuoteService.cs" />
|
||||
|
@ -4,10 +4,10 @@
|
||||
<asp:Content runat="server" ID="Main" ContentPlaceHolderID="MainContent">
|
||||
<h2>Submit New Quote</h2>
|
||||
|
||||
<%= Html.ValidationSummary() %>
|
||||
<%= Html.ValidationSummary("Some errors occurred while trying to submit your quote:") %>
|
||||
|
||||
<div id="create-quote-form">
|
||||
<% using (Html.BeginForm()) { %>
|
||||
<% using (Html.BeginForm("Submit", "Quote")) { %>
|
||||
<p>
|
||||
<span id="game-select">
|
||||
<%= Html.Label("Game", "GameId") %>
|
||||
@ -108,15 +108,18 @@
|
||||
<%= Html.TextAreaFor(model => model.QuoteText) %>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<%= Html.LabelFor(model => model.CategoryIds) %>
|
||||
<br />
|
||||
</p>
|
||||
<%= Model.MakeCategoryTable(Html) %>
|
||||
|
||||
<a href="#" id="create-category-link">Create new category</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%= Html.Submit("Submit") %>
|
||||
<hr />
|
||||
|
||||
<%= Html.Submit("Submit Quote") %>
|
||||
<% } %>
|
||||
</div>
|
||||
</asp:Content>
|
||||
|
@ -20,7 +20,7 @@
|
||||
</div>
|
||||
|
||||
<div id="main-menu">
|
||||
<ul class="clearfix">
|
||||
<ul class="clearfix menu">
|
||||
<li><%= Html.ActionLink("Recent", "Recent", "Quote") %></li>
|
||||
<li><%= Html.ActionLink("Random", "Random", "Quote") %></li>
|
||||
<li><%= Html.ActionLink("Best", "Best", "Quote") %></li>
|
||||
|
@ -37,6 +37,20 @@ legend {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
ul.menu {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
.validation-summary-errors {
|
||||
color: #000000;
|
||||
border: 1px solid #000000;
|
||||
background-color: #F7DBDB;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.inset {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
@ -57,10 +57,33 @@ table {
|
||||
.mir { letter-spacing : -1000em; }
|
||||
/*\*/html>body .mir { letter-spacing : normal; text-indent : -999em; overflow : hidden;}
|
||||
|
||||
|
||||
|
||||
/* defaults */
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
ul, ol {
|
||||
list-style-position: outside;
|
||||
margin-left: 20px;
|
||||
padding: 5px;
|
||||
}
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
padding: 2px;
|
||||
}
|
||||
dd {
|
||||
margin-left: 20px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
|
@ -165,10 +165,15 @@ namespace VideoGameQuotes.Api.Tests.NHibernate {
|
||||
.AddCategory(danger)
|
||||
.VoteFor(creator, VoteDirection.Up);
|
||||
|
||||
var hopOnMyBack = new Quote { Creator = creator, Game = crystalis, Text = "Please hop on my back. I'll take you wherever you like." }
|
||||
.AddCategory(new Category { Name = "Dolphins" })
|
||||
.VoteFor(creator, VoteDirection.Up);
|
||||
|
||||
using (var tx = session.BeginTransaction()) {
|
||||
var repo = new NHibernateRepository<Quote>(session);
|
||||
repo.Save(allYourBase);
|
||||
repo.Save(dangerousToGoAlone);
|
||||
repo.Save(hopOnMyBack);
|
||||
tx.Commit();
|
||||
}
|
||||
#endregion
|
||||
|
@ -161,7 +161,7 @@ alter table quote_category_map drop foreign key FK5892F846C2AA09DD
|
||||
|
||||
create table category (
|
||||
category_id INTEGER NOT NULL AUTO_INCREMENT,
|
||||
category_name VARCHAR(255) not null,
|
||||
category_name VARCHAR(255) not null unique,
|
||||
created DATETIME not null,
|
||||
primary key (category_id)
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user