I'm using Asp.Net MVC 5 with EF 6.
I have a Model, let's call it "Checkout". It has the following properties:
int BuyerId
List<CheckoutItem> Items
CheckoutItem has the following properties:
int ItemId
decimal Price
bool IsPaid
I want to have a view first display EditorFor -> BuyerId. When the user enters a BuyerId, the view should update with the Checkout data, the items displayed in a list in which the user can click a "remove" link to remove that item from the current transaction (the View's current Model). When the user clicks on the submit button, I want the controller to update the items in the Checkout.Items list with IsPaid = true.
I understand all of the logic needed for all of this. The problem I'm having is how this all works withing the MVC context.
Currently I have Checkout.cshtml whose Model is Buyer (accessed by BuyerId) which has a textbox for the user to enter the BuyerId and an empty <div>. Using jquery on .focusout I use .ajax to call the controller and return a partial view, "_CheckoutDetail". _CheckoutDetail uses Checkout Model to display the information in the model.
Currently _CheckoutDetail has a form, but when I submit it from the partial view, the binding isn't working.
If this is all clear what I'm trying to do, my question is, what is the best way to accomplish this? I expected my partial view to post its Model back to the controller, but it isn't working. I've tried both
public async Task<ActionResult> CheckoutDetails(CheckoutViewModel checkout)
and
public async Task<ActionResult> CheckoutDetails([Bind(Include = "BuyerId,Items")] CheckoutViewModel checkout)
in my controller definition. In both cases I receive a message "The name 'checkout' does not exist in the current context".
Thank you for your help.
Related
I have a multiple partials views on main view with specific employee name and button to get full data for that employee. I am not getting any idea of how to invoke specific action to display data in pop-up and get the full data of that specific employee on button click.
Assuming the model for each partial view includes the employee's ID, you could use anchor tags instead of buttons and include the employee ID in the href attribute.
For example, in your partial view for the employee details, include something like this:
Details...
If you decide to use javascript instead to display the popup, check out data attributes:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
In that case, you could render a button like this in your Partial View:
<button type="button" class="employee-btn" data-employee-id="#Model.EmployeeID">Details...</button>
And then read the value in javascript (this example uses jQuery event handlers):
$('.employee-btn').click(function() {
var employeeId = $(this).data('employee-id');
// logic to fetch employee details and display in popup...
});
For my Website model, I have a boolean property called isLive. My Index method shows the result of this property (if true it will display "live", "offline" otherwise). In my controller, I added a method called EditStatus that allows the user to update only the website's status. My EditStatus view (which belongs to the Websites controller) displays a dropdown menu with 2 options: Live/Offline. This is how I pass it to the Index view:
#Html.Partial("EditStatus", item)
I want to know how to pass the item's (aka the model) unique ID to this partial view so that specific model will be updated.
You can use viewdatadictionary:
example:
#Html.Partial("EditStatus", new ViewDataDictionary { { "item", someInteger } });
Can I create 2 views for a model and controller?
My current application is MVC complaint , and it has a single view.
I need to create a second GUI, that fetches few information from the model (updated from the first GUI data) , update it and display back in the first GUI.
You can have a different view per action. Based on your description, this seems to be what you are looking for. You have different actions for the same model, it's ok.
You can add a new action for the new information that you want to update and click on the right button of the mouse and click "add view". It will add a new view for that action.
The most common way to do this is to create other actions, one for each View you want to display.
You can have as many Views as you like, as long as you can route between them.
As default, the line return View(); or return View(model) will look for a view in this path: /Views/{ControllerName}/{ActionName}.
You can also specify the view name, as Controller.View() also accepts a string as the view name.
Knowing this, you could display different views from a single action, according to parameters passed to your action.
Example:
public ActionResult Example(bool a)
{
if (a) return View("a");
else return View("b");
}
this will call the view /Views/{ControllerName}/a.cshtml if a is true and /Views/{ControllerName}/b.cshtml if a is false.
You can also call other partial views or actions from your first view, using html helpers: #Html.Partial({ViewName}), #{Html.RenderPartial({ViewName});} or #{Html.RenderAction({ActionName});}
EDIT:
View() also searchs for /Views/Shared/{ActionName}
I have an Action result that returns a list
public ActionResult GetData(Profiles profiles)
{
Vertical Vdata = new Vertical();
List<Ver> Vertical = new List<Ver>();
//Code to fill list
return View(Vertical);
}
And then a partial view to display the List
#model IEnumerable< List<VerticalContainer.Models.Vertical>>
#foreach(var item in Model)
{
<span>#item.name</span>
}
I'm not sure how to render the partial view from my main view
#Html.Action("GetData")??
What do I pass with the Html.Action? or Should I use Partial/RenderPartial?
1- the correct way to render actions is as per the following:
#Html.RenderAction("ACTION_NAME","CONTROLLER_NAME")
where you replace both action name and controller name with the correct values according to your solution.
2- For the passed model, if this action is being rendered inside a view that has a Model property of Profiles
, then you don't have to specify the model to be passed to the action, as it will implicitly read it from the parent view.
if this is not the case, then you will need to store your Profiles values inside a medium variable (for example inside a ViewBag property) and then you will pass it when calling the action, so it should work on this passed model istead of working on the parent view one.
example: #Html.RenderAction("ACTION_NAME","CONTROLLER_NAME", YOUR_MODEL_VALUE_HERE)
Suggestion: if this parital view will just render the list passed, you can skip creating the mentioned action, and just make a call which can render the partial view, passing to it the correct list so it can work with.
To make it more clear, using your question I can see that the action named GetData is just constructing the list called Vertical from the Profiles model passed, so you can construct this list in your original action (Index, Details, WHAT_EVER_THE_NAME_IS) and store it in a ViewBag, then you can call RenderParial instead of RenderAction and this should result in the same output as your mentioned scenario.
example: #{ Html.Partial("ViewName", YOUR_MODEL_HERE);}
#{Html.RenderAction("actionName","controllerName");}
From your main view, you may simply render your Partial view as:
#Html.Partial("_PartialViewName", VerticalList);
VerticalList in this case will be the list of type VerticalContainer.Models.Vertical, that you populated in controller action.
I've been trying to figure out a solution for quite some time, to no avail. What I have is a form. I'm using ASP.NET MVC4 with jQuery Mobile. The user is first directed to the following screen:
Here, they choose a capsule and click Submit. The capsule they choose has a primary key value that I want to persist to the next page.
Once they click Submit, they will be taken to:
Here, they'll fill out the form and click "Create". The fillers list that you see on this screenshot is based on the capsule selected on the previous screen. So, depending on the capsule selected, the filler list above can vary. How can I retain the Capsule's primary key value that was selected on the previous screen and persist it to the next screen (a completely different view)? I understand I cannot use ViewBag because ViewBag is only in the scope of a single View. Essentially, what I want is the data on the form above, as well as the primary key of the capsule selected in the previous view.
You will need to post the value back to the server from View1 and then pass that back to View2 via a Controller action method:
Below is a code snippet that show was happens on the server :
//Serve the view when the URL is requested
public ActionResult ViewAllItems()
{
return View();
}
//Handle the posted form from the ViewAllItems page
[HttpPost]
public ActionResult ViewAllItems(int selectedItemId)
{
RedirectToAction("ViewItemDetail", new { id = selectedItemId });
}
public ViewResult ViewItemDetail(int id)
{
var item = repo.GetItem(id);
return View(item);
}
Here the method with the Controller Action method ViewAllItems receives the posted value and redirects to the ViewItemDetail method which then loads the item data and passes it to the view. The view will hence be passed the id (along with the full item).
This is the general MVC pattern where the values are passed up to controller action methods and then relayed back to views.
Consider this psuedo code but in essence the controllers could look like this...
[HttpPost]
public ActionResult FormOnePost(ModelFromFormOne modelFromFormOne)
{
var model = new ModelForFormTwo();
model.Filters = IList<Filter> from database? query using id
model.MoreStuff etc.
return View("ViewTwoWithSecondForm", model);
}
This keeps from exposing your primary key in the path.
You can make the variable holding the value static