I have a asp.net MVC View Page which is Master/Detail style.
After reading from this , I realize that I need to serialize jqgrid data before I send to Controller Layer.
[HttpPost]
public ActionResult Detail(Seminar Seminar, List<Seminar_Detail> Seminar_Details)
{
}
So my question is,
1. How could i send data to controller, by using 2 ViewModel classes.
SeminarMaster for Form Input Fields and SeminarDetail for Jqgrid entire rows.
2.If you say, I have only one way which is serializing to jqgrid, then Do i need to serialize Form input fields also?
3.If I have to use serialize way, Do I have chance to use ViewModel classess to parse data to Controller Layer ?
Updated
JqGrid Code or View Layer Implementation
Or Detail Page which user can make Insert/update or delete process.
#model MvcMobile.ViewModel.SeminarListDetailViewModel
#{
ViewBag.Title = "Detail";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Detail</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Seminar</legend>
<table>
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Seminar.Seminar_Code)
</div>
</td>
<td>
<div class="editor-field">
#Html.EditorFor(model => model.Seminar.Seminar_Code)
#Html.ValidationMessageFor(model => model.Seminar.Seminar_Code)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Seminar.Title)
</div>
</td>
<td>
<div class="editor-field">
#Html.EditorFor(model => model.Seminar.Title)
#Html.ValidationMessageFor(model => model.Seminar.Title)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Seminar.Description)
</div>
</td>
<td>
<div class="editor-field">
#Html.EditorFor(model => model.Seminar.Description)
#Html.ValidationMessageFor(model => model.Seminar.Description)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Seminar.Room)
</div>
</td>
<td>
<div class="editor-field">
#Html.EditorFor(model => model.Seminar.Room)
#Html.ValidationMessageFor(model => model.Seminar.Room)
</div>
</td>
</tr>
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pager" class="scroll" style="text-align:center;"></div>
<script type="text/javascript">
jQuery(document).ready(function () {
var AllSpeakers = (function () {
var list = null;
$.ajax({
'async': false,
'global': false,
'url': 'GetAllSpeakers',
'dataType': 'json',
'success': function (data) {
list = data;
}
});
return list;
})();
var AllTags = (function () {
var list = null;
$.ajax({
'async': false,
'global': false,
'url': 'GetAllTags',
'dataType': 'json',
'success': function (data) {
list = data;
}
});
return list;
})();
var lastSel = 0;
jQuery("#list").jqGrid({
url: '/Seminar/DetailGridData/',
editurl: "/Seminar/MyEdit/",
datatype: 'json',
mtype: 'GET',
colNames: ['Seminar_Code', 'Speaker', 'Tag', 'DateAndTime'],
colModel: [
{ name: 'Seminar_Code', index: 'Seminar_Code', width: 40, align: 'left', editable: true, edittype: "text", editoptions: { size: "35", maxlength: "50"} },
{ name: 'SpeakerID', index: 'SpeakerID', align: 'left', editable: true, edittype: "select", formatter: 'select', editoptions: { value: AllSpeakers,
dataEvents: [
{ type: 'change',
fn: function (e) {
//alert("Speaker change"); // For Cascading Dropdownlist Or Dependent Combo
}
}
]
}, editrules: { required: true}
},
{ name: 'TagID', index: 'TagID', align: 'left', editable: true, edittype: 'select', formatter: 'select', editoptions: { value: AllTags }, editrules: { required: true} },
{ name: 'DateAndTime', index: 'DateAndTime', width: 40, align: 'left', editable: true, edittype: "text", editoptions: { size: "35", maxlength: "50"} }
],
pager: jQuery('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
sortname: 'SpeakerName',
sortorder: "desc",
viewrecords: true,
autowidth: true,
autoheight: true,
imgpath: '/scripts/themes/black-tie/images',
caption: 'My first grid'
})
$("#list").jqGrid('navGrid', '#pager', { edit: false, add: false, del: false, refresh: false, search: false });
$("#list").jqGrid('inlineNav', '#pager', {
addtext: "Add",
edittext: "Edit",
savetext: "Save",
canceltext: "Cancel",
addParams: {
addRowParams: {
// the parameters of editRow used to edit new row
keys: true,
oneditfunc: function (rowid) {
alert("new row with rowid=" + rowid + " are added.");
}
}
},
editParams: {
// the parameters of editRow
key: true,
oneditfunc: function (rowid) {
alert("row with rowid=" + rowid + " is editing.");
}
},
cancelParams: {
key: true,
oneditfunc: function (rowid) {
//alert("row with rowid=" + rowid + " cancel.");
}
}
});
});
</script>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Controller Layer Code
public class SeminarController : Controller
{
ISeminarListDetailRepository seminarRepository;
//
// Dependency Injection enabled constructors
public SeminarController()
: this(new SeminarListDetailRepository()) {
}
public SeminarController(ISeminarListDetailRepository repository)
{
seminarRepository = repository;
}
/// <summary>
/// Just for Listing page.
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
return View();
}
/// <summary>
/// Master Detail CRUD form according to previous form's choosen code.
/// </summary>
/// <param name="Seminar_Code"></param>
/// <returns></returns>
public ActionResult DetailByCode(string Seminar_Code)
{
return View();
}
/// <summary>
/// Master Detail CRUD form.
/// </summary>
/// <returns></returns>
public ActionResult Detail()
{
var SeminarListDetailViewModel = new SeminarListDetailViewModel();
return View(SeminarListDetailViewModel);
}
/// <summary>
/// It is this method what I really focus when it comes to save all rows of jqgrid at once.
/// </summary>
/// <param name="Seminar"></param>
/// <param name="Seminar_Details"></param>
/// <returns></returns>
[HttpPost]
public ActionResult Detail(Seminar Seminar, List<Seminar_Detail> Seminar_Details)
{
return View();
}
/// <summary>
/// Just for test purpose only.
/// I will not use this method when I know how to save JQGrid's All Rows at once.
/// </summary>
/// <param name="Seminar_Detail"></param>
/// <returns></returns>
public ActionResult MyEdit(Seminar_Detail Seminar_Detail)
{
//var seminar_Code = Seminar_Detail.Seminar_Code;
var jsonData = new
{
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
public ActionResult GetAllSpeakers()
{
string AllSpeakers = " : ;";
var Speakers = seminarRepository.GetAllSpeakerList().Seminar_Item_Speaker;
for (int i = 0; i < Speakers.Count; i++)
{
if (i == Speakers.Count - 1)
{
///For the last row
AllSpeakers += Speakers[i].SpeakerID + ":" + Speakers[i].SpeakerName;
}
else
{
AllSpeakers += Speakers[i].SpeakerID + ":" + Speakers[i].SpeakerName + ";";
}
}
return Json(AllSpeakers, JsonRequestBehavior.AllowGet);
}
public JsonResult GetAllTags()
{
string AllTags = " : ;";
var Tags = seminarRepository.GetAllTagList().Seminar_Item_Tag;
for (int i = 0; i < Tags.Count; i++)
{
if (i == Tags.Count - 1)
{
///For the last row
AllTags += Tags[i].TagID + ":" + Tags[i].TagName;
}
else
{
AllTags += Tags[i].TagID + ":" + Tags[i].TagName + ";";
}
}
return Json(AllTags, JsonRequestBehavior.AllowGet);
}
public ActionResult DetailGridData(string sidx, string sord, int page, int rows)
{
int currentPage = Convert.ToInt32(page) - 1;
int totalRecords = 0;
var SeminarList = seminarRepository.GetSeminarDetail("CMP04").Seminar_Detail; //OrderBy(x => x.Seminar_Code).Skip(page * rows).Take(rows).ToList();
var totalPages = (int)Math.Ceiling(totalRecords / (float)rows);
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = (
from s in SeminarList
select new
{
id = s.Seminar_Code + "__" + s.SpeakerID + "__" + s.TagID,
cell = new object[]
{
s.Seminar_Code,
s.SpeakerID,
s.TagID,
s.DateAndTime
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
public ActionResult ListingGridData(string sidx, string sord, int page, int rows)
{
int currentPage = Convert.ToInt32(page) - 1;
int totalRecords = 0;
var SeminarList = seminarRepository.AllSeminarList().Seminar_Masters; //OrderBy(x => x.Seminar_Code).Skip(page * rows).Take(rows).ToList();
var totalPages = (int)Math.Ceiling(totalRecords / (float)rows);
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = (
from s in SeminarList
select new
{
id = s.Seminar_Code,
cell = new object[]
{
s.Seminar_Code,
s.Title,
s.Description,
s.Room
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
}
Updated 2
Please let me make my question more clear.
I have two tables to insert data at once.
1.SeminarMaster(Seminar_Code, Title, Description, Room)
[At Razor View] - Form Input Fields
2.SeminarDetail(Seminar_Code, SpeakerID, TagID, DateAndTime)
[At Razor View] - JQGrid Rows and Columns
These two tables are in one-to-many relationship.
Update 3
I am really sorry for making my question unclear again and again.
Now please read my update again.I tried my best to make you clear understand my question.
Index.cshtml Or First time display form which user can select any row and go to detail page to make update.But Actually, below razor is not complete yet. Because I need to add Edit buttons at every rows of jqgrid. That Edit button will redirect to another page that I called Detail.cshtml by parsing selected Code. I will update it later. It is not my main problem.
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Seminar List</h2>
<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pager" class="scroll" style="text-align:center;"></div>
#Html.ActionLink("Click here", "Detail") to add new data.
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery("#list").jqGrid({
url: '/Seminar/ListingGridData/',
editurl: "/Seminar/MyEdit/",
datatype: 'json',
mtype: 'GET',
colNames: ['Seminar_Code', 'Title', 'Description', 'Room'],
colModel: [
{ name: 'Seminar_Code', index: 'Seminar_Code', width: 40, align: 'left', editable: false },
{ name: 'Title', index: 'Title', width: 40, align: 'left', editable: false },
{ name: 'Description', index: 'Description', width: 40, align: 'left', editable: false },
{ name: 'Room', index: 'Room', width: 40, align: 'left', editable: false }
],
pager: jQuery('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
sortname: 'Title',
sortorder: "asc",
viewrecords: true,
autowidth: true,
autoheight: true,
caption: 'Seminar List - Grid'
})
});
</script>
Every suggestion will be appreciated.
Related
I needed to create a search page where various types of text, dropdown, date field will be there. i added onkeyup function to every text field so that whenever i put any text or number a grid will appear with subgrid. The issue i am facing is if i give input for the first time then the grid appear with correct data. if i clear that field then the grid is reloading also but if i input again in that field or any other text field then the js is not sending request to the action method with updated post value.
Here is my View Part:
<section class="content">
<div class="container-fluid">
<!-- SELECT2 EXAMPLE -->
<!-- SELECT2 EXAMPLE -->
<div class="card card-info">
<div class="card-header">
<h3 class="card-title">Search Criteria</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
</div>
</div>
<!-- /.card-header -->
#using (Html.BeginForm("SearchReport", "LRLiveSearch", FormMethod.Post))
{
<div class="card-body">
<div class="row">
<div class="col-md-12" style="line-height:1.50px;">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Deed No</label>
#Html.TextBoxFor(model => model.DeedNo, new { #class = "form-control", onkeyup = "LiveSearch('DN', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Deed Identity</label>
#Html.TextBoxFor(model => model.DeedId, new { #class = "form-control", onkeyup = "LiveSearch('DI', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Client Name</label>
#Html.TextBoxFor(model => model.ClientName, new { #class = "form-control", onkeyup = "LiveSearch('CN', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Client Contact Number</label>
#Html.TextBoxFor(model => model.ClientPhoneNumber, new { #class = "form-control", onkeyup = "LiveSearch('CP', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>MR No</label>
#Html.TextBoxFor(model => model.MRNo, new { #class = "form-control", onkeyup = "LiveSearch('MR', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Cheque No</label>
#Html.TextBoxFor(model => model.ChequeNo, new { #class = "form-control", onkeyup = "LiveSearch('CQN', this.value)" })
</div>
</div>
</div>
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Collection Type</label>
#Html.DropDownListFor(model => model.CollectionType, Model.CollectionTypeList, new { #class = "form-control" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>From Date</label>
<div class="input-group date" id="FirstDate" data-target-input="nearest">
#Html.TextBoxFor(model => model.FromDate, new { #class = "form-control datetimepicker-input", #data_target = "#FirstDate" })
<div class="input-group-append" data-target="#FirstDate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>To Date</label>
<div class="input-group date" id="SecondDate" data-target-input="nearest">
#Html.TextBoxFor(model => model.ToDate, new { #class = "form-control datetimepicker-input", #data_target = "#SecondDate" })
<div class="input-group-append" data-target="#SecondDate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
#*<div class="col-md-1">
<div class="form-group">
<center>
<button id="btnLRSearch" formaction="SearchList" class="btn btn-md btn-primary" style="margin-top:.80rem" type="button">Search</button>
</center>
</div>
</div>
<div class="col-md-1">
<div class="form-group">
<center>
<button id="btnPrint" formaction="SearchReport" class="btn btn-md btn-warning" style="margin-top:.80rem" type="submit">Report</button>
</center>
</div>
</div>*#
</div>
</div>
</div>
</div>
}
</div>
</div>
<!-- /.container-fluid -->
<table class="table table-bordered table-striped table-hover text-nowrap text-sm" id="Demogrid"></table>
<div class="container-fluid" id="pager"></div>
</section>
here is my JS part where i handled onkeyup event:
function LiveSearch(type, value) {
var searchType = type;
var searchValue = value;
if (value == "" || value == null) {
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
else {
$("#Demogrid").jqGrid({
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
colNames: ['ProjectName', 'PlotName', 'TotalLandArea', 'DeedId', 'DeedDate', 'RentFeeType', 'RentFee', 'ClientName', 'ClientAddress', 'ClientContactNo', 'EffectiveDate'],
//colModel takes the data from controller and binds to grid
colModel: [
{ name: "ProjectName" },
{ name: "PlotName" },
{ name: "TotalLandArea" },
{ name: "DeedId" },
{ name: "DeedDate" },
{ name: "RentFeeType" },
{ name: "RentFee" },
{ name: "ClientName" },
{ name: "ClientAddress" },
{ name: "ClientContactNo" },
{ name: "EffectiveDate" }
],
height: '100%',
viewrecords: true,
caption: 'Deed Info',
emptyrecords: 'No records',
rowNum: 10,
pager: jQuery('#pager'),
rowList: [10, 20, 30, 40],
jsonReader:
{
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
postData: {
Type: searchType,
SearchValue: searchValue
},
autowidth: true,
subGrid: true,
subGridRowExpanded: function (subgridId, rowId) {
// create the subgrid HTML here
var subgridTableId = subgridId + "_t";
$("#" + subgridId).html("<table id='" + subgridTableId + "'></table>");
// get the data for the parent row
var parentRowData = $("#Demogrid").jqGrid("getRowData", rowId);
// retrieve the primary key value of the parent row
var parentId = parentRowData.DeedId;
$("#" + subgridTableId).jqGrid({
// configure the subgrid
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
colNames: ['CollectionId', 'CollectionDate', 'MRIdentity', 'MRNo', 'MRDate', 'MRType', 'CollectionType', 'ChequeNo', 'BankName'],
//colModel takes the data from controller and binds to grid
colModel: [
{ name: "CollectionId", hidden: true },
{ name: "CollectionDate" },
{ name: "MRIdentity" },
{ name: "MRNo" },
{ name: "MRDate" },
{ name: "MRType" },
{ name: "CollectionType" },
{ name: "ChequeNo" },
{ name: "BankName" }
],
height: '100%',
viewrecords: true,
caption: 'Collection Details',
emptyrecords: 'No records',
rowNum: 10,
jsonReader: {
repeatitems: false
},
postData: {
Type: searchType,
SearchValue: searchValue,
DeedId: parentId
},
autowidth: true
});
},
}).navGrid('#pager',
{
edit: true,
add: true,
del: true,
search: true,
refresh: true,
closeAfterSearch: true
});
}
}
and it is my action method:
public JsonResult LiveSearch(string sord, int page, int rows, string searchString, string Type, string SearchValue, string DeedId)
{
if(SearchValue == "")
{
SearchValue = "$";
}
var query = iLRSearchRepository.LiveSearchFilter(Type, SearchValue);
if (DeedId == null)
{
//#2 Setting Paging
int pageIndex = Convert.ToInt32(page) - 1;
int pageSize = rows;
//#3 Linq Query to Get Data
var Results = query.Select(
x => new
{
ProjectName = x.ProjectName,
PlotName = x.PlotName,
TotalLandArea = x.TotalLandArea,
DeedId = x.DeedId,
DeedDate = x.DeedDate.ToString("dd/MM/yyyy"),
RentFeeType = x.RentFeeType,
RentFee = x.RentFee,
ClientName = x.ClientName,
ClientAddress = x.ClientsAddress,
ClientContactNo = x.ClientsContactNo,
EffectiveDate = x.ActivateDate.ToString("dd/MM/yyyy")
}).Distinct();
//#4 Get Total Row Count
int totalRecords = Results.Count();
var totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
//#5 Setting Sorting
if (sord.ToUpper() == "DESC")
{
Results = Results.OrderByDescending(s => s.DeedId);
Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
}
else
{
Results = Results.OrderBy(s => s.DeedId);
Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
}
//#6 Setting Search
if (!string.IsNullOrEmpty(searchString))
{
Results = Results.Where(m => m.DeedId == searchString);
}
//#7 Sending Json Object to View.
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = Results
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
else
{
var Results = query.Where(x => x.DeedId == DeedId).Select(
x => new
{
CollectionId = x.CollectionId,
CollectionDate = x.CollectionDate?.ToString("dd/MM/yyyy"),
MRIdentity = x.MRIdentity,
MRNo = x.MRNo,
MRDate = x.MRDate?.ToString("dd/MM/yyyy"),
MRType = x.MRType,
CollectionType = x.CollectionType,
ChequeNo = x.ChequeNo,
BankName = x.BankName,
});
var jsonData = new
{
rows = Results
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
//model.landRent_View_SearchInfos = query;
//return View("_LandRentInfoList", model);
}
With your code you every time try create jqGrid when you do a search, which of course is not allowed since the grid is already created.
if (value == "" || value == null) {
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
else {
$("#Demogrid").jqGrid({}...)
}
To solve the problem first create the grid and the do a reload when the value changes
$("#Demogrid").jqGrid({
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
...
});
function LiveSearch(type, value) {
var searchType = type;
var searchValue = value;
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
Hope this helps.
Initially you can set values (postData) so that the grid return empty data or create the grid with empty local data (datatype : local) and then change the datatype to json.
I am getting this error when passing parameter to the datatable jQuery.
If I changed my controller to this
public ActionResult GetUsers(int divisionId)
with out parameter it work fine but I need to pass the parameter.
DataTables warning: table id=users - Ajax error. For more information about this error, please see http://datatables.net/tn/7
here is my view
<div>
<div class="row row-xs align-items-center mg-b-20">
<div class="col-md-4">
<label class="form-label mg-b-0">Division</label>
</div>
<div class="col-md-8 mg-t-5 mg-md-t-0">
<select id="selection" class="form-control select-group">
<option value="0">-- Select User --</option>
#foreach (var user in Model.divisions)
{
<option value="#user.DivisionID">#(user.DivisionName)</option>
}
</select>
</div>
</div>
<div class="table-responsive">
<table id="users" class="table table-striped text-md-nowrap">
<thead>
<tr>
<th>User ID</th>
<th>Employee ID</th>
<th>Username</th>
<th>Email</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
</div>
Controller
public ActionResult GetUsers(int divisionId)
{
int pageSize = 0, skip = 0;
string orderBy = "", draw = "", search = "";
Utility.SetDataTableValues(Request, out draw, out orderBy, out search, out pageSize, out skip);
int recordsTotal = 0;
List<UserPartial> usersList = new List<UserPartial>();
usersList = UserBL.GetUsersByDivision(pageSize, skip, out recordsTotal,2, search);
return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = usersList }, JsonRequestBehavior.AllowGet);
}
and the script:
$(function () {
$("#selection").on('change', function () {
var table = $('#users').DataTable();
table.destroy();
$("#users").show();
var divisionId = $("#selection option:selected").val();
var url = '/AssignHod/GetUsers/';
table = $('#users').DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"orderMulti": false,
"destroy": true,
"ordering": true,
"ajax": {
"url": '#Url.Action("GetUsers", "AssignHod")',
"type": "POST",
"datatype": "json"
},
"columns":
[
{
"data": "UserID"
},
{
"data": "EmployeeId"
},
{
"data": "Username"
},
{
"data": "Email"
},
{
"render": function (data, type, row, meta) {
var html = "";
//if (row.canEdit) {
if (row.isHOD) {
html += '<a title="Mark as User" href="/AssignHoD/deactivate/' + row.UserID + '" class="btn btn-sm waves-effect waves-light btn-outline-info"><i class="fa fa-toggle-off"></i></a>';
}
else if (!row.isHOD) {
html += '<a title="Mark as H.O.D" href="/AssignHoD/activate/' + row.UserID + '" class="btn btn-sm waves-effect waves-light btn-outline-info"><i class="fa fa-toggle-on"></i></a>';
}
return html;
}
}
]
,
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (aData[0]) {
}
}
});
});
});
I add attribute route before ActionResult and its now working.
[Route("AssignHoD/GetUsers/{Id}")]
public ActionResult GetUsers(int Id)
{
}
This is my ViewComponet:
#model X.PagedList.PagedList<CbWebApp.DTOs.UsuarioDTO>
#using X.PagedList.Mvc.Core
#using X.PagedList.Mvc.Common
//.....more code
<div class="pagination-sm text-center">
Página #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) de
#Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("ListaUsuario", new { page = page }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new PagedListRenderOptions { Display = PagedListDisplayMode.IfNeeded, MaximumPageNumbersToDisplay = 5 }, new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "Get", UpdateTargetId = "usuariosPartial" }))
</div>
// more code....
My partialView that has the ViewComponent to be rendered and the DIV of reference:
<div id="usuariosPartial" class="col-xs-12 col-md-12">
#await Component.InvokeAsync("Usuario")
</div>
Maybe I can get the X.PagedList HTML id for JQuery for instance something like that:
// is this the correct id?
$("#pagesizelist").change(function (event) {
I tried that id but with no success. :(
Well, I found this solution but I am not sure if is the best approach:
JQuery - Give an ID to your table tr tag and reference it on the click event of an 'a' tag in jQuery as follows:
$('#replaceMyTr').on('click', 'a', function (e) {
e.preventDefault();
$("#icon").hide();
$("#progress").show();
$("#msg").hide();
$('input, button, a').disable(true);
var IdDoPerfilDoUsuario;
var este = $(this);
function getUrlVars() {
var vars = [], hash;
var hashes = este.attr("href").slice(este.attr("href").indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
var page = getUrlVars()["page"];
if ($("select option:selected").first().val() === "--Todos--") {
IdDoPerfilDoUsuario = 0;
}
else {
IdDoPerfilDoUsuario = $("select option:selected").first().val();
}
$("#usuariosPartial").hide();
este.attr('disabled', 'disabled');
$.ajax({
url: "/Usuario/ListaUsuario",
type: 'GET',
cache: false,
data: { IdDoPerfilDoUsuario: IdDoPerfilDoUsuario, page: page },
success: function (result) {
$("#icon").show();
$("#progress").hide();
$("#msg").show();
$('input, button, a').disable(false);
$("#usuariosPartial").show();
$('#usuariosPartial').html(result);
}
});
return false;
});
View code:
// more code...
<tfoot>
<tr id="replaceMyTr">
#*<td colspan="7">*#
<td>
<div class="pagination-sm text-center">
#Html.PagedListPager((IPagedList)Model.Usuarios.ToEnumerable(), page => Url.Action("ListaUsuario", new { page = page }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new PagedListRenderOptions { Display = PagedListDisplayMode.IfNeeded, MaximumPageNumbersToDisplay = 5 }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "teste" }))
</div>
</td>
</tr>
</tfoot>
//....more code
I am using WebGrid in my MVC project and I want to add a context menu on right click (on row click) in that WebGrid. So, could anyone please help me how to add a context menu in my webgrid and on selection of a context menu item, how to retrieve the id? Following is the code of more detail:
#using (Html.BeginForm("save", "Inventory"))
{
var grid = new WebGrid(Model.products, canSort: false, canPage: true, rowsPerPage: 3);
int rowNum = 0;
<div>
#grid.GetHtml(tableStyle: "webGrid", alternatingRowStyle: "alt", headerStyle: "header",
selectedRowStyle: "select",
columns: grid.Columns
(
grid.Column("RowNumber", format: item => rowNum = rowNum + 1, style: "rowno"),
grid.Column("Id",
format: (item) => Html.TextBox("products[" + (rowNum - 1).ToString() + "].Id",
(object)item.Id, new { #readonly = "readonly" }),
style: "id"),
grid.Column("Name", format: (item) => Html.TextBox("products[" + (rowNum - 1).ToString() + "].Name", (object)item.Id), style:"name"),
grid.Column("Description", format: (item) => Html.TextBox("products[" + (rowNum - 1).ToString() + "].Description", (object)item.Description), style: "desc"),
grid.Column("Quantity", format: (item) => Html.TextBox("products[" + (rowNum - 1).ToString() + "].Quantity", (object)item.Quantity), style: "qty"),
grid.Column("QualityType", format: #item => Html.DropDownList("products[" + (rowNum - 1).ToString() + "].QualityType", (IEnumerable<SelectListItem>)Model.products[rowNum - 1].QualityTypeModel), style: "qlty")
), mode: WebGridPagerModes.Numeric)
</div>
<input type="submit" value="Submit">
}
Recently I implemented a similar task, using jQuery Context Menu.
Here is the result
#{
#model IEnumerable<TestWebGirdContextMenu.Models.User>
}
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.4.3/jquery.contextMenu.min.css" rel="stylesheet" type="text/css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.4.3/jquery.contextMenu.min.js" type="text/javascript"></script>
<div class="container">
<h2>WebGrid Context Menu</h2>
<div class="row">
<div class="col-lg-12">
#{
var grid = new WebGrid(Model);
}
#grid.GetHtml(htmlAttributes: new { id = "webGrid" })
</div>
</div>
</div>
<script>
$(function () {
$.contextMenu({
selector: "#webGrid tbody tr",
callback: function (key, options) {
var m = "clicked: " + key;
window.console && console.log(m) || alert(m);
},
items: {
"edit": { name: "Edit", icon: "edit" },
"cut": { name: "Cut", icon: "cut" },
"copy": { name: "Copy", icon: "copy" },
"paste": { name: "Paste", icon: "paste" },
"delete": { name: "Delete", icon: "delete" },
"sep1": "---------",
"quit": {
name: "Quit", icon: function () {
return 'context-menu-icon context-menu-icon-quit';
}
}
}
});
$('.context-menu-one').on('click', function (e) {
console.log('clicked', this);
});
});
</script>
</body>
Demo jQuery Context Menu
I am new to C# and ASP.NET MVC and specially views.
I have the following problem
I have this code
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult ManageEmployee(int cntID, string command)
{
//repository = new ContactRepository();
cntadrRepository = new ContactAddressCountryRepository();
//addressRepository = new AddressRepository();
if (!String.IsNullOrEmpty(command) && command.Equals("edit"))
{
var cdrcnts = cntadrRepository.GetById(cntID);
ViewBag.IsUpdate = true;
//return View("_ManageEmployee", cdrcnts);
return View("Index", cdrcnts);
//return View("Index");
}
else
{
ViewBag.IsUpdate = false;
//return View("_ManageEmployee");
return View("Index");
}
}
that returns my form empty when I click on Add button
when I click on Add I get the form slide in and the grid slide out and I can enter a new record and then after clicking on save I return to my grid with the new record.
Now the problem is When I click on Edit I have the view with only an Add button that when I click on I get the result that I want to get, directly, when I click on Edit which is the form filled with the required information
I think that I have a problem when I return the view.
What I want is that I return that form populated with the contact information when I click on Edit and stay in the same page that shows again the grid and the edited record and not have that empty page with the Add button that I need to click on again to have the required result.
Thank you for your help.
<script type="text/javascript">
$.ig.loader({
scriptPath: './js/',
cssPath: './css/',
resources: 'igGrid.*',
ready: function () {
$.getJSON("Home/GetAll", null, function (data) {
var headerTextValues = ["Relation to Will maker", "First Name", "Last Name","","",""];
$('#employeeGrid').igGrid({
expandCollapseAnimations: true,
animationDuration: 1000,
expandTooltip: "Expand to View Details",
collapseTooltip: "Hide details",
height: "400px",
width: "800px",
dataSource: data,
responseDataKey: "Records",
//dataSourceType: "json",
autoGenerateLayouts: false,
autoGenerateColumns: false,
rowEditDialogContainment: "owner",
showReadonlyEditors: false,
columns: [
{ headerText: headerTextValues[0], key: "cntID", width: 200 },
{ headerText: headerTextValues[1], key: "cntFirstName", width: 175 },
{ headerText: headerTextValues[2], key: "cntLastName", width: 175 },
//{ headerText: headerTextValues[3], key: "Age", width: 175 },
{ headerText: headerTextValues[4], key: "UpdateRow", width: 110, template: "<a href='Home/ManageEmployee?cntID=${cntID}&command=edit' class='editDialog'>Edit</a>" },
{ headerText: headerTextValues[5], key: "DeleteRow", width: 50, template: "<a href='Home/Delete?cntID=${cntID}' class='confirmDialog'><button>Delete</button></a>" },
],
initialDataBindDepth: -1,
primaryKey: 'cntID',
width: '800',
updateURL: "Home/Update",
/*columnLayouts: [
{
key: "cntD",
responseDataKey: "Records",
autoGenerateColumns: false,
autoGenerateLayouts: false,
generateCompactJSONResponse: false,
primaryKey: "cntID",
foreignKey: "cntAddressID",
columns: [
{ key: "cntId", headerText: "Address Id", width: "150px" },
{ key: "cntAddressID", headerText: "Address", width: "150px" },
//{ key: "Street", headerText: "Street", width: "150px" },
//{ key: "City", headerText: "City", width: "150px" },
//{ key: "Zip", headerText: "Zip", width: "150px" }
]
}
],*/
features: [
{
name: "Selection",
mode: "row",
multipleSelection: false
},
{
name: 'Hiding'
},
{
name: 'Paging',
type: 'local',
pageSize: 10,
inherit: true
},
{
name: 'Filtering'
},
{
name: "ColumnMoving",
mode: "immediate",
//columnDragStart: function (event, ui) {
// ui.owner.element.find('tr td:nth-child(' + (ui.columnIndex + 1) + ')').addClass("ui-state-moving");
// colMovingKey = ui.columnKey;
//},
//columnDragEnd: function (event, ui) {
// var grid = $(event.target).data('igGrid');
// var newindex = grid.options.columns.indexOf(grid.columnByKey(colMovingKey)) + 1;
// grid.element.find('tr td:nth-child(' + newindex + ')').removeClass("ui-state-moving");
//},
addMovingDropdown: true,
mode: "deferred",
type: "render"
}
],
});
});
}
});
$(document).ready(function () {
$.ajaxSetup({ cache: false });
$(".editDialog").live("click", function (e) {
e.preventDefault();
var url = $(this).attr('href');
$("#dialog-edit").load(url);
$("#dialog-edit").toggle("slide");
});
$("#openDialog").live("click", function (e) {
e.preventDefault();
var url = $(this).attr('href');
$("#dialog-create").load(url);
$("#dialog-create").toggle("slide");
})
});
</script>
#section featured {
<section class="featured">
<div class="overlap">
<div class="content-wrapper">
<!-- the igHierarchicalGrid target element-->
<table id="employeeGrid" style="width: auto;"></table>
<p>
<a id='openDialog' href='Home/ManageEmployee?cntID=0&command=create' class='openDialog ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only' style="color: white;">Add Employee</a>
</p>
<div id="btn">
<button id="add">Add</button>
</div>