Using promises response in calendar function ( which required data from ajax call ) - javascript

Ajax call in promise :
var promise = new Promise(function(resolve, reject) {
jQuery.ajax({
url:'<?php echo site_url();?>/MyController/ajax_cal',
type:'POST',
dataType: "JSON",
success:function(results) {
resolve(results);
//reject(Error(request.statusText)); // status is not 200 O K, so reject
}
});
});
Respose from promise
promise.then(function(data) {
alert(data); // this is working fine BUT i want to use this in calendar function
}, function(error) {
console.log('Promise rejected.');
console.log(error.message);
});
Calander javascript code :
<!-- Calander Module starts-->
var calendar = $('#calendar').calendar({
console.log(data); /// want to use the data from ajax call on promises
events_source: data , // here
view: 'month',
tmpl_path: '<?php echo base_url();?>asserts/bootstrap_calender/tmpls/',
tmpl_cache: false,
day: '2017-02-14',
onAfterEventsLoad: function(events) {
if(!events) {
return;
}
var list = $('#eventlist');
list.html('');
$.each(events, function(key, val) {
$(document.createElement('li'))
.html('' + val.title + '')
.appendTo(list);
});
},
onAfterViewLoad: function(view) {
$('.page-header h3').text(this.getTitle());
$('.btn-group button').removeClass('active');
$('button[data-calendar-view="' + view + '"]').addClass('active');
},
classes: {
months: {
general: 'label'
}
}
});
(function($) {
$('.btn-group button[data-calendar-nav]').each(function() {
var $this = $(this);
$this.click(function() {
calendar.navigate($this.data('calendar-nav'));
});
});
$('.btn-group button[data-calendar-view]').each(function() {
var $this = $(this);
$this.click(function() {
calendar.view($this.data('calendar-view'));
});
});
$('#first_day').change(function(){
var value = $(this).val();
value = value.length ? parseInt(value) : null;
calendar.setOptions({first_day: value});
calendar.view();
});
$('#language').change(function(){
calendar.setLanguage($(this).val());
calendar.view();
});
$('#events-in-modal').change(function(){
var val = $(this).is(':checked') ? $(this).val() : null;
calendar.setOptions({modal: val});
});
$('#format-12-hours').change(function(){
var val = $(this).is(':checked') ? true : false;
calendar.setOptions({format12: val});
calendar.view();
});
$('#show_wbn').change(function(){
var val = $(this).is(':checked') ? true : false;
calendar.setOptions({display_week_numbers: val});
calendar.view();
});
$('#show_wb').change(function(){
var val = $(this).is(':checked') ? true : false;
calendar.setOptions({weekbox: val});
calendar.view();
});
$('#events-modal .modal-header, #events-modal .modal-footer').click(function(e){
//e.preventDefault();
//e.stopPropagation();
});
}(jQuery));
<!-- Calander Module ends-->
i have want to get the dynamic data (json format ) in "calendar events_source field" . i have use a ajax call but i came to know that the variable are inaccessible outside the ajax call . i than use promises than i was successfully to alert the variable outside the ajax call But i am still unable to access it in the "calendar events_source field" . i don't know what is wrong and how i can use it .

One way to solve it is to create your calendar element after you have data (in then block). I would probably do it so that I build UI then trigger fetching and in then() function I would call onAfterEventsLoad with the received events since it seems to build the the calendar.

Related

Failed to execute postMessage on window on Ajax

