Why is the view not refreshed? (.Net MVC) - asp.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.

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" };
}

how to prepopulate the selected value in Db in a #html.Dropdown in mvc

I want to pre-populate the selected value stored in the DB in the Dropdown list in mvc.
Controller
public ActionResult POCallDown(int? skuid)
{
var supplierlist = db.QuoteMasters.Include(e => e.CommunicationMode).Include(e => e.SKUMaster).Include(e => e.EmployeeMaster).Include(e => e.SupplierMaster).Include(e => e.CreditTerm);
var SupplierforSKU = (from supplierdetails in supplierlist.ToList()
where skuid.HasValue && skuid.Value == supplierdetails.SKU
select supplierdetails).ToList();
foreach(var cred in SupplierforSKU)
{
ViewBag.CreditId = new SelectList(db.CreditTerms, "CreditId", "Description",cred.CreditTermId);
}
return View(SupplierforSKU);
}
View
<table>
<th>Credit</th>
<tr><td> #Html.DropDownList("CreditId")</td></tr>
</table>
I get the first value in the db for all the rows in the view. Please help. I tried using this Populate dropdown but it dowsnot give me the desired result.
Try this :
<table>
<th>Credit</th>
<tr>
<td>
#Html.DropDownList("CreditId", null, "--Select One--", new { #id = "CreditId", #name ="CreditId"})
</td>
</tr>
</table>

How to add Edit, Delete and Search functionality in single view in MVC?

I'm new to MVC.
on MSDN i've studied that there should be folder in view with the same name of controller. For every Action Method in the controller we have to create a View in the same folder.
I'm creating a test application in which:
I have a homeController with an Index ActionMethod. Corresponding to it i have a View in View/home/Index, which simply show the listing of the employees.
I know i can add a [HTTP POST] Index ActionMethod in the homeController.
But i want to add the Delete and Search functionality on the view. So that a user can search the employees with there name and can delete an employee on the same page.
I don't know how can i move ahead for this functionality.
Still i'm using this code.
homeController
public ActionResult Index()
{
ViewBag.text = "Records Listing";
var q = from p in objEmp.tbemployees select p;
return View(q);
}
Index.cshtml
#model IEnumerable<MvcApplication6.Models.tbemployee>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>#ViewBag.text</h1>
<table style="font-size:15px;">
<tr>
<th>
Name
</th>
<th>
Address
</th>
<th>
Sallary
</th>
</tr>
#foreach (var item in Model)
{
<tr >
<td style="padding:7px;">
#Html.DisplayFor(mm => item.ename)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.eadd)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.esal)
</td>
<td style="padding:7px; color:Blue; text-decoration:underline;">
#Html.ActionLink("Edit", "Edit", new { id = item.empno })
</td>
</tr>
}
</table>
Thanks.
For the Delete you could add a column in the table that will invoke a controller action and pass it the current record id:
<tr>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.ename)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.eadd)
</td>
<td style="padding:7px;">
#Html.DisplayFor(mm => item.esal)
</td>
<td style="padding:7px; color:Blue; text-decoration:underline;">
#Html.ActionLink("Delete", "Delete", new { id = item.empno })
#Html.ActionLink("Edit", "Edit", new { id = item.empno })
</td>
</tr>
and your Delete action:
public ActionResult Delete(int id)
{
... use the passed id to delete the record from the database
return RedirectToAction("Index");
}
for the Edit functionality you could have a controller action that will fetch the record and render a view that will allow for editing:
public ActionResult Edit(int id)
{
var employee = objEmp.tbemployees.FirstOrDefault(x => x.Id == id);
if (employee == null)
{
// no employee with the specified id was found
return new HttpNotFound();
}
return View(employee);
}
and then you could have a corresponding ~/Views/Home/Edit.cshtml view:
#model Employee
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.ename)
#Html.EditorFor(x => x.ename)
</div>
<div>
#Html.LabelFor(x => x.eadd)
#Html.EditorFor(x => x.eadd)
</div>
...
<button type="submit">Save</button>
}
and of course a corresponding action to update the record when this form is submitted:
[HttpPost]
public ActionResult Edit(Employee employee)
{
... update the employee record
return RedirectToAction("Index");
}
You can add and implement a Delete action method in your controller. Then in your view, call #Html.ActionLink("Delete", "Delete", new { id = item.empno }). This will return a hyperlink which links to your Delete method in the controller.

MVC 3 - The model item passed into the dictionary is of type 'System.Collections.Generic.List`1

Hi I am very new to mvc and need help
I created this
public ActionResult Index()
{
var joblist = (from s in _entities.TaleoJobs
group s by new { s.JobTitle}
into myGroup
where myGroup.Count() > 0
select new { myGroup.Key.JobTitle }
);
return View(joblist.ToList());
}
but when I create the view I get the following error
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType01[System.String]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[careers.TaleoJobs]'.
Here is the code for the view
*#model IEnumerable<careers.TaleoJobs>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
JobTitle
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.JobTitle)
</td>
</tr>
}
</table>*
I would be grateful if anyone can help - tried looking at other examples but i am at a loss.
When you are selecting the list, you are only selecting the JobTitle, which is a string. So your list is indeed a List<string>.
You can either update your select to select the entire object:
var joblist = (from s in _entities.TaleoJobs
group s by new { s.JobTitle}
into myGroup
where myGroup.Count() > 0
select s
);
Or, keep your current select and update the type of the view to:
IEnumerable<string>

Resources