Blazor WASM integration with Datatables (with ajax) - c#

I have read this post
I'm moving from MVC .Net Core to Blazor. I'm using Datatable with MVC but I want to reuse it. But I'm using ajax function from datatable. Here the JS code:
function AddDataTable(elementName, controller, columns, columnDefs, actionMethod = "/Search") {
var table = $(elementName).DataTable(
{
"lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
"searching": true,
"processing": true,
"serverSide": true,
"filter": true,
"orderMulti": true,
"pageLength": 10,
"pagingType": "simple_numbers",
"ajax": {
"url": controller + actionMethod,
"type": "POST",
"datatype": "json",
"error": function (xhr, error, thrown) {
if (xhr.status === 405) {
window.location.href = urlBase + "StatusCode/" + xhr.status;
}
return EmptyTable(elementName, controller, columns, columnDefs);
},
},
"columns": columns,
"columnDefs": columnDefs
}
);
return table;
}
API (C# .Net Core)
[HttpPost]
[Route("Datatable")]
public IActionResult Search(string start, string length, string sortColumn, string sortColumnDir, string searchValue, string draw = null)
{
try
{
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordsTotal = 0;
var list= _context.Entity;
if (!(string.IsNullOrEmpty(sortColumn) && !string.IsNullOrEmpty(sortColumnDir)))
{
list= list.OrderBy(sortColumn + " " + sortColumnDir);
}
List<Entity> data;
if (!string.IsNullOrEmpty(searchValue))
{
list= list.Where(m => m.property.Contains(searchValue));
recordsTotal = list.Count();
}
else
{
recordsTotal = list.Count();
}
data = list.Skip(skip).Take(pageSize).ToList();
return Ok(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data });
}
catch (Exception ex)
{
return Conflict();
}
}
In my Blazor APP I moved script and implemented the code in this post it works but it first call all my data and then only filter, sort and search but in client side. I want implement a way to call it from Blazor
Actually on my Blazor app just call Datatable in this way:
protected async override Task OnAfterRenderAsync(bool firstRender)
{
await JSRuntime.InvokeAsync<string>("AddDataTable", new object[] { "#" + id + " table", Searchable });
await base.OnAfterRenderAsync(firstRender);
}
My script in Blazor App
function AddDataTable(table, searching) {
$(table).DataTable({
"searching": searching
});
}
There is a way to reuse it?

Related

jQuery Datatable not sorting in asp.net webform

I have used jquery datatable Server-side processing in my application (asp web form ), after the data returned, paging, searching and sorting do not work. I've read several cases here on the forum of similar or equal problems, but I still haven't been able to solve mine. Could you look at my code, please?
datatable
<script type="text/javascript">
$(document).ready(function () {
$("#stockDatatable").DataTable({
"processing": true, //show processing message
"serverSide": true, //is server side
"filter": true, //allow filter
"ajax": {
"url": "WebForm2.aspx/GetData", //endpoint to get data
"contentType": "application/json",
"type": "GET",
"dataType": "JSON",
"data": function (d) {
return d;
},
"dataSrc": function (json) {
json.draw = json.d.draw;
json.recordsTotal = json.d.recordsTotal;
json.recordsFiltered = json.d.recordsFiltered;
json.data = json.d.data;
var return_data = json.d.data;
return return_data;
}
},
"columns": [ // columns to populate
{ "data": "Id" },
{ "data": "Code"},
{ "data": "Type" },
{ "data": "Text_Description" },
{ "data": "Date_Time" },
{ "data": "Date_Created"},
{ "data": "Added_by" },
],
});
});
</script>
Code Behind (Webform2.cs)
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
public static object GetData()
{
DataTables result = new DataTables();
using (var db = new MunchData())
{
string search = HttpContext.Current.Request.Params["search[value]"];
string draw = HttpContext.Current.Request.Params["draw"];
string order = HttpContext.Current.Request.Params["order[0][column]"];
string sortColumnDirection = HttpContext.Current.Request.Params["order[0][dir]"];
int startRec = Convert.ToInt32(HttpContext.Current.Request.Params["start"]);
int pageSize = Convert.ToInt32(HttpContext.Current.Request.Params["length"]);
string start = HttpContext.Current.Request.Params["start"];
int skip = start != null ? Convert.ToInt32(start) : 0;
var data = db.Machineinfoes.OrderByDescending(p => p.Id).ToList();
int totalRecords = data.Count;
int recFilter = data.Count;
result.draw = Convert.ToInt32(draw);
result.recordsTotal = totalRecords;
result.recordsFiltered = recFilter;
result.data = data.Skip(skip).Take(pageSize).ToList();
}
return result;
}

