<img> not being refreshed with jQuery - php

I am developing with xhtml, LAMP and jQuery 2.0.2 on Debian 7.0.0.
I am using the following php-generated element
echo "<img id=\"displayImageID\" src=\"" . $DisplayFileName . "\" alt=\"Background\" style=\"margin:10px 0px 10px 5px\"/>";
I am hoping to change it to a different color look up table when the used clicks on a radio button. In order to do this, I use the following code
jQuery.ajax({
type: "POST",
url: "DisplayParameters.php",
data: { LUT:lut }
}).done(function( result ) {
$("#msg").html( " Ajax called" );
});
with the following code in DisplayParameters.php
$LUT=$_POST['LUT'];
$Executable="Executables/changeLUT";
$DisplayImageName="images/display.png";
$Str=$Executable . " -t " . $LUT" . " -o " . $DisplayImageName;
$output=exec($Str, $dummy, $returnValue);
echo "<script language=\"JavaScript\">";
echo "d = new Date();";
echo "jQuery('#displayImageID').attr('src', '" . $DisplayImageName . "?'+d.getTime());";
echo "</script>";
}
to update the image and to reload it into the image element but nothing happens until I refresh the whole page with the Firefox "Reload current page".
I had thought that maybe, due to the asynchronous nature of Ajax, the image is getting loaded before it is replaced by a new image with the same name but different color LUT. However, if this were the case, I would expect the new LUT image to eventually be loaded if I keep clicking on radio buttons after the image that is saved to the disk is changed. This is not the case. I do not get a new image until I reload the page.

Try this:
JS
jQuery.ajax({
type: "POST",
url: "DisplayParameters.php",
data: { LUT:lut },
cache: false //CHANGED
}).done(function( result ) {
$("#msg").html( " Ajax called... and returned " + result );
//('#displayImageID').attr('src', result);
('#displayImageID').attr('src', result+'?'+$.now()); //CHANGED
});
PHP
$LUT=$_POST['LUT'];
$Executable="Executables/changeLUT";
$DisplayImageName="images/display.png";
$Str=$Executable . " -t " . $LUT" . " -o " . $DisplayImageName;
$output=exec($Str, $dummy, $returnValue);
echo $DisplayImageName; //CHANGED

Related

PHP handling data POSTED via AJAX

