Link to home
Start Free TrialLog in
Avatar of Marco Gasi
Marco GasiFlag for Spain

asked on

dynamic image

Hi all.
Okay, I fought hard: now, I surrend!
In a page I do an ajax call to a script which returns an array containing all products of a given category. In the array are the image name hold in the database, but not always the image exists. SO I do another ajax call to a php script which return true or files accordingly: if the script returns false a placeholder should be used.
My not-working code is this:

	var listProductsPerSubcategory = function (dest, subcatid)
	{
		$.ajax({
			type: 'post',
			url: 'scr_list_products_per_subcategory.php',
			data: {subcatid: subcatid},
			dataType: 'json',
			success: function (result)
			{
				var lst = '<script>$(function() {$( ".imgres" ).aeImageResize({ height: 150, width: 100 });})</script>';
				$.each(result, function (k, v)
				{
					var img = v['pictures'];
					$.ajax({
						type: 'post',
						url: 'scr_file_exists.php',
						data: {f: img},
						success: function (result)
						{
							if (result === false)
							{
								img = 'nopic';
							}
							else
							{
								img = v['pictures'];
							}
						},
						error: function ()
						{
							img = 'nopic';
						}
					});
					lst = lst + '<div class="productFrame">';
					lst = lst + '<div class="imgwrapper"><img class="imgres" src="../pictures/' + img + '.jpg" /></div>';
					lst = lst + v['prod_code'] + '<br>';
					lst = lst + v['prod_name'] + '<br>';
					lst = lst + '</div>';
				});
				$(dest).html(lst).fadeIn('slow');
			},
			error: function (result)
			{
				$(dest).html(result).fadeIn('slow');
			}
		});
	};

Open in new window


Shortly, the img valus remains just the same even if the php script returns false.
Please, help me to understand!!!
Thank you all in advance.
Marco
Avatar of Rob
Rob
Flag of Australia image

Your code looks ok on first inspection.  Are you able to post a link to your site?
Avatar of Marco Gasi

ASKER

Hi, Rob, thanks for you reply.
You can go here: www.webcanario.com/1stop-homeshop/admin/admin-dashboard.html
For the moment it is not password protected because is a temprary database in a develpment environment hosted temporarily in my server. Look, colours and all the rest are just raw: please, don't judge my taste for that :-)
You have to choose 'Update a product' from hte menu on your left and then elect a category and a subcategory. I suggest to choose 'Lightning' as category and the only one available subcategory becaue there are few product and the problem is evident.
Thank you so mutch. Hope you find the solution.
Cheers
Hi Marco,

I'm getting an error:
Errore

Stai cercando una pagina che non esiste: admin/admin-dashboard.html
Thanks for that, it now works.

I'm using the browser developer tools and I can see the ajax requests to scr_file_exists.php.  That script isn't returning any data.  How are you returning true or false?
IIn php script I have:

<?php
$file = filter_input(INPUT_POST, 'f');
mgLogger::writeLog($file);
if (file_exists('/home/u406076075/public_html/1stop-homeshop/pictures/'.$file.'.jpg'))
{
	mgLogger::writeLog('/home/u406076075/public_html/1stop-homeshop/pictures/'.$file.'.jpg'.'  file exists');
}
else
{
	mgLogger::writeLog('/home/u406076075/public_html/1stop-homeshop/pictures/'.$file.'.jpg'.'  file doesn\'t exist');
}
echo file_exists('/home/u406076075/public_html/1stop-homeshop/pictures/'.$file.'.jpg');

Open in new window

Anyway, a good point. I changed the script as follows:

<?php
$file = filter_input(INPUT_POST, 'f');
if (file_exists('/home/u406076075/public_html/1stop-homeshop/pictures/'.$file.'.jpg'))
{
	echo "yes";
	exit;
}
else
{
	echo "no";
	exit;
}
echo 'yes';

Open in new window

This time it gives a response which is correctly receive by the calling javascript function, but till the value of img variable isn't modified and in the html I get the name of the expected image intead of the name of placeholder...
Sure, I'll take a look now
Your script is returning "no" regardless of whether the image exists or not
I'm going to fix that but... the strange things is that the javascript behaves if the response be always yes! lol
Ah! I've got it!  Where you set your image with the following code:

lst = lst + '<div class="productFrame">';
lst = lst + '<div class="imgwrapper"><img class="imgres" src="../pictures/' + img + '.jpg" /></div>';
lst = lst + v['prod_code'] + '<br>';
lst = lst + v['prod_name'] + '<br>';
lst = lst + '</div>';

