Hello I am using autocomplete to allow users to search venues stored in a MySQL database. The autocomplete plugin is currently listing the venues when the user begins typing and prints the selected venue using the result handler.
I would like to also print the address, phone number and website of the venue as well but I am not sure how to do this.
I have the autocomplete plugin running a php script to print out the venue names from the database. I am not sure how to retrieve the other fields in the database without displaying the autocomplete input field...
This is what I have so far:
JQuery
$(document).ready(function(){
$("#example").autocomplete("search.php", {width: 260, selectFirst: false}).result(function(event, data, formatted) {
$("#result").html( !data ? "No match!" : "Selected: " + formatted);
});
});
PHP
$search = $_GET['q'];
$search = "%".$search."%";
$result = mysql_query("SELECT club_name FROM clubs WHERE club_name LIKE '$search'") or die('Something is wrong');
while($value = mysql_fetch_array($result)){
$club = $value[club_name];
echo "$club\n";
}
The php above only select the club name because when I try to select more fields they display in the search results on the JQuery side.
I am new to JQuery so I am a little lost... Any suggestions?
There are a few ways to do it, but this is the easiest:
You want to return the data from the server like this. The first column should contain the value you want to retrieve in the end:
title|address|phone|web
title|address|phone|web
title|address|phone|web
And then you want to use the formatItem and formatValue callback in your autocomplete function:
$(document).ready(function(){
$("#example").autocomplete("search.php", {
width: 260,
selectFirst: false,
formatItem: function(row){
var ret = '<span class="title">' + row[0] + '</span><br />';
ret += '<span class="address">' + row[1] + '</span> ';
ret += '<span class="phone">' + row[2] + '</span> ';
ret += '<span class="web">' + row[3] + '</span> ';
return ret;
},
formatValue: function(row){
return row[0]; // We only want the first value to be searched
}
}).result(function(event, data, formatted) {
$("#result").html( !data ? "No match!" : "Selected: " + formatted);
});
});
Also, your are not escaping the input from the user and as such have a nasty vunerability for SQL injection
Related
I have a request to get data in my mySQL database (36,848 entries).
Then I format and append them with jQuery on my web page.
These two operations take 2 minutes and 30 seconds.
During this time, no other operation is possible on the page.
Is there a way to optimize this to speed up the process?
Like this, it's unusable.
My PHP function
<?php
function get_my_customers() {
$req = $bdd->prepare("SELECT * FROM clients ORDER BY raison_sociale");
$req->execute();
$customers = $req->fetchAll(PDO::FETCH_ASSOC);
return $customers;
}
if(isset($_POST['ajax'])){
$result = get_my_customers();
echo json_encode($result);
}
?>
Data retrieval in jQuery (Ajax)
function get_my_customers(){
var customers;
$.ajax({
url: "model/application/*******/customers/get_my_customers.php",
async: false,
type: "POST",
dataType: 'json',
data: {ajax: 'true'},
success: function(data)
{
customers = data;
}
});
return customers;
}
var my_customers = get_my_customers();
$('#customers_list').append('<div class="list_card" card="customers_list"></div>');
$.each(my_customers, function(key, val){
if(val.enseigne == null){
var enseigne = '';
}else{
var enseigne = ',' + val.enseigne;
}
$('.list_card[card="customers_list"]').append(''+
'<div class="list_card_element">'+
'<div><b>'+ val.numero_client +'</b></div>'+
'<div>'+
'<b>'+ val.raison_sociale +'</b>' + enseigne +
'<br>'+
val.cp_livraison + ', ' + val.adresse_livraison +
'</div>'+
'</div>'
);
});
Do you know what I can do to speed up processing time?
I've tried limiting the SELECT query to only the fields I need but that doesn't improve processing time.
I wonder if it's not rather the jQuery layout that takes time rather than the SQL query.
Thank you !
Use devtools in your browser to determine which step is causing the slowdown. The Network tab will show you the Ajax request and the time interval of the data fetch. If that time interval is not the issue, it's likely with the Javascript. You can get deeper on the Javascript performance using the Performance tab.
try to use indexes see that
MySQL can use an index on the columns in the ORDER BY (under certain conditions). However, MySQL cannot use an index for mixed ASC,DESC order by (SELECT * FROM foo ORDER BY bar ASC, pants DESC). Sharing your query and CREATE TABLE statement would help us answer your question more specifically.
I just passed from 2 minutes and 30 secondes to 14 secondes with this optimization.
var construct_customers = "";
$.each(my_customers, function(key, val){
if(val.enseigne == null){
var enseigne = '';
}else{
var enseigne = ',' + val.enseigne;
}
construct_customers += '<div class="list_card_element">'+'<div><b>'+ val.numero_client +'</b></div>'+'<div>'+'<b>'+ val.raison_sociale +'</b>' + enseigne +'<br>'+val.cp_livraison + ', ' + val.adresse_livraison +'</div>'+'</div>';
//OLD CODE
// $('.list_card[card="customers_list"]').append(''+
// '<div class="list_card_element">'+
// '<div><b>'+ val.numero_client +'</b></div>'+
// '<div>'+
// '<b>'+ val.raison_sociale +'</b>' + enseigne +
// '<br>'+
// val.cp_livraison + ', ' + val.adresse_livraison +
// '</div>'+
// '</div>'
// );
});
$('.list_card[card="customers_list"]').append(construct_customers);
I'm impressed
i am not able to export multiple time searched and selected data to CSV.
i am fetching data from database which has more than 1000 records.
so for example, if i select 2 rows on page one then i search for some other record and select that record and export but it is only exports searched record not the records from the page one.
$('#master tfoot th').each(function() {
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
});
// DataTable
var master = $('#master').DataTable({
dom: 'Blfrtip',
buttons: [
'copy',
'csv',
'excel',
'pdf',
{
extend: 'print',
text: 'Print all (not just selected)',
exportOptions: {
modifier: {
selected: null
}
}
}
],
select: true
});
// Apply the search
master.columns().every(function() {
var that = this;
$('input', this.footer()).on('keyup change', function() {
if (that.search() !== this.value) {
that
.search(this.value)
.draw();
}
});
});
This is a known limitation when using processing on the server-side. In this case the datatable-object only knows the data of the current draw. This is the reason you are only able to export the visible/rendered content of the table.
If you want to export the data from all currently selected rows, you could listen for the select.dt and deselect.dt events of the datatable and store the row-data of the selection in an extra array from that you can create the csv-data for an export.
Further information and examples about the events can be found in the oficial doumentation:
select event
deselect event
Whenever the selection changes, an event will be dispatched. We can listen for this select-event, check if the selection is of type row and add the data to an array or object. Since we want to prevent duplicates, we should choose an unique key for the data (based on an id or some other data of the row).
Depending on how you have implemented your datatable and the processing, you have to watch for the deselect-event too. And maybe add some special handling of the pagination inside the datatable, so that rows on other pages are displayed as selected when you navigate to them again.
let selectedRows = {}; // holds all the data of selected rows
let table = $('#example').DataTable({ /* settings */ });
table.on('select', function(e, dt, type, indexes) {
if ( type === 'row' ) {
let data = table.rows( indexes ).data();
for (let item of data) {
let key = item[0] + '_' + item[2] + '_' + item[2]; // an unique key, for example built from: eventName, firstName and lastName
if (!(key in selectedRows)) {
selectedRows[key] = item;
}
}
}
});
// Todo: handle deselect and maybe pagination...
You can then export that data inside the browser with javascript.
let csvData = 'COLUMN_1,COLUMN_2,COLUMN_3, ..., COLUMN_N';
for (let row of selectedRows) {
csvData = csvData + '\n'
+ '"' + row.column_1 + '",'
+ '"' + row.column_2 + '",'
+ '"' + row.column_3 + '",'
/* ... */
+ '"' + row.column_N + '",';
// Create temporary download-element
let a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([csvData], { type: 'text/csv;charset=utf-8;' }));
a.download = 'export.csv';
a.display = 'none';
// Append element to body and click it
document.body.appendChild(a);
a.click();
// Remove element from body
document.body.removeChild(a);
Note: If your data has strings that includes double quotes ", you have to escape them with an extra double quote "".
I have a searchbar included with the livesearch.com functionality from ajaxlivesearch.com
The problem is when i click on a result nothing happens. I want to send a query and show a result page when i click on the result. Before i included the ajaxlivesearch funtion i just typed in a keyword and pushed enter and then my result page showed up, this happens with an query. But after i included the ajaxlivesearch funtion pressing enter was not an option anymore, nothing happens.
I think the problem is within these jQuery lines;
jQuery(".mySearch").ajaxlivesearch({
loaded_at: <?php echo $time; ?>,
token: <?php echo "'" . $token . "'"; ?>,
maxInput: <?php echo $maxInputLength; ?>,
onResultClick: function(e, data) {
// get the index 1 (second column) value
var selectedOne = jQuery(data.selected).find('td').eq('1').text();
// set the input value
jQuery('.mySearch').val(selectedOne);
// hide the result
jQuery(".mySearch").trigger('ajaxlivesearch:hide_result');
},
onResultEnter: function(e, data) {
// do whatever you want
// jQuery(".mySearch").trigger('ajaxlivesearch:search', {query: 'test'});
},
onAjaxComplete: function(e, data) {
// do whatever you want
}
});
I hope someone can help me out
Cheers!
Before you do anything, go to the ajaxlivesearch.js file, and find this line of code ->
// disable the form submit on pressing enter
form.submit(function () {
return false;
});
Basically it's disabling anything form happening when you press enter, which is kind of the opposite of what you're trying to do. So obviously you need to change it, ex.
$("#search_ls_query").submit(function(){
return true;
});
Now, (This is not an entirely vital addition but nonetheless, submit the form in the "onResultEnter" area that you add to your index page. Ex.
jQuery(document).ready(function(){
jQuery(".mySearch").ajaxlivesearch({
loaded_at: <?php echo $time; ?>,
token: <?php echo "'" . $token . "'"; ?>,
maxInput: <?php echo $maxInputLength; ?>,
onResultClick: function(e, data) {
// get the index 0 (1st column) value
var selectedOne = jQuery(data.selected).find('td').eq('0').text();
// set the input value
jQuery('.mySearch').val(selectedOne);
// hide the result
jQuery(".mySearch").trigger('ajaxlivesearch:hide_result');
},
onResultEnter: function(e, data) {
$("#search_ls_query").submit();
},
/* #search_ls_query is the id of the default form that is submitted when you press enter (Find in ajaxlivesearch.js)*/
onAjaxComplete: function(e, data) {
}
});
})
Now go to the ajaxlivesearch.js file and find this:
var wrapper = '<div class="' + ls.container_class + '">' +
'<form accept-charset="UTF-8" class="' + ls.form_class + '" id="' + ls.form_class + '_' + elem_id + '" name="ls_form">' +
'</form>' +
'</div>';
And add an action to this form as this is what is being activated when you press enter in the search bar. So make it this:
var wrapper = '<div class="' + ls.container_class + '">' +
'<form accept-charset="UTF-8" action="search.php" class="' + ls.form_class + '" id="' + ls.form_class + '_' + elem_id + '" name="ls_form">' +
'</form>' +
'</div>';
This way it actually has a destination to send the values to. So the name of the value being sent is "ls_query", so whatever you type in the bar will now be inserted into the value of "ls_query". Therefore, once you press enter and arrive at your new page, you can then use this variable to filter your search options, or whatever you need. For example, on your search page you could write:
$ls_query = secure($_GET['ls_query'],$mysqli);
$sql = "SELECT *
FROM users
WHERE username ='$ls_query'";
This took me a while to figure out as well. But if you're still looking for the answer, this worked for me. Let me know how it went!
I have the code that dynamically generates textboxes and select boxes upon a button click. I want to fetch the data from DB and display in the dynamically generated select box.
Fiddle http://jsfiddle.net/hEByw/11/ shows how the text and selectboxes are generated dynamically.
I have tried the following part of code to fetch the data from DB and Put into dynamically generated select box(Tax Type) but its not working for me.
//To Display the tax types from DB
$(function(){
var items="";
$.getJSON("get_tax_type.php",function(data){
$.each(data,function(index,item)
{
items+="<option value='"+item.id+"'>"+item.name+"</option>";
});
$("#tax_type' + counter + '").html(items);
});
});
I feel the way I am doing is wrong.Can anybody suggest where am I doing wrong or the proper way of implementing it. I am newbie in jquery. Any help is appreciated.Thanks in advance.
PHP Code(get_tax_type.php)
<?php
include('includes/db.php');
$q = "select TaxID, TaxName from tax";
$sql = mysql_query($q);
$data = array();
while($row = mysql_fetch_array($sql, true)){
$data[] = $row;
};
echo json_encode($data);
?>
Try this. UPDATED
$(document).ready(function() {
var items = "";
$.getJSON("get_tax_type.php", function(data) {
alert(data);
$.each(data, function(index, item) {
$("#tax_type" + parseInt(index) + parseInt(1)).empty();
$("#tax_type" + parseInt(index) + parseInt(1)).append("<option value='" + item.TaxID+ "'>" + item.TaxName+ "</option>");
});
}, 'json');
});
I've been wrestling with a problem that I just cannot seem to solve. I've got a web form that is built from a MySQL query that's run from PHP and returned to JQuery that displays a gallery of movies that the user can give a numeric rating. I'm wanting to send the form back to PHP for processing and writing to the database.
function loadGallery()
{
$('content').append('<form id="movieRatings" action="../php/saveRatings.php" method="post">).html();
$.get('../php/getMovies.php')
.done(function(data) {
var query = $.parseJSON(data);
for (var i = 0, len = query.length; i < len; i++) {
var galleryMovies = '<div class="movContainer">' +
'<div class="movie">' +
'<a title="' + query[i].mov_title + '" href="../' + query[i].mov_title + '.html">' +
'<h3>' + query[i].mov_title + '</h3>' +
'<img src="../imgs/' + query[i].poster_path + '" /></a>' +
'<input type="number" name="' + query[i].mov_title + '" >' +
'</div>' +
'</div>';
$('#content').append(galleryMovies).html();
}
$('#content').append('<input type="submit" value="Submit"></form>');
})
.fail(function() {
$('#content').html("Epic Fail!") ;
});
}
The form displays without any issues, but clicking the submit button doesn't even send the request for the "saveRatings" PHP file. I'm sure I'm missing something simple, I just can't seem to figure out what that is. My first thought was that it was because the gallery isn't part of the actual html, but from what I've read that shouldn't have anything to do with it.
And pointers/sugestions/insight would be appreciated.
instead of
$('#ID').click(function(){
// do something here
});
switch to
$(document).on("click", "#ID", function(){
// do smth here
});
Your first assumption was true, if the element is not part of the initial html, then any events bound to it won't work unless you go with my second approach. You can find more about this behavior in the jquery documentation.
L.E: same goes for the submit action, in case i was not clear with the click example:
$(document).on("submit", 'form#formID',function(){
// do smth here...
});