jQuery wrap syntax - javascript

It's end of day. I'm hoping I'm just having a lapse of logic.
I can't get this to work:
var $divA= $("<div></div>").addClass('classA');
var $divB= $("<div></div>").addClass('classB');
$myDiv.after($divA.wrap($divB));
The above should turn this:
<div id="myDiv"></div>
Into this:
<div id="myDiv"></div>
<div class="classB">
<div class="classA"></div>
</div>
But it doesn't seem to work with that 'wrap' in there. I don't get any errors, it just doesn't wrap divA with divB and just inserts divA by itself.
Am I misunderstanding wrap?
UPDATE:
A simpler example that does not work:
$myBox.after($("<p></p>").wrap("<div></div>"));
That will add just the DIV after myBox.
It seems like jQuery doesn't like wrap added to after.

Have you tried
$myDiv.after($divA.wrap('<div class="divB"></div>'));
just for testing purposes?
As far as I understand, you shouldn't pass a jQuery object to the wrap-function:
The .wrap() function can take any
string or object that could be passed
to the $() factory function to specify
a DOM structure. This structure may be
nested several levels deep, but should
contain only one inmost element. The
structure will be wrapped around each
of the elements in the set of matched
elements.
If the example above works, then this is the reason ;-)

Just stumbled onto this thread having the same problem: jQuery .wrap() isn't working
I think if you change your code from
$myDiv.after($divA.wrap($divB)) to $myDiv.after($divA.wrap($divB).parent())
you'll get your wrap.

The confusing part might have been to You that .wrap() returns the inner element, not the parent element.
So you have to use the parent object of the wrapped one like this:
var $divA= $("<div/>").addClass('classA'),
$divB= $("<div/>").addClass('classB');
$myDiv.after($divA.wrap($divB).parent());
($divA.parent() is equal to $divB after the wrapping)
So the key part is that $divA.wrap($divB) returns $divA, NOT $divB
see the reference:
This method returns the original set of elements for chaining
purposes.
http://api.jquery.com/wrap/

I got this to work:
$('div#myDiv').after("<div class='classA'></div>").end().find('.classA').wrap("<div class='classB'></div>");
with your html to solve your initial question. Here's the source for jQuery's end function. This code will go make the chain go up one level (to the myDiv level), and will then wrap based on the find('.classA') at that level. That will find your div added with after, and wrap it in div with classB.
Edit:
Ok, I think this will work for you the way you want:
var divA= $("<div></div>").addClass('classA');
$('div#myDiv').after($(divA).wrap('<div class="divB" />'));
I think the problem was that when calling wrap on divA, it needs to be a jQuery object to work correctly. So really all you were missing was wrapping divA in ().

You're not looking for wrap. You want:
divB.append(divA).insertAfter('#myDiv');

I may be reading this wrong, but if you're using jQuery, isn't the $ a reserved character? have you tried just setting your variable names so they don't use it?
If so:
var divA = $("<div></div>").addClass('classA');
divA.wrap("<div class=\"classB\"></div>");
divA.insertAfter($("#myDiv"));
or
divA.after($("#myDiv"));
Here's the jQuery docs on the matter.

Related

Get a jQuery element for a DOMElement

I know how to do the opposite. Getting a certain DOMElement for a jQuery element is easy. (Use the get() method)
But how can you get a jQuery element for a specific DOMElement?
Unfortunately this DOMElement does not have any attributes like class or id so constructing a selector is not really an option.
Lets say I have this html:
<div class="edit">Abcd<b><i><u>asdasd</u>adasda</i></b>sdfsdf<br>asd</div>
I am in the u-DomElement. How can I get this as a jQuery element?
Is there a smart way to do this?
EDIT:
I wanted to know if there is a gerneral way to do this. Not specific to the code shown above.
Like:
DomElement.toJQuery()
Is there anything like that? I am aware that this might not be possible.
Getting a jQuery object for a DOM object is as simple as jQuery(dom_node) (or $(dom_node)). See http://api.jquery.com/jQuery/
This is commonly used in event handlers, which are given the DOM node as this, so that you will often see $(this)
If you want to get just the Element use the below code. if you wanted to get the HTML of any element you might want to add the .html() tag to either of the examples
var myVar = $('.edit u');
or
var myVar = $(".edit").find("u");
Are you looking for this?
$(".edit").find("u");
hope this is what you are looking for,
$(DomElement)
you want a only 1 specific dom element i suggest you find a way to add an id to that element.
but to get an u element inside a edit class:
$('.edit u');
$('.edit').find('u');

jQuery: render element to the DOM, then select it with jquery selector

Trying to understand something here: if I render something to the DOM from javascript, and want to call jQuery methods on it, it behaves differently than if I "re-select" the element from the DOM. Here's a simple example, in CoffeeScript:
element = """
<div id="my_div">TEST!</div>
"""
$('body').html(element)
element.hide() #this doesn't work.
$(element).hide() #this doesn't work either.
$('div#my_div').hide() #this does.
So, I seem to be misunderstanding something here. I guess the element variable is just a string and jQuery doesn't understand that it has been added as an element in the DOM.
Is there a different way to insert content into the dom, then, so that it behaves like a normally-selected jQuery object once it has been inserted?
The reason the first line doesn't work is because element is a string. The reason the second line doesn't work is because it ends up creating another DOM version of the string.
The fix would be to maintain a ref to the DOM version of the element the first time you construct it (in JS):
var $elem = $(element);
$elem.appendTo(document.body);
$elem.hide() // should work
Hope that helps.
I think you need:
element = $('<div id="my_div">TEST!</div>');

