Hiding columns values for few records in the grid depending on their role type: MVC3 - asp.net-mvc-3

**I am trying to create a view which has a grid
View layout, I am using is:**
#model IEnumerable<VC.MC.ReportalWeb.UI.Users>
#using myspace
#{
ViewBag.Title = "Users";
var grid = new WebGrid(source: Model, canSort: true);
}
<h2>Users</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#grid.GetHtml(columns: grid.Columns(
grid.Column("UserName"),
grid.Column("Email"),
grid.Column(
header: "",
style: "text-align-center",
format: (item) => new HtmlString(Html.ActionLink("Edit", "Edit", new { id = item.id ).ToString() + " | " +
Html.ActionLink("Details", "Details", new { id = item.id }).ToString() + " | " +
Html.ActionLink("Delete", "Delete", new { id = item.id }).ToString()))
)
)
#grid.GetHtml(columns: grid.Columns(Html.RoleBasedColumns(grid)))
#{
if (!string.IsNullOrWhiteSpace(grid.SortColumn))
{
<script type="text/javascript">
$('thead > tr > th > a[href*="sort=#grid.SortColumn"]').parent().append('#(grid.SortDirection == SortDirection.Ascending ? "^" : "v")');
</script>
}
}
The RoleBasedColumns(grid) is a helper method in my razor which is
public static WebGridColumn[] RoleBasedColumns(
this HtmlHelper htmlHelper,
WebGrid grid
)
{
var user = htmlHelper.ViewContext.HttpContext.User;
var columns = new List<WebGridColumn>();
var query = from p in _adminModelContainer.Users
select p;
IList<Users> userList = query.ToList();
for (int i = 0; i < userList.Count; i++)
{
// The Prop1 column would be visible to all users
columns.Add(grid.Column("UserName"));
if (userList[i].RolesId == 1)
{
// The Prop2 column would be visible only to users
// in the foo role
columns.Add(grid.Column("Email"));
}
}
return columns.ToArray();
}
I want to show Edit and delete link buttons only for those users whose RolesId is 1.
Using the above functionality the grid is just replicating itself .Columns headers are shown whose rolesid is 1.
I am in a fix.
Any help would be of great use.
Thanks

Do it the easy way and use Telerik's free open source mvc controls (the grid) and when you define your grid.. just use a dynamic column along the lines of:
#(Html.Telerik().Grid(Model)
.Name("Grid").TableHtmlAttributes(new { width="800"})
.Columns(columns =>
{
if (userIsInWhateverRole){
columns.Template(o => Html.Action(GenerateYourLinkStuffHere));
}
columns.Bound(o => o.Address).Width(150);
columns.Bound(o => o.City).Width(120);
columns.Bound(o => o.State).Width(100);
})
.Sortable()
.Scrollable()
.Groupable()
.Filterable()
.Pageable(paging =>
paging.PageSize(5)
.Style(GridPagerStyles.NextPreviousAndNumeric)
.Position(GridPagerPosition.Bottom)))
No other grid is as nice in my opinion - and its free. Why give yourself the headache : )

Related

Get PK of Selected Row Kendo Grid From Toolbar Button

I have a Selectable Kendo Grid with a Custom Toolbar Button.
How can I get the selected row PK when button is Clicked?
I tried many tips but no one was working because I have a Server DataSource.
<%: Html.Kendo().Grid<Web.Models.Model>()
.Name("Grid")
.BindTo((IEnumerable<Web.Models.Model>)ViewBag.List)
.Columns(columns =>
{
columns.Bound(p => p.PK).Title("PK");
columns.Bound(p => p.STATUS).Title("Status");
columns.Bound(p => p.NOTES).Title("Notes");
})
.ToolBar(toolbar =>
{
toolbar.Custom();
toolbar.Template("<a class='k-button k-button-icontext' onClick='EditItem();' ></span>Edit Item</a>");
})
.DataSource(dataSource => dataSource
.Server()
.Model(Model => Model.Id(p => p.PK))
)
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple))
%>
function EditItem(e) {
???
};
Please try with the below code snippet.
<script>
function EditItem() {
var grid = $("#Grid").data("kendoGrid");
var rows = grid.select();
rows.each(function (index, row) {
var selectedItem = grid.dataItem(row);
alert(selectedItem.PK);
});
}
</script>
Let me know if any concern.
hi you can use plain jquery for that as an another option
var rowID = $("#Grid .k-state-selected").find("td:eq(0)")[0].innerText
alert(rowID)
This one works!
function EditItem(e) {
var selectedRows = $("#Grid").find(".k-state-selected");
for (var i = 0; i < selectedRows.length; i++) {
var selectedRow = selectedRows[i];
var PK = selectedRows[i].cells[0].innerText;
}
};

