submit form now works, except for categories, and error handling, and handling failed transactions, and...

This commit is contained in:
tmont 2011-02-13 09:55:01 +00:00
parent f0221f2a7b
commit 2409a207cf
8 changed files with 187 additions and 115 deletions

View File

@ -11,7 +11,7 @@
<property name="Modified" column="modified" not-null="false" type="DateTime" /> <property name="Modified" column="modified" not-null="false" type="DateTime" />
<many-to-one name="Creator" column="creator" not-null="true" foreign-key="fk_quote_user"/> <many-to-one name="Creator" column="creator" not-null="true" foreign-key="fk_quote_user"/>
<many-to-one name="Game" column="game_id" not-null="true" foreign-key="fk_quote_game" /> <many-to-one name="Game" column="game_id" not-null="true" foreign-key="fk_quote_game" cascade="save-update" />
<set access="field" name="categories" table="quote_category_map" cascade="save-update"> <set access="field" name="categories" table="quote_category_map" cascade="save-update">
<key column="quote_id" /> <key column="quote_id" />

View File

@ -11,8 +11,6 @@ namespace VideoGameQuotes.Api {
Japan = 2, Japan = 2,
Europe = 4, Europe = 4,
PAL = 8, PAL = 8,
Australia = 16, Australia = 16
All = NorthAmerica | Japan | Europe | PAL | Australia
} }
} }

View File