AJAX request within the datatables plugin doesnt work in every part of my code

I am working with ASP.NET MVC 5, jquery and the datatables plugin in a project. My goal is to use the serverside function of datatables in order to retrieve data of a database and then to display the dat in a datatable. This works fine in one part of my code. Here you can see the jquery code where I use the datatables plugin:
var problemTable = $('#ProblemTable').DataTable({
processing: true, // show message while querying fro data
serverSide: true,
ajax: {
url: "/OverView/LoadProblems"
}
});
As you can see in the following picture, the request is successful and my datatables gets filled as it should in the website.
The request URL looks like this:
So far is everything fine. But now comes the part, which is driving me crazy. In a different jquery script I try to call again the the datatables method for a new datatable. The code looks like this:
$('.DeleteEntity').click(
function () {
try
{
var deleteTable = $('#DeleteTable').DataTable({
processing: true,
serverside: true,
destroy: true,
ajax: {
url: "/Administration/ShowEntriesDelete"
}
});
}
catch (e)
{
console.log(e);
}
});
This Ajax call doesnt work anymore. As you can see the following picture, the action method in C# Code fails.
In this case, the request URL looks like this.
So here is my question: Why do I get this behavior although I use the same function in my jquery code? Or is there something which I got totally wrong?
I think that I have tried everything by now, but I still don´t get it. Both datatables look exact the same in HTML, only id and column headers are different.
I also looked for similar questions, but I couldn't find anything. I would be very glad if someone could give me a hint for this.
Best regards!
EDIT:
#Calvin Ananda
I adapted your answer and added both DataTable functions to one script, just for testing purpose. Here is the hole script.
var troubleshootingIDs = [];
$(document).ready(
function () {
// if I call this method, everything works just fine, the c# code throws an error (which it should) but the ajax method is successfull
var problemTable = $('#ProblemTable').DataTable({
processing: true, // show message while querying fro data
serverSide: true,
"ajax": "/Administration/ShowEntriesDelete"
});
// if I call this method, the ajax method doesnt get called, because there is absolute no data provided in the url
var deleteTable = $('#DeleteTable').DataTable({
processing: true,
serverside: true,
destroy: true,
"ajax": "/Administration/ShowEntriesDelete",
"columns": [
{ "data": "Description" },
{ "data": "Connection" },
{ "data": "Action" }
]
});
var table = $('#reasonTable').DataTable({
pageLength: 2,
lengthChange: false,
columnDefs: [
{
targets: [3],
className: "hide_me"
}
]
}
);
var agentButton = $('.agentButton');
$('td').on('click', '#BadgeContainer', function () {
var IDs = [];
$('#DocList').empty();
$('.DocLinkID').each(function (counter) {
IDs[counter] = $(this).html();
});
console.log(IDs);
$.ajax({
url: "/OverView/GetDocuments",
traditional: true,
data: { IDs: IDs },
content: 'application/json; charset=utf-8',
success: listDocuments
});
});
$('#reasonTable tbody').on('click', 'tr', function () {
$('#SolutionList').empty();
troubleshootingIDs = [];
if ($(this).hasClass('selected')) {
}
else {
table.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
var selectedReason = $('.ReasonGuid', this).text();
$.ajax({
url: '/OverView/ReasonJson',
contentType: 'application/json; charset=utf-8',
data: { 'selectedReason': selectedReason },
success: handleJsonForWizard
}
);
}
);
$('.SolutionButton').on('click',
function () {
var indexToRemove = [];
var dummyArray = [];
for (var counter = 0; counter < troubleshootingIDs.length; counter++) {
if ($('#q' + (+counter * 2)).hasClass('btn-active')) {
indexToRemove.push(counter);
}
dummyArray[counter] = troubleshootingIDs[counter];
}
for (var counter = indexToRemove.length - 1; counter >= 0; counter--) {
dummyArray.splice(indexToRemove[counter], 1);
}
$.ajax(
{
url: '/OverView/GetSolutions',
contentType: 'application/json; charset=utf-8',
traditional: true,
data: { troubleshootingIDs: dummyArray },
success: function (json) {
$('#SolutionList').empty();
try {
for (var counter = 0; counter < Object.keys(json).length; counter++) {
$('#SolutionList').append('<li class="list-group-item">' + json[counter] + '</li>');
}
}
catch (err) {
}
}
}
);
}
);
$('#ProblemTable tbody').on('click', '.WizardButton',
function () {
var IdToGet = $(this).attr('id');
var url = '/OverView/Wizard?SelectedID=';
window.location.replace(url + IdToGet);
}
);
// Carousel fuction overriding (doesn't work wiht jquery template)
$('.carousel-control.left').click(
function () {
var parentId = '#' + $(this).parent().attr('id');
$(parentId).carousel('prev');
}
);
$('.carousel-control.right').click(
function () {
var parentId = '#' + $(this).parent().attr('id');
$(parentId).carousel('next');
}
);
// comment to define
$('.row #BackToTable').click(
function () {
window.location.replace("/OverView");
}
);
$('body').on('click', '.AgentButton',
function () {
var idNum = $(this).attr('id');
var num = idNum.substring(1);
$('#' + idNum).toggleClass('btn-active');
if ((num % 2) == 0) {
var numToCompare = +num + 1;
var classToCompare = $('#q' + numToCompare).attr('class');
if (classToCompare == 'btn AgentButton btn-active') {
$('#q' + numToCompare).toggleClass('btn-active');
}
}
else {
var numToCompare = +num - 1;
var classToCompare = $('#q' + numToCompare).attr('class');
if (classToCompare == 'btn AgentButton btn-active') {
$('#q' + numToCompare).toggleClass('btn-active');
}
}
}
);
function handleJsonForWizard(json) {
initializeCarousel(json.ImgLinks);
initializeAgent(json.Troubleshootings, json.TroubleshootingIDs);
}
function initializeCarousel(imgLinks) {
$('#ReasonVisualisation > ol').empty();
$('#ReasonVisualisation > .carousel-inner').empty();
for (var counter = 0; counter < Object.keys(imgLinks).length; counter++) {
$('#ReasonVisualisation > ol').append('<li data-target="#ReasonVisualisation" data-slide-to="' + counter + '"></li>');
$('#ReasonVisualisation > .carousel-inner').append('<div class="item"><img src="' + imgLinks[counter] + '"/> </div>');
}
$('#ReasonVisualisation > ol >li:first').addClass('active');
$('#ReasonVisualisation > .carousel-inner>div:first').addClass('active');
var list = $('#ReasonVisualisation > ol').html();
var inner = $('#ReasonVisualisation > .carousel-inner').html();
}
function initializeAgent(troubleshootings, ids) {
$('#Agent').empty();
for (var counter = 0; counter < Object.keys(troubleshootings).length; counter++) {
$('#Agent').append('<div>' + troubleshootings[counter] + ' </div>');
$('#Agent').append('<div class="btn AgentButton" id="q' + (counter * 2) + '">Yes</div>');
$('#Agent').append('<div class="btn AgentButton" id="q' + ((counter * 2) + 1) + '">No</div>');
agentButton = $('.AgentButton');
troubleshootingIDs[counter] = ids[counter];
}
}
function listDocuments(json) {
//Array.isArray(json);
if (json.length > 1) {
for (var counter = 0; counter < json.length; counter++) {
$('#DocList').append('<li> <a href=\"' + json[counter] + '\" > Link </a></li>');
}
}
}
}
);
The most interesting part are the first to methods within the script. In my provided code within the code I described my issue. I simply don´t why ajax reacts so different...
I use this method in my project, and it works.
But I dont know if it works to answer your problem.
JSFiddle Here
Change to "ajax": "/OverView/LoadProblems"
var problemTable = $("#ProblemTable").DataTable({
processing: true, // show message while querying fro data
serverSide: true,
"ajax": "/OverView/LoadProblems"
});
=========================================================================
$(".DeleteEntity").click(
function () {
try
{
var deleteTable = $("#DeleteTable").DataTable({
processing: true,
serverside: true,
destroy: true,
"ajax": "/Administration/ShowEntriesDelete"
});
}
catch (e)
{
console.log(e);
}
});

How to pass a fetched value from back-end to front-end in asp.net mvc5?

I have a stored procedure that equates and gets the occupancy rate of a room. I want to fetch the data from the back-end using JSon and display the output data of the stored procedure in the front-end code. But the output data only sticks at the Business Layer. How can i call it from my Controller using Json?
Here is my code
In my Controller
public JsonResult GetoccupancyRate()
{
string _connectionString = rAppSetting.ConnectionString;
try
{
IList<Hotel> _currentOccupancyRateList = rHotelFacade.GetOccupancyRate(HotelIDCookie, DateTime.Now, _connectionString);
IList<Hotel> _yesterdayOccupancyRateList = rHotelFacade.GetOccupancyRate(HotelIDCookie, DateTime.Now.AddDays(-1), _connectionString);
return Json(new
{
success = true,
message = "Success",
yesterdayOccupancyRate = _yesterdayOccupancyRateList,
currentOccupancyRate = _currentOccupancyRateList
},JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new
{
success = false,
message = ex.Message,
currentOccupancyRate = "",
yesterdayOccuoancyRate = ""
}, JsonRequestBehavior.AllowGet);
}
}
Javascript
myapp.factory("occupancyRateService", ['$http', function ($http) {
this.LoadOccupancyRate = function () {
return $http.get("/Dashboard/GetOccupancyRate", {});
};
return this;}]);
myapp.controller('MainController', ['$scope', 'dashboardService', 'occupancyRateService', function ($scope, dashboardService, occupancyRateService) {
$scope.myChart = {
type: 'google.charts.Bar',
options: {},
data: {}
};
$scope.loadOccupancyRateDetails = function () {
occupancyRateService.LoadOccupancyRate().success(function (result) {
if (result.success)
{
var currentOccupancyRateData = result.currentOccupancyRate;
var yesterdayOccupancyRateData = result.yesterdayOccupancyRate;
console.log(result.currentOccupancyRate);
console.log(result.yesterdayOccupancyRate);
//console.log(yesterdayResultData)
if (currentOccupancyRateData || yesterdayOccupancyRateData === null)
{
google.charts.load('current', { 'packages': ['line', 'bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Day', 'Rate'],
['Yesterday', 0],
['Today', 0]
]);
var options = {
chart: {
//title:'Occupancy Rate',
},
bars: 'vertical',
hAxis: { format: 'none', gridlines: { count: 5 } },
vAxis: { format: '.######%' },
height: 180,
//width: 100%,
colors: ['#1b9e77']
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
$(window).resize(function () {
drawChart();
});
}
else
{
google.charts.load('current', { 'packages': ['line', 'bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Day', 'Rate'],
['Yesterday', currentOccupancyRateData],
['Today', yesterdayOccupancyRateData]
]);
//function drawChart() {
// var data = google.visualization.arrayToDataTable([ORData]);
var options = {
chart: {
//title:'Occupancy Rate',
},
bars: 'vertical',
hAxis: { format: 'none', gridlines: { count: 5 } },
vAxis: { format: '.################%' },
height: 180,
//width: 100%,
colors: ['#1b9e77']
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
$(window).resize(function () {
drawChart();
});
}
}
})
.error(function (error) {
alert(error);
})
};
$scope.loadOccupancyRateDetails();
//<--------------------------------------->
}]);

MVC5 Controller: Check for duplicate in DB before saving?

On my View I have a button I use to submit a [description] value to my Controller via JSON, which is then used to create a new Table record. For example:
[HttpPost]
public JsonResult createNewStatus(string description)
{
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
//var allErrors = ModelState.Values.SelectMany(x => x.Errors);
try
{
if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);
}
What I'd like to do now (before saving the Status to the DB) is run a check to see if any other records in the INV_Statuses table have a [description] value matching the one submitted to the function for new creation. If there is a match, I want to return an error/validation? message and alert the user the submitted value already exists and to choose it from the DropDownList on the View.
Can anyone provide an example of how to go about this with LINQ in my MVC Controller?
EDIT: Added my View JS code for submitting the new Status:
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
},
error: function () {
alert("ERROR!");
}
});
});
EDIT2:
Adricadar's suggestion:
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
try
{
var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
var isDuplicateDescription = existingStatus != null;
if (isDuplicateDescription)
{
ModelState.AddModelError("Error", "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.");
}
else if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);
I added a .ToUpper() in my comparison in Controller, but even though the match with .ToUpper() gets identified, the ModelState.AddModelError() code fires, then the code returns and no error message is issued?
The value (though duplicate) still gets added to the dropdownlist (visually, not in DB) via my current JS code:
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
},
error: function () {
alert("ERROR!");
}
});
});
Check for existing status and set status back as follows:
var existingStatus = db.INV_Statuses.FirstOrDefault(s => s.status_description == description);
if (existingStatus ==null)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
else
{
// set the status back to existing
status = existingStatus;
}
Set an existing flag in your response:
return Json(new { ID = status.Id, Text = status.status_description, AlreadyExists = (existingStatus != null) }, JsonRequestBehavior.AllowGet);
Then in your response JavaScript, simply parse out the returned data:
success: function (resp) {
if (resp.AlreadyExists != true)
{
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
}
else
{
alert(resp.status_description + " already exists");
$("#selectStatus").val(resp.Id);
}
}
You can query the database for a status with an existing description and if exists and an model state error.
Be aware that string comparison is case sensitive.
[HttpPost]
public JsonResult createNewStatus(string description)
{
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
//var allErrors = ModelState.Values.SelectMany(x => x.Errors);
try
{
var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
var isDuplicateDescription = existingStatus != null;
string error = String.Empty;
if (isDuplicateDescription)
{
error = "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.";
}
else if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description, Error = error , IsDuplicate = isDuplicateDescription }, JsonRequestBehavior.AllowGet);
}
In javascript verify if response have IsDuplicate = true if is true you skip the part where you need to add an element in dropdown.
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
if(resp.IsDuplicate)
{
//display error from response
//display resp.Error
} else {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
}
},
error: function () {
alert("ERROR!");
}
});
});

