3 questions for APPs (related to tables)

Started by sinus, May 20, 2015, 05:42:08 PM

Previous topic - Next topic

sinus

Hi all
I have two sets of Attributes.
Because displaying Attributes is fine with an App, I created one, as you can see in the Attachement.

But I do not have a lot of knowledge doing so.
Hence I have some questions for Javascript.

1) if a table is empty, in my App the table does appears empty. Is there a way to simply NOT display the table, when there is no entry?

2) For some fields, like KM (Kilometer) or currency (CHF), I created some lines like this:

<td><strong> - {File.AT.Verrechnung.Rabatt} % </strong></td>

If the field has an entry, the display is fine, for example: 8.5 %
But if the field is empty, I get the display like this: %

and this is not very good.
Is there a way to prevent this?

3) Is there an easy way to show also the selected image (say a thumb) in the app? I guess, this is not possible or VERY complicated.

See my attachement, and this is my code so far:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us"  xml:lang="en-us">

<head>
<!-- DO NOT USE TIDY ON THIS PAGE -->
    <!--
This is a mandatory entry for simple HTML app
IMatch sets the local path of the HTML document at runtime
and all links on the page use the base path set by IMatch.
{base} is replaces with the fully qualified folder name.
    -->
    <base href="{base}"/>


<!-- Force support of HTML 5 in WebBrowser Control!  -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<!-- Include the IMatch JavaScript library -->
<script src="../../lib/imatch_app.js" type="text/javascript"></script>

<!-- Always use UTF-8 encoding for best results in IMatch -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<!-- Use the template.css or your own style sheet -->
<link rel="stylesheet" type="text/css" media="screen" href="styles.css">

<title>sinus-Attributes</title>
</head>
<body>

<table>
<table class="att-table">
<div class="attribute">

</br>

<caption><titel>Wichtige Felder von beiden Sets</titel></caption>

<tr> <th>Anmerkungen</th>
  <th>Verr-Daten</th>
<th>erledigen</th>
  <th>verrechnen</th></tr>

<tr> <td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.Et|replace:No==nein; replace:Yes==JA} </strong></td>
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Verrechnung.Et|replace:No==nein; replace:Yes==JA}</strong></td>
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.Ze|replace:No==no/erledigt; replace:Yes==JA}</strong></td>                     
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.Zv|replace:No==nein; replace:Yes==JA !}</strong></tr>









<tr> <th>Eintrag-Dat</th>
  <th>RG-Datum</th>
<th>OK erledigt</th>
  <th>verrechnet</th></tr>


<tr> <td><strong>{File.AT.Anmerkungen.Dat}</strong></td>
<td><strong>{File.AT.Verrechnung.RG-Dat}</strong></td>
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.OK|replace:No==nein; replace:Yes==JA}
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.RG-norm|cast:int;is:0,;is:1,RG-norm}<strong>{File.AT.Anmerkungen.RG-Arc|cast:int;is:0,;is:1,RG-Arc}<strong>{File.AT.Anmerkungen.Gratis|cast:int;is:0,;is:1,Gratis} </td></tr>

</div>
</table>



<table>
<table class="att-table">
<div class="attribute">

</br>

<caption><titel>wichtige Anmerkungen</caption>

<tr> <th colspan="4">Allgemeine Anmerkungen</th></tr>

<tr> <td colspan="4"><strong>{File.AT.Anmerkungen.Allgemein}</strong></td></tr>

<tr>
<th colspan="2">Zuständig Kunde</th>
                 <th colspan="2">Zuständig vor Ort</th></tr>

<tr> <td colspan="2"><strong>{File.AT.Anmerkungen.Kunde.Firma}, {File.AT.Anmerkungen.Kunde.Vorname}, {File.AT.Anmerkungen.Kunde.Nachname}, {File.AT.Anmerkungen.Kunde.Duzis|replace:No==SIE; replace:Yes==DU}</strong></td> 
<td colspan="2"><strong>{File.AT.Anmerkungen.Bezug}</strong></td> </tr>



<tr> <th colspan="2">Fotos senden</th>
                 <th colspan="2">Person war</th></tr>

<tr> <td colspan="2"><strong>{File.AT.Anmerkungen.will Fotos}</strong></td> 
<td colspan="2"><strong>{File.AT.Anmerkungen.Person}</strong></td> </tr>

<tr> <th colspan="2">Erhalten</th>
                 <th colspan="2">Adresse</th></tr>

<tr> <td colspan="2"><strong>{File.AT.Anmerkungen.Erhalten}</strong></td> 
<td colspan="2"><strong>{File.AT.Anmerkungen.Adresse}</strong></td> </tr>


<tr> <th>Geliefert</th>
<th>link</th>
                 <th colspan="2">Tel/mail</th></tr>


<tr> <td><strong>{File.AT.Anmerkungen.Geliefert}</strong></td>   
<td><strong>{File.AT.Anmerkungen.link}</strong></td>
<td colspan="2"><strong>{File.AT.Anmerkungen.Tel/mail}</strong></td> </tr>


<tr> <th colspan="4">RG-Infos</th></tr>

<tr> <td colspan="4"><strong>{File.AT.Anmerkungen.RG-Infos}</strong></td></tr>


</div>
</table>



<table>
<table class="att-table">
<div class="attribute">
</br>

<caption><titel>wichtig für Verrechnung</caption>


<tr> <th colspan="4">Verrechnen an</th> </tr>



<tr> <td colspan="4"><strong>{File.AT.Verrechnung.Kunde.Firma}, {File.AT.Verrechnung.Kunde.Vorname} {File.AT.Verrechnung.Kunde.Name}, {File.AT.Verrechnung.Kunde.Ort}</strong></td> </tr>


