Select2 field not rendering inside partial view - c#

On a main page for example the Edit.cshtml I have this code here which renders a select 2 with the country flags and it works fine, but when I attempt to move it into a partial view it does not work.
My Html Field which is inside PleasureCraftEditViewPartial.cshtml
<div class="form-group">
#Html.DisplayNameFor(model => model.MooringCountry)
<select asp-for="MooringCountry" class="form-control select2" style="height:35px" id="MooringCountry" name="MooringCountry">
<option>Please select Mooring Country</option>
</select>
<span asp-validation-for="MooringCountry" class="text-danger"></span>
</div>
The above is in my PleasureCraftEditViewPartial.cshtml
#if (#Model.VesselCat == (int)VesselCat.VesselCatType.Commercial) {
#await Html.PartialAsync("ComercialEditViewPartial")
}
#if (#Model.VesselCat == (int)VesselCat.VesselCatType.MotorBoats ||
#Model.VesselCat == (int)VesselCat.VesselCatType.SailingBoats ||
#Model.VesselCat == (int)VesselCat.VesselCatType.SmallBoats) {
#await Html.PartialAsync("PleasureCraftEditViewPartial")
}
The below is in my Edit.cshtml
<script>
$(function () {
//Initialize Select2 Elements
$('.select2').select2();
var isoCountries = [
{ id: 1, flag: 'gbp', text: 'United Kingdom' },
{ id: 2, flag: 'usa', text: 'United States' }
];
function formatCountry(country) {
if (!country.id) { return country.text; }
var $country = $('<span class="flag-icon flag-icon-' + country.flag + ' flag-icon-squared"></span>' + '<span class="flag-text">' + country.text + "</span>");
return $country;
};
//Assuming you have a select element with name country
// e.g. <select name="name"></select>
$("[id='Flag']").select2({
placeholder: "Please Select a Flag",
templateResult: formatCountry,
data: isoCountries
});
$("[id='MooringCountry']").select2({
placeholder: "Please Select a Mooring Country",
templateResult: formatCountry,
data: isoCountries
});
$('#Flag').trigger('change');
});
</script>
There are no errors in my console
Just an empty dropdown

Related

Filling Cascading dropdown from database during edit

