$.deferred does not work as expected - javascript

on some button's click event I'm calling function a() which contains below mentioned Ajax call, in the success I'm using $.Deferred. It works perfectly fine on very first click of the button but when I click a button second, third, fourth... or nth time it does not work as expected (It does not go inside of confirmation function at all). what I'm doing wrong. Thank you in advance.
$.ajax({
type: "GET",
url: "some url",
data: {
parameters
},
success: function (result) {
//result is an Array object. for example **result:Array[3]**, further expand result will be like this **result[0]:Array[19], result[1]:Array[39], result[2]:Array[15]**
var defer = $.Deferred();
function confirmation(result) {
if (result.length > 1) {
$('#field' + questionID).append('<div id=dialog></div>');
$("#dialog").append('<div id=grid></div>');
$("#dialog").kendoDialog({
modal: true,
visible: false,
draggable: true,
closable: false,
title: "Please Select One Submission",
maxWidth: 500,
//maxHeight:300,
animation: {
open: {
effects: "slideIn:down fadeIn",
duration: 500
},
close: {
effects: "slide:up fadeOut",
duration: 500
}
},
actions: [
{ text: 'OK', primary: true, action: onOK }
]
});
$("#grid").kendoGrid({
dataSource: {
data: result,
schema: {
data: function (result) {
return $.map(result, function (item) {
return $.map(item, function (innerData) {
for (var i = 0; i < displayFields.length; i++) {
if (displayFields[i] == innerData.FieldIDString) {
return {
EntryGroupID: innerData.EntryGroupID,
FieldTextString: innerData.FieldTextString,
EntryValue: innerData.EntryValue
}
}
}
});
});
}
},
pageSize: 2,
group: { field: "EntryGroupID" }
},
filterable: {
mode: "row"
},
pageable: {
refresh: true,
},
noRecords: {
template: "No records to display"
},
groupable:false,
//scrollable: true,
selectable: true,
columns: [{
field: "EntryGroupID",
title: "Submissions",
filterable: {
cell: {
operator: "contains"
}
}
}, {
field: "FieldTextString",
title: "Questions",
filterable: {
cell: {
operator: "contains"
}
}
}, {
field: "EntryValue",
title: "Answers",
filterable: {
cell: {
operator: "contains"
}
}
}]
});
var wnd = $("#dialog").data("kendoDialog");
wnd.wrapper.find('.k-dialog-title').css('background', CIMSFields.backgroundColour).css('color', CIMSFields.textColour).css('width','100%').css('text-align','center');
wnd.open().center(true);
//in this function i'm waiting for user response which they will choose one array object based on this value **Confirmation** function will get the data.
function onOK(e) {
var data = [];
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
if (selectedItem != null) {
$.map(result, function (item) {
if (selectedItem.EntryGroupID == item[0].EntryGroupID) {
data.push(item);
defer.resolve(data);
}
});
}
else {
defer.resolve(data);
}
wnd.close();
}
}
else
{
defer.resolve(result);
}
return defer.promise();
}
alert(defer.state());
confirmation(result).then(function (data) {
//it never reach here except first time
alert(defer.state());
alert(data);// data is the user selected value from the grid.
})
}
});

If result is an array, .empty is not an Array property or method. $.Deferred() is not necessary, $.ajax() returns a jQuery promise object.
You can check .length of expected array, or property of expected object at .then() chained to a() call. Also, chain .fail() to log and handle errors that could possibly occur.
function a(/* parameters */) {
// note, we are `return` ing `jQuery.ajax()` call,
// which returns a jQuery promise object
return $.ajax({type: "GET", url: "some url", data: {parameters}})
}
a()
.then(function(result, textStatus, jqxhr) {
console.log(result.length, jqxhr.state());
if (result.hasOwnProperty("empty")) { console.log(result.empty); }
else { console.log("result does not have property \"empty\""); };
})
// log, handle errors here
.fail(function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown, jqxhr.state());
});

found my answer here
basically my need was I have to wait for user response in the function before proceeding further. Thank you all who took time to respond my question. I appreciate your time and effort. Most importantly I'm not using deferred at all now.

Related

Why Kendo datasource functions is not called?

