Checking if all data has been returned from server in Knockout - asp.net-mvc

I am displaying data from the user on the user page and i would like to notify the user once all the data has been loaded and there is no more data to retrieve from the server using knockout.
Knockout script
$.views.Roster.GetPage = function ( pageNumber) {
$.grain.Ajax.Get({
Url: Views.Roster.Properties.Url,
DataToSubmit: { pageNumber: pageNumber, id: Views.Roster.Properties.Id },
DataType: "json",
OnSuccess: function (data, status, jqXHR) {
$.views.Roster.RosterViewModel.AddUsers(data);
},
OnError: function (jqXHR, status, errorThrown) {
var _response = $.parseJSON(jqXHR.responseText);
$.pnotify({ title:_response.title, text: _response.Message, type: _response.TypeString});
}
});
};
$.views.Roster.ViewModel = {
RosterUsers: ko.observableArray([]),
TotalRoster: null,
CurrentPage: ko.observable(1)
};
$.views.Roster.BindModel = function (data) {
var self = $.views.Roster.ViewModel;
$.views.Roster.ViewModel.TotalRoster = ko.computed(function () {
return self.RosterUsers().length;
});
$.views.Roster.RosterViewModel.AddUsers(data);
ko.applyBindings($.views.Roster.ViewModel);
}
Next = function () {
var _page = $.views.Roster.ViewModel.CurrentPage() + 1;
$.views.Roster.ViewModel.CurrentPage(_page);
$.views.Roster.GetPage(_page);
};
$.views.Roster.RosterViewModel = function (data) {
$.views.Roster.RosterViewModel.AddUsers(data);
};
$.views.Roster.RosterViewModel.AddUsers = function (data) {
$.each(data, function (index, value) {
$.views.Roster.RosterViewModel.PushUser(value);
});
};
$.views.Roster.RosterViewModel.PushUser = function (user) {
$.views.Roster.ViewModel.RosterUsers.push(new $.views.Roster.UserViewModel(user));
};

When you say 'once all the data has been loaded', I assume you mean when the GetPage method finishes loading a single page of users, as that is the only data loading that I see in the code above. Here is one way you can do it:
First, create an observable somewhere that you can bind to to tell the user if data is loading
$.views.Roster.ViewModel = {
RosterUsers: ko.observableArray([]),
TotalRoster: null,
CurrentPage: ko.observable(1),
DataIsLoading: ko.observable(false)
};
And add some markup that shows something in the UI when data is loading
<div data-bind="visible:DataIsLoading">Data is Loading, please wait...</div>
Then set DataIsLoading before you make the ajax call, then reset it when the call is done
$.views.Roster.GetPage = function ( pageNumber) {
$.views.Roster.ViewModel.DataIsLoading(true); // Add this!
$.grain.Ajax.Get({
Url: Views.Roster.Properties.Url,
DataToSubmit: { pageNumber: pageNumber, id: Views.Roster.Properties.Id },
DataType: "json",
OnSuccess: function (data, status, jqXHR) {
$.views.Roster.RosterViewModel.AddUsers(data);
$.views.Roster.ViewModel.DataIsLoading(false); // Add this!
},
OnError: function (jqXHR, status, errorThrown) {
var _response = $.parseJSON(jqXHR.responseText);
$.pnotify({ title:_response.title, text: _response.Message, type: _response.TypeString});
$.views.Roster.ViewModel.DataIsLoading(false); // Add this!
}
});
};

Related

Difficulty with upload csv to knockout js table (ASP MVC)

