Jquery Click Handler Not Working After Two Times - javascript

I am facing a little strange problem. I am using bing translator (http://www.bing.com/widget/translator) and trying to customize it on my own using their API.
Here is my code for testing purposes.
Script:
$(document).ready(function (e) {
var lang;
$('#changeLang a').click(function (e) {
Microsoft.Translator.Widget.Translate(null, 'en', null, null, function () {
lang = Microsoft.Translator.Widget.GetAutoDetectedLanguage();
alert(lang)
});
document.getElementById('WidgetFloaterPanels').style.display = 'none';
var to = $(this).attr('id');
if (to == "en") {
Microsoft.Translator.Widget.Translate(lang, 'en');
document.getElementById('WidgetFloaterPanels').style.display = 'none';
} else if (to == "ja") {
Microsoft.Translator.Widget.Translate(lang, 'ja');
document.getElementById('WidgetFloaterPanels').style.display = 'none';
} else if (to == "fr") {
Microsoft.Translator.Widget.Translate(lang, 'fr');
document.getElementById('WidgetFloaterPanels').style.display = 'none';
} else if (to == "ru") {
Microsoft.Translator.Widget.Translate(lang, 'ru');
document.getElementById('WidgetFloaterPanels').style.display = 'none';
}
});
}); //ready ends
HTML:
<div id="changeLang">
English
Japenese
French
Russia
</div>
<div>This paragraph needs to be translated</div>
Now, the script is working fine as it should but for the first two times. For example, if i click on Japenese, the page would translate accordingly, and if i click back to english or any other language, the page will be translated accordingly. But after the second time, if i click third time on any language. The function does not work. But it should work like it was working in the first two clicks. I have tried several hours but can't get it to work so i opened the questions. Please someone point it out to me what is wrong.

It seems that Microsoft script changes the HTML structure during the translation process. Because of this you have to use delegation: instead of $("#changeLang a").on("click", handler) you will do $('#changeLang').on("click", "a", handler). Also, your code can be simplified:
var lang;
$('#changeLang').on("click", "a", function (e) {
var to = $(this).attr('id');
console.log("Translating from ", lang, " to ", to);
Microsoft.Translator.Widget.Translate(lang, to);
lang = to;
});
JSFIDDLE

Related

$(this).hide() hides containers it shouldn't

I have this little piece of code that filters through a list of results and hides the divs that don't match. I am writing this for a PhoneGap iOS application. It works fine on Android, but on iOS for some reason it hides the entire search field as well after typing a few characters, not just the results.
Any idea why? I've stripped it down to almost only the HTML code and jQuery and it's still happening. I tried commenting out the $(this).hide(); part and it stops hiding the search field, so I assume somehow that's the culprit, but I can't figure out why or how to fix this. Been at it for 10 hours straight. Any ideas? Maybe I can target the results some other way?
$('#box_search').keyup(function() {
var valThis = $(this).val().toLowerCase();
if (valThis == "") {
$('#listing-results > .listing_container').show();
} else {
$('#listing-results > .listing_container').each(function() {
var text = ($(this).find('.listing_results_text_name').text() + $(this).find('.listing_results_text_name').data("alt")).toLowerCase();
if (text.indexOf(valThis) >= 0) {
$(this).show();
} else {
$(this).hide();
}
});
};
});
obviously I cant see the html but sometimes it helps to clean the code and just change the logic slightly
var box_search = function(e){
var myIndex = $(this).val();
val = (!myIndex || myIndex==='')?false:myIndex;
if(!myIndex){
$('#listing-results > .listing_container').show();
return;
}
//
$('#listing-results > .listing_container').each(function() {
var text = $(this).find('.listing_results_text_name').text() +
$(this).find('.listing_results_text_name').data("alt")
text = (!text || text==='')?false:text;
text = text.toLowerCase();
if(text.indexOf(myIndex.toLowerCase()) >= 0){
$(this).show();
return;
}
$(this).hide();
});
} //end of function
$('.box_search').keyup(box_search);

Click to enlarge image, then click again to make it go back to previous size

I want to be able to click on an image, have it become big, and then when I click it again, make it go back to being small. I'm trying to use an if/else statement to solve this problem, but I still can't figure it out. This is the JS I have so far:
document.addEventListener("DOMContentLoaded", function(event) {
var thumbnailElement = document.getElementById("smart_thumbnail");
if (thumbnailElement.className === "small") {
thumbnailElement.addEventListener("click", function() {
thumbnailElement.className = "";
});
} else {
thumbnailElement.addEventListener("click", function() {
thumbnailElement.className = "small";
});
}
});
And the HTML for the image:
<img class="small" id="smart_thumbnail" src="http://4.bp.blogspot.com/-QFiV4z\
3gloQ/ULd1wyJb1oI/AAAAAAAAEIg/LE1Kakhve9Y/s1600/Hieroglyphs_Ani-papyrus.jpg">
I'm simply wanting to get rid of the "small" class on the id "smart_thumbnail" to make it big and put the "small" class back to make it small again, but I can only make it big. When I click on it the 2nd time, it doesn't do anything. I've tried an if/else if statement and that didn't work. I looked on here for the same question, but could only find stuff about jQuery. Trying to solve this with JavaScript only.
Any help greatly appreciated. Thanks!
The problem is that the code above will only be run once: After loading your site. So only one condition is fullfilled (thumbnailElement.className === "small")
What you want is something along the lines of:
var thumbnailElement = document.getElementById("smart_thumbnail");
thumbnailElement.addEventListener("click", function() {
if (this.className === "small")
this.className = "";
else
this.className = "small";
});
This will check the class when clicking the image.
Alternatively, you can also use classList.toggle
The DOMContentLoaded event only fires once, that is, when the page is loaded. Instead run your if-statement on a per-click basis.
For example
thumbnailElement.addEventListener("click", function() {
if (thumbnailElement.className === "small") {
thumbnailElement.className = "";
} else {
thumbnailElement.className = "small";
}
});
Now you will register the click event once, but every time it is clicked it will check the classname logic and apply the class name appropriately.

creating simple JS with PHP

I am trying to recreate the JS below with PHP. The reason is that the numbered classes and values are actually IDs pulled from a mysql database. I have an area where say a report is creating, the code below shows and hides rules for that report. Since different reports have different rules, it shows and hides rules dependent on the grouping, determined in the code below as #rule_who.
When trying to recreate the following I was trying to use while loops however it got pretty ridiculous. Is there a more efficient way in JavaScript or AJAX to show and hide divs that would be better suited to using a large number of divs? The 2,3,4, and so on shouldn't be an incrementing number as it would rely on IDs and thus some numbers will disappear over time as reports are deleted.
Any help would be appreciated. Thanks
<script>
//<![CDATA[
$(window).load(function(){
$(".2").hide();
$(".3").hide();
$(".4").hide();
$('#rule_who').on('change', function () {
if(this.value === "2"){
$(".2").show();
$(".3").hide();
$(".4").hide();
} else if(this.value === "3"){
$(".2").hide();
$(".3").show();
$(".4").hide();
} else if(this.value === "4"){
$(".2").hide();
$(".3").hide();
$(".4").show();
} else {
$(".2").hide();
$(".3").hide();
$(".4").hide();
}
});
});//]]>
</script>
EDIT: Thanks everyone for the help.
What I ended up using was the following:
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
$("#rule_who").change(function() {
$("div.specific_rules").hide();
var targetId = $(this).val();
console.log($(targetId).html());
// show the new selected one
$("#"+targetId).show();
});
});//]]>
</script>
I think you can do:
$('.' + this.value).show();
$('.' + this.value).siblings().hide();
Try this (FIDDLE EXAMPLE HERE):
$('.1, .2, .3').hide();
$(window).load(function(){
$('#rule_who').on('change', function () {
var elems = document.getElementsByTagName('div');
for (var i = 0; i < elems.length; i++) {
if (elems[i].className != this.value) {
elems[i].style.display = 'none';
} else {
elems[i].style.display = 'block';
}
}
});
});