@ -72,7 +72,7 @@ namespace VideoGameQuotes.Web.Controllers {
//construct game from model data //construct game from model data
var game = new Game { var game = new Game {
Name = model.GameName, Name = model.GameName,
Region = model.GameRegions.Aggregate(Region.Unknown, (current, next) => current | (Region)Enum.Parse(typeof(Region), next)), Region = model.GameRegions,
Website = model.GameWebsite, Website = model.GameWebsite,
Creator = currentUserProvider.CurrentUser Creator = currentUserProvider.CurrentUser
}; };
@ -123,6 +123,7 @@ namespace VideoGameQuotes.Web.Controllers {
model.AllGames = quoteService.GetAllGames().OrderBy(game => game.Name); model.AllGames = quoteService.GetAllGames().OrderBy(game => game.Name);
model.AllSystems = quoteService.GetAllSystems().OrderBy(system => system.ReleaseDate); model.AllSystems = quoteService.GetAllSystems().OrderBy(system => system.ReleaseDate);
model.AllPublishers = quoteService.GetAllPublishers(); model.AllPublishers = quoteService.GetAllPublishers();
model.AllCategories = quoteService.GetAllCategories();
} }
public ActionResult Quote(int id) { public ActionResult Quote(int id) {

View File

@ -2,16 +2,21 @@
using System.Web.Routing; using System.Web.Routing;
using Microsoft.Practices.Unity; using Microsoft.Practices.Unity;
using Portoa.Web; using Portoa.Web;
using Portoa.Web.Models;
using Portoa.Web.Unity; using Portoa.Web.Unity;
using UnityGenerics; using UnityGenerics;
using VideoGameQuotes.Api; using VideoGameQuotes.Api;
using VideoGameQuotes.Api.Persistence; using VideoGameQuotes.Api.Persistence;
using VideoGameQuotes.Web.Controllers;
using VideoGameQuotes.Web.Security; using VideoGameQuotes.Web.Security;
using VideoGameQuotes.Web.Services; using VideoGameQuotes.Web.Services;
namespace VideoGameQuotes.Web { namespace VideoGameQuotes.Web {
public class MvcApplication : ApplicationBase { public class MvcApplication : MvcApplicationBase {
protected override void ConfigureModelBinders(ModelBinderDictionary binders) {
binders.Add<Region, FlagEnumModelBinder>();
}
protected override void ConfigureUnity() { protected override void ConfigureUnity() {
Container Container
.AddNewExtension<ConfigureLog4Net>() .AddNewExtension<ConfigureLog4Net>()

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
@ -12,6 +13,8 @@ namespace VideoGameQuotes.Web.Models {
public class QuoteSubmitModel { public class QuoteSubmitModel {
[Required, DisplayName("Quote")] [Required, DisplayName("Quote")]
public string QuoteText { get; set; } public string QuoteText { get; set; }
[DisplayName("Categories")]
public IList<int> CategoryIds { get; set; }
public int GameId { get; set; } public int GameId { get; set; }
@ -21,7 +24,7 @@ namespace VideoGameQuotes.Web.Models {
[DisplayName("Website")] [DisplayName("Website")]
public string GameWebsite { get; set; } public string GameWebsite { get; set; }
[DisplayName("Region")] [DisplayName("Region")]
public IList<string> GameRegions { get; set; } public Region GameRegions { get; set; }
[DisplayName("Publishers")] [DisplayName("Publishers")]
public IList<int> PublisherIds { get; set; } public IList<int> PublisherIds { get; set; }
[DisplayName("Systems")] [DisplayName("Systems")]
@ -44,6 +47,7 @@ namespace VideoGameQuotes.Web.Models {
public IEnumerable<Game> AllGames { get; set; } public IEnumerable<Game> AllGames { get; set; }
public IEnumerable<GamingSystem> AllSystems { get; set; } public IEnumerable<GamingSystem> AllSystems { get; set; }
public IEnumerable<Publisher> AllPublishers { get; set; } public IEnumerable<Publisher> AllPublishers { get; set; }
public IEnumerable<Category> AllCategories { get; set; }
public IEnumerable<SelectListItem> GetGameList() { public IEnumerable<SelectListItem> GetGameList() {
return new[] { new SelectListItem { Value = "0", Text = "--none--" } } return new[] { new SelectListItem { Value = "0", Text = "--none--" } }
@ -78,18 +82,41 @@ namespace VideoGameQuotes.Web.Models {
return table.ToString(TagRenderMode.Normal); return table.ToString(TagRenderMode.Normal);
} }
public string MakePublisherTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 4) { public string MakePublisherTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 8) {
return MakeTable(cellsPerRow, AllPublishers, publisher => { return MakeTable(
var id = "publisher_" + publisher.Id; cellsPerRow,
return html.CheckBox("PublisherIds", new { id }) + html.Label(publisher.Name, id); AllPublishers,
}); publisher => CreateCheckbox(html, "PublisherIds", publisher.Id, "publisher_" + publisher.Id, publisher.Name)
);
} }
public string MakeSystemTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 8) { public string MakeSystemTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 8) {
return MakeTable(cellsPerRow, AllSystems, system => { return MakeTable(
var id = "system_" + system.Id; cellsPerRow,
return html.CheckBox("SystemIds", new { id }) + html.Label(system.Abbreviation, id, new { title = system.Name }); AllSystems,
}); system => CreateCheckbox(html, "SystemIds", system.Id, "system_" + system.Id, system.Abbreviation)
);
}
public string MakeCategoryTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 8) {
return MakeTable(
cellsPerRow,
AllCategories,
category => CreateCheckbox(html, "CategoryIds", category.Id, "category_" + category.Id, category.Name)
);
}
public string MakeRegionTable(HtmlHelper<QuoteSubmitModel> html, int cellsPerRow = 8) {
return MakeTable(
cellsPerRow,
(IEnumerable<Region>)Enum.GetValues(typeof(Region)),
region => CreateCheckbox(html, "GameRegions", region, "region_" + (int)region, region.ToString())
);
}
private static string CreateCheckbox(HtmlHelper<QuoteSubmitModel> html, string name, object value, string id, string labelText) {
return string.Format("<input type=\"checkbox\" name=\"{0}\" value=\"{1}\" id=\"{2}\"/>", name, value, id)
+ html.Label(labelText, id);
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Portoa.Persistence; using Portoa.Persistence;
using VideoGameQuotes.Api; using VideoGameQuotes.Api;
@ -8,10 +9,12 @@ namespace VideoGameQuotes.Web.Services {
IEnumerable<Game> GetAllGames(); IEnumerable<Game> GetAllGames();
IEnumerable<GamingSystem> GetAllSystems(); IEnumerable<GamingSystem> GetAllSystems();
IEnumerable<Publisher> GetAllPublishers(); IEnumerable<Publisher> GetAllPublishers();
IEnumerable<Category> GetAllCategories();
Quote SaveQuote(Quote quote); Quote SaveQuote(Quote quote);
Quote GetQuote(int id); Quote GetQuote(int id);
Publisher GetPublisher(int id); Publisher GetPublisher(int id);
GamingSystem GetSystem(int systemId); GamingSystem GetSystem(int systemId);
Category GetCategory(int categoryId);
} }
public class QuoteService : IQuoteService { public class QuoteService : IQuoteService {
@ -19,14 +22,16 @@ namespace VideoGameQuotes.Web.Services {
private readonly IRepository<Game> gameRepository; private readonly IRepository<Game> gameRepository;
private readonly IRepository<GamingSystem> systemRepository; private readonly IRepository<GamingSystem> systemRepository;
private readonly IRepository<Publisher> publisherRepository; private readonly IRepository<Publisher> publisherRepository;
private readonly IRepository<Category> categoryRepository;
public QuoteService( public QuoteService(
IRepository<Quote> quoteRepository, IRepository<Quote> quoteRepository,
IRepository<Game> gameRepository, IRepository<Game> gameRepository,
IRepository<GamingSystem> systemRepository, IRepository<GamingSystem> systemRepository,
IRepository<Publisher> publisherRepository IRepository<Publisher> publisherRepository, IRepository<Category> categoryRepository
) { ) {
this.quoteRepository = quoteRepository; this.quoteRepository = quoteRepository;
this.categoryRepository = categoryRepository;
this.gameRepository = gameRepository; this.gameRepository = gameRepository;
this.systemRepository = systemRepository; this.systemRepository = systemRepository;
this.publisherRepository = publisherRepository; this.publisherRepository = publisherRepository;
@ -43,7 +48,7 @@ namespace VideoGameQuotes.Web.Services {
} }
[UnitOfWork] [UnitOfWork]
public IEnumerable<Api.GamingSystem> GetAllSystems() { public IEnumerable<GamingSystem> GetAllSystems() {
return systemRepository.Records; return systemRepository.Records;
} }
@ -52,6 +57,11 @@ namespace VideoGameQuotes.Web.Services {
return publisherRepository.Records; return publisherRepository.Records;
} }
[UnitOfWork]
public IEnumerable<Category> GetAllCategories() {
return categoryRepository.Records;
}
[UnitOfWork] [UnitOfWork]
public Quote SaveQuote(Quote quote) { public Quote SaveQuote(Quote quote) {
return quoteRepository.Save(quote); return quoteRepository.Save(quote);
@ -71,5 +81,10 @@ namespace VideoGameQuotes.Web.Services {
public GamingSystem GetSystem(int systemId) { public GamingSystem GetSystem(int systemId) {
return systemRepository.FindById(systemId); return systemRepository.FindById(systemId);
} }
[UnitOfWork]
public Category GetCategory(int categoryId) {
return categoryRepository.FindById(categoryId);
}
} }
} }

View File

@ -6,103 +6,119 @@
<%= Html.ValidationSummary() %> <%= Html.ValidationSummary() %>
<% using (Html.BeginForm()) { %> <div id="create-quote-form">
<p> <% using (Html.BeginForm()) { %>
<span id="game-select"> <p>
<%= Html.Label("Game", "GameId") %> <span id="game-select">
<%= Html.Label("Game", "GameId") %>
<br />
<%= Html.DropDownListFor(model => model.GameId, Model.GetGameList()) %>
</span>
<a href="#" id="create-game-link">Create new game</a>
</p>
<div id="create-game-form">
<fieldset>
<legend>Create new game</legend>
<p>
<%= Html.LabelFor(model => model.GameName) %>
<br />
<%= Html.TextBoxFor(model => model.GameName) %>
</p>
<p>
<%= Html.LabelFor(model => model.GameWebsite) %> <small>(link to Wikipedia page or something)</small>
<br />
<%= Html.TextBoxFor(model => model.GameWebsite) %>
</p>
<p>
<%= Html.LabelFor(model => model.GameRegions) %>
<br />
<%= Model.MakeRegionTable(Html) %>
</p>
<p>
<span id="system-select">
<%= Html.LabelFor(model => model.SystemIds) %>
<br />
<%= Model.MakeSystemTable(Html) %>
</span>
<a href="#" id="create-system-link">Create new system</a>
</p>
<div id="create-system-form">
<fieldset>
<legend>Create new system</legend>
<p>
<%= Html.LabelFor(model => model.SystemName) %>
<br />
<%= Html.TextBoxFor(model => model.SystemName) %>
</p>
<p>
<%= Html.LabelFor(model => model.SystemAbbreviation) %>
<br />
<%= Html.TextBoxFor(model => model.SystemAbbreviation) %>
</p>
<p>
<%= Html.LabelFor(model => model.SystemReleaseDate) %>
<br />
<%= Html.TextBox("SystemReleaseDate", DateTime.UtcNow.ToString("yyyy-MM-dd")) %>
</p>
</fieldset>
</div>
<p>
<span id="publisher-select">
<%= Html.LabelFor(model => model.PublisherIds) %>
<br />
<%= Model.MakePublisherTable(Html) %>
</span>
<a href="#" id="create-publisher-link">Create new publisher</a>
</p>
<div id="create-publisher-form">
<fieldset>
<legend>Create new publisher</legend>
<p>
<%= Html.LabelFor(model => model.PublisherName) %>
<br />
<%= Html.TextBoxFor(model => model.PublisherName) %>
</p>
<p>
<%= Html.LabelFor(model => model.PublisherWebsite) %>
<br />
<%= Html.TextBoxFor(model => model.PublisherWebsite) %>
</p>
</fieldset>
</div>
</fieldset>
</div>
<p>
<%= Html.LabelFor(model => model.QuoteText) %>
<br /> <br />
<%= Html.DropDownListFor(model => model.GameId, Model.GetGameList()) %> <%= Html.TextAreaFor(model => model.QuoteText) %>
</span> </p>
<a href="#" id="create-game-link">Create new game</a> <p>
</p> <%= Html.LabelFor(model => model.CategoryIds) %>
<br />
<%= Model.MakeCategoryTable(Html) %>
<div id="create-game-form"> <a href="#" id="create-category-link">Create new category</a>
<fieldset> </p>
<legend>Create new game</legend>
<p> <%= Html.Submit("Submit") %>
<%= Html.LabelFor(model => model.GameName) %> <% } %>
<br /> </div>
<%= Html.TextBoxFor(model => model.GameName) %>
</p>
<p>
<%= Html.LabelFor(model => model.GameWebsite) %> <small>(link to Wikipedia page or something)</small>
<br />
<%= Html.TextBoxFor(model => model.GameWebsite) %>
</p>
<p>
<span id="system-select">
<%= Html.LabelFor(model => model.SystemIds) %>
<br />
<%= Model.MakeSystemTable(Html) %>
</span>
<a href="#" id="create-system-link">Create new system</a>
</p>
<div id="create-system-form">
<fieldset>
<legend>Create new system</legend>
<p>
<%= Html.LabelFor(model => model.SystemName) %>
<br />
<%= Html.TextBoxFor(model => model.SystemName) %>
</p>
<p>
<%= Html.LabelFor(model => model.SystemAbbreviation) %>
<br />
<%= Html.TextBoxFor(model => model.SystemAbbreviation) %>
</p>
<p>
<%= Html.LabelFor(model => model.SystemReleaseDate) %>
<br />
<%= Html.TextBox("SystemReleaseDate", DateTime.UtcNow.ToString("yyyy-MM-dd")) %>
</p>
</fieldset>
</div>
<p>
<span id="publisher-select">
<%= Html.LabelFor(model => model.PublisherIds) %>
<br />
<%= Model.MakePublisherTable(Html) %>
</span>
<a href="#" id="create-publisher-link">Create new publisher</a>
</p>
<div id="create-publisher-form">
<fieldset>
<legend>Create new publisher</legend>
<p>
<%= Html.LabelFor(model => model.PublisherName) %>
<br />
<%= Html.TextBoxFor(model => model.PublisherName) %>
</p>
<p>
<%= Html.LabelFor(model => model.PublisherWebsite) %>
<br />
<%= Html.TextBoxFor(model => model.PublisherWebsite) %>
</p>
</fieldset>
</div>
</fieldset>
</div>
<p>
<%= Html.LabelFor(model => model.QuoteText) %>
<br />
<%= Html.TextAreaFor(model => model.QuoteText) %>
</p>
<%= Html.Submit("Submit") %>
<% } %>
</asp:Content> </asp:Content>
<asp:Content runat="server" ID="DeferrableScripts" ContentPlaceHolderID="DeferrableScripts"> <asp:Content runat="server" ID="DeferrableScripts" ContentPlaceHolderID="DeferrableScripts">
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[

View File

@ -132,9 +132,19 @@ legend {
border-bottom: 2px solid #000000; border-bottom: 2px solid #000000;
} }
#create-game-form, #create-system-form { #create-game-form, #create-system-form, #create-publisher-form {
display: none; display: none;
} }
#create-quote-form input[type="text"] {
width: 300px;
}
#create-quote-form textarea {
width: 500px;
height: 100px;
}
#create-quote-form td {
padding: 5px;
}
#footer { #footer {
text-align: center; text-align: center;