I am learning MVC and creating a project management site, and am stuck on a couple key ideas. I have a complex model, which includes a summary of the project, and a list of tasks
public class SummaryAndCategoriesViewModel
{
public Project Summary { get; set; }
public IEnumerable<task> Tasks { get; set; }
}
Inside the tasks, i've created an EditorTemplate, so that the user can switch each task state (from 'not started' -> 'completed'. for example)
In may main 'details' View, i have two partial views:
#{var categories = ViewData["AllCategories"] as List<Models.category>;}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
<div class="form-horizontal">
<hr />
<div class="Summary">
#Html.LabelFor(item => Model.Summary )
#{Html.RenderPartial("_Summary", Model.Summary);}
</div>
<hr />
<div class="tasks">
#Html.LabelFor(item => Model.Tasks )
#{Html.RenderPartial("_Task", Model.Tasks);}
</div>
</div>
}
What I'd ideally like is that the 'summary' loads in the normal details view, which it does, while the 'tasks' loads in an edit mode, which i've done as well.
As of now, i'm stuck on two things:
1- I would like to be able to change only the 'summary' partial view to edit somewhow (modal popup could work too), and still perform httpPosts.
2- I would like the user to be able to change the 'tasks' partial view, and by clicking save, update the tasks in the database and refresh the 'tasks' partial. I've been reading up on the partials and renderpartials, but i'm a bit confused on which method I should be using, how to return the partial models to the HTTPPost, and how to switch the partial views.
Any guidance would be greately appreciated
Related
I am creating a Live Chat web page in Razor Pages with c#.
I have a cshtml form that contains the gui.
#page
#model Project.Pages.LiveChatModel
#{
ViewData["Title"] = "LiveChat";
Layout = "~/Pages/_LoggedIn.cshtml";
}
<div class="container">
<h2>Live Chat</h2>
<div id="enterName">
Enter your name: <input type="text" id="name" />
<button id="btnName">Save</button>
</div>
<div id="currentName">
Your Name:
</div>
<div id="supportName">
Support Name: Jeff
</div>
Chat History
<div id="messages">
</div>
<div>
<textarea id="message" name="Message" cols="100"></textarea>
<button id="sendMessage">Send</button>
</div>
</div>
What I want to do is use the C# model to get a value from the textarea that is sent and write it to a text file in the project folder.
Hope you can help.
Thanks
This describes the steps and the flow and should clarify the process and answer your question.
Model:
public class ChatModel
{
public string Message{ get; set; }
View:
#model ChatModel
#using (Html.BeginForm("SendMessage", "MessageController", FormMethod.Post}))
{
#Html.TextAreaFor(model => model.Message)
Controller:
public class MessageController : Controller
[HttpPost]
public ActionResult SendMessage(ChatModel viewModel)
{
var message = viewModel.Message;
// Code to save to file here
You have a model, a controller and a view.
The model declares the variables that will be used for binding.
In the View you declare your model and you set the properties of this model as shown above. It is 2 way binding, meaning that you can have values that come from the server initially and these values also go back to the server when you submit.
Example: if I set the value of property Message to "Hello, this is initial value". Then this will be shown to the client side.
Now if it is editable field, the user can change that value, e.g. "This is my message" and when the form that contains this element is submitted, the controller should have parameter of type ChatModel...then the ASP.Net engine will bind the values from the client side to the corresponding variables.
And yes...you will get the message value on the server and you can persist to anything you want, DB, file or transport further to another service...
I am new to NET MVC and I try to develop an app where user will answer few questions,
I have the following models related to my question:
Question
Choice (includes question ID as FK)
and a ViewModel
public class QuestionChoiceViewModel
{
public Question Question { get; set; }
public IEnumerable<Choice> Choices { get; set; }
}
In my view I want to display all questions with their responding choices as radio buttons, so i have the following lines in my view Choice/Index.
#model IEnumerable<WebApplication.Models.QuestionChoiceViewModel>
#using (Html.BeginForm("Index", "Choices", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#foreach (var q in Model){
#:<b>Question:</b>
#Html.DisplayFor(modelItem => q.Question.questionText)
<form class="form-group">
#foreach(var c in q.Choices){
<input type="radio" name="#c.choiceText" value="#c.choiceID" />
#c.choiceText
<br />
}
</form>
<br />
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Back" class="btn btn-default" id="btnBack" />
<input type="submit" name="btnSubmit" value="Submit" class="btn btn-default" />
</div>
</div>
</div>
}
I display and can choose from multiple questions without a problem.
And for the final sample of code, see my controller takes only a FormCollection type as paramater
public ActionResult Index(FormCollection form)
The problem: When I debug and see what is in the form -besides Token etc.- is the value of only the first radiobutton group. Lets say I have 10 questions but what I get passed in controller is whatever selected in 1st question. What did I do wrong?
Also, any tips about my style are most welcome, thanks!
At first glance, two things seem out of place:
The inner form tags <form class="form-group"> do not need to be form, and nesting forms can cause problems.
The name property of the radio inputs is used to group them together, so it should be the same for choices for one question, e.g. it should be #q.something instead of #c.choiceText
Also, name should be some short identifier instead of a text targeted at the user, as I supsect c.choiceText is:
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be
followed by any number of letters, digits ([0-9]), hyphens ("-"),
underscores ("_"), colons (":"), and periods (".").
https://www.w3.org/TR/html401/types.html#type-name
I read the other questions that were similar but my issue is more basic. I'm rather new to bootstrap but I'm testing it out to see if this will work for a simple form that I need to be opened by phones, tablets, and any other device.
I'm trying to get my textbox on the same line as the text that describes it. Instead, the textbox is under the text.
Here is what is happening:
Here is the cshtml page of the above:
#model MvcBootstrap.Models.HomeModels.VisitingCustomer
#{
ViewBag.Title = "Home Page";
}
<div class="">
<p class="lead">Please enter your branch number, account number, and at least the first three characters of your last name or at least the first three characters of your company name below so we can locate your account.</p>
</div>
<div class="container">
#using (Html.BeginForm("TypeOfPayment", "Home", FormMethod.Post))
{
<div class="row">
<h2>Account Lookup</h2>
<div class=".col-md-4">
Branch Number
</div>
<div class=".col-md-8">
#Html.TextBoxFor(m => m.Branch, new {#class = "", #maxlength = "2"})
</div>
</div>
<div class="row">
<input id="submitpayment" class="typicalbutton" type="submit" value="Continue" />
</div>
}
</div>
I have no additional css code nor have I modified any of the existing css.
This should be pretty straight forward but I'm just not grasping the concept I guess. What am I doing wrong?
You could group the Branch Number and the text box in one column like so
<div class="col-md-4">
<label for="branch-number">Branch Number</label>
# add text box here and give it an id="branch-number"
</div>
Also, you don't need to have a . before the class name in your classes.
You can try this format. form-inline class makes the form inline. you don't need to use the responsive column classes. also you should use class="col-md-*" not class=".col-md-*"
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<form class="form-inline">
<div class="form-group">
<label for="branch"> Branch Number</label>
<input type="text" class="form-control" id="branch no">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
You can specify the class for different screen
i.e
col-lg-1 to col-lg-12 for large screen
col-md-1 to col-md-12 for desktop / laptop screen
col-sm-1 to col-sm-12 for tablet screen
col-xs-1 to col-xs-12 for mobile screen
Example
<input type="text" class="col-lg-6 col-md-6 col-sm-6 col-xs-12" >
What you are looking for is an inline form.
#using (Html.BeginForm("TypeOfPayment", "Home", FormMethod.Post, new { #class="form-inline" }))
{
<div class="row">
<div class="col-md-12">
<h2>Account Lookup</h2>
<div class="form-group">
#Html.LabelFor(m => m.Branch)
#Html.TextBoxFor(m => m.Branch, new {#class = "form-control", #maxlength = "2"})
</div>
<input id="submitpayment" class="typicalbutton" type="submit" value="Continue" />
</div>
</div>
}
In your model for this form you will want to add a [DisplayName] attribute for your Branch property so that you can use the Html.LabelFor() helper I included above:
[DisplayName("Branch Number")]
public string Branch { get; set; }
You will also want to read more about the grid system. Your original code did not use the proper classes for the columns.
Like #Asif Raza said, you should specify what size of screen are targeting. Keep in mind that the sizing will work for the size you specify and UP. So if you specify a medium size screen, it will affect medium size screens and larger, not smaller.
I dont think thats your issue though, I think whats happening with you is there are extra margins you are not seeing that is causing the textbox to be placed below. The max width of the container is going to be 12 columns, which you are using, but if there are any other margins in between it's going to cause the textbox to fall below. I recommend inspecting the element with F12 to zone in and see if there is anything extra being added.
I would like to know what is the best way to send a parameter to a view.
This is my first time with MVC.
I have a menu and I would like to change the item menu class depending which item menu is selected.
For example I have a menu with Home, Products, About.
<div class="nav-main-item">
<a asp-controller="Home" asp-action="About">
<div class="top-solid-line selected"></div>
<div class="row nav-item">
<div class="item-line-1">
Home
</div>
</div>
</a>
</div>
<div class="nav-main-item">
<a asp-controller="Home" asp-action="Products">
<div class="top-solid-line"></div>
<div class="row nav-item">
<div class="item-line-1">
Products
</div>
</div>
</a>
</div>
<div class="nav-main-item">
<a asp-controller="Home" asp-action="About">
<div class="top-solid-line"></div>
<div class="row nav-item">
<div class="item-line-1">
About
</div>
</div>
</a>
</div>
If I select Products I want to add the class 'selected' to it, and remove the class selected to the item menu was selected before an so on.
I know how to do it in jquery, is very simple, but the thing is when I click one of the items menu the selected class continue in the home item menu, that is because I initialize the selected on the Home item menu.
I need some kind of parameter to pass to the view and depending on that value add the class selected to the item menu selected.
I know should be very simple, any help will be appreciate it!
Thanks.
In the controller you can use return View(model), where model is some variable or object. In the cshtml file you can then declare #Model int for instance, when passing an integer and access it like a normal variable as model. For instance: #if (model == 1){ your code here }.
EDIT: you can also add parameters to the ViewBag (google it, there are lots of examples) but I would use the model since it is strongly typed.
ASP.NET MVC Send Multiple Data to View
My opinion
ViewBag, ViewData,TempData is basic solution method exm: (alert, message, script vb. other run client-side code and single data) but write a long code line this dirty and complexible. But using ViewModel property is best solve so your code is not complexible and full compatible Object Oriented Programming architecture.
Understanding ViewModel
I'll admit I'm new to MVC and this question might be a single case of RTFM. But I'm googling this problem and I can't seem to find a solution.
I've got a simple view used to fill out some details for a specific model. I need to render part of the form using Html.Partial (in truth this is a wrapper which renders old non-MVC controls used from another project).
I've no problems getting data FROM the controller INTO the view.
So what's the issue? How do I get user input from the partial view back to the controller after the user pressed the submit button?
Here's the view and controller I've currently got:
#model Poll
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Poll</h4>
<hr />
#*#Html.ValidationSummary(true)*#
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.Name)
#Html.Partial("~/ControlPlaceholder/QuestionPlaceholder.ascx", Model, new ViewDataDictionary(Model))
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Fill" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The view has been copied almost one-to-one from the standard generated edit view available in MVC5. Note that this is currently just a PoC - normally the whole thing should render a QuestionPlaceholder for every question in a Poll.
Here's the relevant part of the controller:
//
// GET: /Poll/Fill
[HttpGet]
public ActionResult Fill(Guid id)
{
var poll = pollRepository.Get(id);
return View(poll);
}
//
// POST: /Poll/Fill
[HttpPost]
public ActionResult Fill(Poll poll, FormCollection collection)
{
try
{
return RedirectToAction("Index");
}
catch
{
return View(poll);
}
}
it is so simple, just set name of inputs same as corresponding action parameters and let MVC ModelBinder do it's job. it's not important to render a partial in the form, it's input elements value would be passed to the action on submitting form.
another way is to use Request.Form["InputName"] that is not my first recommendation.