I need to loop through some data that was posted to a PHP page through AJAX. I've read about a dozen answers here and none are working for me. This is what my data object looks like before the post:
{"sessionValues":[{"ProductID":"507","State":"CHECKED"}, {"ProductID":"204","State":"UNCHECKED"}]}
I then post it like this:
$.ajax({
url: 'setSessionValues.php',
type: 'post',
data: {"session" : JSON.stringify(postObj)},
success: function(data) {
console.log(data); // Hello worldData: , Data: ,
}
});
This is the last thing that I tried in PHP:
if (isset($_POST["session"])) {
echo "Hello world";
$session = json_decode($_POST["session"]);
echo "Data: " . $session->sessionValues[0]->ProductID . ", " . $session->sessionValues[0]->State;
$session = json_decode($_POST["session"], true);
echo "Data: " . $session['sessionValues'][0]['ProductID'] . ", " . $session['sessionValues'][0]['State'];
}
Everything I've tried either throws out blanks or errors.
Edit:
Turns out that it doesn't like my data. Syntax Error: Unexpected end of input. Any ideas on that?
The second thing (xdebug is the first one) you should have tried in PHP is
if (isset($_POST["session"])) {
$session = json_decode($_POST["session"]);
print_r($session);

AJAX call from inside a Widget in Yii2?

I would like to create a Widget for my Yii2 project that will based on a few parameters given in the View create an AJAX call that updates a portion of my View.
Basically I have a Postcode field that when updated will look up the corresponding town in a different PHP file. I created something that works, but I was wondering if this is the right (or only?) way to do what I'm looking for. I don't want to have to rewrite the AJAX call as I want to be able to reuse this functionality on several forms and thus fields in my project.
I call the Widget in my View like this:
<?= SearchWidget::Widget(['id' => 'customerform-postalcode',
'dataTarget' => 'cities',
'targetId' => 'customerform-city',
'targetType' => 'dropdown']);?>
and in the Widget I basically have only a run() function which echoes the AJAX call to the page.
public function run()
{
$jScript =
'<script>'
. '$("#' . $this->id . '").change(function(){'
.'$.ajax({'
. 'url: "../scripts/search.php",'
. 'data: {'
. 'needle: $("#' . $this->id . '").val(),'
. 'haystack: "' . $this->dataTarget . '"'
. '},'
. 'type: "POST"'
. '}).done(function(data){'
.'var targetType = "' . $this->targetType . '";'
.'if (targetType=="dropdown") {'
. '$("#' . $this->targetId . '").empty();'
. 'var obj = jQuery.parseJSON(data);'
. '$.each(obj, function(key, value) {'
. '$("#' . $this->targetId . '").append("<option>" + value + "</option>");'
. '});'
. '} else {'
. 'var obj = jQuery.parseJSON(data);'
. '$("#' . $this->targetId . '").val(obj);'
. '}'
. '});'
. '})'
.'</script>';
echo $jScript;
}
First off, I've only just started working with Yii and frameworks so I'm really unsure if this is the correct way to go about it. My first instinct says this is too messy and there should be a better way to do it. Any help is appreciated.
Personally I don't like to write JS code in my PHP files. So I would try to get the JS in a separate .js file.
I would change my SearchWidget to echo an input field with some additional attributes that will provide the JavaScript with the right variables. So my postcode input field would look something like:
<input type="text" name="postcode" id="postcode" class="search-field" data-target="cities" data-targetid="customerform-city" data-targettype="dropdown" />
Then you can rewrite your JS to something like below (untested).
$('.search-field').change(function() {
var id = $(this).attr('id');
var data_target = $(this).data('target');
var target_id = $(this).data('targetid');
var target_type = $(this).data('targettype');
$.ajax({
url: "../scripts/search.php",
data: {
needle: $("#" + id).val(),
haystack: data_target
},
type: "POST"
}).done(function(data) {
if (target_type == "dropdown") {
$("#" + target_id).empty();
var obj = $.parseJSON(data);
$.each(obj, function(key, value) {
$("#" + target_id).append("<option>" + value + "</option>");
});
} else {
var obj = $.parseJSON(data);
$("#" + target_id).val(obj);
}
});
});
Then put this JS file somewhere and register it in the init part of your widget.

Echo not printing anything (It was before)

I am having a bit of a headache with a echo on my php code, the problem is that it isn't printing anything on screen, even though it was before, granted I added a function but when I used firebug to debug it it showed that it was getting the information out of a database correctly, just not printing it on-screen.
Where a list should be displayed there is nothing but empty space, staring into my soul.
I would appreciated if someone could point me out if I am missing something, as well why it is happening so I many not have to bother anyone anymore and if needed share my newly acquired knowledge.
PHP
function displayInfoLabs(){
if(isset($_POST['pId'])){
$id = $_POST['pId'];
$info = getSpecificLabs($id);
while($row = mysql_fetch_assoc($info)){
echo '<ul>' .
'<li>Laboratorio # ' . $row['codigolab'] . '</li>' .
'<li>Capacidad: ' . $row['capacidad'] . '</li>' .
'<li>Carrera: ' . $row['carrera'] . '</li>' .
'<li>Ubicación: ' . $row['ubicacion'] . '</li>' .
'</ul>';
}
}
}
function getSpecificLabs($pId){
$query = "SELECT bk.idlab , bk.codigolab , bk.capacidad, bk.carrera, bk.ubicacion FROM labs as bk WHERE bk.idlab = $pId";
$result = do_query($query);
return $result;
}
For reference I am also including the html and JS code of this function.
JS
$("#lnkInfo").click(function() {
var id = $('#txtId').val();
var request = $.ajax({
url: "includes/functionsLabs.php",
type: "post",
data: {
'call': 'displayInfoLabs',
'pId':id},
dataType: 'json',
success: function(response){
alert('exito')
}
});
});
HTML created via PHP, mind the lnkInfo which calls the JS that in turn calls the PHP
function displayList(){
$lista = getLabs();
while($row = mysql_fetch_assoc($lista)){
echo
'<div class="box" id="lab'.$row['idlab'].'">
<p id="labName">Lab #'.$row['codigolab'] . '</p>
<p class="info">Info</p>
<p class="info">Reservar</p>
<input type="hidden" name="txtId" id="txtId" value="'.$row['idlab'].'">
</div>';
}
}
Thanks a lot in advance.
EDIT:
Changing the success function made the list appear but it overrode the div's style including the buttons it had and all. This is the div's code.
div class="popUp1 hide" id="popUpCorrecto1">
<div class="estiloPopUp">
<span>Información de laboratorio</span>
<span value="Cerrar" id="btnCerrar">x</span>
</div>
<input type = "button" value = "Eliminar" id = "btnEliminar" onclick="eliminar()" />
<input type = "button" value = "Modificar" id = "btnModificar" onclick="window.location='modificarLab.html';" />
</div>
As you said in the comments, your data is being captured, but you aren't appending it to the document. you are simply doing:
alert('exito');
What you want to do is append the response to an element that is present in your page.
For examples sake, we can put a <div> with the id of mydata like so:
<div id="mydata"></div>
Now in your jQuery.ajax function, you could do something like the following:
$("#lnkInfo").click(function() {
var id = $('#txtId').val();
var request = $.ajax({
url: "includes/functionsLabs.php",
type: "post",
data: {
'call': 'displayInfoLabs',
'pId':id},
dataType: 'text/html',
success: function(response){
$('#mydata').html(response);
}
});
});
As you can see in the above, we modified your success function to include
$('#mydata').html(response);
provided all your data is printed and supplied correctly, it should display on the page.
EDIT:
it seems in your PHP query
$query = "SELECT bk.idlab , bk.codigolab , bk.capacidad, bk.carrera, bk.ubicacion FROM labs as bk WHERE bk.idlab = $pId";
You are selecting the columns prefixed with bk.* yet trying to print out the values without the prefix as seen below:
echo '<ul>' .
'<li>Laboratorio # ' . $row['codigolab'] . '</li>' .
'<li>Capacidad: ' . $row['capacidad'] . '</li>' .
'<li>Carrera: ' . $row['carrera'] . '</li>' .
'<li>Ubicación: ' . $row['ubicacion'] . '</li>' .
'</ul>';
Try changing the above to something like:
echo '<ul>' .
'<li>Laboratorio # ' . $row['bk.codigolab'] . '</li>' .
'<li>Capacidad: ' . $row['bk.capacidad'] . '</li>' .
'<li>Carrera: ' . $row['bk.carrera'] . '</li>' .
'<li>Ubicación: ' . $row['bk.ubicacion'] . '</li>' .
'</ul>';
If i understood it correctly.
Edit: ignore above php examples.
Change the success function from:
$('#mydata').html(response);
to
$('#mydata').append(response);
As .html() replaces all content within the specified element with the supplied content.
EDIT #2:
From the comments, you're ajax request is run every time that #LnkInfo is triggered which seems like it happens a lot as it loads the PopUp?
What you want to do is add in some logic, either in your jQuery function that checks if you've already appended the list to the popup and to stop it appending.
That could be done simply by adding a boolean variable somewhere in there.
Alternatively, you could just add a little div on that popup that you append it to.
Example:
This is your popup:
div class="popUp1 hide" id="popUpCorrecto1">
<div class="estiloPopUp">
<span>Información de laboratorio</span>
<span value="Cerrar" id="btnCerrar">x</span>
</div>
<!-- ADDED A NEW DIV HERE FOR LIST CONTENT -->
<div id="mylistcontent"></div>
<input type = "button" value = "Eliminar" id = "btnEliminar" onclick="eliminar()" />
<input type = "button" value = "Modificar" id = "btnModificar" onclick="window.location='modificarLab.html';" />
</div>
As you can see above, I've added the following:
<!-- ADDED A NEW DIV HERE FOR LIST CONTENT -->
<div id="mylistcontent"></div>
Now in your jQuery success function, you could append to that #mylistcontent div instead of the popup div :)

Unable to get animations to work correctly in jQuery

I just recently started learning jQuery. To help me learn, I started redesigning this website. The problems I have at the moment are:
Once a thumb image is clicked and the main post loads; after closing the main post and when hovering over the thumbs again, the title and post information no longer fade in above and beside the thumbs.
When hovering over a thumb image for the first time, you should notice that it hides everything (including itself) and then shows itself again, this gives the illusion that it flickers. How can I stop this?
Here is the .js file containing the jQuery code:
$(".post").hover(
function () {
$(this).children(".post_title, .post_info").stop(true).fadeIn();
$(this).children(".link-to-post").stop().show();
$(".post").stop().fadeTo(0,0.2);
$(this).fadeTo(300,1);
},
function () {
$(this).parent().find(".post_title, .post_info").stop(true).hide();
$(this).parent().find(".link-to-post").stop().hide();
$(".post").stop().fadeTo(300,1);
});
$(".cover-img").click(function(){
$("#main-post").fadeIn(1000);
$.post("inc/fullpost.php", {postid: $(this).data('postid')},
function(output){
$("#gotpostid").html(output).show();
}).fail(function(x,y,z){
$("#gotpostid").html(x + "<br />" + y + "<br />" + z)
});
$('.post').fadeTo(0,0);
});
$('input[name=close]').click(function(){
$(this).closest('#main-post').hide();
Each thumbnail is within its own class:
// Retrieve all active posts order by lastest first
$resultarray = retrieve_active_posts();
echo '<div id="content-wrap">';
foreach($resultarray AS $value){
$filename = substr($value['img_file_name'],9);
$cat_id = $value['cat_id'];
echo '<article class="post">';
echo '<div class="post_title">' . stripslashes(stripslashes($value['post_title'])) . '</div>';
echo '<div class="post_info">' .
'Category: ' . $cat_name = get_cat_name($cat_id) .'<br />'.
'Year: ' . $value['post_year'] .'<br />'.
stripslashes($value['post_desc']) .'<br />'.
'</div>';
echo '<div class="link-to-post">Click to view</div>';
echo '<img class="post-thumb" src="img/thumb_/'.$filename.'" alt="MJbox Michael Jackson memorabilia thumbnail" data-postid="'.$value['post_id'].'"/>';
echo '<img class="cover-img" src="img/post-bg-1.png" alt="test" data-postid="'.$value['post_id'].'"/>';
echo '</article>';
}
echo '</div>';
I'll have another go :-)
I've looked on the Google Developer Tools and it looks like this is the problem...
$('.post').fadeTo(0,0);
It is leaving the opacity attribute as 0. When I override this in developer tools, the popups show again. Try changing it to:
$('.post').fadeOut;
or even
$('.post').hide();
Should do the trick.
I'm pretty sure I have the answer to the other problem:
You have two animations. You are fading all of the .post items out and then fading $(this) back in again. You need this solution:
$(".post").hover(
function () {
$(this).children(".post_title, .post_info").stop(true).fadeIn();
$(this).children(".link-to-post").stop().show();
$(this).siblings.().stop().fadeTo(0,0.2);
},
This will fade out only the other ones so you don't have to fade $(this) back in again!
Fingers crossed!
I have tested this. It fixes both problems and also stops the browser going to the top of the page when you click one of the thumbs.
Here is the complete jQuery code
$(document).ready(function(){
$(".fancybox").fancybox();
$("#login").click(function(){
$("#searchform").hide();
$("#loginform").fadeIn('3000','swing');
});
$("#search").click(function(){
$("#loginform").hide();
$("#searchform").fadeIn('3000','swing');
});
$(".post").hover(
function () {
$(this).children(".post_title, .post_info").stop(true).fadeIn();
$(this).children(".link-to-post").stop().show();
$(this).siblings().stop().fadeTo(0,0.2);
},
function () {
$(this).parent().find(".post_title, .post_info").stop(true).hide();
$(this).parent().find(".link-to-post").stop().hide();
$(".post").stop().fadeTo(300,1);
});
$(".cover-img").click(function(e){
e.preventDefault();
$("#main-post").fadeIn(1000);
$.post("inc/fullpost.php", {postid: $(this).data('postid')},
function(output){
$("#gotpostid").html(output).show();
}).fail(function(x,y,z){
$("#gotpostid").html(x + "<br />" + y + "<br />" + z)
});
$('.post').fadeOut();
});
$('input[name=close]').click(function(){
$(this).closest('#main-post').hide();
});
});
Just cut and paste this in place of your code.
Chris
This is for your first problem.
Try doing ...
$(".cover-img").click(function(e){
e.preventDefault();
.... rest of your code
This prevents the default behaviour of the browser to follow the link. This may solve your first problem but should be in there anyway with click events.

Jquery/Ajax and PHP rendering TR

I am scraping sites, and I am doing this one at a time, and then trying to get the results to display AS I get them. I am trying to render one TR at a time, but instead, it does every single one, and then renders ALL the TRs.
Here is the call to javascript:
<body onload="getOffers(companies , {$scraped}, {$isbn13});">
Here is the JS/Jquery function:
function getOffers($company_ids, $scraped, $isbn)
{
if($scraped)
{
$.ajaxSetup({cache: false});
for(var $id in $company_ids)
{
$.ajax({
url: "../get_offer.php",
data: "id=" + $company_ids[$id] + "&isbn=" + $isbn + "&code=" + $id,
dataType: "html",
success: function(data) {
$("#results tbody:last").append(data);
}
});
}
}
else
{
return true;
}
}
And here is the PHP page:
<?php
require_once 'scrape.php';
require_once 'include.php';
$id = requestValue('id');
$isbn = requestValue('isbn');
$code = requestValue('code');
$page = curlMultiRequest(isbn10($isbn), $id);
$offer = getOffer($code, $page[$code], isbn10($isbn));
print "<tr><td>". $offer['company']."</td><td>". $offer['offer_new'] . "</td><td>" . $offer['offer_used']."</td></tr>";
?>
I tried returning the sting I am printing, but that didn't even work. How can I make it print each table row to the screen as the data is retrieved?
EDIT: so I tried adding this:
print "<tr><td>". $offer['company']."</td><td>". $offer['offer_new'] . "</td><td>" . $offer['offer_used']."</td></tr>";
ob_flush();
flush();
To the PHP and it didn't work. I don't understand, if I throw an alert, it happens on the fly for every ID, but the html rendering does not.
It may have magically fixed itself because your browser was caching some of the javascript. You should use some developer tools to manually flush the cache of resources for the host you are testing on to avoid old code being subtly used ....

Categories