2017년 1월 9일 월요일

Set webstring "response" in dynamic javascript html


Been working around with the webstring property, generating a web page of images and setting the onclick property of each image with the webstring response e.g. onclick="javascript:window.AppInventor.setWebViewString( 'my response')

Have had success doing this with php:

$files = glob("signs/*.png");



for ($i=0; $i<count($files); $i++) {

//path to image

    $image = $files[$i];

    //strips path

    $fname =  substr($image, 6);
    //strips extension
    $sname = substr($fname, 0, -4);
    //for onclick
    $xname = "'" . $sname . "'";
    //displays all files and creates clickable link to video of the same name
    echo '<a href=# ><img src="'.$image .'" onclick="javascript:window.AppInventor.setWebViewString('.$xname .');" alt="sign image" /></a>'. "&nbsp;&nbsp;&nbsp;&nbsp;"; //."<br /><br />"
}

so if the image is called apple.png, when I click the image it returns "apple" to the appinventor app.

Now this is all good if my user has a web connection, but if they are out of range using php won't work.

Therefore I looked for a javascript solution which i could run locally on the device as a part of the app's assets.

This piece of code seems to do the trick, as long as the images (signs) folder is browseable:

<script type="text/javascript" language="javascript">

var folder = "signs/";



$.ajax({

    url : folder,

    success: function (data) {

        $(data).find("a").attr("href", function (i, val) {
            if( val.match(/\.(jpe?g|png|gif)$/) ) { 
                $("body").append( "<a href=# ><img src='"+ folder + val +"'>" );
            } 
        });
    }
});
</script>

But I have been unable to get the body append section to take the webstring "response" code in the same way as the php example, like so:

<script type="text/javascript" language="javascript">

var folder = "signs/";



$.ajax({

    url : folder,

    success: function (data) {

        $(data).find("a").attr("href", function (i, val) {
            if( val.match(/\.(jpe?g|png|gif)$/) ) { 
                $("body").append( "<a href=# ><img src='"+ folder + val +"' onclick="javascript:window.AppInventor.setWebViewString( + val +);"></a>" );
            } 
        });
    }
});
</script>

telling me I have a missing ) after the arguments list

I'm going wrong somewhere, can anyone help?

--
I apologize that I am not writing to help, but to ask how you have access to code? I have been trying to figure out if I can use App Inventor 2 and have access to write my own code, not be restricted to the blocks. 

-- 
April

The code I have posted is part of html or php pages accessed through the Webviewer component. The webviewer>webstring block allows interaction between the web page (local on device or on distant server) and the appinventor app/device.

Because I can't run php on the device, I need to use javascript.

-- 
Is there no-one with javascript guru-ness who can help with this?  Pleeaase :)

-- 
probably my tips how to test your html file outside of App Inventor can help? 
see here https://puravidaapps.com/listview.php#q
and in case you get this running, then you will be our JavaScript Guru...

-- 
Thanks for the encouragement Taifun ;)

After a heavy day on the keys yesterday (on AppInventor!), I awoke refreshed and decided to have another crack at resolving this.

If you refer to the example in the OP there is a line that is appended as html by the javascript. this is the one giving all the problems



$("body").append( "<a href=# ><img src='"+ folder + val +"' onclick="javascript:window.AppInventor.setWebViewString( + val +);"></a>" );


I know that this works (the original find on Stack Overflow:

$("body").append( "<img src='"+ folder + val +"'>" );

I also know that this works, including the <a> section:

$("body").append( "<a href=# ><img src='"+ folder + val +"'></a>" );

but  couldn't figure out why the onclick part refused to work. Had to break it down and iterate until I got there, hitting hard on the Stack Overflow servers, the answer is usually there somewhere, even if you have to interpret it!

The solution comes from the webViewString needing to be a "string", simply providing it with the variable 'val' was not enough, the output of 'val' needed to be in quotes.

So for this I created another variable with a collection of quotes and slashes:


myval = "\'"+val+"\'"

This then outputted the contents of 'val' with quotes around it.

Eventually, after a few other changes to single and double quotes here and there this is what I came up with:

AppInventor

With trepidation I loaded up Genymotion emulator and started up my simple test app, clicked on an image and "Hey Presto!" the name of the image in question appeared in the text box. (this is just for testing, I can now take this string and do things with it!)

I can't label myself as a javascript guru, but I did do a little dance :) Credit must go to the folks on Stack Overflow, steeped in knowledge and information. I didn't have to ask, just searches and browsing

Halfway there now, as I have to test this out locally on a tablet, to be sure the javascript will run without needing to be connected to the interweb, also to sort out the href so it stops jumping back to the top of the page.

This is looking like a useful solution for unknown numbers of images/items, cuts down the load on an app (no buttons or images required as assets) and should speed develop in other ways. I know there are some more sexy solution with jquery mobile but this works for me :)

