Delayed Image Load with DataGrid

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

dave_probertGA6e24
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 328
Joined: Mon Dec 05, 2011 5:34 pm
Location: Thailand
Contact:

Delayed Image Load with DataGrid

Post by dave_probertGA6e24 » Mon Nov 12, 2012 11:31 am

Hi All,

First - background, then question.

I have a DataGrid which is populated with dynamic data pulled from a web server (PHP accessing MySQL). This works nicely.

But if I also include image URL's for little preview thumbnails (100x75) for each row of the Datagrid, then I get a huge slowdown for showing the data. This is because the images have to be fully downloaded as each Row is constructed so they can be displayed. Also, if an image is missing at the URL then LC will either Hang or Crash!!!

To get around these points I would like to use the "Load" command to pre-load the image URL's into cache and then I know they are there (or not) and don't need to wait for them to download before displaying the text part of the DataGrid.

Now, the question...

How can I send a custom message to a specific row of the DataGrid? i.e.. I have created a custom handler in the behaviour script for the row, but I can't figure out from the Docs how to actually do a simple "send" to a specific row of the grid.

I know this should be simple, but it's got me stumped ;)

I have determined the row index via the dgDataOfIndex array, but there doesn't seem to be any way of associating that with a way of calling the row group.

Can anyone help?

I hope the above makes sense, if not then I can try and clarify.

Cheers,
Dave
Coding in the Sun - So much Fun.
Visit http://electronic-apps.info for released App information.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Delayed Image Load with DataGrid

Post by sturgis » Mon Nov 12, 2012 5:07 pm

Probably not the best method, but I just did a test.

I set up a datagrid with ONLY images, modified the behavior as follows:

Code: Select all

on FillInData pDataArray
   -- This message is sent when the Data Grid needs to populate
   -- this template with the data from a record. pDataArray is an
   -- an array containing the records data.
   -- You do not need to resize any of your template's controls in
   -- this message. All resizing should be handled in resizeControl.
   
   -- Example:
   if pDataArray["img"] is among the lines of the cachedUrls then -- if its cached, show it
      put URL pDataArray["img"] into img 1 of me
   else
      put image id 1033 into image 1 of me -- otherwise put in a placeholder image
      put the dgindex of me into tIndex --grab the index
      load pDataArray["img"] with message ("refreshdg" && tIndex) -- load and call "refreshdg" which is a handler on the card
   end if
end FillInData
The handler on the card is as follows:

Code: Select all

command refreshdg pIndex
   put word 1 of pIndex into tIndex -- the index and url are both in the passed parameter, grab the index which is the first word
   get the dgDataOfIndex[tIndex] of group 1  -- get the data from the index
   set the dgDataOfIndex [tIndex] of group 1 to it -- then pop it right back in, no changes needed.
end refreshdg
From my quick tests it seems to work fine. You'll probably want to handle failures of course but as a bare minimum this seems to work ok.


EDIT:
Just realized that it is probably better to reference the url rather than shoving the data directly into the image so you might change this:

Code: Select all

put URL pDataArray["img"] into img 1 of me
to this:

Code: Select all

set the filename of image 1 of me to pDataArray["img"]

dave_probertGA6e24
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 328
Joined: Mon Dec 05, 2011 5:34 pm
Location: Thailand
Contact:

Re: Delayed Image Load with DataGrid

Post by dave_probertGA6e24 » Tue Nov 13, 2012 7:28 pm

Thanks for that Sturgis,

Your version did things in a slightly different way than I was attempting, but your's didn't require a send to the row - much better.

After a bit of fiddling around I managed to get it working in the context of what I was doing and it's all good now.

Either route for the image seems to work - I'm going with the image data - mainly because it's already written that way and works ok.

The only thing that is strange (not your code as such) is that the pIndex parameter to the refreshdg command only seems to get the index and the URL - the Status is not there - which is a shame. Otherwise that would save having to check if the URL has an error via a call to URLStatus. But it's not a major problem, just another strangeness with LC ;) :)

Thanks again for that.

Dave
Coding in the Sun - So much Fun.
Visit http://electronic-apps.info for released App information.

JosepM
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 344
Joined: Tue Jul 20, 2010 12:40 pm

