JQuery auto complete with links - javascript

I'm in the process of establishing a website which uses JQuery's auto complete to give users suggestions on pages. I store the page ID and title in a SQL database (connecting using PDO). At the moment, I've got the auto complete feature working, however, I am absolutely stumped on how to get the auto complete list to turn into clickable links which direct the user to the relevant page based off the page ID in the database.
Here's my search.php file
<?php
require('includes/connect.class.php');
if (isset($_GET['term'])) {
$return_arr = array();
try {
$stmt = $conn->prepare('SELECT id, locationName FROM locations WHERE locationsName LIKE :term');
$stmt->execute(array(
'term' => '%' . $_GET['term'] . '%'
));
while ($row = $stmt->fetch()) {
$return_arr[] = $row['locationName'];
}
}
catch (PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
echo json_encode($return_arr);
}
?>
and my JavaScript
$(function() {
$(".locationlist").autocomplete({
source: "search.php",
minLength: 1
});
});
The database looks like this
Locations
|---ID---||---locationName---|
| 1 || Test1 |
| 2 || Test2 |
----------------------------
I've done some research, and I believe I need to modify JQuery to display an array of objects. I'm not too sure how to do this.
What would be the best way to have my auto complete list get the page ID from the SQL database and become clickable links?

You don't actually need for clickable links there. You can redirect the page within the autocomplete's select event , where you have access to the selected item object:
ui (Type: Object):
item (Type: Object):
An Object with label and value properties for the selected option.
ui.item.value will be the page ID generated with your PHP
$(".locationlist").autocomplete({
source : "search.php",
minLength: 1,
select : function(event, ui){
// You may need to change this part, as I don't know the exact values:
location.href = "http://your-site.com/" + ui.item.value;
}
});
As for your PHP, you can modify the output array like so:
while ($row = $stmt->fetch()) {
$return_arr[] = array(
'value' => $row['ID'],
'label' => $row['locationName']
);
}

Related

Typeahead.js -- refresh data

I have managed to get this code to work for an application -- http://twitter.github.io/typeahead.js/ but, the problem I have run into, is that I need to be able to re-load the data. I would rather not duplicate the code to do this, although it's an option, it seems kind of silly. I have inserted some PHP into my JavaScript to create an array for the dropdown list, and it works great. But if I stuff it into a function, and then try to call the function in the document open, it doesn't work (nothing appears to happen).
$(document).ready(function()
{
// call function when page loads(?)
getAwards();
}); // end document.ready ...
This is the PHP code, if I comment out the JavaScript function parts it runs and the typeahead code sees the value of the array. If I put it into the function, it doesn't execute despite being called above, and I have no data for the typeahead code ...
function getAwards(
{
// build array for use with typeahead:
<?php
$sql_statement = "select title from awards order by title desc limit 1";
$aw_result = mysqli_query( $connect, $sql_statement );
$aw_row = mysqli_fetch_array( $aw_result );
$last_award = $aw_row["title"];
// need to rewind table:
mysqli_data_seek( $aw_result, 0);
// start from the top:
$sql_statement = "select title from awards order by title";
$aw_result = mysqli_query( $connect, $sql_statement );
$count = 0;
$out = 'awards = [';
while ( $aw_row = mysqli_fetch_array( $aw_result ) )
{
// the quotes deal with forcing this to handle
// branch names with apostrophes in them ...
$count++;
$out .= '"'. $aw_row["title"] . '"';
if( $aw_row["title"] != $last_award )
{
$out .= ',';
}
}
$out .= ']';
echo $out . "\n";
?>
})
I need to be able to update the data, and reload the list while working on the form (I am working that out in my fuzzy brain, but anyway I'll get to that -- currently intend to click a button to update the list used by the typeahead, which is why I want a function ...)
Any suggestions are gratefully accepted. I am at a loss ...

wp_enqueue_script not working on AJAX called php file

I've got a complicated little problem here.
I'm building a WordPress plugin where I select a "parent" post (of a custom type that I made called 'step') and then an AJAX function shows a new select bar with all of the children of that parent. I do this by outputting the new and elements in the PHP file that's called in the AJAX function. This works, but now I want to repeat the process to run a function from the same JQuery file when this new outputted element is added to the page. (See Javascript code)
Main php plugin file (in a folder within the plugin directory):
<?php
/*
Plugin Name: n8jadams Step by Step Plugin (WIP)
Plugin URI:
Description:
Author: Nathan James Adams
Author URI: http://nathanjamesadams.com
Version: 0.0.1a
*/
//Exit if accessed directly
if(!defined('ABSPATH')) {
exit;
}
//My custom post type, it works fine
require_once(plugin_dir_path(__FILE__).'n8jadams-step-funnel-cpt.php');
require_once(plugin_dir_path(__FILE__).'n8jadams-ajax.php');
//Add my javascript
function n8jadams_init_javascript() {
wp_register_script('n8jadams_javascript', plugin_dir_url(__FILE__).'n8jadams-scripts.js', array('jquery'),'1.1', false);
wp_enqueue_script('n8jadams_javascript');
}
add_action('wp_enqueue_scripts', 'n8jadams_init_javascript');
//Adds a plugin menu to the wordpress sidebar
function n8jadams_add_plugin_menu() {
add_menu_page('', 'Steps Settings', 4, 'steps-settings', 'n8jadams_steps_settings', '');
}
add_action('admin_menu', 'n8jadams_add_plugin_menu');
//The actual function for the menu page
function n8jadams_steps_settings() {
//Access the database and the tables we want
global $wpdb;
$posts = $wpdb->prefix.'posts';
//Get the user id
$user = wp_get_current_user();
$userid = $user->ID;
//Initialize javascript (it works here!)
n8jadams_init_javascript();
/* Get all the parents */
$parentsquery = "
SELECT `ID`, `post_title`
FROM $posts
WHERE `post_author` = $userid
AND `post_parent` = 0
AND `post_status` = 'publish'
AND `post_type` = 'step'
";
$parentsarray = $wpdb->get_results($parentsquery);
?>
<h4>My Forms:</h4>
<select id="parentselect">
<option id="-1"> - Select Your Step Form - </option>
<?php
//output the parents
for($i=0;$i<sizeof($parentsarray);$i++) {
echo '<option id="'.$parentsarray[$i]->ID.'">'.$parentsarray[$i]->post_title.'</option>';
}
?>
</select>
<div id="displayChildren"></div>
<?php
}
?>
Javascript (n8jadams-scripts.js):
(function($){
$('#parentselect').change(function(s) {
var thisID = s.target[s.target.selectedIndex].id;
var outputDisplay = document.getElementById('displayChildren');
if(thisID != '-1') {
$.ajax({
type: 'POST',
url: 'admin-ajax.php',
data: {
action: 'n8jadams_get_children',
id: thisID
},
success: function(response){
if(response == "") {
outputDisplay.textContent = "This form has no children. Add them in the sidebar menu of this step form.";
} else {
outputDisplay.innerHTML = response;
}
},
error: function(errorThrown) {
alert(errorThrown);
}
});
} else {
outputDisplay.textContent = '';
}
});
// I want this function to work
/*
$('#childselect').change(function(t) {
console.log("test");
});
*/
})(jQuery);
PHP file called by AJAX (n8jadams-ajax.php):
<?php
function n8jadams_get_children() {
//Get the id of the parent
$parent_post_id = $_POST['id'];
//Sanitize the input (Added after question was answered)
$parent_post_id = preg_replace("/[^0-9]/","",$parent_post_id);
//Access database
global $wpdb;
$posts = $wpdb->prefix.'posts';
$user = wp_get_current_user();
$userid = $user->ID;
$childrenquery = "
SELECT `ID`, `post_title`,`post_content`
FROM $posts
WHERE `post_parent` = $parent_post_id
AND `post_status` = 'publish'
AND `post_type` = 'step'
AND `post_author` = $userid
";
//Retrieve the children associated with this parent
$childrenarray = $wpdb->get_results($childrenquery);
//Initialize Javascript (it doesn't work here!)
n8jadams_init_javascript();
if(!empty($childrenarray)) { ?>
<h4>My Steps:</h4>
<select id="childselect">
<option id="-1"> - Select Your Step - </option>
<?php
//output the children of the parent
for($i=0;$i<sizeof($childrenarray);$i++) {
echo '<option id="'.$childrenarray[$i]->ID.'">'.$childrenarray[$i]->post_title.'</option>';
} ?>
</select>
<?php wp_die();
}
}
add_action('wp_ajax_n8jadams_get_children', 'n8jadams_get_children');
add_action('wp_ajax_nopriv_n8jadams_get_children', 'n8jadams_get_children');
?>
Screenshot of Plugin Menu
I cannot figure out why my javascript file isn't working in the PHP file that's called by AJAX. Maybe the vast wisdom of the StackOverflow can help me. Thanks for the help in advance. :)
You are hooking into wp_enqueue_scripts, which is only run for the frontend of Wordpress (the part the average visitor sees). If you want to load a script into wp-admin, the backend of Wordpress, use the admin_enqueue_scripts action.
Since this code does not work in /wp-admin/, you don't need to use admin_enqueue_scripts. I guess the whole problem would be that you are attaching a handler to $('#childselect'), while no such element exists on the page at that time. Use deferring with $(..).on(..):
$(document).on('change', '#childselect', function(e) {
//Black magic
});
Side note: As already mentioned in the comments, the following part contains an unsanitised variable which will allow an attacker to perform sql injections.
$childrenquery = "
SELECT `ID`, `post_title`,`post_content`
FROM $posts
WHERE `post_parent` = $parent_post_id
AND `post_status` = 'publish'
AND `post_type` = 'step'
AND `post_author` = $userid
";
Use WP_Query if at all possible. If this is only used from the backend of Wordpress, don't use wp_ajax_nopriv_*, because users that are not logged in into your site have no right to use that anyway.

bring data from a JSON and show in a popup

I have a leaderboard where if you click on a name a popup is displayed : https://jsfiddle.net/pvwvdgLn/1/
In practice, I will pull the list of the leaderboard from a DB.What you see here in the list are static names of employees,just for reference. So,how do I assign names using data attributes and search for that name in the JSON?
There are various fields in the popup like: Name,Email,Date of birth etc which I want to display for the respective person whose name is clicked by the user.
I have below JSON which is fetching me the array which contains all these data of all the people in the list :
<?php
session_start();
$servername = "xxxxx";
$connectioninfo = array(
'Database' => 'xxxxxxxxxxxxx'
);
$conn = sqlsrv_connect($servername, $connectioninfo);
if (!$conn) {
echo 'connection failure';
die(print_r(sqlsrv_errors() , TRUE));
}
$q1 = "select top 10 *
from pointsBadgeTable
WHERE WeekNumber ='week51'
order by pointsRewarded desc";
$stmt = sqlsrv_query($conn, $q1);
if ($stmt == false) {
echo 'error to retrieve info !! <br/>';
die(print_r(sqlsrv_errors() , TRUE));
}
do {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
while (sqlsrv_next_result($stmt));
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn); //Close the connnectiokn first
//Set content type to json
header('Content-Type: application/json');
//Echo a json object to the browser
echo json_encode($result);
?>
As can be seen in the query,it fetches JSON for all the top10 ,whose names can be seen in the list.
the html and JS related to the popup is here : https://jsfiddle.net/woef5mn6/
How can I display the respective data in the popup from the JSON only for the person whose name is clicked ?
please help me.
I have edited your fiddle to show how your problem can be solved. This is just a simple solution. It needs to modified according to your requirement.
Here is the fiddle
I am creating the employee list from your JSON and populating the ordered list
function employeeList() {
$("#myOL").empty();
$.each(employee, function(i,o) {
$("#myOL").append("<li><mark>" + o.EmployeeName + "</mark><small>" + o.score + "</small></li>");
});
}
Then onclick of the individual employee, i am getting his details from JSON by his name and then populating the popup details (as a best practice here - you should get the employee details by calling a service through ajax using a unique identifier [employeeId] ):
function getEmployeeByName(name) {
var index = -1;
var filteredObj = employee.find(function(item, i) {
if(item.EmployeeName === name){
index = i;
}
});
return employee[index];
}
Hope this helps!

AJAX: How would I bind autocomplete feature on KeyUp to be able to use Keyboard key

How would I bind or use the so called "autocomplete" feature on to the code below in order to use the autocomplete features keyboard up, down and enter functionality, because currently my code doesn't have that. It is on wordpress template and it is just being controlled by mouse for right now.
<script>
$(document).ready(function(){
$("#search-box").keyup(function(){
$.ajax({
type: "POST",
url: "autocomplete.php",
data:'keyword='+$(this).val(),
success: function(data){
$("#suggesstion-box ").show();
$("#suggesstion-box").html(data);
}
});
});
});
function selectCountry(val) {
$("#search-id").val(val);
$("#suggesstion-box").hide();
}
function updateSearchBox(el) {
$("#search-box").val($(el).html());
}
</script>
I have tried using
$("#search-box").keyup.autocomplete(function() {
or
$("#search-box").autocomplete(function() {
or even
$("#search-box").autocomplete.keyup(function() {
But it doesn't pull the list. I know there is something wrong with my AJAX causing me to have this issue of keyboard is not working correctly. Any Suggestions?
Ok... I have changed my php to give out a json.
Autocomplete.php
<?php
include_once "functions.php";
if(isset($_POST['keyword']))
{
$database = lookup_connectToDatabase();
$result = pg_query($database, "SELECT country, id, state FROM customers WHERE country iLIKE '" . $_POST["keyword"] . "%' OR id iLIKE '" . $_POST["keyword"] . "%' ORDER BY country");
if (!$result){
echo "<div class='show' align='left'>No matching records.</div>";
}else {
while($row=pg_fetch_assoc($result)){
$array[] = array(
'label' = $row['id'].': '.$row['country'].', '.$row['state'],
'value' = $row['id'],
);
}
echo json_encode ($array);
}
}
?>
But still doesn't seem to work right. What am I missing with this json?
I suspect you're looking for: http://jqueryui.com/autocomplete/#remote
In your script, this might look like:
$(document).ready(function(){
$("#search-box").autocomplete({
minLength: 0,
source: "autocomplete.php",
select: function(e, ui){
$("#search-box").val(ui.item.label);
$("#search-id").val(ui.item.value);
return false;
}
});
});
See More: http://api.jqueryui.com/autocomplete/#option-source
String: When a string is used, the Autocomplete plugin expects that string to point to a URL resource that will return JSON data. It can be on the same host or on a different one (must provide JSONP). The Autocomplete plugin does not filter the results, instead a query string is added with a term field, which the server-side script should use for filtering the results. For example, if the source option is set to "http://example.com" and the user types foo, a GET request would be made to http://example.com?term=foo. The data itself can be in the same format as the local data described above.
If you must use POST, this can be done, but it's a bit more complex.
Function: The third variation, a callback, provides the most flexibility and can be used to connect any data source to Autocomplete.
This might look like:
$(document).ready(function(){
$("#search-box").autocomplete({
minLength: 0,
source: function(req, resp){
$.ajax({
type: "POST",
url: "autocomplete.php",
data:'keyword=' + req.term,
success: function(d){
resp(d);
}
});
},
select: function(e, ui){
$("#search-box").val(ui.item.label);
$("#search-id").val(ui.item.value);
return false;
}
});
});
These examples are untested since you did not provide example data.
Update
Based on your autocomplete.php file, I would suggest the following:
<?php
include_once "functions.php";
if(isset($_POST['keyword'])){
$database = lookup_connectToDatabase();
$result = pg_query($database, "SELECT country, id, state FROM customers WHERE country iLIKE '" . $_POST["keyword"] . "%' OR id iLIKE '" . $_POST["keyword"] . "%' ORDER BY country");
$data = array();
if ($result){
while($row=pg_fetch_assoc($result)){
$data[] = array(
"label" => $row['country'].', '.$row['state'],
"value" => $row['id'],
);
}
}
header('Content-Type: application/json');
echo json_encode ($array);
}
?>
This should return an Array of objects with label and value properties.
The label property is displayed in the suggestion menu. The value will be inserted into the input element when a user selects an item. If just one property is specified, it will be used for both, e.g., if you provide only value properties, the value will also be used as the label.
If there are no matches, we'll just get an empty array in return. So let's say we get the following response:
[
{
"label": "United States, California",
"value": 420
},
{
"label": "United States, New York",
"value": 100
}
]
When one of these is selected, the select callback is executed and #search-box will receive the ui.item.label; #search-id will receive the ui.item.value.

Autocomplete form once the name is enter PHP

I found a couple of similar questions but nothing with the same "variables" so here we go:
I have a simple form where I enter a name and I need the rest of the form to be completed automatically (ID).
Fetching the data in the DB is not an issue, I'm able to return Json using PHP (Search.php):
//get search term
$searchTerm = $_GET['term'];
//get matched data from table
$query = $db->query("SELECT * FROM info_employer WHERE Prenom LIKE '%".$searchTerm."%' ORDER BY Prenom ASC");
while ($row = $query->fetch_assoc()) {
$data[] = array( Nom => $row['Prenom'] . ' ' . $row['Nom'], Num => $row['Num'] );
}
//return json data
echo json_encode($data);
This give me an array that look like this:
[{"Nom":"Andre Nadeau","Num":"104J"},{"Nom":"Andre Potvin","Num":"130J"},{"Nom":"Andre Thibodeau","Num":"91J"}]
Friends told me that I should use Jquery and Ajax to use this array to fill my form but I have 2 issue.
First If I return an Array instead of "just the name" my autocomplete form don't work anymore. It give me X numbers of blank space (depending the number of results).
And of course my biggest problem is that i'm not able to send the ID (Num) in the form
Javascript i'm using to autocomplete the name :
<script>
$(function() {
$( "#Nom" ).autocomplete({
source: 'Search.php',
})
})
</script>
You need to change the return object to make it match the spec here
$data[] = array( "label" => $row['Prenom'] . ' ' . $row['Nom'], "value" => $row['Num'] );
This should result in an array of objects with a 'label' and 'value' key. This will work with your autocomplete.

Categories

Resources