Removing last cloned element - javascript

Similar to this thread, I am trying to be able to add and remove select boxes for different parts of my document. However, when I call the remove function, it removes the first instance of my cloned object, instead of the last. I have tried using :last and :last-child, but they do not seem to be working(May just be a syntax error, as I am new to Javascript/Jquery)
Also, should I be assigning different id's to each of my cloned objects? My goal is for each g:select to select a database object, and compile all of the different objects text into 1 big string (each object has a 'documentBody' field that I want to compile). Since I am basically doing the same thing to each object, is it necessary for me to assign specific id's to each select, or will just cloning them be sufficient?
Here is what I currently have implemented
<div id="selects">
<g:select name="intro"
id= "intro" from="${package.name.Subtag.findAllWhere(tag: package.name.Tag.get(2))}" noSelection="['': 'Please choose Subtag']"/>
</div>
<button onclick="addSelect()">Add</button>
<button onclick="removeSelect(intro)">Remove</button>
and
<g:javascript library="jquery"/>
<g:javascript>
function addSelect(){
var cloner = $("#intro").clone();
$("#selects").append(cloner);
}
function removeSelect(id){
$("#intro:last-child").remove();
}
</g:javascript>

As Jai has mentioned, the issue is that you are cloning and appending an element with an id, creating a duplicate id on the page. When jQuery searches for an element by id, it stops at the first one found, regardless of any other pseudo classes.
The issue is that a duplicate id on the page means that the HTML document is invalid, so all bets are off. Older browsers may even throw an error. Using a class rather than an id prevents the .clone() function from copying the dupe id, but if you still need the first element's id, you can always remove it from your cloned object before appending it to the page:
cloner.removeAttr('id');

Related

How to append to a variable in jquery?

