Looping Issue - AJAX/jQuery - php

So i spent some time over night adding user pictures to a voting feature we have, and all is working nicely, however we notice that as users pictures show up as who voted, it repeats the results twice, instead of a row of pictures going across per item.
So per item, users picture (who voted on the poll ID) shows up but duplicates the row.
Does this have to do with $.each() ? How can I iterate the photos across each row (id column) without creating a copy of the answer and not show only 1 picture?
function fetchPollData() {
$(function(){});
$.ajax({
url: "ajax_pollresults.php",
method: "GET",
dataType: 'JSON',
success: function (data) {
var html_to_append = '';
$.each(data, function (i, item) {
var scase = (item.votes > 1) ? 'votes' : 'vote';
html_to_append +=
'<div class="content poll-result"><div class="wrapper"><div class="poll-question"><p>' +
item.title +
' - <span style="font-weight:bold">' + item.votes + ' ' + scase + ' <img class="tooltip-polluser" title="' + item.username + ' - Voted: ' + item.title + '" href="/user/?id=' + item.user_id + '" style="width:25px;height:25px;border-radius:50%;margin-left:10px;vertical-align:middle" src="/' + item.avatar + '" /></span></p><div class="result-bar" style="width:' + roundVotes(item.votes) + '%"><b>' + item.votes + '</b> ' + scase + ' </div></div></div></div>';
});
$("#recent-poll").html(html_to_append);
$('.tooltip-polluser').tooltipster({
animation: 'grow',
delay: 200,
theme: 'tooltipster-punk'
});
}
});
}
fetchPollData();
setInterval(function () {
fetchPollData()
}, 10000);
The bug we cant figure out a fix for:
It seems it is only showing 1 user per voted item, and ignoring the rest of the row.
our SQL query:
SELECT
poll_answers.id AS id,
IFNULL(poll_users.user_id, '') AS user_id,
IFNULL(users.username, '') AS username,
poll_answers.poll_id,
poll_answers.title,
poll_answers.votes,
poll_users.added AS date,
IFNULL(users.avatar_thumb,
'images/poll_avatarfix.png') AS avatar
FROM
poll_answers
LEFT JOIN
poll_users ON poll_users.poll_id = poll_answers.poll_id
LEFT JOIN
users ON users.user_id = poll_users.user_id
And the database results:
I spent a fair bit of the evening writing this SQL query, so I'm not sure if this is the query not bringing all avatars out or if its jQuery.
Any help is greatly appreciated!

You will want to get each voter image in an inner loop. You can do something like the following...
Instead of using just the one record, call something like getVoteImages() and pass in the poll id you are looking for. This will get all of your images and append them to a string then return it. There may be faster, more elegant ways to do it, but this should work.
$.each(data, function (i, item) {
var scase = (item.votes > 1) ? 'votes' : 'vote';
html_to_append +=
'<div class="content poll-result"><div class="wrapper"><div class="poll-question"><p>' +
item.title +
' - <span style="font-weight:bold">' + item.votes + ' ' + scase + getVoteImages(data, item.poll_id) + "</span></p><div class="result-bar" style="width:' + roundVotes(item.votes) + '%"><b>' + item.votes + '</b> ' + scase + ' </div></div></div></div>';
});
function getVoteImages(data, poll_id) {
var images = "";
$.each(data, function (i, item) {
if (item.poll_id == poll_id) {
images += ' <img class="tooltip-polluser" title="' + item.username + ' - Voted: ' + item.title + '" href="/user/?id=' + item.user_id + '" style="width:25px;height:25px;border-radius:50%;margin-left:10px;vertical-align:middle" src="/' + item.avatar + '" />';
}
});
return images;
}

Related

Slow SQL Query / Displaying (PHP / jQuery)

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

issue trying to get a div and clone it via jquery

