MVC3 ActionLink nightmare - asp.net-mvc-3

I have a dashboard page which has 4 partial views.
each view has an edit link which when clicked, loads another temaplate.
Now ofcourse the new template will have Save and Cancel. When I click on cancel, i want to load the old view, and when click on save, i want to save the model and return to the old view.
all this has to be a partial update. How would i achieve this.
To start of with, i am using ajax action link (using post) to just return a datetime string. instead of updating my div, it is redirectin me to a different view.
MVC is ridiculously difficult. huh...

Ah.. MVC is simple once you establish a clean way to do things : )
so - each dashboard has 4 partials. So as one option - have your main page have four divs.
inside each div, use Html.Partial to render your views.
Each partial view has its own Ajax.BeginForm tag. The UpdateTargetId is the divs id in the parent view. I'm not a huge fan of a child needing to know the name of its parent to update, and there are some other ways (one option is each of the four views really is two other views for each one - one to contain the form and div that is updated and then a call to the partial view like:
Each 'parent' partial view has for example
<div id='divAddressEdit'>
#using (Ajax.BeginForm("action","controller", new AjaxOptions() { UpdateTargetId = "divAddressEdit", InsertionMode = InsertionMode.Replace }){
#Html.Partial(....)
}
</div>
Lets assume you go with the first option where each partial view contains its own ajax form.
So - when the user saves - ok.. the ajax form posts back, and then RedirectsToAction() and renders the new content again. When cancel is clicked, the same thing occurs - the form posts and you reload the original info.
The key here are the ajax forms. I know I didn't include much code here - as I believe your post is more of a conceptual question - if it doesn't make sense I'll post specific samples.

Related

Partial View Submit inside Parent View MVC 3 w/Razor

I have three partial views that I load into a div based on radio button selection using jquery. Everything works fine on the loading and on the forms, however each partial form has a submit button(none on the parent form). I begin each partial form with:
<div id="newTicketPartial">
#using (Ajax.BeginForm("CreateNewTicket", "SubmitTicket", new AjaxOptions() { UpdateTargetId = "newTicketPartial", HttpMethod = "POST" }))
The issue is that within this form once I finish entering data and click the submit button it seems to skip this forms ajax post back header and instead uses the parent views #using Html.BeginForm
If I put an action and controller in the parent forms BeginForm field it will use that, otherwise there is an error. My problem is even if it does use the parent views POST path my controller only returns the partial view that I was editing, which updates the entire page. I need to be able to submit information from each partial view and have only that partial view be updated, not the entire page. I am open to suggestions of ways this can be done. If more code is desired I will post more.
Nested forms are the issue. You should not nest forms, or else any buttons further down the page (even those generated by partial views) will cause the parent form to POST.

How to get parent view from partial view

I have a partial view as part of the _Layout.cshtml, so that it gets rendered on multiple pages. Think of the partial view as a menu that gets displayed on every page on the website.
When one of these links in the menu of the partial view is clicked, I can only access/see in the Action Method that gets called the partial view, like it's name etc.
But what I really need to have is the View that the partial view was on when the item was clicked.
How can I get this?
You can use ParentActionContext
For example
var controller = ControllerContext.ParentActionViewContext.RouteData.Values["Controller"] as string;
var action = ControllerContext.ParentActionViewContext.RouteData.Values["Action"] as string;
Update
From the view this call should do what you need
#HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString()
#HttpContext.Current.Request.RequestContext.RouteData.Values["action"].ToString()

Unable to pass model into partial view inside layout pages

I have a layout page within that layout I have used a partial view, the partial view contains a menu feature that I have built, I split the menu into a partial view to ensure it is easy to maintain. The menu has been purposely placed in the layout because it is used across every page, however there are conditional elements in the menu whereby some options only appear on certain pages.
I have stumbled upon what will be an issue for me moving forward, the menu uses ajax calls to render partial views containing the content (reducing page loads) I was just working on a page which contains a company, the company contains a list of contacts, the menu option when clicked should display the list of contacts. I have already loaded the contact list under the company model, but! I can’t access it from my new partial view that should render the contact list because the menu is a partial view that is contained within the layout page and as such cannot accept a model, so I cannot pass a model into the partial view I am trying to load because the menu partial view sits in the layout page.
This is a sticky situation, I obviously could change the layout to render a new section to contain the menu so I can pass a new view model into it but then every single page I build needs to reference the menu (what a pest!) I must be missing something here (considering this is my first MVC3 application that is likely). Any suggestions?
Edit: I took this further on my own, in short my layout page will always be able to access the model of the page that consumes it, as such my partial view which contains the menu can also access that data. I wrote some conditional logic in my menu partial view that checks the page and then passes in data as required.
<div class="menu">
<ul>
<li><a href="#Url.Action("Create", "Contact")">New Contact </li>
<li>Contact List </li>
</ul>
#if (Request.Url.PathAndQuery.Contains("/Contact/Details/"))
{
<ul>
<li>#Html.ActionLink("New Activity", "Create", "Activity", new { companyid = 0, contactid = Model.contact.id }, null)</li>
</ul>
}
</div>
The above is a small sample of the menu partial view but contains one example where the menu is built for the contact/details page and is able to pass in the model.contact.id. It works in that my menu and my layout do not explicitly contain a model, but it does not feel very tidy.
If I'm understanding your question correctly, your issue is that you don't think your Partial View can have a model because you don't want your layout to have a model. So the question is how can you get a model into your layout without needing every single action to extend this base model type your layout would use.
1) Instead of using Html.Partial in your layout for the menu use Html.Action where you'll then have an action method that fetches the menu data.
2) Write a custom WebViewPage and include a property that has something like
return ((BaseController)ViewContext.Controller).MenuData;
now you don't even need a model in your partial view, it can access the data directly.
Both of these require having a Menu property containing all menu information available in your base model, but if every page in your websites going to need to access this data, then that seems appropriate.
Edit: In response to your tidiness concern, it sounds like you want sections, which give you the ability to customize pieces of your menu either in their appropriate view page or sub layout.
See http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx for an overview of sections and http://blogs.msdn.com/b/marcinon/archive/2010/12/15/razor-nested-layouts-and-redefined-sections.aspx for information of nested layouts/sections.