it is outside the scope of the ajax callback.  If you debug each call you'll see the ajax returns to each of the success functions, one after the other before it even gets to the lines above.  What you need to do is move the above code into the success function
ASKER CERTIFIED SOLUTION
Avatar of Rob
Rob
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Oh, now I try, but I have a question: when I did it, Netbeans IDE highlight the code with a red underline howing an error so I didn't test the code at all: is it a Netbeans error? We'll see now...
What did the error in netbeans say? (mouseover the error)

As a side note, I would suggest looking a model based framework like knockoutjs or Angularjs as it separates the logic from how the site looks.  The whole lst = lst + .... is very messy and I'm sure it doesn't make it easy to get your layout right, let alone SEO.
Well the error was a mine one (obvious, uh?)
Anyway, placing the messy code within tha ajax call I get... nothing. That is the lst isn't displayed. Now, I'm going to investigate this.
Using Angular or Knockout means I have to change all my jquery scripts?
Thank you so mutch for your help. I'll look for Angular and Knockout (any suggetion about?)
On to the next.
I gather it works now? :)

Using Angular or Knockout means I have to change all my jquery scripts?
Not necessarily.  With Knockout, no you don't.  It runs independently.  Angular uses its own version of jQuery that may conflict.
I'm biased having only used Knockout but In a case like this, where you want more control over your logic, you can't beat it's very low overhead and non conflict with jQuery.  Angular is more a fully fledged, all in one, framework versus picking and choosing your own like you would with jQuery, Knockout, jQueryUI etc.

Have a look at http://knockoutjs.com/index.html
Oh, yes it works fine. :-)
But now I worry a bit about SEO and the messy coding... Let me understand: if knockout runs independently, then my code remains as it is, that is messy (at least in the part we have seen in this question: fortunately I have  only that part built in that way right now).
And why the build of a string which holds some markup is messy? And why it breaks the SEO? If you want it would be fine for me to open new questions about this...
Mmmh, it looks very interesting... thanks a lot, Rob :-)
It only affects your SEO when you include the content dyamically via ajax.  SEO is more than just one thing so it's not broken just maybe not as good as it could be.

Building a string is messy because the design component is tied with the logic component.  What I mean is, you change something in your code, your layout can change dramatically.

With knockout, you design the layout separately from the logic.  To give you a quick example (and yes we probably should open another question on it if you want to know more if only to benefit others)

Conceptual Example:
Your PHP file returns an array of images right? well you would store this in an array, in the knockout model (just a javascript object).  e.g. products is an array of objects that is returned as json from your php, [{image: "../pictures/lamp.jpg", prod_code: "237382", prod_name: "Metal lamp (matte finish)"}, { ... }];

Your markup would look something like this:
<div class="productFrame" data-bind="foreach: products">
	<div class="imgwrapper"><img class="imgres" data-bind="attr: {src:\"../pictures/' + image + '\"}" /></div>
	<div class="textwrapper">
		<span data-bind="text: prod_code"><br/>
		<span data-bind="text: prod_name"><br/>
		<a class="editProduct" data-bind="attr: {href: prod_code}">Edit data for this product</a>
	</div>
</div>

Open in new window


The above markup would be repeated for each entry in the products array.  This makes it very easy to send data back and forth from your php using the JSON format.  

The best thing I've found is you don't have to refresh the page.  As long as your "products" array is in the knockout model, the page will update automatically
Here's a sample of how easy it is.  http://jsbin.com/rixawu/1/edit?html,js,output

Can you see how the layout is separated from the data/logic?
Very interesting, thank you so mutch for this explanation. Knockout seems to be very powerful if I can write the markup only once for n elements and it replicates it as needed! You're like Robi-Wan Kenobi :-)
I've just opened another question about the same page (but not related to knockout.js: I'll take my time to study it): can you take a look?
https://www.experts-exchange.com/questions/28583307/multizoom-js-breaks-my-scripts.html
Cheers
Wow, really fantastic! And in that case, has knockout some opions to apply fade effect, or show elements one at once see my page after your fix: the each function shows the divs sequentially and I like the ffect (and I'm sure my client will like it too)
ooops, now you can't see it because of my other question: including multizoom breaks all my scripts: wonderful, isn't it?
And in that case, has knockout some opions to apply fade effect, or show elements one at once see my page after your fix: the each function shows the divs sequentially and I like the ffect (and I'm sure my client will like it too)
That's the beauty of it.  You still use jQuery for that, but yes you can tie effects in as needed.
I think your multizoom issue is fixed too ;)