MVC 5 Cascading DropDownList Bootstrap selectpicker - empty list - asp.net-mvc

I am not a frontend guy but I have to do something.
I have two lists:
showTeam
showMember - cascading based on showTeam.
In my HTML source code I see all the items placed as option, but when I click the DropDownList I see 0 items to pick. If I remove the selectpicker all items are visible. Any help is appreciated.
#Html.DropDownList("showTeams", null, "-Select Team-", htmlAttributes: new { id = "ddshowTeams", #class = "selectCountry selectpicker show-tick form-control" })
#Html.DropDownList("showMembers", null, "-Select Team-", htmlAttributes: new { id = "ddshowMembers", #class = " selectCountry selectpicker show-tick form-control" })
Ajax call:
debugger;
$(document).ready(function () {
//Dropdownlist Selectedchange event
$("#ddshowTeams").change(function () {
alert("pehla andar");
$("#ddshowMembers").empty();
$.ajax({
type: 'POST',
url: '#Url.Action("GetListLabels","CTComparer")',
dataType: 'json',
data: { id: $("#ddshowTeams").val() },
success: function (mems) {
console.log("which ayaeee");
// states contains the JSON formatted list
// of states passed from the controller
$.each(mems, function (i, member) {
//alert('<option value="'
// + member.Value + '">'
// + member.Text + '</option>');
$("#ddshowMembers").append('<option value="'
+ member.Value + '">'
+ member.Text + '</option>');
});
},
error: function (ex) {
alert('Failed to retrieve states.' + ex);
}
});
return false;
})
});
Json method:
[HttpPost]
public ActionResult GetListLabels(int id)
{
var list = GetLabelList(id)
.Select(p =>
new SelectListItem
{
Value = "",
Text = p.Name
});
// this.ViewBag.SourceLabels = this.GetListLabelsSelectedItems(id);
// this.ViewData["showMembers"] = this.GetListLabelsSelectedItems(0);
return Json(list, JsonRequestBehavior.AllowGet);
}

Related

Set value of ng-select2 on a button click

The scenario is, I need to set the value of the dropdown (ng-select2) when a user presses on edit button present on the page. I am using ajax to fetch the options. The code is in angular.
I took reference from : https://github.com/tealpartners/ng-select2
<div class="form-div">
<label for="uploader">Select Uploader<span class="asterick-red">*</span>
</label>
<ng-select2 formControlName="uploader" id="uploader" [options]="select2Options" width="270">
</ng-select2>
</div>
<div class="form-div">
<label for="uploader">Select Approver<span class="asterick-red">*</span>
</label>
<ng-select2 formControlName="approver" [id]="uploader" [options]="select2Options" width="270">
</ng-select2>
</div>
</div>
setSelect2Options() {
this.select2Options = {
triggerChange: true,
allowClear: true,
placeholder : 'Select User* ',
minimumInputLength: 3,
ajax: {
url: '/api/reward/uploader/approver/search/user?limit=15',
headers: {
'X-XSRF-TOKEN': sessionStorage.getItem("auth"),
'content-type': 'application/json'
},
dataType: 'json',
type: "GET",
quietMillis: 50,
data: function (term, page) {
return {
q: term.term, // search term
_: term._type
};
},
processResults: function (data) {
return {
results: $.map(data.results, function (item) {
return {
id: item.id,
text: item.name + " - " + item.email
}
})
};
}
},
//[placeholder]="'Select User* '"
}
}
The above codes are well and good. But now on a button click i need to set a value inn the select box.
this.vcDataService.getUploaderAproverDetails(id).subscribe((res: any) => {
this.uploaderApproverForm.controls['approver'].setValue(res.approverDetails.uploaderUserId);
this.uploaderApproverForm.controls['uploader'].setValue(res.uploaderDetails.approverUserId);
console.log("134", res)//uploaderUserId
//this.select2Options.ajax.processResults.push({id: 103, text: "aa"})
this.select2Options.placeholder="aa";
//this.displayUploader = "aaa";
// $('#uploader').val('ENABLED_FROM_JS');
// $('#uploader').trigger('change');
// this.select2Options.templateSelection = {
// selected: true,
// id: res.approverDetails.approverUserId,
// text: res.approverDetails.approverName,
// title: res.approverDetails.approverName
// }
// this.select2Options.initSelection = {
// callback: {
// data: {"id":103, "text":'ENABLED_FROM_JS'}
// }
// }
console.log(this.select2Options);
this.updateApproverUploader = true;
this.uploaderApproverId = res.uploaderApproverId;
this.cd.detectChanges();
},
err => {
Swal.fire('Oops...', err.error.err, 'error');
})
I tried few things but didn't got the workaround.
After going through the documentation I found a solution for it. I used the data attribute of the ng-select2 and assigned it to a Select2OptionData type variable.
import { Select2OptionData} from 'ng-select2';
patch_panel_array: Select2OptionData[];
Then I added the required data which I needed to show in the field as displayed below:
res.panelApprovers.map(item => {
this.patch_panel_array.push({
id: item.panelApproverUserId,
text: item.panelApproverUserName + " - " + item.panelApproverUserEmail
})
approverIds.push(String(item.panelApproverUserId));
});
this.formData.controls['panelApprover'].setValue(approverIds);
And here is my select 2 field:
<ng-select2 formControlName="panelApprover" [data]="patch_panel_array" [options]="select2OptionsPanel" width="100%" style="width: 100%;">
</ng-select2>