<tr> <th>RG-Datum</th>
<th>RG normal</th>
  <th>RG Archiv</th>
<th>Kostenlos</th></tr>

<tr> <td><strong>{File.AT.Verrechnung.RG-Dat}</strong></td>
<td><strong>{File.AT.Anmerkungen.RG-norm|replace:No==nein; replace:Yes==JA}</strong></td>
<td><strong>{File.AT.Anmerkungen.RG-Arc|replace:No==nein; replace:Yes==JA}</strong></td>
<td><strong>{File.AT.Anmerkungen.Gratis|replace:No==nein; replace:Yes==JA}</strong></td></tr>


<tr> <th>LS-Datum</th>
  <th>LS-Nummer</th>
<th>RG-Nummer</th>
<th>Geliefert</th></tr>

<tr> <td><strong>{File.AT.Verrechnung.LS-Dat}</strong></td>
<td><strong>{File.AT.Verrechnung.LS-Nr}</strong></td>
<td><strong>{File.AT.Verrechnung.RG-Nr}</strong></td>
<td><strong>{File.AT.Verrechnung.Deliv}</strong></td></tr>


<tr> <td colspan="4"><strong>{File.AT.Verrechnung.RgText}</strong></td></tr>


<tr> 
<td><strong>{File.AT.Verrechnung.Anzahl Einh}</strong></td>
<td><strong>{File.AT.Verrechnung.Einheit}</strong></td>
<td><strong>je {File.AT.Verrechnung.zu je}</strong></td>
<td style="text-align: right; background-color:#FF8C8C;"><strong>{File.AT.Verrechnung.Total-1}</strong></td></tr>


<tr> <td><strong>{File.AT.Verrechnung.Anzahl KM} KM</strong></td>
<td><strong>je {File.AT.Verrechnung.pro KM}</strong></td>
<td style="text-align: right; background-color:#FFDFDF;"><strong> + {File.AT.Verrechnung.KM-total|hasvalue:{File.AT.Verrechnung.KM-total};default:{File.AT.Verrechnung.KM-pausch}}</strong></td> </tr>


<tr> <td colspan="2"><strong>{File.AT.Verrechnung.Spesentext}</strong></td>
<td style="text-align: right; background-color:#FFDFDF;"><strong> + {File.AT.Verrechnung.Spesen}</strong></td></tr>


<tr> <td><strong>Verpackung</strong></td>
<td></td>
<td style="text-align: right; background-color:#FFDFDF;"><strong> + {File.AT.Verrechnung.VP}</strong></td>
<td style="text-align: right; background-color:#FF8C8C;"><strong>{File.AT.Verrechnung.Total-2}</strong></td></tr>


<tr> <td><strong> - {File.AT.Verrechnung.Rabatt} % </strong></td>
<td>Rabatt</td>
<td style="text-align: right; background-color:#9BFFFF;"><strong> - {File.AT.Verrechnung.Rabattbetrag}</strong></td>
<td style="text-align: right; background-color:#FF8C8C;"><strong>{File.AT.Verrechnung.Zw-Total}</strong></td><tr>


<tr> <td><strong> + {File.AT.Verrechnung.MWST} %</strong></td>
<td>MwSt</td>
<td style="text-align: right; background-color:#FFDFDF;"><strong>+ {File.AT.Verrechnung.Mwst-Betr} </strong></td>
<td style="text-align: right; background-color:#FF5959;"><wichtig>{File.AT.Verrechnung.TOTAL}</strong></td></tr>

</div>
</table>


</body>
</html>





[attachment deleted by admin]
Best wishes from Switzerland! :-)
Markus

Mario

1. The easiest way would be to hide your table via JavaScript (set the display attribute to none of the table).
Or, create you table dynamically via JavaScript at runtime, but only when the file has attributes. See, for example, the Report App or MP3 Player app.

2. Don't add the % to your HTML. Instead add it to your variable, as a postfix. This way % is not emitted when the variable is empty.

3. See the MP player for an example on how to retrieve the thumbnail and display it in HTML. It uses a neat trick to do this without temporary image files on disk.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Hey Mario

cool, thanks a lot for your QUICK answer and the best of all:

I think, I could manage this with your good "link" to other sources. At the beginning I have not understood the difference between scripts and Apps, now I begin slowly to understand  :D
Best wishes from Switzerland! :-)
Markus

sinus

#3
Quote from: Mario on May 20, 2015, 06:04:37 PM

3. See the MP player for an example on how to retrieve the thumbnail and display it in HTML. It uses a neat trick to do this without temporary image files on disk.

Hi Mario
I tried to bring a thumb into an  App.
For this I looked into your mp3-app.

It brings the cache-files into the app, if no chache-files are there, it shows nothing.

These are the lines of your htm:

<script type="text/javascript">
       
        function onLoad() {
            renderRating({File.Rating|cast:int});

            // If we have a label color, fill the div with the stars
            if ('{File.LabelColor}' != '') {
                document.getElementById("rating").style.backgroundColor = '{File.LabelColor}';
            }

    // If we have no cache image, we hide it
            var pelement = document.getElementById("cover");
            if ('{File.CacheFileName}' == '') {
            pelement.style.display = "none";
            }
            else {
            pelement.style.display = "block";
}
    }


I tried this in my app and it works!  :)
But I have one problem, what is in fact, I guess, a small problem.  :-[

If I do this with a nef-file, this has no cache, hence it will be displayed. (display = "block")

But a jpg has usually no chache, hence the result will be "display = "none" and the image will not be displayed.

I tried several things, either the jpg works or the raw, but not both.

The important lines are also these, I think:


[code] <div id="cover" style="display:none;"><img class="coverfull" src="{File.FullName}" alt="Foto zum verrechnen" width="220" title="Foto zum verrechnen" /></div>

        <div id="cover" style="display:none;"><img class="cover" src="file://{File.CacheFileName}" alt="Foto zum verrechnen" width="220" title="Foto zum verrechnen" /></div>


The first line creates the real file (when there is not a cache-file), the second line the cache-file.[/code]

The jpg-file I can create (see attachement), fine, or with a change in the line I can get the cache-file.

But I am not able, that I can see both, either

-a thumb for a jpg (in this case there is no cache, the file will be used)
or
-a raw, with its cache

Background: I try to see simply a thumb in the app, when I select on a nef or on a jpg.
I am sure, this is not a big deal to code it proper, but ...  :-\ :-[ grrrrr.... ok, in some weeks/monthes I am maybe able (hopefully)

(sorry for my chaos, hence in German: wenn ich auf ein nef klicke, sollte ein thumb in der app erscheinen, und auch, wenn ich auf ein jpg klicke. Einmal wird das chache-Bild genommen, das andere mal das jpg selbst).



or

[attachment deleted by admin]
Best wishes from Switzerland! :-)
Markus

JohnZeman

Marcus I'm on a short lunch break right now so I haven't had time to study your issue but if it helps you any I think I'm hiding one or more table rows in my collapsible metadata viewer app if the active image does not contain GPS coordinates.

Mario

Check out the 'Tiles' app:

C:\ProgramData\photools.com\IMatch5\apppanel\system\tiles\tiles.htm

The function loadTile loads a thumbnail from the bitmap, converts it into a base64 string and then sets this as the src for an image. It also resizes the thumbnail if needed etc. but the general idea is to use

var srcimg = IMatchLib.database().GetThumbnailImage(file);

and then

var url = "data:image/jpeg;base64," + srcimg.SaveBase64(IMatchLib.IMImageSaveFormat.imsfJPEG24Standard);

someimage.attr("src", url);


The trick to encode the binary image data into a Base64 string and then using that as the src= attribute for an <image> tag allows this to work without accessing images on disk or using tempoary files. Very neat.

-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Hi John and Mario
Thanks both for your answer.

To be honest: I looked and tried both of your ideas - but without success.
I must see myself, for this my understanding of Javascript (and also html/css) is simply not enough good, specialy with Javascript I am standing at the very beginning.

But for me that is at the moment fine.
I have managed to get it work, when I click on jpgs, and that is the case for 95%, because I do fill out Attributes mostly for jpgs.

You can see that in Attachement 1, looks fine for me.

When I click on a raw (nef), what has a cache-file, then it works not, you can see that in attachement 2.

I think, the solution lies in these lines of Javascript an html, what I have picked up from Mario's mp3-app.
In the mp3-app, Mario counts "only" with files with cache. If there is a cache, then display it, if not, hide it.

Javascript:
            if ('{File.LabelColor}' != '') {
                document.getElementById("rating").style.backgroundColor = '{File.LabelColor}';
            }
    // If we have no cache image, we hide it
            var pelement = document.getElementById("cover");
            if ('{File.CacheFileName}' == '') {
            pelement.style.display = "none";
            }
            else {
            pelement.style.display = "block";


html:
<div id="cover" style="display:none;"><img class="coverfull" src="{File.FullName}" alt="Foto zum verrechnen" width="220" title="Foto zum verrechnen" /></div>

        <div id="cover" style="display:none;"><img class="cover" src="file://{File.CacheFileName}" alt="Foto zum verrechnen" width="220" title="Foto zum verrechnen" /></div>


But for the moment that is fine for me, no problem for me, I wanted only to "say it".  ;D

Thanks for your help - and John, your app is really great!

Oh, Mario, yes, and your tip with prefix and postfix works fine, thanks!

[attachment deleted by admin]
Best wishes from Switzerland! :-)
Markus

Mario

My tip should just work. Did you try the tiles app?
Since it loads the thumbnail from the database, it is independent from cache files entirely. IMatch has a thumbnail for all files (except files for which it cannot create a thumbnail).
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Quote from: Mario on May 28, 2015, 10:58:22 AM
My tip should just work. Did you try the tiles app?
Since it loads the thumbnail from the database, it is independent from cache files entirely. IMatch has a thumbnail for all files (except files for which it cannot create a thumbnail).

Yes, of course I tried it. But I could not see, how to implement the lines correct into my lines.
But this afternoon I will try again, maybe I have more luck in the second half of the day.

Btw, the tiles-app is very nice!
Best wishes from Switzerland! :-)
Markus

Mario

Load the thumbnail and produce the special url as shown.
The assign the string to your src= attribute, like you would assign something like "file://c:/images/foo.jpg".
Usually you do that via JavaScript as in the tiles app, changing the src attribute to use the new url you have created from the thumbnail.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Thanks a lot, Mario!
Sorry, that I have wasted your time, I think, it is simply over my possibilities at the moment. I have delete all other lines now from my code, so that the app basically only load the thumb.
As I have written,  it works for jpg (what have no cache), but it works not for nefs (with cache).

Then I have tried this and that, to take lines of your tiles-app, but without success, errors after errors. But this is  no wonder, because I do simply not know, what I do, because I have not the knowledge, what is essentiell, I think.

Your help is for sure helpful and very good, but not for me as a javascript-beginner, I could even not follow your simple steps.

My current short code is this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us"  xml:lang="en-us">