I've made a custom throttle for ajax requests.
Problem is I keep getting this error?
Uncaught TypeError: Failed to execute 'postMessage' on 'Window': 1 argument required, but only 0 present.
The line points to $.ajax({.
HTML:
<input class="image_title" />
<span class="the_title"></span>
JS:
$(function() {
var aj_count = 0;
var aj_flag = false;
var aj_flag2 = false;
var run_on = -1;
setInterval(function() {
aj_count++;
if (aj_flag === true) {
run_on = aj_count + 250;
aj_flag = false;
aj_flag2 = true;
}
if (run_on < aj_count && aj_flag2 === true) {
var $t = $(this);
var daid = $('.image_id').val();
aj_flag2 = false;
$.ajax({
type: "POST",
url: '/ajax/set_title.php',
data: {
'title' : $t,
'id' : daid
},
success: function(data) {
var data = JSON.parse(data);
$('.the_title').html( '<small>Title:</small> <strong>' + data.title + '</strong>' );
}
});
}
}, 1);
$('.image_title').on('input', function(e) {
aj_flag = true;
e.preventDefault();
return false;
});
$('.image_title').on('keydown', function(e) {
if (e.which == 13) {
e.preventDefault();
return false;
}
});
});
As you can see I have tried moving direct form vals into variables etc but I cannot get it to work anymore. When I replace the ajax section with a console.log it runs as expected. I've been looking around but I don't really understand what the error means still as ajax has an array passed to it.
Thank you for your time
The error is probably because of
var $t = $(this);
You're trying to send $t as the value of the title: parameter with
data: {
title: $t,
id: daid
},
But a jQuery object can't be serialized into a POST parameter.
You need to set $t to a proper title string. I don't know where that is in your application, but that should fix it.

event handler are not working in asynchronous ajax call

i am filling up my dropdowns using this ajax call ..selectItems create select option tags in html using attribute_map
var $el = this.$el(model);
var rule_title = "Job Family: ";
var attribute_map = [];
var current_object = this;
$el.append(this.getRuleTitle(rule_title, model));
jQuery.ajax({
url : "<%= Rails.configuration.url_prefix %>/team/index/get_rule_attribute_values",
type : "GET",
data : { name : "jobFamily" },
dataType : "json",
success : function(data){
var attribute_array = data.value.rule_attribute_values;
attribute_array.sort(function(a,b){
if(a.display_name > b.display_name){
return 1;
}
if(a.display_name < b.display_name){
return -1;
}
return 0;
});
var index = 0;
var obj;
for (obj in attribute_array){
attribute_map[index] = [];
attribute_map[index][0] = attribute_array[index].display_name + " ( " + attribute_array[index].internal_name + " ) " ;
attribute_map[index][1] = attribute_array[index].internal_name;
index++;
}
current_object.selectItems($el,
attribute_map,
"jobFamily", model.jobFamily, {multiple : "multiple", "data-placeholder" : "Add Constraint..."}, "400px");
},
complete : function() {
console.log("completed");
},
error : function(jqXHR, textStatus,errorThrown){
var requestResponse = {
httpStatus: jqXHR.status,
error:jqXHR.statusText,
};
}
});
when i put async as false ..event handler works fine but in synchronous call , the just doesn't do anything
event handler looks like
$('.chosen-select jobFamily').on('change',function(evt, params){
console.log("completeddddddd");
var value = $('.chosen-select jobFamily').val();
console.log(value);
if (value == null) {
// Input is empty, so uncheck the box.
$('.jobFamily').prop("checked", false);
} else {
// Make sure the box is checked.
$('.jobFamily').prop("checked", true);
}
});
});
where '.chosen-select jobFamily' is class of select tag and '.jobFamily' is class of check box ... i have tried writing my jquery inside complete argument of ajax call , i tried writing my jquery inside
$('document).bind('ajaxComplete',function({
//above jquery
});
please help . i have spent more than 2 days on that . all code lies inside ready function.

jQuery - Do action when all ajax have completed

