homepage Welcome to WebmasterWorld Guest from 54.242.200.172
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Subscribe to WebmasterWorld
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
Multiple Image Swap Code Not Working
icon_kid




msg:4609711
 4:13 am on Sep 14, 2013 (gmt 0)

I have a basic 'image swap' code that works for swapping a single pair of images by toggling a checkbox but I need to adapt it so that I can have multiple pairs. Below is the <script>, the checkbox <form> and the <img> tag. On load there is a blue icon (and the checkbox is unchecked) -- when checked the blue icon turns into a red one.


</head>
<script>
function processCheckbox(checkbox) {
if (checkbox.checked) {
image.src = "ICONS/red_dot.png";
image.onclick = enabledClick;
} else {
image.src = "ICONS/blue_dot.png";
image.onclick = null;
}
}
function enabledClick() {
alert("enabled!");
}
</script>
</head>

<body>
<form style='display:inline;' name="form-001" method="post" action="">
<input type="checkbox" onclick="processCheckbox(this);">
</form>

<img src="ICONS/blue_dot.png" id="image">
</body>


Of course, setting up additional swaps means having each checkbox properly linked to specific pairs of images through the use of NAME and/or ID. One of our WebmasterWorld members offered me a template that looks like this:


</head>
<script>
function processCheckbox(checkbox) {
if (checkbox.checked) {
image.src = "ICONS/red_dot.png";
image.onclick = enabledClick;
} else {
image.src = "ICONS/blue_dot.png";
image.onclick = null;
}
}
function enabledClick() {
alert("enabled!");
}
</script>
</head>

<body>
<form style='display:inline;' name="form-001" id="my_form_1" method="post" action="JavaScript:void(0);">
<input type="checkbox" id="red_dot" 'onClick="processCheckbox('this');">
</form>

<img onClick="processCheckbox('red_dot');" src="ICONS/blue_dot.png" style="cursor:pointer;">
</body>
</html>


...but this version of the code, however, does not do the swap when you check the box and, if it can't do a single swap, it definitely won't do multiples. Something must not be linked correctly, else some other kind of error. Can anyone see exactly where that is?

 

Fotiman




msg:4609768
 12:51 pm on Sep 14, 2013 (gmt 0)

Did you ever try my suggestion here?
[webmasterworld.com...]

My suggestion did not require a name or id associated that "links" the checkbox with the image, but instead uses the indexes to create that association.

icon_kid




msg:4609881
 5:22 am on Sep 15, 2013 (gmt 0)

Thanks, Fotiman.

Im that thread you had numerous suggestions but, to be honest, I'm not sure which ones apply to my current issue. That was also when I was pursuing the 'Hide" script for the effect I want. I've abandoned that method and I'm going to stick with a 'Swap' script.

I did make note of your suggestion about the action="JavaScript:void(0);being well replaced with action="#". In the second, unworking version of my swap code that portion of the line had been removed altogether.

I was wondering about lines like this:

image.src = "ICONS/red_dot.png";

Can't it be image1.src, image2.src, etc.?

Another swap code I experimented with looked like this:

<SCRIPT>
img01 = "ICONS/red_dot.png";
img02 = "ICONS/blue_dot.png";
function chng(c_img) {
image.onclick = null;
}
function enabledClick() {
alert("enabled!");
}
}
if (c_img.src.indexOf(img01)!= -1) c_img.src = img02;
else c_img.src = img1;
}
</Script>


I really liked the way this looked the instant I saw it -- it's compact and it gives a Number to each image.

Why does it have to be such an arcane issue to make checkbox 'A' swap images '1 & 2' and make checkbox 'B' swap images '3 & 4' and make checkbox 'C' swap images '5 & 6'? There aught to be an app where I can tell it which checkboxes are associated with which images and have the app compose all the rediculously convoluted, protracted code -- I'm a graphic artist, not a computer programming student. I know that apps like that don't exist yet -- it's just a lament.

Fotiman




msg:4609984
 12:30 am on Sep 16, 2013 (gmt 0)


Im that thread you had numerous suggestions but, to be honest, I'm not sure which ones apply to my current issue.

I'd start with the bit that begins:

In my script file, I would want to achieve the following:


One of the points I was trying to make was that it would be a lot of work to maintain the association of a checkbox to an image, which you could avoid by automating. Of course, it partly depends on whether you're looking to swap the same images for all of them, or if you'd have different images associated with each checkbox.

icon_kid




msg:4609989
 1:48 am on Sep 16, 2013 (gmt 0)

It partly depends on whether you're looking to swap the same images for all of them, or if you'd have different images associated with each checkbox.


I thought I was very clear on that...

checkbox 'A' swaps images '1 & 2' -- checkbox 'B' swaps images '3 & 4' -- checkbox 'c' swaps images '5 & 6' and so on.

If you just look at it, each checkbox is dealing with a different pair of images.

I'm not seeing what's not clear about what I've stated I need to do.

Fotiman




msg:4609996
 3:00 am on Sep 16, 2013 (gmt 0)

Ok, that's clear now.

You might be interested in this thread:
[webmasterworld.com...]

There's some code there that does basically exactly what you're trying to do (swap an image). It works by adding data attributes to your HTML that contain the replacement images.

icon_kid




msg:4610842
 3:49 am on Sep 19, 2013 (gmt 0)

Ok, that's clear now.


Ha, ha -- this thread is starting to become humorous. I'm sorry but somehow I've still not made the concept clear enough. The thread (linked to in the above reply) is barely similar to the issue I have at hand.

This time, let's put it like this:
Imagine three school matrons and six small children who are about to cross a street together. Each matron will hold the hands of two children. Each matron is responsible only for the two children they're holding hands with. Here's a diagram of that. By the way, each matron is wearing a name tag (or ID card) -- For instance, on Abigail's tag it reads "MATRON-1" This is one way in grouping two children to her by stating on the children's "sticky name tags" that they belong to the 'MATRON-1' group.


*********************(MATRON-1)
******************|---Abigail---|
*********Ann<-----|+++++++++++++|----->Amy

*********************(MATRON-2)
******************|---Barbara---|
*******Basha<-----|+++++++++++++|----->Bess

*********************(MATRON-3)
******************|---Carolyn---|
*******Corey<-----|+++++++++++++|----->Casey

Likewise, as in the diagram below, checkboxes would be analogous to the matrons -- each checkbox will flip only two specified images when clicked -- exclusively from all other images and regardless of the status of any other checkboxes, just as one specific matron holds the hands of only two specific children.


***********************(group-1)
******************|--CHECKBOX-1--|
*****Ann.png<-----|++++++++++++++|----->Amy.png

***********************(group-2)
******************|--CHECKBOX-2--|
****Basha.png<----|++++++++++++++|----->Bess.png

***********************(group-3)
******************|--CHECKBOX-3--|
****Corey.png<----|++++++++++++++|----->Casey


This concept is rediculously simple -- it behooves me as to why I can't find even one person who knows how to link elements like this to work properly in a script. To me it seems that something like this would be common, but I guess it's just not commom enough.

Also, would anyone like to take a stab at this one:
In the following line, what does 'this' mean?

onclick="processCheckbox(this);"

What can you put there other than 'this' and why would you want it to be changed? Would it have something to do with linking elements?

rainborick




msg:4610864
 6:17 am on Sep 19, 2013 (gmt 0)

The problem with questions like yours is that it's often difficult to discern exactly what you're trying to achieve without a more precise description along with some code to use as a starting point. Often when people discuss "image swap", they want to replace an image in a single <img> tag with another image, for example. And since all of your previous examples have only had a single <img> tag, that's possibly one reason why you haven't gotten useful help. It wasn't until you said that you wanted to exchange two images that, for me at least, the problem was finally clear.

Even so, with all of the possible variations in HTML mark-up and many possible programming approaches, I'm not sure if this will work for you, but the code does work:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Swap Two Images Within a Form</title>
<script>

function processCheckbox(checker) {
var image1 = checker.form.getElementsByClassName('firstImage')[0];
var image2 = checker.form.getElementsByClassName('secondImage')[0];
var tmp1 = image1.src;
image1.src = image2.src;
image2.src = tmp1;
return false;
} // end processCheckbox()

