I have a page which load data from multiple partial views. One of the partial view has few links. say 3. Every time user clicks on the link I reload the page with a data related to clicked link. The form looks like this.
#model TestPostback.Models.HomeModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<form id="testform" method="post" action="#Url.Action("Index","Home")" runat="server">
<div>
<table>
<tr>
<td>
This is a test page
</td>
</tr>
</table>
</div>
</form>
<div>
<table>
<tr>
<td style="vertical-align:top;">
<h2 class="expand">Test Expand</h2>
<div class="collapse">
<table id="testgrid" class="scroll" cellpadding="0" cellspacing="0"></table>
</div>
</td>
</tr>
</table>
</div>
<script type="text/javascript">
jQuery(document).ready(function () {
var grid = jQuery("#testgrid");
grid.jqGrid({
url: 'Home/GridData/',
datatype: 'json',
mtype: 'POST',
colNames: ['Id', 'Votes', 'Title'],
colModel: [
{ name: 'Id', index: 'Id', width: 40, align: 'left' },
{ name: 'Votes', index: 'Votes', width: 40, align: 'left' },
{ name: 'Title', index: 'Title', width: 400, align: 'left'}
],
rowNum: 10,
rowList: [5, 10, 20, 50],
sortname: 'Id',
sortorder: "desc",
viewrecords: true,
imgpath: '',
caption: 'My first grid'
});
});
</script>
Controller Code :-
public ActionResult Index(string selectedValue)
{
return View();
}
public JsonResult GridData(string sidx, string sord, int page, int rows)
{
int totalPages = 1; // we'll implement later
int pageSize = rows;
int totalRecords = 3; // implement later
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = new[]{
new {id = 1, cell = new[] {"1", "-7", "Is this a good question?"}},
new {id = 2, cell = new[] {"2", "15", "Is this a blatant ripoff?"}},
new {id = 3, cell = new[] {"3", "23", "Why is the sky blue?"}}
}
};
return Json(jsonData);
}
Here is what I am trying to do.
When i click on Link "This is a Test Page", it calls the controller with some value but it does not load my grid. I want that value because i want to load a grid with different value based on user clicks. what are the changes I have to make for this to work?
please advice.
I'd recommend following the PRG (post redirect get) pattern: so after the post, you redirect to whichever action method is suitable (in this case the one that displays all the jqGrids). With MVC this can be achieved using a RedirectResult or the RedirectToAction method available on Controller.
Are you serializing your data when you get it back (ie serializeGridData)
Are you loading by JSON?
If so, check out
Setting the content-type of requests performed by jQuery jqGrid
Related
I am attempting to implement ASP.NET Core SignalR. I am looking for assistance. The project is located at: https://github.com/Talsiter/AspNetCore-SignalR-SqlTableDependency
The issue that I am running into is when a datatable is being populated from jQuery AJAX, no data is being populated into the view.
Items model (Item.cs)
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace InAndOut.Models
{
public class Item
{
[Key]
public int Id { get; set; }
public string Borrower { get; set; }
public string Lender { get; set; }
[DisplayName("Item name")]
public string ItemName { get; set; }
}
}
Items view (Index.cshtml)
#model IEnumerable<InAndOut.Models.Item>
<div class="container p-3">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<div class="card-body">
<table id="myTable" class="table table-bordered table-striped">
<thead>
<tr>
<th>Id</th>
<th>Item Name</th>
<th>Borrower</th>
<th>Lender</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
#section Scripts {
#* These Scrips are Required *#
<script src="~/js/signalr/dist/browser/signalr.js"></script>
#*This one gives me an error of "ItemsHub undefined"*#
#*<script src="~/js/items01.js"></script>*#
#* This gives me an error "DataTable is not a function"
This probably requires the *#
<link href="//cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css" rel="stylesheet" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="~/js/items03.js"></script>
}
Items JS file (items03.js):
// This is from:
//https://stackoverflow.com/questions/51764211/jquery-datatable-loading-using-ajax-asp-net-mvc
// Does Not Display any data
function getAllMessages() {
$('#myTable').DataTable({
processing: true,
serverSide: false,
ordering: true,
paging: true,
searching: true,
columns: [
{ title: "Id" },
{ title: "ItemName" },
{ title: "Borrower" },
{ title: "Lender" },
{ title: "View Data" }
],
columns: [
{ data: "Id" },
{ data: "ItemName" },
{ data: "Borrower" },
{ data: "Lender" },
{
data: null,
defaultContent: "<button class='tblview'>View Id</button><button class='tblDelete'>Delete</button>"
}
],
ajax: {
"url": "/Item/GetItems",
"type": "GET",
"dataSrc": ''
},
"columnDefs": [
{
"targets": 0,
"visible": false
}
]
});
}
Item controller (ItemController.cs):
// This was updated from:
// https://stackoverflow.com/questions/51705732/jquery-datatable-ajax-no-data-available-mvc
public IActionResult GetItems()
{
var items = new List<Item>
{
new Item { Id = 1, ItemName = "Computer", Borrower = "Justin", Lender = "Don"},
new Item { Id = 2, ItemName = "Mouse", Borrower = "Mark", Lender = "Susan"},
new Item { Id = 3, ItemName = "Monitor", Borrower = "Mark", Lender = "Joe"},
new Item { Id = 4, ItemName = "Keyboard", Borrower = "Candace", Lender = "Angela"},
new Item { Id = 5, ItemName = "Printer", Borrower = "Mike", Lender = "Watson"},
};
// JsonRequestBehavior requires Microsoft.AspNet.MVC
// I do not want to reference it. I want to use Microsoft.AspNetCore.Mvc
//return Json(items, JsonRequestBehavior.AllowGet);
// I referenced this to mitigate the above issue
// https://stackoverflow.com/questions/38578463/asp-net-core-the-name-jsonrequestbehavior-does-not-exist-in-the-current-cont
//return Json(items);
// Error: Cannot read property 'style' of undefined
// This was another option
//return Json(items, new Newtonsoft.Json.JsonSerializerSettings());
// Error: Cannot read property 'style' of undefined
// This seems to be returning the correct data format
// Now the data just is not being displayed in the view
// My error seems to be in the JavaScript
return Json(new { data = items });
}
After many attempts, this is about the closest that I am able to get. While debugging the site, I do not receive any errors, but the mock data does not appear in the items view.
I am suspecting that my issue is in the Items JS file in the getAllMessages() method. I am just not sure how to fix it.
The naming convention for response in asp.net core is camel case instead of pascal case. Also you need remove "dataSrc": ''.
Change like below:
columns: [
{ data: "id" },
{ data: "itemName" },
{ data: "borrower" },
{ data: "lender" },
{
data: null,
defaultContent: "<button class='tblview'>View Id</button><button class='tblDelete'>Delete</button>"
}
],
ajax: {
"url": "/Item/GetItems",
"type": "GET",
//"dataSrc": ''
},
I would like to know if it is possible to use datatables (Metronic Laravel Theme) to display a 6*4 grid of user-images instead of displaying the images row-by-row (the standard datatable behavior). Anyone able to help?
ive just started on this so i don't want to waste a lot of time if it's not possible at all, this is what i have so far:
let members_datatable,
members_element = $('...');
members_datatable = members_element.MyCustomDataTable({
columns: [
{
field: 'id',
title: members_element.data('column-id'),
width: 50,
template: function (row) {
return row.id;
}
},
{
field: 'first_name',
title: members_element.data('column-name'),
width: 150,
template: function (row) {
let user_id = ...;
let user_company = ...;
let company_branche = ...;
return `<div class="mt-card-item">
<div class="mt-card-avatar mt-overlay-4">
<img src="storage/public/userImages/${user_id}.jpg">
<div class="mt-overlay">
<h2>${user_company}</h2>
<div class="mt-info font-white">
<div class="mt-card-content">
${company_branche}
</div>
</div>
</div>
</div>
</div>`;
}
},
],
});
I have a table with my data from base and 3 buttons to delete, create and update which return PartialViews.
I want to update the part of my page with data after clicking the submit button in the corresponding dialog (delete, update, ...).
What is the easiest way to achive this?
This is what I've got now
I will just add, delete is mostly the same.
<div id="delete-dialog" title="Delete Product"></div>
<script type="text/javascript" >
$(".deleteLink").button();
var deleteLinkObj;
// delete Link
$('.deleteLink').click(function () {
deleteLinkObj = $(this);
var name = $(this).parent().parent().find('td :first').html();
$('#delete-dialog').html('<p>Do you want delete ' + name + ' ?</p>');
//for future use
$('#delete-dialog').dialog('open');
return false; // prevents the default behaviour
});
$('#delete-dialog').dialog({
dialogClass: "ConfirmBox",
autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
buttons: {
"Continue": function () {
$.post(deleteLinkObj[0].href, function (data) { //Post to action
if (data == '<%= Boolean.TrueString %>') {
deleteLinkObj.closest("tr").hide('fast'); //Hide Row
}
else {
}
});
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
</script>
And after dialog close I want something like a reload of a part of the page.
The data looks like
<table>
<tr>
<th> Name </th>
<th> Date </th>
<th> </th>
</tr>
#foreach (var m in this.Model)
{
<tr>
<td>
<div class="ProductName">#Html.DisplayFor(Model => m.Name)</div>
</td>
<td>
#Convert.ToDateTime(m.AddDate).ToShortDateString()
</td>
<td>
<div class="ProductPrice">#string.Format("{0:C}", m.Price)</div>
</td>
<td>
<div class="CategoryName">#Html.DisplayFor(Model => m.CategoryName)</div>
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = m.ID }, new { #class = "editLink" })
#Html.ActionLink("Delete", "Delete", new { id = m.ID }, new { #class = "deleteLink" })
</td>
</tr>
}
</table>
I'm not sure if im doing this well
I tried to put this action after click the button but nut sure if is right
I changed the Index to a Partial View
buttons: {
"Continue": function () {
$.post(deleteLinkObj[0].href, function (data) { //Post to action
if (data == '<%= Boolean.TrueString %>') {
deleteLinkObj.closest("tr").hide('fast'); //Hide Row
}
else {
}
});
$.ajax.ActionLink("Index",
"Index", // <-- ActionMethod
"Shop", // <-- Controller Name.
new { }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. Y
)
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
I suggest you use the ASP.NET MVC ActionLink helper in your .cshtml file, and not jQuery:
[...]
<script type="text/JavaScript">
function openPopup()
{
// Set your options as needed.
$("#yourPopupDialogId").dialog("open");
}
</script>
[...]
#Ajax.ActionLink(
"Delete",
"Delete",
"Controller",
new { someValue = 123 },
new AjaxOptions
{
// Set your options as needed
HttpMethod = "GET",
UpdateTargetId = "yourPopupDialogId",
OnSuccess = "openPopup()"
}
)
[...]
<div id="yourPopupDialogId" style="display: none;"></div>
Now in your Controller for the methods you want to use for your popups you should return PartialViews:
public ActionResult Delete(int id)
{
RecordDeleteModel model = YourRepository.GetModel( id );
return PartialView( model );
}
I have a webgrid with an actionlink which I want to use to edit the selected row in a new view. I know that I can use an actionlink to supply an arguement to my actionresult method but I don't know how to pass the webgrid's row data to my controller apart from using actionlink.
#{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<p>
#Html.ActionLink("Create New User", "CreateUser")
</p>
<div class="webgrid-wrapper">
#model IEnumerable<UserManager.Models.vw_UserManager_Model_Add_Users>
#{
ViewBag.Title = "Jobs";
WebGrid grid = new WebGrid(Model, canPage: true, canSort: true, rowsPerPage: 15, selectionFieldName: "selectedRow", fieldNamePrefix: "gridItem");
}
#grid.GetHtml(
fillEmptyRows: true,
tableStyle: "webgrid",
alternatingRowStyle: "webgrid-alternating-row",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style",
mode: WebGridPagerModes.All,
columns: new[] {
//grid.Column("ApplicationId"),
//grid.Column("salutation"),
//grid.Column("PasswordSalt"),
grid.Column("FirstName"),
//grid.Column("LoweredEmail"),
//grid.Column("PasswordQuestion"),
//grid.Column("PasswordAnswer"),
// grid.Column("PasswordFormat"),
grid.Column("LastName"),
grid.Column("Password"),
grid.Column("isactive"),
//grid.Column("IsLockedOut"),
grid.Column("email"),
grid.Column("module_name"),
//grid.Column("LastLoginDate"),
//grid.Column("LastPasswordChangedDate"),
//grid.Column("LastLockoutDate"),
//grid.Column("FailedPasswordAttemptCount"),
//grid.Column("FailedPasswordAttemptWindowStart"),
//grid.Column("FailedPasswordAnswerAttemptCount"),
//grid.Column("FailedPasswordAnswerAttemptWindowStart"),
// Rest of grid columns, seen previously
#*grid.Column(
"",
header: "Actions",
format: #<text>
#Html.ActionLink("Edit", "Edit", new { id = item.email })
</text>
) ,
grid.Column(
"",
header: "Actions",
format: #<text>
#Html.ActionLink("Delete", "Delete", new { id = item.email })
</text>
) *#
#* grid.Column(
header:"",
format:#<text><div id="btnSelectedRow">
"#item.GetSelectLink("Edit")</div></text>
),*#
grid.Column(
header:"",
format:#<text><div id="btnSelectedRow">
"#Html.ActionLink("Edit record",
"EditUser",
"UserManager",
new {selectedRow = grid.SelectedRow },
null
)</div></text>
)
})
#if (grid.HasSelection)
{
var record = grid.SelectedRow;
#*#RenderPage("~/Views/UserManager/EditUser.cshtml", new { record = grid.SelectedRow })*#
}
</div>
<script type="text/javascript">
$(document).ready(function () {
function jQueryUIStyling() {
$('input:button, input:submit').button();
// Style tables.
$('.webgrid-wrapper').addClass('ui-grid ui-widget ui-widget-content ui-corner-all');
$('.webgrid-title').addClass('ui-grid-header ui-widget-header ui-corner-top');
jQueryTableStyling();
}
//
// Style tables using jQuery UI theme. This function is
// split out separately so that it can be part of the AJAX
// callback of the WebGrid WebHelper in ASP.NET MVC.
//
function jQueryTableStyling() {
$('.webgrid').addClass('ui-grid-content ui-widget-content');
$('.webgrid-header').addClass('ui-state-default');
$('.webgrid-footer').addClass('ui-grid-footer ui-widget-header ui-corner-bottom ui-helper-clearfix');
}
});
</script>
My controller
public ActionResult EditUser(System.Web.Helpers.WebGrid record)
{
record.ToString();
return View();
}
Summary
How to pass row data using ActionLink from one view to another via ActionResult method.
You have two options, really: have your action take the user Id and look the user up, or have each row of your grid contain a form which sends all the user details to the action when you click 'edit'. Which of those you choose depends on what your action is supposed to do:
If it redirects to a form where the user can edit the user they selected, use the first approach
If it takes all the user details and saves an updated user, use the second approach
Edit
To pass the id you can use this for the action link:
#Html.ActionLink(
"Edit record",
"EditUser",
"UserManager",
new { id = item.email })
...and this for the action signature:
public ActionResult EditUser(string id)
Basically, I'm using WebGrid and I need to filter the results. The first problem I have here is it's my first time using WebGrid and I was hoping some of you could give me a hand with it... So far, I've managed to sort grid results and filter them with Ajax, but, when re-sorting the filtered results, the subset is lost and I go back to the beginning with the full set of results. I know why it's happening of course, but I don't figure out how to make it work.
Example:
On my view:
#model IQueryable<Cities>
#section MoreScripts
{
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
}
#using (Ajax.BeginForm(new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "GridData"}))
{
<fieldset>
<legend>Search Filters</legend>
<br />
<div>
Name
</div>
<div>
#Html.TextBox("Name")
</div>
<p>
<input type="submit" value="Search" />
</p>
</fieldset>
}
<div id="GridData">
#Html.Partial("Grid", Model)
</div>
My Partial View:
#model IQueryable<Cities>
#{
var grid = new WebGrid<Cities>(null,rowsPerPage: 5, defaultSort: "Nombre", ajaxUpdateContainerId: "GridData");
grid.Bind(Model, autoSortAndPage: true, rowCount: Model.Count());
#grid.GetHtml(columns:
grid.Columns(
grid.Column("Name", "Name", canSort: true),
grid.Column("CreationDate", "Creation Date", canSort: true),
grid.Column("Active", "Active", canSort: true, format: #<text><input type="checkbox" disabled="disabled" value="#item.ID" #(item.Active == true ? "Checked" : null) /></text>),
grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { #class = "editLink smallCell", #title = "Edit" })),
grid.Column(format: (item) => Html.ActionLink("Delete", "Delete", new { id = item.Id }, new { #class = "deleteLink smallCell", #title = "Delete" }))),
tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style");
}
And finally what am doing wrong is here, on my controller:
public ActionResult Index()
{
return View(repository.GetAllRecords().OrderByDescending(f => f.CreationDate));
}
[HttpPost]
public ActionResult Index(string name)
{
var data = repository.GetAllRecords();
if(!string.IsNullOrEmpty(name))
data = data.Where(a => a.Name.Contains(name));
data = data.OrderByDescending(f => f.CreationDate);
return PartialView("Grid", data);
}
I'm also using a class WebGrid : WebGrid as seen here:
http://archive.msdn.microsoft.com/mag201107WebGrid/Release/ProjectReleases.aspx?ReleaseId=5667
So, this actually works fine for filtering, but once you get the filtered results and then try to change the sort order of your narrowed search results, you lose the elements and the 'name' parameter's value because the WebGrid goes agains the first controller action. Probably this is not the best approach, but as I said, I've never used WebGrid so I'm willing to learn. Any help would be really appreciated. Thanks.
Try to add FormMethod.Post to your form, so the request will go to the second ActionResult. Otherwise, the request is a GET, and goes to the first ActionResult Index() without the parameters.