How to send DataSourceRequest object to the controller via ajax call properly?

I have a kendo grid on my razor view mvc as below:
#(Html.Kendo().Grid(Model.employeeList)
.Name("grid")
.Pageable(pager => pager
.Messages(messages => messages.Empty("No data"))
)
.Pageable(pager => pager
.PageSizes(new[] { 15, 20, 25, 50 })
)
.Filterable()
.Groupable()
.Sortable()
.Columns(columns =>
{
columns.Bound(employee => employee.employeeId);
columns.Bound(employee => employee.firstName);
columns.Bound(employee => employee.lastName);
columns.Bound(employee => employee.jobTitle);
columns.Bound(employee => employee.employeeId).ClientTemplate(
"<a href='" + Url.Action("Edit", "Employee", new { id = "#=employeeId#" }) + "'>Edit</a> | " +
"<a href='" + Url.Action("Details", "Employee", new { id = "#=employeeId#" }) + "'>Details</a> | " +
"<a href='" + Url.Action("Delete", "Employee", new { id = "#=employeeId#" }) + "'>Delete</a>"
)
.Filterable(false)
.Groupable(false)
.Sortable(false)
.Title("");
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetEmployeesList", "Employee").Data("branchData")).PageSize(15)
)
)
Along with the controller for GetEmployeesList ActionResult:
[HttpPost]
public ActionResult GetEmployeesList([DataSourceRequest]DataSourceRequest request, int branchId, bool includeNonActive)
{
IQueryable<Employee> employees;
if (includeNonActive)
{
employees = db.Employee.Where(e => e.branchId == branchId && e.isDeleted == false)
.Include(e => e.HireType).Include(e => e.HireStatus);
}
else
{
employees = db.Employee.Where(e => e.branchId == branchId && e.HireStatus.hireStatusId == 1 && e.isDeleted == false)
.Include(e => e.HireType).Include(e => e.HireStatus);
}
DataSourceResult result = employees.ToDataSourceResult(request, employee => new EmployeeViewModel
{
employeeId = employee.employeeId,
firstName = employee.firstName,
lastName = employee.lastName,
jobTitle = employee.jobTitle,
HireStatus = new HireStatus() { hireStatus = employee.HireStatus.hireStatus },
HireType = new HireType() { hireType = employee.HireType.hireType }
});
return Json(result);
}
So far, everything went well. DataSourceRequest request was passed from the grid successfully.
But then I have another post AJAX call via jQuery:
$(document).ready(function () {
$('#ddlBranchList').change(function () {
var isNonActive = $('#isNonActive')[0].checked;
var ddlValue = $('#ddlBranchList').val();
$.ajax({
type: "POST",
url: "/Employee/GetEmployeesList",
data: JSON.stringify({ branchId: ddlValue, includeNonActive: isNonActive }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
resultData = result;
},
error: function () {
alert("Error retrieving Employees List!");
}
}).done(function () {
var dataSource = new kendo.data.DataSource({
data: resultData.Data,
pageSize: 15
});
var grid = $('#grid').data("kendoGrid");
grid.setDataSource(dataSource);
dataSource.read();
});
});
}
A dropdown change event should trigger an ajax post to the controller, but I couldn't properly pass a proper object to DataSourceRequest request parameter. When it is posted, DataSourceRequest request is always null.
How do I pass the object correctly?
I got it working by forcing the kendo grid to re-read the data:
$('#ddlBranchList').change(function () {
var grid = $('#grid').data("kendoGrid");
grid.dataSource.read();
});
and then modify the branchData function:
function branchData() {
var isNonActive = $('#isNonActive')[0].checked;
var ddlValue = $('#ddlBranchList').val();
if (ddlValue > 0) {
branchId = ddlValue;
}
return {
branchId: branchId,
includeNonActive: isNonActive,
}
}

Devexpress MVC5 Grid GetRowKey(e.visibleIndex) returns always null

Hi everyone I am trying to get the primary key of the selected row to send it to the server later here is the code:
This the mainpage
<script type="text/javascript">
function OnRowClick(s, e) {
var grid = MVCxClientGridView.Cast(s);
var key = grid.GetRowKey(e.visibleIndex);
console.log(key);
$.ajax({
url: '#Url.Action("FundDetails", "Fund")',
type: "POST",
dataType: "text",
traditional: true,
data: { rowKey: key },
success: function (data) {
console.log(data);
},
error: function (xhr, textStatus, errorThrown) {
alert('Request Status: ' + xhr.status + '; Status Text: ' + textStatus +
'; Error: ' + errorThrown);
}
});
}
</script>
<div>
#Html.Partial("_FundsList", Model)
</div>
And this is the partial view that contains the Grid
#Html.DevExpress().GridView(settings =>
{
settings.Name = "FundGrid";
settings.CallbackRouteValues = new { Controller = "Fund", Action =
"FundsList" };
settings.Width = 450;
settings.Columns.Add("codeIsin");
settings.Columns.Add("fundLabel");
settings.Columns.Add("variation");
settings.Columns.Add("ClassNiv1");
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsBehavior.AllowSelectSingleRowOnly = true;
settings.ClientSideEvents.RowClick = "OnRowClick";
}).Bind(Model).GetHtml()
the problem is that the key value is always null:
var key = grid.GetRowKey(e.visibleIndex); ==> always Null
PS : e.visibleIndex is not null.
The GetRowKey method explains how null value returned:
If the index passed via the visibleIndex parameter is wrong, or the
ASPxGridBase.KeyFieldName property is not set, null is returned.
It is possible that you need to set KeyFieldName which refers to primary key and/or identity field (with unique value) in the GridView, like this example:
#Html.DevExpress().GridView(settings =>
{
settings.Name = "FundGrid";
settings.CallbackRouteValues = new { Controller = "Fund", Action = "FundsList" };
settings.Width = 450;
settings.Columns.Add("codeIsin");
settings.Columns.Add("fundLabel");
settings.Columns.Add("variation");
settings.Columns.Add("ClassNiv1");
// set primary/identity key field to determine selected row index
settings.KeyFieldName = "codeIsIn";
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsBehavior.AllowSelectSingleRowOnly = true;
settings.ClientSideEvents.RowClick = "OnRowClick";
}).Bind(Model).GetHtml()
Also you can put null value checking with if condition before executing AJAX call to ensure key field value passed properly:
var key = grid.GetRowKey(e.visibleIndex);
if (key != null)
{
$.ajax({
url: '#Url.Action("FundDetails", "Fund")',
type: "POST",
data: { rowKey: key },
// other AJAX settings
success: function (data) {
// do something
},
error: function (xhr, textStatus, errorThrown) {
// error handling
}
});
}

