Forum Moderators: open

Message Too Old, No Replies

New to JavaScript - Would Like Checkbox to Update Image

Countries in WEorld Image to Change Color According to Checkbox States

         

socrtwo

10:39 pm on Apr 6, 2010 (gmt 0)

10+ Year Member



Hi. I'm new to Javascript. I have some successful Perl, VB and VBA forays in my past. Now I'm trying to make a web service where users can check which countries they have visited from a list of 175 or so and a World map image would then instantly update with a filled color.

There are other similar services, but I'm envisioning mine to be both updating from checks in checkboxes and by clicking on the target country in the displayed image. Additionally other solutions make all the countries the same color. I would like different colors for the different countries or at least for those countries that touch. Eventually I would like to include the feature that enables the choice of which colors to assign countries.

I found a Sourceforge project called pwmfccd. It's simply an open source image of the world and the coordinates on the PNG image for all the countries. You can use mogrify from ImageMagick and floodfill to fill the countries with color. I have done this successfully, locally with batch files.

My ISP has told me where mogrify is located, basically "/usr/bin/mogrify". I now have a horrendously complicated cgi script which if it worked is set to redraw the world map image with each checkbox. It also redraws the whole web page. Of course this is not at all efficient, and I think the real way to go is Ajax or Javascript. Sorry I don't even know the difference at his point.

I suppose you could make just one part of the image update with each check or click on the image instead of even just the image redrawing, but I have never even heard of a hint at being able to do that. So I guess an Image map and sister checkbox entries tied to mogrify events redrawing the user's personal copy of the image with an image refresh would be the only way to go.

So how do you do this with Javascript and/or Ajax?

Thanks in advance for reading and considering answering this post.

Fotiman

4:12 pm on Apr 7, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Welcome to WebmasterWorld!

It sounds like you may already have a functioning server side solution, which is good because JavaScript should only be used to enhance the page. You'd want your service to continue to be functional even for those users that don't have JavaScript.

AJAX stands for "Asynchronous JavaScript And XML". Most people who talk about AJAX are referring to the XMLHttpRequest object and communication between the client and server without the need for a page refresh.

Now, if I was designing this, I'd probably want a page that took the parameters required to generate the image, and then returned a JSON string containing the details of the image (location, etc). For example:

http://example.com/getCountryMap/?l=...&c=...

Where "l" contains the location and "c" contains the colors to use.

The result of this might be a JSON string like the following:

{
img: {
src: 'GENERATEDIMGSRC',
alt: 'World Map'
}
}