</script>
</head>
<body>
<h1 style="text-align:center;">Swap Images</h1>
<br>
<br>
<form id="form1" action="#">
<input type="checkbox" name="Abigail" onclick="processCheckbox(this);"><b>Abigail</b><br>
<img src="images/A.png" class="firstImage" width="100">&nbsp;<img src="images/B.png" class="secondImage" width="100">
</form>
<br>
<form id="form2" action="#">
<input type="checkbox" name="Barbara" onclick="processCheckbox(this);"><b>Barbara</b><br>
<img src="images/C.png" class="firstImage" width="100">&nbsp;<img src="images/A.png" class="secondImage" width="100">
</form>
<br>
</body>
</html>

In order to simplify things, this code depends on enclosing each checkbox and image pair in a <form> tag, and using the indicated class names for the image tags. You can have as many checkbox/image pairs as you need. Let me know if you need it to work in older versions of IE.

Fotiman




msg:4610938
 1:42 pm on Sep 19, 2013 (gmt 0)


And since all of your previous examples have only had a single <img> tag, that's possibly one reason why you haven't gotten useful help. It wasn't until you said that you wanted to exchange two images that, for me at least, the problem was finally clear.

I agree. It was not clear that you wanted to exchange 2 images at once.

Let us know if rainborick's solution works for you.

icon_kid




msg:4611527
 4:05 am on Sep 21, 2013 (gmt 0)

...it's often difficult to discern exactly what you're trying to achieve without a more precise description.

Well I don't think there's anything more precise (and succinct) than:

make checkbox 'A' swap images '1 & 2'...
make checkbox 'B' swap images '3 & 4'...
make checkbox 'C' swap images '5 & 6'.

-- from an earlier post (three replies above this one) which you must have missed.(and is a heck of lot neater than an elaborate 'school matron' analogy to express exactly the same thing).

...along with some code to use as a starting point.

The starting point code is shown at the top of this thread. It didn't seem necessary to keep displaying it. I had assumed that people who've followed this thread from the start would remember that it's there if they want to refer to it.

...all of your previous examples have only had a single <img> tag...

Of course there's only one <img> tag -- To swap back and forth between two images requires only the <img> tag for one of the images -- the other image is referenced from the script.

Both of my examples (at the top of this thread) are for a single image swap.
The first example works, but it needed to be modified so that it could be adapted to doing multiple swaps (which meant adding some kind of linking so that each checkbox would affect their own designated images). The second example is that modified code for a single swap but it does not work. I needed to get it to work properly before adding more checkboxes and more image pairs -- my thought was that: if it can't do one swap, then it won't do two, or three. In other words, if I were to take your sample code -- which contains two flips (four images) and remove one image tag, one checkbox and remove the references of those two related images from the script, then I should be left with only one flip on the page -- but one that still works but mine didn't work. Anyway, I will test your sample code with the two flips.

One issue I see ahead is about this:

...this code depends on enclosing each checkbox and image pair in a <form> tag...

In this project the checkbox and the <img> tag will be far removed from each other in the layout of the page with many tags of different kinds between them and, if I can find a way to do it, the checkboxes and the images will lie in separate tables as well. Might there be a work-around to having to enclose the <img> within a checkbox <form>?

Fotiman




msg:4611623
 7:00 pm on Sep 21, 2013 (gmt 0)

Actually, I think the school matron example made it less clear to me, because I thought from that example that you'd want to show 2 images at once. It seems, though, that you just want to toggle a single image between 2 different states (which is what I originally thought).

Ok, this is going to be my last post on this I think. I'm going to start over and try to explain my earlier solution as a step by step process.

First, lets assume you have an image:


<img src="ICONS/blue_dot.png" id="image">


Now, lets assume that you're going to want to swap that image src. Where should you define the alternate src? My suggestion is that you define it as a data attribute on the image, like so:

<img src="ICONS/blue_dot.png" data-images="ICONS/blue_dot.png,ICONS/red_dot.png" id="image">


This data-images attribute will hold the values for all of the possible img src.

Next, lets assume you have a checkbox somewhere that will control which of the images will be displayed:

<input type="checkbox" data-img-id="image">

I've given this checkbox a data attribute as well, which is how we "link" the checkbox to a particular image (at least at first). In this example, I'm planning on creating the link between this checkbox and an img element with an id of "image".