cascade dropdownlist asp.net

i've two table in DB.
i want to create dropdownlist for city and corresponding area after that.this is my first cascade drodown menu in my entire life.i've tried to follow some examples.in the get action i've :
ViewBag.cities = db.cities.ToList();
ViewBag.areas = db.areas.ToList();
in the view i've:
<div class="editor-field">
#Html.DropDownListFor(model => model.city,new SelectList(ViewBag.cities as
System.Collections.IEnumerable, "city_id", "name"),
"Select City", new { id = "ddlCars" })
#Html.ValidationMessageFor(model => model.city)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.area)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.area, new
SelectList(Enumerable.Empty<SelectListItem>(), "area_id", "name"),
"Select Area", new { id = "ddlModels" })
#Html.ValidationMessageFor(model => model.area)
</div>
i've just copied a js file from a site that is
$(document).ready(function () {
$("#ddlCars").change(function () {
var idModel = $(this).val();
$.getJSON("/Post/LoadAreasByCity", { id: idModel },
function (carData) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select Area"
}));
$.each(carData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
$("#ddlModels").change(function () {
var idColour = $(this).val();
$.getJSON("/Home/LoadColoursByModel", { id: idColour },
function (modelData) {
var select = $("#ddlColours");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select a Colour"
}));
$.each(modelData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
in my Post/LoadAreasByCity my method is:
public JsonResult LoadAreasByCity(string id)
{
PostManager pm = new PostManager();
if ( id=="") { id = "1"; }
int c_id =(int) Convert.ToInt32(id);
var areaList = pm.GetModels(c_id);
var modelData = areaList.Select(m => new SelectListItem()
{
Text = m.name,
Value = m.area_id.ToString(),
});
return Json(modelData, JsonRequestBehavior.AllowGet);
}
it propagate cities and area is correctly in the view page.but after submitting the data it gives errorin this line
#Html.DropDownListFor(model => model.city,new SelectList(ViewBag.cities as
System.Collections.IEnumerable, "city_id", "name"),"Select City", new { id =
"ddlCars" })
it says Value cannot be null.
Parameter name: items
Finally in my post action
int c_id = Convert.ToInt32(p.city);
int a_id = Convert.ToInt32(p.area);
area a = db.areas.Single(x=>x.area_id == a_id);
city c = db.cities.Single(s => s.city_id == c_id);
post.city = c.name;
post.area = a.name;
....Save to DB
what is the problem in this ..... thanks in advance
I suspect that in your POST action you have redisplayed the same view but forgot to populate the ViewBag.cities and ViewBag.areas items as you did in your GET action:
[HttpPost]
Public ActionResult Process()
{
... Save to DB
ViewBag.cities = db.cities.ToList();
ViewBag.areas = db.areas.ToList();
return View();
}

Telerik MVC grid Access Data out side the grid binding

In Telerik MVC 3.0 Grid (Razor engine)
How can i access the data after grid binding.
I am using Detailed view tab
using below code.
items.Add()
.Text("Additional Tab")
.Content(#<text>
#(Html.Telerik()
.Grid<Models.PModel>()
.Name( "Additional_<#= AddressID #>" )
.DataBinding( dataBinding => dataBinding.Ajax()
.Select( "Action", "Controller", new { ID = "<#= ID #>" } ) )
.Pageable()
.Sortable()
.Columns( columns =>
{
columns.Bound( e => e.Name ).Title( "Name" ).Width( 150 );
columns.Bound( e => e.Email ).Title( "Email" );
columns.Bound( e => e.Status ).Title( "Prescriber Status" );
columns.Template( e => e.ID ).ClientTemplate(
Ajax.ActionLink( "Edit", "EditDetails", new { ID = "<#= ID #>", PID = "<#= PID #>" },
new AjaxOptions
{
OnSuccess = "LoadAddEditForm",
UpdateTargetId = "ShowAddEditFormDialogModel",
InsertionMode = InsertionMode.Replace
},
new { #class = "button" } ).ToString() );
} )
.NoRecordsTemplate( "No additional added for this" )
)
#Ajax.ActionLink("Add New", "AddEdit", "Controller",
new { ID = "<#= ID #>"},
new AjaxOptions
{
OnSuccess = "LoadAddEditForm",
UpdateTargetId = "ShowAddEditFormDialogModel",
InsertionMode = InsertionMode.Replace
},
new { #class = "button", id="AjaxAddNewButton" })
</text>);
Now the Problem is,, if you notice i have added a Ajax.Action link after the grid binding.
#Ajax.ActionLink("Add New", "AddEdit", "Controller",
new { ID = "<#= ID #>"},
new AjaxOptions
{
OnSuccess = "LoadAddEditForm",
UpdateTargetId = "ShowAddEditFormDialogModel",
InsertionMode = InsertionMode.Replace
},
new { #class = "button", id="AjaxAddNewButton" })
In this Ajax Link I can get the value of object new { ID = "<#= ID #>"}
as I am trying to access the <#= ID #> after the grid binding, it is not rendering the value.
How can i get this work?
Any help would be greatly appreciated.
Thanks
This is not possible.
The <# ID #> you are using is for a single row in your grid. It cannot be used outside the .Columns() method. So your column template may work, but if you inspect what is being sent to the Action handling the binding, you will see that the ID parameter literally equals "<# ID #>".
For the ActionLink past the grid, what ID did you want? from which row?

MVC3 WebGrid - Creating Columns Dynamically (foreach?)

I want to create a WebGrid with columns based on a collection, such as List. Something like this (which obviously doesn't work):
#grid.GetHtml(
columns: grid.Columns(
#foreach (var column in Model.ListOfColumns) {
grid.Column(column.Name, column.Title);
}
)
)
Any clever ideas?
You could ViewBag it like below.
Controller:
List<WebGridColumn> columns = new List<WebGridColumn>();
columns.Add(new WebGridColumn() { ColumnName = "Id", Header = "Id" });
columns.Add(new WebGridColumn() { ColumnName = "Name", Header = "Name" });
columns.Add(new WebGridColumn() { ColumnName = "Location", Header = "Location" });
columns.Add(new WebGridColumn() { Format = (item) => { return new HtmlString(string.Format("<a href= {0}>View</a>", Url.Action("Edit", "Edit", new { Id = item.Id }))); } });
ViewBag.Columns = columns;
View:
#grid.GetHtml(tableStyle: "ui-widget ui-widget-content",
headerStyle: "ui-widget-header",
columns: ViewBag.Columns
)
Try this:
#{
List<WebGridColumn> cols = new List<WebGridColumn>();
foreach(var column in Model.ListOfColumns)
{
cols.Add(grid.Column(column.Name, column.Title));
}
}
#grid.GetHtml(
columns: cols
)
You could use helper method
public static class GridExtensions
{
public static WebGridColumn[] DynamicColumns(
this HtmlHelper htmlHelper,
WebGrid grid
)
{
var columns = new List<WebGridColumn>();
columns.Add(grid.Column("Property1", "Header", style: "record"));
columns.Add(grid.Column("Property2", "Header", style: "record"));
columns.Add(grid.Column("Actions", format: (item) => { return new HtmlString(string.Format("<a target='_blank' href= {0}>Edit </a>", "/Edit/" + item.Id) + string.Format("<a target='_blank' href= {0}> Delete</a>", "/Delete/" + item.Id)); }));
return columns.ToArray();
}
Usage:
#{
var grid = new WebGrid(Model);
}
#grid.GetHtml(columns: grid.Columns(Html.DynamicColumns(grid)))

MVC 3 WebGrid with a checkbox filter

I'm developing a web application using MVC 3 RTM. In a view I have a WebGrid which works fine with sorting and paging. However, I also needed some filtering support on the page, so I added a textbox and a checkbox. The view code looks like this:
#using (Html.BeginForm("Index", "Customer", FormMethod.Get))
{
<fieldset>
<legend>Filter</legend>
<div class="display-label">
Search for</div>
<div class="display-field">#Html.TextBox("filter", null, new { onchange = "$('form').submit()" })</div>
<div class="display-label">
Show inactive customers?
</div>
<div class="display-field">
#Html.CheckBox("showInactive", false, new { onchange = "$('form').submit()" })
</div>
</fieldset>
var grid = new WebGrid(canPage: true, canSort: true, ajaxUpdateContainerId: "grid", rowsPerPage: 10, defaultSort: "Name");
grid.Bind(Model, rowCount: Model.Count, autoSortAndPage: false);
grid.Pager(WebGridPagerModes.All);
#grid.GetHtml(htmlAttributes: new { id = "grid" },
columns: grid.Columns(
grid.Column("Name", "Name"),
grid.Column("Address", "Address"),
grid.Column("IsActive", "Active", (item) => item.IsActive ? "Yes" : "No")));
}
This works fine except when I check the checkbox. When I load the page for the first time, the checkbox is not checked. Sorting and paging works, and I can enter some text as a filter and it filters my result, and sorting and paging still works after that. However, if I check the checkbox, it updates the result, but sorting no longer works. The filter still works though, so if I enter some text, it correctly filters the result and still respects the checkbox.
I've tried setting a breakpoint in my controller, and there's no problem there. The request is sent when I try to sort, and the controller correctly returns the view with the result as the model. But it doesn't seem like the WebGrid is updating itself.
Has anyone else experienced this, or has anyone some good advice on what to look for?
Thanks!
I normally add a form (above my WebGrid) which contains a textbox called "Keywords" and a checkbox called "IsActive" and when the "Go" button is clicked it reloads the WebGrid adding the "Keywords" and "IsActive" options to the query string.
You can add more elements to your form and their values will be sent al
Use the following helper script - webgrid.helper.js:
function reloadGrid(form) {
var grid = form._grid ? form._grid.value : "grid";
var args = {};
updateQueryParams(args, grid + " th a");
args.sort = "";
args.sortdir = "";
updateQueryParams(args, grid + " tfoot a");
args.page = 1;
for (var i = 0; i < form.elements.length; i++) {
var el = form.elements[i];
if (el.type == "text" || el.type == "select" || (el.type == "radio" && el.checked))
args[el.name] = el.value;
else if (el.type == "checkbox")
args[el.name] = el.checked;
}
//get controller name
var s = $("#grid th a")[0].onclick.toString();
s = s.substring(s.indexOf("/"));
var controller = s.substring(0, s.indexOf("?"));
var queryString = "";
for (var key in args)
queryString += "&" + key + "=" + escape(args[key]);
var url = controller + "?" + queryString.substring(1);
$("#" + grid).load(url + " #" + grid);
}
function updateQueryParams(args, path) {
var links = $("#" + path);
if (links.length == 0)
return;
var s = links[0].onclick.toString();
s = s.substring(s.indexOf("?") + 1);
s = s.substring(0, s.indexOf(" #"));
var a = /\+/g; // Regex for replacing addition symbol with a space
var r = /([^&=]+)=?([^&]*)/g;
var d = function (s) { return decodeURIComponent(s.replace(a, " ")); };
var q = s;
while (e = r.exec(q))
args[d(e[1])] = d(e[2]);
}
Then just above my webgrid, I have the following partial file - *_ListFilter.cshtml*
#using (Html.BeginForm(null, null, FormMethod.Get))
{
<div id="filter">
<table width="600">
<tr>
<td>#Html.TextBoxFor(c => c.Keywords, new { size = 50, placeholder = Strings.SearchByKeywords, title = Strings.SearchByKeywords })</td>
<td>&nbsp

Resources