I'm pretty new to web programming so, making a logic for a web-page, I made a mistake and now I'm in trouble.
I named some divs like "Dv_1.2.1.3" (without knowing the problems linked to using the dot) and I have issues trying to clone (via jquery called by button) some of these.
The button id contains the id of the div I want to clone, so, my logic is:
1) extract the id of the div;
2) get the div and clone it (giving a new id).
I'm stuck with getting the div because of the dots in the id.
The below code is what I've done so far:
$('.CloneDiv').click(function () {
var SplittedId = (this.id).split('_');
if (SplittedId[0]=='Clone'){
alert('SplittedId 1 =' + SplittedId[1]);
//Modify id to use it to find the div to clone
var UsableId = SplittedId[1].replace(/\./g, '\\\\.');
alert('UsableId =' + UsableId);
//Count existing elements
var ClonedNum = $('#' + 'Dv_' + UsableId + '_').length;
ClonedNum++;
var OrigElem = $('#' + 'Dv_' + UsableId).length;
alert('OrigElem =' + OrigElem); //THIS IS 0
//NO ELEMENTS FOUND BUT THE ELEMENT EXISTS
//Clone the element and give new id
var ClonedElem = $('#' + 'Dv_' + UsableId).clone().attr('id', function( i, val ) {
return val + '_' + ClonedNum;
});
ClonedElem.find("input").val("");
if (ClonedNum > 1){
ClonedNum--;
var AnteId = '#' + 'Dv_' + UsableId + '_' + ClonedNum;
alert(AnteId);
$(AnteId).after(ClonedElem);
}else{
var AnteId = '#' + 'Dv_' + UsableId;
alert('AnteId = ' + AnteId);
$(AnteId).after(ClonedElem);
};
}else if(SplittedId[0]=='Del'){
alert(SplittedId[0]);
alert('Del');
}else{
//error
};
});
Might these help: developer.mozilla.org/en-US/docs/Web/API/CSS/escape , Polyfill: github.com/mathiasbynens/CSS.escape/blob/master/css.escape.j‌​s

Populate select box with json data from laravel db query

