variable in selector for click() not working - javascript

I have some buttons that should respond to a jQuery script. The buttons are to zoom and pan a svg image on a webpage. Because I want to have more than 1 svg files on a page a need my code to know which image I want to zoom. I can also use my mouse to zoom and pan (dragging), this works fine.
Short example
var currentID;
//get the id of the container around the image. This is: 'SVGfile' followed by a number
jQuery( ".svgcontainer" ).mousemove(function( event ) {
currentID = jQuery(this).attr('id');
});
var target1='#zoomInButtonSVGfile1';
var target2='#panRightButton'+currentID;
jQuery(target1).click(function(){ zoomIn(); }); //this works, but is hardcoded
jQuery("#zoomOutButtonSVGfile1").click(function(){ zoomOut(); }); //this works, but is hardcoded
jQuery(target2).click(function(){ panRight(); }); //this doesn't work
jQuery('#panLeftButton'+currentID).click(function(){ panLeft(); });//this doesn't work
In the first 2 opties I don't use the variable, but hardcode it, and then it works, but it doesn't serve my purpose.
The other 2 options should works as far as I know, and after searching for options. Somehow it does nothing... Can anybody spot my mistake?

If you are going to set a variable and then use it in order to bind an event, the event binding must also happen within the .mousemove.
jQuery( ".svgcontainer" ).mousemove(function( event ) {
if(!jQuery(this).data("bind")){
jQuery(this).data("bind", true);
var currentID = jQuery(this).attr('id');
var target1='#zoomInButtonSVGfile1';
var target2='#panRightButton'+currentID;
jQuery(target1).click(function(){ zoomIn(); });
jQuery("#zoomOutButtonSVGfile1").click(function(){ zoomOut(); });
jQuery(target2).click(function(){ panRight(); });
jQuery('#panLeftButton'+currentID).click(function(){ panLeft(); });
}
});

Related

Access a JQuery object in multiple event handlers

I am new to JQuery and web development in general and hence facing a troubling issue during development. My website interface looks like below:
When a user clicks on any checkbox (for referral purposes, I have selected the box above 'chk2') and then clicks on the 'Show Evidence' button (box 2 in the image), I want the user to be able to highlight portions of the article displayed in the adjacent iframe. I am using a text highlighter Jquery plugin I found on the web. The code for the click event of the 'Show Evidence' button looks like:
$('.show_evidence').click(function(event){
var iframe = document.getElementById('myiFrame');
var hltr = new TextHighlighter(iframe.contentDocument.body);
hltr.setColor("yellow");
});
The above code works fine.
Now, I want to set the highlight color (i.e. hltr.setColor("blue")) to blue when the user clicks on the checkbox 'Unselect' (box 3 in the image). For that I need to be able to access the 'hltr' object I have defined above (i.e. inside the 'click' event handler for '.show_evidence'). Also I want to set the highlight color back to 'yellow' when the user unchecks the 'Unselect' checkbox.
$(".unselect").change(function() {
if(this.checked) {
//Something like - hltr.setColor("blue");
}
else {
// Something like - hltr.setColor("yellow");
}
});
Finally, I also want to unset or undefine the object 'hltr' when the user clicks on the link 'Hide Datums' (box 1 in the image).
So my question is how do I access the hltr object inside the event handlers for .Unselect and the 'Hide Datums' link.
After a lot of stackoverflow surfing, I found that I could use external variables but I am not sure whether that will work for objects. Also, is there a universally recommended design that I should use or follow? What is the best way to achieve what I want?
Looking forward to your suggestions. Please help!
Regards,
Saswati
One way you can go about is extract the lines of code which does the element selection to a separate method.
var hltr;
function getBodyElementOfIframe() {
var iframe = document.getElementById('myiFrame');
if(!hltr) {
hltr = new TextHighlighter(iframe.contentDocument.body);
}
return hltr;
}
Call that method where you want to access the element and then set the color.
$(".unselect").change(function() {
var hltr = getBodyElementOfIframe();
if(this.checked) {
hltr.setColor("blue");
}
else {
hltr.setColor("yellow");
}
});
There are a number of ways to solve it, but one simple way to do it would be to move the variable outside the scope of the method so that it is accessible through out.
I would put it inside on ready.
$(document).ready(function () {
var hltr = {};
$('.show_evidence').click(function(event){
var iframe = document.getElementById('myiFrame');
hltr = new TextHighlighter(iframe.contentDocument.body);
hltr.setColor("yellow");
});
$(".unselect").change(function() {
if(this.checked) {
//Something like - hltr.setColor("blue");
}
else {
// Something like - hltr.setColor("yellow");
}
});
})();
If you need the variable inside several functions, declare it outside of all of them.
$(function(){
var iframe = document.getElementById('myiFrame');
var hltr = new TextHighlighter(iframe.contentDocument.body);
$('.show_evidence').click(function(event){
hltr.setColor("yellow");
});
});
When your event handlers fire, they'll be updating this var and it will be accessible to the next handler called.