Also made a little video if the thing in action on the emulator


-- 
Quick update

Fixed the href issue with

<ahref"javascript:;">

Bigger problem trying to run locally on device, though.   If I try to run locally on my linux pc my browser gets quite up set about security issues and cross site conflicts from jquery. On my tablet/emulator I just get a blank screen, either because of the same issue or because the images folder has to be "browseable" ? (had to create .htaccess file with options +indexes on my web server to get all this to run properly) Pretty certain my links and references are correct and i have the jquery-latest.min.js in the same folder as the html file.

Guessing that this won't work on a local device unless I run a web server on it. Oh well ;) 

-- 
generating a web page of images and setting the onclick property of each image with the webstring response

this should work, if you store the images in the assets of your app or alternatively in the internet. I don't think, you can access the file system from within the webviewer.
Also I'm not sure about the ajax part

-- 
I tried it with the html (js too) and image files as assets but the same blank page.

Also had a look in the jquery mobile stuff you sold me a while back, but no real clues in the html there either.

What about not allowing the webviewer to clear the cache unless there is an internet connection, would that allow use when there is not net connection?

Clutching at straws now, having spent the morning fishing in the dark :)

-- 
I now added an image listview example here https://puravidaapps.com/listview.php and also sent the project directly to you by email


What about not allowing the webviewer to clear the cache unless there is an internet connection, would that allow use when there is not net connection?

you always can use the webviewer, but there are some restrictions, for example as already mentioned, you can't access the file system

 image2.jpg

-- 
Good news, I believe I have a solution. Taifuns ListView stuff was very useful, but took me round the houses a bit, until i broke it all down and saw for a very basic working example I hardly needed any of it ;)

Once I had figured out I didn't need to do any uri encoding and decoding, and how to setup the "csv list" to move across as the webviewstring property, it all fell into place.

My examples use images and html file (along with the jquery file) installed as assets on the app for sharing purposes, the eventual aim is to load these separately on the sdcard. I also have some work to do on the css ;)

Here is the code for the webpage (ImageView.html):



<!DOCTYPE html>

<html>



<head>

 <meta name="author" content="puravidaapps.com">

 <meta charset="utf-8">

 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
 <script src="jquery-1.8.3.min.js"></script>
 <title>ImageView</title>

<style>
img {
width:100px;
height:100px;
}
</style>
</head>

<body>

  <script>
  $(document).ready(function() {
    
    var webString = window.AppInventor.getWebViewString().split(",");
    $.each( webString, function( index, val ) {
myextn = ".png";
myval = "\'"+val+"\'";
$("body").append($( '<a href="javascript:;"><img src='+ val + myextn +' onclick="window.AppInventor.setWebViewString('+ myval +')"></a>' ));
});
    });

  </script>

</body>

</html>

Yes, that is all ;)

Here are the blocks:

A view of the designer window


I'll just explain what is going on:
⦁ In Appinventor I create a list of filenames (without the file extension, which gets added later)
⦁ I then take this list, make into a csv row and create a string, stripping away all the "
⦁ This resultant string is then fed to the WebViewString block
⦁ At this point the WebView is blank
⦁ Clicking on the Home button in the app calls the ImageView,html page
⦁ The javascript picks up the webviewstring and splits it at the commas (,) thereby turning the variable into an array
⦁ This array is then fed into the remainder of the script, with a simple jquery for loop ($.each)
⦁ This takes each item in the array in turn, adds an extension, and creates a return webviewstring value
⦁ The web page is rendered and all the images from the list are displayed, they are <a href> clickable (so they blink) and on clicking an image the name of the image is returned to the app

I'm a cheerful rabbit, a jolly badger, and a dancing ferret all rolled into one :)

See also attached aia for anyone who is interested  
ImageView.aia

--
congratulations! keep up the good work!

-- 
Nice work, Tim!

-- 

댓글 1개: