Display Text from DropDownListFor - asp.net-mvc-2

Here's the view:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<TravelDeskWebsite.Models.TestModel>" %>
<!DOCTYPE html>
<html>
<head>
<title>TestPage</title>
</head>
<body>
<% using (Html.BeginForm())
{ %>
<%= Html.DropDownListFor(x => x.SelectedText, ViewBag.Tests as SelectList)%>
<%: (string)ViewBag.Test %>
<% } %>
</body>
</html>
The controller:
public ActionResult TestFunc(TestModel model)
{
List<string> TestList = new List<string>();
TestList.Add("Help");
TestList.Add("Please");
ViewBag.Tests = new SelectList(TestList, model.SelectedText);
ViewBag.Test = model.SelectedText;
return View();
}
What I wanted to achieve here is just to display the selected value as text on the same view. The problem is that the ViewBag returns null even if I have a selected value. When I test it, it throws null exception.

You will have your SelectedValue in the SelectedText Property. try to use that.
ViewBag.Test = model.SelectedText;
return View(model);

Related

MVC2 ajax partial view does not register jquery scripts

I have my page where i have ajax call to display form.
My code works when the register the code for form but not from postback (validation error in controller).
any idea how to fix this?
My container page has:
Scripts:
<%= Html.JQuery() %>
<script src="../../../../Scripts/jquery.ui.core.js" type="text/javascript"></script>
<script src="../../../../Scripts/jquery.ui.datepicker.min.js" type="text/javascript"></script>
<script src="../../../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../../../Scripts/MicrosoftMvcAjax.js" type="text/javascript">/script>
<script src="../../../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<script type="text/javascript">
function registerStuff() {
//this gets triggered when onsuccess is called
$("#date").datepicker({ dateFormat: 'dd/mm/yy' });
$("#sla").datepicker();
}
</script>
Content:
<%= Ajax.AjaxButton("New action", "CreateWorkFlowAction", new {
controller = "CaseWorkFlow" }, new AjaxOptions() { UpdateTargetId =
"divTableContainer", HttpMethod = "Get", OnSuccess =
"registerStuff"})%>
<div id="divTableContainer">
response will appear here
</div>
my form looks like
<script type="text/javascript">
function RegisterJs() {
$("#date").datepicker({ dateFormat: 'dd/mm/yy' });
$("#sla").datepicker({ dateFormat: 'dd/mm/yy' });
}
</script>
<% Html.EnableClientValidation(); %>
<% using (Ajax.BeginForm("CreateWorkFlowAction", new AjaxOptions() { UpdateTargetId = "divTableContainer", HttpMethod = "Post" }))
{%>
<%= Html.ValidationSummary() %>
<fieldset>
<div>
<label for="title">
Title</label>
<%= Html.TextBoxFor(x=>x.Title) %>
</div>
<div>
<label for="SLA">
SLA(Due Date)</label>
<%= Html.TextBoxFor(x => x.SelectSlaDate, new { id = "sla", #Value = string.Empty} )%>
</div>
<div>
<label for="date">
Date</label>
<%= Html.TextBoxFor(x => x.SelectDate, new { id = "date", #Value = string.Empty})%>
</div>
<div>
<button type="submit">Save action</button>
</div>
</fieldset>
<% } %>
the problem is
i have found the solution to my question.
I have to reregister my javascript inside of a partial view.
this means that i had to update add register scripts into the parent page to which i will insert partial view.
and therfore if my view page contains partial view i had to move
function registerStuff() {
//this gets triggered when onsuccess is called
$("#date").datepicker({ dateFormat: 'dd/mm/yy' });
$("#sla").datepicker();
}
to the index page.
After on success call this function "registerStuff" from my oncomplete,
and after then everything is working like charm
hope this helps to you too

How to access my model from my view?

I cannot seem to figure out how to access my Model from my View. I am confused.
Here is my Home controller. I have verified that "specimens" is being populated with data from the database:
public class HomeController : Controller
{
wildtropEntities wildlifeDB = new wildtropEntities();
public ActionResult Index()
{
ViewData["CurrentDate"] = System.DateTime.Now.ToString("MM/dd/yyyy");
var specimens = from s in wildlifeDB.specimen1
select s;
return View(specimens);
}
}
And here are couple snippets from my View:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<% foreach (WildlifeTropical.Models.specimen s in ??????)
{ %>
<div>s.Name</div>
<% } %>
I assumed I would be able to access "specimens" since I passed it to the View from the Controller (ie, return View(specimens))...but it isn't working.
You will have to make your view strongly typed to a collection of specimen which is what you are passing to it from your controller action (IEnumerable<specimen>):
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<WildlifeTropical.Models.specimen>>" %>
<% foreach (WildlifeTropical.Models.specimen s Model) { %>
<div><%= Html.Encode(s.Name) %></div>
<% } %>
Notice how the view inherits System.Web.Mvc.ViewPage<IEnumerable<WildlifeTropical.Models.specimen>> and it is now strongly typed to a collection of specimens that you will be able to loop through.
This being said, personally I don't like writing foreach loops in my views. They make them look ugly. In this case I would use a display template:
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<WildlifeTropical.Models.specimen>>" %>
<%= Html.DisplayForModel() %>
and then I would define a display template which will automatically be rendered for each element of the model collection (~/Views/Shared/DisplayTemplates/specimen.ascx):
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<WildlifeTropical.Models.specimen>" %>
<div>
<%= Html.DisplayFor(x => x.Name) %>
</div>
See how the specimen.ascx user control is now strongly typed to System.Web.Mvc.ViewUserControl<WildlifeTropical.Models.specimen>. This is because it will be rendered for each specimen of the main view model.
I am not sure about MVC2. In MVC 3(with Razor View Engine), I can pass the Model / ViewModel to the View like this.
#model MyProject.ViewModel.UserViewModel
#{
ViewBag.Title = "Welcome To My Site";
}
<div class="divSubHead">
<h2>Hello #Model.FirstName</h2></div>
How about this? Note the Inherits for the Page.
<%# Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable(Of Specimen))" %>
<% foreach (WildlifeTropical.Models.specimen s in Model)
{ %>
<div>s.Name</div>
<% } %>

ASP.NET MVC2 InputHelper and List.Insert() strange behavior

I cannot make sense of this...
The simplified code below OUGHT to insert a new form field of the current time's second value.
Instead, even though the list manipulation happens correctly (as verifiable within the controller and in the debug output), the View does render an additional element, but seems to be just a copy of the final field's value (prior to submit). This can be verified by changing a field prior to submit - the values stick and the new element is a duplicate of the submitted final value.
The part that really cooks my noodle is that if I trivially change the operation from an Insert() to an Add(), the Add() works as expected!!
Using this example Model:
public class MyViewData
{
List<string> stringData = new List<string>();
public List<string> StringData { get { return stringData; } }
}
And this Controller:
public class TestController : Controller
{
public ActionResult Index()
{
return View(new MyViewData());
}
[HttpPost]
public ActionResult Index(MyViewData data)
{
data.StringData.Insert(0, DateTime.Now.Second.ToString());
return View(data);
}
}
And this View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Forms.Controllers.MyViewData>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Test
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%
System.Diagnostics.Debug.WriteLine("---");
for (var i = 0; i < Model.StringData.Count; i++)
System.Diagnostics.Debug.WriteLine("{0}", Model.StringData[i]);
%>
<% using (Html.BeginForm()) { %>
<% for (var i = 0; i < Model.StringData.Count; i++) { %>
<%: Html.TextBoxFor(model => model.StringData[i])%></br>
<% } %>
<div><input type="submit" value="Do it" /></div>
<% } %>
</asp:Content>
This is the normal behavior of standard HTML helpers and is by design. When rendering the input field they will first look at the request POSTed values and only after in the ViewData and view model. This basically means that you cannot change POSted values in your controller action.
So if you have a form with an input field:
<%= Html.TextBoxFox(x => x.Id) %>
which is posted to the following action
[HttpPost]
public ActionResult Index(MyModel model)
{
model.Id = "some new value";
return View(model);
}
when rendering the view back the html helper will use the posted value. You could either write a custom html helper that does the job for you or handle it manually (absolutely not recommended but for the record):
<input type="text" name="StringData[<%= i %>]" value="<%= Model.StringData[i] %>" />

MVC2/Jquery validation issues

I have read the following:
http://weblogs.asp.net/imranbaloch/archive/2010/08/23/asp-net-mvc-jquery-validation-and-validationsummary.aspx
http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
And still can't get the jQuery validation to work with MVC2. I can get non jQuery working but when i swap out the JS files it doesn't work. It's going on day 3 and I'm totally stuck at this point. So here is what I have. I appreciate your help.
Site.Master
<script src="<%= this.ResolveClientUrl("~/Resources/js/jquery-1.4.1.js") %>"
type="text/javascript"></script>
<script src="<%= this.ResolveClientUrl("~/Resources/js/jquery.validate.js") %>"
type="text/javascript"></script>
<script src="<%= this.ResolveClientUrl("~/Resources/js/MicrosoftMvcJqueryValidation.js") %>"
type="text/javascript"></script>
<script src="<%= this.ResolveClientUrl("~/Resources/js/ourJS--VERSION--.js") %>" type="text/javascript"></script>
<script src="<%= this.ResolveClientUrl("~/Resources/js/json2.js") %>" type="text/javascript"></script>
<link href="../../Resources/css/ourCSS--VERSION--.css" rel="stylesheet" type="text/css" />
ViewModel:
namespace OurNamespace
{
[ExcludeFromCodeCoverage]
public class OurDataModelView : PersistedDataModelView
{
public OurModelView () : base()
{
ID = -1;
StartDate = DateTime.MinValue;
EndDate = DateTime.MinValue;
Description = string.Empty;
Deleted = false;
}
[DisplayFormat(DataFormatString = "{0:MM/yyyy}")]
public DateTime? StartDate { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/yyyy}")]
public DateTime? EndDate { get; set; }
[Required(ErrorMessage="Description is required.")]
[StringLength(250000, ErrorMessage = "A maximum of 250000 characters are allowed")]
public string Description { get; set; }
public int? ID { get; set; }
public bool Deleted { get; set; }
}
}
ASPX page
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
...
<% Html.RenderAction(WebConstants.ACTION_DISPLAY_HEADER, WebConstants.CONTROLLER, new { id = ViewData["ID"] }); %>
...
our partial view that validation is done on:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<OurNameSpace.OurDataModelView>" %>
...
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm("", "", FormMethod.Post , new { id = "HeaderForm", onSubmit="return false;"})) { %>
<%: Html.ValidationSummary(false, "validation failed") %>
<%: Html.HiddenFor(model => model.ID) %>
<div class="form-row">
<div class="form-label">Description</div>
<div class="form-element"><%: Html.TextAreaFor(model => model.Description)%></div>
<div><%= Html.ValidationMessageFor(model => model.Description) %></div>
</div>
<div class="buttons">
<input id="Save" type="submit" class="save-button" value="" />
<div id="Cancel" class="cancel-button"></div>
</div>
<% } %>
...
**SO by doesn't work here is what I do see.
on view source I see:
//<![CDATA[
if (!window.mvcClientValidationMetadata) { window.mvcClientValidationMetadata = []; }
window.mvcClientValidationMetadata.push({"Fields":[{"FieldName":"Description","ReplaceValidationMessageContents":true,"ValidationMessageId":"Description_validationMessage","ValidationRules":[{"ErrorMessage":"A maximum of 250000 characters are allowed","ValidationParameters":{"minimumLength":0,"maximumLength":250000},"ValidationType":"stringLength"},{"ErrorMessage":"Description is required.","ValidationParameters":{},"ValidationType":"required"}]}],"FormId":"HeaderForm","ReplaceValidationSummary":true,"ValidationSummaryId":"validationSummary"});
//]]>
However, client side validation is not appearing. I click on the textarea type in a char and delete it unfocus from the element and nothing happens. Any ideas for debugging this?
Here's a very simple working example:
Model:
public class MyViewModel
{
[Required(ErrorMessage = "Description is required.")]
[StringLength(10, ErrorMessage = "A maximum of 10 characters are allowed")]
public string Description { get; set; }
}
Controller:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
}
View:
<script type="text/javascript" src="<%= Url.Content("~/scripts/jquery-1.4.1.js") %>"></script>
<script type="text/javascript" src="<%= Url.Content("~/scripts/jquery.validate.js") %>"></script>
<script type="text/javascript" src="<%= Url.Content("~/scripts/MicrosoftMvcJQueryValidation.js") %>"></script>
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) { %>
<%: Html.TextAreaFor(x => x.Description)%></div>
<%: Html.ValidationMessageFor(x => x.Description) %>
<input type="submit" value="OK" />
<% } %>
The MicrosoftMvcJQueryValidation.js is not included in the standard project template as it is part of the MVC Futures project (extract it from the source code).
Once you've put this example into action and proved it to work you could start adding functionality.

Having difficulty with ModelBinding and Dictionary, ASP.NET MVC 2.0

Using the following model, I expect that when the Submit button is hit, the Edit Method to Fire, and the model parameter to have the adjusted values. But it keeps returning an instance of the class with all null values. It is as if no model binding ever happens.
class Trait
{
string Name { get; set; }
// other properties
}
class DesignViewModel
{
Dictionary<Trait, int> Allocation { get; set; }
}
Controller
public ActionResult Create()
{
var model = new DesignViewModel();
// retrieve traits from database
foreach(var trait in Repository.Traits)
model.Allocation.Add(trait, 0);
return View(model);
}
[HttpPost]
public ActionResult Edit(DesignViewModel model)
{
// nothing works yet, so I don't have a lot of code here...
}
HTML
Top Level Page
<%# Page Title="" Language="C#" MasterPageFile="~/Areas/Setup/Views/Shared/Setup.master"
Inherits="System.Web.Mvc.ViewPage<OtherModel>" %>
<% Html.RenderAction("Design", "Test"); %>
Partial View
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DesignViewModel>" %>
<% using (Html.BeginForm("Edit", "Test", FormMethod.Post ) ) {%>
<div id="eq">
<% foreach (var trait in Model.Allocations) { %>
<div style="margin: 15px;">
<%: trait.Key.Name %>
<br />
<span class="slider"></span>
<%: Html.TextBox(trait.Key.Name, trait.Value, new { #class = "spent" , #readonly = "readonly" })%>
</div>
<% } %>
</div>
<p>
<input type="submit" value="Submit" />
</p>
<% } %>
You need to add [HttpPost] to your Edit method for it to be fired during POST requests.