Set bootstrap tooltip to AJAX call results - javascript

I have a bootstrap tooltip that I want to load data from an AJAX requestion, with the text from the request being the titleproperty of the tooltip. My AJAX request works fine, but I have two problems:
Why isn't the data from the AJAX call making its way into the tooltip?
How can I use my ttManager object to encapsulate the tooltip's state?
Currently, when the page first loads and I click on #btnSubmit in the console I see
success and the correct data from the console.log(ttManager) line
$(document).ready(function () {
//this object's title attribute will be the value of ttManager.title seen below
var ttManager = {
title: '',
setTitle: function (data) {
this.title = data;
}
}
var ajaxCall = function () {
//this returns the top five results of text from a query
$.ajax({
type: "POST",
contentType: "application/json",
url: "Service.asmx/GetDrugs",
dataType: "json",
success: function (data) {
console.log('success');
ttManager.title = data.d;
//inside this function I want to set ttManager.title equal to the data.d
console.log(ttManager);
},
error: function (xhr) {
console.log('failed: ' + xhr.status);
}
});
}
$('#btnSubmit').tooltip({
//reference to ajax call
//title is the attribute responsible for displaying text in the tooltip
//I need to use a reusable object to set the text property instead of referencing ajaxCall
//would it be better if there below were title: ttManager.title?
title: ajaxCall,
trigger: 'click',
placement: 'right'
});
});
I'm pretty sure that I need a callback function somewhere, but I'm not sure where. Any future pointers would be appreciated, too. Thanks.

First, a little explanation of bootstrap's tooltip plugin. The tooltip displayed will pull from the elements title attribute if there's one present, otherwise it will use the title argument passed.
The next thing you need to understand is that ajax calls are asynchronous. This means code will continue to run while it's waiting for a response. So, for example, if I do something like this
$.ajax({
URL: 'google.com',
success: function(){
console.log('yay');
}
});
console.log('woohoo');
you'd see "woohoo" in the console before "yay". So, currently, you're calling $('#btnSubmit').tooltip before your ajax query has altered the state of ttManager.
The other issue is that you're currently not doing anything with ttManager in relation to bootstrap. I feel like I should also mention that the ttManager object seems meaningless here.
Personally, I would change my ajax success function to this (sets the title attribute, calls tooltip, then produces another click to make the tooltip appear)
success: function(data) {
$('#btnSubmit').attr('title', data.d)
.tooltip({
trigger: 'click',
placement: 'right'
}).click();
}
remove the current $('#btnSubmit').tooltip... code currently there, and add in a one time click handler to call your ajax.
$('#btnSubmit').one('click', function() {
ajaxCall();
});

Related

Javascript does not work on returned ajax results

I have an ajax call that returns html. This works well on changes. What does not work though is the javascript I have that does stuff based on clicks in the returned results.
The ajax call is:
function update_order_shipping(){
$.ajax({
url: 'ajax_order_shipping.php',
method: "post",
dataType: 'html',
success: function (result) {
$('#shipping-method').html(result);
},
error: function(xhr, status, error) {
//alert(xhr.responseText);
}
});
};
This works well. Returns the exact results I need.
The issue is that these returned results also have radio buttons and on change I perform this javascript:
$('input[name="shipping"]').change(function() {
if($(this).is(':checked') && ( $(this).val() == 'freeamount_freeamount' ) ){
document.getElementById('fedex_number').style.display="none";
document.getElementById('ups_number').style.display="none";
document.getElementById('your_shipping_conditions').style.display="none";
var shipping_method = document.getElementById('text-freeamount').innerText;
document.getElementById('text-shipping').innerHTML = shipping_method;
var shipping_value = document.getElementById('value-freeamount').innerText;
document.getElementById('value-shipping').innerHTML = shipping_value;
}
});
Now on initial page load this works great, but the returned results which is identical html as the intial page load, the javascript fails to work. I understand it has to do with binding or something like that, but not quite sure how to implement it, so that results will always use the javascipt.
You need to use on to bind events to dynamically created elements.
$("body").on("change", "input[name='shipping']", function(event) {
// stuff here
});
"body" can be replaced with any non-dynamic element that's an ancestor of your input.
Any matching events will automatically listen for the change event, whether the element was added at the start or later.

Bootstrap modal does not work correctly with my ajax code

I created a partial view called ModalReq, which needs to be populated with data from the database.
The controller and view is working correctly.
But when you click on an element with the class '.car-box', nothing happens at first, after the second press, the correctly filled modal appears, but it doesn’t want to close in any way, how to make the modal work correctly?
Ajax code in main view:
<script>
function ajaxReq(url,type,selector) {
$.ajax({
url: url,
type: type,
contentType: 'application/json',
success: function (data) {
$(selector).html(data);
}
});
}
</script>
<script>
$(document).on('click', '.car-box', function () {
var objText = $(this).children('.box-his').children("span").text();
var objId = objText.substring(1, objText.length);
ajaxReq("#Url.Action("ModalReq")" + "?productId=" + objId, "POST", '#result');
$('#myModal').modal('show')
});
</script>
And I create a div with it at the very bottom of this view( but still above the Ajax code )
<div id="result"></div>
When you click on an element with the class '.car-box', the Ajax code creates an object that receives its number with a string type inside the card. It then leaves only a number with the same type of string. Then I call ajaxReq in which I transmit my partial view that accepts the Id specified by us. Then includes the created modal ...
I never use ajax before, so I need your help =)
In the current iteration $('#myModal').modal('show') is not waiting for the Ajax response.
How about moving it to your success function?
success: function (data) {
$(selector).html(data);
$('#myModal').modal('show')
}
Then the modal will get the data after one press.
Or: this answer jQuery ajax with ES6 Promises should give you guidance setting it up as a Promise.

select2 : cannot read property query of null

I have create javascript like this
$(document).on("select2:open", ".provider_suggestion", function() {
$(this).select2({
minimumInputLength: 2,
ajax: {
url: "../include/suggestion/provider_name.php",
dataType: 'json',
delay: 250,
data: function(params){ return { q: params.term }; },
processResults: function (data, page) { return { results: data }; },
cache: true
}
});
});
and create select html input like this
<select id="c_providers" name="c_providers" class="provider_suggestion" style="width:100%"></select>
and when page loaded, I click the select input.
I open the browser console, its mentioned that
Uncaught TypeError: Cannot read property 'query' of null
I still dont understand about this issue.
You must have already initialized the select2 somewhere previous to your provided code snippet, or I expect the select2:open listener would never fire and cause your problem. When I replicated the situation in a fiddle and peeked at the select2 source, it seemed that select2 was complaining about a dataAdapter being null, which must be a side effect of this double select2() call, or that the .select2() call is inside the listener with an unexpected context... Or something, don't have the time or interest to explore down to the root cause.
Regardless, moving the .select2() call out of the listener (and removing the then empty listener) removed the problem. Based on the limited information available in your question, it does not seem like there is any need at all to use this listener, at least the way you are using it. A simplistic working example is in this JSfiddle, where the only real difference to your original code is the removal of the listener wrapping (and the mocking of AJAX calls). So, try something like
$('#c_providers').select2({
minimumInputLength: 2,
ajax: {
url: "../include/suggestion/provider_name.php",
dataType: 'json',
delay: 250,
data: function(params){ return { q: params.term }; },
processResults: function (data, page) { return { results: data }; },
cache: true
}
});
as the only select2 initialization for this #c_providers element.

JQGRID: Trigger Reload not working on iFrame