<head>
<!-- DO NOT USE TIDY ON THIS PAGE -->

<base href="{base}"/>

<!-- Force support of HTML 5 in WebBrowser Control!  -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<!-- Include the IMatch JavaScript library -->
<script src="../../lib/imatch_app.js" type="text/javascript"></script>

<!-- Always use UTF-8 encoding for best results in IMatch -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<!-- Use the template.css or your own style sheet -->
<link rel="stylesheet" type="text/css" media="screen" href="styles.css">


   <script type="text/javascript">
       
        function onLoad() {

    // If we have no cache image, we hide it
            var pelement = document.getElementById("cover");
                 
if ('{File.CacheFileName}' == '') { // wenn KEIN Cache vorhanden ist, (betrifft also jpgs) dann
            pelement.style.display = "block";
            }
            else { // sonst hat es ein Cache, betrifft also nefs
            pelement.style.display = "block";
}
    }
   
    </script>

</head>
<body onload="onLoad();">

</br>
<div id="cover" style="display:none;"><img class="cover" src="{File.FullName}" alt="echtes file" width="200" title="Foto zum verrechnen" /></div>
<div id="cover" style="display:none;"><img class="cover" src="file://{File.CacheFileName}" alt="cache-file" width="120" title="Foto zum verrechnen" /></div> 

</body>
</html>


and it works at least for jpgs!  :D

Sorry, Mario, forget this post, you have better things to do! But thanks really for your help.
For the moment this, what I have, is enough good for me,.  8)
Best wishes from Switzerland! :-)
Markus

thrinn

Hi Markus,
first, you use the same id attribute for both of your divs. The id should be unique (it is used to identify an element, after all). For example, use "cover_file" for the first div, "cover_cache" for the second.
<div id="cover_file" style="display:none;"><img class="cover" src="{File.FullName}" alt="echtes file" width="200" title="Foto zum verrechnen" /></div>
<div id="cover_cache" style="display:none;"><img class="cover" src="file://{File.CacheFileName}" alt="cache-file" width="120" title="Foto zum verrechnen" /></div> 


Second, in your function get both of your divs in different variables. And get the focused file to work with.
Third, I don't think using a variable name just in a string will work. Use the parseVariables function of IMatchLib on it.

// If we have no cache image, we hide it
var pelem_1 = document.getElementById("cover_file");
var pelem_2 = document.getElementById("cover_cache");
var file = IMatchLib.focusedFile();
if (IMatchLib.parseVariables(file, '{File.CacheFileName}') == '') { // wenn KEIN Cache vorhanden ist, (betrifft also jpgs) dann
  pelem_1.style.display = "block";
  pelem_2.style.display = "none";
} else { // sonst hat es ein Cache, betrifft also nefs
  pelem_1.style.display = "none";
  pelem_2.style.display = "block";
}


Let me know if this works for you.
Thorsten
Win 10 / 64, IMatch 2018, IMA

sinus

Hey Thorsten
Thanks a lot for your input!
And specialy thanks for your explanations, I think, I have understood them.   :D

I took now both of your lines and replaced them with my old lines.

I wondered, no error.
But unfortunately it works like before:

- the nef does not display (attachement 1)
- the jpg works perfectly (attachement 2)

I assured also, that there is finally a cached image, and yes, it is there.


[attachment deleted by admin]
Best wishes from Switzerland! :-)
Markus

Mario

If you have that somewhere in your code


<div id="cover_file"><img class="cover" src="#" alt="echtes file" width="200" title="Foto zum verrechnen" /></div>


You can do this in the onLoad


var srcimg = IMatchLib.database().GetThumbnailImage(file);
if (srcimg) {
document.getElementById("#cover").src = "data:image/jpeg;base64," + srcimg.SaveBase64(IMatchLib.IMImageSaveFormat.imsfJPEG24Standard);
}
else {
// No thumbnail. Maybe hide the div with the image or load a standard image from disk using file://...
}



This loads the thumbnail for 'file', creates a data url on-the-fly and sets this as the src for the <img> with the id 'cover'.


-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Curious (at least for me  :-[)

These lines, taken and shortend, from the IMatch-MP3-app, works fine for cached images.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us"  xml:lang="en-us">
<head>
<!-- Force support of HTML 5 in WebBrowser Control!  -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <!--
        This is a mandatory entry. IMatch sets the local path of the HTML document at runtime
        and all links on the page use the base path set by IMatch.
        {base} is replaces with the fully qualified folder name.
    -->
    <base href="{base}"/>

    <!-- Always use UTF-8 encoding for best results in IMatch -->
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
   
    <!-- Use the template.css or your own style sheet -->
    <link rel="stylesheet" type="text/css" href="mp3.css" />

    <title>File Fact Sheet</title>

    <script type="text/javascript">
       
        function onLoad() {
             // If we have no cache image, we hide it
            var pelement = document.getElementById("cover");
            if ('{File.CacheFileName}' == '') {
            pelement.style.display = "none";
            }
            else {
            pelement.style.display = "block";
}
        }
    </script>

</head>
<body onload="onLoad();">
    </div>
    <div id="cover" style="display:none;"><img class="cover" src="file://{File.CacheFileName}" alt="Cover Image" width="200" title="Cover Image" /></div>

<div id="hint">Also check out the IMatch <b>MP3 Player App</b>. Right here in this panel!</div>
</body>
</html>
Best wishes from Switzerland! :-)
Markus

Mario

I'm not sure about what you want to tell us.
There are Apps and HTML templates. I guess you have create a template, not an App.
A HTML template is automatically processed by IMatch, all variables are replaced by their values.
See the IMatch help for the difference between a HTML template (easy to start, but limited) and Apps (almost limitless).
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Thanks Mario, Thorsten and John