I've been working with these two tutorials, but am having difficulty merging them together to get an upload csv to populate the table. It most likely is my lack of understanding of the view model.
Here's the tutorial for the knockout js editable table from the knockout js site: KnockoutJS: Editable Grid Table
And here's the tutorial for uploading a csv I'm referencing:
KnockoutJS - Upload CSV
Here's the javascript code I've been working on to upload a csv to my table. I keep getting "JavaScript runtime error: Unable to get property 'push' of undefined or null reference" - I marked in comments the problem spot. As you can see, I'm having trouble with the view model.
<script>
var UserModel = function (users) {
var self = this;
self.users = ko.observableArray(users);
self.addUser = function () {
self.users.push({
id: "",
firstName: "",
lastName: ""
});
};
self.removeUser = function (user) {
self.users.remove(user);
};
self.save = function (form) {
sendData = ko.toJSON(self.users);
$.ajax({
url: '/Users/CreateMultiple',
contentType: 'application/json',
async: true,
type: 'POST',
dataType: 'json',
data: sendData,
error: function (jqXHR, textStatus, errorThrown) {
console.log("FAIL: " + errorThrown);
},
success: function (data, textStatus, jqXHR) {
console.log("SUCCESS");
}
});
};
};
var viewModel = new UserModel([
{ id: "", firstName: "", lastName: "" }
]);
ko.applyBindings(viewModel);
// Activate jQuery Validation
$("form").validate({ submitHandler: viewModel.save });
/////
/////Upload CSV
/////
$('#lnkUpload').click(function () {
var FileToRead = document.getElementById('UserFile');
if (FileToRead.files.length > 0) {
var reader = new FileReader();
reader.onload = Load_CSVData;
reader.readAsText(FileToRead.files.item(0));
}
});
function Load_CSVData(e) {
CSVLines = e.target.result.split(/\r\n|\n/);
$.each(CSVLines, function (i, item) {
var element = item.split(",");
var csvID = (element[0] == undefined) ? "" : element[0].trim();
var csvFirstName = (element[1] == undefined) ? "" : element[1].trim();
var csvLastName = (element[2] == undefined) ? "" : element[2].trim();
UserModel.users.push(new UserModel()//here's my problem
.id(csvID)
.firstName(csvFirstName)
.lastName(csvLastName)
)
});
}
</script>
I was able to identify the fully qualified for the observable array which in turn made it work:
function Load_CSVData(e) {
CSVLines = e.target.result.split(/\r\n|\n/);
$.each(CSVLines, function (i, item) {
var element = item.split(",");
var csvID = (element[0] == undefined) ? "" : element[0].trim();
var csvFirstName = (element[1] == undefined) ? "" : element[1].trim();
var csvLastName = (element[2] == undefined) ? "" : element[2].trim();
viewModel.users.push({
id: csvID,
firstName: csvFirstName,
lastName: csvLastName
});
}

Couchbase-Lite-PhoneGap: I get “Status 400 - Bad request” when I try to create _design document(view)

I've been dealing with Couchbase-Lite-PhoneGap-Plugin.
I've try to create a design document in an Android emulator using REST API. But every time I get status: 400 - Bad request message and I cannot find my mistakes.
My codes are the following;
var cblUrl = "";
var dbName = "user";
var app = {
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
if(window.cblite) {
window.cblite.getURL(function(err, url) {
if(err) {
console.log("error launching Couchbase Lite: " + err);
} else {
console.log("Couchbase Lite running at " + url);
cblUrl = url;
}
});
} else {
console.log("error, Couchbase Lite plugin not found.");
}
// jQuery Main function
$(function() {
$("#connect").on("tap", function() {
$.ajax({
url: cblUrl + '_all_dbs',
type: 'GET',
success: function (data, textStatus, xhr) {
if (data.indexOf(dbName) == -1) { // db doesn't exist
// create a database (bucket)
$.ajax({
url: cblUrl + dbName,
type: 'PUT',
async: true,
success: function (data, textStatus, xhr) {
console.log(xhr.status);
},
error: function (xhr, statusText, errorThrown) {
console.log(xhr.status);
}
});
} else {
console.log("db exists");
}
},
error: function (xhr, statusText, error) {
console.log(xhr.status);
}
});
}); // #connect tap
// create button tap event
$("#create").on("tap", function() {
var view = {
"language" : "javascript",
"views" : {
"view_user" : {
"map" : "function(doc) {if (doc.username) {emit(doc.username, null)}}"
}
}
}
// ** create VIEW **
$.ajax({
url: cblUrl + dbName + "/_design/users",
type: 'PUT',
data: view,
success: function (data, textStatus, xhr) {
console.log(xhr.status);
},
error: function (xhr, statusText, error) {
console.log(xhr.status);
}
});
});
}); // main jQuery function
}, // onDeviceReady
};
app.initialize();
I had installed my plugin using command of
cordova plugin add com.couchbase.lite.phonegap
However the plugin was beta and a former version at plugins.cordova.io.
And then I've tried to uninstall and re-install plugin using command of
cordova plugin add https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git
I was able through this way.

How to avoid multiple ajax call from the Jquery Autocomplete ? Using Cache

I am using jquery automcomplete with the Ajax call but what i want is if part is present in the json data fetched by the ajax on first call then i want to return that data as it is without giving the ajax call i have tried it as below
function SearchText() {
var cache = {};
$("#txtItem").autocomplete({
source: function (request, response) {
var term = request.term;
$.each(cache, function (index, value) {
$.each(value, function (index, value) {
if (value.indexOf(term) >= 0) {
response(cache[term]);
return;
}
});
});
cache = {};
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "JobTagPricing.aspx/GetAutoCompleteData",
data: "{'item':'" + document.getElementById('txtItem').value + "'}",
dataType: "json",
success: function (data) {
cache[term] = data.d;
response(data.d);
},
error: function (result) {
alert("Error");
}
});
},
minLength: 3
});
}
but even if it finds the matching term in the array then also it generates the ajax call.
I m stuck here for 3 hrs now any help would be great. I have tried maxCacheLength but it is also not working.
Try this out, sometime ago i faced same problem and came up with this it might work for you
function SearchText() {
var cache = {};
var oldterm;
$("#txtItem").autocomplete({
source: function (request, response) {
if (request.term.indexOf(oldterm) >= 0) {
if (typeof (oldterm) != 'undefined') {
var data = jQuery.grep(cache[oldterm],
function (ele) {
return (ele.indexOf(request.term) >= 0);
});
response($.map(data, function (item) {
return { value: item }
}))
return;
}
} else {
cache = {};
$.ajax({
url: "JobTagPricing.aspx/GetAutoCompleteData",
data: "{ 'item': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
oldterm = request.term;
cache[request.term] = data.d;
response($.map(data.d, function (item) {
return {
value: item
}
}))
},
error: function (result) {
alert("Error");
}
});
}
},
minLength: 3,
select: function (event, ui) {
if (ui.item) {
formatAutoComplete(ui.item);
}
}
});
}
Here is a solution i found for you, It uses jQuery UI's autocomplete using cache and $.map function
function SearchText() {
var cache = {};
$("#textbox").autocomplete({
source: function(request, response) {
if (request.term in cache) {
response($.map(cache[request.term].d, function(item) {
return { value: item.value, id: item.id }
}))
return;
}
$.ajax({
url: "JobTagPricing.aspx/GetAutoCompleteData",
data: "{ 'term': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json",
dataFilter: function(data) { return data; },
success: function(data) {
cache[request.term] = data;
response($.map(data.d, function(item) {
return {
value: item.value,
id: item.id
}
}))
},
error: HandleAjaxError
});
},
minLength: 3,
select: function(event, ui) {
if (ui.item) {
formatAutoComplete(ui.item);
}
}
});
}
Hope this helps.

