Async tooltip using JSON and kendo.template - javascript

I am struggeling with the KendoUI tooltip helper. Currently I am doing the following to get some tooltip information on a grid row:
$("#grid").kendoTooltip({
filter: 'td:nth-child(10)',
content: function (e) {
var template = kendo.template($("#myToolTipTemplate").html());
var dataItem = $("#grid").data("kendoGrid").dataItem(e.target.closest("tr"));
var tooltipHtml;
$.ajax({
url: DetailsURL + "/" + dataItem.Id,
async: false
}).done(function (data) { // data.Result is a JSON object from the server with details for the row
if (data.Success) {
data.Result = data.Result.replace(/null/g, "\"N/A\"");
tooltipHtml = template($.parseJSON(data.Result));
} else {
tooltipHtml = "Ooops!<br>Something went wrong (" + data.Result + ")";
}
});
return tooltipHtml;
}
});
I would like to get rid of the synchronous ajax call and make it asynchronous. I saw some asynchronous examples where the server delivers the full html, but nothing that works with JSON data from the server, that is then "compiled" via a kendo.template() to html on the client. Any suggestions how to do this?

Set the content of the tooltip to be a placeholder value (e.g.
"Loading..")
Listen for the "Show" event of the tooltip.
When the show event is triggered, start the request for JSON from the server
In the 'done' callback, execute the template, and replace the content of the tooltip with the new html in the 'done' callback
$("#ID").data("kendoTooltip").popup.wrapper.find(".k-tooltip-content").html("........");

Telerik helped me here. And, as often, it's easier than guessed..
$("#grid").kendoTooltip({
filter: 'td:nth-child(10)',
content: function (e) {
var template = kendo.template($("#myToolTipTemplate").html());
var dataItem = $("#grid").data("kendoGrid").dataItem(e.target.closest("tr"));
var tooltipHtml;
$.ajax({
url: DetailsURL + "/" + dataItem.Id,
async: false
}).done(function (data) { // data.Result is a JSON object from the server with details for the row
if (data.Success) {
data.Result = data.Result.replace(/null/g, "\"N/A\"");
tooltipHtml = template($.parseJSON(data.Result));
} else {
tooltipHtml = "Ooops!<br>Something went wrong (" + data.Result + ")";
}
// set tooltip content here (done callback of the ajax req)
e.sender.content.html(tooltipHtml);
});
}
});

Related

Adding to JSON array by HTML button

