Opposite of append in jQuery - javascript

I use .append to add to a div
$(this).append('<ul><li>test</li></ul>');
how can I search for a <ul> and remove it if it exists in the children of $(this)?

You could use remove(). More information on jQuery remove().
$(this).children("ul").remove();
Note that this will remove all ul elements that are children.

The opposite of .append() is .prepend().
From the jQuery documentation for prepend…
The .prepend() method inserts the specified content as the first child of each element in the jQuery collection (To insert it as the last child, use .append()).
I realize this doesn’t answer the OP’s specific case. But it does answer the question heading. :) And it’s the first hit on Google for “jquery opposite append”.

Use the remove() method:
$(this).children("ul").remove();

What you also should consider, is keeping a reference to the created element, then you can easily remove it specificly:
var newUL = $('<ul><li>test</li></ul>');
$(this).append(newUL);
// Later ...
newUL.remove();

just had the same problem and ive come across this - which actually does the trick for me:
// $("#the_div").contents().remove();
// or short:
$("#the_div").empty();
$("#the_div").append("HTML goes in here...");

Opposite up is children(), but opposite in position is prepend().
Here a very good tutorial.

Related

Find related element using jQuery

Based on this DOM tree below when a comment reply button is clicked I need to use $(this) and then navigate to the next comment textarea .task-modal-cmt-reply-textarea
I am using jQuery and tried to use .parent().parent().closest('.task-modal-cmt-reply-textarea') and a few other combination without luck so far.
Can someone show me an efficient way to get this element into a var?
What I am trying to accomplish...
I have a click even on a comment reply button which insert a reply form into the DOM below a parent comment when the reply button is clicked using...
$document.on('click', '.cmt-reply-btn', function(e) {}
In this click event the reply form is put into the DOM with...
$parentCmtDomNode.after(cmtReplyFormTemplateHtml);
After the form is in the DOM I try to attach a jQuery plugin to it for #mention style capability using...
$('.task-modal-cmt-reply-textarea').mentionsInput({});
The problem
The #mention library works for the 1st clicked on comment form but all other reply forms do not work
another way to get a reference to that element, would be to do this:
var el = $(this).parent().parent().next().find('.task-modal-cmt-reply-textarea').eq(0);
note that the eq(0) just gives a single object back instead of an array with one element, which may or may not be necessary depending on what you want to do with it.
You need to do another .parent(), the two parent() you did only bring you up to the level of class "Activity-item Activity-comment" with data-activity-id = 12. Do another parent and you should be fine.
try this
var textarea_value=$(this).closest('.Activity-item').next('.Activity-item').find('form .task-model-cmt-reply-textarea').val();
or if its related with data-activityid = "12" so you can use
$(document).on('click','.cmt-reply-btn',function(){
var textarea_value = $(form[data-comment-parent-id = "'+$(this).attr('data-activityid')+' .task-modal-cmt-reply-textarea"]).val();
});
A more efficient way would be to use the parents api from jQuery then followed by your .closests
.parents('div')
The .parents() and .parent() methods are similar, except that the latter only travels a single level up the DOM tree. Also, $( "html" ).parent() method returns a set containing document whereas $( "html" ).parents() returns an empty set.
Then add the following sub selector to your closest chain.
.closest('textarea[name=^"task-modal-cmt-textarea"]')
This looks for the closest textarea with the name starting with task-modal-cmt-textarea. This is more efficient than what you have as this will eliminate any lookups on non textarea elements then it will only filter out the textareas that have that particular name.
EDIT: Updated Answer to the OP's recent edit.
$('.task-modal-cmt-reply-textarea').mentionsInput({});
This will select all of the ".task-modal-cmt-reply-textarea" that are on the screen at the time, it will not account for future ones. To achieve what you are looking for you should put a sub selector on this chain to allow it to attach to the newest form that was created.
$('.task-modal-cmt-reply-textarea',$($parentCmtDomNode).next('textarea')).mentionsInput({});
This should be placed after the
$parentCmtDomNode.after(cmtReplyFormTemplateHtml);
Try this:
var txt_html = $(this).parents('.Activity').children("textarea:first").html();
var txt_val = $(this).parents('.Activity').children("textarea:first").val();
In the parents() function you need to use the closest parent class/ id.
var el = $(this).parents('.Activity-item').next().find('.task-modal-cmt-reply-textarea').eq(0);

Jquery backwards tree traversal

I'm looking for a solution to a little problem I have, currently I'm looking to get the entire DOM tree from an element (e.g. all the parents), which I can do using .closest('body').first().
The problem is I'm looking for a way to go through each element and parent and remove all of the text/html from them except the original target, so basically have a blank tree but have html in the bottom element.
Although I haven't tried it yet, I was thinking just .each() might work, although something tells me it would have a problem with the nested structure?
Any advice would be great!
Thanks
Dom
UPDATE:
Accepted answer works great! I adapted the code and added to the fiddle below to allow it to work with deep nested structures like the ones I was working with...
Fiddle here: http://jsfiddle.net/RDNTc/2/
That script remove every text nodes of the parent of the target :
$('p').parentsUntil('body').each(function(){
$(this).contents().each(function(){
if(this.nodeType === 3) this.parentNode.removeChild(this);
});
});
http://jsfiddle.net/RDNTc/;
You can traverse up the parents in jQuery using .parents(). Then use .each() to iterate over them in a loop.

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.

How to add child tags to a javascript array

I'm trying to fill an array with all direct child elements of a div.
example:
<div>
<span></span>
<a></a>
</div>
should result in an array containing span and a
How Would I achieve this?
I tried var elements = $('.thediv').children(); but that doesn't seem to work.
Also how Would I then use that information for this kind of function?:
$("element1","element2","element3") depending on the result of the array?
Really thank you for your help! I am kind of lost with this thing
Note: I'm using zepto.js which has a similar syntax to jquery but misses a lot of functions so that might be a problem but I am also happy with solutions using jquery syntax because it should work pretty well :) https://github.com/madrobby/zepto
To get the tags into the array, you could easily use, with jQuery (though I'm unfamiliar with zepto):
var elementsArray = [];
$('div').children().each(
function(i){
elementsArray.push(this.tagName.toLowerCase());
});
JS Fiddle demo.
And to use them, you can try:
for(i=0;i<elementsArray.length;i++){
$('div').find(elementsArray[i]).css('color','red');
}
JS Fiddle demo.
Although this simply uses the tagName of each element, so if there is more than one a within the relevant element all elements matching the selector, effectively $('div').find('a') in this case, will be targeted by the selector.
The above caution seems to be discounted through use of a more complicated selector, and behaviour, and allows for each element to be iterated over one at a time, though I can't help but feel it's a little more complex than it needs to be:
var elementsArray = [];
$('div').children().each(
function(i){
elementsArray.push(this.tagName.toLowerCase());
});
for(i=0;i<elementsArray.length;i++){
$('div')
.find(elementsArray[i])
.not('.edited')
.eq(0).css('color','red')
.addClass('edited');
}
JS Fiddle demo.
Sigh, I'm an idiot. The final iteration of this is below, which reduces the complexity somewhat, and allows for proper iteration over each element according to their position in the array:
var elementsArray = [];
$('div').children().each(
function(i){
elementsArray.push(this.tagName.toLowerCase());
});
for(i=0;i<elementsArray.length;i++){
$('div')
.children()
.eq(i)
.css('color','red');
}
JS Fiddle demo.
Having said the above, though, if you want to "target all elements within," why not simply target those elements with:
$('div').children();
Which will select, and target, each direct child of the div element without first holding them in, or having to hold them in, a user-created array variable.
$("div").children().toArray();
http://api.jquery.com/toArray/
$("element1","element2","element3")
Does this mean you want to use the array as a jQuery selector? Or you really want the tag names?
Each DOM node has a childNodes attribute, which is a NodeList containing all the direct descendants of the node in question.

How can I target an element's 'parent'

I have some <TD>s without unique names. Inside them there are spans with unique classnames so I have no problem targetting the spans. How can I target the parent <td> so I can change its class?
I want to do something like $(".classname").parent("TD").className="newClassclassname".
You were close:
$('.classname').parent('td').addClass('newClassName');
Though typically it's safer to go with:
$('.classname').closest('td').addClass('newClassName');
... which doesn't assume the <td> is the immediate parent.
The reason .className doesn't work is because jQuery returns elements wrapped in the jQuery object. If you want to access the original (DOM) object you need to select the first item in the jQuery collection with [0]:
$('.classname').parent('td')[0].className = 'newClassName';
But I recommend using the jQuery function addClass() anyway since it won't interfere with existing classes.
You can do
$("span.classname").closest("td").addClass("newClassclassname");
Sorry, do you mean following code:
$(".classname").parent("TD").addClass("newClassName");
$(".classname").parent("TD")[0].className="newClassname";
$(".classname").parent().addClass("newClassclassname");

Categories

Resources