I've read about the jQuery's Deferred object, but I can't seem to make much sense out of it, here's my problem, I've got the following code:
function preprocess(form) {
$(form).find(".input input").each(function() {
var required = $(this).attr("required");
var checkField = $(this).closest(".inputcontainer").children(".check");
var errorField = $(this).closest(".inputcontainer").children(".errormessage");
if (typeof required !== 'undefined') {
$(checkField).each(function() {
$(this).css("color", "#FFFF00");
$(this).html("✘");
});
$(errorField).each(function() {
$(this).css("color", "#FFFF00");
$(this).html("(Required)");
});
}
else {
$(checkField).each(function() {
$(this).css("color", "#FFFF00");
$(this).html("✔");
});
$(errorField).each(function() {
$(this).css("color", "#000000");
$(this).html("");
});
}
});
$(form).find("datalist").each(function() {
var datalist = $(this);
callService({
name: "datalist_" + $(this).attr("id"),
data: { },
success: function(json) {
$(json).each(function() {
var html = "";
$(this.options).each(function() {
html += "<option value='" + this.value + "'>";
});
$(datalist).append(html);
});
}
});
});
$(form).find("select").each(function() {
var select = $(this);
callService({
name: "select_" + $(this).attr("name"),
data: { },
success: function(json) {
$(json).each(function() {
var html = "";
$(this.options).each(function() {
html += "<option value='" + this.id + "'>" + this.value + "</option>";
});
$(select).append(html);
});
}
});
});
}
This code prepares a form to be ready to be presented to the user, which involves AJAX calls, which I have wrapped in a callService({}); call, what you can see is the following:
It checks input and puts possibly (Required) next to the fields. (No AJAX)
It loads options from <datalist> and <select>s dynamically. (AJAX)
Then I also have the following (simplified):
function setContent(html, url) {
html = $.parseHTML(html);
$(html).filter("form").each(function() {
preprocess($(this));
});
$("#pagemain").html(html);
}
This gets html from an AJAX call, then calls preprocess on all its forms and updates the #pagemain.
However now data is being displayed before the preprocess has completely finished.
The question: How can I do the $("#pagemain").html(html); after preprocessed ánd involving AJAX processes, have been finished?
Try:
function preprocess(form) {
//Your above code is omitted for brevity
var promises = [];
$(form).find("datalist").each(function() {
var defered = $.Deferred();//create a defered object
promises.push(defered.promise());//store the promise to the list to be resolved later
var datalist = $(this);
callService({
name: "datalist_" + $(this).attr("id"),
data: { },
success: function(json) {
$(json).each(function() {
var html = "";
$(this.options).each(function() {
html += "<option value='" + this.value + "'>";
});
$(datalist).append(html);
});
defered.resolve();//resolve the defered when ajax call has finished
}
});
});
$(form).find("select").each(function() {
var defered = $.Deferred();//create a defered object
promises.push(defered.promise());//store the promise to the list to be resolved later
var select = $(this);
callService({
name: "select_" + $(this).attr("name"),
data: { },
success: function(json) {
$(json).each(function() {
var html = "";
$(this.options).each(function() {
html += "<option value='" + this.id + "'>" + this.value + "</option>";
});
$(select).append(html);
});
defered.resolve();//resolve the defered when ajax call has finished
}
});
});
return promises;
}
Your setContent:
function setContent(html, url) {
html = $.parseHTML(html);
var promises = [];
$(html).filter("form").each(function() {
promises = promises.concat(preprocess($(this)));//Concatenating all promises arrays
});
$.when.apply($,promises).then(function(){// Use $.when to execute a function when all deferreds are resolved.
$("#pagemain").html(html);
});
}
Deferred's can be a little intimidating to learn at first, but, like most things, once the light bulb goes on and you get it, it's pretty simple. The simple setup for creating a deferred object is like this:
var defer = $.Deferred(function(dfd) {
// do the processing you need, and then...
// when processing is complete, make a call to...
dfd.resolve(/* return data goes here, if required */);
}).promise();
// use the deferred object like it was an ajax call
defer.then(/* do the stuff that needed to wait */);
So, using your example:
function setContent(html, url) {
html = $.parseHTML(html);
var defer = $.Deferred(function(dfd) {
$(html).filter("form").each(function() {
preprocess($(this));
});
dfd.resolve();
}).promise();
defer.then($("#pagemain").html(html));
}
neat solution will be using when :
http://api.jquery.com/jQuery.when/
$.when( {//your preprocessing function here
} ).done(function( x ) {
//your done action here
});

Callback never called on Jquery.post();

I'm having some trouble using JQUERY Post function.
I have 2 functions that call JQUERY Post function.
Both of them is working fine, but the callback function is never called (handleLike).
When I call handleLike manually, it's works perfect.
(Even if handleLike has just an alert inside, the callback function is not called)
Could you please help me with this thing?
<script type="text/javascript">
$(document).ready(function() {
function handleLike(v_cb){
alert("Call back chamou!");
$('#erro').html(v_cb.mensagem);
if (v_cb.class == 'map'){
var elemento = $('#maplike');
}else{
var elemento = $('#commentlike'+v_cb.id);
}
if (!(elemento.hasClass('disabled'))){
elemento.addClass("disabled");
var likes = elemento.find('font').text();
likes++;
elemento.find('font').html(likes);
}
}
$('#maplike').click(function() {
//var map_id = $('#like').find('font').attr('value');
var id = $(this).attr("name");
if (!($(this).hasClass('disabled'))){
var JSONObject= {
"mensagem":"Testando Json",
"id":86,
"class":"map"
};
handleLike(JSONObject);
alert("Teste");
$.post(
'/cmap/maps/like',
{ id: id },
handleLike,
'json'
);
}
});
$('[id*="commentlike"]').click(function() {
//var map_id = $('#like').find('font').attr('value');
var id = $(this).attr("name");
if (!($(this).hasClass('disabled'))){
$.post(
'/cmap/comments/like',
{ id: id },
handleLike,
'json'
);
}
});
});
</script>
Diagnostic, not solution
Rationalizing and adding an error handler, you should get something like this :
$(document).ready(function() {
function handleLike(v_cb){
alert("Call back chamou!");
$('#erro').html(v_cb.mensagem);
var elemento = (v_cb.class && v_cb.class == 'map') ? $('#maplike') : $('#commentlike'+v_cb.id);
if (!elemento.hasClass('disabled')){
var f = elemento.addClass("disabled").find('font');
f.html(++Number(f.text()));
}
}
function ajaxError(jqXHR, textStatus, errorThrown) {
alert('$.post error: ' + textStatus + ' : ' + errorThrown);
};
$('#maplike').on('click', function() {
var $this = $(this);
if (!$this.hasClass('disabled')) {
$.post('/cmap/maps/like', { id: $this.attr("name") }, handleLike, 'json').fail(ajaxError);
}
});
$('[id*="commentlike"]').on('click', function() {
var $this = $(this);
if (!$this.hasClass('disabled')) {
$.post('/cmap/comments/like', { id: $this.attr("name") }, handleLike, 'json').fail(ajaxError);
}
});
});
untested
Barring mistakes, there's a good chance the error handler will inform you of what's going wrong.
I follow the Kevin B tip and use $ajax method.
It was a parseerror. Sorry.
The return of v_cb was not a json, it was a html. I correct my return, and everything was ok.