Typeahead.js and Bloodhound.js integration with C# WebForms WebMethod

I'm trying to implement a simple WebMethod in C# to search a db of 50,000 people. I'm using Twitter Bootstrap bloodhound.js and typeahead.js to tokenize and autocomplete the responses.
When I run this code, typeahead shows a dropdown menu with undefined.
How can I correctly process the JSON response to strip out the d object returned by .NET WebMethod and correctly pass my records to Bloodhound? I've tried this using the dataFilter method provided by jQuery's $.ajax, but it's not working for me.
C# WebMethod:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static object searchStaffByName(string q)
{
using (App_Data.DQDBDataContext dc = new App_Data.DQDBDataContext())
{
var results = dc.getStaffDetails(q).ToList();
return new { Status = "OK", Records = results, Count = results.Count };
}
}
Typeahead JS implementation:
var textlookup = new Bloodhound({
datumTokenizer: function (d) {
return Bloodhound.tokenizers.whitespace(d.val);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: 'Search.aspx/searchStaffByName',
replace: function (url, query) {
searchQuery = query;
return url;
},
ajax: {
beforeSend: function (jqXhr, settings) {
settings.data = JSON.stringify({
q: searchQuery
});
jqXhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
},
dataFilter: function (data, type) {
if (type === "json") {
data = $.parseJSON(data);
if (typeof data.d === 'object' && data.d.Count > 0) {
return data.d.Records;
}
}
},
type: 'POST'
}
}
});
textlookup.initialize();
$('.autocomplete').typeahead({
hint: true,
highlight: true,
minLength: 3
},
{
name: 'textlookup',
displayKey: 'Forename',
source: textlookup.ttAdapter()
});
Sample JSON Response:
{
"d": {
"Status":"OK",
"Records": [{
"id":45711192,
"phone":"514-579-5721",
"Forename":"Jayden",
"Surname":"Adams",
"DOB":"\/Date(990226800000)\/"
},
{
"id":12603644,
"phone":"333-143-9094",
"Forename":"Jake",
"Surname":"Adams",
"DOB":"\/Date(43542000000)\/"
},
{
"id":68196438,
"phone":"440-505-2403",
"Forename":"Josh",
"Surname":"Adams",
"DOB":"\/Date(-51152400000)\/"
}],
"Count":6
}
}
If your typeahead data will be in the name: 'textlookup', array, populate the array with your JSON response first. The following assumes data is the JSON.
textlookup = [];
for (var i = 0; i < data.d.Records.length; i += 1) {
textlookup.push(data.d.Records[i].Forename);
}
This should push each Forename into the array textlookup. You are getting the undefined error because you are placing objects into the array.
I spent some time on this and found that it's better to return a an string array.
Here's my web method.
[WebMethod]
public static string[] MemberLookup(string MbrFullName)
{
DataSet ds = (dataset provider goes here)
List<string> members = new List<string>();
foreach(DataRow dr in ds.Tables[0].Rows)
{ members.Add(string.Format("{0}-{1}", dr["label"].ToString(), dr["value"].ToString())); }
return members.ToArray();
}

Categories