jqGrid is not reloading or refreshing properly on keyup event - c#

I needed to create a search page where various types of text, dropdown, date field will be there. i added onkeyup function to every text field so that whenever i put any text or number a grid will appear with subgrid. The issue i am facing is if i give input for the first time then the grid appear with correct data. if i clear that field then the grid is reloading also but if i input again in that field or any other text field then the js is not sending request to the action method with updated post value.
Here is my View Part:
<section class="content">
<div class="container-fluid">
<!-- SELECT2 EXAMPLE -->
<!-- SELECT2 EXAMPLE -->
<div class="card card-info">
<div class="card-header">
<h3 class="card-title">Search Criteria</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
</div>
</div>
<!-- /.card-header -->
#using (Html.BeginForm("SearchReport", "LRLiveSearch", FormMethod.Post))
{
<div class="card-body">
<div class="row">
<div class="col-md-12" style="line-height:1.50px;">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Deed No</label>
#Html.TextBoxFor(model => model.DeedNo, new { #class = "form-control", onkeyup = "LiveSearch('DN', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Deed Identity</label>
#Html.TextBoxFor(model => model.DeedId, new { #class = "form-control", onkeyup = "LiveSearch('DI', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Client Name</label>
#Html.TextBoxFor(model => model.ClientName, new { #class = "form-control", onkeyup = "LiveSearch('CN', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Client Contact Number</label>
#Html.TextBoxFor(model => model.ClientPhoneNumber, new { #class = "form-control", onkeyup = "LiveSearch('CP', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>MR No</label>
#Html.TextBoxFor(model => model.MRNo, new { #class = "form-control", onkeyup = "LiveSearch('MR', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Cheque No</label>
#Html.TextBoxFor(model => model.ChequeNo, new { #class = "form-control", onkeyup = "LiveSearch('CQN', this.value)" })
</div>
</div>
</div>
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Collection Type</label>
#Html.DropDownListFor(model => model.CollectionType, Model.CollectionTypeList, new { #class = "form-control" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>From Date</label>
<div class="input-group date" id="FirstDate" data-target-input="nearest">
#Html.TextBoxFor(model => model.FromDate, new { #class = "form-control datetimepicker-input", #data_target = "#FirstDate" })
<div class="input-group-append" data-target="#FirstDate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>To Date</label>
<div class="input-group date" id="SecondDate" data-target-input="nearest">
#Html.TextBoxFor(model => model.ToDate, new { #class = "form-control datetimepicker-input", #data_target = "#SecondDate" })
<div class="input-group-append" data-target="#SecondDate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
#*<div class="col-md-1">
<div class="form-group">
<center>
<button id="btnLRSearch" formaction="SearchList" class="btn btn-md btn-primary" style="margin-top:.80rem" type="button">Search</button>
</center>
</div>
</div>
<div class="col-md-1">
<div class="form-group">
<center>
<button id="btnPrint" formaction="SearchReport" class="btn btn-md btn-warning" style="margin-top:.80rem" type="submit">Report</button>
</center>
</div>
</div>*#
</div>
</div>
</div>
</div>
}
</div>
</div>
<!-- /.container-fluid -->
<table class="table table-bordered table-striped table-hover text-nowrap text-sm" id="Demogrid"></table>
<div class="container-fluid" id="pager"></div>
</section>
here is my JS part where i handled onkeyup event:
function LiveSearch(type, value) {
var searchType = type;
var searchValue = value;
if (value == "" || value == null) {
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
else {
$("#Demogrid").jqGrid({
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
colNames: ['ProjectName', 'PlotName', 'TotalLandArea', 'DeedId', 'DeedDate', 'RentFeeType', 'RentFee', 'ClientName', 'ClientAddress', 'ClientContactNo', 'EffectiveDate'],
//colModel takes the data from controller and binds to grid
colModel: [
{ name: "ProjectName" },
{ name: "PlotName" },
{ name: "TotalLandArea" },
{ name: "DeedId" },
{ name: "DeedDate" },
{ name: "RentFeeType" },
{ name: "RentFee" },
{ name: "ClientName" },
{ name: "ClientAddress" },
{ name: "ClientContactNo" },
{ name: "EffectiveDate" }
],
height: '100%',
viewrecords: true,
caption: 'Deed Info',
emptyrecords: 'No records',
rowNum: 10,
pager: jQuery('#pager'),
rowList: [10, 20, 30, 40],
jsonReader:
{
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
postData: {
Type: searchType,
SearchValue: searchValue
},
autowidth: true,
subGrid: true,
subGridRowExpanded: function (subgridId, rowId) {
// create the subgrid HTML here
var subgridTableId = subgridId + "_t";
$("#" + subgridId).html("<table id='" + subgridTableId + "'></table>");
// get the data for the parent row
var parentRowData = $("#Demogrid").jqGrid("getRowData", rowId);
// retrieve the primary key value of the parent row
var parentId = parentRowData.DeedId;
$("#" + subgridTableId).jqGrid({
// configure the subgrid
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
colNames: ['CollectionId', 'CollectionDate', 'MRIdentity', 'MRNo', 'MRDate', 'MRType', 'CollectionType', 'ChequeNo', 'BankName'],
//colModel takes the data from controller and binds to grid
colModel: [
{ name: "CollectionId", hidden: true },
{ name: "CollectionDate" },
{ name: "MRIdentity" },
{ name: "MRNo" },
{ name: "MRDate" },
{ name: "MRType" },
{ name: "CollectionType" },
{ name: "ChequeNo" },
{ name: "BankName" }
],
height: '100%',
viewrecords: true,
caption: 'Collection Details',
emptyrecords: 'No records',
rowNum: 10,
jsonReader: {
repeatitems: false
},
postData: {
Type: searchType,
SearchValue: searchValue,
DeedId: parentId
},
autowidth: true
});
},
}).navGrid('#pager',
{
edit: true,
add: true,
del: true,
search: true,
refresh: true,
closeAfterSearch: true
});
}
}
and it is my action method:
public JsonResult LiveSearch(string sord, int page, int rows, string searchString, string Type, string SearchValue, string DeedId)
{
if(SearchValue == "")
{
SearchValue = "$";
}
var query = iLRSearchRepository.LiveSearchFilter(Type, SearchValue);
if (DeedId == null)
{
//#2 Setting Paging
int pageIndex = Convert.ToInt32(page) - 1;
int pageSize = rows;
//#3 Linq Query to Get Data
var Results = query.Select(
x => new
{
ProjectName = x.ProjectName,
PlotName = x.PlotName,
TotalLandArea = x.TotalLandArea,
DeedId = x.DeedId,
DeedDate = x.DeedDate.ToString("dd/MM/yyyy"),
RentFeeType = x.RentFeeType,
RentFee = x.RentFee,
ClientName = x.ClientName,
ClientAddress = x.ClientsAddress,
ClientContactNo = x.ClientsContactNo,
EffectiveDate = x.ActivateDate.ToString("dd/MM/yyyy")
}).Distinct();
//#4 Get Total Row Count
int totalRecords = Results.Count();
var totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
//#5 Setting Sorting
if (sord.ToUpper() == "DESC")
{
Results = Results.OrderByDescending(s => s.DeedId);
Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
}
else
{
Results = Results.OrderBy(s => s.DeedId);
Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
}
//#6 Setting Search
if (!string.IsNullOrEmpty(searchString))
{
Results = Results.Where(m => m.DeedId == searchString);
}
//#7 Sending Json Object to View.
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = Results
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
else
{
var Results = query.Where(x => x.DeedId == DeedId).Select(
x => new
{
CollectionId = x.CollectionId,
CollectionDate = x.CollectionDate?.ToString("dd/MM/yyyy"),
MRIdentity = x.MRIdentity,
MRNo = x.MRNo,
MRDate = x.MRDate?.ToString("dd/MM/yyyy"),
MRType = x.MRType,
CollectionType = x.CollectionType,
ChequeNo = x.ChequeNo,
BankName = x.BankName,
});
var jsonData = new
{
rows = Results
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
//model.landRent_View_SearchInfos = query;
//return View("_LandRentInfoList", model);
}

With your code you every time try create jqGrid when you do a search, which of course is not allowed since the grid is already created.
if (value == "" || value == null) {
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
else {
$("#Demogrid").jqGrid({}...)
}
To solve the problem first create the grid and the do a reload when the value changes
$("#Demogrid").jqGrid({
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
...
});
function LiveSearch(type, value) {
var searchType = type;
var searchValue = value;
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
Hope this helps.
Initially you can set values (postData) so that the grid return empty data or create the grid with empty local data (datatype : local) and then change the datatype to json.

Related

How make kendo ui async in ASP.NET MVC

I have an ASP.NET MVC project. The cshtml is as following:
<div class="container">
<div class="PublicInfo form-group">
<div class="dividerBar">
<div class="row">
<div class="col-lg-2 col-md-2 col-sm-4 col-xs-4">
<span class="lableName">From: </span>
</div>
<div class="col-lg-4 col-md-4 col-sm-8 col-xs-8">
#Html.TextBoxFor(m => m.StartTimeShamsi, new { #readonly = "readonly", #class = "pdate form-control input-sm", #id = "StartTimeShamsi", #style = "width: 85% !important" })
#Html.HiddenFor(m => m.StartTime, new { #id = "StartTime" })
</div>
<div class="col-lg-2 col-md-2 col-sm-4 col-xs-4">
<span class="lableName">To: </span>
</div>
<div class="col-lg-4 col-md-4 col-sm-8 col-xs-8">
#Html.TextBoxFor(m => m.EndTimeShamsi, new { #readonly = "readonly", #class = "pdate form-control input-sm", id = "EndTimeShamsi", #style = "width: 85% !important" })
#Html.HiddenFor(m => m.EndTime, new { #id = "EndTime" })
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<button class="btn btn-primary btn-sm pull-right" type="button" onclick="btn_Search();">Search</button>
</div>
</div>
</div>
<div class="k-rtl col-lg-12 col-md-12 col-sm-12 col-xs-12 " id="KendoGrid">
#(Html.Kendo().Grid<SerialDestination>()
.Name("GridSerialDestination")
.Columns(columns =>
{
columns.Bound(o => o.SerialNo).Width(130).Filterable(filterable => filterable
.Extra(true)
.Operators(ops =>
ops.ForString(str => str.Clear()
.Contains("Contains")
.StartsWith("StartsWith")
.EndsWith("EndsWith")
.IsEqualTo("IsEqualTo"))));
})
.Selectable(s => s.Mode(GridSelectionMode.Single))
.Pageable()
.Sortable()
.Scrollable(builder => builder.Height("auto"))
.AutoBind(false)
.Filterable(ftb => ftb.Mode(GridFilterMode.Row))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GridSerialDestination_ReadAll", "SerialDestinationRpt").Data("GridSerialDestination_GetParam"))
)
.Resizable(resize => resize.Columns(true))
)
</div>
</div>
When I push search button in the cshtml then the function btn_Search in the jquery will be called. In the jquery it must first read "grid.dataSource.read()" and wait for it to fill the kendo grid in the cshtml then after that the ajax must be called but it does not happen because as soon as the "grid.dataSource.read()" was read the ajax will be called
function btn_Search() {
var grid = $('#GridSerialDestination').data('kendoGrid');
grid.dataSource.read();
$.ajax({
url: '/SerialDestinationRpt/GetProcessCount',
data: { startDate: $("#StartTime").val(), endDate: $("#EndTime").val() },
type: "POST",
dataType: 'json',
async: true,
success: function (data) {
$('#pendingprocess').attr('data-count', data.AllSales);
$('#finishedprocess').attr('data-count', data.AllInstallation);
},
error: function (reponse) {
},
});
}
The backend function is as following:
public ActionResult GridSerialDestination_ReadAll([DataSourceRequest] DataSourceRequest request, string beginDate, string endDate)
{
var dt = SerialDestinationRptBAL.Sp_SerialDestinationRpt_ByDate(beginDate, endDate);
TempData["allSales"] = dt.Rows.Count;
TempData["allInstallation"] = dt.Select("ReceptionDate IS NOT NULL ").Count();
dt = PrepareData(dt);
return Json(dt.ToDataSourceResult(request));
}
[HttpPost]
public JsonResult GetProcessCount(string startDate, string endDate)
{
var allSales = TempData["allSales"]?.ToString();
var allInstallation = TempData["allInstallation"]?.ToString();
TempData["allSales"] = null;
TempData["allInstallation"] = null;
var model = new
{
AllSales = allSales,
AllInstallation = allInstallation
};
return Json(model, JsonRequestBehavior.AllowGet);
}
How can I solve the problem? Any help will be appriciated.

validate required jquery doesnt work when i try to change rules

I have 2 fields. I'm trying to insert a number into the first. The second value should be less or equal to the first field.
I'm using jquery validation to warn user, but when i do it it doesn't change the messages and layout.
I've tried to follow the documentation but doesn't understand what's wrong.
<div class="form-group">
<label class="control-label" for="inputDefault-4">Quantidade permitida por pedido<span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeVenda, new { maxlength = "10", #class = "form-control", #id = "quantidade_pedido", placeholder = "0", validate = "required",#name = "quantidade_pedido" , #type = "number" })
</div>
<div class="form-group">
<label class="control-label" for="inputDefault-4">Possui regime de comodato<span class="text-danger">*</span></label>
<div>
#Html.CheckBoxFor(t => t.Produto.FlagComodato, new { #class = "chk-inativar switcher-example-default", #id = "comodato", #onclick = "checkComodato(this)" })
</div>
</div>
<div id="limitEmprestimo" style="display: none" class="form-group">
<label class="control-label" for="quantidade_comodato">Quantidade limite de empréstimo <span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeComodato, new { maxlength = "10", #class = "form-control", #id = "quantidade_comodato", placeholder = "0", validate = "required", #name = "quantidade_comodato", #type = "number"})
function checkComodato(check) {
if (check.checked) {
$("#limitEmprestimo").show();
}
else {
$("#limitEmprestimo").hide();
}
}
$("#quantidade_comodato").focusout(function () {
var quantc = $("#quantidade_comodato").val() === "" ? 0 : parseInt($("#quantidade_comodato").val());
var quantp = $("#quantidade_pedido").val() === "" ? 0 : parseInt($("#quantidade_pedido").val());
if (quantc > quantp) {
var validator = $("#frmCadastro").validate();
$("#quantidade_comodato").rules("remove", "required");
$("#quantidade_comodato").rules("add", {
max: quantp,
messages: {
quantp: "Invalid !"
}
});
validator.element($(this));
}
});
The problem is most likely that the jquery script is not within a <script> tag. Therefore the browser won't understand that your code should be run as javascript, instead the browser just thinks that your code is plain text.
Try this:
<div class="form-group">
<label class="control-label" for="inputDefault-4">Quantidade permitida por pedido<span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeVenda, new { maxlength = "10", #class = "form-control", #id = "quantidade_pedido", placeholder = "0", validate = "required",#name = "quantidade_pedido" , #type = "number" })
</div>
<div class="form-group">
<label class="control-label" for="inputDefault-4">Possui regime de comodato<span class="text-danger">*</span></label>
<div>
#Html.CheckBoxFor(t => t.Produto.FlagComodato, new { #class = "chk-inativar switcher-example-default", #id = "comodato", #onclick = "checkComodato(this)" })
</div>
</div>
<div id="limitEmprestimo" style="display: none" class="form-group">
<label class="control-label" for="quantidade_comodato">Quantidade limite de empréstimo <span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeComodato, new { maxlength = "10", #class = "form-control", #id = "quantidade_comodato", placeholder = "0", validate = "required", #name = "quantidade_comodato", #type = "number"})
</div>
<script>
function checkComodato(check) {
if (check.checked) {
$("#limitEmprestimo").show();
}
else {
$("#limitEmprestimo").hide();
}
}
$("#quantidade_comodato").focusout(function () {
var quantc = $("#quantidade_comodato").val() === "" ? 0 : parseInt($("#quantidade_comodato").val());
var quantp = $("#quantidade_pedido").val() === "" ? 0 : parseInt($("#quantidade_pedido").val());
if (quantc > quantp) {
var validator = $("#frmCadastro").validate();
$("#quantidade_comodato").rules("remove", "required");
$("#quantidade_comodato").rules("add", {
max: quantp,
messages: {
quantp: "Invalid !"
}
});
validator.element($(this));
}
});
</script>
If that isn't the problem another typical one is that the jquery script is loaded in the end of the _layout.cshtml. So when you call jquery it haven't been defined yet. In that case you should get a script error in the developer console (hit F12 in your browser to show it).
That's easy corrected by wrapping the script in a Razor section.
#section Scripts
{
<script>
// your code here
</script>
}
"Scripts" is declared in _Layout.cshtml as #RenderSection("Scripts", required: false).

How to add items to a Dropdownlist that is in SelectList(Enumerable.Empty<SelectListItem>() format [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have a dropdownlist like this
#Html.DropDownListFor(model => model.si_sec_id, new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"), "Select a Section", new { id = "ddlSection" })
it was like that because of this
<script type="text/javascript">
$(document).ready(function () {
$("#ddlGrade").change(function () {
var id = $(this).val();
$.getJSON("../Employee/PopulateDetails", { id:id},
function (marksData) {
var select = $("#ddlSection");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select a Section"
}));
$.each(marksData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
and the JSON
public JsonResult PopulateDetails(string id)
{
List<Models.Section> a = new List<Models.Section>();
Models.ModelActions Ma = new ModelActions();
a = Ma.getSection(id);
var marksData = a.Select(c => new SelectListItem()
{
Text = c.sec_name,
Value = c.sec_id.ToString(),
});
return Json(marksData, JsonRequestBehavior.AllowGet);
}
now how can i add initial values to the dropdownlist in that format on postback? i need it for my search functionality. comments are much appreciated
EDITED:
VIEW:
<legend>CreateStudent</legend>
Full Name:
#Html.TextBox("searchTerm", null, new { id = "txtSearch" })
<input type="submit" value="search" name="submitbutton" />
<div class="editor-label">
#Html.LabelFor(model => model.si_id)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.si_id, new { #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.si_id)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.si_fname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.si_fname)
#Html.ValidationMessageFor(model => model.si_fname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.si_mname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.si_mname)
#Html.ValidationMessageFor(model => model.si_mname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.si_lname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.si_lname)
#Html.ValidationMessageFor(model => model.si_lname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.si_gl_id)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.si_gl_id, new SelectList(Model.GradeLevel,"gl_id","gl_name"),"Select Grade Level", new { id = "ddlGrade" })
#Html.ValidationMessageFor(model => model.si_gl_id)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.si_sec_id)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.si_sec_id, new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"), "Select a Section", new { id = "ddlSection" })
#Html.ValidationMessageFor(model => model.si_sec_id)
</div>
<p>
<input type="submit" value="Create" name="submitbutton" />
</p>
</fieldset>
<p>
<input type="submit" value="Create" name="submitbutton" />
</p>
Controller
[HttpPost]
public ActionResult RegisterStudent(CreateStudent Create, string submitbutton, string searchTerm)
{
acgs_qm.Models.ModelActions Ma = new acgs_qm.Models.ModelActions();
List<CreateStudent> stud = new List<CreateStudent>();
switch (submitbutton)
{
case "search":
ModelState.Clear();
var model = new CreateStudent
{
GradeLevel = Ma.getGrade(),
//Guardian = Ma.getGuardian(),
si_id = Ma.getStringval(searchTerm,"si_id","student_info_tb","si_fullname"),
si_fname = Ma.getStringval(searchTerm, "si_fname", "student_info_tb", "si_fullname"),
si_mname = Ma.getStringval(searchTerm, "si_mname", "student_info_tb", "si_fullname"),
si_lname = Ma.getStringval(searchTerm, "si_lname", "student_info_tb", "si_fullname"),
si_gender = Ma.getStringval(searchTerm, "si_gender", "student_info_tb", "si_fullname"),
};
return View("RegisterStudent",model);
case "Create":
if (ModelState.IsValid)
{
Ma.insertStudent(Create);
}
Create.GradeLevel = Ma.getGrade();
Create.si_id = Ma.getcode("student_info_tb", "si_id", "1");
return View(Create);
default:
return View(Create);
}
}
Change your implementation as follows :
$.getJSON("../Employee/PopulateDetails", { id:id},
function (marksData) {
var $select = $("#ddlSection");
$select.empty();
$select.append('<option value=' + '0' + '>' + 'Select a Section' + '</option>');
$.each(marksData, function (index, itemData) {
$select.append('<option value=' + itemData.Value + '>' + itemData.Text + '</option>');
});
});
Try this
$("#ddlSection").change(function () {
var Id = this.value;
if (Id != 0) {
$.ajax({
type: "POST",
url: "/Employee/PopulateDetails",
data: JSON.stringify({ Id: Id }),
dataType: "text",
contentType: "application/json; charset=utf-8",
processData: false,
success: function (data) {
$("#ddlSection").empty();
$('#ddlSection').append("<option value='0'>Select Selection...</option>");
var yourArray = $.parseJSON(data);
if (yourArray != null) {
for (var i = 0; i < yourArray.length; i++) {
$('#ddlSection').append("<option value='" + yourArray[i].YourFiledName + "'>" + yourArray[i].YourFiledName + "</option>");
}
}
},
error: function (response) {
if (response != 1) {
alert("Error!!!!");
location.reload();
}
}
});
}
else {
alert("Please Select Any Value Name....");
}
});

Retrieving ViewModel data collection is null

I am passing model from view to controller. in my viewmodel List<TradeLaneDetailsDTO> is null always, and i am passing my data through ajax. what is the problem in my code.
please help me...
here is my viewmodel
public class SLAViewModel
{
public List<TradeLaneDetailsDTO> Items { get; set; }
}
here is my view
#using (Html.BeginForm("SaveSLA", "SLAMgmt", FormMethod.Post, htmlAttributes: new { #class = "form-horizontal", #role = "form", id = "frmEstDays" }))
{
for (int i = 0; i < Model.Items.Count; i++)
{
<div class="form-group">
#Html.LabelFor(model => model.Items.ElementAt(i).legname, Model.Items.ElementAt(i).legname, new { #class = "col-md-4" })
<div class="col-md-3">
#Html.TextBoxFor(model => model.Items.ElementAt(i).estddays, new { #class = "form-control", type = "text", MaxLength = "10" })
</div>
</div>
}
<div class="form-group">
<div class="offset-3 col-md-8">
<button id="btnSave" type="button" title="Save" class="btn btn-success" onclick="getPage1('#Url.Action("SaveSLA", "SLAMgmt")')">
<span class="glyphicon glyphicon-floppy-disk"></span>Save
</button>
</div>
</div>
}
and here is my ajax function
function getPage1(page)
{
alert("get page1");
$.ajax({
type: "POST",
url: page,
data: $("#frmEstDays").serialize(),
xhrFields: {
withCredentials: true
},
success: function (html) {
alert(html.responseText);
},
error: function (data) {
var error = "Error ";
}
});
}
here is my controller functions
public ActionResult SaveSLA(SLAViewModel slavModel)
{
string[] ErrorMessageArray = new string[4];
int errorIndex = 0;
return anything;
}
Simply use model=>model.Items[i].PROPERTYNAME as below
#Html.TextBoxFor(model => model.Items[i].estddays, new { #class = "form-control", type = "text", MaxLength = "10" })
hope this will help
Please remove type = "text" from TextBoxFor html helper.
#Html.TextBoxFor(model => model.Items.ElementAt(i).estddays, new { #class = "form-control", MaxLength = "10" })
The HtmlTextboxFor always creates a textbox <input type="text" />. So you don't have to specify explicitly.

Null value in Model property using HiddenFor

I am writing some javascript where the selected option in a dropdown menu get assigned to a hiddenfor value. This hiddenfor is using a model property (SelectedModule).
When I click my submit button, the model.SelectedModule has null value even though I assigned a value to it with my javascript.
View
#model UserManager.Models.vw_UserManager_Model
#{
ViewBag.Title = "EditUser";
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div id="edit-user">
<fieldset>
<legend>Edit user details</legend>
<div class="editor-field">
#Html.DropDownListFor(Model => Model.salutation, new List<SelectListItem>
{
new SelectListItem{ Text="Mr", Value = "Mr" },
new SelectListItem{ Text="Mrs", Value = "Mrs" },
new SelectListItem{ Text="Miss", Value = "Miss" },
new SelectListItem{ Text="Ms", Value = "Ms" },
new SelectListItem{ Text="Dr", Value = "Dr" }
})
#Html.ValidationMessageFor(model => Model.salutation)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.firstname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.firstname)
#Html.ValidationMessageFor(model => model.firstname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.lastname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.lastname)
#Html.ValidationMessageFor(model => model.lastname)
</div>
#{Html.Partial("~/Views/Partial/_AutocompleteGroupName.cshtml", this.ViewData);}
<div class="editor-label">
#Html.LabelFor(model => model.isactive)
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.isactive)
#Html.ValidationMessageFor(model => Model.isactive)
</div>
<div class="editor-label">
#Html.Label("Is approved")
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.IsApproved)
#Html.ValidationMessageFor(model => Model.IsApproved)
</div>
<div class="editor-label">
#Html.Label("Maximum concurrent users")
</div>
<div class="editor-field">
#Html.EditorFor(model => Model.MaxConcurrentUsers)
#Html.ValidationMessageFor(model => Model.MaxConcurrentUsers)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.email)
#Html.ValidationMessageFor(model => model.email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.rowtype)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.rowtype, new { #readonly = "readonly", #id = "txtNonEditableRowType" })
- Non editable
</div>
<div class="editor-label">
#Html.Label("Current Module")
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.module_name, new { #readonly = "readonly", #id = "txtNonEditableModule" })
- Non editable
#Html.ValidationMessageFor(model => model.module_name)
</div>
<br />
#if (Model.rowtype == "ALF")
{
<div id="alfModules">
#Html.Label("New module")
<br />
#{Html.RenderAction("_CreateUserModulesAlf", "UserManager");}
</div>
}
#if (Model.rowtype == "BRAD")
{
<div id="bradModules">
#Html.Label("New module")
<br />
#{Html.RenderAction("_CreateUserModulesBrad", "UserManager");}
</div>
}
<div class="editor-label">
#Html.LabelFor(model => model.group_name)
</div>
#* <div class="editor-field">
#Html.EditorFor(model => model.group_name)
#Html.ValidationMessageFor(model => model.group_name)
</div>*#
<div class="editor-label">
#Html.Label("Current Group")
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.group_name, new { #readonly = "readonly", #id = "txtNonEditableGroup" })
- Non editable
#Html.ValidationMessageFor(model => model.group_name)
</div>
#Html.HiddenFor(model => Model.selected_module, new { id = "hdnSelectedModule" })
#* #Html.HiddenFor(model => Model.selected_moduleAlf, new { id = "hdnSelectedModuleAlf" })
#Html.HiddenFor(model => Model.selected_moduleBrad, new { id = "hdnSelectedModuleBrad" })*#
<br />
<fieldset style="width: 400px; padding-left: 15px;">
<legend>Group Checker</legend>
<div id="createuser-groupnamesearch">
#{Html.RenderAction("_txtGroupSearchForm", "UserManager");}
</div>
</fieldset>
<p>
<input type="submit" value="Edit" onclick="newModule()" />
</p>
<br />
#Html.ActionLink("Back to User Manager Dashboard", "Index")
</fieldset>
</div>
}
<script type="text/javascript">
$("#group_name").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("LookUpGroupName", "UserManager")',
dataType: "json",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
value: request.term
},
success: function (data) {
response($.map(data, function (item) {
// alert(item.group);
return {
label: item.group,
value: item.group
} // end of return
})); // end of response
}, // end of success
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus);
} // end of error
}); // end of ajax
},
minLength: 2,
select: function (event, ui) { // Assign to hidden values to trigger onchange ajax call.
$.ajax({
url: '#Url.Action("GroupnameCheck", "UserManager")',
dataType: "json",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
value: ui.item.label
},
success: function (data) {
$.each(data, function (index, value) {
if (index == "AlfGroup") {
$("#txtGroupnameExistsAlf").val(value);
if ($("#txtGroupnameExistsAlf").val() == "Alf Group doesn't exist.") {
$("#txtGroupnameExistsAlf").css("background-color", "red");
}
else {
$('#txtGroupnameExistsAlf').css("background-color", "#33ff00");
}
}
if (index == "BradGroup") {
$("#txtGroupnameExistsBrad").val(value);
if ($("#txtGroupnameExistsBrad").val() == "Brad Group doesn't exist.") {
$("#txtGroupnameExistsBrad").css("background-color", "red");
}
else {
$('#txtGroupnameExistsBrad').css("background-color", "#33ff00");
}
}
});
}, // end of success
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus);
} // end of error
}); // end of ajax
$('#hdnGroupAlf').val(ui.item.label);
$('#hdnGroupBrad').val(ui.item.label);
},
open: function () {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
function chkSelection() {
var rowType = $("#txtNonEditableRowType").val();
if (rowType == "ALF") {
var selectedVal = $("#ddlSelectedAlf option:selected").val();
$('#hdnSelectedModule').val(selectedVal);
}
else {
var selectedVal = $("#ddlSelectedBrad option:selected").val();
$('#hdnSelectedModule').text(selectedVal);
alert(selectedVal);
}
}
$(document).ready(function () {
// Non editable fields grey
$("#txtNonEditableGroup").css("background-color", "gray");
$("#txtNonEditableModule").css("background-color", "gray");
$("#txtNonEditableRowType").css("background-color", "gray");
// Show/Hide group check part based on IF ALF or BRAD
var rowType = $("#txtNonEditableRowType").val();
if (rowType == "ALF") {
$("#groupname-checker-alf").show();
$("#groupname-checker-brad").hide();
var selectedVal = $("txtNonEditableRowType").val();
$('#hdnModuleAlf').val(selectedVal);
}
else {
$("#groupname-checker-alf").hide();
$("#groupname-checker-brad").show();
var selectedVal = $("txtNonEditableRowType").val();
$('#hdnModuleBrad').val(selectedVal);
}
});
function newModule() { // Assign new selected module from dropdown to hidden form
// so it can be used in model as selected_module
if ($("#txtNonEditableRowType").val() == "ALF") {
var val = $("#module_name :selected").val();
$("#hdnSelectedModule").val(val);
}
else {
var val = $("#module_name :selected").val();
$("#hdnSelectedModule").val(val);
}
}
</script>
Controller
[HttpPost]
public ActionResult EditUser(vw_UserManager_Model model)
{
List<UserManager.Models.vw_UserManager_Model> modellist = new List<vw_UserManager_Model>();
int outcome = 0;
if (ModelState.IsValid)
{
outcome = UserManager.DAL.EditUser(model);
modellist.Add(model);
}
if (outcome == 1)
{
if (modellist.FirstOrDefault().rowtype == "Alf")
{
}
else
{
}
return RedirectToAction("showSuccessUser", new
{
CrudType = "Edit",
UserName = modellist.FirstOrDefault().UserName,
Password = modellist.FirstOrDefault().password,
FirstName = modellist.FirstOrDefault().firstname,
LastName = modellist.FirstOrDefault().lastname,
Email = modellist.FirstOrDefault().email,
GroupName = modellist.FirstOrDefault().group_name,
IsActive = modellist.FirstOrDefault().isactive,
selected_module = modellist.FirstOrDefault().module_name
});
}
else
{
ViewBag.Message = "Failure";
return RedirectToAction("showError", model);
}
}
Summary
When an item is selected in the drop down menu, the value is assigned to HiddenFor field. This works from using firebug I can see the value.
The problem is when I submit the form, the model.SelectedModule property in my C# code has a null value.
Does anyone know why?
I don't know if this is the problem but in one of your cases you are doing:
$('#hdnSelectedModule').text(selectedVal);
which should be:
$('#hdnSelectedModule').val(selectedVal);
Also since you are already using FireBug, inspect the AJAX request in the Net tab. You will see all the key/value pairs that are sent to the server and will be able to more easily identify the problem. For example is there a SelectedModule=some_value in the request? If so, assuming that your model has a property called SelectedModule and is of simple type (such as string) you will be able to get its value.

Categories