I have an AJAX call, as below. This posts data from a form to JSON. I then take the values and put them back into the div called response so as to not refresh the page.
$("form").on("submit", function(event) { $targetElement = $('#response'); event.preventDefault(); // Perform ajax call // console.log("Sending data: " + $(this).serialize()); $.ajax({
url: '/OAH',
data: $('form').serialize(),
datatype: 'json',
type: 'POST',
success: function(response) {
// Success handler
var TableTing = response["table"];
$("#RearPillarNS").empty();
$("#RearPillarNS").append("Rear Pillar Assembly Part No: " + response["RearPillarNS"]);
$("#TableThing").empty();
$("#TableThing").append(TableTing);
for (key in response) {
if (key == 'myList') {
// Add the new elements from 'myList' to the form
$targetElement.empty();
select = $('<select id="mySelect" class="form-control" onchange="myFunction()"></select>');
response[key].forEach(function(item) {
select.append($('<option>').text(item));
});
$targetElement.html(select);
} else {
// Update existing controls to those of the response.
$(':input[name="' + key + '"]').val(response[key]);
}
}
return myFunction()
// End handler
}
// Proceed with normal submission or new ajax call }) });
This generates a new <select id="mySelect">
I need to now extract the value that has been selected by the newly generated select and amend my JSON array. Again, without refreshing the page.
I was thinking of doing this via a button called CreateDrawing
The JS function for this would be:
> $(function() {
$('a#CreateDrawing').bind('click', function() {
$.getJSON('/Printit',
function(data) {
//do nothing
});
return false;
});
});
This is because I will be using the data from the JSON array in a Python function, via Flask that'll be using the value from the select.
My question is, what is the best way (if someone could do a working example too that'd help me A LOT) to get the value from the select as above, and bring into Python Flask/JSON.

Javascript loop with ajax call

I've been struggling all afternoon to understand how to make this work, hopefully someone can help. I have a simple requirement to run through a list of checked check boxes, retrieve some data from the server, fill an element with the data expand it. So far I have the following code;
function opentickedrows() {
$('input[type=checkbox]').each(function () {
if (this.checked) {
tid = $(this).attr('name').replace("t_", "");
$.ajax({
url: '/transfer_list_details_pull.php?id=' + tid,
type: 'GET',
success: function (data) {
$('#r' + tid).html(data);
$("#r" + tid).show();
$("#box" + tid).addClass("row-details-open");
}
});
}
});
}
The problem that I am having is that the ajax calls all seem to happen so fast that 'tid' isn't being updated in the ajax call. From what I have read I believe I need to wrap this up into a couple of functions with a callback but I just can not get my head around how. I'd be really grateful if someone can set me on the right path.
Ajax calls are asynchronous, so when the success callback is invoked, tid has the value of the last item of the $('input[type=checkbox]').
You could use a closure:
function opentickedrows() {
$('input[type=checkbox]').each(function () {
if (this.checked) {
tid = $(this).attr('name').replace("t_", "");
(function(tid) {
$.ajax({
url: '/transfer_list_details_pull.php?id=' + tid,
type: 'GET',
success: function (data) {
$('#r' + tid).html(data);
$("#r" + tid).show();
$("#box" + tid).addClass("row-details-open");
}
});
})(tid)
}
});
}

jQuery AJAX queue checkbox filters and send request to server

Hi I am creating a site using Laravel, jQuery & AJAX. I have multiple checkbox filters on a page that is sent to the server using AJAX and the results are filtered on the front end of the website. Now the problem I have is that everything a checkbox is changed a request is sent to the server; which I want to amend. I want to instead queue this in an array or something similar so that I can send it to the server every minute or perhaps when the last request has finished. But I'm not entirely sure how I would do this.
This is the code I have so far;
$('#filters input[type=checkbox]').click(function(e) {
console.info('Thank you for selecting "' + $(this).attr('value') + '"');
filters.update('/index/filter',$('#filters :input').serialize(), '&offset=0', true);
});
a typical filter looks as follows;
<input type="checkbox" id="tag_982" name="region[]" class="essex checkbox form-filters" value="Essex" data-name="Essex">
and the request is sent as follows;
var filters = {
update: function(url, data, offset, reset) {
var count = '&count=40';
if (typeof offset === 'undefined') {
data = data + count;
} else {
data = data + count + offset;
}
$('.loading-icon').fadeIn();
$('#adverts').addClass('loading');
$.ajax({
url: url,
async: true,
dataType: 'json',
data: data,
type: 'POST',
success: function(json) {
console.log('Adverts successfully loaded');
$('.loading-icon').fadeOut();
$('.append-data').html(json.data.viewData);
$('#adverts').removeClass('loading');
$('.info-num').html(json.data.offset + ' of ' + json.data.total + ' adverts');
if (json.data.offset >= json.data.total) {
$('#load-more').children('a').text('All adverts loaded').contents().unwrap();
} else {
$('#load-more').children('a').text('Show more adverts');
$('#load-more').children('a').attr('href', json.data.offset);
}
} // end success
}).done(function() {
}); //end ajax
}, //end update function
} //end var filters
Does anyone have any ideas how this can be achieved? I'm looking for some basic examples.

Ajax request does not update database until page refresh

I'm making a ToDo list for a dashboard system I'm creating.
So the idea is that a user can add new ToDo items, delete ToDo items and finish/unfinish ToDo items. I'm working in this project with codeIgniter.
The problem is when I'm adding a task it is added to the database but when I delete it after that or finish it, it has not been updated in the database. Only when I refresh the page and delete the task or finish the task after that it is updated in the database. I have checked the data and that has been succesfuly sended to the controller and from the controller to the model. It just does not get updated in the Database for some reason.
I'm sending all data using AJAX post requests to the codeigniter controller.
$(document).ready(function () {
runBind();
function runBind() {
/**
* Deletes a task in the To Do list
*/
$('.destroy').on('click', function (e) {
var $currentListItem = $(this).closest('li');
var $currentListItemLabel = $currentListItem.find('label');
$('#main-content').trigger('heightChange');
$.ajax({
url: 'dashboard/deleteToDo',
type: 'post',
data: 'message=' + $currentListItemLabel.text()
}).success(function (data) {
$currentListItem.remove();
}).error(function () {
alert("Error deleting this item. This item was not deleted, please try again.");
})
});
/**
* Finish the to do task or unfinish it depending on the data attribute.
*/
$('.toggle').on('ifClicked', function (e) {
console.log("hallo");
var $currentListItemLabel = $(this).closest('li').find('label');
/*
* Do this or add css and remove JS dynamic css.
*/
if ($currentListItemLabel.attr('data') == 'done') {
$.ajax({
url: 'dashboard/finishToDo',
type: 'post',
data: 'message=' + $currentListItemLabel.text() + '&finish=' + false
}).success(function (data) {
console.log(data);
$currentListItemLabel.attr('data', '');
$currentListItemLabel.css('text-decoration', 'none');
}).error(function () {
alert("Error updating this item. This item was not updated, please try again.");
})
}
else {
$.ajax({
url: 'dashboard/finishToDo',
type: 'post',
data: 'message=' + $currentListItemLabel.text() + '&finish=' + true
}).success(function (data) {
console.log(data);
$currentListItemLabel.attr('data', 'done');
$currentListItemLabel.css('text-decoration', 'line-through');
}).error(function () {
alert("Error updating this item. This item was not updated, please try again.");
})
}
});
}
$todoList = $('#todo-list');
/**
* Add a new To Do task.
*/
$("#frm_toDo").submit(function (e) {
e.preventDefault();
var url = $(this).attr('action');
var method = $(this).attr('method');
var data = $(this).serialize();
$.ajax({
url: url,
type: method,
data: data
}).success(function (data) {
addItemToHTMLList();
$('#new-todo').val('');
}).error(function () {
alert("Error saving this task. This task has not been saved, please try again.");
});
});
/**
* Adds the task that has been created directly to the HTML page
*/
var addItemToHTMLList = function () {
$('.destroy').off('click');
$('.toggle').off('click');
var todos = "";
todos +=
"<li>" +
"<div class='view'>" +
"<div class='row'>" +
"<div class='col-xs-1'>" +
"<input class='toggle' type='checkbox'>" +
"</div>" +
"<div class='col-xs-10'>" +
"<label id='item'>" + " " + $('#new-todo').val() + "</label>" +
"</div>" +
"<div class='col-xs-1'>" +
"<a class='destroy'></a>" +
"</div>" +
"</div>" +
"</div>" +
"</li>" + $todoList.html();
$todoList.html(todos);
$todoList.find('input').iCheck({checkboxClass: 'icheckbox_flat-grey', radioClass: 'iradio_flat-grey'});
runBind();
$('#main').show();
}
});
It would be great if you can help me out because I have no clue. I have checked all the data but it just does not get updated in the database before the page refresh.
Have you compared the XHR requests using browser dev tools to ensure they are 100% equivalent (for a delete on an existing todo versus a delete on a newly added todo)?
Also, the typical pattern is to use some sort of id instead of using the whole message as the matcher -- have you considered having finish/delete operate on the id of the todo instead of sending the text of the todo? You can make a unique id if you do not want to expose your database ids.
The problem is that you are creating objects after the page has finished initializing and the events have already been attached. You need to instead assign the events to a parent element, so that this element delegates the event to any new items in the to-do. See the "Delegated Events" section in the jQuery docs: http://api.jquery.com/on/

Add returned data from ajax call to a UL then update jQuery quicksand

I'm building a list of users and trying to use jQuery quicksand to update the UL based upon the returned data from an ajax request.
The data is requested like so:
$.webMethod({
url: 'http://staging.cmdapp.com/Services/Poll.asmx/LeaderboardGetTopScores',
data: '{quizIDs:"'+quizIDs+'",numRecords:"'+numRecords+'"}',
beforeSend: function () { },
success: function (ret) {
$.each(ret.leaderboard,function(i){
// do something
});
},
error: function (response) { console.log(response.responseText); }
});
The returned data is a JSON string and each user is defined by 'user_id'. JSON data (sorry for unformatted):
{"d":"{\"leaderboard\":[{\"user_id\":\"8\",\"first_name\":\"Kevin\",\"last_name\":\"McFarlane\",\"points\":\"1\",\"time_taken\":1408,\"incorrect_attempts\":0},{\"user_id\":\"9\",\"first_name\":\"Hanna\",\"last_name\":\"Gilbert\",\"points\":\"1\",\"time_taken\":4762,\"incorrect_attempts\":0},{\"user_id\":\"1\",\"first_name\":\"Adrian\",\"last_name\":\"Bathurst\",\"points\":\"0\",\"time_taken\":1616,\"incorrect_attempts\":0}]}"}
In my html page I have the quicksand list ready like so:
<ul class="quicksand">
<li data-id="1">1</li>
<li data-id="2">2</li>
<li data-id="3">3</li>
<li data-id="4">4</li>
</ul>
I now want to update the UL on every ajax request. How can I store the returned data and add each separate 'user' in a separate LI item?
I tried the following but no luck:
$.webMethod({
url: 'http://staging.cmdapp.com/Services/Poll.asmx/LeaderboardGetTopScores',
data: '{quizIDs:"'+quizIDs+'",numRecords:"'+numRecords+'"}',
beforeSend: function () { },
success: function (ret) {
$.each(ret.leaderboard,function(i){
pos = i + 1;
str = '<li data-id="'+pos+'">' + ret.leaderboard[i].first_name + ' ' + ret.leaderboard[i].last_name + '</li>';
});
$('.quicksand').quicksand( str, { adjustHeight: 'dynamic' } );
console.log(str);
},
error: function (response) { console.log(response.responseText); }
});
It maybe worth noting that I can see the correct data in each LI items being pulled in every ajax request into the DOM, but it disapears immedietely and only the first LI item is displayed.
Your JSON is incorrect. The value for the key d is actually a string here and not an object and that is the reason you feel that the JSON Formatter is not working. Its actually working but is treating it like a string instead on an Object.
You have to unwrap the quotes to treat it like an object or use $.parseJSON to convert it into an object.
$.webMethod({
url: 'http://staging.cmdapp.com/Services/Poll.asmx/LeaderboardGetTopScores',
data: '{quizIDs:"'+quizIDs+'",numRecords:"'+numRecords+'"}',
beforeSend: function () { },
success: function (ret) {
ret = $.parseJSON(ret.d);
$.each(ret.leaderboard,function(i){
pos = i + 1;
str = '<li data-id="'+pos+'">' + ret.leaderboard[i].first_name + ' ' + ret.leaderboard[i].last_name + '</li>';
});
$('.quicksand').quicksand( str, { adjustHeight: 'dynamic' } );
console.log(str);
},
error: function (response) { console.log(response.responseText); }
});
Fiddle - http://jsfiddle.net/rttAZ/

Categories