Generating a modal jQuery partial view with MVC4 does not work - asp.net-mvc-4

I like the way MVC4 manage the new logon screen: it is possible to have a modal dialog showed.
I tried to reproduce the same behavior in the same solution for another view. But it doesn't work because Request.QueryString["content"] is null. I don't know why. In fact, there is an action method called ContextDependentView (generated by the MVC template) where the trick occurred. Here it is:
private ActionResult ContextDependentView()
{
string actionName = ControllerContext.RouteData.GetRequiredString("action");
if (Request.QueryString["content"] != null)
{
ViewBag.FormAction = "Json" + actionName;
return PartialView();
}
else
{
ViewBag.FormAction = actionName;
return View();
}
}
If the value of Request.QueryString["content"] is not null then we display a partial view (modal jQuery) otherwise it is a classic view.
Can someone help me understand why this is not working?
PS: another thread already exists but without any solution.

The login and register links are bound to a click handler in AjaxLogin.js which then adds content=1 in loadAndShowDialog

Related

MVC 4 website back press return the same form with old values

I am new in MVC 4 web development and i am creating a control panel. I have developed a Add user page and submit information in database successfully.
But after submit when i press back button it will show previous form.
i am using redirection the page to same page after submit form.
here is the code to redirect
public ActionResult AdminPanel(RegisterUserModel user)
{
if (ModelState.IsValid) // Check the model state for any validation errors
{
if (user.AddUserToDB(user.username, user.password, user.fullName,user.contactNo,user.COAId)) // Calls the Login class checkUser() for existence of the user in the database.
{
TempData["SuccessMessage"] = "User Added Sucessfully!";
ModelState.Clear();
return Redirect("AdminPanel");
}
else
{
ViewBag.SuccessMessage = "User Not Added";
return View();
}
}
SelectList clientsList = GetClinetList();
ViewBag.clientsList = clientsList;
return View(); // Return the same view with validation errors.
}
I have tried many examples but issue not resolved yet so kindly give my suggesstions
If you don't want the user to be able to see the previous content when clicking back, then you must indicate that content should not be cached by the browser and must revalidate with the origin server
A summary of this behaviour is here - http://blog.55minutes.com/2011/10/how-to-defeat-the-browser-back-button-cache/
You could create a nocache attribute, like this one - https://stackoverflow.com/a/10011896/1538039, and apply it to your controller methods.

How to get a url after returning the view?

I am new to MVC4, I am using more then one form in one View. When i am posting the form i am getting all the formcollecion values in controller. When i am returning the different view also, its working fine. My problem is after returning view, the url showing that post method name.when i try to refresh this page its showing error.
Initially the url was : Admin/Activities
after posting the form : Admin/UpdateActivity
I need url like this after returning the view : Admin/Activities
how to get it, Please help me. Thanks in advance.
I dont have any separate view for this ActionResult. This is my code:
[HttpPost]
public ActionResult UpdateActivity(FormCollection coll)
{
................
ViewBag.updateAlert = "Activity updated sucessfully";
return View("Activities");
}
#using (Html.BeginForm("UpdateActivity", "Admin", FormMethod.Post,new { #id = "formID" }))
Change your form attribute as it. It will automatically return to the view Activities.
Note: if your form on Admin/Activities.
After updating the record,you can Redirect to that action,instead of returning the same view again, and instead of ViewBag you will have to use TempData as ViewBag will be null after redirecting:
[HttpPost]
public ActionResult UpdateActivity(FormCollection coll)
{
................
TempData["updateAlert"] = "Activity updated sucessfully";
return RedirectToAction("Activities","Admin");
}

What ActionResult should you return to update just the ActionLink text?