I am trying to bind returned data from datasource to grid but the problem is that non of my data source functions is called...
transactionHistoryGridDS: new kendo.data.DataSource({
error: function () {
alert("erroe")
},
complete: function () {
alert("completed")
},
success: function () {
alert("success");
},
transport: {
read: {
dataType: "json",
type: 'POST',
url: args.TransactionHistoryUrl,
data: {
id: function () {return vm.transactionHistoryParams.id },
originBranch: function () {return vm.transactionHistoryParams.originBranch },
take: function () {return vm.transactionHistoryParams.take },
skip: function () {return vm.transactionHistoryParams.skip }
}
},
schema: {
parse: function (data) {
alert("hey...")
return data;
},
data: "data",
total: "total",
},
pageSize: 20,
serverPaging: false
}
}),
When i call read datasource through below code
vm.transactionHistoryGridDS.read();
Ajax request is called and data successfully returned from the server,but non of the functions including success and error and complete and parse is called
and consequently, data is not bind to the grid.
I can see some bugs that need to be fixed before your grid will work.
First of all, schema, pageSize, serverPaging is on wrong indent level, it should be on same level as transport not inside it.
transport: {...},
schema: {...},
serverPaging: ...,
pageSize: ...
Every grid should have dataSource property, read will be called automatically and data will be populated, you dont need to set data to grid or call read() function:
$('#grid').kendoGrid({
dataSource: {
transport: {
read: {...}
}
}
});
In your case I assume vm is a grid so you need to set dataSource:transactionHistoryGridDS, check example links below
If you need to send data with request use parameterMap:
$('#grid').kendoGrid({
resizable: true,
filterable: true,
sortable: true,
pageable: {
pageSize: 10,
refresh: true,
pageSizes: [5, 10, 20, 100, 500, 1000]
},
dataSource: {
pageSize: 10,
serverPaging: true,
serverFiltering: true,
transport: {
read: {
url: 'url',
type: 'POST',
dataType: 'JSON',
contentType: 'application/json'
},
update: {...},
destroy: {...},
parameterMap(data, type) {
switch (type) {
case 'read':
let request = {};
request.page = data.page - 1;
request.page_size = data.pageSize;
request.sort = data.sort;
request.filter = data.filter;
return JSON.stringify(request);
case 'destroy':
return kendo.stringify(data);
default:
break;
}
}
}
}
});
There is two way of geting data from kendo dataSource request, first one it with complete function that is called when request and response is finished. The second is promise on every dataSource request.
First example: complete call
Second example: promise call

JQuery DataTable resets on button click

I am using jQuery DataTables on a site that features the regular searchbox and some preset buttons that sort the table by column when pressed. The code does indeed sort the table when the button resets, but it immediately resets within 1/2 second. Here is my code:
//CATEGORY BUTTONS
$("#Term").on('click', function (event) {
dataTable.column(2).search('Term').draw();
});
I've searched around and looked at many forums. This should be correct, but the result always instantly resets the form. I've removed the search box functionality to see if that was interfering and causing the issue, but the issue remained. It just blinks the results up really fast and then resets it all to showing the entire list again. Could this be a thing with Internet Explorer (this machine has no access to any other browsers)?
Here is the full code:
$(document).ready(function () {
//USES API FOR DYNAMIC SEARCHING
//RENDERS TABLE
var dataTable = $("#videos").DataTable({
"paging": false,
bjQueryUI: true,
ajax: {
url: "/api/videos",
dataSrc: ""
},
columns: [
{
width: "70%",
data: "title",
render: function (data, type, video) {
var videoTitle = video.title.toUpperCase();
return "<VideoItem><a href='" + "../" + video.url + "'>" + "<spacerTop>" + videoTitle + "</spacerTop></a></VideoItem>";
}
},
{
width: "10%",
visible: false,
data: "description",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "categoryName",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "meta",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "date",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "categoryID",
render: function (data) {
return data;
}
}
]
});
//CONTROLS DELETE BUTTON ACTION
$("#videos").on("click", ".js-delete", function () {
var button = $(this);
bootbox.confirm("Are your sure you want to delete this video?", function (result) {
if (result) {
$.ajax({
url: "/api/videos/" + button.attr("data-video-id"),
method: "DELETE",
success: function () {
button.parents("tr").remove();
}
});
}
});
});
//MAKES SEARCH BOX ON TOP INTERACT WITH DATATABLE
$(".search-box-input").keyup(function () {
dataTable.search(this.value).draw();
});
//CATEGORY BUTTONS
$("#Term").on('click', function (event) {
dataTable.column(2).search('Term').draw();
});
});

How to show "No Results Found" with typeahead.js?