Change classname of div

In my page I want to change the class name of the div whose id is answer1 in div id=question. How can I do that? Thanks.
$('question1 answer1').addClassName('new_name');
<div id="question1">
<div id="answer1" class="old_name">
</div>
</div>
<div id="question2">
<div id="answer2" class="old_name">
</div>
</div>
So, as it has been pointed out, any selector method requires an iterator of some sort, so you can not just apply a method to all objects returned. You will notice in the documentation for Element.select that this is supposed to alleviate having to explicitly convert the object to an array, but I have not had luck with this on jsfiddle. However, I did try the following:
$('answer2').addClassName('new_name');
​
And it worked just fine. I don't know if the issue is that you are trying to traverse the DOM in your original element object (by using question1 answer1) and this requires the object/array iterator, or if it's just a hiccup elsewhere in the code. But in your specific example, since you know the id of the actual element you want to change the class of, the above code should work fine without specificing the parent element or using an array index of any kind.
I will admit that prototypejs threw me off because they use the same method names for the Element objects as Enumerable objects, so I saw the first instance of select and thought it looked pretty straight forward. Having now seen that almost every class/method requires you to set up a selector and convert it or manually traverse it, I will definitly say that this would be much easier with jquery and that your initial comment that they are almost the same is specifically not true in this scenario. Perhaps protojs offers some features that jquery does not, perhaps your code is tied to protojs (I worked on a project for a year that had to use YUI, which is a much bigger nightmare, trust me), but jquery is set up to play nice with prototypejs, so in cases like these, I'd consider using both. In jquery, the code would have been:
jQuery.noConflict(); // Avoids $ fight between jquery and prototypejs
jQuery( '#question1 #answer1' ).addClass('new_name');
or, to remove the old one first:
jQuery.noConflict(); // Avoids $ fight between jquery and prototypejs
jQuery( '#question1 #answer1' )removeClass('old_name').addClass('new_name');
Also, prototype has a toggleClass method that is probably also unnecessarilly esoteric, but maybe you should read up on: toggleClassName
And I wouldn't be this pissy about wasting my time on this (because I don't like to consider getting stuck learning a new framework a waste of time) except that their documentation, while attractive, has the worst examples I've ever seen. They all assume you have some fundamental idea without ever a friendly real world example or hyperlink to the difference between an instance and a class, and their examples distinguishing the two are identical. I'm definitely going to take some time out later today to find the real best answer to your question, out of spite and pride, if nothing else, but if it really comes down to having to iterator every time, just use vanilla js and use this framework when it's actually useful.
Simply $('answer1') will get you a reference to the div element that you want. The $ function returns an element with the given id string (or null if none was found). Note that you don't use a selector string when using $ - it only operates on ids.
The $$ function takes in a CSS selector string and returns an array of all matching elements, or an empty array if nothing matched. If you wanted or needed to go that route, you could locate the same div like this:
$$('#question1 .answer1')[0]
Once you have your element reference using either of the above methods, you can use addClassName or removeClassName or any other element methods available.

Passing Multiple Inner Child Node to Function

I need to pass the contents of an inside div to a function, for example myfun(string). I have tried using
myfun((this).children[0].innerHTML)
myfun((this).children[1].innerHTML)
myfun((this).children[0].children[0].innerHTML)
but none of those seem to work. I can't just pass the getElementById value because the function should be generic since it would be called by php on various <a> elements (ideally I think it should include the this. keyword).
Thanks for any help.
If you don't need it to work cross-browser, there's:
this.getElementsByClassName('label')[0]
This will fail in IE 8 and below.
If you're absolutely certain the HTML/DOM structure won't change, you could perhaps use:
this.nextSibling.children[0];
But this might have issues in browsers that consider textNodes as childNodes
in your function, "this" refers to the link, and can't be used.
a much cleaner solution would be to have myfunc know that it is going to receive an object which contains the text
javascript:
myfunc(obj){
alert(obj.childNodes[0].nodeValue);
}
html
click
<div id="target">target contents</div>
The object this will apply to the <a> tag that it calls. You need to call the parent div first and then select the children accordingly.
Try using this.parent.children[1].children[0].innerHTML
Try
this.parent.children[1].children[0].innerHTML
But you should really use dynamic IDs instead of this mess.

jQuery stop append removing div

I am copying a div into another div using append. However it removes the original. I tried to use clone but it seems to only work with appendTo. But appendTo breaks my layout so I have to use append with works fine.
I am wrong that clone will not work with .append and is there another way to stop the div removing?
Thanks
$('.compareWrapper').append(htmlStr)
foo.appendTo(bar)
Take foo and append it to bar.
foo.append(bar)
Take bar and append it to foo
Syntactically they're different. You have to think of what's the target object and what's the destination object. So, having said that you can move ahead in one of two ways:
var $clone = $('target').clone();
$clone.appendTo('wrapper');
$('wrapper').append($clone);
Both do the same thing.
The following does not work?
$('.compareWrapper').append($(htmlStr).clone());
I don't see any reason for .clone() not working with .append(). The code should be:
$('.compareWrapper').append($(htmlStr).clone());
Is that what you tried? From the name of your variable, I'm assuming htmlStr is a string, not a jQuery object.

Categories

Resources