Re: Delayed Image Load with DataGrid

Post by JosepM » Fri Jul 04, 2014 6:30 pm

Hi,

I'm on the same problem loading images from an URL into an image into a datagrid. I followed the code but all the images are loaded on the first row only.
Any idea about where is the problem?
I don't know if the cachedurls is available on Android and iOS.

Seems like all the images are loaded into the same image on the first row. :(

Salut,
Josep

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Delayed Image Load with DataGrid

Post by Klaus » Fri Jul 04, 2014 7:13 pm

Hi Josep,

please post your script(s), thanks.


Best

Klaus

JosepM
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 344
Joined: Tue Jul 20, 2010 12:40 pm

Re: Delayed Image Load with DataGrid

Post by JosepM » Fri Jul 04, 2014 7:29 pm

Code: Select all

on FillInData pDataArray

   
   set the text of field "Label" of me to pDataArray["label 4"]
   set the text of field "Label2" of me to pDataArray["label 2"]
   set the text of field "Label3" of me to pDataArray["label 5"]
   
   if tURL is among the lines of the cachedUrls then -- if is cached show it
      
      if the URLStatus of tURL is not "error" then
         set the filename of img "f_image" to tURL
      end if
      
   else
      put img "NoImage" into img "f_image" -- otherwise put in a placeholder image
      put the dgindex of me into tIndex --grab the index
      put "http://www.xxxxxx.com/tienda/img/p/"&pDataArray["label 2"]&"-"&pDataArray["label 5"]&"-home.jpg" into tURL
      
      load URL tURL with message ("refreshdg" && tIndex) --load and call "refreshdg" which is a handler on the card
   end if
   
end FillInData

Code: Select all

command refreshdg pIndex
   put word 1 of pIndex into tIndex -- the index and url are both in the passed parameter, grab the index which is the first word
   get the dgDataOfIndex[tIndex] of group "DataGrid1"
   set the dgDataOfIndex [tIndex] of group "DataGrid1" to it -- then pop it right back in, no changes needed.
end refreshdg
With this version is loaded the placeholder image each 5 rows. The visibles rows 4 rows.

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Delayed Image Load with DataGrid

Post by Klaus » Fri Jul 04, 2014 7:56 pm

Hi Josep,

in your first script "FillinData" tUrl is not filled witj content:

Code: Select all

on FillInData pDataArray
   set the text of field "Label" of me to pDataArray["label 4"]
   set the text of field "Label2" of me to pDataArray["label 2"]
   set the text of field "Label3" of me to pDataArray["label 5"]
   
   ## ???
   if tURL is among the lines of the cachedUrls then -- if is cached show it
...
and it looks like you cannot pass a parameter with the "callback" message!
From the dictionary about "send":
...
The callbackMessage is sent to the object whose script contains the load command, after the URL is loaded,
so you can handle the callbackMessage to perform any tasks you want to delay until the URL has been cached.
Two parameters are sent with the message: the URL and the URLStatus of the file.
...
So YOUR parameter will be overwritten, I'm afraid.


Best

Klaus

JosepM
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 344
Joined: Tue Jul 20, 2010 12:40 pm

Re: Delayed Image Load with DataGrid

Post by JosepM » Fri Jul 04, 2014 8:19 pm

Hi Klaus,

I understand but I don't see how add the parameter. :oops:

load URL tURL with message ("refreshdg" && tURL && pStatus && tIndex) ??

Salut,
Josep M

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Delayed Image Load with DataGrid

Post by Klaus » Fri Jul 04, 2014 8:36 pm

Hi Josep,

you can't!

Livecode will automaticaly add the URL and STATUS parameters to your message
and your parameter will be treated as non-existent!

Maybe you can store pairs of URL (= key) and INDEX (= content of key) in an array first***,
store it in a custom property and use it later in the "refreshdg" handler?
Just a quick thought...

***Maybe in the handler that turns the database records into the array for the datagrid.


Best

Klaus

JosepM
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 344
Joined: Tue Jul 20, 2010 12:40 pm

Re: Delayed Image Load with DataGrid

Post by JosepM » Fri Jul 04, 2014 8:50 pm

I see. Yes, I can get the URL from the database query and use like the original code of the post, isn't?
Inside the callbackmessage how I can get the status of the URL

load URL tURL with message ("refreshdg" && tURL && tStatus) ?? To handle if any error exist with the images...

Thanks for your help Klaus.

Salut,
Josep-M

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Delayed Image Load with DataGrid

Post by Klaus » Fri Jul 04, 2014 9:29 pm

Hi Josep,
JosepM wrote:I see. Yes, I can get the URL from the database query and use like the original code of the post, isn't?
Inside the callbackmessage how I can get the status of the URL
I mean something like this:
1. when creating the array for the datagrid, store a list of URL/INDEX pairs separated by TAB in a variable or custom property:
http://www.... TAB 1
htttp://www... TAB 2
etc...

2. Then use this list to lookup the INDEX for the given URL, see below!, to update the correct index.
Know what I mean? Use lineoffest with the url to find the appropriate index.
JosepM wrote:load URL tURL with message "refreshdg"
WITHOUT -> tURL && tStatus!!!!
These parameters will be added dynamycally by Livecode!


Best

Klaus

JosepM
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 344
Joined: Tue Jul 20, 2010 12:40 pm

Re: Delayed Image Load with DataGrid

Post by JosepM » Sun Jul 06, 2014 3:24 pm

Hi Klaus,

Code: Select all

command refreshDg pIndex
   put word 1 of pIndex into tIndex -- the index and url are both in the passed parameter, grab the index which is the first word
   get the dgDataOfIndex[tIndex] of group "DataGrid1" 
   put it into tData
   put 1 into tData["Label 1"]
   --answer "Refresh" && pIndex
   set the dgDataOfIndex [tIndex] of group "DataGrid1" to tData -- then pop it right back in, no changes needed.
end refreshDg

Code: Select all

on FillInData pDataArray
   set the text of field "Label" of me to pDataArray["label 4"]
   set the text of field "Label2" of me to pDataArray["label 3"]
   set the text of field "Label3" of me to pDataArray["label 5"]
   
   if pDataArray["Label 1"] is 1 then
      put URL pDataArray["label 6"] into img "f_image" of me
   else
      put img "NoImage" into img "f_image" of me -- otherwise put in a placeholder image
      put the dgindex of me into tIndex --grab the index
      load URL pDataArray["label 6"] with message ("refreshDg" && tIndex) --load and call "refreshdg" which is a handler on the card   
   end if
end on FillInData
Really adding the tIndex parameter to the message works, on desktop almost.

This code on desktop works fine, but on the device all the images have the placeholder image and any is updated.
Any idea why?

Salut,
Josep M

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Delayed Image Load with DataGrid

Post by Klaus » Sun Jul 06, 2014 4:04 pm

Hi Josep,

I tried to tell you all the time that, according to the dictionary, you CANNOT pass any OWN parameter to the callback message! 8)
So why not create a "lookup table" that will definitively work, as I proposed in my last post?


Best

Klaus

JosepM
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 344
Joined: Tue Jul 20, 2010 12:40 pm

Re: Delayed Image Load with DataGrid

Post by JosepM » Sun Jul 06, 2014 4:20 pm

Hi Klaus,

I know I know, but try the stack please. The param is working, or only work for desktop ?
The callback message received after a load url is of the form:
myUrlDownloadFinished url, status, data

Here, data is the actual content of the url that was fetched (assuming an error didn’t occur).
http://livecode.com/developers/guides/m ... -features/

Attach my stack to try :oops:
Attachments
s_main_prestaboard_android.livecode.zip
(55.6 KiB) Downloaded 170 times

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Delayed Image Load with DataGrid

Post by Klaus » Sun Jul 06, 2014 4:37 pm

Hi Josep,
JosepM wrote: The param is working, or only work for desktop?
maybe, but this is not officially suipported, so why tempt your fate? :D
JosepM wrote:
The callback message received after a load url is of the form:
myUrlDownloadFinished url, status, data
Here, data is the actual content of the url that was fetched (assuming an error didn’t occur).
Yes, but "data" does not contain your "dgindex", but rather the image FILE itself in your case!



Best

Klaus

Post Reply

Return to “Talking LiveCode”