i have a html select box that needs to be populated using jquery ajax with select options that come from a php (Laravel) database query. I tried many approaches but no result, i only get 'undefined' as result.
The Laravel script:
public function loturi($articol) {
$loturi = DB::select("select mgla_lotto from MG_V_DispoLottiBarcode d
join MG_AnaArt art on art.MGAA_Id = d.MGAA_Id join MG_LottiAnag l on
l.MGLA_Id = d.MGLA_Id where MGAA_MBDC_Classe IN ('SEM','FIN') and mbmg_id = 55
and mgaa_matricola in (select child.MGAA_Matricola component
from DB_Legami join MG_AnaArt child on child.MGAA_Id = DBLG_Com_MGAA_Id
join MG_AnaArt p on p.MGAA_Id = DBLG_MGAA_Id
where p.MGAA_Matricola = '$articol') and mgla_datacreazione > '2014-01-01'
group by mgla_lotto having sum(dispo) > 0");
return compact('loturi');
}
The result is this:
{"loturi":[{"mgla_lotto":"1282\/15"},{"mgla_lotto":"1316\/15"},{"mgla_lotto":"1339\/15"},{"mgla_lotto":"1349\/15"},{"mgla_lotto":"1354\/15"},{"mgla_lotto":"1404\/15"},{"mgla_lotto":"1405\/15"},{"mgla_lotto":"1412\/15"}]}
The jquery script is this:
$(document).ready(function() {
$("#cod").change(function(){
var cod_articol = $("#cod").val();
$.ajax ({
url: "/internal/" + cod_articol ,
datatype: "json",
success: function(data) {
$.each(data, function(value){
$("#lot").append('<option id="' + value.index + '">' + value.name +
'</option>');
})
}
});
});
});
Hi here is your answer.
change
$.each(data, function(value){
to
$.each(data.loturi, function(value){
and use below syntax
$.each(data.loturi, function( index, value ){
$("#lot").append('<option value="' + index + '">' + value.mgla_lotto + '</option>');
}
Go to the link to see the example i have made for you.
https://jsfiddle.net/ovht7fkh/2/

Jquery autocomplete text field with data attribute in dynamically added rows

The following jQuery works fine to add rows, and populate the select list from a php/mysql file. The issue I am having is that the price field is being auto-populated and changed on select change on each new row that is added... but if you go back and try to change one of the rows that has already been added, it does not work. For instance, if you add 4 blank rows and then try to go back and select products, it will only populate the price on the last row. Or if you add each row and select the products before you add a new row, then go back and attempt to change the product, the price previously selected will remain the same. Any ideas?
EDIT 1 Added html
EDIT 2 Changed jQuery change(function() to on()... still works exactly the same. The autocomplete only works on the last row added.
var count = 0;
$(document).ready(function(){
$('p#add_field').click(function(){
count += 1;
$('#addingContainer').append('<label>Product or Service</label><select id="product_' + count + '" name="products[]'+ '" ><option value=""></option>');
$.getJSON('includes/productrow.php', function(data){
var select = $('#product_' + count + '');
$.each(data, function(key, val) {
$('<option/>').attr('value', val.product_id)
.attr('data-price', val.price)
.html(val.product)
.appendTo(select);
});
$('#addingContainer').append('</select> <label>Price</label><input type="text" id="price_' + count + '" name="prices[]' + '" class="price" ><br>');
});
$('#addingContainer').on('change', 'select[id="product_' + count + '"]', function(){
$('#price_' + count +'').val($('select[id="product_' + count + '"] option:selected').data('price'));
});});});
HTML:
<div id="addingContainer" class="pure-control-group">
<p id="add_field"><span>Add Products</span></p>
</div>
edit Actually, I think the reason it isn't working is because of where you declared count. Something like this would work:
$(document).ready(function(){
$('p#add_field').click(function(){
var count = $('#addingContainer').data("count") || 0;
count += 1;
$('#addingContainer').data("count", count).append('<label>Product or Service</label><select id="product_' + count + '" name="products[]'+ '" ><option value=""></option>');
$.getJSON('includes/productrow.php', function(data){
var select = $('#product_' + count + '');
$.each(data, function(key, val) {
$('<option/>').attr('value', val.product_id)
.attr('data-price', val.price)
.html(val.product)
.appendTo(select);
});
$('#addingContainer').append('</select> <label>Price</label><input type="text" id="price_' + count + '" name="prices[]' + '" class="price" ><br>');
});
$('#addingContainer').on('change', 'select[id="product_' + count + '"]', function(){
$('#price_' + count +'').val($('select[id="product_' + count + '"] option:selected').data('price'));
});});});
Note I removed your initial declaration of count outside of the document.ready and the function closure; that allowed you to keep track of it (I handled that by setting it on a data attribute, there are other and better ways) but that was why your on('change' method was always using the highest count.
By declaring count inside the function, it is specific to that closure -- and so it won't increase for all of the functions you declared each time a new click event is fired.
Give this a try. I added a class "pselect" to the select box which makes it easier to work with. Then I modified the change function.
var count = 0;
$(document).ready(function(){
$('p#add_field').click(function(){
count += 1;
$('#addingContainer').append('<label>Product or Service</label><select id="product_' + count + '" name="products[]'+ '" class="pselect"><option value=""></option>');
$.getJSON('includes/productrow.php', function(data){
var select = $('#product_' + count + '');
$.each(data, function(key, val) {
$('<option/>').attr('value', val.product_id)
.attr('data-price', val.price)
.html(val.product)
.appendTo(select);
});
$('#addingContainer').append('</select> <label>Price</label><input type="text" id="price_' + count + '" name="prices[]' + '" class="price" ><br>');
});
$('#addingContainer').on("change",".pselect",function(){
$(this).next(".price").val($("option:selected", this).attr('data-price'));
});
});});

Json result "undefined" when attempting to dynamically populate select list

I am attempting to add dynamic rows with a product and a price to an order form with Jquery. The issue is that I need the product dropdown to be dynamically filled from mysql. The rows are adding correctly. The only problem I am having how is that the dropdown menu only has one option and that option says "undefined".
EDIT 1 : I changed the PHP code. I think it is formatted correctly now but I am still getting "undefined" in my select list.
EDIT 2 : I tested the php and there were some errors. Now the php works perfectly on its own and returns the following json encoded array, but when I am attempting to pull it into my jquery script it is still returning an "undefined" result. :
[{"product":"wedding 4","price":"400.00","id":"9"},
{"product":"wedding 2 ","price":"400.00","id":"8"},
{"product":"Wedding 1","price":"4000.00","id":"1"},
{"product":"potato","price":"50.00","id":"6"},
{"product":"Event","price":"3000.00","id":"5"},
{"product":"alligator","price":"800.00","id":"7"}]
jQuery:
var count = 0;
$(document).ready(function(){
$('p#add_field').click(function(){
count += 1;
$('#addingContainer').append('<strong>Link #' + count + '</strong><br />' + '<label>Product or Service</label><select id="product_' + count + '" name="products[]'+ '" >');
$.get('includes/productrow.php', function(data){
$('#product_' + count + '').append('<option value=' + data.product_id + ' data-price=' + data.price + '>' + data.product +'</option>');
});
$('#addingContainer').append('</select> <label>Price</label><input type="text" id="price_' + count + '" name="prices[]' + '" class="price" >');
});
productrow.php
<?php
$productSql = "SELECT product_id, product, price FROM products WHERE compid = '$compid' ORDER BY product desc";
$productResult = mysql_query($productSql, $link);
while($productRow = mysql_fetch_array($productResult)){
$final_array[] = array("product" => $productRow['product'], "price" => $productRow['price'], "id" => $productRow['id']);
};
echo json_encode($final_array);
?>
** Disclaimer, I know I should be using PDO and as soon as this project is finished I will begin using it.
I always use jquerys $.get:
$.get('includes/productrow.php', function(resp){
$('#yourid').append(resp);
});
Try if you could implement this.
Use it like this:
$.get('includes/productrow.php', function(resp){
$('#addingContainer').append('<strong>Link #' + count + '</strong><br />' + '<label>Product or Service</label><select id="product_' + count + '" name="products[]'+ '" /><option value=""></option>' + resp + '</select> <label>Price</label><input type="text" id="price_' + count + '" name="prices[]' + '" class="price" >');
});
Hope this works!
I made the following files to test it:
<html>
<head>
<script type="text/javascript" src="../server/public/js/jquery.js"></script>
<script type="text/javascript">
$.get('productrow.php', function(resp){
$('body').append('<strong>Link #</strong><br />' + '<label>Product or Service</label><select id="product_" name="products[]'+ '" /><option value=""></option>' + resp + '</select> <label>Price</label><input type="text" id="price_" name="prices[]' + '" class="price" >');
});
</script>
</head>
<body>
</body>
</html>
productrow.php:
<?php
echo "test";
result:
Link #
Product or Servicetest Price
the test is there as expected. Could you send me your whole code or create a jsfiddle
The problem was in the JSON request. The corrected code is below. This code also allows a text field with the price of the product to be automatically populated using the data-price attribute:
Jquery:
var count = 0;
$(document).ready(function(){
$('p#add_field').click(function(){
count += 1;
$('#addingContainer').append('<strong>Link #' + count + '</strong><br />' + '<label>Product or Service</label><select id="product_' + count + '" name="products[]'+ '" ><option value=""></option>');
$.getJSON('includes/productrow.php', function(data){
var select = $('#product_' + count + '');
$.each(data, function(key, val) {
$('<option/>').attr('value', val.product_id)
.attr('data-price', val.price)
.html(val.product)
.appendTo(select);
});
$('#addingContainer').append('</select> <label>Price</label><input type="text" id="price_' + count + '" name="prices[]' + '" class="price" >');
});
productrow.php
$productSql = "SELECT product_id, product, price, compid FROM products WHERE compid = '$compid' ORDER BY product desc";
$productResult = mysql_query($productSql, $link);
while($productRow = mysql_fetch_array($productResult)){
$final_array[] = array("product" => $productRow['product'], "price" => $productRow['price'], "id" => $productRow['product_id']);
};
echo json_encode($final_array);

Categories