So now for the JavaScript. I want to create an object that will take an ID of an img element, and will get the value of the data-images attribute on that element:

function ImageToggler(id) {
this.img = document.getElementById(id);
this.images = this.img.getAttribute('data-images');
this._init();
}


Next, I'll create a method to do the initialization work: converting the string of data-images to an array, setting the first image, and setting any event handlers.


ImageToggler.prototype._init = function () {
var that = this;
if (this.images) {
this.images = this.images.split(",");
this.imageindex = 0;
this.n = this.images.length;
this.setImg(this.imageindex);
//this.img.onclick = function () {that._nextImage.call(that);};
}
}

Next, I need to define the setImg function:


ImageToggler.prototype.setImg = function(idx) {
this.imageindex = idx;
this.img.src = this.images[idx];
}


Lastly, we need a method we can call that will swap the image:

ImageToggler.prototype.nextImage = function () {
this.imageindex = (this.imageindex + 1 < this.n? this.imageindex + 1: 0);
this.setImg(this.imageindex);
}

Now we need to create on of these ImageToggler objects for each image. We also need to associate the 'click' event with each checkbox to the nextImage function of the appropriate ImageToggler. To do that, I'm going to search for all input elements that have a data-img-id attribute:


var checkboxes = document.getElementsByTagName('input'),
imgTogglers = [],
id,
i,
n;
for (i = 0, n = checkboxes.length; i < n; i++) {
id = checkboxes[i].getAttribute('data-img-id');
if (id) {
imgTogglers[i] = new ImageToggler(id);
checkboxes[i].onclick = (function (idx) {
return function () {
imgTogglers[idx].nextImage();
};
})(i);
}
}


That's all there is to it. Now create as many image and checkboxes as you want. Here's a complete example:


<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
<img src="Ann.png" data-images="Ann.png,Amy.png" id="Abigail">
<img src="Basha.png" data-images="Basha.png,Bess.png" id="Barbara">
<img src="Corey.png" data-images="Corey.png,Casey.png" id="Carolyn">
<div>
<input type="checkbox" data-img-id="Abigail">
<input type="checkbox" data-img-id="Barbara">
<input type="checkbox" data-img-id="Carolyn">
</div>
<script>
function ImageToggler(id) {
this.img = document.getElementById(id);
this.images = this.img.getAttribute('data-images');
this._init();
}
ImageToggler.prototype._init = function () {
var that = this;
if (this.images) {
this.images = this.images.split(",");
//console.log('this.images: ' + this.images);
this.imageindex = 0;
this.n = this.images.length;
this.setImg(this.imageindex);
//this.img.onclick = function () {that.nextImage.call(that);};
}
}
ImageToggler.prototype.setImg = function(idx) {
this.imageindex = idx;
this.img.src = this.images[idx];
//console.log('setting image to ' + this.images[idx]);
}
ImageToggler.prototype.nextImage = function () {
this.imageindex = (this.imageindex + 1 < this.n? this.imageindex + 1: 0);
this.setImg(this.imageindex);
//console.log('set image on ' + this.img.id + ' to ' + this.img.src);
}
var checkboxes = document.getElementsByTagName('input'),
imgTogglers = [],
id,
i,
n;
for (i = 0, n = checkboxes.length; i < n; i++) {
id = checkboxes[i].getAttribute('data-img-id');
if (id) {
imgTogglers[i] = new ImageToggler(id);
checkboxes[i].onclick = (function (idx) {
return function () {
imgTogglers[idx].nextImage();
};
})(i);
}
}
</script>
</body>
</html>


At this point, I'm pretty spent with regards to this thread. I've provided several examples, all of which could be applied to your scenario. I'm hoping that this last example answers your questions, and you're able to apply this to what you're doing. Good luck.

icon_kid




msg:4611886
 1:31 am on Sep 23, 2013 (gmt 0)

Thank you Fotiman.

Your script works. Though rainborick's script (thank you rainborick) may have worked I didn't get to try it because I tried yours first -- and I hope that a reference to this issue of multiple image flips using checkboxes, and the code for it, will help the next hapless person (like myself) who's looking for it.

Fotiman




msg:4611900
 3:35 am on Sep 23, 2013 (gmt 0)

Glad it's working for you. :)

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved