I'm building a simple paginated table view with KnockoutJS and Twitter Bootstrap. Right now I have everything working except that I can't get the initial dataset to load when the page loads. Looking at my view model, you can see that the proper data loads when "navigating" trough the customer repository via a RESTful API.
How can I get the initial data to load?
<script>
var ListViewModel = function() {
var self = this;
window.viewModel = self;
//Properties
self.list = ko.observableArray();
self.pageSize = ko.observable(20);
self.pageIndex = ko.observable(0);
self.itemCount = ko.observable();
self.maxPageIndex = ko.dependentObservable(function () {
return Math.ceil(self.itemCount() / self.pageSize()) - 1;
});
self.allPages = ko.dependentObservable(function () {
var pages = [];
for (i = 0; i <= self.maxPageIndex() ; i++) {
pages.push({
pageNumber: (i + 1)
});
}
return pages;
});
//navigation Functions
self.previousPage = function () {
if (self.pageIndex() > 0) {
self.pageIndex(self.pageIndex() - 1);
}
self.getItems();
};
self.nextPage = function () {
if (self.pageIndex() < self.maxPageIndex()) {
self.pageIndex(self.pageIndex() + 1);
}
self.getItems();
};
self.moveToPage = function (index) {
self.pageIndex(index);
self.getItems();
};
//API interactions
self.getItems = function () {
$.ajax({
url: '/api/customer/?pageNumber='+self.pageIndex()+"&pageSize="+self.pageSize(),
async: false,
dataType: 'json',
success: function (result) {
self.list(result);
}
});
};
self.getTotalItemCount = function() {
//TODO: Add call to fetch total number of customers in the database and set it to self.itemCount property.
};
};
$(document).ready(function() {
ko.applyBindings(new ListViewModel());
});
</script>
Change you start code
$(document).ready(function() {
var vm = new ListViewModel()
vm.getItems()
ko.applyBindings(vm)
});
Related
I have implemented Cascading (Dependent) DropDownList using ASP.NET MVC.
This is the tutorial
Now I need show alert message box after insert data and redirect on Index page in ASP.NET MVC.
To show alert message in ASP.NET MVC after insert data using store procedure from MySQL database, I have write the code like as shown below.
<script type="text/javascript">
$(function () {
var msg = '#ViewData["result"]';
if (msg > 0)
{
alert("User Details Inserted Successfully");
window.location.href = "#Url.Action("Index", "Home")";
}
});
</script>
The data is correctly registered in the database table and the alert message box after insert data it's show.
But the redirect to index.cshtml not working because all the DropDownList on the form are empty except the first DropDownList that populates correctly.
window.location.href = "#Url.Action("Index", "Home")";
I mean that all other (populated cascading) DropDownList are enabled but empty.
I need redirect to Index Action page and being able to reload a new record, with this redirection it is impossible because the populated cascading DropDownList remain empty... instead of disabled and populated from value of first dropdownlist...
How to do resolve this?
Thanks.
Update 2021-01-02
#section Scripts {
#Scripts.Render("~/bundles/jqueryui")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/Scripts/DatePicker.js");
#Styles.Render("~/Content/cssjqryUi")
<script type="text/javascript">
$(function () {
var msg = '#ViewData["result"]';
console.log(msg);
if (msg > 0)
{
alert("User Details Inserted Successfully");
var url = "#Url.Action("Index", "Home")";
window.location.href = url;
}
});
</script>
<script src="Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
jQuery(function ($) {
$.validator.addMethod('date',
function (value, element) {
if (this.optional(element)) {
return true;
}
var ok = true;
try {
$.datepicker.parseDate('dd/mm/yy', value);
}
catch (err) {
ok = false;
}
return ok;
});
$("#thedate").datepicker(options);
$(function () {
$(".loading").hide();
$("select").each(function () {
if ($(this).find("option").length <= 1) {
$(this).attr("disabled", "disabled");
}
});
$("select").change(function () {
var value = 0;
if ($(this).val() != "") {
value = $(this).val();
}
var id = $(this).attr("id");
$.ajax({
type: "POST",
url: "/Home/AjaxMethod",
data: '{type: "' + id + '", value: "' + value + '"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var dropDownId;
var list;
switch (id) {
case "CountryId":
list = response.States;
DisableDropDown("#TicketId");
DisableDropDown("#CityId");
dropDownId = "#TicketId";
list = response.Ticket;
PopulateDropDown("#TicketId", list);
break;
case "TicketId":
list = response.States;
DisableDropDown("#StateId");
PopulateDropDown("#StateId", list);
break;
case "StateId":
dropDownId = "#CityId";
list = response.Cities;
DisableDropDown("#CityId");
PopulateDropDown("#CityId", list);
dropDownId = "#CityId2";
list = response.Cities2;
PopulateDropDown("#CityId2", list);
$("#GPS").val(response.GPS);
break;
}
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
function DisableDropDown(dropDownId) {
$(dropDownId).attr("disabled", "disabled");
$(dropDownId).empty().append('<option selected="selected" value="">[ === Select === ]</option>');
}
function PopulateDropDown(dropDownId, list) {
var modal = $('<div />');
modal.addClass("modalBackground");
$('body').append(modal);
var loading = $(".loading");
loading.show();
var top = Math.max($(window).height() / 2 - loading[0].offsetHeight / 2, 0);
var left = Math.max($(window).width() / 2 - loading[0].offsetWidth / 2, 0);
loading.css({ top: top, left: left });
setTimeout(function () {
if (list != null && list.length > 0) {
$(dropDownId).removeAttr("disabled");
$.each(list, function () {
$(dropDownId).append($("<option></option>").val(this['Value']).html(this['Text']));
});
$(".loading").hide();
$('.modalBackground').remove();
}
}, 1000);
}
</script>
}
update controller
[HttpPost]
public ActionResult Index(PersonModel person)
{
MTsqlinsert(person); //Insert values in the database
if (ModelState.IsValid)
{
PersonModel personModel = new PersonModel();
person.Countries = PopulateDropDown("SELECT CountryId, CountryName FROM Countries", "CountryName", "CountryId");
person.States = PopulateDropDown("SELECT StateId, StateName FROM States WHERE CountryId = " + countryId, "StateName", "StateId");
person.Cities = PopulateDropDown("SELECT CityId, CityName FROM Cities WHERE StateId = " + stateId, "CityName", "CityID");
ViewData["result"] = "1";
return RedirectToAction("Index");
}
return View(person);
}
[HttpGet]
[OutputCache(NoStore = true, Duration = 60, VaryByParam = "*")]
public ActionResult Index()
{
PersonModel personModel = new PersonModel
{
Countries = PopulateDropDown("SELECT CountryId, CountryName FROM Countries", "CountryName", "CountryId");
};
return View(personModel);
}
I have approx 100000 rows in each of 4 database tables and using web api async Action to get the data through ADO.NET Datasets. I am using 2 drop downs and 2 grid views to load 100000 entries into them.
Following is one of the four controllers I am using to get the Data.
public class OrdersDCController : ApiController
{
public async Task<int> GetOrdersDC()
{
return await DCOrderHelper.GetOrdersCount();
}
// GET api/Orders
public async Task<List<OrderDTO>> GetOrdersDC(int offset, int fetchRecords)
{
return await DCOrderHelper.GetAllOrders(offset, fetchRecords);
}
}
And the following ajax call is
///The Button Click which makes an ajax call to Web API
$("#btngetdata").click(function () {
offset = 0;
custRecordsRendered = 0;
$.when(
$.ajax({
type: 'GET',
url: "/api/OrdersDC",
datatype: "application/json; charset=utf-8",
success: function (data) {
totalRecords = data;
fetch = parseInt(totalRecords / 10);
$("#progressBar").progressbar(0);
//alert(fetch);
getDataAtOffset();
}
})
);
function getDataAtOffset() {
$.ajax({
type: 'GET',
url: "/api/OrdersDC?offset=" + offset * fetch + "&fetchRecords=" + fetch,
datatype: "application/json; charset=utf-8",
success: function (customerData) {
var customers = [];
customers = getDataInArray(customerData); //Convert the JSON response into an Array
var custCount = customers.length;
for (var i = 0; i < custCount; i++) {
displayCustomerInformation($("#customerTemplate").render(customers[i]));
custRecordsRendered = custRecordsRendered + 1;
}
updateProgress();
if (offset * fetch < totalRecords) {
offset = offset + 1;
getDataAtOffset();
}
}
});
}
function updateProgress() {
var progress = $("#progressBar").progressbar("option", "value");
if (progress < 10) {
//Increase the value of the progress by 1
$("#progressBar").progressbar("option", "value", progress + 1);
}
$("#completeCount").text(custRecordsRendered + "/" + totalRecords + " Records Rendered");
}
function displayCustomerInformation(ele) {
$("#tblemp").append(ele);
}
///Method to convertt the JSON data into an array
function getDataInArray(array) {
var cust = [];
$.each(array, function (i, d) {
cust.push(d);
});
return cust;
}
});
I actually wanted to make my Browser UI not getting stucked when data is getting loaded. But Browser is having rendering issues when this much data get loads into the browser. Any help will be appreciated.
Thanks
I am trying to load my typeahead.js by using bloohound's remote function where i can call my Web Method. I have seen similar threads where a querystring is being used :
Integrating Typeahead.js with ASP.Net Webmethod
Typeahead.js and Bloodhound.js integration with C# WebForms WebMethod
http://yassershaikh.com/using-twitter-typeahead-js-with-asp-net-mvc-web-api/
And many more....
However, i cannot find an example where ajax is used to call the webmethod from typeahead.js.
So this is what i have currently and it works:
WebMethod
[WebMethod]
public static string GetEmployeeTypeahead()
{
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.MaxJsonLength = 100000000;
string json;
using (var rep = new RBZPOS_CSHARPEntities())
{
var result = rep.Employees
.Where(x => x.EMPLOYEESTATE == 1)
.Select(x => new {
x.EMPLOYEEID,
x.FULLNAME,
x.MANNO,
x.NRC
}).ToList();
json = jss.Serialize(result);
}
return json;
}
The Client
function LoadEmployeeJSON() {
$.ajax({
type: "POST",
url: "/WebMethods/Test.aspx/GetEmployeeTypeahead",
data: "{}",
contentType: "application/json",
dataType: "json",
success: function (msg) {
empList = $.parseJSON(msg.d); //otherwise does not work
LoadEmployeeTypeahead();
},
error: function (msg) {
alert("error:" + JSON.stringify(msg));
}
});
}
function LoadEmployeeTypeahead() {
var empData = empList;
var fullname = new Bloodhound({
datumTokenizer: function (d) {
return Bloodhound.tokenizers.whitespace(d.FULLNAME)
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: empData,
limit: 10
});
fullname.initialize();
// Make the code less verbose by creating variables for the following
var fullnameTypeahead = $('#<%=txtFullName.ClientID %>.typeahead');
// Initialise typeahead for the employee name
fullnameTypeahead.typeahead({
highlight: true
}, {
name: 'FULLNAME',
displayKey: 'FULLNAME',
source: fullname.ttAdapter(),
templates: {
empty: [
'<div class="empty-message">',
'No match',
'</div>'
].join('\n'),
suggestion: function (data) {
return '<h6 class="">' + data.FULLNAME + "<span class='pull-right text-muted small'><em>" + data.NRC + "</em></span>" + '</h6>';
}
}
});
var fullnameSelectedHandler = function (eventObject, suggestionObject, suggestionDataset) {
/* See comment in previous method */
$('#<%=txtFullName.ClientID %>').val(suggestionObject.FULLNAME);
$('#<%=txtEmployeeID.ClientID %>').val(suggestionObject.EMPLOYEEID);
$('#<%=txtManNo.ClientID %>').val(suggestionObject.MANNO);
$('#<%=txtNRC.ClientID %>').val(suggestionObject.NRC);
};
// Associate the typeahead:selected event with the bespoke handler
fullnameTypeahead.on('typeahead:selected', fullnameSelectedHandler);
}
function clearAndReInitilize() {
$('.typeahead').typeahead('destroy');
$('.typeahead').val('');
}
So as you can see i am making a local call instead of remote.
How can i get the remote function to call my webthod and fill the typeahead without using any querystrings
Okay finally got it to work via an ashx generic handler. So instead of using a web method i used the following ashx handler:
public class Employess : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.MaxJsonLength = Int32.MaxValue;
string json;
string prefixText = context.Request.QueryString["query"];
using (var rep = new RBZPOS_CSHARPEntities())
{
var result = rep.Employees
.Where(x => x.EMPLOYEESTATE == 1 && x.FULLNAME.Contains(prefixText.ToUpper()))
.Select(x => new
{
x.EMPLOYEEID,
x.FULLNAME,
x.MANNO,
x.NRC
}).ToArray();
json = jss.Serialize(result);
}
context.Response.ContentType = "text/javascript";
context.Response.Write(json);
}
public bool IsReusable
{
get
{
return false;
}
}
}
Below is the jquery and the ajax call to the ashx handler
$(document).ready(function () {
$(document).ajaxStart($.blockUI).ajaxStop($.unblockUI);
LoadEmployeeTypeahead();
// LoadEmployeeJSON();
});
function LoadEmployeeTypeahead() {
//var empData = empList;
var fullname = new Bloodhound({
remote: {
url: '/Employess.ashx?query=%QUERY',
wildcard: '%QUERY'
},
datumTokenizer: function (d) {
//var employees = $.parseJSON(msg.d);
return Bloodhound.tokenizers.whitespace(d.FULLNAME)
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 10
});
fullname.initialize();
// Make the code less verbose by creating variables for the following
var fullnameTypeahead = $('#<%=txtFullName.ClientID %>.typeahead');
// Initialise typeahead for the employee name
fullnameTypeahead.typeahead({
highlight: true
}, {
name: 'FULLNAME',
displayKey: 'FULLNAME',
source: fullname.ttAdapter(),
templates: {
empty: [
'<div class="empty-message">',
'No match',
'</div>'
].join('\n'),
suggestion: function (data) {
return '<h6 class="">' + data.FULLNAME + "<span class='pull-right text-muted small'><em>" + data.MANNO + "</em></span><span class='pull-right text-muted small'><em>" + data.NRC + "</em></span>" + '</h6>';
}
}
});
var fullnameSelectedHandler = function (eventObject, suggestionObject, suggestionDataset) {
/* See comment in previous method */
$('#<%=txtFullName.ClientID %>').val(suggestionObject.FULLNAME);
$('#<%=txtEmployeeID.ClientID %>').val(suggestionObject.EMPLOYEEID);
$('#<%=txtManNo.ClientID %>').val(suggestionObject.MANNO);
$('#<%=txtNRC.ClientID %>').val(suggestionObject.NRC);
};
// Associate the typeahead:selected event with the bespoke handler
fullnameTypeahead.on('typeahead:selected', fullnameSelectedHandler);
}
I am quite new to MVC and Jquery and I am trying to dynamically load data from a database to populate a dropdown list. Although the data is returned from the controller, it is not displayed in the dropdown. What is wrong here?
Here is my controller code:
public JsonResult GetReasonforLeave(int typecode)
{
List<LeaveReason> reason_list = itlbg1.LeaveReasons.Where(f => f.LeaveType_typeCode == typecode).ToList();
return Json(reason_list, JsonRequestBehavior.AllowGet);
}
Here's the jquery:
function getreason(selecteditem) {
sel_val = selecteditem.value;
$.getJSON("/Leave/GetReasonforLeave", { typecode: sel_val })
.done(function (data) {
var options = $("#reason");
$.each(data, function (item) {
options.append($("<option />").val(item.reasonID).text(item.description));
});
});
}
Did the changes Stephen requested and it worked. Here's the working code FYI. Thanks Stephen.
Jquery:
function getreason(selecteditem) {
sel_val = selecteditem.value;
$.getJSON("/Leave/GetReasonforLeave", { typecode: sel_val })
.done(function (data) {
alert(data);
var options = $("#reason_dd");
options.empty();
$.each(data, function (index, item) {
options.append($("<option />").val(item.value).text(item.text));
});
});
}
Changed controller to:
public JsonResult GetReasonforLeave(int typecode)
{
var reason_list = itlbg1.LeaveReasons.Where(f => f.LeaveType_typeCode == typecode).Select(r => new { value = r.reasonID, text = r.description });
return Json(reason_list, JsonRequestBehavior.AllowGet);
}
Source Code aspx page:
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function loadData(e) {
e.preventDefault();
var ltlng = [];
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/getData",
dataType: "json",
success: function (data) {
$(data.d).each(function (index, item) {
var firstValue = parseFloat(item.FirstValue).toFixed(2);
var secondValue = parseFloat(item.SecondValue).toFixed(2);
ltlng.push(new google.maps.LatLng(firstValue, secondValue));
});
},
error: function () {
alert("Error");
}
});
//alert("Test");
markicons(ltlng);
}
var map; var infowindow;
function InitializeMap() {
var latlng = new google.maps.LatLng(40.756, -73.986);
var myOptions =
{
zoom: 5,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
}
function markicons(ltlng) {
InitializeMap();
map.setCenter(ltlng[0]);
for (var i = 0; i <= ltlng.length; i++) {
if (ltlng[i] != undefined) {
marker = new google.maps.Marker({
map: map,
position: ltlng[i]
});
alert(ltlng[i]);
(function (i, marker) {
google.maps.event.addListener(marker, 'click', function () {
if (!infowindow) {
infowindow = new google.maps.InfoWindow();
}
infowindow.setContent("Message" + i);
infowindow.open(map, marker);
});
})(i, marker);
}
else {
}
}
}
window.onload = loadData;
</script>
<div id="map" style="width: 800px; height: 500px;">
</div>
Source Code for C#:
[WebMethod]
public static object getData()
{
var obj = new { FirstValue = 17.22, SecondValue = 78.28 };
var objList = (new[] { obj }).ToList();
objList.Add(new { FirstValue = 13.5, SecondValue = 79.2 });
objList.Add(new { FirstValue = 15.24, SecondValue = 77.16 });
return objList;
}
I am getting the result like this,
Tested Browser : Google Chrome. Please suggest me how can i resolve from this error.
You are calling your markicons(ltlng); method after you initialize your ajax request for the data.
You need to call this method AFTER you have got your data back.
Example:
success: function (data) {
$(data.d).each(function (index, item) {
var firstValue = parseFloat(item.FirstValue).toFixed(2);
var secondValue = parseFloat(item.SecondValue).toFixed(2);
ltlng.push(new google.maps.LatLng(firstValue, secondValue));
});
// Call method here.
markicons(ltlng);
},