I am dynamically adding columns to a Web-grid using MVC-5 and C# and when the grid renders everything looks fine but the column headers won't function as an action Links. There are two versions of the code and both render but don't function as Action Links.
Thank you for your help.
cols.Add(grid.Column(Model.DictionaryList[i].Keys.ElementAt(i).ToString(), Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
format: #<Text>#Html.ActionLink((string)Model.DictionaryList[i].Values.ElementAt(i).ToString(), "Select_MSPart_Search",
"MaterialSupply", new
{
id = ViewData["id"],
type = 1,
SearchFilter = Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
SearchValue = "",
rowsPerPage = 7
})</Text>, style: "column-action"));
cols.Add(grid.Column(header: Model.DictionaryList[i].Keys.ElementAt(i).ToString(),columnName: Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
format: (item) => new HtmlString(Html.ActionLink((string)Model.DictionaryList[i].Values.ElementAt(i).ToString(), "Select_MSPart_Search",
"MaterialSupply", new
{
id = ViewData["id"],
type = 1,
SearchFilter = Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
SearchValue = "",
rowsPerPage = 7
},null).ToHtmlString()), style: "column-action"));
Everything seems to render correctly except the column headers are not Action Links as I had hoped for. I also tried the second piece of code with the same results.
Thank you for your help.
I realized that seeing the entire view would be critical because I am building the grid dynamically.
#using System.Dynamic
#using System.Linq
#using System.Data.Common
#using CeleroPortal.Models.ConstraintsAnalysis
#using System.Collections.Generic
#using System.Web.Mvc.Html
#using System.Web.Mvc.Razor
#model mdlViews
#using PagedList.Mvc
#{
ViewBag.Title = "View Report records Page";
var result = new List<dynamic>();
int rowcnt = 0;
foreach (var recRow in Model.DlList)
{
var row = (IDictionary<string, object>)new ExpandoObject();
Dictionary<string, object> eachFieldRow = (Dictionary<string, object>)recRow; //for when list was string,object
foreach (KeyValuePair<string, object> keyValuePair in eachFieldRow)
{
row.Add(keyValuePair.Key, keyValuePair.Value);
}
result.Add(row);
rowcnt++;
}
//WebGrid grid = new WebGrid(source: result, rowsPerPage: Model.PageSize, canPage: true, canSort: true, sortFieldName: Model.Sort, sortDirectionFieldName: Model.SortDir);
WebGrid grid = new WebGrid(rowsPerPage: Model.PageSize, canPage: true, canSort: false, sortFieldName: Model.Sort, sortDirectionFieldName: Model.SortDir);
List<WebGridColumn> cols = new List<WebGridColumn>();
cols.Add(grid.Column("Order ID","Order ID"));
cols.Add(grid.Column("Part ID", "Part ID"));
cols.Add(grid.Column("Description", "Description"));
cols.Add(grid.Column("Customer ID", "Customer ID"));
cols.Add(grid.Column("Customer", "Customer"));
cols.Add(grid.Column("Qty Due", "Quantity Due"));
cols.Add(grid.Column("Target Date", "Target Date"));
cols.Add(grid.Column("Days", "Days"));
cols.Add(grid.Column("Final Date", "Final Date"));
for (int i = 9; i < Model.DictionaryList[0].Count(); i++)
{
if (Model.DictionaryList[0].Keys.ElementAt(i).StartsWith("#"))
{
cols.Add(grid.Column(Model.DictionaryList[0].Keys.ElementAt(i).ToString(), Model.DictionaryList[0].Keys.ElementAt(i).ToString()));
}
else
{
//cols.Add(grid.Column(Model.DictionaryList[i].Keys.ElementAt(i).ToString(),header: Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
// format: (Model) => Html.ActionLink((string)Model.DictionaryList[i].Values.ElementAt(i).ToString(), "Select_MSPart_Search",
// "MasterSupply",new { id = ViewData["id"] , type = 1, SearchFilter = Model.DictionaryList[i].Keys.ElementAt(i).ToString() , SearchValue = "",
// rowsPerPage = 7}),style: "column-action"));
cols.Add(grid.Column(header:Model.DictionaryList[i].Keys.ElementAt(i).ToString(),columnName: Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
format: #<Text>#Html.ActionLink((string)Model.DictionaryList[i].Values.ElementAt(i).ToString(), "Select_MSPart_Search",
"MaterialSupply", new
{
id = ViewData["id"],
type = 1,
SearchFilter = Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
SearchValue = "",
rowsPerPage = 7
})</Text>, style: "column-action"));
//cols.Add(grid.Column(header: Model.DictionaryList[i].Keys.ElementAt(i).ToString(),columnName: Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
// format: (item) => #Html.ActionLink((string)Model.DictionaryList[i].Values.ElementAt(i).ToString(), "Select_MSPart_Search",
// "MaterialSupply", new
// {
// id = ViewData["id"],
// type = 1,
// SearchFilter = Model.DictionaryList[i].Keys.ElementAt(i).ToString(),
// SearchValue = "",
// rowsPerPage = 7
// }, null)));
}
}
grid.Bind(result, rowCount: Model.TotalRecords, autoSortAndPage: true);
grid.Pager(WebGridPagerModes.All);
}
<style type="text/css">
.webgrid-table {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
font-size: 1.2em;
width: 100%;
display: table;
border-collapse: separate;
border: solid 1px #000066; /*#98BF21;*/
background-color: white;
}
.webgrid-table td, th {
border: 1px solid #000099; /*#98BF21;*/
padding: 3px 7px 2px;
}
.webgrid-header {
background-color: #b3d9ff; /*#A7C942;*/
color: #FFFFFF;
padding-bottom: 4px;
padding-top: 5px;
text-align: left;
}
.webgrid-footer {
}
.webgrid-row-style {
padding: 3px 7px 2px;
}
.webgrid-alternating-row {
background-color: #e6f2ff; /*#EAF2D3;*/
padding: 3px 7px 2px;
}
.webgrid-selected-row {
background-color: #ffff66; /*#EAF2D3;*/
padding: 3px 7px 2px;
}
</style>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<div class="jumbotron">
<h1><img src="~/Images/Celero.png" /></h1>
<p class="lead">Constraints Analysis Application Pushed Orders Grid</p>
<div>
#Html.ActionLink("Search for Part across reports", "Select_MSPart", "MaterialSupply", new { id = ViewData["Id"].ToString(), type = ViewData["type"]},null)
</div>
</div>
<div class="row">
#using (Html.BeginForm("Views", "ConstraintsAnalysis", new { id = ViewData["id"], type = ViewData["type"] }, FormMethod.Post))
{
<div class="row">
<div class="form-horizontal" style="float: left">
<div class="col-md-4">
#if (Model.RwsPrPge == Model.TotalRecords)
{
<select id="rwsPrPge" name="rwsPrPge">
<option value="5">50</option>
<option value="0">All</option>
</select>
}
else
{
<select id="rwsPrPge" name="rwsPrPge">
<option value="0">All</option>
<option value="5">50</option>
</select>
}
<input type="submit" value="Rows/Page" />
#Html.Hidden("id", (object)ViewData["Id"].ToString())
#Html.Hidden("type", (object)ViewData["type"].ToString())
</div>
<div class="col-lg-4">
#*#Html.DropDownListFor(Model => Model.SearchFilter, new SelectList(ViewBag.SelectFilter, "Value", "Text"),
"Select Part for Search", new { #class = "form-control", #placeholder = "Search Filter" })*#
#Html.DropDownList("m", new SelectList(ViewBag.SelectFilter, "Value", "Text"), "Select Part")
</div>
<div class="col-lg-4" float="right">
<button type="submit" class="btn btn-success" value="m">
<span class="glyphicon glyphicon-search"></span>
</button>
</div>
<br /><br />
<div class="col-md-4">
<select id="Export" name="Export">
<option value="00">No Export</option>
<option value="XX">Export to CSV</option>
#Html.EditorFor(model => model.DlList)
#Html.ValidationMessageFor(model => model.DlList)
</select>
</div>
<div class="col-md-4">
<button type="submit" class="btn btn-success" value="Export" href="/ConstraintsAnalysis/Views">
<span class="glyphicon glyphicon-export"></span>
</button>
</div>
</div>
</div>
if (Model != null)
{
<span>
<span class="vam" style="float: left">
#Html.ActionLink("Report Selection Menu", "Index", "ConstraintsAnalysis")
</span>
<span class="vam">
#grid.GetHtml(tableStyle: "table table-bordered table-hover",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
caption: "Celero Constraints Grid",
rowStyle: "webgrid-row-style");
</span>
</span>
}
}
</div>
I found the problem. I forgot the columns: cols on the #grid.GetHtml.
Thank you
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'm creating a web site, where I have a list of classes, and I want that each class will have it`s own calendar. What I mean is, when I click button 1, I will go to a separate calendar then button 2 and so on.
I already have a working calendar, I just don't understand how assign to each button a calendar.
So I have a working calendar with options of add/delete/update events, but I don't understand how to connect them.
I'm on this problem over a week now, and I couldn't find any solution. help please.
This is the index.cshtml where the classes are created: (classes view)
#model IEnumerable<ClasSaver.Models.ClassesModel>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<style>
.button {
background-color: deepskyblue; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
}
</style>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Building)
</th>
<th>
#Html.DisplayNameFor(model => model.How_Many_In_Class)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Building)
</td>
<td>
#Html.DisplayFor(modelItem => item.How_Many_In_Class)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
<input id="#item.Id" type="button" onclick="parent.open('https://www.google.com/')" value="Open in new window" class="button">
</td>
</tr>
}
</table>
<script>
</script>
and the controller
using ClasSaver.Data;
using ClasSaver.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ClasSaver.Controllers
{
public class ClassesController : Controller
{
// GET: Classes
public ActionResult Index()
{
List<ClassesModel> classes = new List<ClassesModel>();
ClassDAO classDao = new ClassDAO();
classes = classDao.FetchAll();
return View("Index",classes);
}
public ActionResult Details(int id)
{
ClassDAO classesDAO = new ClassDAO();
ClassesModel classes = classesDAO.FetchOne(id);
return View("Details", classes);
}
public ActionResult Create(ClassesModel classesModel)
{
return View("ClassesForm", classesModel);
}
[HttpPost]
public ActionResult ProcessCreate(ClassesModel classesModel)
{
//save to DB
ClassDAO classesDAO = new ClassDAO();
classesDAO.CreateOrUpdate(classesModel);
return View("Details", classesModel);
}
public ActionResult Edit(int id)
{
ClassDAO classesDAO = new ClassDAO();
ClassesModel classes = classesDAO.FetchOne(id);
return View("ClassesForm", classes);
}
public ActionResult Delete(int id)
{
ClassDAO classesDAO = new ClassDAO();
classesDAO.Delete(id);
List<ClassesModel> classes = classesDAO.FetchAll();
return View("Index", classes);
}
public ActionResult SearchForm()
{
return View("SearchForm");
}
[HttpPost]
public ActionResult searchForName(string searchPhrase)
{
ClassDAO classesDAO = new ClassDAO();
List<ClassesModel> searchResults = classesDAO.SearchForName(searchPhrase);
return View("Index", searchResults);
}
}
}
and this is where the calendar is created index.cshtml: (home view)
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="calender"></div>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><span id="eventTitle"></span></h4>
</div>
<div class="modal-body">
<button id="btnDelete" class="btn btn-default btn-sm pull-right">
<span class="glyphicon glyphicon-remove"></span> Remove
</button>
<button id="btnEdit" class="btn btn-default btn-sm pull-right" style="margin-right:5px;">
<span class="glyphicon glyphicon-pencil"></span> Edit
</button>
<p id="pDetails"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="myModalSave" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Save Event</h4>
</div>
<div class="modal-body">
<form class="form-horizontal">
<input type="hidden" id="hdEventID" value="0" />
<div class="form-group">
<label>Subject</label>
<input type="text" id="txtSubject" class="form-control" />
</div>
<div class="form-group">
<label>Start</label>
<div class="input-group date" id="dtp1">
<input type="text" id="txtStart" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<label><input type="checkbox" id="chkIsFullDay" checked="checked" /> Is Full Day event</label>
</div>
</div>
<div class="form-group" id="divEndDate" style="display:none">
<label>End</label>
<div class="input-group date" id="dtp2">
<input type="text" id="txtEnd" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<label>Description</label>
<textarea id="txtDescription" rows="3" class="form-control"></textarea>
</div>
<div class="form-group">
<label>Theme Color</label>
<select id="ddThemeColor" class="form-control">
<option value="">Default</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="black">Black</option>
<option value="green">Green</option>
</select>
</div>
<button type="button" id="btnSave" class="btn btn-success">Save</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>
</div>
</div>
</div>
</div>
<link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.css" rel="stylesheet" />
<link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.print.css" rel="stylesheet" media="print" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />
#section Scripts{
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script>
<script>
$(document).ready(function () {
var events = [];
var selectedEvent = null;
FetchEventAndRenderCalendar();
function FetchEventAndRenderCalendar() {
events = [];
$.ajax({
type: "GET",
url: "/home/GetEvents",
success: function (data) {
$.each(data, function (i, v) {
events.push({
eventID: v.EventID,
title: v.Subject,
description: v.Description,
start: moment(v.Start),
end: v.End != null ? moment(v.End) : null,
color: v.ThemeColor,
allDay: v.IsFullDay
});
})
GenerateCalender(events);
},
error: function (error) {
alert('failed');
}
})
}
function GenerateCalender(events) {
$('#calender').fullCalendar('destroy');
$('#calender').fullCalendar({
contentHeight: 400,
defaultDate: new Date(),
timeFormat: 'h(:mm)a',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay,agenda'
},
eventLimit: true,
eventColor: '#378006',
events: events,
eventClick: function (calEvent, jsEvent, view) {
selectedEvent = calEvent;
$('#myModal #eventTitle').text(calEvent.title);
var $description = $('<div/>');
$description.append($('<p/>').html('<b>Start:</b>' + calEvent.start.format("DD-MMM-YYYY HH:mm a")));
if (calEvent.end != null) {
$description.append($('<p/>').html('<b>End:</b>' + calEvent.end.format("DD-MMM-YYYY HH:mm a")));
}
$description.append($('<p/>').html('<b>Description:</b>' + calEvent.description));
$('#myModal #pDetails').empty().html($description);
$('#myModal').modal();
},
selectable: true,
select: function (start, end) {
selectedEvent = {
eventID: 0,
title: '',
description: '',
start: start,
end: end,
allDay: false,
color: ''
};
openAddEditForm();
$('#calendar').fullCalendar('unselect');
},
editable: true,
eventDrop: function (event) {
var data = {
EventID: event.eventID,
Subject: event.title,
Start: event.start.format('DD/MM/YYYY HH:mm A'),
End: event.end != null ? event.end.format('DD/MM/YYYY HH:mm A') : null,
Description: event.description,
ThemeColor: event.color,
IsFullDay: event.allDay
};
SaveEvent(data);
}
})
}
$('#btnEdit').click(function () {
//Open modal dialog for edit event
openAddEditForm();
})
$('#btnDelete').click(function () {
if (selectedEvent != null && confirm('Are you sure?')) {
$.ajax({
type: "POST",
url: '/home/DeleteEvent',
data: { 'eventID': selectedEvent.eventID },
success: function (data) {
if (data.status) {
//Refresh the calender
FetchEventAndRenderCalendar();
$('#myModal').modal('hide');
}
},
error: function () {
alert('Failed');
}
})
}
})
$('#dtp1,#dtp2').datetimepicker({
format: 'DD/MM/YYYY HH:mm A'
});
$('#chkIsFullDay').change(function () {
if ($(this).is(':checked')) {
$('#divEndDate').hide();
}
else {
$('#divEndDate').show();
}
});
function openAddEditForm() {
if (selectedEvent != null) {
$('#hdEventID').val(selectedEvent.eventID);
$('#txtSubject').val(selectedEvent.title);
$('#txtStart').val(selectedEvent.start.format('DD/MM/YYYY HH:mm A'));
$('#chkIsFullDay').prop("checked", selectedEvent.allDay || false);
$('#chkIsFullDay').change();
$('#txtEnd').val(selectedEvent.end != null ? selectedEvent.end.format('DD/MM/YYYY HH:mm A') : '');
$('#txtDescription').val(selectedEvent.description);
$('#ddThemeColor').val(selectedEvent.color);
}
$('#myModal').modal('hide');
$('#myModalSave').modal();
}
$('#btnSave').click(function () {
//Validation/
if ($('#txtSubject').val().trim() == "") {
alert('Subject required');
return;
}
if ($('#txtStart').val().trim() == "") {
alert('Start date required');
return;
}
if ($('#chkIsFullDay').is(':checked') == false && $('#txtEnd').val().trim() == "") {
alert('End date required');
return;
}
else {
var startDate = moment($('#txtStart').val(), "DD/MM/YYYY HH:mm A").toDate();
var endDate = moment($('#txtEnd').val(), "DD/MM/YYYY HH:mm A").toDate();
if (startDate > endDate) {
alert('Invalid end date');
return;
}
}
var data = {
Id: $('#hdEventID').val(),
Subject: $('#txtSubject').val().trim(),
Start: $('#txtStart').val().trim(),
End: $('#chkIsFullDay').is(':checked') ? null : $('#txtEnd').val().trim(),
Description: $('#txtDescription').val(),
ThemeColor: $('#ddThemeColor').val(),
IsFullDay: $('#chkIsFullDay').is(':checked')
}
SaveEvent(data);
// call function for submit data to the server
})
function SaveEvent(data) {
$.ajax({
type: "POST",
url: '/home/SaveEvent',
data: data,
success: function (data) {
if (data.status) {
//Refresh the calender
FetchEventAndRenderCalendar();
$('#myModalSave').modal('hide');
}
},
error: function () {
alert('Failed');
}
})
}
})
</script>
}
and the controller
using ClasSaver.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ClasSaver.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public JsonResult GetEvents()
{
using (ClassaverDBEntities2 dc = new ClassaverDBEntities2())
{
var events = dc.Events.ToList();
return new JsonResult { Data = events, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
[HttpPost]
public JsonResult SaveEvent(Event e)
{
var status = false;
using (ClassaverDBEntities2 dc = new ClassaverDBEntities2())
{
if (e.EventID > 0)
{
//Update the event
var v = dc.Events.Where(a => a.EventID == e.EventID).FirstOrDefault();
if (v != null)
{
v.Subject = e.Subject;
v.Start = e.Start;
v.End = e.End;
v.Description = e.Description;
v.IsFullDay = e.IsFullDay;
v.ThemeColor = e.ThemeColor;
}
}
else
{
dc.Events.Add(e);
}
dc.SaveChanges();
status = true;
}
return new JsonResult { Data = new { status = status } };
}
[HttpPost]
public JsonResult DeleteEvent(int eventID)
{
var status = false;
using (ClassaverDBEntities2 dc = new ClassaverDBEntities2())
{
var v = dc.Events.Where(a => a.EventID == eventID).FirstOrDefault();
if (v != null)
{
dc.Events.Remove(v);
dc.SaveChanges();
status = true;
}
}
return new JsonResult { Data = new { status = status } };
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}
Good Evening,
I'm trying to upload a file and when the form submits I just want to reload the partial view in the modal div, not the entire page. I looked at a number of other posts and they suggested to use AJAX but even when I used AJAX, instead of just reloading the partial view popup, It takes me to a full page view of the Partial View. I want to just reload the content inside of the modal div.
Here is my code:
Controller
public PartialViewResult FileUpload(int jobID)
{
ViewBag.jobID = jobID;
return PartialView(GetFiles(jobID));
}
[HttpPost]
public ActionResult FileUpload(int jobID, HttpPostedFileBase files)
{
int id = Convert.ToInt32(Session["id"]);
String FileExt = Path.GetExtension(files.FileName).ToUpper();
if(FileExt == ".PDF")
{
Stream str = files.InputStream;
BinaryReader Br = new BinaryReader(str);
Byte[] FileDet = Br.ReadBytes((Int32)str.Length);
UploadFileModel Fd = new UploadFileModel();
Fd.FileName = files.FileName;
Fd.FileContent = FileDet;
Fd.personID = id;
Fd.jobID = jobID;
file fileDB = new file();
fileDB.FileContent = Fd.FileContent;
fileDB.FileName = Fd.FileName;
fileDB.personID = id;
fileDB.jobID = Fd.jobID;
db.files.Add(fileDB);
db.SaveChanges();
return PartialView("FileUpload", GetFiles(jobID));
}
else
{
ViewBag.FileStatus = "Invalid file format.";
return PartialView();
}
}
[HttpPost]
public FileResult DownloadFile(int? fileId)
{
byte[] bytes;
string fileName, contentType;
var file = db.files.Find(fileId);
bytes = (byte[])file.FileContent;
fileName = file.FileName;
return File(bytes, fileName);
}
public List<UploadFileModel> GetFiles(int jobID)
{
List<UploadFileModel> files = new List<UploadFileModel>();
var filesDB = db.files.Where(x => x.jobID == jobID);
foreach (var fileDB in filesDB)
{
files.Add(new UploadFileModel
{
id = fileDB.id,
FileName = fileDB.FileName,
personID = fileDB.personID,
jobID = fileDB.jobID
});
}
return files;
}
Partial View:
#model IEnumerable<Church_Musician_Administration_App__Updated_.Models.UploadFileModel>
<style>
.table-striped tbody tr:nth-of-type(odd) {
background-color: rgb(222, 178, 241);
}
.table-striped tbody tr:nth-of-type(even) {
background-color: rgb(233, 204, 246);
}
#fileTable {
font-family: "Arial";
}
#fileTable tr {
cursor: default;
}
a:link {
color: darkviolet;
background-color: transparent;
text-decoration: none;
}
a:visited {
color: gray;
background-color: transparent;
text-decoration: none;
}
a:hover {
color: white;
background-color: transparent;
text-decoration: none;
}
a:active {
color: rebeccapurple;
background-color: transparent;
text-decoration: none;
}
</style>
#using (Html.BeginForm("FileUpload", "App", FormMethod.Post, new { enctype = "multipart/form-data", id="fileUploadForm"}))
{
<input type="hidden" name="jobID" value="#ViewBag.jobID" />
<label class="btn btn-primary" for="my-file-selector">
<input id="my-file-selector" name="files" type="file" style="display:none"
onchange="$('#upload-file-info').text(this.files[0].name)">
Choose File
</label>
<span class='label label-info' id="upload-file-info">No File Uploaded</span>
<input class="btn btn-primary" type="submit" id="btnUpload" value="Upload" style="margin-bottom:5px" />
}
#using (Html.BeginForm("DownloadFile", "App", FormMethod.Post))
{
<input type="hidden" id="hfFileId" name="FileId" />
<input type="submit" id="btnDownload" value="Download" style="display:none" />
}
<hr />
<table id="fileTable" class="table table-striped" style="width:100%; border: 1px solid rgba(0,0,0,.125); border-left:none; border-right:none; text-align: center; display:inline-table;">
<tbody>
<tr style="background-color:darkviolet; height:40px; width:100%">
<th style="display:none;">JobID</th>
<th style="display:none">File ID</th>
<th style="color:white; border: 1px solid rgba(0,0,0,.125);">File Name</th>
<th style="color:white; border: 1px solid rgba(0,0,0,.125);">Download</th>
</tr>
#if (Model.Count() > 0)
{
foreach (var file in Model)
{
<tr>
<td style="display:none;">#file.id</td>
<td style="border: 1px solid rgba(0,0,0,.125);">#file.FileName</td>
<td style="border: 1px solid rgba(0,0,0,.125);">Download</td>
</tr>
}
}
else
{
<tr>
<td colspan="3"> </td>
</tr>
}
</tbody>
</table>
<script type="text/javascript">
function DownloadFile(fileId) {
$("#hfFileId").val(fileId);
$("#btnDownload")[0].click();
};
</script>
<script>
$('#btnUpload').click(function (event) {
event.preventDefault();
event.stopImmediatePropagation();
$('#fileUploadForm').submit();
$.ajax({
url: '/App/FileUpload',
type: 'POST',
success: function (data) {
$("#addMusicModalBodyDiv").html(data);
$("#addMusicModal").modal("show");
}
});
});
</script>
EDIT: Here is the code for where the addMusicModal is defined. It's located in a view called ViewSubstituteJobs
<button type="button" class="btn btn-primary" id="addMusic" onclick="addMusic()">Add Music</button>
<div class="modal" tabindex="-1" id="addMusicModal">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add Music</h5>
<button type="button" class="close" aria-label="Close" id="closeAddMusicModal" onclick="closeDialog()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="addMusicModalBodyDiv">
</div>
</div>
</div>
</div>
var addMusic = function () {
var idFromTable = $("#subJobs tr").closest('tr.highlight').find('td:eq(0)').text();
if (idFromTable == 0) {
return false;
}
$.ajax({
type: "GET",
url: "/App/FileUpload",
data: {
jobID: idFromTable,
},
success: function (response) {
$(".modal").modal("hide");
$("#addMusicModalBodyDiv").html(response);
$("#addMusicModal").modal("show");
}
})
}
</script>
I'm developing an MVC webpage, where I'm intending to do Create and Edit operations via a pop-up. So, the idea is I click on the 'Create' button, a modal-popup appears with all the model fields empty and allows user to input. In the same way, when user double clicks on any row, the row would open up for edit via the same pop-up, this time with the details filled from that row.
So, for reusage, I have decided to develop a single partial view(that would be the pop-up) and accept 'Model' as input.
My problem is, no matter what I do, I'm not able to make the partial view come up as pop-up. (Note: my main parent Index view would accpet input as List
Here is my code:
MY Index view:
#model List<TrackBuildConfig.DAL.Models.BuildModel>
#{
Layout = null;
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/MyScript.js" type="text/javascript"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="jumbotron">
<h1>Track Coverity and Nightly builds</h1>
<h4>on your own!</h4>
</div>
<div class="container-fluid">
<div class="row btn-group">
#Html.ActionLink("Create a new record", "SaveData", "Home", new { configID = 0 }, new { #class = "btn btn-primary modal-link", id = "btnCreate"})
</div>
<div class="modal fade" aria-labelledby="ModalLabel" id="modal-container" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content" style="width: 500px !important; margin:10px !important">
</div>
</div>
</div>
</div>
</body>
</html>
Script:
$(function () {
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$('#btnCreate').attr('data-toggle', 'modal');
$('#btnCreate').attr('data-target', '#modal-container');
$('#modal-container').modal('show');
return true;
});
}
});
Partial view _PartialModal.csHtml
#model TrackBuildConfig.DAL.Models.BuildModel
#{
Layout = null;
}
<html>
<head>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/MyScript.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="">
<div class="modal-header">
<button type="button" class="close" aria-hidden="true" data-dismiss="modal">×</button>
<h4>Configure Coverity and Nightly builds</h4>
</div>
<div class="modal-body" style="height: 400px;">
#using (Html.BeginForm("SaveData", "Home", FormMethod.Post))
{
<div class="row">
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Stream name", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("BuildLocations", (IEnumerable<SelectListItem>)ViewBag.BuildLocations, new { #class = "col-sm-6 form-control", id = "ddlBuildLocation" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Build Location", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("Streams", (IEnumerable<SelectListItem>)ViewBag.Streams, new { #class = "col-sm-6 form-control", id = "ddlStreams" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsCoverity)
Enable Coverity
</label>
</div>
</div>
<div class="col-sm-8">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsNightly)
Enable Nightly build
</label>
</div>
</div>
<label style="color: red; font-weight: 300;" id="warningEnableBuild"></label>
</div>
<div class="form-group row">
#Html.Label("Email for Coverity", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailCoverity, new { #class = "form-control clsEmailCoverity", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailCoverity" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelCoverity"></label>
</div>
</div>
<div class="form-group row">
#Html.Label("Email for Nightly", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailNightly, new { #class = "form-control clsEmailNightly", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailNightly" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelNightly"></label>
</div>
</div>
<div class="modal-footer">
<button id="btnSave" class="btn btn-success" type="submit" role="button">Save changes</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
}
</div>
</div>
</body>
</html>
Controller methods:
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
GetData getdata = new GetData();
return View(getdata.GetDataFromTable());
}
[HttpPost]
public ActionResult SaveData()
{
return View("Index");
}
//[HttpGet]
public ActionResult SaveData(int configID)
{
BuildModel model = new BuildModel();
PopulateBuildLocations();
PopulateStreams();
//Create
if (configID != 0)
{
GetData getdata = new GetData();
model = getdata.GetDataFromTable().Where(co => co.ConfigID == configID).FirstOrDefault();
}
else
{
model.BuildLocation = "";
model.EmailCoverity = "";
model.EmailNightly = "";
model.IsCoverity = false;
model.IsNightly = false;
}
return PartialView("_PartialModal", model);
}
public void PopulateBuildLocations()
{
string reportTypes = ConfigurationManager.AppSettings["ddlStreams"].ToString();
ViewBag.BuildLocations = reportTypes.Split('|')
.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
public void PopulateStreams()
{
List<string> lstStreams = new List<string>();
for (int i = 0; i < 6; i++)
{
lstStreams.Add("Stream " + i);
}
ViewBag.Streams = lstStreams.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
}
This is the link I used as reference. Reference
Please put my code in your visual studio and see that it works.
Controller/View Model/Classes:
public class BuildModel
{
public string theBuildModel { get; set; }
public int ConfigID { get; set; }
public string BuildLocation { get; set; }
public string EmailCoverity { get; set; }
public string EmailNightly { get; set; }
public bool IsCoverity { get; set; }
public bool IsNightly { get; set; }
}
public class GetData
{
public IList<BuildModel> GetDataFromTable()
{
IList<BuildModel> list = new List<BuildModel>();
var buildModel1 = new BuildModel { theBuildModel = "one" };
var buildModel2 = new BuildModel { theBuildModel = "two" };
var buildModel3 = new BuildModel { theBuildModel = "three" };
list.Add(buildModel1);
list.Add(buildModel2);
list.Add(buildModel3);
return list;
}
}
public class HomeController : Controller
{
[HttpPost]
public ViewResult SaveData(BuildModel buildModel)
{
GetData getdata = new GetData();
var model = getdata.GetDataFromTable();
return View("IndexStackOverflow", model);
}
[HttpGet]
public PartialViewResult SaveData(int configID)
{
BuildModel model = new BuildModel();
PopulateBuildLocations();
PopulateStreams();
//Create
if (configID != 0)
{
GetData getdata = new GetData();
model = getdata.GetDataFromTable().Where(co => co.ConfigID == configID).FirstOrDefault();
}
else
{
model.BuildLocation = "";
model.EmailCoverity = "";
model.EmailNightly = "";
model.IsCoverity = false;
model.IsNightly = false;
}
return PartialView("_PartialModal", model);
}
public void PopulateBuildLocations()
{
string reportTypes = ConfigurationManager.AppSettings["ddlStreams"].ToString();
ViewBag.BuildLocations = reportTypes.Split('|')
.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
public void PopulateStreams()
{
List<string> lstStreams = new List<string>();
for (int i = 0; i < 6; i++)
{
lstStreams.Add("Stream " + i);
}
ViewBag.Streams = lstStreams.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
public ActionResult IndexStackOverflow()
{
GetData getdata = new GetData();
return View(getdata.GetDataFromTable());
}
web.config:
<appSettings>
<add key="ddlStreams" value="text1|value1"/>
</appSettings>
View:
#model List<Testy20161006.Controllers.BuildModel>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>IndexStackOverflow</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
#*YOU MUST PUT THE NEXT LINE FOLLOWING IN YOUR CODE-NUGET IF YOU NEED TO GET THE SCRIPT*#
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
</head>
<body>
<div class="jumbotron">
<h1>This is part of the Main Page</h1>
<h1>Partial View rendered in result</h1>
<h1>Track Coverity and Nightly builds</h1>
<h4>on your own!</h4>
</div>
<div class="container-fluid">
<div class="row btn-group">
#*#Html.ActionLink("Create a new record", "SaveData", "Home", new { configID = 0 },
new { #class = "btn btn-primary modal-link", id = "btnCreate" })*#
#using (Ajax.BeginForm("SaveData", "Home", new { configID = 0 },
new AjaxOptions
{
UpdateTargetId = "result",
InsertionMode = InsertionMode.Replace,
OnFailure = "error",
HttpMethod = "Get"
}))
{
<input id="btnCreate" type="submit" value="Create a new record" class="btn btn-primary modal-link" />
}
<div id="result"></div>
</div>
</div>
</body>
</html>
Partial View in shared folder:
#model Testy20161006.Controllers.BuildModel
<script type="text/javascript">
$(function () {
$('#myModal').modal('show');
})
</script>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Configure Coverity and Nightly builds</h4>
</div>
<div class="modal-body">
<div class="modal-body" style="height: 400px;">
#using (Html.BeginForm("SaveData", "Home", FormMethod.Post))
{
<div class="row">
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Stream name", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("BuildLocations", (IEnumerable<SelectListItem>)ViewBag.BuildLocations, new { #class = "col-sm-6 form-control", id = "ddlBuildLocation" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Build Location", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("Streams", (IEnumerable<SelectListItem>)ViewBag.Streams, new { #class = "col-sm-6 form-control", id = "ddlStreams" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsCoverity)
Enable Coverity
</label>
</div>
</div>
<div class="col-sm-8">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsNightly)
Enable Nightly build
</label>
</div>
</div>
<label style="color: red; font-weight: 300;" id="warningEnableBuild"></label>
</div>
<div class="form-group row">
#Html.Label("Email for Coverity", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailCoverity, new { #class = "form-control clsEmailCoverity", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailCoverity" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelCoverity"></label>
</div>
</div>
<div class="form-group row">
#Html.Label("Email for Nightly", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailNightly, new { #class = "form-control clsEmailNightly", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailNightly" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelNightly"></label>
</div>
</div>
<div class="modal-footer">
<button id="btnSave" class="btn btn-success" type="submit" role="button">Save changes</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
I currently have table that displays a list of all of the issues. I added PagedList.MVC to the application as well as a jquery filterTable the issue is that when I click on a different page using the PagedListPager it loses all of the sort options at the top of the page. I believe I just need to add the parameters to the pagedlistpager but I am not sure how to get the value of the textbox. I was thinking about trying to use jquery and using the val() of the element but not sure if that is the best/easiest way to do this.
Here is my View:
#model PagedList.IPagedList<ApIssues.Models.AP_Tasks>
#using System.Data.SqlClient
#using PagedList.Mvc;
#{
ViewBag.Title = "Index";
}
<div class="search-sort-section">
<h2>Search and Sort</h2>
#using (Html.BeginForm("Index","ApIssues"))
{
<p>
#Html.Label("Company: ")
#Html.DropDownList("company", (SelectList)ViewBag.CompanyList, " ")
#Html.Label("Warehouse: ")
#Html.DropDownList("warehouse", (SelectList)ViewBag.WarehouseList, " ")
#Html.Label("Past Due Only: ")
#Html.DropDownList("pastDue", (SelectList)ViewBag.PastDueList, " ")
#Html.Label("Assigned To/By: ")
#Html.DropDownList("assignedToBy", (SelectList)ViewBag.UsersList, " ")
</p>
<p>
#Html.Label("Open / Completed: ")
#Html.DropDownList("openco", (SelectList)ViewBag.OpenCompList, " ")
#Html.Label("Sort By: ")
#Html.DropDownList("sortBy", (SelectList)ViewBag.SortByList, " ")
#Html.Label("PO #: ")
#Html.TextBox("poNumber")
#Html.Label("Freight #: ")
#Html.TextBox("freightNumber")
#Html.Label("Vendor Name: ")
#Html.TextBox("vendorName")
</p>
<p>
#Html.Label("Issue Date")
#Html.TextBox("beginIssueDate") - #Html.TextBox("endIssueDate")
#Html.Label("Invoice Date")
#Html.TextBox("beginInvoiceDate") - #Html.TextBox("endInvoiceDate")
#Html.Label("Completed Date")
#Html.TextBox("beginCompletedDate") - #Html.TextBox("endCompletedDate")
#Html.Label("Quick Filter: ")
#Html.TextBox("quickFilter")
</p>
<p>
<input type="submit" value="Go" />
<input type="button" value="Printable View" onclick=" location.href = '#Url.Action("PrintablePdf", "ApIssues")' " />
<input type="button" value="Add New Task" onclick=" location.href = '#Url.Action("Create", "ApIssues")' " />
<input type="button" value="Reporting" />
</p>
}
</div>
<div class="issue-table">
<h2>A/P Issues</h2>
<table id="data-table">
<tr>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Task ID", "Index",
new { sortOrder = "TaskID", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Task Date", "Index",
new { sortOrder = "TaskDate", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Invoice Date", "Index",
new { sortOrder = "InvDate", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Assigned To", "Index",
new { sortOrder = "AssignedTo", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("CC", "Index",
new { sortOrder = "CC", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("WHSE", "Index",
new { sortOrder = "Whse", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("PO #", "Index",
new { sortOrder = "PO", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Freight #", "Index",
new { sortOrder = "FreightNo", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Vendor Name", "Index",
new { sortOrder = "VendName", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Req. Completion Date", "Index",
new { sortOrder = "ReqCompDate", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Task Type", "Index",
new { sortOrder = "TaskType", CurrentSort = ViewBag.CurrentSort })
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink(item.TaskID.ToString(), "Task", new { id = item.TaskID })
</td>
<td>
#Html.DisplayFor(modelItem => item.TaskDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.InvDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedTo)
</td>
<td>
#Html.DisplayFor(modelItem => item.CC)
</td>
<td>
#Html.DisplayFor(modelItem => item.Whse)
</td>
<td>
#Html.DisplayFor(modelItem => item.PO)
</td>
<td>
#Html.DisplayFor(modelItem => item.FreightNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.VendName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ReqCompDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.TaskType)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.TaskID })
</td>
</tr>
}
</table>
<br />
<div id='Paging' style="text-align:center">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index", new {page}))
</div>
</div>
<head>
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://sunnywalker.github.io/jQuery.FilterTable/jquery.filtertable.min.js"></script>
<script src="~/Scripts/Additional JS/jquery.tablesorter.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('table').filterTable(
{
minRows: 1,
label: "Search :",
inputSelector: "#quickFilter" ,
placeholder: "Keyword"
});
});
</script>
</head>
Here is my action:
public ActionResult Index(string sortOrder,string currentSort, int? page, string company, string warehouse,
string pastDue, string assignedToBy, string openco, string sortBy, string poNumber, string freightNumber,
string vendorName, string beginIssueDate, string endIssueDate, string beginInvoiceDate, string endInvoiceDate,
string beginCompletedDate, string endCompletedDate)
{
//Variable Definitions
const int pageSize = 20;
var pageIndex = 1;
pageIndex = page.HasValue ? Convert.ToInt32(page) : 1;
IPagedList<AP_Tasks> tasks = null;
// Instantiate the Entities
var nxtDb = new nxtSQLEntities();
var db = new Accounting_AaronTestEntities();
var usersDb = new PDDAEntities1();
//Query that gets the warehouses, companys, and users from the nxtDB and the PPP DB
var whses = from w in nxtDb.icsds select w.whse;
var coNames = from c in nxtDb.icsds select c.name;
var userDb = new PDDAEntities1();
var query1 = from u in userDb.Users where u.Cono == 1 select new { u.UserName, u.FirstName, u.LastName };
var query2 = from gm in userDb.GroupMembers
join ug in userDb.UserGroups on gm.GroupID equals ug.GroupID
join u in userDb.Users on gm.UserName equals u.UserName
where ug.GroupName == "AP Department" || ug.GroupName == "MIS"
orderby new { u.LastName, u.FirstName }
select new { UserName = u.UserName, FirstName = u.FirstName, LastName = u.LastName };
var query3 = query1.Concat(query2);
var users = new List<string> { };
users.AddRange(query3.Select(entry => entry.UserName));
//Dropdown lists being created and using a viewbag to setup and communication line between the the conroller and view
var warehouseList = new SelectList(whses);
ViewBag.WarehouseList = warehouseList;
var companyList = new SelectList(coNames);
ViewBag.CompanyList = companyList;
var pastDueList = new SelectList(new[]{"Yes", "No"});
ViewBag.PastDueList = pastDueList;
var usersList = new SelectList(users);
ViewBag.UsersList = usersList;
var openCompList = new SelectList(new[] { "Open", "Completed" });
ViewBag.OpenCompList = openCompList;
var sortByList = new SelectList(new[] { "Task ID", "Warehouse", "Assigned To", "PO Number", "Task Date" });
ViewBag.SortByList = sortByList;
tasks = GetFilteredSortedTasks(db,company, warehouse, pastDue, assignedToBy, openco, sortBy, poNumber,
freightNumber, vendorName, beginIssueDate, endIssueDate, beginInvoiceDate, endInvoiceDate,
beginCompletedDate, endCompletedDate).ToPagedList(pageIndex, pageSize);
return View(tasks);
}
Html.PagedListPager can take an additional parameter that is an expression that tells it how to generate the URL for the next page:
#Html.PagedListPager((IPagedList)ViewBag.OnePageOfItems, page => SomeMethodToGetUrlFor(page))
What you need to do basically is keep the current URL of the page (with all the appropriate querystring params for the filters and such) and add or update a page parameter. The "add or update" part makes this tricky, though: for example, you can't just tack on &page=N to the end of the URL as page may already be present in the querystring. I created a UrlHelper extension for just this purpose:
public static string ModifyQueryString(this UrlHelper helper, string url, NameValueCollection updates, IEnumerable<string> removes)
{
NameValueCollection query;
var request = helper.RequestContext.HttpContext.Request;
if (string.IsNullOrWhiteSpace(url))
{
url = request.Url.AbsolutePath;
query = HttpUtility.ParseQueryString(request.QueryString.ToString());
}
else
{
var urlParts = url.Split('?');
url = urlParts[0];
if (urlParts.Length > 1)
{
query = HttpUtility.ParseQueryString(urlParts[1]);
}
else
{
query = new NameValueCollection();
}
}
updates = updates ?? new NameValueCollection();
foreach (string key in updates.Keys)
{
query.Set(key, updates[key]);
}
removes = removes ?? new List<string>();
foreach (string param in removes)
{
query.Remove(param);
}
if (query.HasKeys())
{
return string.Format("{0}?{1}", url, query.ToString());
}
else
{
return url;
}
}
What this does is essentially let you pass in a NameValueCollection of parameters you want to add or update and/or a list of parameters you want to remove from the querystring. By default, it uses the current request URL, but if you pass in a URL it will do the transformation on that instead. Finally, it returns the modified URL back to the view.
I also added some additional methods to make working with this a little easier such as:
public static string UpdateQueryParam(this UrlHelper helper, string param, object value)
{
return ModifyQueryString(helper, new NameValueCollection { { param, value.ToString() } }, null);
}
public static string UpdateQueryParam(this UrlHelper helper, string url, string param, object value)
{
return ModifyQueryString(helper, url, new NameValueCollection { { param, value.ToString() } }, null);
}
So, if I just need to add/update one parameter, I don't need to actually instantiate a new NameValueCollection in my view.
Using these extensions, then, you can modify the URL appropriately with:
Url.UpdateQueryParam("page", page)
Which makes your pager line:
#Html.PagedListPager((IPagedList)ViewBag.OnePageOfItems, page => Url.UpdateQueryParam("page", page))