JsonResult returns HTML response

I have this method in a controller to reset the password of a user by mail.
public JsonResult RecoverPasswordByEmail(string mail)
{
MembershipUser member = Membership.GetUser(Membership.GetUserNameByEmail(mail));
string newPassword = System.Web.Security.Membership.GeneratePassword(14, 0);
member.UnlockUser();
if (!member.ChangePassword(member.ResetPassword(), newPassword))
{
return Json(new { Resultado = false, Excepcion = "Couldn't change password" }, JsonRequestBehavior.AllowGet);
}
System.Net.Mail.MailAddress from = new System.Net.Mail.MailAddress("foo#bar.com");
System.Net.Mail.MailAddress to = new System.Net.Mail.MailAddress(mail);
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(from, to);
message.Subject = "Forgot pass";
if (member.IsLockedOut)
{
message.Body = "You're locked";
}
else
{
message.Body = "New password: " + newPassword;
}
var client = new System.Net.Mail.SmtpClient("my.smtpserver.com", 587)
{
Credentials = new System.Net.NetworkCredential("foo#bar.com", "12345"),
EnableSsl = true
};
try
{
client.Send(message);
}
catch (System.Net.Mail.SmtpException ex)
{
return Json(new { Resultado = false, Excepcion = ex.Message }, JsonRequestBehavior.AllowGet);
}
return Json(new { Resultado = true }, JsonRequestBehavior.AllowGet);
}
I do an ajax request using jQuery from a button in a dialog from the login View.
The weird thing is that I use another controller method RecoverPassword that does the same thing but by the username and that works. Using firebug I see that RecoverPassword does the job and returns a JSON with the result, but RecoverPasswordByEmail responds with a big html document.
The important part of the HTML:
<div id="dialog">
<h2>Retrieve Password</h2>
#Html.Label("Mail:")<br/>
#Html.TextBox("txtMail")
<div id="loading">
<br/><img class="displayed" src="#Url.Content("~/Content/Images/Ajax/ajax-loader3.gif")" alt="loading" /><br/>
#Html.Label("Error")
</div>
<br/><br/><input class="button" id="btnSendMail" type="submit" value="Get new password" />
<div>
Recuperar contraseƱa
</div>
</div>
And the js:
$(document).ready(function () {
var requestMail;
$('#btnSendMail').button();
$('#loading').hide();
$("label[for=Error]").text("");
$('#btnSendMail').click(function (event) {
event.preventDefault();
var mail = $("#txtMail").val();
if (mail.length > 0) {
if (requestMail && requestMail .readystate != 4) {
requestMail .abort();
}
$('#loading').show();
$('input[id="btnSendMail"]').attr('disabled', 'disabled');
requestCorreo = $.ajax({
url: '/Users/RecoverPasswordByEmail',
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
timeout: 8000,
data: { Email: mail },
success: function (response) {
if (response.Result) {
$("label[for=Error]").text('New password has been sent to: ' + mail);
}
else {
alert(response.Result + ' ' + response.Exception);
}
},
error: function (xhr, textStatus, thrownError) {
if (textStatus === "timeout") {
alert("got timeout");
}
else {
alert(xhr.status + ' ' + textStatus + ' ' + thrownError);
}
},
complete: function () {
$('#loading').hide();
$('input[id="btnSendMail"]').removeAttr('disabled');
}
});
}
else {
$("label[for=Error]").text("Insert a valid email");
}
requestCorreo.done(function (msg) {
alert(msg);
});
requestCorreo.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus + " " + jqXHR.responseText);
});
});
});
What is in the HTML that is returned? I'm going to bet that your method is throwing an exception, which is caught by ASP.NET, and an error page is returned rather than the JsonResult from your method.
Or it not, the content of the HTML would help shed more light on the issue.
As a side note, you don't seem to be checking null anywhere in your method - and you're assuming the MembershipUser will be found no matter what email address is passed (which may indeed be the source of your exception).