Autocomplete in Jqgrid returns Data from Server but dont know to put in View

This is my first post. stackoverflow is a wonderful place for developers. Here is my issue.
I am trying to use Autocomplete in JqGrid Edit Form. i successfully retrieved data from server using ajax call but dont know how to display it in the view. below is my code.
FrontEnd Code:
colModel :[
{name:'prf_articlename', index:'prf_articlename', width:90, editable:true, edittype:'text',
editoptions: {
dataInit:function(e){
$(e).autocomplete({
source: function(request, response,term) {
var param = request.term;
$.ajax({
url: '/Myelclass/AutoCompleteServlet.do?term='+param+"&action="+"artname",
success: function (data) {
response($.map(data, function(item) {
return {
label: item.label,
};
}));//END Success
},
});//END AJAX
},
minLength: 2,
});//END AUOTOCOMPLETE
}//END Dataint
}//END Dataint
},
BackEnd Code:
String term = request.getParameter("term");
List<AutoComplete> articlelist = prfbo.getArticleNameinEditGrid(term);
System.out.println("List Value " +articlelist.size());
JSONArray jsonOrdertanArray = JSONArray.fromObject(articlelist);
System.out.println(jsonOrdertanArray);
out.println(jsonOrdertanArray);
Any one help on this???
This is what I personally use in my project:
Inside colModel:
dataInit: function (elem) { NameSearch(elem) }},
The function:
function NameSearch(elem) {
$(elem).autocomplete({ source: '/Controller/NameSearch',
minLength: 2, autosearch: true,
select: function (event, ui) {
$(elem).val(ui.item.value);
$(elem).focus().trigger({ type: 'keypress', charCode: 13 });
}
})//$(elem).autocomplete
$(elem).keypress(function (e) {
if (!e) e = window.event;
if (e.keyCode == '13') {
setTimeout(function () { $(elem).autocomplete('close'); }, 500);
return false;
}
})//$(elem).keypress(function (e){
} //function NameSearch(elem) {
I'm also dealing with an Enter key press as well in the above function.
here is the complete code for my Autocomplete in jqgrid Edit form..
colModel :[
{name:'name', index:'name', width:90, align:'center', editable:true, hidden: false, edittype:'text',
editoptions:{
dataInit:function (elem) {
$(elem).autocomplete({
minLength: 2,
source: function(request, response,term) {
var param = request.term; //values we enter to filter autocomplete
$.ajax({
url: "myurl",
dataType: "json",
type:"GET",
success: function (data) {
response($.map(data, function(item) {
return {
//can add number of attributes here
id: item.id,
shform: item.shortform,
value: item.name,
clr : item.color, //here apart from name and id i am adding other values too
size: item.size,
remar:item.remarks,
subs: item.subs,
selec:item.selec ,
};
}));//END Response
},//END Success
});//END AJAX
},
select: function( event, ui ) {
// setting values to textbox in jqgrid edit form based on selected values
$('#textbox1').val(ui.item.id);
$('#textbox2').val(ui.item.shform);
$('#textbox3').val(ui.item.clr);
$('#textbox4').val(ui.item.size);
$('#textbox5').val(ui.item.sizeremar);
$('#textbox6').val(ui.item.subs);
$('#textbox7').val(ui.item.selec);
$('#textbox8').val(ui.item.selp);
}
});
$('.ui-autocomplete').css('zIndex',1000); // if autocomplete has misalignment so we are manually setting it
}
}, editrules :{required : true},
formoptions:{rowpos: 1, colpos: 2}
},
........
]
server code :
String term = request.getParameter("term");
List<ArticleDetails> articlelist = prfbo.getPrfArticleName(term); //DB call via BO and DAO class
System.out.println("List Value " +articlelist.size());
JSONArray jsonOrdertanArray = JSONArray.fromObject(articlelist);
System.out.println(jsonOrdertanArray);
out.println(jsonOrdertanArray);
hope some one find it useful.

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