I managend now, that the App is running (Mario, it is an App) and a thumb will be displayed, if the image has a cache (raw) or not (jpg).

So my problem is solved!  :D
Best wishes from Switzerland! :-)
Markus

Mario

If you use variables in your HTML, and these are automatically parsed without you explicitly calling the ParseVariables method, you are using a HTML template, not an App.

If you just use something like <image src="file://{File.FullName}...  it will work, but the browser will have to load the original image or cache file and then scale it down to whatever thumbnail size you use. And that every time you make a change in the file window and the HTML panel is updated. This is real bad for performance and will probably slow down IMatch considerably. I strongly suggest that you don't do this and instead use the method to load the thumbnail from the database "in-memory" I have shown you above. This will display a thumbnail for all files, and not impact performance at all.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Thanks, Mario, for your very interesting input.

I am sure, you are right, but until now I tried and tried with your suggestion, but without sucess.
But now I have a solution, what works fine ... but as you pointed out, it is the wrong direction.

So I will now patiently try to do the same with your suggestion, after all, I am lerning on this way something, step by step.  ;D

As you can see in my attachement, this is it, how it is working now (with the image).
But I will now try to add your (better) solution. One time (einmal) it will work, I think.

... I am on the lerning curve for JavaScript, CSS and html ... but of course only a bit.

[attachment deleted by admin]
Best wishes from Switzerland! :-)
Markus

sinus

At the moment I am here, without success, but to be honest, I do not really know, what I am doing.  :-\ :-[ :-[

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us"  xml:lang="en-us">

<head>
<!-- DO NOT USE TIDY ON THIS PAGE -->

    <base href="{base}"/>

<!-- Force support of HTML 5 in WebBrowser Control!  -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<!-- Include the IMatch JavaScript library -->
<script src="../../lib/imatch_app.js" type="text/javascript"></script>

<!-- Always use UTF-8 encoding for best results in IMatch -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<!-- Use the template.css or your own style sheet -->
<link rel="stylesheet" type="text/css" media="screen" href="styles.css">

   <script type="text/javascript">
       
// We load the database files only once!
databaseFiles = IMatchLib.database().Files();{

function loadTile(tileIndex, file, skipAnimation) {

//IMatchLib.debugPrint(file.FileName+"\n");
clearTimeout(timeoutId);

// Get the thumbnail for the file from the database
var srcimg = IMatchLib.database().GetThumbnailImage(file);

// We produce an URL from a Base64-encoded representation of the thumbnail.
// This is *awesome* because we don't need temporary files or anything. The IE directly uses the JPEG
// representation of the thumbnail! IMatch is kewl ;-)
var url = "data:image/jpeg;base64," + img.SaveBase64(IMatchLib.IMImageSaveFormat.imsfJPEG24Standard);
}
}
 
    </script>
</head>
<body>

<div id="hint" style="display:block;"><img src=url</div>
</body>
</html>
Best wishes from Switzerland! :-)
Markus

thrinn

Hi Markus,
I am a bit confused at the moment: Do you try to create an App or an HTML template? I am asking because there are syntactical differences (using variables directly in HTML templates vs. using ParseVariables in an App, for example) how you do some things. You said you created an App, but the following code looks like having been copied from a template:
<base href="{base}"/>

    Templates are easier, but Apps are much more powerful, as Mario pointed out.

    In the coding you posted last, there are a number of things I do not quite understand:

    • You declare a function loadTile, but I can't see it is ever called.
    • You assign a base64 encoded value to a Javascript variable url. But a variable is not linked automatically to something like src=url. So you have to set the src attribute to the value of the variable somehow.
    • Isn't there an extra opening curly brace in your databaseFiles = ... line?

    Maybe it becomes clearer when we know if we are talking about Apps or Templates.
Thorsten
Win 10 / 64, IMatch 2018, IMA

sinus

Hi Thorsten
Sorry for the confusion.

I am confused now myself, I do not know, do you (and Mario) call this an App or a html-template!?  :-\

At least the result will be displayed in the App-Panel see my Attachement 1.
There are mostly displayed fields of the selected thumb from the Attributes.
At the end is an image, with the name under the image.

This caused me a lot of problems, because I did not know, how can be displayed both, if I select a jpg (what has no cache) or if I select a raw (nef), what has a cache.
NOW with the code below I could manage, that it works now!
The actual code, what is in a html-file called "viewer.htm", together with two files, viewer.xml and styles.css.
These 3 files are in the apppanel-folder, in the subfolder "user".
So I do not know, is this an app or a htlm (or both).   :-[

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us"  xml:lang="en-us">

<head>
<!-- DO NOT USE TIDY ON THIS PAGE -->
    <!--
This is a mandatory entry for simple HTML app
IMatch sets the local path of the HTML document at runtime
and all links on the page use the base path set by IMatch.
{base} is replaces with the fully qualified folder name.
    -->
    <base href="{base}"/>

<!-- Force support of HTML 5 in WebBrowser Control!  -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<!-- Include the IMatch JavaScript library -->
<script src="../../lib/imatch_app.js" type="text/javascript"></script>

<!-- Always use UTF-8 encoding for best results in IMatch -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<!-- Use the template.css or your own style sheet -->
<link rel="stylesheet" type="text/css" media="screen" href="styles.css">

   <script type="text/javascript">
        function onLoad() {
                 
var pelem_1 = document.getElementById("cover_file");
var pelem_2 = document.getElementById("cover_cache");

// If we have no cache image, we hide it
          if ('{File.CacheFileName}' == '') {
  pelem_2.style.display = "none";
  pelem_1.style.display = "block";

}
       }
    </script>

<title>sinus-Attributes</title>
</head>
<body onload="onLoad();">

<table>
<table class="att-table">
<div class="attribute">
</br>

<caption><titel>Wichtigste Felder von beiden Sets</titel></caption>

<tr> <td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.Et|prefix:</strong>Infos: <strong>;|replace:No==nein; replace:Yes==JA} </strong></td>
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Verrechnung.Et|prefix:</strong>RG-Daten: <strong>;|replace:No==nein; replace:Yes==JA}</strong></td>
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.Ze|prefix:</strong>erledigen: <strong>;|replace:No==no/erledigt; replace:Yes==JA}</strong></td>                     
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.Zv|prefix:</strong>verrechnen: <strong>;|replace:No==nein; replace:Yes==JA}</strong></tr>

