How do you run trigger("create") on content loaded with ajax? - jquery-mobile

I have a function that refreshes the content on a page after a form is filled out. It works but the jquery mobile elements are not formatted. Calling trigger() is not working because apparently it is getting called before the elements appear on the page. Here's the code:
function add_note() {
var vid = $("#basic_note_vid_hidden").val();
note = $("#basic_note_textarea").val().replace(/(\r\n|\n|\r)/gm,"<br />");
$.ajax({
async: true,
type: "POST",
url: "ajax.pl",
data: "action=add_note&vid=" + vid + "&note=" + note,
error: function(res) {
$.growl({title:"Update failed!", style: "error",message:"Are you connected to the Internet?", static:true, size: 'medium' })
},
success: function(res) {
$.growl({title:"Update successful", message:"Note added", duration:500, size: 'small' });
$("#basic_note_close_button").click();
$("#basic_note_textarea").val('');
$("#notes .ui-content").load('ajax.pl?action=print_note_ajax&vid=' + vid).parent().trigger('create');
},
});
}
The meat of the matter is the very last line of code. Is there a way to detect when the new content gets loaded into the page so I know when I can call the trigger() function?

I'm obviously still learning basic jquery. Answer was in the docs for load():
$("#notes .ui-content").load('ajax.pl?action=print_note_ajax&vid=' + vid, function() {
$('#notes .ui-content').trigger('create');
});

Related

Ajax call will not work without preventDefault

