Getting Data of Specific year from database to show in gridview - MVC - asp.net-mvc

I have a gridview in MVC project which display all records from a table but I want to display just current year's records and on clicking backward or forward arrow the records changes to the previous or next year accordingly.
I just have a ActionResult Index to which returns a list how do I implement a query here?
here is the code in my contrller
public ActionResult Index()
{
return View(db.tbl_HolidayList.ToList());
}
and here is my view code
#foreach (var item in Model) {
<tr>
#* <td>
#Html.TextBoxFor(modelItem => item.Holiday_Id, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_Id)
</div>
</td>*#
<td>
#Html.TextBoxFor(modelItem => item.Holiday_Name, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_Name)
</div>
</td>
<td>
#Html.TextBoxFor(modelItem => item.Holiday_Description, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_Description)
</div>
</td>
<td>
#Html.TextBoxFor(modelItem => item.Holiday_date, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_date)
</div>
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Holiday_Id }, new { #class = "lnkEdit" }) |
#* #Html.ActionLink("Details", "Details", new { id = item.Holiday_Id}, new { #class = "lnkDetail" }) |*#
#Html.ActionLink("Delete", "Delete", new { id = item.Holiday_Id![enter image description here][1] }, new { #class = "lnkDelete" })

Have the index method return values for the current year and a separate method that returns values for a specific year as a partial view
Controller (assume HolidaysController)
public ActionResult Index()
{
return View();
}
public ActionResult Details(int year)
{
var model = db.tbl_HolidayList.Where(h => h.Holiday_date.Year == year);
return PartialView(model);
}
Index.cshtml
#{
int year = DateTime.Today.Year;
}
<button type="button" id="previous">Previous</button>
<div id="year">#year</div>
<button type="button" id="next">Next</button>
<div id="details">
#Html.Action("Details", "Holidays", new { id = year })
</div>
<script>
var year = '#year';
var url = '#Url.Action("Details", "Holidays")'; // Assumes the controller is HolidayController
var updateHolidays = function() {
$('#year').text(year);
$('#details').load(url, { id: year });
}
$('#previous').click(function() {
year--;
updateHolidays();
}
$('#next').click(function() {
year++;
updateHolidays;
}
Details.cshtml (partial)
#model IEnumerable<tbl_HolidayList>
<table>
....
<thead>
#foreach (var item in Model)
{
<tr>
<td>
#Html.TextBoxFor(m => item.Holiday_Id, new { #class = "control", id = "" })
....
</td>
....
</tr>
}
</thead>
</table>
css
.control { // could be just input[type="text"] {
display:none;
height:15px;
width: 100%; // style the column widths!
}
Note: use a class name for styling the textboxes (not inline styles) and use id = "" to remove the id attribute from the textbox (otherwise your creating duplicate id's which is invalid html)

I would :
Update your Controller to take an (int year) parameter and only return the appropriate data (no need to retrieve everything)
Create a partial view with your table in it
When clicking on Previous/Next, I would do a jQuery ajax request to retrieve the data (return a PartialViewResult for example)

In this scenario we do not know how many rows will be there for a year. So better to handle "previous" and "next" button click event and fire a AJAX call which calls an Action method to get data and then refresh the content of WebGrid.
While making AJAX call read current year value and add +1 or -1 based on which button is clicked. Then send it to an Action method as parameter (Action method will be a POST type)...Now Action method will filter data for given year and return it to view. Hope following articles may help to implement this scenario:
https://web.archive.org/web/20210927202530/http://www.4guysfromrolla.com/articles/121510-1.aspx
http://www.binaryintellect.net/articles/59b91531-3fb2-4504-84a4-9f52e2d65c20.aspx
Thanks.

Related

MVC DropDownList lagging

I am posting the id of a dropdownlist back to the index (index2 view). but is lagging behind. After a second time pressing Select it shows me the correct list.
http://www.jeroenchristens.be/CountriesWorld
(the first page is only for showing the complete list, after selecting from the dropdownlist,, it gets to index2, a shorter list) And then after choosing another Selection from the dropdownlist, you have to try this twice each time.
I successfully copied this from the id the value and pass this on, why is it lagging behind.
Index2 Viewpage
#using System.Collections
#using System.Web.UI.WebControls
#model IEnumerable<CVtje.Models.Countries>
<h2>Index</h2>
#using (Html.BeginForm("Index2", "CountriesWorld", new { #id = Request.Form["SelectedContinent"] }, FormMethod.Post))
{
<div class="form-group">
#Html.DropDownList("SelectedContinent",
new SelectList((IEnumerable) ViewData["continentsList"], "Continent", "Continentomschrijving"))
<button type="submit" class="btn btn-primary">Select</button>
</div>
}
<table id="countriesworld" class="table table-active table-hover">
<thead>
<tr>
<th>Vlag</th>
<th>
Code
</th>
<th>
Land
</th>
<th>Continent</th>
</tr>
</thead>
#foreach (var item in Model)
{
<tr>
<td>
<img src="#string.Format("../../images/countries/{0}.png", item.Code)" width="25" HEIGHT="15" />
</td>
<td>
#item.Code
</td>
<td>
#item.Country
#*#Html.ActionLink("Details", "Index", "ReizensDetails", new { id = item.ReizenId }, null)*#
#*|
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
<button data-myprofile-id="#item.Id" class="btn-link js-delete">Delete</button>*#
</td>
<td>#item.Continents.Continentomschrijving</td>
</tr>
}
</table>
my controller:
public ActionResult Index(int? id)
{
List<Continents> continentsList = new List<Continents>();
continentsList = _context.Continents.ToList();
ViewData["continentsList"] = continentsList;
var countriesWorld = _context.Countries.OrderBy(e => e.Country).ToList();
return View(countriesWorld);
}
[HttpPost]
public ActionResult Index2(int id)
{
//return View(db.MyProfiles.ToList());
List<Continents> continentsList = new List<Continents>();
continentsList = _context.Continents.ToList();
ViewData["SelectedContinent"] = id.ToString();
ViewData["continentsList"] = continentsList;
var countriesWorld = _context.Countries.Where(e => e.Continent == id).OrderBy(e => e.Country).ToList();
return View(countriesWorld);
You have added a route value using new { #id = Request.Form["SelectedContinent"] } in your BeginForm() method.
Assuming the initial value is 0, then it generates action = "/CountriesWorld/Index2/0". Lets assume you select the option with value="1" and you now post the form. The id attribute is bound to 0 and you filter the Countries based on .Where(e => e.Continent == 0) - no where have you ever used the value of the selected option which is bound to a non-existent property named SelectedContinent.
Now you return the view and the forms action attribute is now action = "/CountriesWorld/Index2/1" (because Request.Form["SelectedContinent"] is 1). If you select the option with value="2", the same thing occurs - you ignore the value of the selected option and the filter the Countries based on .Where(e => e.Continent == 1) because the id parameter is 1.
Always bind to a model, which in your case will be
public class CountriesVM
{
public int? SelectedContinent { get; set }
public IEnumerable<SelectListItem> ContinentsList { get; set; }
public IEnumerable<Country> Countries { get; set; }
}
and in the view, strongly bind to your model (note the FormMethod.Get and the 3rd parameter in DropDownListFor())
#model CountriesVM
#using (Html.BeginForm("Index", "CountriesWorld", FormMethod.Get))
{
#Html.DropDownListFor(m => m.SelectedContinent, Model.ContinentsList, "All")
<button type="submit" class="btn btn-primary">Select</button>
}
<table ... >
....
#foreach(var country in Model.Countries)
{
....
}
</table>
and you need only one method
public ActionResult Index(int? selectedContinent)
{
var countries = _context.Countries.OrderBy(e => e.Country);
if (selectedContinent.HasValue)
{
countries = countries.Where(e => e.Continent == selectedContinent.Value);
}
continentsList = _context.Continents.Select(x => new SelectListItem
{
Value = x.Continent.ToString(),
Text = x.Continentomschrijving
});
var model = new CountriesVM
{
SelectedContinent = selectedContinent,
ContinentsList = continentsList,
Countries = countries
};
return View(model);
}
Note you might also want to consider caching the Continents to avoid repeated database calls assuming they do not change often (and invalidate the cache if their values are updated)

.NET MVC JQuery function is not getting fired in table row click event

I have table data in UI. I want to display data in a div in the same page when I click the Details link in the row. The JQuery function is not getting fired in when I click on details link in any row.
Below is my code:
Model view class:
public class ItemViewModel
{
public Item item { get; set; }
public IEnumerable<Item> items { get; set; }
}
UI Code:
#model Medhub.Models.ItemViewModel
#{
ViewBag.Title = "View";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>View</h2>
<p>
#Html.ActionLink("Create New", "CreateEdit", new { controller = "Item" }, new { #class = "btn btn-primary" })
</p>
<table align="center" height="10%" width="90%">
<tr>
<td>
<div id="Items">
<table style="vertical-align:top; height:200px" width="100%">
<tr style="height:20px">
<th>
#Html.DisplayName("Name")
</th>
<th>
#Html.DisplayName("Description")
</th>
<th>
#Html.DisplayName("Item Type")
</th>
</tr>
#if (Model != null)
{
foreach (var item in Model.items)
{
<tr style="height:15px">
<td>
#Html.HiddenFor(model => item.ItemId)
#Html.DisplayFor(model => item.Name)
</td>
<td>
#Html.DisplayFor(model => item.Description)
</td>
<td>
#Html.DisplayFor(model => item.Type)
</td>
<td>
#Html.ActionLink("Edit", "CreateEdit", new { id = item.ItemId }) |
#Html.ActionLink("Details", "Item", new { id = item.ItemId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ItemId })
</td>
</tr>
}
}
</table>
</div>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div id="ItemDetails">
#if (Model.item != null)
{
Html.RenderPartial("Details", Model.item);
}
</div>
</td>
</tr>
</table>
<script type="text/javascript">
$(function () {
$("div.Items a").click(function (e) {
//e.preventDefault();
var url = this.ref;
$("#ItemDetails").load(url);
});
});
</script>
Controller code:
List<Item> items = new List<Item>();
// GET: Item
public ActionResult Item(int id = 0)
{
ItemViewModel itemVM = new ItemViewModel();
itemVM.items = GetItems();
if (id > 0)
itemVM.item = itemVM.items.FirstOrDefault(u => u.ItemId == id);
return View(itemVM);
}
Any clues?
First of all, you are waiting for clicks on a class called Items. This is the reason the jquery code is not being fired. You should have
$("div#Items a").click(function (e) {
Secondly, you need to check the attribut href, not ref. Also, prevent default needs to be there, otherwise you just reload your page
e.preventDefault();
var url = this.href;
You don't need the renderpartial in the page, just leave it empty:
<div id="ItemDetails">
</div>
While your logic kind of works, the way the url is loaded causes the entire page to be loaded into the ItemDetails section. I'd suggest that in your controller, you'd create a separate method for the details:
public ActionResult Details(int id) {
Item item = GetItem(id);
return View(item);
}
private Item GetItem(int id) {
return new Item() { Details = "details here" };
}

Can we pass the textbox values(autocomplete) to controller without using jquery ajax?

Initially i have used this controller for searching the text once after clicking the search button.
but now i need to make it as a autocomplete textbox. this is the view page
View:cshtml
The textbox value needs to be passed to controller.
<div class="panel-body">
<div class="form-group">
#Html.TextBox("search", ViewBag.CurrentFilter as string, new { #class = "form-control input-sm" })
</div>
</div>
<table class="table table-hover table-condensed">
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CategoryName)
</td>
</tr>
}
</table>
</div>
IndexContoller:
Can i able to call this without using jquery ajax?
public ActionResult Search(string searchText)
{
var category = from s in db.Table
select s;
category = category.Where(x => x.CategoryName.Contains(searchText));
category = category.OrderBy(x => x.CategoryName);
int pageSize = 6;
int pageNumber = 1;
return View(category.ToPagedList(pageNumber, pageSize));
}
Thanks in advance.

Passing the selected value of the radiobutton to action link

I am very new to MVC, I have to display the value coming from the database in a table format and show the radio buttons in front of each display so that user can select whatever option they want to choose, I need to post that option to the controller. Below is what I am doing.
#model IList<CertificateModel>
#{
ViewBag.Title = "RefreshCertificates";
}
<h2>
RefreshCertificates</h2>
#using (Html.BeginForm())
{
<table cellpadding="1" style="text-align: center; border: 5 px">
<tr>
<td>
</td>
<td>
Name
</td>
<td>
Issuer
</td>
</tr>
#for (var i = 0; i <= Model.Count - 1; i++) {
#Html.HiddenFor(x=>x[i].Subject)
<tr>
<td>
#Html.RadioButtonFor(x => x[i].Subject, true, new { #name = "optionsRadios", #id = "rbtrue" })
</td>
<td>
#Html.DisplayFor(x => x[i].Subject)
</td>
<td>
#Html.DisplayFor(x => x[i].Issuer)
</td>
</tr>
}
</table>
}
<table>
<tbody>
<tr>
<td>
#Html.ActionLink("STANDARD", "SelectCertOk", "LogIn", new { Type = "STANDARD", }, new { #class = "button" })
</td>
<td>
</td>
</tr>
</tbody>
</table>
Below is my model
public class CertificateModel
{
public string Subject
{
get { return cert.Subject; }
}
public string Issuer
{
get { return cert.Issuer; }
}
public bool validCert { get; set; }
}
My Controller that is putting the data on the screen code is below:
public ActionResult RefreshCertificates()
{
certificates = new List<CertificateModel>();
// some code here to fill up the list
return View(certificates );
}
The output that is displayed on the page is like this(RB is a radio button)
Subject Issuer
RB Coffee Test1
RB Tea Test2
From the current database only two are output on the screen. the user is only supposed to select only one of the radio button and then hit the actionLink button.
My problem is that right now both the buttons are selected, i want only one of the radio button to be selected and also, I also want the value of that radio button to be posted to the controller.
so for e.g if the user selects Coffee and Test1 radio button then I want to pass
#Html.ActionLink("STANDARD", "SelectCertOk", "LogIn", new { Type = "STANDARD", }, new { #class = "button" })
Type=STANDARD and SubjectIssue Coffee,Test1 to the controller. My controller signature is like this
public void SelectCertOk(string Type, string SubjectIssue)
{
}
any help will be greatly appreciated.
You are doing the right thing, but unfortunately we can't override the name attribute like the id.
Update your view to include multiple radiobuttons with same 'name'.
#Html.RadioButton('Subject', x[i].Subject)
STANDARD
<script>
function SelectCertOk(){
var subject = $("input:radio[name=Subject]")
$.post("#Url.Content("~/ControllerName/SelectCertOk")", { SubjectIssue : subject}, function (data) {}
});
}
</script>
But it won't solve your purpose.
So i would prefer to use javascript to check/uncheck radiobuttons.

Why is the view not refreshed? (.Net MVC)

I am learning .Net MVC. I have a page where I show productlines. I want to filter the productlines by their suppliers via a dropdownlist.
My controller:
public class ProductlineController : Controller
{
SupplierRepository sr = new SupplierRepository();
ProductlineRepository pr = new ProductlineRepository();
public ActionResult Default()
{
SupplierModel sm = new SupplierModel();
List<Supplier> suppliers = sr.GetAll();
sm.Suppliers = (from s in suppliers select new SelectListItem {
Text = s.Name,
Value = s.Id.ToString()
}).ToList();
sm.Productlines = pr.GetAll();
return View("List", sm);
}
[HttpPost]
public ActionResult SupplierDropUsed(int id)
{
SupplierModel sm = new SupplierModel();
List<Supplier> suppliers = sr.GetAll();
sm.Suppliers = (from s in suppliers
select new SelectListItem
{
Text = s.Name,
Value = s.Id.ToString()
}).ToList();
Supplier supplier = sr.GetById(id);
sm.Productlines = supplier.Productlines.ToList();
return View("List", sm);
}
}
The default action shows all productlines. SupplierDropUsed is called when dropdownlist is changed.
The view:
#model RyfMvcTestApplication1.Models.SupplierModel
#{
Layout = null;
}
List
<script type="text/javascript">
function supplierDropChanged() {
$.post("Productline/SupplierDropUsed", { id: $('#SupplierDrop').val() });
}
</script>
<div><strong>Filter by supplier</strong></div>
<br />
<div>
#Html.DropDownList("SupplierDrop", Model.Suppliers, "Select supplier", new { onChange = "supplierDropChanged()" })
</div>
<br />
<br />
<table>
<tr>
<th style="width:50px; text-align:left">Id</th>
<th style="text-align:left">Name</th>
<th style="text-align:left">Supplier</th>
</tr>
#foreach (var item in Model.Productlines) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Supplier.Name)
</td>
</tr>
}
</table>
When I select a supplier, the javascript and controller action are executed (I checked in debug mode). I also get the correct supplier id. But the view is never refreshed. I still see the list with all productlines.
You're doing a post via the jquery post method which submits the request and that is why your debug action is called but that result that is returned from the post call is never used to update your UI.

Resources