autosuggestion box, set focus

Been knocking up a simple suggestion box on an input field.. all working as it should so far except for two issues I can't seem to resolve:
1) when onkeypress event fires, the value of the input box is not correct - it misses off the last character! So for e.g. if you enter 3 chars only first two get carried through. so sometimes suggestions aren't totally accurate!
2) I need to watch out for users pressing the arrow down key, and then set focus to the first list item in the suggestion box! Can't seem to get this working though!
Have included code for you to look at! Any suggestions welcomed.. However I don't really want to use a plugin seeing as I have this 95% done already..
Here is the jsfiddle link!
http://jsfiddle.net/beardedSi/kr4Cq/
Note - I just noticed that in the fiddle verison as I have put dummy array in the code it is no longer matching suggestions - but this doesn't matter, it works fine in my working code!
work = true;
function finish() {
work = true;
}
var autoComp = $('.autoComp');
var skillInput = $('.new-skills input');
$('.new-skills input').keypress(function (e) {
var param = $(skillInput).val();
if (param.length > 0) {
$.getJSON('/recruiter/home/GetAutocompleteSkills?term=' + param, function (data) {
$(autoComp).slideDown().empty();
var items = [];
$.each(data, function (key, val) {
items.push('<li>' + val + '</li>');
});
$(autoComp).append(items.join(''));
$('.base-wrapper a').not('.button').click(function (e) {
work = false;
e.preventDefault();
$(skillInput).val($(this).text());
$(autoComp).empty().slideUp(500, finish);
});
});
}
});
$(skillInput).keydown(function (e) {
if (e.keyCode == 40) {
console.log("down");
$('.autoComp li:first:child').focus();
}
});
$('.new-skills input').blur(function () {
if (work == true)
$(autoComp).slideUp();
});