jquery ajax to bind dropdownlist MVC

I have a 2 dropdownlist, I have to bind the 2nd one based on the Id I got from first dropdown. in the first dropdown I added OnChange event.
function onChange() {
var variantDropDown = $('#VariantName');
$.ajax({
url: '/Admin/CustomProductPinCodesManagement/GetProductVarinats',
type: 'post',
data: { productId: $("#ProductName").data("tDropDownList").value() },
success: function (data) {
$.each(variants, function (i, variant) {
$states.append('<option value="' + variant.Id + '">' + variant.Name + '</option>');
});
},
error: function () {
alert('Error');
}
});
}
and this is the c# code .
[HttpPost]
public ActionResult GetProductVarinats(string productId)
{
var variants = _productService.GetProductVariantsByProductId(Convert.ToInt32(productId));
return Json(new { Result = true, data = variants }, JsonRequestBehavior.AllowGet);
}
but it does not work.
Use val() instead of value()
Change statement
data: { productId: $("#ProductName").data("tDropDownList").value() }
to
data: { productId: $("#ProductName").data("tDropDownList").val() }
and the success should be like
success: function (data) {
//For getting list of variants, you should access it by `data.data.variants`
//because you will get your json object in data, and for getting the value `variants`
//you should capture the `data` property of returned json object like `data.data`
$.each(data.data.variants, function (i, variant) {
$states.append('<option value="' + variant.Id + '">'+ variant.Name + '</option>');
//you can try this also for creating options
//$states.append($('<option/>').text(variant.Name).attr('value',variant.Id));
});
}
so your function should look like :
function onChange() {
var variantDropDown = $('#VariantName');
$.ajax({
url: '/Admin/CustomProductPinCodesManagement/GetProductVarinats',
type : 'post',
data: { productId: $("#ProductName").data("tDropDownList").val() },
success: function (data) {
$.each(data.data.variants, function (i, variant) {
$states.append($('<option/>').text(variant.Name).attr('value',variant.Id));
});
},
error: function () {
alert('Error');
}
});
}
AcidMedia has a library called TTControls which uses Telerik and you can use the TTControls.LinkedDropDown control which solves this problem.

Resources