Or something similar (I'm just speaking in general terms). Then you would use JavaScript to attach onclick event handlers to your checkboxes and/or image map, which in turn would generate the URL and create an AJAX request to that service, then parse the response from the server and replace the image that was currently being displayed with the new one.

Most JavaScript libraries (jQuery, YUI, etc.) have AJAX functionality with simplified interfaces. Alternatively, you can work directly with the XMLHttpRequest object to perform the request. If you have questions on this, please feel free to ask here.

Hope this helps you get started.

socrtwo

3:58 pm on Apr 12, 2010 (gmt 0)

10+ Year Member



Hi. Thanks so much for answering. I used GD and php finally. The results are here: URL Removed

It works pretty well now. The next issues, which may need to move to another forum here are:
  1. How to maintain persistence of checks between image updates. In the php section if I set the dollar sign variable to the name of the checkbox and set it equal to 'checked', it does not keep it checked between sessions.

    For instance I found that this on Google might lead to persistence of checking:

    if (isset($_POST['angola'])) {
    $angola = $_POST['angola'];
    if ($angola == 'angola_visited') {
    $angola_color = imagecolorallocate($im, 57, 150, 6);
    imagefill($im, 709, 421, $angola_color);
    $angola = 'checked';
    }
    }

    However this doesn't work.

  2. How do you make a checking of a box, immediately reprocess the script? This doesn't seem to work:

    <input type="checkbox" onclick="testnewgood.php" name="angola" value="angola_visited"/>


    IE throws a zero error saying that testnewgood is undefined at the line in the script and Firefox ignores it.

[edited by: Fotiman at 5:23 pm (utc) on Apr 12, 2010]
[edit reason] No URLs please. See TOS [webmasterworld.com] [/edit]

Fotiman

5:21 pm on Apr 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The onclick handler needs to take a function reference or expression, not a URL. You could have a function that sets the location though. For example:

<input type="checkbox" onclick="location='testnewgood.php';" ...

socrtwo

7:20 pm on Apr 12, 2010 (gmt 0)

10+ Year Member



Cool thanks, I'll try that.

I am now able to maintain the checks in boxes between button submissions through better understanding and copying the code I originally was trying to use.

The PHP upper section of my script was partially correct. For instance setting:

$angola = 'checked';

was right. I also however needed to set all the countries to 'unchecked'; at the beginning of the script before any isset checks are made. Apparently this does not interfere with the isset checks later on , I'm not quite sure why.
So this section now contains first:

$algeria = 'unchecked';
$angola = 'unchecked';
$botswana = 'unchecked';

...etc.
After that I need to put this code in each input in the html section. So Angola would look like this:

<br><input type='checkbox' name='angola' value='angola_visited' <?php print $angola; ?> >Angola

Microsoft Expression says that IE8 disallows this PHP in the input tag, but it still works in both IE and Firefox.

socrtwo

7:36 pm on Apr 12, 2010 (gmt 0)

10+ Year Member



OK, it's cool but it doesn't quite work:

<input type="checkbox" onclick="location='testnewgood2.php';"

does submit testnewgood2.php (my current scripts address) and I get back the map, however the checkbox is not checked anymore, and the country hasn't turned color.

So do I need to instead simulate the button submission? Maybe I also need to simulate submission with a box checked say for Angola.

Also do I need to use PHP in my input tag to print out the earlier PHP setting of the checkbox scalar setting to 'checked'? Is there something similar to "location=" which will keep the box checked between redraws?

Fotiman

7:58 pm on Apr 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm sorry, I didn't really look at what you were trying to do... what you want to do is actually submit the form.

So try something like this:
onclick="this.form.submit();"

You'll need your form to have action="testnewgood2.php"

socrtwo

8:39 pm on Apr 12, 2010 (gmt 0)

10+ Year Member



The new code has the same effect. The page is refreshed but the countries don't get colored and the checkbox chosen does not remain checked. I appreciate your continued help. This is a good forum :-).

Fotiman

1:17 pm on Apr 13, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Is your form method set to POST?
<form method="post" ...>

socrtwo

1:56 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Yes. Thanks

Fotiman

2:51 pm on Apr 13, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Well, assuming that:
1. Your form action is set to "testnewgood2.php" and
2. Your form method is set to "post" and
3. Your input element is within the form and
4. testnewgood2.php has code that looks for $_POST['angola']

Perhaps the problem is the event handler... perhaps instead of onclick you should be using onchange.

<form action="testnewgood2.php" method="post">
<div>
...
<input type="checkbox" onchange="this.form.submit();" name="angola" value="angola_visited"/>
...
</div>
</form>

socrtwo

3:37 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Well onchange submits for Firefox but not IE. Neither update the colors.

I was wondering though, what is the correct form of $_POST['angola']. Right now the full "function" looks like this:

if (isset($_POST['submit1'])) {
if (isset($_POST['angola'])) {
$angola = $_POST['angola'];
if ($angola == 'angola_visited') {
$angola_color = imagecolorallocate($im, 57, 150, 6);
imagefill($im, 709, 421, $angola_color);
$angola = 'checked';
}
}
}

Is that right?

socrtwo

4:09 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



OK I take it back, it does work correctly when I simply change

if (isset($_POST['submit1'])) {

to
 
if (isset($_POST['angola'])) {


My next question is it possible to update just the image and not redraw the whole page so there is no flash each time a page is drawn?

Also when I make an image map, should I use Javascript for each time a user clicks on a country? If so what kind of statement should I use.

I did find a great image map generator called MapEdit, that has a magic wand like tool for selecting things like countries. It also has a point editor to move points in the vector border produced by the magic wand thing.

In Mapedit, you can specify a page to which a visitor who clicks on an area is directed. You can also fill in Javascript, I guess instead of a web page address.

socrtwo

5:12 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



I have a test image map. I guess we can work on just getting it to update at all, basically doing the same thing as checking a box.

So what would I need to do to this code to turn it into a form? I guess it start with

<input type="image" usemap
,

but I don't know from there. Can I put onclick handlers in the Area tags if the form tags enclose all the area blocks?


<form action="where.php" method="post">
<div>

<input type="image" src="world_map2.png" alt="" usemap="#world_map2" style="border-style:none">

</div>

<div>
<map id="world_map2" name="world_map2">
<area shape="poly" alt=""
coords="392,154,333,201,315,220,312,246,302,232,
269,226,256,230,244,237,233,228,222,224,212,
217,196,219,181,213,168,203,166,191,172,172,
181,160,192,152,202,146,214,146,223,146,230,
146,236,146,240,146,246,146,253,146,262,146,
274,146,298,146,314,177" href="albania.php" title="">
<area shape="poly" alt=""
coords="445,106,461,146,379,153,319,173,309,161,
304,139,259,139,249,139,241,139,231,139,219,
139,205,139,192,132,191,118,196,104,183,94,
193,83,203,75,211,69,218,64,225,60,235,62,242,
62,248,60,256,58,307,40,421,20,486,12,461,18,
446,58" href="albania.php" title="">
<area shape="default" nohref="nohref" alt="">
</map>
</div>
</form>

[edited by: Fotiman at 2:17 pm (utc) on Apr 14, 2010]
[edit reason] Formatting [/edit]

socrtwo

11:41 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



OK, I see if I enclose my image with a set of <div> tagsd that has an ID, I can change this image dynamically with javascript. So the image code would look like this:
<div id="world_image">
<img alt='world map' src='world_map2_users_copy.png?x=<?=time()?>' style="width: 800px; height: 350px">
</div></td>


I never knew what good the <div> tags were, now I understand some.

Anyway my question is can I use PHP in my javascript function? My problem stems from being unable to manipulate the images using imagemagick. My ISP told me that mogrify from the imagemagick toolbox, lies here:

/usr/bin/mogrify

However when I create a function using a call to that address or to /usr/bin/mogrify/mogrify nothing happens.

So this function does not seem to work:

function seen_united_states(){
/usr/bin/mogrify -fill "#FF0000" -draw "color 22, 266 floodfill" world_map2_users_copy.png;
}


So I can work in PHP but I'm not sure how to dynamically update parts of the page like just the image, using just php.

Fotiman

2:13 pm on Apr 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



JavaScript runs client side (in the web browser), whereas mogrify runs server side. You can't interact directly with it from JavaScript. You could use JavaScript/AJAX to send an HTTP request to a PHP page, which in turn interacts with mogrify. Something like:

function seen_united_states() {
var xhr = getXHR(); // * See note below
xhr.open("GET", url, true); // ** See note below
xhr.onreadystatechange = function () {
// The mogrify function has been called
};
xhr.send(null);
}


Within that callback function, you would then set the client side image to the one created by the PHP script.

* For getXHR, see Cross Browser XMLHttpRequest Explained [webmasterworld.com]
** url would be the php page that calls mogrify

socrtwo

2:29 pm on Apr 25, 2010 (gmt 0)

10+ Year Member



Hi again. I now have a partial solution. An onclick event kicks off a javascript function which rewrites the source image as one of 175 or so country php files. The image is returned as a PHP file and the source changes to the country name with a php extension.


My issue now is that I have tabs with all the countries listed from each continent. The data is split into 5 inline frames on the original file which gets loaded and has the tabs. When a user clicks on a tab the page displays 5 different parts of the same file which have been demarked with bookmarks to allow accessing the right section within the inline frames. Frame # 2 is the image.

Clicking on the country does process the php file, however it does not update the image within the inline frame of the parent. How would I do that? I have tried to place the update event within the javascript function and the onclick events as follows:

;frames['I2'].location.href='new.htm#world_image';

However neither places refresh the image. Instead the only way to display the updated image appears to be to hit F5 in the original parent page where the tabs and inline frame data exists.

So is there a way for me to send a refresh signal to the image alone from second html file to the parent?

Thanks as usual.

socrtwo

10:12 pm on Apr 25, 2010 (gmt 0)

10+ Year Member



Never mind, this works great:

window.parent.document.frames('I2').location.reload();

Thanks anyway.

Just to recap I needed a parent iframe to reload, but I just wanted one of five iframes to load, not the full page nor the other iframes.

The above does the trick.