From DropDownList to Textbox - c#

I have DropDownList and Textbox on my page.
DropDownList show data from DataBase(Table "List").
When I choose one line in DropDownList I want to see it in Textbox, make changes and save this line into DataBase(Table "Text") after press "OK".
Please tell me, how to do this?
Code:
Controller.cs:
public ActionResult Create(Model model)
{
var viewModel = new ISMSViewModel
{
Model = new Model(),
};
return View(viewModel);
}
[HttpPost]
public ActionResult Create(Model model, int i)
{
try
{
sysDB.AddToActives(model);
sysDB.SaveChanges();
return RedirectToAction("Browse");
}
}
ListText.ascx:
<%: Html.EditorFor(model => model.Model, new { Lists = Model.Lists } %>
<%: Html.Label("List") %>
<%: Html.DropDownList("ListId", new SelectList(ViewData["Lists"] as IEnumerable, "ListId", "Name", Model.ListId)) %>
<%: Html.Label("TextBox") %>
<%: Html.TextBoxFor(model => model.TextBox) %>
<%: Html.ValidationMessageFor(model => model.TextBox) %>

For this you need to write some JavaScript.
handle the onchange event for dropdown
<%: Html.DropDownList("ListId", new SelectList(ViewData["Lists"] as IEnumerable, "ListId", "Name", Model.ListId), new {#onchange="setVal(this)"}) %>
on your view
inside head block
<script type="text/javascript">
function setVal(obj)
{
document.getElementById("TextBox").value=obj.value;
}
</script>

Related

MVC ViewModel containing a dictionary for fields returning empty to controller

Attempting to make a Questionnaire page for a client. It's a pretty large list of questions, so I've broken it up into sections and subsections to make it easier for the user to navigate. The problem seems to be that in order to build the page, I iterate over the sections/subsections/questions, and not the answers. Answers are stored in a dictionary, with the key being the ID number of the associated question.
The ViewModel passed to the view is UserQuestionnaireViewModel, QuestionnaireViewModel has a list of Sections, each of which has a list of SubSections, each of which has a list of Questions. The Answers Dictionary gets all Answers linked to the relevant user, indexed by the Question they're linked to. Missing Answers are populated here, the View breaks if they're missing.
Model
public class UserQuestionnaireViewModel {
ClientPortalDbContext db = new ClientPortalDbContext();
public QuestionnaireViewModel Questionnaire { get; set; }
public Dictionary<Int32, QuestionnaireAnswer> Answers { get; set; }
public UserQuestionnaireViewModel() { }
public UserQuestionnaireViewModel(Int32 userID) {
Questionnaire = new QuestionnaireViewModel();
Answers = new Dictionary<Int32, QuestionnaireAnswer>();
List<QuestionnaireAnswer> answerList = db.QuestionnaireAnswers.Where(a => a.UserID == userID).ToList();
foreach (QuestionnaireAnswer answer in answerList) {
Answers.Add(answer.QuestionID, answer);
}
foreach (QuestionnaireViewModel_Section section in Questionnaire.Sections) {
foreach (QuestionnaireViewModel_SubSection subsection in section.SubSections) {
foreach (QuestionnaireQuestion question in subsection.Questions) {
if (!Answers.ContainsKey(question.ID)) {
Answers.Add(question.ID, new QuestionnaireAnswer() {
QuestionID = question.ID,
UserID = userID,
AnswerBool = false,
AnswerText = ""
});
}}}}}}
The Section and SubSectionclasses contain a name string, and a List of whatever comes under them (SubSection and Question respectively). Question has an id int, string for question text, and bools for what fields to show.
View
<div class="content-wrapper">
<% using (Html.BeginForm("Save", "Questionnaire", new { input = Model.Answers })) { %>
<%: Html.AntiForgeryToken()%>
<%: Html.ValidationSummary(true)%>
<fieldset>
<ul class="questionnaire-tabs">
<% Int32 tabIndex = 0; %>
<% foreach (clientportal.Models.QuestionnaireViewModel_Section section in Model.Questionnaire.Sections) { %>
<% tabIndex++; %>
<li id="<%: "tab-button-" + tabIndex.ToString()%>" data-tab="<%: "tab-" + tabIndex.ToString()%>">
<%: section.Name%>
</li>
<% } %>
</ul>
<div class="clear"></div>
<% tabIndex = 0; %>
<% foreach (clientportal.Models.QuestionnaireViewModel_Section section in Model.Questionnaire.Sections) { %>
<% tabIndex++; %>
<div class="questionnaire-tab-content" id="<%: "tab-" + tabIndex.ToString()%>">
<p><%: section.Heading%></p>
<% foreach (clientportal.Models.QuestionnaireViewModel_SubSection subsection in section.SubSections) { %>
<h4><%: subsection.Name%></h4>
<p><%: subsection.Heading%></p>
<div>
<table class="questionnaire-table">
<% foreach (clientportal.Models.QuestionnaireQuestion question in subsection.Questions) { %>
<% clientportal.Models.QuestionnaireAnswer answer = Model.Answers[question.ID]; %>
<% if (question.Enabled) { %>
<tr>
<td class="label-col">
<%: Html.Label(question.Text) %>
<%: Html.Hidden("Model.Answers.Index", question.ID) %>
<%: Html.Hidden("Model.Answers[" + question.ID + "].ID", answer.ID) %>
<%: Html.Hidden("Model.Answers[" + question.ID + "].QuestionID", answer.QuestionID) %>
<%: Html.Hidden("Model.Answers[" + question.ID + "].UserID", answer.UserID) %>
</td>
<td class="bool-col">
<% if (question.ShowCheckBox) { %>
<%: Html.CheckBox("Model.Answers[" + question.ID + "].AnswerBool", answer.AnswerBool) %>
<% } else { %>
<%: Html.Hidden("Model.Answers[" + question.ID + "].AnswerBool", answer.AnswerBool) %>
<% } %>
</td>
<td class="text-col">
<% if (question.ShowTextBox) { %>
<%: Html.TextBox("Model.Answers[" + question.ID + "].AnswerText", answer.AnswerText) %>
<% } else { %>
<%: Html.Hidden("Model.Answers[" + question.ID + "].AnswerText", answer.AnswerText) %>
<% } %>
</td>
</tr>
<% } %>
<% } %>
</table>
</div>
<% } %>
</div>
<% } %>
</fieldset>
<h4>Please ensure you have checked all sections of the Questionnaire before saving.</h4>
<input type="submit" value="Save Answers" />
<% } %>
</div>
On submitting the form, it goes through to the Controller fine (The Controller takes a Dictionary<Int32, QuestionnaireAnswer> for this Action), except the model sent through has 0 rows and fails ModelState.IsValid
Looking around SO has given me the idea that this is an issue with MVC and Dictionaries in general, or simply failure to bind the dictionary. Any answers in the Database are displayed correctly, it's simply the inability to get the contents of the page back to the controller that's preventing me moving onwards.
Don't use foreach loop. Use for loop.
One more thing always use Html.HiddenFor(model.xxxx) and for other controls also.
If you use for loop along with HiddenFor this will automatically create appropriate name for controls
If it's possible to separate out database operation from MVC model then it's best.

Load DropDownList from ViewData in MVC 2

I have the following View. This is the whole code of my view
<asp:Content ID="Content2" ContentPlaceHolderID="HeadContent" runat="server">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div>
<table>
<tr>
<td>
<select id="clientDDL">
</select>
<% Html.DropDownList("clientDDL",
new SelectList((IEnumerable)ViewData["Clients"], "Code", "Name")); %>
</td>
</tr>
</table>
</div>
</asp:Content>
I use the next ViewData from my Model:
public static List<lookup> GetClients()
{
using (ModelDataContext data = new ModelDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
{
List<lookup> retVal = new List<lookup>();
List<Client> lClient = data.Clients.Where(a => a.IsActive == true).ToList();
lClient = lClient.OrderBy(o => o.ClientName).ToList();
foreach (Client item in lClient)
{
retVal.Add(new lookup() { Code = item.ClientID.ToString(), Name = item.ClientName, });
}
return retVal;
}
}
This is my Controller:
public ActionResult ProcedureFilter()
{
ViewData["Clients"] = WorkflowModels.GetClients();
return View();
}
What did I miss? My DropDownList is still empty. Maybe i have to put some reference? Any suggestions please.
UPDATE:
The problem was ';' at the end of part <%= %>. The works code:
<%= Html.DropDownList("clientDDL",
new SelectList((IEnumerable)ViewData["Clients"], "Code", "Name")) %>
In the ASP.NET code you provided, 2 HTML select tags (or DropdownLists) are defined with the same id (cliendDDL) :
<select id="clientDDL"> <-- the first one
</select>
<% Html.DropDownList("clientDDL",
new SelectList((IEnumerable)ViewData["Clients"], "Code", "Name")); %> <-- the second one, Html.DropDownList generating a select under the hood.
Would it be possible that only the first one is displayed (the empty one) and the second remains hidden because of a missing character, changing your expected HTML generation routine (Html.DropDownList) into an Embedded Code Block?
Maybe instead of :
<% Html.DropDownList
it should be :
<%= Html.DropDownList or <%: Html.DropDownList
See here for <%:%> ASP.NET 4 syntax
Edited
Also the ";" end of line character is not needed and should be removed.
View Page:
"<%=Html.DropDownList("Description", New SelectList(ViewData("Description")), "--Select--")%>"
Contoller:
Function Purchase() As ActionResult:
Dim dataContext As New tblMVCDataContext
Dim teststr As String
Dim itemVar = From U In dataContext.Items Select U.Description
For Each tbItem In itemVar
teststr += tbItem + ","
Next
ViewData("Description") = teststr.Split(",")
Return View(itemVar)
End Function

Pass model name as a parameter

I have a partial view where I pass the model name to populate it, is there any way to pass model name as a parameter based on the controller action executed?
<div id = "Details" >
<% List<Freshmen>() = model based on controller action executed %>
<% using (Html.BeginForm("FreshmenDetails", "Students")) %>
<% { %>
<% Html.RenderPartial("FreshmenDetails", new List<Freshmen>()); %>
<% } %>
</div>
Controller Action:
public ActionResult FreshmenDetails(string id)
{
DataContext Student = new DataContext();
var FreshmenDetails = Student.Freshmen.Where(a => Convert.ToInt64(a.Id) == Convert.ToInt64(id)).ToList();
return PartialView("FreshmenDetails", FreshmenDetails );
}
I have 3 more Actions each for SophomoreDetails(),JuniorDetails(),SeniorDetails()
Currently I am displaying Partial View like this:
<div id = "Details" >
<% using (Html.BeginForm("FreshmenDetails", "Students")) %>
<% { %>
<% Html.RenderPartial("FreshmenDetails", new List<Freshmen>()); %>
<% } %>
<% using (Html.BeginForm("SophomoreDetails", "Students")) %>
<% { %>
<% Html.RenderPartial("SophomoreDetails", new List<Sophomore>()); %>
<% } %>
<% using (Html.BeginForm("JuniorDetails", "Students")) %>
<% { %>
<% Html.RenderPartial("JuniorDetails", new List<Junior>()); %>
<% } %>
<% using (Html.BeginForm("SeniorDetails", "Students")) %>
<% { %>
<% Html.RenderPartial("SeniorDetails", new List<Senior>()); %>
<% } %>
</div>
I want something like:
<div id = "Details" >
<% using (Html.BeginForm("FreshmenDetails", "Students")) %>
<% { %>
<% Html.RenderPartial("FreshmenDetails", new List<Freshmen>()); %>
<% } %>
</div>
I am having a hard time figuring out exactly what your after. That being said, have you tried using reflection?
return PartialView(Model.GetType().Name, new { // Partial View object });
Further more, you can use Model.GetType().Name to get the model object name and use it where you want.
That should work for you.

Asp.Net MVC EditorTemplate Model is lost after Post

I have a controller with two simple Methods:
UserController Methods:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Details(string id)
{
User user = UserRepo.UserByID(id);
return View(user);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Details(User user)
{
return View(user);
}
Then there is one simple view for displaying the details:
<% using (Html.BeginForm("Details", "User", FormMethod.Post))
{%>
<fieldset>
<legend>Userinfo</legend>
<%= Html.EditorFor(m => m.Name, "LabelTextBoxValidation")%>
<%= Html.EditorFor(m => m.Email, "LabelTextBoxValidation")%>
<%= Html.EditorFor(m => m.Telephone, "LabelTextBoxValidation")%>
</fieldset>
<input type="submit" id="btnChange" value="Change" />
<% } %>
As you can see, I use an editor template "LabelTextBoxValidation":
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<%= Html.Label("") %>
<%= Html.TextBox(Model,Model)%>
<%= Html.ValidationMessage("")%>
Showing user information is no problem. The view renders perfectly user details.
When I submit the form, the object user is lost. I debugged on the row "return View(User);" in the Post Details method, the user object is filled with nullable values. If I dont use the editor template, the user object is filled with correct data. So there has to be something wrong with the editor template, but can't figure out what it is. Suggestions?
I would re-architect a little bit - change your LabelTextBoxValidation editor to an Html helper, and then make one EditorTemplate for your data model. That way you could do something like this:
<% using (Html.BeginForm("Details", "User", FormMethod.Post))
{%>
<fieldset>
<legend>Userinfo</legend>
<% Html.EditorFor(m => m); %>
</fieldset>
<input type="submit" id="btnChange" value="Change" />
<% } %>
And your editor template would be something like:
<%= Html.ValidatedTextBoxFor(m => m.Name); %>
<%= Html.ValidatedTextBoxFor(m => m.Email); %>
<%= Html.ValidatedTextBoxFor(m => m.Telephone); %>
where ValidatedTextBoxFor is your new html helper. To make that, it would be fairly easy:
public static MvcHtmlString ValidatedTextBoxFor<T>(this HtmlHelper helper, Expression thingy)
{
// Some pseudo code, Visual Studio isn't in front of me right now
return helper.LabelFor(thingy) + helper.TextBoxFor(thingy) + helper.ValidationMessageFor(thingy);
}
That should set the names of the form fields right I believe, as that seems like the source of the problem.
EDIT: Here is the code that should help you out:
public static MvcHtmlString ValidatedTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
return MvcHtmlString.Create(
html.LabelFor(expression).ToString() +
html.TextBoxFor(expression).ToString() +
html.ValidationMessageFor(expression).ToString()
);
}

Asp.Net MVC2 Clientside Validation and duplicate ID's problem

I'm using MVC2 with VS2010
I have a view that has two partial views in it: "Login" and "Register"
both partial views contains the Email address field i use the following in both partial views:
<%: Html.TextBoxFor(model => model.EmailAddress ) %><br /><%: Html.ValidationMessageFor(model => model.EmailAddress) %>
if i use both partial views on one page, it ends up having duplicate id's so validation happens across both views (even thopugh they are in seperate forms)
how can i go about eliminating this
For some controls you can specify the HTML attributes in an overload like this:
<%: Html.TextBoxFor(model => model.EmailAddress, new { id = 'my-unique-id" }) %>
<br />
<%: Html.ValidationMessageFor(model => model.EmailAddress, new { id = 'my-unique-id" }) %>
You can also either write your HTML by hand or use the older HTML helpers so you can add your own ID that way (you need to do this for Html.LabelFor() helpers)
<%: Html.TextBox( "EmailAddress", Model.EmailAddress, new { id = 'my-unique-id" } ) %>

Categories