Checkbox click script - [SHIFT] check/uncheck range, [CTRL] check/uncheck all -- based on select name?

Would anyone know of a ready-made script or plugin providing:
-Shift click for check/uncheck all in range
-CTRL click to select or unselect all
That can works off the check inputs 'name' (instead of all on a page or all inside a div):
input[name='user_group[]']
input[name='record_group[]']
I've been using a couple of scripts (javascript and jQuery) but they're based on all checkboxes in a div or table and I'm not smart enough to roll my own or modify another script. Google searching on this has been a little difficult (too many common terms I think)...
Thanks Much Appreciated!
I started playing around with this script, although it's missing a CTRL+Click feature (select all/none control).
In it's original form it works against all checkboxes on a page. I changed the "$('input[type=checkbox]').shiftClick();" linke to "$("input[name='selected_employees[]']").shiftClick();" and as far as I can tell it seems to be working perfectly now against only the single checkbox group.
The only flaw (for my requirements) is there is not a CTRL+Click function to toggle check or un-check all checkboxes in the group.
<script type="text/javascript">
$(document).ready(function() {
// shiftclick: http://sneeu.com/projects/shiftclick/
// This will create a ShiftClick set of all the checkboxes on a page.
$(function() {
$("input[name='selected_employees[]']").shiftClick();
// $('input[type=checkbox]').shiftClick();
});
(function($) {
$.fn.shiftClick = function() {
var lastSelected;
var checkBoxes = $(this);
this.each(function() {
$(this).click(function(ev) {
if (ev.shiftKey) {
var last = checkBoxes.index(lastSelected);
var first = checkBoxes.index(this);
var start = Math.min(first, last);
var end = Math.max(first, last);
var chk = lastSelected.checked;
for (var i = start; i < end; i++) {
checkBoxes[i].checked = chk;
}
} else {
lastSelected = this;
}
})
});
};
})(jQuery);
});
</script>
I believe this should work!
Working demo on jsFiddle: http://jsfiddle.net/SXdVs/3/
var firstIndex = null;
$(":checkbox").click(function(e) {
$this = $(this);
if (e.ctrlKey) {
if ($this.is(":checked")) {
$("input[name='"+ $this.attr("name") +"']").attr("checked", "checked");
} else {
$("input[name='"+ $this.attr("name") +"']").removeAttr("checked");
}
} else if (e.shiftKey) {
$items = $("input[name='"+ $this.attr("name") +"']");
if (firstIndex == null) {
firstIndex = $items.index($this);
} else {
var currentIndex = $items.index($this);
var high = Math.max(firstIndex,currentIndex);
var low = Math.min(firstIndex,currentIndex);
if ($this.is(":checked")) {
$items.filter(":gt("+ low +"):lt("+ high +")").attr("checked", "checked");
} else {
$items.filter(":gt("+ low +"):lt("+ high +")").removeAttr("checked");
}
firstIndex = null;
}
}
});

Categories

Resources