I have a requirement which I need to display details based on drop down selection. These details coming from database. when I click one user all then all the details belong to that user has to be displayed.
Model class
public class TaskDetails
{
public string ProjectID { get; set; }
public string ProjectName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EstimatedDate { get; set; }
public string TaskDescription { get; set; }
}
Controller
List<SelectListItem> query = DE.tblEmployees.Select(c => new SelectListItem
{ Text = c.Name, Value = c.Name }).ToList();
ViewBag.Categories = query;
return View();
View
<div class="dropdown">
#Html.DropDownList("CategoryID", (List<SelectListItem>)ViewBag.Categories, "--User Name--")
</div>
In the View I am loading all the user values inside the drop down. But when admin selects any of the user then all the details of user has to be displayed under a table. Upto here I am perfect but from here got strucked. How to move forward how to show the details of the user based on dropdown selection.
Steps
Create A view Where you can display all details of particular user.
Make Ajax call on user change and fetch specific user details from that use with partial view from controller.
Than append that html result to your html.
As Here
Drop Down Html
<div class="dropdown">
#Html.DropDownList("CategoryID", (List<SelectListItem>)ViewBag.Categories, "--User Name--")
</div>
Ajax
$("#CategoryID").change( function (event) {
var userId = $(this).val();
$.ajax({
url: "#Url.Action("GetUser","Controller")",
data: { id : userId },
type: "Get",
dataType: "html",
success: function (data) {
//Whatever result you have got from your controller with html partial view replace with a specific html.
$("#divPartialView").html( data ); // HTML DOM replace
}
});
});
Controller
public PartialViewResult GetUser(int id /* drop down value */)
{
var model = db.Users.find(id); // This is for example put your code to fetch record.
return PartialView("MyPartialView", model);
}
Create a partial view, which is basically to bind data for user details. For example you created a partial view called, userDetails.cshtml.
Add the model reference inside your partial view like bellow,
#model Your_Project_Name.ModalFolderName.TaskDetails
You need to write the html code inside details partial view to bind data.
Suppose you have a div with id="mydetailsTable" inside your main view, where you want to load the user details data after drop down select.
Then call an ajax method in drop down change event, and get the data and load it inside mydetailsTable div. check my bellow code,
$(".myDropdown").change(function() {
var id = $(this).val();
$.ajax({
type: 'GET',
url: '/ControllerName/GetUserDetails/'+id,
contentType: 'application/html; charset=utf-8',
datatype: 'html',
success: function (data) {
$('#mydetailsTable').html('');
$('#mydetailsTable').html(data);
})
});
See, .myDropdown is my class of drop down. You need to add.
Your Action method will be like this,
public ActionResult GetUserDetails(int userId)
{
//fetch the data by userId and assign in a variable, for ex: myUser
return PartialView("userDetails",myUser);
}
That's it. Hope it helps :)
Related
Hi im trying to call a method from controller from view just to display the "staff_name"
Controller
public JsonResult getStaffName(int staff_id)
{
var staffname = (from a in db.master_staff where b.staff_id == staff_id
select a.staff_name).SingleOrDefault();
return Json(staffname,JsonRequestBehavior.AllowGet);
}
View
int[] staff_id = { 24,25,26 };
#foreach (var n in staff_id){
//call method getStaffName from Controller to get "staff_name"
}
it suppose to get the "staff_name" according to the "staff_id"
is there any possible method for this situation?
To call method from controller to view you have to use ajax call from view.
here is ajax call syntax in asp.net mvc:
$.ajax({
type: "GET",
url: '#Url.Action("controller method name", "controller name")',
data: { searchText: value },
contentType: "application/json; charset=utf-8",
dataType: 'json',
success: function (result) {
},
error: {
}
});
type can be GET or POST depending on your controller method type.
In URL attribute two parameters are passed the first one is controller method name and second one is controller name.
In data attribute you have to pass the values which are required to pass in controller from view such as parameters in controller method.
In success and error attribute you have to write a block of code which should be executed in both cases. such as display data on UI upon success and error message on failure.
Do not do this. It is the way to the Dark side :) And each JSON request is taking some time.
Create model to store your staff
Fill it in controller (or even better in some business logic class)
Display in your view
public ActionResult Staff()
{
// This would be nice to have as separate Data Access Layery class
var staffs = GetStaffs();
return View(staffs);
}
private static StaffDto[] GetStaffs()
{
// One call to database is better that several
var staffs = db.master_staff
.Where(x => x.staff_id > 0) // Any other condition, if needed
.Select(x => new StaffDto(x.staff_id, x.staff_name))
.ToArray();
return staffs;
}
// Data Transfer Object class to separate database from presentation view
public class StaffDto
{
public int StaffId { get; set; }
public string Name { get; set; }
public StaffDto(int staffId, string name)
{
StaffId = staffId;
Name = name;
}
}
Your view file (Staff.cshtml in my case)
#model IEnumerable<TestMvc.Controllers.StaffDto>
<div>
#foreach (var staff in Model)
{
#staff.Name<br />
}
</div>
And, as bonus, you could unit test it easily
private readonly HomeController _homeController = new HomeController();
[TestMethod]
public void Staff_CheckCount()
{
var result = _homeController.Staff();
Assert.IsInstanceOfType(result, typeof(ViewResult));
var actual = ((ViewResult)result).Model as StaffDto[];
Assert.IsNotNull(actual);
Assert.AreEqual(3, actual.Length);
}
You can do it like this:
#Html.Action("getStaffName", "YourController", staff_id)
For more info, look at child actions: https://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx/
However, I do not know what you are trying to achieve with this.
As part of a form, I need to display some data about an object from a dropdown. The user using the field is assigning a student to a section of a class, and will need to see the current count of open/filled seats in the class.
Currently, I am building my class drowndown like this:
#Html.DropDownList("Sections Available", new SelectList(Model.AvailableSections, "Id", "Name"))
and later I want to have a div that lists out the availability like:
Open Slots: #someVariable
Filled Slots: #someOtherVariable
This information is part of my Sections model that belongs to the VM for this page. Those look like:
public class ApproveStudentViewModel
{
public string FriendlyName { get; set; }
public List<Section> AvailableSections { get; set; }
public Guid UserId { get; set; }
}
public class Section
{
public Guid Id {get; set; }
public string Name {get; set; }
public int SpacesRemaining {get; set;}
public int SpacesTaken {get; set;}
}
I have a controller call available for getting the section by Id, but that is as far as I've gotten on figuring this out. I'm very new to using MVC and Razor in particular, and this sort of thing should not be as hard as it is appearing to be.
One way you could do this is by using jQuery if you are open to that.You can then make the jQuery AJAX function create a new Div based on the Section by ID. So changes to your code would be as follows:
#Html.DropDownList("SectionsAvailable", new SelectList(Model.AvailableSections, "Id", "Name"))
<div id="slot-information"></div>
The at the end of your Razor page you need to make sure that you are referencing jQuery
<script src="~/lib/jquery/dist/jquery.js"></script>
Now you can create an AJAX call to your controller function and send the sectionID as a parameter:
<script>
$("#SectionsAvailable").change(function () {
$.ajax({
type: "GET",
contentType: "application/json",
dataType: "json",
url: '#Url.Content("~/")' + "{ControllerName/GetSpaceInfo",
data: { sectionID: $("#SectionsAvailable").val() }, //id of the section taken from the dropdown
success: function (data) {
var items = '';
$.each(data, function (i, row) {
items += "<label> Open Slots: " + row.SpacesRemaining + "</label> <label> Filled Slots: " + row.SpacesTaken + "</label> ";
//To test in your browser console
console.log(row.SpacesTaken);
console.log(row.SpacesRemaining);
});
$("#slot-information").html(items);
},
error: function () {
alert("oops");
}
});
});
Finally in your controller (maybe SectionsController) create the following function to return the JSON object.
// returns a list of space available based on section
[HttpGet]
public ActionResult GetSpaceInfo(int sectionID)
{
List<Section> sect = new List<SSection>();
//Should only return 1 item to the JSON list
sect = _context.Sections.Where(m => m.Id == sectionID).ToList();
return Json(sect);
}
Haven't tested the code but this should do the trick. If it isn't working check the console in your browser.
This is my first MVC project and I've been trying to figure out how to refresh a Partial View after calling a controller method from AJAX.
My classes look like this and I want to add as many courses as I want for a semester in one view.
public class CourseViewModel
{
public int SemesterID {get; set;}
public List<Course> Courses {get; set;}
}
public class Course
{
public string CourseID {get; set;}
public string CourseTitle {get; set;}
}
An Example page looks like this:
In my view, I set up a typeahead for the Course textbox. When a user select a course from a list of typeahead suggestion, I call the SaveCourse method in the controller and it successfully saves. The problem is that I cannot refresh the Partial View after the save occurs.
My View (Index.cshtml):
#using Project.ViewModels;
#model Project.ViiewModels.CourseViewModel
<div id="divCourseTypeahead">
<input class="typeahead form-control" type="text" />
</div>
<div id="listCourses">
#{Html.RenderPartial("_CourseList");}
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#divCourseTypeahead .typeahead').typeahead({
//setup typeahead
}).on('typeahead:select', function(obj, datum){
var semesterId = #Model.SemesterID
$.ajax({
type: "GET",
url: "/Course/SaveCourse/",
data: { semesterId: semesterId, courseId: datum.id },
success: function (result) {
alert(result);
}
});
});
</script>
What I've tried (1):
I tried return a PartialVeew from SaveCourse.
public PartialViewResult SaveCourse(int semesterId, string courseId)
{
//Insert course
CourseViewModel data = new CourseViewModel(semesterId);
return PartialView("_CourseList", data);
}
When I do this, the PartialView does not get refreshed and the alert(result); in ajax success function does not get called.
What I've tried (2):
public ActionResult SaveCourse(int semesterId, string courseId)
{
//Insert course
return RedirectToAction("Index", "Course", new {id=semesterId});
//in Index, I return `CourseViewModel`
}
When I do this, the alert(result); in AJAX success function gets called so I added $('#listCourses').html(result); in the success function then the PartialView does refresh but I get two textboxes like the image below.
I've tried many other options but I am so confused. Could someone please help me how I can achieve what I want to do?
You have a couple of problems in your document.ready function.
1. You're passing
courseId: datum.id
However, datum object can't be seen anywhere in the javascript function.
Maybe you're defining it somewhere else.
instead of alert line I suggest write
$('#listCourses').html(result);
Also, Remove #{Html.RenderPartial("_CourseList");}, because since _CourseList partial view requires a list model, and you're not providing it during render. So the page will not load.
I could achieve below result with these changes.
I have a create user page - it currently list a table with all current users in system. I can click create new button - this does a jQuery ajax submit which calls my controller method and returns a partial view and loads the new modal jQuery dialog box which contain all the fields i.e Forename, Surname, etc. So I have my table in the background and this dialog box on centre of screen in modal view so it takes precedence. If a username is clicked the same method is called excpet a uniquie user id is passed in so the dialog form is not loaded blank - it is loaded with the current details of the user from the DB and as a user id was there a Delete button is added to the User dialog box as well as Save and Cancel which are there on create new.
Now for the problem - I have enclosed my Partial view page as below - I have also added its own js to the partial view as I need to show/hide diff dropdown boxes based on some choices made by user.
#using (Html.BeginForm("UserAction", "Admin", FormMethod.Post, new { id = "userActionForm" }))
{
//Fields on the dialog box....
}
on the dialog box then - I have buttons i.e
<input id="DoDeleteUser" type="button" class="dialog-button" value="Delete User" style="margin: 5px" />
and then in the JS file for my page I have the following:
$('#DoDeleteUser').click(function (event) {
//alert("Delete Button Pressed"); - In for debugging
$('#userID').val($(event.target).attr("userId")); - get id value into hidden field on page
$('action').val('Delete'); - put action string into hidden field on page
$('#userActionForm).submit();
});
$('#userActionForm').submit(function () {
var formData = $("#userActionForm").serializeArray();
$.ajax({
url: this.action,
type: this.method,
data: formData,
success: function (result) {
$('#dialogContainer').html(result);
}
});
return false;
});
My dialog container is the same container which the first page loads which I want to update when I come back from the UserAction method with a simple message saying "User Updated" or "User Deleted" and an OK button which when clicked would refresh the whole page (so the main table would be updated)
Then on my controller I have the method like:
public ActionResult UserAction(UserModel model)
{
if (ModelState.IsValid)
{
if(model.Action == "Delete")
//Go and do delete
return PartialView ("UserActionSuccess", model);
//close if etc etc
However I set a breakpoint on my UserAction method in my controller but it is never getting hit when I hit the Delete User button or the Save User button which is were I am stuck.
You're sending your post with form data, but you're expecting a model (json object) on your UserAction. You should use parameters instead to match the form input.
public ActionResult UserAction(string id)
{
...
}
You should consider using message classes for CRUD methods. It should make the logic a bit cleaner.
public class CreateUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class DeleteUser
{
public int UserId { get; set; }
}
Then you would have a controller action for each CRUD method, like so:
public ActionResult Create(CreateUser message)
{
}
public ActionResult Delete(DeleteUser message)
{
}
In jQuery, you would prepare the AJAX call as follows:
$.ajax({
url: "/yourcontroller/create",
type: "POST",
data: formData,
success: function() { console.log('success'); },
error: function() { console.log('error'); }
});
$.ajax({
url: "/yourcontroller/delete/" + $("#userId").val(),
type: "DELETE",
success: function() { console.log('success'); },
error: function() { console.log('error'); }
});
Finally, once you wire those up, you can use Firebug to check the jQuery side of things, and then use breakpoints in VS administrator mode to make sure the calls are populating your message objects correctly.
Is it possible to use HTMl.RenderAction using ajax to provide the parameter?
I have a controller action like this
[ChildActionOnly]
Public ActionResult EmployeeData(string id)
{
Employee employee = new Employee();
//do work to get data
Return PartialView(employee);
}
The partial view is just a small table with some employee data (name, address, etc)
I then have a page with a drop down list of employees with the data field being the id needed for EmployeeData(string id)
I would like to use ajax so when a employee is selected from a drop down list the EmployeeData partial view will appear below it without refreshing the page. Then again if another employee is selected.
Though i am not sure how to do this, if it is possible.
As was recommended here is what I have now. (please don't mind that this is not the employee data example i mentioned above, that data is not ready in the DB and I have multiple areas that will do this same thing so I decided to work on this one today)
here is my the JS in my view
$("#repList").change(function () {
var id = $("#repList").val();
$.ajax({
url: '/Reporting/GetSalesTargets/' + id,
success: function (result) {
$("#partialdiv").html(result);
},
error: function () {
alert("error");
}
});
});
I am getting to the controller action that will return the view, here is it.
public ActionResult GetSalesTargets(string id)
{
int month = DateTime.Now.Month;
SalesMarketingReportingService mktSrv = new SalesMarketingReportingService();
SalesTargetModel model = mktSrv.GetRSMSalesTargetModel(id, month);
return PartialView(model);
}
It is possible but you have to remove the [ChildActionOnly] attribute. The it becomes a normal action that returns a partial view the you could invoke using AJAX:
$.ajax({
url: '/home/employeedata/123',
success: function(result) {
$('#somedivid').html(result);
}
});