MVC 3 Razor - show modal based on an EF query - asp.net-mvc-3

At work I have been tasked with adding additional functionality to an existing MVC 3/Razor project. I haven't used MVC before, but am quite versed with Web Forms.
However, I am not quite sure where to place everything I need.
When the app is first loaded, a login page appears. When the user logs in successfully, the user sees a dashboard type page.
The new functionality is to detect whether the user has FollowUpItems with a Due Date < Now. If Count > 0 then display a Modal popup with some text and a link to 'View Followup Items'.
There is already a controller and action made for viewing Followup items. I need to display the modal, and I would like to make the modal a reuseable type of object - I am assuming/thinking a PartialView where I can pass in the name of the Controller, Action, Params for a possible ActionLink that I would display in the modal popup, and the message text, etc.
I need a little guidance on how to open the modal since it isn't attached to a click, but rather to whether an expression evaluates true or false, and where the best place for the pieces are.
Thanks in advance for the guidance

I would detect if the user has FollowUpItems in the Action that loads the dashboard page, and store that information in the ViewBag. For example,
public ActionResult Dashboard()
{
ViewBag.HasFollowupItems = UserHasFollowupItems();
return View();
}
In this example, UserHasFollowupItems() returns a string, something like 'true' or false'.
In the dashboard view, add an empty div into which the modal data will be loaded
<div id="followup_items"></div>
then add a document.ready() in the same view which defines the modal and determines if the modal should be loaded:
$(document).ready(function ()
{
// define modal
$("#followup_items").dialog({
autoOpen: false,
height: 'auto',
width: 825,
title: 'Followup Items',
position: [75, 75],
modal: true,
draggable: true,
closeOnEscape: true,
buttons: {
'Close': function ()
{
$(this).dialog('close');
}
},
close: function ()
{
$('.ui-widget-content').removeClass('ui-state-error');
},
});
if(#ViewBag.HasFollowupItems == 'true')
{
$('#followup_items').load("/FollowupItems/Load", function (data, txtStatus, XMLHttpRequest)
{
$('#followup_items').dialog('open');
}
});
});
In this example /FollowupItems/Load is the URL to the proper controller/action that generates the data for the view. You are correct, the view for this would be a partial view, loaded into the empty followup_items div on the page.
So you can use the #ViewBag object anywhere in the view, in this case passing in your boolean indicating if the modal should be loaded/opened. I have not found a way to use ViewBag in an external javascript file, so I typically use embedded script tags in my views so I can use the ViewBag.
You could also add in the user id in the same way (/FollowupItems/Load/#ViewBag.Userid), or any other data the followup action needs.

Related

How to present partial view in jQuery dialog without navigating to another page

I have two controllers, A and B. A is responsible for representing some data in a grid view. Assume I have a button called "ShowInfo" which brings additional info about the selected record. And to retrieve the info about the selected record is the job of controller B.
The info is so little that it'd take just a tiny place in the corner if I navigate to another view. So I thought I'd rather bring that info inside a jQuery dialog without navigating to anywhere. But I'm a bit confused as to how to do it.
Here's the action method in controller B that is responsible for providing that info in a partial view.
public class BController:Controller{
public ActionResult GetInfo(int recordID){
RecordInfo info=RecordsRepository.GetRecordInfoById(recordID);
return PartialView(viewName:"RecordInfo",model:info);
}
}
I don't know, maybe the action method needs to different. Maybe I should return JSON instead of Partial view, but anyway, how do I do that?
You can use the jquery .get or .load methods. For example, to replace the contents of <div id="SomeElement"></div> with the partial view returned by GetInfo()
$('#ShowInfo').click(function() {
var url = '#Url.Action("GetInfo", "B")';
var ID = someValue; // the value to pass to the GetInfo method
$.get(url, { recordID: ID }, function(data) {
$('#someElement').html(data);
});
});
You can use Jquery ajax to achieve this.
Wrtire jquery ajax on the view page and call the partial view action from ajax.
receive the result in html format and replace it in the dialog box.
Put following code on main view page(ShowInfo button page)
$(document).ready(function(){
$("#ShowInfo").on("click",function(){ ///give id to showinfo button and attr data-id is record id
var id=$(this).attr("data-id");
$.ajax({
type: "POST",
url: "B/GetInfo",
data: JSON.stringify({ recordID: id }),
dataType: "html",
success: function (html)
{
////put the html response in dialog box
}
});
})
});

Jquery Mobile submit button not working after page refresh

I have a single page mark-up with popup divs that contain forms that the user can use to update his/her account information. After form submission the popup closes and the page refreshes showing the updated information that is located within a li (this seems to be working). The problem is, if the user goes back and tries to update again the button within the popup is not submitting.
Thanks in advance for any suggestions!!!
Javascript
$('#updateadmin').click(function() {
var admin = $('#adminform').serializeArray();
/*alert(admin);*/
$.ajax({
type: "POST",
url: 'adminupdate.php',
data: admin,
success: function(data) {
if(data=="success") {
$('#admindiv').popup('close');
$.mobile.changePage('companyinfo.php', {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true,
changeHash: false
});
} else {
$('#adminupdatestatus').html(data).css({color: "red"}).fadeIn(1000);
}
}
});
return false;
});
It sounds like the #updateadmin link/button is located on the page that gets reloaded, if this is the case then you should delegate your event handler so it affects matching elements in the DOM for all time, not just when the code runs.
You would change this:
$('#updateadmin').click(function() {
to this:
$(document).on("click", "#updateadmin", function() {
This works because you're now attaching the event handler to the document element which always exists. When events reach the document element they are checked to see if the element on which they originally fired matches the selector we put as the second argument for .on().
Documentation for .on(): http://api.jquery.com/on

Edit pop up box for a grid design

I am writing a MVC3 project. Right now I have a table which has column with Data as actionLinks as:
<td style="color: Black; background-color: Bisque; text-align: center; width: 410px">
#Html.ActionLink(#item.LookUp_NameString, "EditPartial", "Capitation", new { id = item.CAPITATION_RATE_ID }, new { #class = "actionLink" })
</td>
EditPartial as the name suggests is a partial view, which I need to be opened as a pop-up menu so that user can edit the details of the object, save it and we can come back to original page.
I have tried the render partial, but can't get it to pass the id value dynamically.
This is for edit functionality of my grid. What will be the best way to implement this?
If you want to open the result of EditPartial Action method in a model popup, you need some model popup code for that.
jQuery UI is one option. http://jqueryui.com/demos/dialog/
1) Include jQuery UI reference in your page,
2) Add the below script to your page which will convert your normal link to a model popup
<script type="text/javascript">
$(function(){
$(".actionLink").click(function (e) {
var url = this.href;
var dialog = $("#dialog");
if ($("#dialog").length == 0) {
dialog = $('<div id="dialog" style="display:hidden"></div>').appendTo('body');
}
dialog.load(
url,
{}, // omit this param object to issue a GET request instead a POST request, otherwise you may provide post parameters within the object
function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog({
close: function (event, ui) {
dialog.remove();
},
modal: true,
width: 460, resizable: false
});
}
);
return false;
});
});
</script>
From your action result, you can return whatever markup you want to show in the Model popup. Mostly you will be returning a View. If you want to show a partial View,If it is an ajax request and show the normal view if it is a normal request, you can check the Request.IsAjaxRequest method to do that.
public ActionResult EditPartial(int id)
{
CustomerViewModel objCustomer=GetCustomer(id);
if(Request.IsAjaxRequest())
{
return View("Partial/Edit",objCustomer);
}
return View(objCustomer);
}
Assuming you have 2 views present to show your normal page and partial page (for model popup)
I prefer to name my action method as Edit instead of EditPartial, because it is handling both requests (ajax and normal)

Present and layout a set of buttons in ASP.NET MVC 3

I am working on a computer support incident management system.
Currently, a Review view for an incident contains several incident manipulation buttons, that are "rendered" onto the view with the help of the following logic:
A model for the view contains several methods that can tell if some action is allowed to be currently executed on this incident
A part ViewModel to which the Review view is bound:
...
public bool CanContactUser()
{
return _manager.CanContactUser(Incident, User);
}
public bool CanComment()
{
return _manager.CanSetComment(Incident);
}
...
In the view, depending on the result of these methods, the actual button for particular action is either displayed or not:
...
#if (Model.CanContactUser())
{
#Html.MakePopupForm("ContactUser", new[] { "id" }, title: "Register user contact", refreshOnSuccess: true, okText: "Save", cancelText: "Cancel", resizable: false)
}
#if (Model.CanComment())
{
#Html.MakePopupForm("Comment", new[] { "id" }, title: "Comment", refreshOnSuccess: true, okText: "Save", cancelText: "Cancel", resizable: false)
}
...
I feel that it is a bad practice. Even though it works, I am willing to have a collection of available buttons in memory (in C# code), I guess in a ViewModel class instance, and bind the view to render this collection.
How can this be achieved? Binding the view to a collection of buttons in particular. I can generate an abstract collection of List<AvailableButton> buttonsToRenderAsHtml ...But how do I link Razor to display it in a controlled fashion?
I think this depends on your preference.
If you have a contiguous set of buttons in your layout then you could add your property to your existing view model and then render in a loop. EG:
#foreach(var button in Model.AvailableButtons) {
YourButtonRenderMethod(button)
}
or have a shared partial view that can render a set of buttons with:
#model IEnumerable<AvailableButton>.
In that case you can just call:
#Html.RenderPartial("SetOfButtons", Model.AvailableButtons)
This is how I tend to build out my UI using composable partial views
But if your buttons are scattered in different areas of your view layout then I don't think you have a choice but to check individually.
It is strictly view logic, so you shouldn't feel bad about that in my opinion.

Custom pager in Telerik MVC Grid

Can i customize appearance of a Grid's pager? I wanna select a page size from list (like Redmine, see 'Per page' block) not from dropdown.
It's standart Telerik's pager:
It's Redmine's pager:
Thanks.
PS for instance Devexpress' Grid has this ability
You could replace the DOM element that is responsible for page size. You need to do it when grid is loaded.
View
#Html.Telerik().Grid(Model)
.Name("Grid")
.ClientEvents(events => events.OnLoad("Grid_onLoad"))
JavaScript
function Grid_onLoad(e)
{
var html = { place your favorite template engine here }
$('#YourGridId').find('.t-page-size').html(html);
// bind 'click' event to your new control
}
Now the problem is that you need to bind own event to the change of the page size and tell new page size for the Telerik grid.
You can provide additional parameters to the controller action that provides data to your controller. There is an example in the documentation how to add additional data to your request.
<script type="text/javascript">
function Grid_onDataBinding(e) {
// pass additional values by setting the "data" field of the event argument
e.data = {
pageSize: // TODO: provide selected page size from your new control
};
}
</script>
In the server side controller action should automatically map your pageSize to an action parameter.
I hope this helps, let me know if you need more information.

Resources