I have googled and looked at SO for a while now and can't seem to figure this out. The only requirement Im trying to meet is to return a properly formatted javascript array that contains the results of the sql statement.
I.E.
Given a query:
SELECT NUMBERS FROM TABLE
And results:
NUMBERS
1
2
3
I would like to eventually get back an array like so
["1","2","3"]
Please help me understand where I am going wrong
Here is my php code
<?php
$mysqli = new mysqli("local.host.com", "user", "pass", "db");
$sql = "SELECT DISTINCT NAME FROM table";
$result = $mysqli->query($sql);
while($row = $result->fetch_array())
{
$rows[] = $row['NAME'];
}
echo(json_encode($rows));
$result->close();
/* close connection */
$mysqli->close();
?>
Here is my javascript:
function GetCards()
{
var cardarray = new Array();
//alert('test');
$.getJSON('getcardlist.php', function(data)
{
for(var i=0;i<data.length;i++)
{
cardarray.push(data[i]);
}
//return cardarray;
});
return cardarray;
}
EDIT:
Little more information, Im trying to setup an autocomplete list for jquery ui, this is my setup for the autocomplete widget.
var list = GetCards();
$( "#name" ).autocomplete({
source: list,
minLength: 2
And this is the error Im getting from chrome console
Uncaught TypeError: Cannot read property 'label' of null
GetCards is returning an empty array -- which is what you're passing on to the Autocomplete widget -- and causing the widget to throw up the TypeError exception. To pass on the populated array, move the code that instantiates Autocomplete into your getJSON success callback (I'm not sure you even need to loop through data -- unless you need to actually transform its contents in some way):
$.getJSON( 'getcardlist.php', function( data ) {
$( "#name" ).autocomplete( {
source: data,
minLength: 2
} );
} );
Alternatively, consider using Autocomplete's shorthand for loading directly from the data feed (see passing source as a string). However, this approach may require some additional work on the server-side to filter down the list as the user types -- if you want that behavior.
you have to use $.each to get the data
$.getJSON('getcardlist.php', function(data)
{
$.each(data, function(key, val) {
cardarray.push(val);
});
//return cardarray;
});
Related
I try to learn JS together with jQuery and Ajax, and until now it was more or less painless, but now I faced myself with some obstacles about getting result from called PHP script, initiated by Ajax. What is my problem here? I have a MySQL table and I wanted to pull some data from JS by Ajax call. I tested my query to check is it correct and make result and with same query I built PHP script. Here is my JS file:
...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
</head>
<body>
<script>
callphp(12,14);
//
function callphp(par1, par2) {
$.ajax({
type: "POST",
url: "_ajax2php2.php",
cache: false,
dataType: "json",
data: { "po1": par1, "po2":par2 },
success: function(data, status, jqXHR){
jss=JSON.stringify(data);
alert(jss);
//
var strBuilder = [];
for(key in data){
if (data.hasOwnProperty(key)) {
strBuilder.push("Key is " + key + ", value is " +data[key] + "\n"); }
}
alert(strBuilder.join(""));
},
error: function(data) {
alert( "params error" );
}
});
// end of JS
and here is my PHP script:
<?php
$eol="<br/>";
$uuu= isset($_POST['po1']) ? $_POST['po1'] : '';
$zzz= isset($_POST['po2']) ? $_POST['po2'] : '';
$con=mysqli_connect("localhost","root","some_password","mydbase");
// Check connection
if (mysqli_connect_errno())
{
echo "Fail to MySQL: " . mysqli_connect_error();
}
mysqli_select_db($con,"mydbase");
$query4 = "SELECT * from mytable WHERE uc_id='$uuu' AND pr_id='$zzz' ";
$result4 = mysqli_query($con, $query4);
$row4= mysqli_fetch_assoc($result4);
if(mysqli_num_rows($result4) > 1) {
while($row4[]=mysqli_fetch_assoc($result4)) {
$data = $row4; }
}
else
{$data=$row4;}
echo json_encode($data, JSON_UNESCAPED_UNICODE);
/* free result set */
mysqli_free_result($result4);
mysqli_close($con);
//end of php
?>
and it seems that it works good when PHP query return just one record, if there are 2 or more then I'm unable to "dismantle" JSON object by this JS code, because for example if my query return 3 records, in alert it appears like
Key is 0, value is [object Object]
Key is 1, value is [object Object]
Key is name_of_field1, value is 1
Key is name_of_field2, value is 12
Key is name_of_field3, value is 2
Key is name_of_field4, value is 1
Key is name_of_field5, value is 14
Key is name_of_field6, value is 2015-09-10
and I need to be able to get each particular record fields of each record in order to fill with it some HTML table. How to write this part of code that resolve JSON response consist of two or more records made by PHP? I tried examples I found here but no one met my needs. Thanks.
In your while loop after the DB query, you are just overwriting the value for $data with every iteration. I would suggest not having different logic for cases with one row in result set vs. more than one row, as this does nothing but add complexity to your code. Just return an array every time and you will be better off. Your code around the query might look like this:
$data = array();
$result4 = mysqli_query($con, $query4);
if($result4) {
while($row = mysqli_fetch_assoc($result4) {
$data[] = $row;
}
}
echo json_encode($data, JSON_UNESCAPED_UNICODE);
This simplifies this section of code and will also simplify the client-side code since now you can write it to simply expect to work with an array of objects in all cases.
This means that in javascript your code might look like (ajax success handler code shown):
success: function(data, status, jqXHR){
// data is an array, with each array entry holding
// an object representing one record from DB result set
var recordCount = data.length;
console.log(recordCount+' records returned in response.');
// you can iterate through each row like this
for(i=0;i<recordCount;i++) {
// do something with each record
var record = data[i];
// in this example, I am just logging each to console
console.log(record);
// accessing individual properties could be done like
console.log(record.name_of_field1);
console.log(record.name_of_field2);
// and so on...
}
}
You should get in the habit of using console.log() rather than alert() or similar for debugging your javascript, as alert() actually interrupts your javascript code execution and could introduce problems in debugging more complex javascript (particularly when there are asynchronous activities going on). Using the javascript console functionalty built into your browser should be fundamental practice for any javascript developer.
I have search results generated by a 3rd party script that I would like to add data to. I have parsed the results to get an array of id's, and queried the database for additional fields. The ajax success method receives the formatted array back, but now I'm stuck on how to get those results into the right place in the DOM.
The HTML:
<div class="ihf-results-property-info">
<div class="ihf-results-price">LIST: $2,150,000</div>
<div class="ihf-results-links"> 24 Photos
</div>
<div class="ihf-results-extra-info">
<div class="ihf-results-listingnum hidden-xs">Listing # 727938</div>
</div>
Repeat...
The last div I included in the example has the unique ID I'm using for the query. I'd like to use that to associate the ajax return with proper placement in the DOM. Here is my javascript:
jQuery(document).ready(function($) {
// grab the listings numbers so we can query the db for extra data
var listings = $('.ihf-results-listingnum').map(function() {
// grab just the digits
var listingNum = $(this).text().replace(/[^0-9]/g, '');
// add the listing number to the parent so we can target it later
$( this ).parents('.ihf-results-extra-info').parent().addClass('marketing-details-' + listingNum);
return listingNum;
// use .get to create an array of the listing numbers
}).get();
$.ajax({
type: "GET",
url: "custom/07-idx-queries.php",
data: 'mlsNums=' + listings, // looks like ?mlsNums=735383,727468,699876...
success: function(result) {
// this logic came from here: http://stackoverflow.com/questions/15311320/how-to-work-with-jquery-ajax-and-php-array-return
resultJson = $.parseJSON(result);
if (typeof resultJson == 'object') {
jsObject = eval(resultJson);
jsArray = [];
for(elem in jsObject){
jsArray.push(jsObject[elem]);
}
console.log(jsArray);
// this works as expected, except keys are 0 based
// This is where it all falls apart. I want to extract each object and stick it in the DOM in the correct place
jQuery.each(jsArray, function(key, value) {
$( this ).appendTo('.marketing-details-' + key);
});
}
else {
console.log("error occurred");
}
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
})
});
And the php I'm using produces the desired results from the db, with the exception that it is a numerical array. I think an associative array would work better when trying to put the results into the DOM, tha way I could use the ID's as the key and match them to the classes I added. Here is the relevant code from custom/07-idx-queries.php:
$mls_nums = explode(",",$_GET['mlsNums']);
// removed all of the conditionals to keep the question clean
$html = array();
foreach ($mls_nums as $mls_num) {
// just retreiving a single object from each row for now
$remarks = $mysqli->query("SELECT mr FROM listings WHERE ln = '$mls_num'")->fetch_object()->mr;
// format the data
$my_html = "<p class='marketing-remarks mlsnum-".$mls_num."'>$remarks</p>";
// build an array of the results - necessary?
array_push($html,$my_html);
}
// send the data back in a JSON string
echo json_encode($html);
So my goal is to query the db for up to 10 rows, and insert the results into an equal number of new divs that are children to a div with the same id number in its class. I greatly appreciate any help.
In your PHP do this:
$html[$mls_num] = $my_html;
// this isn't needed
// array_push($html,$my_html);
Now your returned data has a way to tie into the target div.
Not clear if you have control over the HTML in the first part of your example, but this would be one approach.
<div class="ihf-results-listingnum hidden-xs">Listing # 727938</div>
<div class="remarks" id="remarks_<?= $listingid; ?>"></div>
Then in the JavaScript $("#remarks_" + key).html(value);
Otherwise, you need to use jQuery to locate the div with the listing id using the :contains selector:
$("div:contains('# " + key + "')").appendTo(value);
'# " + key + "' would equate to # 1234 or whatever it is. This won't work if the same listing is on the page twice though!
Okay, here is the working success method. Thanks to LG_PDX for the cleaned up php. I eliminated the unnecessary processing as .each() appears to iterate just fine over the JSON response:
success: function(result) {
resultJson = $.parseJSON(result);
if (typeof resultJson == 'object') {
$.each(resultJson, function(key, value) {
$('.marketing-details-' + key).append( value );
});
}
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
I am trying to make an html select list of options update according to a selection made on a prior html select object. My jquery is below. This is being called correctly.
var brandName = $("#Brand").val();
$.get("updateTypes.php?q="+brandName, function(data) {
$("#Type").remove();
var typeData = JSON.parse(data);
for (loop=0; loop < typeData.length; ++loop) {
$("#Type").options.add(new Option(typeData[loop]));
}
});
As I am using a singleton to interface with my mySQL database, this jquery function calls a 'go-between' .php file called updateTypes.php which is below:
include 'databaseInterface.php';
$brand = $_GET["q"];
$typesData = databaseInterface::getBrandTypes($brand);
return $typesData;
This calls the getBrandTypes function in my singleton below:
$query = "SELECT psTypeName FROM types WHERE brands_psBrandName='$BrandName'";
$result = mysqli_query($con, $query) or die ("Couldn't execute query. ".mysqli_error($con));
$resultArray = array();
while ($row = mysqli_fetch_assoc($result)) {
extract($row);
$resultArray[] = $psTypeName;
}
return json_encode($resultArray);
The webpage correctly removes the existing options from the jquery function but fails to update them. It seems to go wrong when I decode the JSON data in the jquery. Why is it going wrong? Is the loop for updating the select object appropriate?
You can use $.getJSON if your expecting a json response. You might also be able to use $.each() and then simply .append() to the select tag. You can reference this.property inside the .each().
Something like the following:
$.getJSON("updateTypes.php?q="+brandName, function(data) {
$("#Type").html('');
$.each(data, function(){
$("#Type").append('<option value="'+ this.value +'">'+ this.name +'</option>')
)
})
This would assume your json response is something like the following:
[ { name : "foo", value : "bar" }, { name : "another", value : "example" } ]
Your code $("#Type").remove(); removes the select object not its options. The correct way of removing options is:
$("#Type option").remove();
or
$("#Type").html('');
The second solution seems to be better as stated here: How to remove options from select element without memory leak?
There is also an error in the part that adds new options. Your javascript code should be:
var brandName = $("#Brand").val();
$.get("updateTypes.php?q="+brandName, function(data) {
$("#Type option").remove();
var typeData = JSON.parse(data);
for (loop=0; loop < typeData.length; loop++) {
$("#Type").get(0).options.add(new Option(typeData[loop]));
}
});
The $('#Type').get(0) method refers to the raw DOM object which has the "options" property that you wanted to use (How to get a DOM Element from a JQuery Selector)
I'm building a search function to retrieve XML data for a google map.
In addition to that, I want to display how many results were actually found.
I thought about doing an echo inside the actual document, however that might mess with my marker data. How would I take a PHP variable and retrieve it in Jquery after a success call?
If my PHP looked like this:
$result = mysql_query($query);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
$num_rows = mysql_num_rows($result);
And Jquery like this:
$.ajax({
type: "POST",
url: "MapSearchxml.php",
data: {
dataFromDate: FromDate,
//lalala
dataHasPatio: HasPatio
},
beforeSend: function (html) { // this happens before actual call
$("#results").html('Please Wait');
$("#searchresults").show();
$(".phpFromDate").html(FromDate);
},
success: function (data, status, jqXHR) {
//Success?
},
dataType: 'xml'
});
Might find it easier to create array in php and send JSON. At client is easy to loop over response object/array
$output=array('status'=>'', 'results'=>array());
$result = mysql_query($query);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
$num_rows = mysql_num_rows($result);
if( $num_rows){
$output['status']='ok';
/* push row data to $output['results'][]; in while loop*/
}else{
$output['status']= 'No results';
}
echo json_encode( $output);
Then in jQuery:
success:function( data){
if (data.status != 'No results' ){
/* count array length*/
var count= data.results.length;
/* loop over data.results array*/
}
}
/* change dataType to "json"*/
I forgot about count and added it in jQuery...can also add a count property to the $output php array and use $num_rows to populate
Just trying out a JSON example for you, this has echo but you can do complex things with it?
Not sure if that is what your after? I get that you don't want to do echo on each variable, and you wont if using JSON.
<?php
$simple = 'simple string';
$complex = array('more', 'complex', 'object', array('foo', 'bar'));
?>
<script type="text/javascript">
var simple = '<?php echo $simple; ?>';
var complex = <?php echo json_encode($complex); ?>;
</script>
You see, what AJAX gets on success is an html code. If you AJAX a complete html page you will get it back, starting with <html> and ending with </html>. You can just make a special markap on your return html data, like [sepcial_info : 'INFO'] or somthing and then just to filter it.
Okay, I needed a bit to decipher your question, probably I'm still wrong, let's try:
What you try to do is not technically possible with what you have in mind. In short: If you do one Ajax request, you return one response. The moment the success function is called, your PHP script is already gone. So you can only pass one return value.
However what you can do is, that you make that return value a nested one, e.g. containing two parts:
The XML document you already returned
The count
That is probably your solution. If you ask how, I would add the count as a namespaced value to the XML and then process it with javascript.
As you have not shown any code here, I can not give a quick example (and I leave that as a pointer for your future questions) for your case. Add a namespace element, like an attribute is pretty simple with DOMDocument in PHP.
I'm trying to get the jquery ui autocomplete to work with a codeigniter project.
so far I have an input field <input type="text" id="text1"/>
and then in my script I have
source: function(request, response) {
$.post('autocompleteHandler', {mechanic: request.term}, function(data) {
console.log('data.phpResp = '+data.phpResp);
console.log('in post?');
console.log('data = '+data.toSource);
var realArray = $.makeArray(data); // this line was needed to use the $.map function
response($.map(realArray, function(item) {
console.log('in map');
return {
label: item.info,
value: item.info
}
}));
}, 'json');
},
In my codeigniter controller I have this function
function autocompleteHandler() {
$input = $this->input->post('mechanic');
$this->load->model('login_model');
$results = $this->login_model->search_mechanic_criteria($input);
$mechs= array();
foreach($results as $result) {
$mechs['info'] = $result['mechanic_name'];
}
}
I'm not getting this to work. anyone have any ideas of where I can begin to troubleshoot? I really have a hard time with the jquery ui documentation.
EDIT: I've changed my code a bit. Instead of returning json_encode, I needed to echo json_encode on the php side of things. I still don't have anything showing up in my console though.
2ND EDIT Now my question is, how can I return multiple values for the autocomplete function? If i have a query that returns, just one row, it works fine, but if I have multiple rows returned, doesn't work. It's gotta be something with the way i'm returning the data, but I can't figure it out.
I have been playing around with jsfiddle after you mentioned toSource(). See http://jsfiddle.net/XYMGT/. I find that the map function does not return jQuery, but the new array.
OLD STUFF:
I suspect that the $.map function does not return the array, but jQuery. Maybe it would to do this:
// also you could inspect the data if the server returns what you think it returns:
console.log(data);
// first map the array
$.map(data, function(item) {
console.log('in response?');
return {
label: 'testing',
value: 'test'
}
})
// ...then separately do the response part
response(data);
Lets us know if it makes a difference.
EDIT:
If this PHP code is still used:
function autocompleteHandler() {
echo json_encode(array('phpResp' => 'something'));
}
Then console.log(data) should show the following in the console tab in FireBug:
{'phpResp':'somehting'}
Meaning that console.log(data.phpResp) should print 'something'. I am unsure where you are getting data.toSource from.
I would launch fiddler and see what it says it's returning. You can also go straight to your server side page in the browser that is serving the JSON results. I think the autocomplete automatically adds ?term to the string. url.aspx?term=|valueofText1|
$("#text1").autocomplete({
source: url,
minLength: 2,
select: function (event, ui) {
sou = ui.item.label;
}
});