<tr> <td><strong>{File.AT.Anmerkungen.Dat}</strong></td>
<td><strong>{File.AT.Verrechnung.RG-Dat}</strong></td>
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.OK|prefix:</strong>erledigt: <strong>;|replace:No==nein; replace:Yes==JA}
<td style="text-align: center; background-color:#FFDFDF;"><strong>{File.AT.Anmerkungen.RG-norm|cast:int;is:0,;is:1,normal;prefix:</strong>RG: <strong>}<strong>{File.AT.Anmerkungen.RG-Arc|cast:int;is:0,;is:1,Archiv}<strong>{File.AT.Anmerkungen.Gratis|cast:int;is:0,;is:1,Gratis} </td></tr>
</div>
</table>

<table>
<table class="att-table">
<div class="attribute">
</br>
<caption><titel>Anmerkungen</caption>
<tr> <td colspan="4"><strong>{File.AT.Anmerkungen.Allgemein|prefix:</strong>Allgemein: <strong>}</td></tr>
<tr>

<tr> <td colspan="2"><strong>{File.AT.Anmerkungen.Kunde.Firma|prefix:</strong>Kunde: <strong>;postfix:, } {File.AT.Anmerkungen.Kunde.Vorname} {File.AT.Anmerkungen.Kunde.Nachname|postfix:, } {File.AT.Anmerkungen.Kunde.Duzis|replace:No==SIE; replace:Yes==DU}</strong></td> 
<td colspan="2"><strong>{File.AT.Anmerkungen.Bezug|prefix:</strong>vor Ort: <strong>}</strong></td> </tr>

<tr> <td colspan="2"><strong>{File.AT.Anmerkungen.will Fotos|prefix:</strong>senden: <strong>}</strong></td> 
<td colspan="2"><strong>{File.AT.Anmerkungen.Person|prefix:</strong>Person: <strong>}</strong></td> </tr>

<tr> <td colspan="2"><strong>{File.AT.Anmerkungen.Erhalten|prefix:</strong>erhalten: <strong>}</strong></td> 
<td colspan="2"><strong>{File.AT.Anmerkungen.Adresse}</strong></td> </tr>

<tr> <td><strong>{File.AT.Anmerkungen.Geliefert|prefix:</strong>geliefert: <strong>}</strong></td>   
<td><strong>{File.AT.Anmerkungen.link}</strong></td>
<td colspan="2"><strong>{File.AT.Anmerkungen.Tel/mail}</strong></td> </tr>

<tr> <td colspan="4"><strong>{File.AT.Anmerkungen.RG-Infos}</strong></td></tr>

</div>
</table>
<table>
<table class="att-table">
<div class="attribute">
</br>

<caption><titel>Verrechnung</caption>

<tr> <td colspan="4"><strong>{File.AT.Verrechnung.Kunde.Firma|postfix:, }{File.AT.Verrechnung.Kunde.Vorname} {File.AT.Verrechnung.Kunde.Name|postfix:, }{File.AT.Verrechnung.Kunde.Ort}</strong></td> </tr>

<tr> <td colspan="2"><strong>{File.AT.Verrechnung.RG-Dat|prefix:</strong>RG <strong>;postfix: / } {File.AT.Verrechnung.RG-Nr|prefix:</strong>Nr. <strong>}</strong></td>
<td colspan="2"><strong>{File.AT.Verrechnung.LS-Dat|prefix:</strong>LS <strong>;postfix: / } {File.AT.Verrechnung.LS-Nr|prefix:</strong>Nr. <strong>}</strong></td>
</tr>

<tr> <td colspan="3"><strong>{File.AT.Verrechnung.RgText}</strong></td>
<td><strong>{File.AT.Verrechnung.Deliv|prefix:geliefert }</strong></td></tr>

<tr> 
<td><strong>{File.AT.Verrechnung.Anzahl Einh}</strong></td>
<td><strong>{File.AT.Verrechnung.Einheit}</strong></td>
<td><strong>{File.AT.Verrechnung.zu je|prefix:zu je }</strong></td>
<td style="text-align: right; background-color:#FF8C8C;"><strong>{File.AT.Verrechnung.Total-1}</strong></td></tr>

<tr> <td><strong>{File.AT.Verrechnung.Anzahl KM|postfix: KM}</strong></td>
<td><strong>{File.AT.Verrechnung.pro KM|prefix:je }</strong></td>
<td style="text-align: right; background-color:#FFDFDF;"><strong>{File.AT.Verrechnung.KM-total|hasvalue:{File.AT.Verrechnung.KM-total|prefix:+ };default:{File.AT.Verrechnung.KM-pausch|prefix:+ }}</strong></td> </tr>

