jamietre / ImageMapster

jQuery plugin for enhancing HTML Image maps
http://jamietre.github.io/ImageMapster/
MIT License
818 stars 331 forks source link

Can not make it work! #2

Closed goivan closed 13 years ago

goivan commented 13 years ago

Hi,

I pretty much had a complete project working with maphilight until I found yours and decided to give a shot. Well to my disdain I have not been able to make it work not even once!

Questions

Thanks in Advanced, Ivan

Here is my code!

{{{ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Untitled Document
``` ```

}}}

jamietre commented 13 years ago

Can you post the code somewhere or give me a link to somewhere public it's hosted? It's getting parsed by the comment system. I will also need the images themselves. I'd be happy to take a look.

I can see one thing wrong:

$('#ksp-containerID').mapster('set', true, 'hoi12'); });

There is no area with id="hoi12", your areas have ids like "aTW01".

Q. Do I need jquery UI? -- NO Q. Do I need to assign class="map maphilighted" to my image? -- NO Q. Do I need to assign to where my image is? -- NO

goivan commented 13 years ago

Thank you for your prompt response

I already fix the area with the proper name Remove the class="map maphilighted" Remove the jquery ui library

here is the link

http://brickell-realty.com/im.html

jamietre commented 13 years ago

In that link, the only problem is that jquery is not being loaded, the include: "jscss/jquery-1.5.2.js" is not valid.

I made a local copy of that page and included jQuery and it seems to work fine.

goivan commented 13 years ago

Thanks, It is really nice what you did with maphilight, your work is so much nicer and easy to use!

Now I am back where I started!

Like I mentioned before I had a project pretty much working with "maphilight" under SAFARI but when I tried in IE 8 I had problems so I found your plugin and you mentioned it was compatible with IE plus the additional functionality so I decided to give a shot

So here is what is happening I have two images with image maps with your plugin, they work perfect the container (image) on the left is a selector for what I show in the right container (image) the container in the right gets assigned a new image with a new image map when I click on the left one; when the onclick callback is executed it works fine in SAFARI 5.0.5, FIREFOX 3.6.10 and CHROME 11.0.696.65 but in IE8 it keeps the previous image map and no the new one.

$(document).ready(function () {

$('#bldg-containerID').mapster({
    isSelectable: false,
    mapKey: 'rel',
    listKey: 'name',    
    fillColor: '78aed7',
    fillOpacity: 0.2,
    strokeColor: '185276',
    stroke: 1,
    showToolTip: false,
    onClick: function (e) {bldgSel(e.key);}
});

$('#ksp-containerID').mapster({
    isSelectable: false,
    mapKey: 'rel',
    listKey: 'name',    
    fillColor: '78aed7',
    fillOpacity: 0.2,
    strokeColor: '185276',
    stroke: 1,
    showToolTip: false
});

});

function bldgSel(tofu) { switch (tofu) { case 'th': document.getElementById("ksp").className = "sprite-th"; document.links["largeksp"].href="javascript:iLoad('images-epic/BRG-Epic-SP-TownHouses.pdf');" document.getElementById('ksp-containerID').useMap = "#mapEpicTH_Map"; $('#ksp-containerID').mapster({ isSelectable: false, mapKey: 'rel', listKey: 'name',
fillColor: '78aed7', fillOpacity: 0.2, strokeColor: '185276', stroke: 1, showToolTip: false }); animatedcollapse.show('fp1t') break;

case 'tw':
    document.getElementById("ksp").className = "sprite-tw";
    document.links["largeksp"].href="javascript:iLoad('images-epic/BRG-Epic-SP-Tower.pdf');"
    document.getElementById('ksp-containerID').useMap = "#mapEpicTW_Map";
    $('#ksp-containerID').mapster({
        isSelectable: false,
        mapKey: 'rel',
        listKey: 'name',    
        fillColor: '78aed7',
        fillOpacity: 0.2,
        strokeColor: '185276',
        stroke: 1,
        showToolTip: false
        });
    animatedcollapse.show('fp2t')
break;

case 'lph':
    document.getElementById("ksp").className = "sprite-lph";    
    document.links["largeksp"].href="javascript:iLoad('images-epic/BRG-Epic-SP-LowerPH.pdf');"
    document.getElementById('ksp-containerID').useMap = "#mapEpicLPH_Map";
    $('#ksp-containerID').mapster({
        isSelectable: false,
        mapKey: 'rel',
        listKey: 'name',    
        fillColor: '78aed7',
        fillOpacity: 0.2,
        strokeColor: '185276',
        stroke: 1,
        showToolTip: false
        });
    animatedcollapse.show('fp3t')
break;

case 'uph':
    document.getElementById("ksp").className = "sprite-uph";    
    document.links["largeksp"].href="javascript:iLoad('images-epic/BRG-Epic-SP-UpperPH.pdf');"
    document.getElementById('ksp-containerID').useMap = "#mapEpicUPH_Map";
    $('#ksp-containerID').mapster({
        isSelectable: false,
        mapKey: 'rel',
        listKey: 'name',    
        fillColor: '78aed7',
        fillOpacity: 0.2,
        strokeColor: '185276',
        stroke: 1,
        showToolTip: false
        });
    animatedcollapse.show('fp4t')
break;

case 'lobby':
    document.getElementById("ksp").className = "sprite-lobby";  
    document.links["largeksp"].href="javascript:iLoad('images-epic/BRG-Epic-SP-LobbyLevel.pdf');"
    document.getElementById('ksp-containerID').useMap = "";
break;

case 'pool':
    document.getElementById("ksp").className = "sprite-pool";   
    document.links["largeksp"].href="javascript:iLoad('images-epic/BRG-Epic-SP-PoolLevel.pdf');"
    document.getElementById('ksp-containerID').useMap = "";
break;
}

}

goivan commented 13 years ago

Sorry, Forgot to include a link!

http://brickell-realty.com/tmapper.html

jamietre commented 13 years ago

It looks like the problem is document.links which is not apparently supported in Internet Explorer 8. This is causing the script to crash before it even gets to the $.mapster line, which is why the map is not changing.

In a local copy, I commented out the lines beginning with "document.links" and it worked fine. I would just use a jquery selector instead of the native javascript for each of these, e.g.

$('#largeksp").attr("href") = "...";

instead of document.links["largeksp"].href="..."

goivan commented 13 years ago

Thank you I will have never found it in a million years!

$('#largeksp').attr('href',largefile);

Keep bugging you, with two more questions

If I already have a image map assigned to the image with ID = ksp-containerID wouldn't the following two statements reset it to have none?

document.getElementById('ksp-containerID').useMap = ""; $('#ksp-containerID').mapster();

Is there an easy way to have a single area being selected, what I mean is if I have an area selected and I clicked in a new one then the one that is already selected gets unselected and the new one becomes selected without having to built a list?

Ivan

jamietre commented 13 years ago

For your first question, actually, I don't think that you can can "unbind" imagemapster right now. Never really thought about that. It looks like the code you have above, binding to an image with no "usemap", would do nothing, any previous binding would still be in effect. This is a simple change, I'll update it shortly.

For the 2nd question, I added an option in 1.0.7:

singleSelect: true

will cause only one area to be selectable at a time. I see that I did not update the documentation! So I'll take care of that too. But hang tight for a little while and I'll add a way to unbind it.

jamietre commented 13 years ago

I updated the source code with a new option

(edited) $('img').mapster('unbind');

to remove the mapster binding from an image. The zip has not been updated however so please download from the source repository. I'll update the download when I've tested thoroughly.

goivan commented 13 years ago

Just tried it and it goes nuts,

Here is the testing link: http://www.brickellrealty.com/tmapper1.html

The moment it loads go to the bottom of the page, in the keyplan to the right click on any unit, at this time I load that keyplan in the left container with the singleSelect option and then I load the floorplan in the right container which I applied the new unbind option

document.getElementById("ksp").style.backgroundImage = newimage; document.getElementById("ksp").style.backgroundPosition = fpposition; $('#ksp-containerID').unbind();

jamietre commented 13 years ago

That link isn't working.

jamietre commented 13 years ago

Oh... and I gave you bad information before, oops!

The format is

$('img').mapster('unbind');

Sorry about that

goivan commented 13 years ago

Sorry missed a "-"

http://www.brickell-realty.com/tmapper1.html

goivan commented 13 years ago

Ok, just changed! You can try the link again

So when I clicked on a unit, that unit area stays on, I though about unselecting it myself but that image is set to isSelectable: false; So I can not do it in my side, I Think?

jamietre commented 13 years ago

I pushed an update which does some better exception handling, and cleaned up some issues with unbind (e.g. if it wasn't already bound it didn't work before, now it works fine whether or not the image is bound).. So that works better now, but your code is still showing duplicate images on rollover. The problem has to do with the way you are switching image maps, I think.

In the HTML, bldg-containerID and ksp-containerID are both using the same map #mapEpictw_Map, so when the document.ready code runs, the event handling is bound twice to the same image map. This is why the areas are appearing in both the left and right image when mousing over.

Also - I think you will want to use this code to unbind:

$('#ksp-containerID').mapster('unbind',true);

That leaves the existing state after unbinding, otherwise, it won't persist the selection since you are unbinding as soon as someone clicks on an area.

So - try updating again, which should solve some problems, but I am not sure how to fix the issue with reusing the same image map, I think that's probably a bug that you will know how to fix.

jamietre commented 13 years ago

Oh by the way, I noticed there is a canvas in your html next to bldg-containerID - that doesn't need to be there, mapster will create canvases as needed.

goivan commented 13 years ago

Ok, I will give a shot,

I have not idea about this canvas, I explicitly do not create any canvases myself, I will look into it

By the way I was looking at the documentation and could not see if there is a way to query the plugin for the key for the currently selected area?

Thanks

jamietre commented 13 years ago

Huh - maybe I was looking at post-rendering markup when I saw that canvas, I thought it was in the pure html I pulled down. But I don't see it now, no worries.

To get currently selected areas.... um, ok, that's just hilarious. No there is no way! My use cases have always looked at the external list. I'll add that now, that is some oversight...

goivan commented 13 years ago

I think I know what is happening after I unbind, the routine gets called again so I test if the image have a image map assigned to it to skip the assignment procedure I was trying first this way

if(document.getElementById('ksp-containerID').useMap == "")

then I tried both of these,

if($('#ksp-containerID').attr('usemap') == "") and if($('#ksp-containerID').attr('useMap') == "")

Any suggestions?

jamietre commented 13 years ago

Pushed another update with method to get selections:

$('img').mapster('get') -- gets a comma separated list of keys

$('img').mapster('get','array') -- gets an array of keys

I'm not sure I understand what you're doing with that bit of logic regarding the usemap. Initially, in document.ready, you are creating a mapster for both images, but they both start out with the same image map, so that's confusing things. You probably don't need to bind 'ksp' to anything until someone clicks on an area from the left-hand map.

I would just re-create the mapster for the needed images each time they click on something from the main image, after you set the usemap attribute. You can't change usemap once it's been bound to mapster, or it won't work, it will still think you're using the old map. So just make sure the "usemap" property is correct before rebinding.

You can re-bind mapster to an image that it's already bound to without any harm - it will toss out all the old info, and use just the new.

Does any of that help?

goivan commented 13 years ago

Hi,

I cleanup and commented my code so I did not have to check for an empty useMap attribute but I added three alerts for troubleshooting it seems like the unbind is not releasing the assigned image map.

- These are my two initial containers, they both have different imagemaps

- Here is my init routine

goivan commented 13 years ago

The code got all screw-up, in here. anyhow the link is the same

http://www.brickell-realty.com/tmapper1.html

when you clicked on the right container to switch you will see the alerts with the residues that are being left right after

Thanks

jamietre commented 13 years ago

Ugh somehow I got in a version mess somewhere, apparently i overwrote some changes in the last update I pushed out. I'm fixing it now. I can see exactly what's wrong...

jamietre commented 13 years ago

OK - sorry about that, somehow all the unbind fixes I made after the first push got lost when I added the get, everything is back in now.

Couple things: the way it is now you actually just want to use $('#ksp-containerID').mapster('unbind'); -- without the "true" parameter.

In my local version with the current imagemapster, everything seems to work, except that ksp & bldg have the same map when you drill into a specific unit. (The last alert you put in there shows this). You don't see any highlight effects on the right image, because the right image isn't bound, but what you will see is if you mouse over the right image (which shouldn't have any bindings at all at this level) it will highlight stuff on the left image.

I think all you need to do now is remove the "usemap" from the right image when drilled down to an individual unit to solve this last issue.

I also couldn't figure out how to get back out to the tower :)

jamietre commented 13 years ago

OK - i just pushed another minor change (jQuery chaining was broken on unbind). But if you pull after this comment, this change should be all you need to make it all work:

$('#ksp-containerID').mapster('unbind').attr("usemap","");

goivan commented 13 years ago

Just included the latest change,

I was trying to implement the last thing, the bottom to get back to the building selector, the moment I try

var $tofu = $('#ksp-containerID').mapster('get');

it breaks!

jamietre commented 13 years ago

I have only done basic testing for "get' but it is passing tests from the latest push, so put the code up again and I can take a look. I didn't see anything on the test link from before (though everything else looks like it's working).

goivan commented 13 years ago

Here is the link http://brickell-realty.com/tmapper1.html with the back button routine, I included a couple of alerts, to see if it was getting there or not and to show that it did not pass. Click on any of the units in the right container, right after the back button will appear besides the enlarge "+" button

alert("got to the back button sub");
var tofu = $('#ksp-containerID').mapster('get');
alert("Pass by the get option");
document.getElementById("bldg").style.backgroundImage = url('images-epic/blfp.jpg');
document.getElementById("bldg").style.backgroundPosition = "-0px -0px";
document.getElementById('bldg-containerID').useMap = "#mapEpicbl_Map";
jamietre commented 13 years ago

There's no mapster assigned to the right image at the point you are issuing the "get" - I think what you want to do is capture the selected key from bldg-containerID when they click on something initially, e.g.

var bldgSelID;
function toFloorPlans(tofu)
{
    bldgSelID=$('#bldg-containerID').mapster('get');
   ...
}

Then in fbldg() use that value as the key to preselect the area when you go back to the main image:

$('#bldg-containerID').mapster({
    isSelectable: true,
    singleSelect: true,
    mapKey: 'rel',
    listKey: 'name',
    fillColor: '78aed7',
    fillOpacity: 0.1,
    strokeColor: '185276',
    stroke: 1,
    showToolTip: false,
    areas:  [{key: bldgSelID, selected: true}],
    onClick: function (e) {bldgSel(e.key);}
});

These changes make it show the main building again, though it still doesn't work completely because there are some other bugs (and I don't understand that part of your code enough). But you can probably figure it out from there.

goivan commented 13 years ago

Thanks again, first you were right I was trying to do a 'get' from the wrong container and I am working things from there.

I have a suggestion: What if when selecting 'singleSelect: true;' you could actually do something like singleSelect: "MI", then you know that implicitly it is TRUE you also know that it is the KEY of the FIRST AREA TO BE SELECTED and that within mapster "THERE MUST ALWAYS BE ONE AREA SELECTED" or since you already have a set option is there a way to indicate that "THERE MUST ALWAYS BE ONE AREA SELECTED"

jamietre commented 13 years ago

If I understand you correctly, what about a flag to prevent "unselecting" things? So to generalize that idea, if you did not have "single select" set, then it would only allow you to add new selections. If you did have single select set, then it would mean only one item could ever be selected. (If you had no default selection, then it would mean the only time zero items could be selected would be before they clicked anything). Does that sound right? Seems useful, I can probably add that easily. I want to catch up on the tests for what I've done in the last couple days before actually releasing the current version, but i ought to be able to add that today.

By the way I appreciate this interaction, you're using the tool in a ways that I hadn't thought of (or tested) so it's nice to have a chance to push it a little bit, it will be better & more stable for the exercise.

goivan commented 13 years ago

Hey, it has been my pleasure working with you. By now your product has evolved into more than just a simple plugin but into a full fledge product and a hell of a good one! (excuse my language)

and yes, that is exactly what I meant!

goivan commented 13 years ago

Hi Jamie, I finished the back button routine and been beating myself to death testing it out, I believe the routine is ok but I may be wrong! You can check it out and see that it basically works but there are residues being left. Please take a look at it. I am so excited I have been trying to do this type of functionality for years without flash and wow it is so close. I am very grateful for your help. Thanks, Ivan http://brickell-realty.com/tmapper1.html

jamietre commented 13 years ago

I'll take a look shortly. I just pushed up another update, there are a few bug fixes, so you can try that, but I will also look at your current dev version. Also added a new option

isDeselectable = true | false

When set to "true" at the global level, nothing can be deselected by the user. So if you combine this with singleSelect it means that only one item will ever be selected (or zero, if there was nothing selected by default, until someone clicks something).

There is one more new option that you may or may not need, it's this:

$('img').mapster('rebind',options);

where options is the same as options passed initially. This is used to refresh an existing mapster with updated options, e.g. if you wanted to change the "isSelectable" state of something. If there are default settings in "options" for a state they will be applied immediately as well. I will update the docs later today.

jamietre commented 13 years ago

I pulled down your latest version and, using the version of imagemapster I just pushed, it seemed to work perfectly! I think I must have caught whatever bug was tripping you up when I updated all the tests. Let me know if it's working for you now.

goivan commented 13 years ago

Hi, just downloaded the new plugin and replace all "isSelectable" with "isDeselectable:false" everything works perfect under Safari, Firefox and Chrome but not in IE8 & IE9 it seems like the isDeselectable is not working right I started looking around and decided just in case to replace all the "document.getElementById('bldg-containerID').useMap = bldgcontainermap;" with the equivalent in jquery "$('#bldg-containerID').attr({ useMap: bldgcontainermap });" but it didn't do anything. (screwballs to IE!)

Any suggestions?

jamietre commented 13 years ago

Argh. I can see there's some singleSelect problem in IE, looking into it now.

jamietre commented 13 years ago

All right! I found the problem, have tested it in IE6, IE7 and IE9 (I can't easily test in 8, but it's not often things that work in 6&7 don't work in 8) and everything seems copacetic. Pull down the latest code and try it again.

goivan commented 13 years ago

Yes, it seems it is working now, I am preparing for a final release myself so now that everything seems to be working I am going to do some heavy duty testing. I am going to check my whole code again to see if I can simplify.

Again and again I can not tell you how grateful I am for your help, you are a very talented developer not only good writing code but understanding other people necessities. I will keep you posted. Thanks a million!

jamietre commented 13 years ago

Great! If you don't mind, let me know when it's online, I'd like to link to it as an example.