I need help filling dependent dropdowns. I have dependent dropdown that work when entering data, select the State dropdown and the dependent dropdowns reload based on the state selected.
Issue is when I want to edit, the state is filled and selected from database, but the dependents don't get filled and selected. The onChange function doesn't get activated or hit.
Here are my codes:
<div class="form-row">
<div class="col">
<div class="form-group">
<label asp-for="Sposted"></label>
<select asp-for="Sposted"
class="form-control"
asp-items="#(new SelectList(#ViewBag.statelist, "Stateid", "Statename" ))"
onchange="sposted(this)">
</select>
</div>
</div>
<div class="col">
<div class="form-group">
<label asp-for="Pcommand"></label>
<select asp-for="Pcommand" class="form-control" id="Pcommand"
asp-items="#(new SelectList(string.Empty, "Commandid", "Cfname"))">
<option>Select ...</option>
</select>
</div>
</div>
<div class="col">
<div class="form-group">
<label asp-for="PayP"></label>
<select asp-for="PayP" id="PayP"
class="form-control"
asp-items="#(new SelectList(string.Empty, "Ppid", "Ppfull"))"></select>
</div>
</div>
</div>
The 2 dropdowns, Pcommand and PayP are dependent on sposted. Again, when editing, the sposted drop down is selected and filled from db, but doesn't cascade to the other 2.
Here is the JS:
<script type="text/javascript">
//$(document).ready(function () {
//$('#Sposted').change(function () {
function sposted(stateid) {
console.log(stateid.value);
var url = '#Url.Content("~/")' + "MemberList/RetPayPoint";
//var ddlsource = "#Sposted";
//$.getJSON(url, { Stateid: $(ddlsource).val() }, function (data) {
$.getJSON(url, { Stateid: stateid.value }, function (data) {
var items = '';
$("#PayP").empty();
$.each(data, function (i, pp) {
items += "<option value='" + pp.value + "'>" + pp.text + "</option>";
});
$('#PayP').html(items);
});
}//});
// });
</script>
Thank you in advance.
A few days later, I have decided to add the controller method that is supposed to fill the dropdowns in the view.
public IActionResult DisplayMem()
{
var statelist = _mr.GetStates().ToList();
statelist.Insert(0, new ToxState { Stateid = 0, Statename = "Select..." });
ViewBag.statelist = statelist;
var rank = _mr.GetRanks().ToList();
rank.Insert(0, new ToxRank { Rankid = 0, Fullname = "Select..." });
ViewBag.rank = rank;
//memid = memlist.FirstOrDefault().MemberId;
var obj = _mr.MemberInfo((long)_ar.FindAcc(long.Parse(HttpContext.Session.GetString("memberid"))).MemId);
return View(obj);
}
All he information needed to fill the view elements are in obj. It loads the selects the state from the id in obj, but the onchange isn't fired to fill the dependent dropdowns.
When editing using selected stateid you need to get both dropdowns data, just like you are getting PayP data by using selected stateid like:
$.getJSON(url, { Stateid: stateid.value }, function (data) {
var items = '';
$("#PayP").empty();
$.each(data, function (i, pp) {
items += "<option value='" + pp.value + "'>" + pp.text + "</option>";
});
$('#PayP').html(items);
});
You will call your function sposted and pass selected stateid both times while creating or editing.
After days of research, I couldn't seem to find a way to to force the onchange to call Ajax to dynamically fill the dependent dropdowns. So I took a cue from Mateen's 3rd comment and rewrote the method in the controller to read load the relevant items into a ViewBag.
public IActionResult DisplayMem()
{
var statelist = _mr.GetStates().ToList();
statelist.Insert(0, new ToxState { Stateid = 0, Statename = "Select..." });
ViewBag.statelist = statelist;
var rank = _mr.GetRanks().ToList();
rank.Insert(0, new ToxRank { Rankid = 0, Fullname = "Select..." });
ViewBag.rank = rank;
var obj = _mr.MemberInfo((long)_ar.FindAcc(long.Parse(HttpContext.Session.GetString("memberid"))).MemId);
ViewBag.payp = _mr.GetPayPoint(obj.Sposted.Value).ToList();
ViewBag.pcommand = _mr.GetCommand(obj.Sposted.Value).ToList();
return View(obj);
}

ASP.NET MVC - Html.Action Sending Empty List

I am using Ajax to populate a partial view in my web application. This partial view contains a link to download a PDF file based upon the data that is currently in the table / List<> of the model.
The partial view is as follows:
#model Inspection_Reports.ViewModel.SummaryReportViewModel
<table id="summaryReportTable" class="table-condensed table-striped">
<thead><tr><td>Inspector</td><td>Attendant</td><td>Property</td><td>Room Number</td><td>Date</td><td>HK Score</td><td>Maint. Score</td></tr></thead>
<tbody id="resultsContainer">
#foreach (var report in #Model.reportsList)
{
<tr><td>#report.inspect.empName</td><td>#report.attendant.empName</td><td>#report.location.locName</td><td>#report.room</td><td>#report.endTime</td><td>#report.hkDisplay</td><td>#report.mainDisplay <input type='hidden' name='reportId[i]' /></td></tr>
}
</tbody>
</table>
#Html.ActionLink("Export as PDF", "GenerateSummaryPDF", new { summary = #Model.reportsList })
GenerateSummaryPDF method:
public FileResult GenerateSummaryPDF(List<report_summary> summary) {
Document doc = pdfWorker.readyDocument("Inspection Report, Generated " + DateTime.Now.ToString("MM-dd-yyyy"));
pdfWorker.createSummaryReport(doc, summary);
pdfWorker.savePDF(doc, String.Format("{0}/Inspection_Summary_{1}.pdf", #"C:\Users\Khandokar\Desktop", DateTime.Now.ToString("MM-dd-yyyy")));
return File(String.Format("{0}/Inspection_Summary_{1}.pdf", #"PATH", DateTime.Now.ToString("MM-dd-yyyy")), "application/pdf", "Inspection.pdf");
The problem is that, when the GenerateSummaryPDF is called, the summary list is empty. The list is not null, but merely has no items in it.
However, I am not sure why this is the case. When I click the export link, there is data in Model.reportsList; it is visible in the table and further verified by setting a breakpoint.
The parent view:
#model Inspection_Reports.ViewModel.SummaryReportViewModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Report Summaries</title>
</head>
<body>
<h2>Summary Reports</h2>
<form class="form-horizontal">
<div class="form-group"><label class="control-label col-md-2">Start Date: </label><div class="col-md-4"><input class="form-control summaryFilter" type='text' value="#Model.fromDate" name='startDate' id='startDate' /></div><label class="control-label col-md-2">End Date: </label><div class="col-md-4"><input type='text' value="#Model.toDate" class='form-control summaryFilter' name='endDate' id='endDate' /></div></div>
<div class="form-group">
<label class="control-label col-md-2">Filter By: </label>
<div class="col-md-4">
<select class="form-control summaryFilter" name="filterTypeList" id="filterTypeList">
<option value="">Select...</option>
<option value="Property">Property</option>
<option value="Attendant">Attendant</option>
<option value="Inspector">Inspector</option>
</select>
</div>
<label class="control-label col-md-2">Filter Selection: </label><div class="col-md-4">
<select class="form-control summaryFilter" name="filterSelectionList" id="filterSelectionList"></select>
</div>
</div>
</form>
<div id="reportResults">
#{Html.RenderPartial("SummaryPartialView", Model);}
</div>
#section scripts {
<script src="~/Scripts/ajaxReports.js"></script>
}
</body>
</html>
The methods used to populate the partial view (based largely on this article: https://cmatskas.com/update-an-mvc-partial-view-with-ajax/)
[HttpGet]
public async Task<ActionResult> GetSummaryReports(string fromDate, string toDate, string filterType, string filterValue)
{
DateTime from = Convert.ToDateTime(fromDate);
DateTime to = Convert.ToDateTime(toDate);
Int32 filterValID = Int32.Parse(filterValue);
SummaryReportViewModel vm = await GetSummaryVM(from, to, filterType, filterValID);
return PartialView("SummaryPartialView", vm);
}
private async Task<SummaryReportViewModel> GetSummaryVM(DateTime from, DateTime to, string filterType, int filterValID)
{
SummaryReportViewModel vm = new SummaryReportViewModel();
to = to.AddDays(1);
var reports = dbContext.report_summary.Where(r => r.endTime <= to && r.endTime >= from);
if (filterType.Equals("Property"))
{
reports = reports.Where(r => r.locationID == filterValID);
}
else if (filterType.Equals("Attendant"))
{
reports = reports.Where(r => r.employee == filterValID);
}
else
{
reports = reports.Where(r => r.inspector == filterValID);
}
vm.reportsList = reports.ToList<report_summary>();
return vm;
}
The Ajax
$(".summaryFilter").change(function () {
var fromDate = $("#startDate").val();
var toDate = $("#endDate").val();
var filterType = $("#filterTypeList").val();
var filterValue = $("#filterSelectionList").val();
if (filterValue != null || typeof (filterValue) != typeof (undefined)) {
$.ajax({
url: "GetSummaryReports?fromDate=" + fromDate + "&toDate=" + toDate + "&filterType=" + filterType + "&filterValue=" + filterValue,
type: 'get',
success: function (data) {
$("#reportResults").html(data);
},
});
}
});
Thanks for any help.
You're asking a bit much of a Get method - you should instead switch to a form that Posts to allow model binding to handle your complex list object.

How to trigger a partialview from webgrid row selection by using jquery in Asp.net mvc

I was comparing a webgrid and a dropdownbox .I want to trigger a partial view CoursePartialDemo via Ajax and has to pass the primary key to the action responsible for partialview.In a dropdownbox i have successfully done it by following Jquery.Similarly if i select a row in a webgrid how can i trigger partial view and pass the primary key which is "id" for webgrid.following code is responsible for dropdownbox
<select id="ddlEmployeeCourse">
#*Iterating Employee ViewModel *#
#foreach (var emp in Model)
{
<option value="#emp.EmpCode">#emp.EmpName</option>
}
</select>
<h4>Courses Of Selected Employeee</h4>
<div id="CoursesForEmp">
</div>
<script>
function getCourseTable(selectedEmpCode) {
$.ajax({
// Get Course PartialView
url: "/Home/CoursePartialDemo",
type: 'GET',
data: { EmpCode: selectedEmpCode },
success: function (data) {
jQuery("#CoursesForEmp").html(data);
},
error: function (error) {
alert("Error: Please try again.");
}
});
}
</script>
<script>
jQuery(document).ready(function () {
jQuery("#ddlEmployeeCourse").change(function (index) {
var selectedEmpCode = $(this).val();
getCourseTable(selectedEmpCode);
});
</script>
and here is my webgrid code
<div id="">
#grid.GetHtml(tableStyle: "webGrid",
headerStyle: "header",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
//grid.Column("Id", format: (item) => item.GetSelectLink(item.Id)),
grid.Column("id", "id"), //primary key
grid.Column("countryname", format: (item) => item.GetSelectLink(item.countryname)),
grid.Column("continent", "Description", style: "continent"),
grid.Column("language", "language")
))
</div>
UPDATE
i have done some changes in webgrid code like shown below
#if (grid.HasSelection)
{
product = (firstmvc4.Models.Country)grid.Rows[grid.SelectedIndex].Value;
var val = #product.id;
<script>
getCourseTable(val)
</script>
}
but javascript function is triggering at all
Change
<script>
getCourseTable(val)
</script>
to
Html.RenderAction("CoursePartialDemo", new { EmpCode = val });
and place inside the CoursesForEmp element.
For example:
<div id="CoursesForEmp">
#if (grid.HasSelection)
{
product = (firstmvc4.Models.Country)grid.Rows[grid.SelectedIndex].Value;
var val = product.id;
Html.RenderAction("CoursePartialDemo", new { EmpCode = val });
}
</div>
I'm not sure if you want to show any product details or employee.

Code first, Data is not inserting into database using cascading dropdown list

in my create [ Http post ] method, all data is inserting except the cascading drop down items. I have Department, Subject and section model. One department can have many subjects, one subject can have many sections. after adding jquery submit portion, it shows, form can not be submitted! then it returns to the index! here is my codes from Section Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Section section)
{
if (ModelState.IsValid)
{
db.Sections.Add(section);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DepartmentId = new SelectList(db.Departments, "DepartmentId", "Name", section.DepartmentId);
ViewBag.SubjectId = new SelectList(db.Subjects, "SubjectId", "SubjectName", section.SubjectId);
return View(section);
}
Here is my create.chtml under Secion view:
#model MvcBCS.Models.Section
#{
ViewBag.Title = "Create Section";
}
#section scripts {
<script type="text/javascript">
$(function() {
$.getJSON("/Section/Departments/List", function(data) {
var items = "<option> Show Department List </option>";
$.each(data, function(i, department) {
items += "<option value='" + department.Value + "'>" + department.Text + "</option>";
});
$("#Departments").html(items);
});
$("#Departments").change(function() {
$.getJSON("/Section/Subjects/List/" + $("#Departments > option:selected").attr("value"), function(data) {
var items = "<option> Show Subject List </option>";
$.each(data, function(i, subject) {
items += "<option value='" + subject.Value + "'>" + subject.Text + "</option>";
});
$("#Subjects").html(items);
});
});
});
$(function() {
$('#submit').on("click", function () {
var form = $(this).parent("form");
$.ajax({
type: "POST",
url: form.attr('action'),
data: form.serialize()
})
.success(function() {
alert("Your form has been submitted");
})
.error(function() {
alert("Your form has not been submitted");
});
return false;
});
});
</script>
}
<h2>Create Section</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Section</legend>
<label for="Departments">Departments</label>
<select id="Departments" name="Departments"></select>
<label for="Subjects">Subjects</label>
<select id="Subjects" name="Subjects"></select>
<label for="Sections">Section</label>
<input id="Sections" name="Sections" type="text" />
<p>
<input type="submit" id="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
I think you need to change the name/Id of your both dropdownlist regarding your properties in your section.
For Departments to DepartmentId and Subjects to SubjectId. They need to match with so in your Post the binder will attach the correct value

checking returned children in knockout js

i am using knockout to display items on page. I have a list of groups ex: Group 1, Group 2,... each group is in it's own div. When i click on one of the groups it will open and display the items in the group. Some of my groups don't have any items to display and instead of it not showing anything i would like to change that to display: "No items in group"
I am having trouble doing this in the view in javascript and thought i would be able to do it in my knockout/jquery script
View:
<div class="accordion-group elements-by-item">
<div class="accordion-heading">
<a class="ui_title accordion-toggle text_x-large item_accordion_toggle" data-toggle="collapse" data-parent="#ByTimeIndex"
data-bind="text: Title() != null ? Title() : Identity(), attr: { 'href': '#itemContent_' + Id(), 'data-item-id': Id() }">
</a>
</div>
<div class="accordion-body collapse state-loading" data-bind="attr: { 'id': 'itemContent_' + Id(), 'data-item-id': Id() }">
#Html.Partial("_itemElements")
</div>
</div>
**_itemElements Page:**
<div class="accordion-inner no_border" data-bind="foreach: Children">
<div class="element">
........
</div>
<div>
knockout/Jquery js
$idx.ItemsRetrieved = new Array();
$idx.GetItemContent = function (element) {
var _itemId = element.attr('data-item-id');
var _elementData = $idx.itemData;
this.GetElementContent({
groupId: _itemId,
groupData: _elementData.items,
elementData: _elementData,
apiUrl: _courseIndexOptions.GetitemUrlPrefix + _itemId,
accordionBodySelector: '.accordion-body[data-item-id="' + _itemId + '"]',
accordionBtnSelector: 'a[data-item-id="' + _itemId + '"]',
viewModel: $idx.TimeViewModel
});
}
$idx.GetElementContent = function (options) {
if (linq.From($idx.ItemsRetrieved).Any(function (x) { return x == options.groupId })) {
$(options.accordionBodySelector).removeClass(constants.StateClasses.Loading);
return;
}
return Ajax.Get({
Url: options.apiUrl,
OnSuccess: function (data) {
var _items = linq.From(options.groupData);
var _itemToUpdate = _items.Where(function (x) { return x.Id == options.groupId; });
if (_itemToUpdate.Any()) {
_itemToUpdate.First().Children = data.Items;
}
ko.mapping.fromJS(options.elementData, options.viewModel);
sections.ElementArray.AddRange(data.Items);
$(options.accordionBodySelector).removeClass(constants.StateClasses.Loading);
$idx.ItemsRetrieved.push(options.groupId);
$(options.accordionBtnSelector).click();
}
});
how can i check if the children ItemsRetrieved = 0 and to set a message "No Items" to show in the view page?
You can do that :
<div class="accordion-inner no_border" >
<div data-bind="foreach: Children">
<div class="element">
</div>
</div>
<span data-bind="if : Children().length == 0">No items in group</span>
<div>
I hope it helps.

Categories