Elements out of scope? - javascript

I am having some trouble with elements being outside scope or something but I am not getting any errors so I am not really sure how to fix it. I've shrunk up my code below to include what is relevant.
(function(){
var zdf = {
theme : $('#zdf_theme')
};
zdf.setupPopup = function(){
zdf.loadThemes();
}
zdf.loadThemes = function() {
zdf.theme
.editableSelect({
effects: 'slide'
})
.on('select.editable-select', function(e, li) {
zdf.theme.attr("data-value", li.attr('value'));
});
});
}
}();
Hopefully I've provided enough code to identify the problem but basically everything is working up until the line
zdf.theme.attr("data-value", li.attr('value'));
It doesn't seem to select the object zdf.theme
If I replace it with the actual selector $('#zdf_theme') it works fine.
The editable select is this code base https://github.com/indrimuska/jquery-editable-select
Any input would be great!

Solution... editable select was replacing my input so I needed to redefine it after initializing the editable select.

Related

How to run a jQuery function only for child elements?

I'm trying to collapse all child comments including the parent comment when some clicks on the icon nested inside parent comment.
With below jQuery code I was able to get the comments box collapse but now the comments located inside another section are also getting collapsed.
jQuery code -
$('.comment-toggle pre').on('click', function(e) {
$(".single-comment-wrapper .comment-text, .single-comment-wrapper .comment-bottom, .single-comment-outer .child-comment ").slideToggle('fast', function() {
if ($(this).is(':visible')) {
$(".comment-toggle pre").text('[–]');
} else {
$(".comment-toggle pre").text('[+]');
}
});
});
$('.comment-toggle pre').on('click', function(e) {
$('.single-comment-wrapper .left-side').slideToggle('fast');
});
Since HTMLand CSS was too long. I've created a codepen. Below is the direct link to it.
https://codepen.io/anon/pen/Vzrvbm
Thanks in advance.
The structure of your divs makes this tricky, I've been playing around on the fiddle for ~10mins and have come up with this - its heading in the right direction but not perfect...
$('.comment-toggle pre').on('click', function(e) {
$(this).parents('.single-comment-wrapper').next().slideToggle('fast', function() {
All the plus and minuses change because currently your code is targeting classes, it needs to change to be relative to the +/- clicked so $(this). etc
Update you jQuery to search elements relative to your clicked element:
$('.comment-toggle pre').on('click', function(e) {
// find main comment element
var rootComment = $(this).closest('.single-comment-wrapper');
// hide child comments of current comment
var children = rootComment.parent().find('>.child-comment');
children.slideToggle('fast');
// hide left part
rootComment.find('.left-side').slideToggle('fast');
// hide current comment
rootComment.find('.comment-text').toggle('fast', function() {
if ($(this).is(':visible')) {
rootComment.find(".comment-toggle pre", this).text('[–]');
} else {
rootComment.find(".comment-toggle pre", this).text('[+]');
}
});
});
Also, if you can change markup to include children elements in the context of the main comment element it would be much more easier to work with. Tree-like view based on ul would simplify markup and reduce amount of HTML elements.
I think, you should use different classes for divs. Because when you click .content-togle class, javascript code executes actions for all .single-comment-wrapper .comment-text, .single-comment-wrapper .comment-bottom, .single-comment-outer .child-comment classes.

for loop vs forEach in JavaScript -- example from book

I am currently learning JavaScript using O'Reilly's "Learning Web Application Development". In the example, we are constructing a website using HTML and CSS, which includes 3 tabs which should be able to be selected and become the "active" tab. The books claims that the following two ways of writing the tab code are equivalent:
1)
var main = function() {
"use strict";
var tabNumber;
for (tabNumber=1;tabNumber<=3;tabNumber++) {
var tabSelector = ".tabs a:nth-child("+tabNumber+") span";
$(tabSelector).on("click",function() {
$(".tabs span").removeClass("active");
$(tabSelector).addClass("active");
$("main .content").empty();
return false;
});
}
}
$(document).ready(main);
2)
var main = function() {
"use strict";
$(".tabs a span").toArray().forEach(function(element) {
$(element).on("click", function() {
console.print("this element: " + element);
$(".tabs span").removeClass("active");
$(element).addClass("active");
$("main .content").empty();
return false;
});
});
}
$(document).ready(main);
However, they do not output the same result. The version using forEach works correctly, so that when I click one of the tabs the attention moves to that tab and it becomes highlighted. However, in the version using a for loop, whenever I click any tab, the attention always moves to the last tab. To confirm what is happening, I printed out the name of the element inside the event listener with both methods, using 3 tabs total. And using the for loop, no matter which tab I click I am getting a response of
"this element: .tabs a:nth-child(3) span"
Could someone please help me explain why this is happening? Why is the output different using for or forEach? And why, using for, is it always passing the last element of tabs to the event listener?
Looks like there's a problem here:
var tabSelector = ".tabs a:nth-child("+tabNumber+") span";
$tabSelector.on("click",function(){
You've created a variable that doesn't have the $ at the beginning, then attached the event to a variable (not sure what it would refer to) with a $ at the beginning.
It should be changed to this, I believe:
$(tabSelector).on("click",function(){
In the for loop solution, you are setting tabSelector multiple times like so:
var tabSelector = ".tabs a:nth-child("+tabNumber+") span";
This selector is, in the end, going to be set to the last tabNumber, which is always going to be called when you make a reference to it:
$(tabSelector).addClass("active");
To avoid that, replace it by this, which will be different for each of them:
$(this).addClass("active");
JS Fiddle Demo

TinyMCE opened in jqueryUI modal dialog

When using tinyMCE in a jqueryUI modal dialog, I can't use the hyperlink or 'insert image' features.
Basically, after lots of searching, I've found this:
http://www.tinymce.com/develop/bugtracker_view.php?id=5917
The weird thing is that to me it seams less of a tinyMCE issue and more of a jqueryUI issue since the problem is not present when jqueryUI's modal property is set to false.
With a richer form I saw that what happens is that whenever the tinyMCE loses focus, the first element in the form gets focus even if it's not the one focused / clicked.
Does some JavaScript guru have any idea how I might be able to keep the dialog modal and make tinyMCE work?
This fixed it for me when overriding _allowInteraction would not:
$(document).on('focusin', function(e) {
if ($(event.target).closest(".mce-window").length) {
e.stopImmediatePropagation();
}
});
I can't really take credit for it. I got it from this thread on the TinyMCE forums.
(They have moved their bugtracker to github. tinymce/issues/703 is the corresponding github issue.)
It seems there are no propper solution for this issue yet. This is kind of a hack but it really worked for me.
Every time you open the Dialog remove the text area and re add it like following,
var myDialog = $('#myDialog');
var myTextarea = myDialog.find('textarea');
var clonedTextArea = myTextarea.clone(); // create a copy before deleting from the DOM
var myTextAreaParent = myTextarea.parent(); // get the parent to add the created copy later
myTextarea.remove(); // remove the textarea
myDialog.find('.mce-container').remove(); // remove existing mce control if exists
myTextAreaParent.append(clonedTextArea); // re-add the copy
myDialog.dialog({
open: function(e1,e2){
setTimeout(function () {
// Add your tinymce creation code here
},50);
}
});
myDialog.dialog('open');
This seems to fix it for me, or at least work around it (put it somewhere in your $(document).ready()):
$.widget('ui.dialog', $.ui.dialog, {
_allowInteraction: function(event) {
return ($('.mce-panel:visible').length > 0);
}
});

.removeClass not functioning within .replaceWith

I'm trying to make a button that will hide a specific -- and then replace it with another hidden . However, when I test the code, everything fires correctly except for the .removeClass which contains the "display: none."
Here is the code:
<script type="text/javascript">
$(document).ready(function(){
var webform = document.getElementById('block-webform-client-block-18');
var unmarriedbutton = document.getElementById('unmarried');
var buyingblock = document.getElementById('block-block-10');
$(unmarriedbutton).click(function () {
$(buyingblock).fadeOut('slow', function() {
$(this).replaceWith(function () {
$(webform).removeClass('hiddenbox')
});
});
});
});
</script>
The CSS on 'hiddenbox' is nothing more than "display: none.'
There is a with the id of unmarried, which when clicked fades out a div and replaces it with a hidden div that removes the class to reveal it. However, the last part doesn't fire -- everything else does and functions properly. When I look at in the console too, it shows no errors.
Can someone please tell me where the error is? Thanks!
Edit: I may be using the wrong function to replace the div with, so here's the site: http://drjohncurtis.com/happily-un-married. If you click the "download the book" button, the the div disappears and is replaced correctly with the div#block-webform-client-block-18. However, it remains hidden.
The function you pass to replaceWith has to return the content you want to replace it with. You have to actually return the content.
I don't know exactly what you're trying to accomplish, but you could use this if the goal is to replace it with the webform object:
$(this).replaceWith(function () {
return($(webform).removeClass('hiddenbox'));
});
NB, use jquery !
var webform = $('#block-webform-client-block-18');
var unmarriedbutton = $('#unmarried');
var buyingblock =$('#block-block-10');
unmarriedbutton.click(function () {
buyingblock.fadeOut('slow', function() {
$(this).replaceWith( webform.removeClass('hiddenbox'));
});
});
Was too fast, i believe it's the way you select your object (getelementbyid) then you create a jquery object from it... -> use jquery API

JQuery Hover Code: Adding an If Statement breaks it

I have this code that makes a box with information follow the mouse. It's really simple, just checks the custom attribute "description" in the div that you hover over and puts that in the box. However, I want to make it so if that div also has a certain CSS class, then it would put other information in the box, in addition to the other code still working.
$(document).ready(function(){
$(".hover").mousemove(function(e){
if ("div").hasclass("item"){
alert("div hasclass item");
} else {
var description = $(this).attr("description");
$("#hoverdiv").text(description).show();
$("#hoverdiv").css("top", e.clientY+10).css("left", e.clientX+5);
}
}).mouseout(function(){
$("#hoverdiv").hide();
});
});
that's the code I have now. None of the hovers in my page work at all. This is the code that works. It's identical in every way, except no if statement.
$(document).ready(function(){
$(".hover").mousemove(function(e){
var description = $(this).attr("description");
$("#hoverdiv").text(description).show();
$("#hoverdiv").css("top", e.clientY+10).css("left", e.clientX+5);
}).mouseout(function(){
$("#hoverdiv").hide();
});
});
I've tried time and time again to get this to work, and through my testing, it would seem that simply adding an if statement breaks the entire thing. I have absolutely no idea how to proceed or how to fix it.
The culrpit..
if ("div")
Maybe you were trying
if($("div").something()){
}
if ("div").hasclass("item") {
Should be:
if ( $("div").hasClass("item") ) {
For some more you can also test:
if ( $("div").is(".item") ) {
Read about jQuery .is()

Categories