I'm trying to execute the remote code completion example in Jquery Mobile using the following url: http://demos.jquerymobile.com/1.4.0/listview-autocomplete-remote/
I use latest PhoneGap with jquery mobile version 1.4.3
the auto complete javascript code:
$(function() {
$( "#drink_brand_autocomplete" ).on( "filterablebeforefilter", function ( e, data ) {
var $ul = $( this ),
$input = $( data.input ),
value = $input.val(),
html = "";
$ul.html( "" );
if ( value && value.length > 2 ) {
$ul.html( "<li><div class='ui-loader'><span class='ui-icon ui-icon-loading'></span></div></li>" );
$ul.listview( "refresh" );
$.ajax({
url: "http://myalcoholist.com/drink-management/drink/drink-brand-autocomplete",
dataType: "jsonp",
crossDomain: true,
data: {
q: $input.val()
}
})
.then( function ( response ) {
console.log("response");
$.each( response, function ( i, val ) {
html += "<li>" + val + "</li>";
});
console.log(html);
$ul.html( html );
$ul.listview( "refresh" );
$ul.trigger( "updatelayout");
});
}
});
});
in chrome developer console i can see that the ajax call is being executed fine and the server returns a json array.
the .then() is not being executed, no ideas why.
i tried .done() instead but i got the same results.
i don't get any javascript errors.
any ideas?
Related
I have used used the chosen function in my file but it is given an error when i tried to access this function as follows:
TypeError: $(...).ajaxChosen is not a function
here is the code that i am using :
$.post( woocommerce_admin_meta_boxes_variations.ajax_url, data, function ( response ) {
$( '#bto_config_group_inner .bto_groups' ).append( response );
$( "#bto_ids_" + bto_groups_metabox_count ).chosen();
$( "#bto_ids_" + bto_groups_metabox_count ).ajaxChosen( {
method: 'GET',
url: woocommerce_admin_meta_boxes.ajax_url,
dataType: 'json',
afterTypeDelay: 100,
data: {
action: 'woocommerce_json_search_products',
security: woocommerce_admin_meta_boxes.search_products_nonce
}
}, function (data) {
var terms = {};
$.each( data, function (i, val) {
terms[i] = val;
} );
return terms;
} );
$( 'input#_per_product_pricing_bto' ).change();
$( '#bto_product_data' ).unblock();
$( '#bto_product_data' ).trigger( 'woocommerce_bto_component_added' );
} );
return false;
} );
Have you included https://github.com/meltingice/ajax-chosen in your project? Looks like it is not visible in your code.
You will need to download the file - https://github.com/meltingice/ajax-chosen/blob/master/lib/ajax-chosen.min.js
Place it in your project so that it can be referenced with your other assets and include it using the
<script type="text/javascript" src="path/to/ajax-chosen.min.js"></script>
Ideally you would use NPM to bring down the asset, but just simply copying the file locally will suffice to get you up and running
I was unable to find a CDN link for this file, so its going to have to be done manually.
I've created some sample code below. You can delete items simply by clicking the text you want to delete (or the li element).
When you look at the network tab when you delete, you get back both a 204 and 200 response. Why are there two? I'm only making 1 call.
Where the heck is the request method "OPTIONS" coming from?
//Cache DOM
var $content = $( 'ul' );
var $name = $( '#name' );
var $bike = $( '#bike' );
var $addButton = $( '#add-item' );
var $liElems = $( 'li' );
//Functions
$( function () {
function addItem( data ) {
$content.append( '<li id="' + data.id + '">' + data.name + ' likes ' + data.bike + '</li>' );
}
$.ajax( {
type: 'GET',
url: 'http://rest.learncode.academy/api/sjm/bikes',
success: function( response ) {
$.each( response, function( index, bikes ) {
addItem( bikes );
});
},
error: function( ) {
console.log ( 'error loading orders' );
}
});
$addButton.on( 'click', function(){
var data = {
name: $name.val(),
bike: $bike.val()
};
$.ajax( {
type: 'POST',
url: 'http://rest.learncode.academy/api/sjm/bikes',
data: data,
success: function( response ) {
addItem( response );
},
error: function( ) {
console.log( 'error while saving' );
}
});
});
$content.delegate( 'li', 'click', function ( ) {
var id = $( this ).attr( 'id' );
var $this = $( this );
console.log ( 'delete ' + id);
$.ajax({
type: 'DELETE',
url: 'http://rest.learncode.academy/api/sjm/bikes/' + id,
success: function( response ){
$this.fadeOut( 300, function ( ) {
remove( );
});
},
error: function( ){
console.log( 'error deleting data' );
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
<section>
name <input type="text" id="name">
bike <input type="text" id="bike">
<button id="add-item">add data</button>
</section>
<ul></ul>
</div>
When you try to send a XMLHttpRequest to a different domain than the page is hosted, you are violating the same-origin policy. However, this situation became somewhat common, many technics are introduced.
CORS is one of them.
In short, server that you are sending the DELETE request allows cross domain requests. In the process, there should be a preflight call and that is the HTTP OPTION call.
So, you are having two responses for the OPTION and DELETE call.
see MDN page for CORS.
Using jQuery to call an endpoint and populate the data on the frontend is a common task. After searching and using multiple solutions the below is my current blueprint for any ajax calls.
How can I improve the following to be faster and more efficient? I realize doing it in pure javascript will be faster but at this point I assume jQuery will be present.
Frontend - Javascript:
$(document).ready(function()
{
function callEndpoint( call_url, payload ){
return $.ajax({
url: call_url,
type: 'GET',
data: payload
});
}
$( '.get-endpoint' ).click( function() {
sSelected = $( this ).text();
console.log( sSelected );
oRequest = callEndpoint( '/play/endpoint2.php', { 'type': sSelected } );
oRequest.done(function( sJson ) {
aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
Frontend - Html:
<body>
<button class="get-endpoint">Games</button>
<button class="get-endpoint">Books</button>
<button class="get-endpoint">Comics</button>
<div class="from-endpoint">Coming soon...</div>
</body>
Backend - PHP:
$aReturn[ 'text' ] = '';
if( !empty( $_GET ) )
{
if( $_GET[ 'type' ] == 'Games' )
{
$aReturn[ 'text' ] = 'Text for games';
}
else if( $_GET[ 'type' ] == 'Books' )
{
$aReturn[ 'text' ] = 'Text for books';
}
else if( $_GET[ 'type' ] == 'Comics' )
{
$aReturn[ 'text' ] = 'Text for comics';
}
}
$sJson = json_encode( $aReturn, 1 );
header( 'Content-Type: application/json' );
echo $sJson;
I don't think that this code can be more efficient in jQuery.
But you have some options left to give a more efficient feeling :
You can use pagination to get a portion of your data each time. The
less data to load, the quicker it get. And your application will be
more responsive to the user's actions. This solution is a trick for
the user, because it will take in reality more time than before to load all the data.
You can keep previous loaded data so when you click back on a button,
it won't load again the data. But, this can only be used if the data
won't change much between each click. The first time you will click
on a button, it will take the same time as before, but the next time,
it will be immediat.
Be aware that the more HTML code you load, the more it will take time to initiate JavaScript behavior on it.
Looks like your categories won't change often. You can save some bandwidth by using JavaScript localstorage or cookies to cache data. If you plan on connecting to a mysql database at somepoint you can use StoredProcedures which are variablized precompiled statements.
Since you are anyways going to use JSON and jQuery, I would suggest that you should check out the getJSON method of jQuery. I feel that it would reduce some lines of code, though I am not sure if it would help it become more efficient.
Anyways getJSON is just a shorthand of AJAX and I thought I should suggest this.
This could be a good approach for AJAX data transport browser->server->browser. Hope it suites your needs.
jQuery
$( function () {
function fetch( data ) {
var encoding = data.encoding,
url = data.url,
params = data.params,
type = ( data.type ) ? : 'GET',
cache = ( data.cache ) ? : 'false',
async = ( data.async ) ? : 'true';
return $.ajax({
url: url,
async: async,
cache: cache,
data: params,
dataType: encoding,
type: type
});
}
var options = {
url: 'controller.php',
params: {
param_one: value_one,
param_two: value_two,
param_n: value_n
},
encoding: 'json'
};
// Get the JSON feed from the server
$.when( fetch( options ) ).then( function ( response ) {
// Is there anything in the pool?
if ( response ) {
// Store the response and use it in your code
var data = response.data;
console.log( data.responseOne );
console.log( data.responseTwo );
}
});
});
PHP Controller
// Set header to application/json
header( 'Content-type: application/json' );
// Create the DB connection object
$dbc = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME );
// Initialize parameters array
$params = array();
// Store the query variables in an array
$query_type = ( $_GET ) ? : $_POST;
// Run foreach and store the values in an array
foreach ( $query_type as $key => $value ) {
$params[ $key ] = mysqli_real_escape_string( $dbc, $value );
}
// Now you can access passed parameters like $params['param_name']
// This would be the data obtained from DB or some server array processing, whatever
$response = array(
'data' => array(
'response_one' => 'some_value',
'response_two' => 'another_value'
)
);
// Encode the result
echo json_encode( $response );
If you don't want use pure javascript, you can improve your jQuery code with better selectors
For example, you can add an id in <div class="from-endpoint">
You can add tag in selector like this:
$('button.get-endpoint')
You can drop your getEndpoint method and just use the $.get method.
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
sSelected = $( this ).text();
console.log( sSelected );
oRequest = $.get('/play/endpoint2.php', { 'type': sSelected });
oRequest.done(function( sJson ) {
aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
You can make your code lint compliant.
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
oRequest = $.get('/play/endpoint2.php', { type: sSelected });
oRequest.done(function( sJson ) {
var aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
Use success instead of done & move the callback to it's own function
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
$.get(
'/play/endpoint2.php',
{ type: sSelected },
insertData
);
});
});
function insertData( sJson ) {
var aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
}
Use $.getJSON instead of $.get or $.ajax
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
$.getJSON(
'/play/endpoint2.php',
{ type: sSelected },
insertData
);
});
});
function insertData( data ) {
$( '.from-endpoint' ).text( data.text );
}
The question I am asking is a basic question because I am new in json and ajax.
so I have a json data of name , task , date and status I am getting data through ajax but it is not showing in on my page.
my ajax code is this:
$(document).ready(function(e) {
// Using the core $.ajax() method
$.ajax({
url: "getdata.php",
type: "GET",
dataType : "json",
success: function( json ) {
$( "<h1/>" ).text( json.name ).appendTo( "body" );
$( "<div class=\"content\"/>").html( json.task ).appendTo( "body" );
},
complete: function( xhr, status ) {
alert( "The request is complete!" );
}
});
});
this is my json data:
[
{"name":"Usman ","task":"Getting work","date":"27-07-2014 12:28:45 PM","status":"1"},
{"name":"Hamza","task":"Starting work","date":"27-07-2014 12:29:36 PM","status":"1"},
{"name":"Hamza","task":"Geted","date":"27-07-2014 2:04:07 PM","status":"1"},
{"name":"Hamza","task":"Start work","date":"02-08-2014 3:56:37 PM","status":"1"}
]
I don't know why It is not appending html data but it is showing complete alert.
I have added fiddle even if it is not working.
Fiddle
Ok, i see you actually getting results so i guess you do have a success. You do have a flaw though. You are trying to access properties directly, but your json is an array of objects and not an object.
You need to do a foreach itteration.
json.forEach(function (entry) {
$( "<h1/>" ).text( entry.name ).appendTo( "body" );
$( "<div class=\"content\"/>").html( entry.task ).appendTo( "body" );
});
Edit Your Json like
{
"jsontext":[
{"name":"Usman ","task":"Getting work","date":"27-07-2014 12:28:45 PM","status":"1"},
{"name":"Hamza","task":"Starting work","date":"27-07-2014 12:29:36 PM","status":"1"},
{"name":"Hamza","task":"Geted","date":"27-07-2014 2:04:07 PM","status":"1"},
{"name":"Hamza","task":"Start work","date":"02-08-2014 3:56:37 PM","status":"1"}
]
}
and the ajax code should be as
$.ajax({
url: '/getdata.txt',
complete: function (data) {
if (data.responseText != "") {
var NewTxt = data.responseText;
NewTxt = NewTxt.replace(/\n/g, "");
NewTxt = NewTxt.replace(/\s/g, "");
obj = JSON.parse(NewTxt);
var NewStr = "";
for (var i = 0; i < obj.jsontext.length; i++) {
NewStr += obj.jsontext[i].name + "<br/>" + obj.jsontext[i].task + "<br/>" + obj.jsontext[i].date + "<br/>" + obj.jsontext[i].status + "<br/><br/>";
}
document.getElementById("demo").innerHTML = NewStr;
}
}
});
and the HTML as:
<div id="demo"></div>
I used the example from jQuery mobile site Autocomplete source code
It's working fine, but when I tried to give alert in the script inside the listviewbeforefilter event, it's showing the alert 3 times, so when 3 characters are entered, it will prompt around 7-9 times.
Why is it showing so many alerts? I thinks it should prompt only once when the character is inserted.
Here is the code retrun in script for autocomplete:
$( document ).on( "pageinit", "#myPage", function() {
alert("abc");
$( "#autocomplete" ).on( "filterablebeforefilter", function ( e, data ) {
var $ul = $( this ),
$input = $( data.input ),
value = $input.val(),
html = "";
$ul.html( "" );
alert("789");
if ( value && value.length > 2 ) {
$ul.html( "<li><div class='ui-loader'><span class='ui-icon ui-icon-loading'></span></div></li>" );
$ul.listview( "refresh" );
$.ajax({
url: "http://gd.geobytes.com/AutoCompleteCity",
dataType: "jsonp",
crossDomain: true,
data: {
q: $input.val()
}
})
.then( function ( response ) {
alert("123");
$.each( response, function ( i, val ) {
html += "<li>" + val + "</li>";
});
$ul.html( html );
$ul.listview( "refresh" );
$ul.trigger( "updatelayout");
});
}
});
});
Here is the code return in the body tag:
<div data-role="content">
<h3>Cities worldwide</h3>
<p>After you enter <strong>at least three characters</strong> the autocomplete `function will show all possible matches.</p>
<ul id="autocomplete" data-role="listview" data-inset="true" data-filter="true" `data-filter-placeholder="Find a city..." data-filter-theme="a">
</ul>
</div>