In an MVC page, I have the following jQuery/javascript:
$("form").submit(function (event) {
var inp = $("input"); inp.attr('value', inp.val());
var html = replaceAll(replaceAll($('html')[0].outerHTML, "<", "<"), ">", "<");
// event.preventDefault();
$.ajax({
url: "/Ajax/SetSession",
asynch: false,
dataType: "json",
cache: false,
type: "get",
data: { name: 'html', data: html.substring(0, 1024) },
error: function (xhr, status, error) {
alert("Ouch! " + xhr.responseText);
// $(this).unbind('submit').submit();
},
success: function (data) {
alert("Awesome: " + data);
// $(this).unbind('submit').submit();
},
complete: function (xhr, status) {
alert('Phew!');
$(this).unbind('submit').submit();
}
});
});
It is meant to intercept the normal submit process, capture the html of the page before it's submitted, and then continue on its way as if nothing happened.
But the problem is, with both commented out, the form re-submits, as expected, put the controller never executes the /Ajax/SetSession url. Whereas, if I uncomment them, the /Ajax/SetSession does execute but the unbind does not appear to work as the form does not seem to get resubmitted.
Not sure what's going on here. What am I missing?
Any and all clues appreciated.
event.preventDefault(); should stay uncommented since this prevents form to submit instantly. Apparently you want to control the moment at which form is submitted.
$(this).unbind does not work because inside success and error handles context is no longer form - it is an jQuery ajax context object. You can do two things here to have the behavior you want:
Set context explicitly to be the form object. This can be done via context property:
$.ajax({
...
context: this, //form here!
...
success: function (data) {
alert("Awesome: " + data);
$(this).unbind('submit').submit(); //now this refers to form
},
Refer to form using a different variable:
$("form").submit(function (event) {
var form = this;
...
$.ajax({
...
success: function (data) {
alert("Awesome: " + data);
$(form).unbind('submit').submit(); //using form variable instead of this
},

select2 unable to search if data source is remote

I am using select2 select box to populate and show some server data. Most of it works fine as I am able to get the results and populate the combo box. But when I type in the search box, the selection doesn't narrow down the the closest match.
I found the problem was because the backend URL doesn't support searching based on the string provided, while select2 keeps making multiple search request to backend, based on user entered text. The legacy backend code returns results in one shot, which is populated into the combobox the first time.
My question is, how do I get the the select box to focus to the closest matching result, without making multiple Ajax calls. I want the search to happen in the results which are already fetched.
Thanx to anyone helping me out on this.
My ajax call is like below, if this helps...
select2: {
placeholder: 'Select Next Plan Id',
allowClear: true,
id: function (item) {
return item.id;
},
ajax: {
type: 'GET',
dataType: "jsonp",
url: "http://172.16.7.248:8480/app/gui?action=1&type=11",
data: function (term, page) {
return { search: term };
},
results: function (data, page) {
return { results: data.aaData };
},
success : function(data, status, xhr) {
var html = "<option value=''>None</option>";
$.each(data.aaData, function(i, item) {
html += "<option data=" + JSON.stringify(item.id) + " value=" + item.id + "'>" + item.id + "</option>";
});
$('#nextplanid').html(html);
self.prop('data-loaded', 'true');
},
error : function(data, status, xhr) {
}
},
formatResult: function (item) {
return item.id;
},
formatSelection: function (item) {
return item.id;
},
initSelection: function (element, callback) {
return $.get('/getText', { query: element.val() }, function (data) {
callback(data);
});
}
},

Tooltip using jquery ui

Its my first time using the tooltip and have done a lot research on it. I used the jquery website to get most of the information. I intend my tooltip to show dynamic data when a mouse clicks the hyperlink. I added the title to my link and have this code below:
var t = 1000;
$(document).tooltip({
content: '... waiting on ajax ...',
open: function(evt, ui) {
var elem = $(this);
$.ajax({ type: "POST",url:'/GetTooltip/', data: 80140}).always(function() {
elem.tooltip('option', 'content', 'Ajax call complete');
});
setTimeout(function(){
$(ui.tooltip).hide('destroy');
}, t);},
position: {
my: "center bottom-20",
at: "center top",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
}
});
I am not fully knowledgeable with the syntax of the ajax call in reference to the always function and how to get the data to show on my tooltip. the GetTooltip returns JSON data, I just want to post to the GetTooltip script and the returned data to show on my tooltip. At the moment my ajax is posting nothing.
Regarding your statement that you are not fully knowledgeable with
always function: the always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { }); is always executed after the ajax request was executed. For more see the documentation deferred.always() Please look also at jqXHR.always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { })
get the returned data to show on the tooltip - see the example in the fiddle
You can find many other answers on stackoverflow. Take a look at this fiddle and let me know if you need more help.
Updated fiddle 2
If have updated the fiddle. You can pass values from the parameters that are returned from the ajax callback. This is a simple wrapper around the ajax call:
function callAjax(elem){
$.ajax({ url: '/echo/json/',
type: 'POST',
contentType:"application/json; charset=utf-8",
dataType:"json",
data: { json: JSON.stringify({ text: 'some text'})}
}).always(
function(data,textStatus, errorThrown)
{
elem.tooltip('option', 'content'
, 'Ajax call complete. Result:' + data.text);
});
}
I am using JSON.stringify(...) above to create a Json-String. This function may be not present in all browsers. So if you run into troubles please use a current chrome / chromium browser to test it.
So you can use the wrapper function inside the tooltip():
$('#tippy').tooltip({
content: '... waiting on ajax ...',
open: function(evt, ui) {
var elem = $(this);
callAjax(elem);
} // open
});
Above you can see that the always method calls an anonymous function with 3 parameters (data, textStatus, errorThrown). To pass the reply from the ajax call you can use data. Above i am only passing a simple object with the propert text. To access it you can use data.text

Using Ajax for maincontentText in Highslide (in Highcharts)

First, thanks for the help!
Basically, I'm using Highslide in Highcharts to display some pictures when someone clicks on a datapoint in a line graph. Below is the code:
hs.htmlExpand(null,
{
pageOrigin:
{
x: this.pageX,
y: this.pageY
},
headingText: "<p style='margin: 0 auto;'> Weight: " + this.y,
maincontentText: "<p class='pictures'></p>" +
$.ajax
({
type: "post",
url: "pictures.php",
data:
{
"date" : this.Pictures
},
success: function(result)
{
$('.pictures').html(result);
}
}),
width: 700,
height: 600
});
Right now, Highslide correctly displays the pictures, but it also outputs "[Object object]" at the end of the Highslide pop-out. If I change my php page to just "echo 'test';", it displays the word "test" and then the [Object object].
Any ideas on how to get rid of this [Object object] piece?
Thanks!
Your ajax appears to be returning a json object. You will need to parse that object to format the result you want to display, or return HTML instead...
Edit::
on second thought, it seems more like an issue with how your are specifying the main content.
Using the + at the end of your HTML for the main content, you are including the ajax call as content.
I would specify the html element in your maincontent, but remove the ajax to a onAfterExpand call instead.
http://highslide.com/ref/hs.Expander.prototype.onAfterExpand
Interestingly, I couldn't use this solution until I saw your other question because the usage of onAfterExpand is unclear and unusual for me.
So I found another working combination of Ajax, Highcharts and Highslide :)
Something like this inside plotOptions.spline.point.events:
click: function (e) {
var curobj = this;
$.ajax({
url: "/path/to/test.html",
dataType: "html",
success: function(data){
hs.htmlExpand(null, {
pageOrigin: {
x: e.pageX || e.clientX,
y: e.pageY || e.clientY
},
headingText: curobj.series.name,
maincontentText: data,
width: 300
});
}
});
}

jQueryMobile - looping each button to change text of nested tag on click with ajax

I have a page that will make an external call on a button click, and then update the button to reflect success. The ajax calls work properly, however I am having difficulty trying to manipulate the text of the button when there are many on the page.
It is easy enough to match using $(".sabPauRes.ui-btn-text").text("Updated"); when it's the only item on the page, but I am not sure how to point to it using $(this) when I am using the each function. I read a bit about 'closest', but it doesn't seem to accomplish what I want (or I'm just doing it wrong).
Code sample below!
$(document).ready(function(){
$('.sabPauRes').each(function() {
$(this).click(function(event) {
event.preventDefault();
$.ajax({
type: "GET",
url: this.href,
cache: false,
dataType: "text",
success: onSuccess
})
})
$("#resultLog").ajaxError(function(event, request, settings, exception) {
$("#resultLog").html("Error Calling: " + settings.url + "<br />HTTP Code: " + request.status);
})
function onSuccess(data)
{
// validate the result of the ajax call, update text, change button methods as needed
if (data == "Success") {
// PROBLEM -- how do I use $this to match a class that is nested within it?
$(this).closest(".ui-btn-text").text("Updated");
} else {
alert("Failed: " + data);
}
$("#resultLog").html("Result: " + data);
}
})
})
html
<body>
<div data-role="page">
<div data-role="content">
<div data-role="collapsible">
<h3>This is an item</h3>
<p>
Resume Download
<div id="resultLog"></div>
</p>
</div>
</div>
</body>
Found the answer within Change button text jquery mobile
If you assign $(this) to a variable, then you can reference it in the .text() function as shown below:
$(document).ready(function(){
$('.sabPauRes').each(function() {
$this = $(this);
$(this).click(function(event) {
event.preventDefault();
$.ajax({
type: "GET",
url: this.href,
cache: false,
dataType: "text",
success: onSuccess
})
})
$("#resultLog").ajaxError(function(event, request, settings, exception) {
$("#resultLog").html("Error Calling: " + settings.url + "<br />HTTP Code: " + request.status);
})
function onSuccess(data)
{
// validate the result of the ajax call, update text, change button methods as needed
if (data == "Success") {
alert(data);
$(".ui-btn-text",$this).text("Updated");
} else {
alert("Failed: " + data);
}
$("#resultLog").html("Result: " + data);
}
})
})
First things first. Please stop using jquery ready handler when working with jQuery Mobile. Give your page an id and use pageinit() event instead.
pageinit = DOM ready
One of the first things people learn in jQuery is to use the
$(document).ready() function for executing DOM-specific code as soon
as the DOM is ready (which often occurs long before the onload event).
However, in jQuery Mobile site and apps, pages are requested and
injected into the same DOM as the user navigates, so the DOM ready
event is not as useful, as it only executes for the first page. To
execute code whenever a new page is loaded and created in jQuery
Mobile, you can bind to the pageinit event.
You can save a ref to the clicked button and use it in success and error handlers like this:
$(document).on("pageinit", "#page1", function(){
$(document).on("click", "a.sabPauRes", function(event){
event.preventDefault();
//Save a ref to the clicked button
$this = $(this);
$.ajax({
type: "GET",
url: this.href,
cache: false,
dataType: "text",
success: function (data){
// validate the result of the ajax call, update text, change button methods as needed
if (data == "Success") {
$this.find(".ui-btn-text").text("Updated");
} else {
$this.find(".ui-btn-text").text("Failed");
}
$("#resultLog").html("Result: " + data);
},
error: function(jqXHR, textStatus, errorThrown) {
$this.find(".ui-btn-text").text("Error");
$("#resultLog").html("Error Calling: " + $this.attr("href") + "<br />HTTP Code: " + jqXHR.status + " " + jqXHR.statusText);
}
})
});
});
Here is jsFiddle

Resources