<tr> <td colspan="2"><strong>{File.AT.Verrechnung.Spesentext}</strong></td>
<td style="text-align: right; background-color:#FFDFDF;"><strong>{File.AT.Verrechnung.Spesen|prefix:+ }</strong></td></tr>

<tr> <td><strong>{File.AT.Verrechnung.VP|hasvalue:Verpackung;default: }</strong></td>
<td></td>
<td style="text-align: right; background-color:#FFDFDF;"><strong>{File.AT.Verrechnung.VP|prefix:+ }</strong></td>
<td style="text-align: right; background-color:#FF8C8C;"><strong>{File.AT.Verrechnung.Total-2}</strong></td></tr>

<tr> <td><strong>{File.AT.Verrechnung.Rabatt|postfix: % }</strong></td>
<td>{File.AT.Verrechnung.Rabatt|hasvalue:Rabatt;default: }</td>
<td style="text-align: right; background-color:#9BFFFF;"><strong>{File.AT.Verrechnung.Rabattbetrag|prefix:- }</strong></td>
<td style="text-align: right; background-color:#FF8C8C;"><strong>{File.AT.Verrechnung.Zw-Total}</strong></td><tr>

<tr> <td><strong>{File.AT.Verrechnung.MWST|postfix: % }</strong></td>
<td>{File.AT.Verrechnung.MWST|hasvalue:MwSt;default: }</td>
<td style="text-align: right; background-color:#FFDFDF;"><strong>{File.AT.Verrechnung.Mwst-Betr|prefix:+ }</strong></td>
<td style="text-align: right; background-color:#FF5959;"><wichtig>{File.AT.Verrechnung.TOTAL}</strong></td></tr>

</div>
</table>

</br>

       <div id="cover_cache" style="display:block;"><img class="cover" src="file://{File.CacheFileName}" alt="cache-file" height="200px" title="Foto zum verrechnen" /></div>
  <div id="cover_file" style="display:none;"><img class="cover" src="{File.FullName}" alt="echtes file" height="200px" title="Foto zum verrechnen" /></div>
</br>
<div id="hint">{File.Name}</div>
<div id="hint">Fotografiert am {File.Name|substr:6,2}.{File.Name|substr:4,2}.{File.Name|substr:2,2}</}</div>
 
</body>
</html>


Now, to end the story: Mario has pointed out, and he is absolutely correct, that this code, how I do display the image (as file-cache or as direct-file (jpg)), is slow and produces flickering and can slow down IMatch.
Mario wrote:
QuoteIf you use variables in your HTML, and these are automatically parsed without you explicitly calling the ParseVariables method, you are using a HTML template, not an App.

If you just use something like <image src="file://{File.FullName}...  it will work, but the browser will have to load the original image or cache file and then scale it down to whatever thumbnail size you use. And that every time you make a change in the file window and the HTML panel is updated. This is real bad for performance and will probably slow down IMatch considerably. I strongly suggest that you don't do this and instead use the method to load the thumbnail from the database "in-memory" I have shown you above. This will display a thumbnail for all files, and not impact performance at all.

In some posting above Mario (and you) gave me some hints. To be honest, your hints helped me a lot, but I guess, Mario's way is the right way, but I tried and tried and tried ... I am simply not able to understand, how Mario does it mean really and specialy of course, how to code it.

But I am sure, it would be the correct way, like Mario wrote here some posts above:
Quote
Check out the 'Tiles' app:

C:\ProgramData\photools.com\IMatch5\apppanel\system\tiles\tiles.htm


The function loadTile loads a thumbnail from the bitmap, converts it into a base64 string and then sets this as the src for an image. It also resizes the thumbnail if needed etc. but the general idea is to use

var srcimg = IMatchLib.database().GetThumbnailImage(file);

and then

var url = "data:image/jpeg;base64," + srcimg.SaveBase64(IMatchLib.IMImageSaveFormat.imsfJPEG24Standard);

someimage.attr("src", url);

The trick to encode the binary image data into a Base64 string and then using that as the src= attribute for an <image> tag allows this to work without accessing images on disk or using tempoary files. Very neat.

So I "studied" his App tiles.htm (this is an App, I guess), and I found some code, what he mentioned, but this code is so "burried" into other stuff, I could not manage to copy the correct lines into my code.

It would help me, if I could simply manage a code with the way of Mario, what displays only the selected image in the App-Panel, without my attributes-stuff, but even to display only such thumbs, I am not able.

And this shows me, apart from my frustration over myself, that I have to lern a LOT about this whole stuff.   ???

So, if I understand Mario correct, the good way would be his "trick", what he has used in his Tiles-App. This App does select several thumbs and displays them in the App-Panel, and after a while they will be changed against others, really a very nice App!
So in this App I can see, that it is possible to display quick thumbs of the DB.
The solution lies in this Tiles-App and in the knowledge of me (what I do not have), to go the same way, as Mario pointed out, but I want only display the selected thumb, independent if it is a raw or jpg or tif.

Phew, SORRY, I hope, that you are not even more confused now! Really!


[attachment deleted by admin]
Best wishes from Switzerland! :-)
Markus

Mario

#22
Markus, I've created a minimal template for you to show how to load the thumbnail.
I would do all this in an app because it's more flexiible. But templates are easier for beginners, because IMatch automatically parses variables etc.

Extract the attached ZIP into the

C:\ProgramData\photools.com\IMatch5\apppanel\user

folder on your machine.
Close the App panel and re-open it so it reads the file system again.
Then select the Sinus Simple Template.

It shows a small table with some variables, and the thumbnail in the last row.

The key part is the