I have a web page with an iFrame. It loads a web page (same domain) with a jqGrid table. What I'm trying to do now is:
You press a link called search it opens a dialog with a filter form to filter your search.
When you press search button inside the dialog, it changes jqGrid url param and it should .trigger('reloadGrid').
It does all except the reloadGrid, I don't know why.
Any suggestion?
Code:
// DIALOG-ACTION-SEARCH IS THE BUTTON CLASS
$('#dialog').find('.dialog-action-search').button({icons: {
primary: 'ui-icon-search'
}, text: true}).click(function(e) {
e.preventDefault();
$('.content-center').contents().find('#list').setGridParam({
url: 'filteredsearch.html?option=1'
}).trigger('reloadGrid');
$('#dialog').dialog('destroy');
$('#dialog').remove();
});
setGridParam returns a jqGrid object, not a jQuery object, so I'm pretty sure you can't chain the trigger method. Try this instead:
var list = $('.content-center').contents().find('#list')
list.setGridParam({
url: 'filteredsearch.html?option=1'
})
list.trigger('reloadGrid');
I've found that before calling trigger('reloadGrid') with JSON data, you should reset the datatype parameter.
$("#grid").jqGrid('setGridParam', { datatype: 'json' });
In response to your comments, I would split up the chained method calls and then put a breakpoint on e.preventDefault() in Chrome debugger so you can assure that everything is actually getting hit.
$('#dialog').find('.dialog-action-search').button(
{
icons: { primary: 'ui-icon-search' } ,
text: true
});
$('#dialog').find('.dialog-action-search').click(function(e) {
e.preventDefault();
var grid = $('.content-center').contents().find('#list');
$(grid).jqGrid('setGridParam', { url: 'filteredsearch.html?option=1' });
$(grid).jqGrid('setGridParam', { datatype: 'json' });
$(grid).trigger('reloadGrid');
$("#dialog").dialog('destroy');
$("#dialog").remove();
});
While I'm a fan of chaining when you can, in this case I don't think you're going to find the root of the issues without doing things a little more explicitly, especially when using .find. How do you know that the .find is actually returning the element that you want?
I experienced same problem. I did not have time to investigate why it was happening but found a workaround for it.
In a javascript file that loads inside iframe with your grid I declared
window.top.reloadEventList = function () {
$("#grid").trigger("reloadGrid");};
Then just call
window.top.reloadEventList()
instead of
list.trigger('reloadGrid')

Trying to understand why AJAX objects added into DOM return undefined

I have a problem when calling a ajax call that after the ajax data is appended into the DOM, any Javascript referring to the appended html returns that the object is undefined.
The forms use tags with Javascript submits and some Javascript to modify hidden fields, thats why the eval() is in there.
edit: This is an example of a 'href' tag and why I have the eval in there:
javascript:document.faultList.sortBy.value='4';document.faultList.sortByPrev.value='3';document.faultList.Action01.value='SetMyRequestItem';
Its how the previous developer has created this software/website before my time instead of using a REST style system.
This is my code:
function ajaxFormUpdate(formID,linkClass){
$(formID+' '+linkClass).click(function(){
eval($(this).attr('href'));
serialised = $(this).closest(formID).serialize();
$.ajax({
type: "POST",
url: 'jadehttp.dll?EbdMulti_www_01',
data: serialised,
success: function(data) {
//console.log(data)
$(formID).html($(data).find(formID));
loadHandlers();
}
});
return false
});
}
function loadHandlers(){
ajaxFormUpdate('#faultList','.ajaxLink');
ajaxFormUpdate('#accessCardList','.ajaxLink');
ajaxFormUpdate('#facilityList','.ajaxLink');
ajaxFormUpdate('#carParkingList','.ajaxLink');
ajaxFormUpdate('#visitorList','.ajaxLink');
}
loadHandlers();
Resolved this by changing .html() to .replaceWith() (thanks jgauffin for putting me on the right track) and using the following click handler instead of the standard .click()
$(".selector_class").live('click', function() { alert("new element clicked"); });

Categories