I am trying to show results not found message when there's no suggestion from user input. typeahead.js shows input suggestion while giving input to text field..if there no suggestion found then how to show results not found message?.. version is typeahead.js 0.11.1
You can check if no result with empty parameter:
I have edited above code a little bit so that it may help to others searching the same thing.
$('.typeahead').typeahead({
hint: false,
highlight: true,
minLength: 3,
},
{
name: 'firstnames',
displayKey: 'value',
source: firstnames.ttAdapter(), // this is your result variable
templates: {
empty: function(context){
// console.log(1) // put here your code when result not found
$(".tt-dataset").text('No Results Found');
}
}
I have the same issue. But i'm using ajax for my source not adapter. You can try adding popover if suggestions length is 0.
function BindControls_facility(facility_names,facility_details,id) {
var timeout;
$('#facility_names'+id).typeahead({
items: "all",
// source: facility_names,
source : function (query, result) {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
$.ajax({
url: master_url + "/facility_name_dropdown_list",
method: 'POST',
xhrFields: {
withCredentials: false
},
data: { input_query : query},
success: function (data) {
if(Object.keys(data.facility_name).length > 0){
// $("#facility_names"+id).popover('destroy');
result($.map(data.facility_name, function (item) {
return item;
}));
}
else{
$('#facility_names'+id).popover({container: '#botdiv'+id,placement: 'top'}).popover('show');
$('#facility_names'+id).attr('data-content','No result found for \"'+$("#facility_names"+id).val()+'\"').data('bs.popover').setContent();
setTimeout(function () {
$('#facility_names'+id).popover('destroy');
}, 2000);
}
}
});
}, 300);
},
hint: true,
highlight: true,
cache: true,
compression: true,
minLength: 3,
updater: function(item) {
var details = "";
$.ajax({
url: master_url + "/get_facility_name",
method: 'POST',
xhrFields: {
withCredentials: false
},
data: { facility_name : item},
success: function (data) {
console.log(data.status);
}
});
return item;
}
});
}
I tried showing this "no results found" warning using bootstrap-popover. I know its not a good one to try but i just shared my way to achieve this if i had the same issue.

Select2 - infinite scroll not loading next page with remote data

I am using Select2 4.0.1, I have used ajax to populate the result based on users input, but whenever I search for anything select2 lists first page result, but consecutive pages were not loading, also request is made for 2nd page on scroll. seems to be I am missing something.
$multiselect = $(element).select2({
closeOnSelect: false,
multiple: true,
placeholder: 'Assign a new tag',
tags: true,
tokenSeparators: [","],
ajax: {
url: '/search_url',
dataType: 'json',
type: 'GET',
delay: 250,
data: function(params) {
return {
search: params.term,
page: params.page
};
},
processResults: function(data, params) {
var more, new_data;
params.page = params.page || 1;
more = {
more: (params.page * 20) < data.total_count
};
new_data = [];
data.items.forEach(function(i, item) {
new_data.push({
id: i.name,
text: i.name
});
});
return {
pagination: more,
results: new_data
};
},
cache: true
}
})
Any help is much appreciated.Thnx:)
This is the code I got working last week. I am using a different transport on my end, but that shouldn't make a difference. I was having the same issue as you regarding the lack of paging working while scrolling. My issue ended up being that I didn't have the proper {'pagination':{'more':true}} format in my processResults function. The only thing I can see that may work for you is to "fix" the page count in the data function vs. the processResults function.
When you scroll to the bottom of your list, do you see the "Loading more results..." label? Have you attempted to hard code the more value to true while debugging?
this.$(".select2").select2({
'ajax': {
'transport': function (params, success, failure) {
var page = (params.data && params.data.page) || 1;
app.do('entity:list:search',{'types':['locations'],'branch':branch,'limit':100,'page':page,'term':params.data.term})
.done(function(locations) {
success({'results':locations,'more':(locations.length>=100)});
});
}
, 'delay': 250
, 'data':function (params) {
var query = {
'term': params.term
, 'page': params.page || 1
};
return query;
}
, 'processResults': function (data) {
return {
'results': data.results
, 'pagination': {
'more': data.more
}
};
}
}
, 'templateResult': that.formatResult
, 'templateSelection': that.formatSelection
, 'escapeMarkup': function(m) { return m; }
});

javascript ajax call before send is not executed

I have this Javascript code:
this.confirmBox = function(data) {
$.jconfirm((function(_this) {
return function() {
var objConfig;
objConfig = $.jconfirm("getConfig");
alert("here");
return true;
};
})(this));
return false;
};
this.beforeSend = function(event, jqXHR) {
if (this.confirmBox()) {
return this.disableSubmit();
} else {
return jqXHR.abort();
}
};
When I run the script I am landing on alert("here") and return true for the function confirmBox.
The problem however is that the ajax call itself is not triggered anymore for some reason. How do I need to adjust the beforeSend function in order to check if the checkBox result is true or false?
You have to add the event on the buttons
Please see this fiddle example
buttons: {
"Yes": function () {
$(this).dialog('close');
callback(true);
},
"No": function () {
$(this).dialog('close');
callback(false);
}
}
I think call to confirmBox method in beforeSend always returns false because $.msgbox does not block thread execution like window.confirm method does. Probably you need to invoke ajax call when you get the result === "Confirm" from message box.
$.msgbox("confirm", {
type: "confirm",
buttons: [
{ type: "cancel", value: "Cancel" },
{ type: "submit", value: "Confirm" }
]}, function(result) {
if (result === "Confirm") {
// $.ajax(..)
}
}
};

Categories