Can't drag dynamically added DIV

I have a DIV with id: TEST that I can drag using jQuery UI. All works, but as soon as I remove it and load the DIV into the HTML dynamically (well to specify more: using SSE to load the DIV into the HTML), the DIV can't be dragged. This is because the jQuery is loaded before the DIV is. How to fix this? Since I use SSE, the DIV is loaded several times over a period of time.
The jquery code:
$(function() {
$( "#TEST" ).draggable({
containment: "parent"
}).css({'cursor': 'all-scroll', 'z-index': '5'});
});
The DIV TEST is loaded into antoher DIV called dragZone
<div id="dragZone" name="dragZone"> [div TEST is loaded here] </div>
The JS that loads the SSE:
//HTML5 SSE(Server Sent Event) initilization
this.initSevr=function(){
sevr = new EventSource('test.php');
sevr.onmessage = function(e){
if(oldata!=e.data){
dragZone.innerHTML+=e.data;
oldata = e.data;
}
};
};
So how can I drag the DIV again? The Div is put into the HTML using SSE, this all works.
You will probably need to move your draggable code into the loading event, like this:
//HTML5 SSE(Server Sent Event) initilization
this.initSevr=function(){
sevr = new EventSource('test.php');
sevr.onmessage = function(e){
if(oldata!=e.data){
dragZone.innerHTML+=e.data;
oldata = e.data;
$( "#TEST" ).draggable({
containment: "parent"
}).css({'cursor': 'all-scroll', 'z-index': '5'});
}
};
};
This is assuming the DOM is updated immediately after innerHTML is used; if not it may be necessary to use a short setTimeout to make it draggable.
I think you forgot a quote, try to change from
sevr = new EventSource('test.php);
to
sevr = new EventSource('test.php');

Javascript onclick event firing for id but not for class

I'm fairly new to Javascript, and am trying to get an 'on click enlarge' kind of effect, where clicking on the enlarged image reduces it again. The enlarging happens by replacing the thumbnail by the original image. I also want to get a slideshow using images from my database later on.
In order to do that, I made a test where I replace the id which indicates enlarging is possible by a class and I also use a global variable so that I can keep a track of the url I'm using. Not sure this is the best practice but I haven't found a better solution.
The first part works fine, my image gets changed no problem, values are also updated according to the 'alert' statement. However, the second part, the one with the class never triggers.
What am I doing wrong (apart from the very likely numerous bad practices) ?
If instead of changing the class I change the id directly (replacing .image_enlarged by #image_enlarged, etc.), it seems to call the first function, the one with the id, yet outputs the updated id, which is rather confusing.
var old_url = "";
$(function(){
$('#imageid').on('click', function ()
{
if($(this).attr('class')!='image_enlarged'){
old_url = $(this).attr('src');
var new_url = removeURLPart($(this).attr('src'));
$(this).attr('src',new_url); //image does enlarge
$(this).attr('class',"image_enlarged");
$(this).attr('id',"");
alert($(this).attr('class')); //returns updated class
}
});
$('.image_enlarged').on('click', function (){
alert(1); //never triggered
$(this).attr('src',old_url);
$(this).attr('class',"");
$(this).attr('id',"imageid");
});
});
function removeURLPart(e){
var tmp = e;
var tmp1 = tmp.replace('thumbnails/thumbnails_small/','');
var tmp2 = tmp1.replace('thumbnails/thumbnails_medium/','');
var tmp3 = tmp2.replace('thumbnails/thumbnails_large/','');
return tmp3;
}
As for the html, it's really simple :
<figure>
<img src = "http://localhost/Project/test/thumbnails/thumbnails_small/image.jpg" id="imageid" />
<figcaption>Test + Price thing</figcaption>
</figure>
<script>
document.write('<script src="js/jquery-1.11.1.min.js"><\/script>');
</script>
<script type="text/javascript" src="http://localhost/Project/js/onclickenlarge.js"></script>
From the API: http://api.jquery.com/on/
The .on() method attaches event handlers to the currently selected
set of elements in the jQuery object.
When you do $('.image_enlarged').on(...) there is no element with that class. Therefore, the function is not registered in any element.
If you want to do so, then you have to register the event after changing the class.
Here's an example based on your code: http://jsfiddle.net/8401mLf4/
But this registers the event multiple times (every time you click) and it would be wrong. So I would do something like:
$('#imageid').on('click', function () {
if (!$(this).hasClass('image_enlarged')) {
/* enlarge */
} else {
/* restore */
}
}
JSfiddle: http://jsfiddle.net/8401mLf4/2/
Try using:
addClass('image-enlarged')
instead of:
.attr('class',"image_enlarged");
the best way to do this would be to have a small-image class and a large image class that would contain the desired css for both and then use addClass() and removeClass depending on which you wanted to show.

Click function on dynamic created elements that shows content of clicked element

I have created a search page that has on top and bottom page navigation. This is a simplified version just to show my problem:
$(function(){
$("select").on("click" , function(){
if ($(this).val() == 10){
var total_pages = 3;
}
else{
var total_pages = 5;
}
var pages = "";
for (var i = 1; i <= total_pages; i++) {
var pages = pages + "<span class='page'>" + i + "</span>";
}
$(".pagination").html(pages);
});
$("select").click();
$(".page").on("click" , function(){
alert($(this).text());
});
});
And you can try it yourself here:
JSFiddle
In this example you have 5 pages when you select 10 items per page and 3 pages for 20 results per page. But when you select an other value per page the alert function doesn't show up anymore. It seems that changes, after the document is loaded, are not being noticed by the document.ready function.
I searched and saw a lot of familiar questions and their solutions. I can imagine also some alternatives but not the one who can satisfy me. Because unfortunately I don't know now a simple solution without a lot of extra code with id's, classes, data-attributes etc. Who can contribute me some knowledge for a good solution?
That's because when you do this:
$(".pagination").html(pages);
You remove old DOM elements and it's "click" functions and replace it with new HTML.
Add this:
$(".page").on("click" , function(){
alert($(this).text());
});
right after first line I mentioned
Event delegation is a good practice when you deal with dynamic content. In your case, you can attach the click event to the parent.
I just tweaked one line in your original code:
$(".pagination").on("click" , ".page" , function(){
alert($(this).text());
});
Live demo: http://jsfiddle.net/zkDF4/6/

jQuery event delegation with non-trivial HTML markup?

I have two DIVs, first one has a link in it that contains the id of the second DIV in its HREF attribute (complete setup on jsbin).
I want to animate the second DIV when user clicks on the first - anywhere on the first. I also want to use event delegation because I'll have many such "DIV couples" on a page (and I'm using a JS snippet from this SO answer).
If user clicks on the DIV itself, it will work - just check firebug console output. The problem is, if user clicks on one of the SPANs or the link itself, it doesn't work anymore.
How can I generalize the click handler to manage clicks on anything inside my DIV?
Here's the JS:
$('#a').click(function(e) {
var n = $(e.target)[0];
console.log(n);
if ( n && (n.nodeName.toUpperCase() == 'DIV') ) {
var id = $(n).find('a').attr('hash');
console.log(id);
$(id).slideToggle();
}
return false;
});
It took me so long to write up the question that I decided to post it anyway, perhaps someone suggests a better way.
Here's the solution I found (jsbin sandbox):
$('#a').click(function(e) {
var n = $(e.target)[0];
var name = n.nodeName.toLowerCase() + '.' + n.className.toLowerCase();
if (n && (name === "div.clicker" || $(n).parents("div.clicker").length )) {
var id = $(n).find('a').attr('hash');
if(!id) {
id = $(n).parents("div.clicker").find('a').attr('hash');
}
console.log(id);
}
return false;
});
Here is my solution. Not sure if that's exactly what you wanted, but it works for me.
$(document).ready(function() {
$('#a').click(function() {
var a = $("a", this);
$(a[0].hash).slideToggle();
});
});
Edit: Tested in both IE7 and Fx3
Edit: In that case...
$(function() {
$("a.tab").click(function() {
$($(this).attr("hash")).slideToggle();
return false;
});
});
Something like that might work (putting the tab class on anything that has a div "attached" to it). However, I'm not sure unless I actually see an example of it. Although if you want it to work when clicking on the span...you would attach the class to the span, and instead do:
$(function() {
$("span.tab").click(function() {
var a = $("a",this);
$(a.attr("hash")).slideToggle();
});
});
Not sure if you want an open div to close if another one is opened. If this doesn't solve your problem, it would help if you would put up an example on jsbin...

Categories

Resources