posting an action from a partial view within a jquery dialog - asp.net

I have an index page with a jquery tab loaded. Within one of the tabs I open a partial view company.ascx. Within that I have 2 RenderActions' One loads the company header and the other loads the branch information.
<% Html.RenderAction("Compheader", "Home"); %>
<br />
<br />
<% Html.RenderAction("BranchList", "Branch", new { Id = Request.QueryString[0], pdate = Request.QueryString[1] }); %>
Within BranchList I display a table of branches each of which has a delete button associated to it. There is also an add button on the branch list. Both these buttons open a jquery dialog that open partial views (acsx) within it. The dialogs have a submit post within them.
When the user clicks on submit on the insert/add or delete view I want to be able to refresh the BranchList action, which will get the new branchlist and display it.
Right now on post within the delete or insert I response redirect to the index page which refreshes the whole page. Can somebody tell me how I can accomplish this using Html.BeginForm and ajax posts in a clean way instead of the response redirect.

You are accessing QueryString directly within your view and that means that you are not using any of the goodness of ASP.NET MVC framework. You should get these values in action method (using the matching parameter names as the QueryString variables in the action method's constructor) and then pass these values from action method to the view (using a view model or ViewData) so that you don't have to access QueryString directly inside the view.
Now coming to your question, I think you are doing it right. If you are getting the right behavior from your application, then you should not change the post-redirect behavior of the application.
You are posting the data from the partial views and then doing a redirect. This is a valid pattern, also known as GPG (Get, Post, Get) pattern. This is advantageous compared to simply sending the user to their "Posted" page as it avoids from letting the user post the same data twice in case they refresh the page.
Hope it helps.

Related

Many forms for editing entity on one page

I have a list of objects on my page. I need to edit an object in a popup.
There are many objects, and generating many forms for each object is not correct.
What can I do, can an iframe do in a popup?
You don't need to use iframe.
Build your form in your controller and render it in the html. The fact that it's in popup doesn't change anything. It doesn't matter if it's in popup or not, the final result will be POST call to your action.
You should have an action that renders a form, callable from an ajax in the view where you have all those entities.
Just change the entity id that will be received in the action as argument by changing the ajax url using js depending on the clicked entity you want to edit.
Then return with the ajax the form already rendered so with only one form you can edit as many entities (of the same class) as you want, without even need to render one form before they click which one they want to edit.

Read hidden field values from another page

I am developing a website using ASP.net.
In my home page I have 14 tree view controls. They were placed under Jquery tabs. So when a user click a tab it only appears one treeview. So in tree node changed event currently what I am doing is passing the values from query string to another page. this query string doesnt have any sensitive data. I have to pass what is the selected Tab Id and selected tree node Id.
Response.Redirect(String.Format("~/Display.aspx?tab=1&type={0}",treeview1.SelectedValue), true);
But you know URL is ugly. I dont want to use Friendly URL thing now.
So what I did was I put 2 hidden fields values in my home page and I set them when I click the tree node.
So then from the source page I used this code to acess this.
if(Page.PreviousPage!=null)
{
string tab= Page.PreviousPage.FindControl("hftab").UniqueID;
string Type= Page.PreviousPage.FindControl("hfType").UniqueID;
}
But Page.PreviousPage always return NULL. So how to solve this probelem without using sessions and query string. I just want to pass two non sensitive data behind the scenes.
IF this is about Cross page postback thing How to do this cross page post back in node change event? Is it ok to do a Cross page post back for to get only 2 values that I needed?
The method you are trying is only possible with "Cross page posting" mechanism. When you set PostbackUrl property of a server control like button, and set the PreviousPage property of Page directive on destination page; then only you will get Page.PreviousPage values.
Here are some reference:
1. http://www.codeproject.com/Tips/604553/Postback-and-Cross-Page-Posting-in-ASP-NET
2. http://www.aspdotnet-suresh.com/2010/05/cross-page-post-backing-in-net.html

ASP .NET MVC - How to redirect a user control to the view its called from?

I have a user control that creates a new record in a database. After it creates the new record, I would like to redirect it back to the view its from. The purpose of this is to refresh the view so that it can show the newly created record. The problem is that user control can exists in more than one view, so how can i know which view is the user control from? so that I can achieve the above scenario? Thanks,
RWendi
I have a user control that creates a new record in a database.
No, it doesn't. It just renders HTML, and nothing else.
It's the controller action which creates a new record in the database, and thus this is where the redirect should happen.
The [HttpPost] action which accepts the model/form should perform the redirect after the save has been completed.
E.g:
public ActionResult Save(SomeModel model)
{
db.Save(model);
return RedirectToAction("Index");
}
I'm assuming that the "view" you want to refresh is the same page, regardless of which page the user controller was rendered on, therefore the above code is fine.
On a side note, you shouldn't be using user controls (e.g partials) for rendering forms.
You should be using editor templates. The presentation code which renders the form (and specifies which action to post to) should be in the view, not in the user control.
EDIT - example of how to render form on Views:
Instead of doing this on a View:
#Html.Partial("_SomeModel")
Do this:
#using (Html.BeginForm()) {
#Html.EditorFor(model => model.SomeModel)
}
And place the form markup in the editor template. The key thing here is IMO the Views should be responsible for setting up the form, not the user control.
There are several ways,
1) You can use this.Request.UrlReferrer.AbsoluteUri , which will always give you the Url of your page.
2) Or, you can have a hidden property in ... in PartialView, which will hold the value for current url. (#this.ViewContext.ParentActionViewContext.HttpContext.Request.UrlReferrer.AbsoluteUri)
But only if you are using #Html.RenderAction.
In the child action, you can redirect to either of above urls. (First approach is much more better and will work in all scenarios)
I think the refresh is responsibility of the action that renders the view your user control is from.
You can have scenarios (or views) where the inserting is done in one action and then pass the request to another action (maybe a list) that shows the newly created record.
Or you can have other scenarios where the inserting is just part of what you want to save to the db and refreshing the original view may cause the loss of data.
Maybe what I'm saying is not what happens with your project right now but it's something you should consider before giving the user control a responsibility it shouldn't have.

Getting form field names on Submit when form is user control

I am slowly, piece by piece learning what I am doing with ASP.NET
I've created the beginnings of my new web application, but I am often coming up against the issue that ASP.NET renames elements IDs or in the case of form fields, their names.
I have a form which is basically a sales system. It is essentially made up of two User Controls, one is a form for Customer Details (name, address etc) and the second is a form for the customer's purchases, it consists of a number lines dynamically created by Javascript created as you list the items the customer is purchasing.
Both these sections are User Controls because they are to be used for other areas of the system where this data will need to be recalled/re-entered.
When the USer Control is loaded, the field which contains the Customers' Name is renamed "m$mainContent$customerForm$name" I understand where this comes from, "m" is the ID of my Master Page, "mainContent" is the main Content Placeholder and "customerForm" is the name of the User Control.
In fact, in my case, this will always remain the same on all forms, so it is relative easy to overcome... but... suppose it wasn't
I can see there are ways I could deal with this with Javascript, but the form doesn't need an AJAX submit, a normal Post will do fine for this, so when I open up the recieving page I want to call Request.Form("name")% to save the customer's name into the database, but of course I really need Request.Form("m$mainContent$customerForm$name")%
How would I dynamically extract those prefixes from the posting form to ensure that if I rename anything or use it in a different scenario, the problem will not break it?
I am using .NET 2.0, so can't use Static Client.
This is really old but let's see if it's useful for you.
Getting this example I managed to get the value from a given field name without prefix.
I'm sure it is not the best solution, but it was useful for me. Let's say you want to recover the value of a field named "hfIdAviso", that comes in the POST as "ctl00$body$hfIdAviso":
var value = Request.Form.Cast<string>()
.Where(key => key.EndsWith("hfIdAviso"))
.ToDictionary(key => key, key => Request.Form[key])
.Values.FirstOrDefault();
That will return the value for that field.
Hope it helps.
If you include runat="server" in the declaration of your user control in the ASPX page, then you can access this control by just using the ID value of the control.
For example
In the ASPX:
<uc:MyUserControl ID="mycontrol1" runat="server" />
In the code behind (in C# syntax):
object foobar = mycontrol1.SelectedValue;
suppose you have a form inside user control that has a TextBox field with ID="txtfname".You have registered your user control in page1 and you want to POST form data to page2 :
in page1 you have user control:
<My:WebUserControl1 ID="myuc" runat="server" />
in page2 codebehind , you can get the value of user control form field (txtfname) this way :
string firstName = Request.Form["myuc$txtfname"];

MVC: capture route url's and pass them to javascript function

Short:Is there a way to have a route-definition that will pass the "CONTROLLER/ACTION" string value to a JavaScript function in stead of actually going straight for the controller action?
More:I have a masterpage which contains the navigation of the site. Now, all the pages need this navigation wrapped around it at all times, but because I didn't want the navigation to constantly load with each pagecall, I changed all my pages to partialviews.
These partial views are loaded via the JQuery.Load() method whenever a menu item is clicked in the navigation.
This all worked very good, up till now because I noticed it's also a requirement of the website to be able to link directly to page X, rather then default.aspx.
So, as an example:The main page is my "default.aspx" page, this utilizes my master page with the navigation around it. And each call to a new page uses a javascript function that loads that particular partial view inside a div that is known in my masterpage. So, the url never changes away from "default.aspx", but my content changes seemlesly.
The problem is, those url's also need to be available when typed directly into the address bar. But, they're partial views, so loading them directly from the address bar makes them display without any masterpages around them. Therefore my question if it might be possible to capture the route typed into the address bar and pass that on to my JavaScript function that will load that route in the content div.
(I hope I explained it ok enough, if not, feel free to ask more information)
You are 100% correct to not want to hard code your URLs in your javascript code as it demolishes one of the primary tenants of MVC to do so. I'm one of those "separation of concerns" guys who will not write a single line of javascript outside of a dedicated .js file so I cannot dynamically specify the URL the way tuanvt has. What I do is use MVCs Url.Action method to emit my service URLs into hidden inputs on the master page (or the specific page if it is not used in multiple places). Then my script file simply pulls the value out of that hidden input and uses it just fine.
ASP.NET MVC View Source
<input id="serviceUrl" type="hidden" value="<%= Url.Action("Action", "Controller") %>" />
JS Source
$.getJSON($("#serviceUrl").val(), function(data) {
//write your JS success code here to parse the data
});
First challenge, as you are using AJAX to load the partial pages you need client accessible URLs for the javascript to call. Second challenge, you need URLs that will load the HomeController and pass the 'page' portion of the URL into the javascript.
For the first aspect I'd create some abstracted routes, i.e. "/ajaxaccess/{controller}/{action}/{id}" for the partial pages. That would be the first registered route. A second route would accept any controller/action reference and always get processed by the HomeController Index action.
In the /Home/Index action you grab the requested URL and slice it up, take the /{controller}/{action}/... section and pass that into your default.aspx using TempData. In your page check for the existence of the TempData and if it exists use the value therein to trigger your AJAX page load for the partial page (don't forget that you'll need to prepend '/ajaxaccess' (or whatever you choose) to the URL before it's passed to your page.
I'm not going to provide code here as I think the information you'll gain from working through this yourself will be invaluable to you moving forward.
You could use hash anchor (#) on your url and read it with javascript.
var url = document.location.toString();
if (url.match('#')) {
anchor = url.split('#');
// do whatever with anchor[1] ..
}
You can do something like this, put this in your javascript code on the view:
var szUrl=<%= ViewContext.RouteData.Route.ToString()%>;
Then the current route will be stored on the variable szUrl.

Resources