Yet another compile error for me:
Error 1 'Model' conflicts with the declaration 'System.Web.Mvc.ViewUserControl.Model' c:\Users\Kevin\Documents\Visual Studio 2010\Projects\HandiGamer\HandiGamer\Views\Shared\EditorTemplates\AdminGameReviewViewModel.ascx 10 51 HandiGamer.WebUI
I'm trying to use a partial view to handle both Create and Edit functionality. So, my Create view is:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<HandiGamer.WebUI.ViewModels.AdminGameReviewViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Create New Review
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create New Review</h2>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Create New Review</legend>
<%: Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to Menu", "Index") %>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="CSSandJavaScript" runat="server">
</asp:Content>
And the partial view is:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HandiGamer.WebUI.ViewModels.AdminGameReviewViewModel>" %>
<p>
<%: Html.Label("Game Title") %>
<%: Html.TextBoxFor(Model => Model.GameData.GameTitle) %>
<%: Html.ValidationMessageFor(Model => Model.GameData.GameTitle) %>
</p>
<p>
<%: Html.LabelFor(Model => Model.GameData.Genre) %>
<%: Html.DropDownList("Genre", new SelectList(Model.AllGenres, "GenreID", "Name", Model.GameData.GenreID)) %>
</p>
<p>
<%: Html.Label("Platforms") %><br />
<% for (int i = 0; i < Model.AllPlatforms.Count(); ++i) { %>
<%: Model.AllPlatforms[i].Platform.Name %> <%: Html.CheckBoxFor(plat => plat.AllPlatforms[i].IsSelected)%><br />
<% } %>
</p>
<p>
<%: Html.Label("Review Title") %>
<%: Html.TextBoxFor(model => model.GameData.Content.Title) %>
</p>
<p>
<%: Html.Label("Review") %>
<%: Html.TextAreaFor(model => model.GameData.Content.Text) %>
</p>
<p>
<%: Html.Label("Review Score") %>
<%: Html.DropDownList("Score", new SelectList(new int[] {1, 2, 3, 4, 5}, "ReviewScore")) %>
</p>
<p>
<%: Html.LabelFor(model => model.GameData.Pros) %><br />
<%: Html.TextBox("Pros[]") %><br />
<%: Html.TextBox("Pros[]") %><br />
<%: Html.TextBox("Pros[]") %><br />
<%: Html.TextBox("Pros[]") %><br />
<%: Html.TextBox("Pros[]") %>
</p>
The line in question is the one that attempts to create the first DropDownList, specifically when I write Model.AllGeneres. That invocation of Model is what's throwing the error. It's confusing since none of the other attempts to access Model trigger an error.
The first few html helpers in your partial are using the capital 'Model' instead of lowercase 'model' for the lambda parameter. You have
<%: Html.TextBoxFor(Model => Model.GameData.GameTitle) %>
But it should be
<%: Html.TextBoxFor(model => model.GameData.GameTitle) %>
Related
I'm trying to validate a phone number without success. When I submit the form for the following model, it always accepts the phone number I put in, whether it's valid or not. Why is this happening?
class Client < ActiveRecord::Base
belongs_to :salon
belongs_to :address
accepts_nested_attributes_for :address
attr_accessible :address_attributes, :name, :phone, :email
validates_presence_of :name
validates_presence_of :email
validates_presence_of :phone,
:unless => Proc.new { |c| c.phone.gsub(/[^0-9]/, "").length != 10 }
end
-
<%= form_for(#client) do |f| %>
<% if #client.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#client.errors.count, "error") %> prohibited this client from being saved:</h2>
<ul>
<% #client.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :salon_id, :value => Salon.logged_in_salon.id %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<%= f.fields_for :address do |address_form| %>
<div class="field">
<%= address_form.label :line1 %><br />
<%= address_form.text_field :line1 %>
</div>
<div class="field">
<%= address_form.label :line2 %><br />
<%= address_form.text_field :line2 %>
</div>
<div class="field">
<%= address_form.label :city %><br />
<%= address_form.text_field :city %>
</div>
<div class="field">
<%= address_form.label :state_id %><br />
<%= select("client[address]", "state_id", State.all.collect {|s| [ s.name, s.id ] }) %>
</div>
<div class="field">
<%= address_form.label :zip %><br />
<%= address_form.text_field :zip %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You should be using validates_format_of instead of validates_presence_of. Something like:
validates_format_of :phone,
:with => /\A[0-9]{10}\Z/,
:allow_blank => true,
:allow_nil => true
I'm new to rails and I recently discovered rails_admin.
How to set a file_upload control for a field in rails_admin?
If you are using the Carrierwave gem for your file uploads you can do something like this
https://gist.github.com/884835 or in erb if you prefer that:
<%= label_tag "#{field.abstract_model.to_param}_#{field.name}", field.label %>
<div class="input">
<% image = field.bindings[:object].send(field.name) %>
<% if image.path %>
<div class="row">
<% default_version = image.versions[:main] %>
<%= image_tag default_version && default_version.url || image.url %>
<br />
<%= form.check_box "remove_#{field.name}" %>
<%= form.label "remove_#{field.name}", "Remove existing #{field.label.downcase}", :class => "inline" %>
</div>
<% end %>
<div class="row">
<%= form.file_field field.name, :class => "fileUploadField #{field.has_errors? ? "errorField" : nil}" %>
<%= form.hidden_field "#{field.name}_cache" %>
</div>
</div>
First of all, am I the only developer on the planet that is attempting to use MVC with VB? I have searched tons of forums and read many posts and everyone that asks a question gives an example in C#. Anyway, now that I've got that out of the way, I've got a simple database table (User) with some columns (UserId, Username, FirstName, LastName). I am using the entity framework and on my edit view, I'm changing a value (Username) and clicking Save. In my Edit http post, I tell it to return to the Index and the value was not saved. Although, in my constructor for the http post, I return the object and it shows the new value...but that value doesn't make it to the db...any help?
My Controller:
Function Edit(ByVal ID As Guid) As ActionResult
'get the user
Dim usr = (From u In db.Users
Where u.UserId = ID
Select u).Single
Return View(usr)
End Function
<HttpPost()> _
Function Edit(ByVal ID As Guid, ByVal usrInfo As User, ByVal formValues As FormCollection) As ActionResult
' Dim usr As User = db.Users.Single(Function(u) u.UserId = ID)
If ModelState.IsValid Then
TryUpdateModel(usrInfo, "User")
Return RedirectToAction("Index")
Else
Return View(usrInfo)
End If
End Function
My view:
<h2>Edit</h2>
<%-- The following line works around an ASP.NET compiler warning --%>
<%: ""%>
<% Using Html.BeginForm() %>
<%: Html.ValidationSummary(True) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.UserId) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.UserId) %>
<%: Html.ValidationMessageFor(Function(model) model.UserId) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.Username) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.Username) %>
<%: Html.ValidationMessageFor(Function(model) model.Username) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.FirstName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.FirstName) %>
<%: Html.ValidationMessageFor(Function(model) model.FirstName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.LastName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.LastName) %>
<%: Html.ValidationMessageFor(Function(model) model.LastName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.CreatedDate) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.CreatedDate, String.Format("{0:g}", Model.CreatedDate)) %>
<%: Html.ValidationMessageFor(Function(model) model.CreatedDate) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.CreatedBy) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.CreatedBy) %>
<%: Html.ValidationMessageFor(Function(model) model.CreatedBy) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(Function(model) model.LastLogin) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(Function(model) model.LastLogin, String.Format("{0:g}", Model.LastLogin)) %>
<%: Html.ValidationMessageFor(Function(model) model.LastLogin) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% End Using %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
Ok, so, aparently I AM the only VB developer using MVC. Anyway, I found the answer. It was in one of the beginner tutorials for MVC on the ASP.Net Site (Found Here). The answer was to change my Edit function (HttpPost) so that it utilizes the formvalues that were posted:
<HttpPost()> _
Function Edit(ByVal id As Guid, ByVal collection As FormCollection) As ActionResult
Dim rest = (From r In db.Restaurants
Where r.RestaurantId = id
Select r).Single()
Try
TryUpdateModel(rest, collection.ToValueProvider())
db.SaveChanges()
Return RedirectToAction("Index")
Catch
Return View(rest)
End Try
End Function
I've got a model which contains a List of QuestionEditModel for which I want to use an EditorFor.
Normally, I would just call EditorFor on the collection and MVC will do the rest. However, I need the individual QuestionEditModel to use different EditorTemplates depending on the value of a field within the object.
I would've thought that the method for doing this would be something like
<%: Html.EditorFor(model=>model.Questions), [fieldname from individual question] %>
but I cannot figure out how to tell it to look at the Question which is currently selected and use the EntryType field from the question to determine which EditorTemplate to use.
So I tried this
<% foreach (Reviewer.Models.QuestionEditModel qem in Model.Questions)
{
Html.EditorFor(q=>qem, qem.EntryType, null);
} %>
but this doesn't render anything on to the page. The odd thing is that if I set a breakpoint and run over the code, this does call the correct EditorTemplate, the correct model data is passed in and there are no exceptions, but it just doesn't render anything.
Is there some additional work I need to do in this scenario to get the rendered EditorTemplate back in to my page?
EDIT:
Full code of the Edit View.
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<%: Html.HiddenFor(model=>model.AcadPeriod) %>
<%: Html.HiddenFor(model=>model.ReviewID) %>
<%: Html.HiddenFor(model=>model.ReviewName) %>
<%: Html.HiddenFor(model=>model.CategoryID) %>
<%: Html.HiddenFor(model=>model.CategoryName) %>
<%-- Categories not getting returned in model for some reason. Use EditorFor or DisplayFor instead of loop? --%>
<%: Html.HiddenFor(model=>model.Categories) %>
<%: Html.HiddenFor(model=>model.ClassificationID) %>
<%: Html.HiddenFor(model=>model.ClassificationName) %>
<div style="width:100%">
<div style="float:left">
<ul style="list-style-type:none">
<% for (int i = 0; i < Model.Categories.Count(); i++)
{ %>
<li style="background-color:Gray; border: 1px solid black; padding: 3px 3px 3px 3px; margin-bottom: 2px">
<%: Html.ActionLink(Model.Categories[i].name, "Edit", new { AcadPeriod = Model.AcadPeriod, ClassificationID=Model.ClassificationID, ReviewID=Model.ReviewID, CategoryID=Model.Categories[i].category_id })%>
</li>
<% }%>
</ul>
</div>
</div>
<% foreach (Reviewer.Models.QuestionEditModel qem in Model.Questions) { %>
<%: Html.EditorFor(q=>qem, qem.EntryType,null); %>
<% } %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
EDIT 2:
Complete View, Controller, and Template code as requested.
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Reviewer.Models.ReviewEditModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Edit
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h1><%: Model.AcadPeriod %> > <%: Model.ClassificationName %> > <%: Model.ReviewName %></h1>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<%: Html.HiddenFor(model=>model.AcadPeriod) %>
<%: Html.HiddenFor(model=>model.ReviewID) %>
<%: Html.HiddenFor(model=>model.ReviewName) %>
<%: Html.HiddenFor(model=>model.CategoryID) %>
<%: Html.HiddenFor(model=>model.CategoryName) %>
<%-- Categories not getting returned in model for some reason. Use EditorFor or DisplayFor instead of loop? --%>
<%: Html.HiddenFor(model=>model.Categories) %>
<%: Html.HiddenFor(model=>model.Questions) %>
<%: Html.HiddenFor(model=>model.ClassificationID) %>
<%: Html.HiddenFor(model=>model.ClassificationName) %>
<div style="width:100%">
<div style="float:left;width: 15%">
<ul style="list-style-type:none">
<% for (int i = 0; i < Model.Categories.Count(); i++)
{ %>
<li style="background-color:Gray; border: 1px solid black; padding: 3px 3px 3px 3px; margin-bottom: 2px">
<%: Html.ActionLink(Model.Categories[i].name, "Edit", new { AcadPeriod = Model.AcadPeriod, ClassificationID=Model.ClassificationID, ReviewID=Model.ReviewID, CategoryID=Model.Categories[i].category_id })%>
</li>
<% }%>
</ul>
</div>
<div style="float:left; width: 80%; margin-left: 5px">
<% foreach (Reviewer.Models.QuestionEditModel qem in Model.Questions) { %>
<%: Html.EditorFor(q=>qem, qem.EntryType,null) %>
<% } %>
</div>
</div>
<div style="clear:both" />
<p>
<input type="submit" value="Save" />
</p>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
Editor Template:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Reviewer.Models.QuestionEditModel>" %>
<div style="width:100%; border: 1px solid black">
<div style="width: 100%; border: 1px solid black"><h2><%: Model.QuestionName %></h2></div>
<div style="width:25%; display:inline; border: 1px solid black; float:left">
<%: Model.QuestionText %>
</div>
<div style="width:70%; border: 1px solid black; float:left">
<%: Html.TextAreaFor(model=>model.Answer) %>
<%:Html.ValidationMessageFor(model=>model.Answer) %>
</div>
<div style="clear:both" />
</div>
<fieldset>
<legend>TEXT</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.QuestionID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.QuestionID) %>
<%: Html.ValidationMessageFor(model => model.QuestionID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.QuestionName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.QuestionName) %>
<%: Html.ValidationMessageFor(model => model.QuestionName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.QuestionText) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.QuestionText) %>
<%: Html.ValidationMessageFor(model => model.QuestionText) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.DefaultText) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.DefaultText) %>
<%: Html.ValidationMessageFor(model => model.DefaultText) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.EntryType) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.EntryType) %>
<%: Html.ValidationMessageFor(model => model.EntryType) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.HelpText) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.HelpText) %>
<%: Html.ValidationMessageFor(model => model.HelpText) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Answer) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Answer) %>
<%: Html.ValidationMessageFor(model => model.Answer) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.OptionValue) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.OptionValue) %>
<%: Html.ValidationMessageFor(model => model.OptionValue) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.completedBy) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.completedBy) %>
<%: Html.ValidationMessageFor(model => model.completedBy) %>
</div>
Option Required: <%:Html.TextBoxFor(model=>model.OptionRequired) %>
Answer Required: <%: Html.TextBoxFor(model=>Model.AnswerRequired) %>
</fieldset>
Edit(GET) Action:
public ActionResult Edit(string AcadPeriod, string ClassificationID, string ReviewID, int CategoryID)
{
Reviewer.Models.ReviewEditModel dset1 = rr.GetReviewEditModel(AcadPeriod, ReviewID, CategoryID.ToString(), ClassificationID);
return View(dset1);
}
Edit(POST) Action:
[HttpPost]
public ActionResult Edit(Reviewer.Models.ReviewEditModel model)
{
try
{
foreach (Reviewer.Models.QuestionEditModel qem in model.Questions)
{
if (qem.Answer == null || qem.OptionValue == null) { qem.completedBy = this.HttpContext.User.Identity.Name; }
}
if (ModelState.IsValid)
{
rr.SaveReviewEditModel(model);
return RedirectToAction("Index");
}
else { return View(model); }
}
catch
{
return View(model);
}
}
You have to tell it what to actually render (<%: %>):
<% foreach (Reviewer.Models.QuestionEditModel qem in Model.Questions) { %>
<%: Html.EditorFor(q=>qem, qem.EntryType, null) %>
<% } %>
I got one problem with showing error message to element.
Is there any option to turn on messages on place where is Html.ValidationMessageFor(model => model.ConfirmPassword). Becsoue for me it isn’t show up. I would like to have summary and near field information too not only red border. Any one know how to do it?
using (Ajax.BeginForm("CreateValidForm", "Test", new AjaxOptions { HttpMethod = "Post" })) {%> <div id="validationSummary1">
<%= Html.ValidationSummary(true)%> </div> <fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%= Html.LabelFor(model => model.Name)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Name)%>
<%= Html.ValidationMessageFor(model => model.Name)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.Email)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Email)%>
<%= Html.ValidationMessageFor(model => model.Email)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.Password)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Password)%>
<%= Html.ValidationMessageFor(model => model.Password)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.ConfirmPassword)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.ConfirmPassword)%>
<%= Html.ValidationMessageFor(model => model.ConfirmPassword)%>
</div>
<p>
<input type="submit" value="Create" />
</p> </fieldset> <% } %> <%= Html.ClientSideValidation<ValidModel>()
.UseValidationSummary("validationSummary1", "Please fix the following problems:") %>
Here is link for sample project http://www.sendspace.com/file/m9gl54 .