var file = IMatchLib.focusedFile();

if (file == null) {
    document.getElementById("thumbnail").style.visibility = "hidden";
}
else {
    var srcimg = IMatchLib.database().GetThumbnailImage(file);
    var url = "data:image/jpeg;base64," + srcimg.SaveBase64(IMatchLib.IMImageSaveFormat.imsfJPEG24Standard);
    document.getElementById("thumbnail").src = url;
    document.getElementById("thumbnail").style.visibility = "visible";
}


in the onLoad method.

And this is the HTML for the last row in the table:


<tr><td colspan="2"><img id="thumbnail" src="#"/></td></tr>


You should be able to copy the code right into your template to make it work.

In my role as a consultant, I would charge you several hundred € for this  ::) ??? 8) :D

[attachment deleted by admin]
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Hey Mario,
You made my day!  :D :D :D Thanks for your effort!!!

Your code works perfectly and yes, I could now copy your lines into my other lines (with all the attributes-fields).
And you are also correct, with your code displaying an image is much quicker than my old code (what works, but is slower).

With your remarks now I understand also (mostly), what your code does.
Thanks again and yes, your support is really outstanding, generally and in détail, and if I had the money, I would hire you as an expert and consultant  :D  :D  ;D

Maybe, in a long distant future (in weiter Ferne), I can help also one day a user and maybe so the "help-user-help-circle" will be (for me) closed   :D and you have more time for doing other things than help helpless users!  8)

Thanks!
Best wishes from Switzerland! :-)
Markus

Mario

Good to hear that you have it solved.
You don't need to hire me. Just purchase IMatch upgrades when they come out  ;) and spread the word about how awesome IMatch is. You helped other users in the past, and now we helped you. Works best that way.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Quote from: Mario on June 02, 2015, 02:06:41 PM
Good to hear that you have it solved.
You don't need to hire me. Just purchase IMatch upgrades when they come out  ;) and spread the word about how awesome IMatch is. You helped other users in the past, and now we helped you. Works best that way.

Yep, you are right, Mario!
Of course I will spread the world, as much as possible. Help others and get help ... a good system!  :D
Best wishes from Switzerland! :-)
Markus

sinus

Quote from: Mario on June 01, 2015, 09:18:20 PM
Markus, I've created a minimal template for you to show how to load the thumbnail.

The key part is the


var file = IMatchLib.focusedFile();

if (file == null) {
    document.getElementById("thumbnail").style.visibility = "hidden";
}
else {
    var srcimg = IMatchLib.database().GetThumbnailImage(file);
    var url = "data:image/jpeg;base64," + srcimg.SaveBase64(IMatchLib.IMImageSaveFormat.imsfJPEG24Standard);
    document.getElementById("thumbnail").src = url;
    document.getElementById("thumbnail").style.visibility = "visible";
}


in the onLoad method.

And this is the HTML for the last row in the table:


<tr><td colspan="2"><img id="thumbnail" src="#"/></td></tr>



Hi Mario,
because it is soooo silent here (what I guess, is a very good sign), I dare to ask you some small thing about your code.

Your code works great.
Except one small problem.
If I click on a "non-image-file", like a word-doc, or some other special files (txt and so on), I get a script-error (see attachement), what ask about "save-base64-problem".

So I guess, if I select a non-image file, the script should not be excecuted.
I tried with if-else, but without success.

Then I tried, like you did in your mp3-App, to add this line in the xml-file:

  <class>image</class>
  <format_tag>JPG</format_tag>
  <file_mask>\.jpg</file_mask>

but this helped also not.

Is there a solution for this? If you can give me a hint, I can try further to solve it.






[attachment deleted by admin]
Best wishes from Switzerland! :-)
Markus

Mario

QuoteHi Mario,
because it is soooo silent here (what I guess, is a very good sign),

And am I thankful for that!
IMatch 5 seems to work awesome and I'm also totally busy working on the big features which will be included in IMatch 5.5.


You need to test if srcimg is null. If the file has no thumbnail. GetThumbnail returns null. And you cannot call SaveBase64 for a null object.

var srcimg = IMatchLib.database().GetThumbnailImage(file);
if (srcimg != null) {
...
}
else {
document.getElementById("thumbnail").style.visibility = "hidden";
}
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

sinus

Yes, that is a good sign.

IMatch is rock-solide for me and for a lot of other users also.

Good times for you to work and play ...  ;D

THANKS a lot for your answer. I try to put the lines in the correct place.
Best wishes from Switzerland! :-)
Markus

sinus

Quote from: Mario on June 20, 2015, 08:05:11 AM


You need to test if srcimg is null. If the file has no thumbnail. GetThumbnail returns null. And you cannot call SaveBase64 for a null object.

var srcimg = IMatchLib.database().GetThumbnailImage(file);
if (srcimg != null) {
...
}
else {
document.getElementById("thumbnail").style.visibility = "hidden";
}

Hi Mario
Thanks to your remarks I could now do the correct code, at least it works fine!  :D

Here is the code, what works now very good:

    var file = IMatchLib.focusedFile();
    var srcimg = IMatchLib.database().GetThumbnailImage(file);

if (srcimg === null) {
    document.getElementById("thumbnail").style.visibility = "hidden";
}
else {

    var url = "data:image/jpeg;base64," + srcimg.SaveBase64(IMatchLib.IMImageSaveFormat.imsfJPEG24Standard);
    document.getElementById("thumbnail").src = url;
    document.getElementById("thumbnail").style.visibility = "visible";


Thanks again for helping and have a good weekend with a lot of success, where you are working on.
Best wishes from Switzerland! :-)
Markus