Finding, loading and adding partial views dynamically

I've been tasked with converting an existing webforms application to mvc 3 razor.
The application currently has an aspx page which has a static header user control and "n" amount of other user controls which are dynamically created. In the code behind for the file, it is executing the below code in various specific sections to dynamically process user controls with information provided from the database.
I know how to statically create partial views, but being somewhat new to MVC, how would I go about defining this new "aspx" page and also to dynamically find, load and add the partial views (each equivalent to the below webforms code)?
btw, the code will be in C# as well.
Dim parent As Control = Page.FindControl(_moduleSettings.PaneName)
Dim portalModule As PortalModuleControl = CType(Page.LoadControl(_moduleSettings.DesktopSrc), PortalModuleControl)
parent.Controls.Add(portalModule)
I think I can do something like this when the page is rendering. I want to make it as simple as possible.
The "PaneName" will be set in the parent variable which determines where in the page it will be shown (Left, Right, or Main)
The "DeskTopSrc" is the name of the partial view to display.
So, take the code out of the code behind and place it in the main View. Perform the above processing logic in the View (boy, switching from aspx code behind to a View throws me a loop. I gotta get use to doing the processing in the View. Reminds me of Classic ASP, but the Razor syntax will help).
Display the partial view via the #Html.PartialView('partial view name'). This view might have a grid in it associated with a specific model.
Below is the part I am unsure about.
I've done database processing for a main View associated with a Controller, but not with a partial view that needs to do some database processing.
Perform any database processing logic (if any) for this partial view in the Controller associated with the main View (which contains this partial View).
In the Action Index method while looping over these "partial views", I can get the data and display the views....
Ahhh, I think I got it.....
After carefully thinking it through, if someone could help me out with the last statement here, I would greatly appreciate it.
1.Have partial views already statically created with the specific HTML markup that I need in the Views/Shared folder.
2.In the main View, I will already have
#Html.Partial(ViewData["partial_view_left"])
#Html.Partial(ViewData["partial_view_right"])
#Html.Partial(ViewData ["partial_view_main"])
statements in specific locations of the HTML which will render the partial views as I retrieve their names from the database.
3.In the Controller's Index method, I need to do the following:
a) Loop through the converted logic (from the CodeBehind of the existing WebForms page in the PageLoad event) in the Index action method of the new Controller which will load the partial views dynamically.
1) Find out where the partial view will be displayed (left, right, main) from the database via the "parent" variable.
2) Find out the name of the partial view that will be displayed from the database via the “DesktopSrc” variable.
eg: ViewData["partial_view_left"] = "left_view"; OR
ViewData["partial_view_right"] = "right_view"; OR
ViewData["partial_view_main"] = "main_view";
3) Right here is where I am unsure of how to properly display the partial view.
I need to have the equivalent of a webforms "Controls.Add" method to render each partial view from the Controller that I retrieve from
the database from step 3.a.2
What statement can I use in this Index method of the Controller that will accomplish this?
In other words, if I dynamically need to display several partial views inside of a parent view, how is this accomplished in MVC?
I know for each partial view, I can send over the model associated with it, but I just don't know how I can place several partial views inside the main view page at run time from one Action method.
If your partial views need to do some processing, like database retrieval, then you should use
#{Html.RenderAction("ActionName");}
This will call an action method (which doesn't have to be on the same controller) that can dynamically choose a view based on logic, and populate the ViewModel with data from the database.
public ActionResult ActionName()
{
var modelData = GetData();
return View(settings.DesktopSrc, modelData);
}

MVC3: Showing entity relationships in a view

I am new to ASP.NET MVC and I have a question regarding viewing entity relationships.
Say I have an entity called 'Person'. This holds the usual data relating to a person (Name, Email, etc). I also have a 'Notes' entity. Under EF, a 'Person' can have many 'Notes'.
I have a Person controller where I can view and preform CRUD operations on a Person object.
I can show the notes in the view easily but what is the best way to allow a user to add/edit/delete these notes from the Person view? I am hoping to do this using AJAX and not have the user move to a completely different page to add/edit/delete a note.
Thanks in advance,
ViperMAN.
When they edit a note, popup a jQuery dialog pointing to your URL to edit or have a separate Ajax.BeginForm() on the page that the details go into. When they finish the edit call a method to refresh the notes.
So:
1. In your Notes grid (or whatever)
you have an edit link for each note called "edit"
this link looks something like the following:
This one actually uses 'notes' : )
http://www.iwantmymvc.com/dialog-form-with-jqueryui-and-mvc-3
ASP.NET MVC | Problem about showing modal dialog using jQuery dialog widget
ASP.NET MVC modal dialog/popup best practice
Also beware of this scenario for multiple links:
MVC3 - Only first row link works well with Jquery Modal Dialog
Now the urls you use to populate the dialogs would be for example
/Note/Edit/10
One thing to note - jQuery validation needs to know about these new items that are being loaded via ajax into the DOM , so in your partial view you need to tell jQuery validation to include the new items - I'll edit in a bit to add this, have to grab it from another machine.

Resources