I have the following code:
var golden_site = '<div id="golden_site"></div>';
$('.form_content').append(golden_site);
var lookup = '<input type="text" name="lookup" value="test">';
Why is this not working:
$(golden_site).append(lookup);
But accessing the node by id works:
$('#golden_site').append(lookup);
This $('#golden_site') selects the div with id=golden_site. While this $(golden_site) doesn't select anything.
Taken from here, you have the following ways of selecting an element using jQuery
Selecting Elements by ID
Selecting Elements by Class Name
Selecting Elements by Attribute
Selecting Elements by Compound CSS Selector
Pseudo-Selectors
The way you tried to select your div doesn't follow one of the above ways. Hence you didn't make it. While using the id you made it, since this is included in the above ways.
update
As Guffa pointed out (I didn't now it) in his comment,
The call $(golden_site) doesn't try to use the string as a selector at
all. It will create an elements from the HTML string, and actually
return that element
The code is working fine, but it doesn't do what you think.
The $(golden_site) part will create a new div element from the HTML code in the string. The lookup element will then be appended to that div. As the div is an element that you just created, it's not in the page and the lookup element that you appended to it isn't in the page either.
If you create the div element first and then append that to the page, instead of using a string in the append, then you have a reference to the div element:
var golden_site = '<div id="golden_site"></div>';
var element = $(golden_site);
$('.form_content').append(element);
Now you can append things to it:
element.append(lookup);
Because when you say
$(golden_site).append(lookup);
Actually you mean:
'<div id="golden_site"></div>'
In plain words, it's just a string, not a jQuery object that can be appended to. golden_site is just a string.
The reason is because the $() is in fact a wrapper of jQuery over the document.querySelector(). So as expected both methods should behave similar, when you do:
$("#blah").append(x);
Indeed the browser is doing this:
document.querySelector("#blah").appendChild(x);
So both methods should work as they explain here -> How query Selector works
As you can see the variable passed as argument is a string that will be used as a CSS Selector, they explain here -> CSS Selector List
I will add this graphic with some of the most common ways to select elements from the DOM, don't forget the '', courtesy from W3CSchools.

Remove elements from in memory element in js

I have a java script file that is used in several places. It has this code:
var newDiv = lastDiv.cloneNode(true);
lastDiv has some <input> elements that I do not want to clone. I've created these input elements with the attribute <input copy="dont"> so that I could remove them out using the following code:
newDiv.select("input[copy=dont]").remove()
The prototype.js select() finds these elements. But remove() does not work, newDiv still has the input elements that I wanted filtered. Prototype documentation states that it will remove from the document, but newDiv is not in the document, it is only in memory.
This is solved now: select() was returning an array. If only prototype would have returned a meaningful error message. It was returning the list of matching elements. Thanks for your answers guys. Will use valid HTML5. This works now
newDiv.select("input[copy=dont]")[0].remove()
i think it's just a type in your selector , try this:
newDiv.select("input[copy='dont']").remove()
also , just s suggestion , use the attribute data-copy instead of copy ex.
<input data-copy="dont" type="text" />
this will keep your elements valid HTML5

Select element inside a cloned element variable

I have cloned an element using clone():
var clone = $('#orig').clone();
The clone works fine, but I having some trouble trying to select elements inside it by ID.
All nested elements have the same ID as the original ones, and I need to manipulate some before appending them to the page...
I am trying something like this for example:
alert(clone.filter("#Full").attr('id'));
Could you help me on that?
The snippet you provided in your question works fine!
Just replace filter with find.
See this fiddle: http://jsfiddle.net/Pkv7S/
However, yes, you should be wary of duplicate IDs.
Try this way
var clone = $('#orig').clone();
clone.attr('id','orig1');
check it here http://jsfiddle.net/3tWks/
Firstly, use classes instead of IDs. IDs should always be unique within a document, and may result in unpredictable behaviour if cloned (if you want the cloned elements to have IDs, by all means assign new ones when you clone!)
That said, you want to be using .find instead of .filter to find elements nested within your clone element:
clone.find(".myClassName")
/* or */
clone.find("#Full")
.find – jQuery Docs

Accessing HTML elements by their id from an array of elements in Javascript is not working

I am trying to access HTML elements by their id from an array of HTML Elements. I created this array using the getElementsByTagName and I am trying to access these elements like this: arrayName.getElementById("theId").
Basically this is what I am trying to implement:
In a Javascript function triggered by an onchange event I receive the reference to the element causing the trigger. Since its a table structure I get the reference to a <td> element.
Now I want to access all the other elements of the <tr> in which that <td> is, using the id of each individual element.
A small replica of my code:
function chngFunction(theTd){
var thisRow = theTd.parentNode;
var inputs = thisRow.getElementsByTagName("input");
alert(inputs[0].value);///////////Currently what I am doing////
alert(inputs[1].value);///////////Currently what I am doing////
.
.
.
//////// What I would like ////////
//// alert(thisRow.getElementById("myId").value); // or something like that////
/////////////// OR ///////////////
//// alert(inputs[].getElementById("myId").value); // or something like that////
///////////////////////////////////
This is what I want because, currently if I make any structural changes to my jsp, I have to make changes to js also (that can leave bugs). So using ids to access individual elements would be great.
Please help me out.
By definition, id values are unique throughout the entire document. So there is no HTMLElement#getElementById that retrieves elements by ID from only that element's descendants. Instead, there's document.getElementById that looks for them globally (since, again, id values are globally unique in the document). So if you're using id values:
alert(document.getElementById("myId").value);
You could use querySelector API.
This should work:
thisRow.querySelector('#myId');
And if your element ids are unique across the document (as they should be), you can just do document.getElementById.
getElementById is a method of the document object, not nodes, so you must use it this way: document.getElementById('id'); .
of course, this will only work if the HTML elements are attached to the DOM tree. In case they are'nt, you should use a selector API. like Sergio is suggesting in his answer.

Javascript Clonenode() - get element by id?

I am fiddling with this javascript code here
http://jsfiddle.net/7Sd4W/4/
I am trying to get it to clone a select element with ID = "sel0"
Then when It clones it I want it to create the same select element but with "sel+i" , i increments meaning everytime its cloned
The ids would be sel0,sel1,sel2,sel3,sel4 etc..
I tried changing
document.getelementsbyID()
or
document.getelementsbyname()
However it does not seem to work
Thanks
var copy = orig.cloneNode(true);
copy.setAttribute("id", modify(orig.getAttribute("id")));
document.body.appendChild(el)
getElementsByTagName works. You can also assign a unique ID to the node before appending it (duplicate IDs can cause all kinds of issues):
See http://jsfiddle.net/7Sd4W/9/

Categories

Resources