Refreshing Pagination in DataTables?

I'm having a strange issue that's only arising in my dataTable in select environments. I've written a function that allows the user to delete a row, then if it's the last row on that particular page, reload the Table and send the user to the 'new' last page.
However, on some servers, it's not working properly -- I think it has to do with the fact that with after using fnClearTable and fnDraw, the pagination of the table still holds the last 'empty' page.
Here's the function I'm working with now:
function fnDelete(elem) {
if (selected.length > 0) {
var c;
c = confirm("Are you sure you want to delete the selected Agency?");
if (c) {
var deleteURL = urlstr.substring(0, urlstr.lastIndexOf("/") + 1) + "delete.do";
deleteRecord(deleteURL, selected[0]);
if ($(".tableViewer tbody tr:visible").length === 1) {
oTable.fnClearTable();
oTable.fnDraw();
oTable.fnPageChange("last");
}}}}
In addition, here's my delet function.
function deleteRecord(deleteURL, iid){
var didDelete = false;
jQuery.ajax({
type: "POST",
url: deleteURL,
dataType:"html",
data:"recordID="+iid,
async : false,
success:function(response){
didDelete = true;
oTable.fnDraw(true);
selected = [];
selectedRecord = [];
enableButtons(selected);
},
error:function (xhr, ajaxOptions, thrownError){
<%-- is the message in a range we can handle? --%>
if ((xhr.status >=400) && (xhr.status < 500)) {
alert(xhr.responseText);
}
else {
alert('<spring:message arguments="" text="Internal Server Error" code="ajax.internal.server.error"/>');
}
}
});
return didDelete;
}
Again, this issue is only coming up on certain computers. Can anyone help?
Also, here's the configuration for my DataTable::
oTable = $('#${tableName}_grid').dataTable({
bDestroy: true,
bSort: true,
bFilter: true,
bJQueryUI: true,
bProcessing: true,
bAutoWidth: true,
bInfo: true,
bLengthChange: true,
iDisplayLength: ${sessionScope.displayLength},
sPaginationType: 'full_numbers',
bServerSide: true,
sAjaxSource: "<c:url value='${dataUrl}'/>",
aaSorting: [<c:forEach items="${sortInfo}" var="oneSort"> [${oneSort.columnIndex},'${oneSort.ascending ? "asc":"desc"}']</c:forEach>],
aoColumns: [
<c:forEach items="${columns}" var="curCol" varStatus="colLoop">
{sName: '${curCol.fieldName}', bSortable: ${curCol.sortable}, bSearchable: false, sTitle: "<c:out value='${curCol.title}'/>", sType: '${curCol.displayType}', bVisible:${curCol.visible}, vdbType:'${curCol.vdbType}', sClass:'${curCol.displayType}'}${colLoop.last ? '' : ','}
</c:forEach>
],
aoColumnDefs:[{sClass:"color_col", aTargets:['color']}],
fnRowCallback: function( nRow, aData, iDisplayIndex ) {
$('#${tableName}_grid tbody tr').each( function () {
if ($.inArray(aData[0], selected)!=-1) {
$(this).addClass('row_selected');
}
});
return nRow;
},
fnInfoCallback: function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
if(myPos>=iStart && myPos<=iEnd){
//alert(myPos+" visible")
}else{
selected = [];
selected = [];
selectedRecord = [];
$('tr').removeClass('row_selected');
enableButtons(selected);
}
},
fnDrawCallback: function ( oSettings ) {
$('#${tableName}_grid tbody tr').each( function () {
var iPos = myPos = oTable.fnGetPosition( this );
if (iPos!=null) {
var aData = oTable.fnGetData( iPos );
if ($.inArray(aData[0], selected)!=-1) {
$(this).addClass('row_selected');
}
}
var htxt = '';
$(this).find('.color').filter(function(i,tdata){
htxt = '';
htxt = '#'+($(tdata).text());
return true;
}).css("background",htxt);
$(this).dblclick( function(){
var iPos = myPos = oTable.fnGetPosition(this);
var aData = oTable.fnGetData(iPos);
var iId = aData[0];
selected = [];
selectedRecord = [];
selected.push(iId);
selectedRecord.push(aData);
$('tr').removeClass('row_selected');
$(this).addClass('row_selected');
enableButtons(selected);
<%-- in case there is no edit button or its enablement is more complex,
// click the button instead of assuming it will call fnEdit.
// Do first() because jQuery is returning the same element multiple times.--%>
$(".${tableName}_bttns > span.edit-doubleclick:not(.disabld)").first().click();
});
$(this).click( function () {
var iPos = myPos = oTable.fnGetPosition(this);<%-- row index on_this_page --%>
var aData = oTable.fnGetData(iPos);
var iId = aData[0];
var is_in_array = $.inArray(iId, selected);
<%-- alert("iPos: " + iPos + "\nData: " + aData + "\niId: " + iId + "\nselected: " + selected + "\nis_in_array: " + is_in_array); --%>
selected = [];
selectedRecord = [];
if (is_in_array==-1) {
selected.push(iId);
selected.sort(function(a,b){return a-b});
selectedRecord.push(aData);
selectedRecord.sort(function(a,b){return a[0]-b[0]});
}
else {
selected = $.grep(selected, function(value) {
return value != iId;
});
selectedRecord = $.grep(selectedRecord, function(value) {
return value != aData;
});
}
if ( $(this).hasClass('row_selected') ) {
$(this).removeClass('row_selected');
}
else {
$('#${tableName}_grid tr').removeClass('row_selected');
$(this).addClass('row_selected');
}
enableButtons(selectedRecord);
});
});
} ,
"sDom": '<"H"lTfr>t<"F"ip>',
"oTableTools":{
"aButtons":[ {
"sExtends":"print",
"bShowAll": true,
"sInfo": printmsg,
"sButtonClass":"ui-icon fg-button ui-button edit-print DTTT_button_print",
"sButtonClassHover":"ui-icon fg-button ui-button edit-print DTTT_button_print"
} ] }
});
$('#${tableName}_grid_filter input').attr("maxlength", "255").attr("size", "35");
$('#${tableName}_grid').ready(function(){
$(".DTTT_containerc").remove();
BuildToolBarButtons();
var tt;
$(".DTTT_containerc").each(function(){
tt = $(this).find("#Print").attr("title");
$(this).find("#Print").remove();
$(this).find(".DTTT_container").remove();
}
);
$(".DTTT_container > button").attr("title",tt).css("border","1px solid #9597A3").removeClass("ui-state-default");
$(".DTTT_containerc").append($(".DTTT_container").removeAttr("style"));
});
});
Your datatable is configured to load data using ajax. This means that any action against the data happens asynchronously. Specifically, the fnDraw() function allows control to go to the statement where you change the page page before the new data is back from the server. You should move the logic that takes you to the last page to the fnDrawCallback. I believe that should resolve your issue.
Thought I'd write a response to help others to show how I fixed it.
#Gavin was correct in that it was in the wrong place -- I moved the function in question to the sucess callback in AJAX. However, to fix it fully, I had to 'premptively' read what page the deletion was happening on (using fn.PageChange plugin), subtract 1 (bc DataTables is zero-based) and send the user there.
Hope this helps anyone! #Gavin, thank you for your help and for leading me int he right direction!
you can keep on the same page after the table refreshed. you need to use the following snippet to keep your pagination same after refreshing datatable. just copy paste following js code on a separate file and hook it with your current page.
$.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
if(oSettings.oFeatures.bServerSide === false){
var before = oSettings._iDisplayStart;
oSettings.oApi._fnReDraw(oSettings);
oSettings._iDisplayStart = before;
oSettings.oApi._fnCalculateEnd(oSettings);
}
oSettings.oApi._fnDraw(oSettings);
};
and now, you might be used the "fnDraw" to refresh the dataTable. So now, instead of that code. change it like this.
oTable1.fnStandingRedraw();
Now, your dataTable will keep the same page after refreshing it.

Categories

Resources