I'm using MVC4 with Entity Framework and like many people I'm new to MVC and trying to get my head around the design patterns.
I have a partial view that displays a list of sessions followed by actionlinks allowing the authenticated member to book into the sessions.
Note: for clarity, I've chopped out most of the code, if a member is booked into a session, it displays "Booked" instead of the action link.
#using OnlineBookings.Website.Models
#{ DateTime currentDate = DateTime.MinValue.Date; }
<form method="post" action="~/Controllers/BookSessionController.cs">
#foreach (SessionsWithBookingInformation s in Model)
{
<p>#s.StartTime.ToString("t")
#s.Description
#Html.ActionLink(
"Book",
"BookSession",
new { sessionId = s.SessionId }
)
</p>
}
</form>
This then displays as part of a larger view:
The actionlinks pass the guid of the session to be booked through to the following function in my controller, which retrieves the memberId from the cookie and uses Entity Framework to create a booking for that member and session.
public ActionResult BookSession(Guid sessionId)
{
using (var db = new OnlineBookingsEntities())
{
// see if the member id is stored in a cookie
if (Request.Cookies["memberId"] != null)
{
var memberId = new Guid(Request.Cookies["memberId"].Value);
db.Bookings.Add(new Booking
{
BookingId = Guid.NewGuid(),
MemberId = memberId,
SessionId = sessionId,
BookingTime = DateTime.Now
});
db.SaveChanges();
}
}
// this refreshes the entire page
/// is there a better way to just replace the actionlink they clicked on?
return RedirectToAction("Index", "Home");
}
All this is working nicely and bookings are being effectively recorded.
But, I'm trying to figure is if the return from the BookSession function can just update the actionlink text.
Ideally, on success, I want to replace the ActionLink in my partial view with the word "Booked" and on failure I want to replace it with the failure condition like "Session full".
Or I could just update my partial view, because that will do the same thing.
Am I missing something simple here? Or, am I barking up entirely the wrong tree?
Your question is great and really well explained, but it's also a little vague since it's a bit of a "What should I do?" question. Here are a few options that might help you develop a solution.
Redisplay the same view. Return whichever view the user was on for them to submit the link. This will look like a simple refresh.
return View();
Submit the request via AJAX and update via a partial view. Put an id tag on a span or similar HTML element with an individual booking's details inside. Submit the request with AJAX, perhaps via #Ajax.ActionLink, and have your action return a partial view.
return PartialView("_OnlineBookingPartial", model);
Once your partial view is returned, update the specific booking with the data returned.
Use AJAX again, but return JSON. Another way might be that you use AJAX again but instead you return JSON and do something with it. You could, for example, return text in which you would replace Book with; i.e. "Session full" or "Booked!".
return new JsonResult
{
Data = "Booked!"
}
Personally, I'd probably use AJAX to update with a non-AJAX (non-Javascript) fallback.
You can do this by using #Ajax.ActionLink and checking if the request is AJAX or not inside your controller action.
if (Request.IsAjaxRequest) {
return PartialView("_OnlineBookingPartial", model);
}
return View();
This means that if the browser has Javascript enabled and supports AJAX, it will be used and the whole process will be seamless and instant for the user. If Javascript is disabled, the page will simply refresh.

How to avoid rendering entire page when using CGridView via AJAX

When creating any ajax request in yii CGridView like (pagination, filtering, ...etc) the result of request will render whole page, how can i avoid that?
I tried to use renderPartial for view but it doesn't work. if this is the solution, how can i do it?
I just need to render the table of GridView not whole page.
Please advice.
In controller:
$this->layout = false;
For me works also $this->renderPartial() in controller instead of $this->render()
if(Yii::app()->request->isAjaxRequest()) $this->renderPartial('view');
else $this->render('view');
U can create class:
class Controller extends CController {
public function beforeAction($action) {
if(Yii::app()->request->isAjaxRequest) $this->layout = false;
return parent::beforeAction($action);
}
}

MVC Grid Delete Record Action Performing Full Page Load, How to stop this?

I have an mvc grid.
Next to each record is a delete button.
This delete button corresponds to an action DeleteRecord. The action deletes this record and performs a RedirectToAction("MyGrid");.
This works pretty well but what is annoying is the fact that my redirectaction causes the entire page to reload. This is something I am trying to stay away from, but can't seem to figure out a way around this.
I start out like this.
/MyApp/MyGrid => click delete
/MyApp/DeleteRecord => redirect
/MyApp/MyGrid => full reload of page
Maybe this isn't possible but I tried doing this by using overriden actions and actions with different action names, but this didn't solve my full reload. I am new to MVC so maybe this isn't even possible. I was thinking maybe if I just did an ajax.post on the clientside that I could get away from this but the more I think about it the more likely that it just will end up in the same action performing the same redirect.
Any ideas on how to get around this situation?
I actually ended up just tying into the callback function of the grid and the inline delete of the grid function and it worked. Although, extremely hackish, it stops the full post back by hoping into the inline grid delete code. Although, you can't count on the callback javascript routines to run in order as that is just how javascript works right. ; o
s.SettingsEditing.DeleteRowRouteValues = new { Controller = "Home", Action = "DeleteRecordGrid" };
s.ClientSideEvents.EndCallback = "function(s,e) { OnEndCallback(s, e, 'delete') }";
<script type="text/javascript">
function deleteWithoutPostback(eVisibleIndex) {
var okToDelete = confirm("Do you really want to delete this record?");
if (okToDelete == true) {
myGrid.DeleteRow(eVisibleIndex);
myGrid.ClearFilter();
} else {
return;
}
}
function OnEndCallback(s, e, callType) {
if (typeof callType == 'undefined') {
if (callType == 'delete') {
myGrid.Refresh();
}
}
}
</script>