Obtaining elements as jQuery-objects fails when bracketing - javascript

I'm retrieving elements from a TABLE using the following syntax.
$("#table").children().children().children().html();
That gives me the contents of the first TD. Then I moved to the second one and discovered that picking it using the bracket-syntax below gives me an error message saying that html() is not a method of that object.
$("#table").children().children().children()[1].html();
Instead, I have to use innerHTML peoperty instead, like so.
$("#table").children().children().children()[1].innerHTML;
My impression is that I'm doing something wrong. While getting the result I want, I can't help feeling that there are more recommended ways to resolve this kind of call. Suggestions are welcome.

That's because html is a jQuery function, but the [1] gives you the DOM element.
You can use .eq(n) to get the nth element:
$("#table").children().children().children().eq(1).html();
...but if you're looping through them, it's very inefficient to repeat the above. Instead, consider each:
$("#table").children().children().children().each(function() {
// Use $(this).html(); for each cell's contents
});
Update In a comment you said:
I'm targeting four different elements with indexes like 143, 237 etc.
In that case, remember the initial set of elements, then use .eq as necessary:
var cells = $("#table").children().children().children();
cells.eq(143).html(...);
cells.eq(237).html(...);
You might also consider something that's less fragile if you adjust your table structure (for instance, perhaps you add a colgroup or rowgroup and now there are different levels):
var cells = $("#table td");

It is because when you use index to access the element it returns a dom element reference not a jQuery object so the .html() method won't be there.
var first = $("#table").find('td').eq(0).html();
var second = $("#table").find('td').eq(1).html();
or
var $tds = $('#table td')
var first = $tds.eq(0).html();
var second = $tds.eq(1).html();

Related

textContent returns undefined

I have a table in which I want to extract the text of the active item. I do this with the following code:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active");
console.log(addedWorkout);
addedWorkout = addedWorkout.textContent;
console.log(addedWorkout);
The problem is that I keep getting undefined. I checked the console and it indeed finds the element I want without fail.
I am relatively new to Javascript, but after over an hour of Googling I could not find the issue and I don't understand why. I know that I can get the text element if I hardcore it using the following line:
document.querySelector("#selectiona1").textContent
but not with:
$("#selectiona1").textContent
What is the difference between these 2? I read that textContent is part of the DOM, to my understanding it relates to objects and according to my console i think it is an object. I made some crazy attempts like putting the object I got into the querySelector, but nothing works.
With this line:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active");
you're using jQuery to select the .dropdown-item.active inside #custDropDownMenuA, and when you select with jQuery, you get a jQuery object in response. So, addedWorkout is a jQuery object, and jQuery objects generally do not have the same properties/methods as standard HTMLElements. (querySelector is the vanilla Javascript method to retrieve an element)
Either select the [0]th item in the jQuery collection to get to the first matching element:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active")[0];
Or use the jQuery method to get the text of the first matching element, which is .text():
var addedWorkoutText = addedWorkout.text();
(note the use of a new variable - you will likely find it easier to read and debug code when you create new variables rather than reassigning old ones, when possible)
Your var 'addedWorkout' is a Jquery object, not a html element.
To show the text use:
addedWorkout.text();
Alternatively, you can change the 'addedWorkout' to a html element by adding the index [0], like this:
addedWorkout[0].textContent;

Removing all elements from a page except those contained within an array and their parents/children?

I have an array of elements I would like to keep on the page that I generated this way. The tricky part is that I need to preserve these elements parents and children.
var maps = document.querySelectorAll("[id^=map]")
I'd like to use jQuery's filter to remove all divs except those contained in the array from the page. I can't quite get it it to work though. I tried:
var all = $("div").get()
$(all)
.filter(function( index ) {
return $.inArray(this, maps) === -1;
}).remove()
That removed every element from the page. I figured that it was eliminating parent divs and their children regardless of whether the children were desired. I tried putting another filter function within the function, adding some nested conditionals, but it started to become a huge nonfunctional mess. Is there a more elegant way to do this? I don't necessarily need to use .filter().
Part of it may be that you are not returning a value from your filter function.
But if I understand you correctly, you can just look at the element and all of its contents:
$(all)
.filter(function( index ) {
$this = $(this);
return !($this.is("[id^=map]") || $this.find("[id^=map]").length > 0);
}).remove()
You can try using complex css selectors in the first place, like this:
$('div:not(div:has(.keep), div.keep)').remove();
http://jsfiddle.net/e_neko/k0bq6gzx/
This locates required elements and removes others in one pass.

How to select multiple ID's in a badly designed webpage?

I am maintaining a complex web application.
I have a large number of divs which all have the same ID.
I know this is totally wrong, and as a matter of fact document.getElementById() with that id is going to only produce one match for me.
However I am able to pull out the element that I'm looking for using jQuery (we are on 1.6.2), like this: $('#bad_id[nonstandard_attr_name=somethingSpecific]')
Not quite ready to say that this is a "solution".
I'm worried about whether this is reliable or not. Is jQuery really actually gonna search through all the elements that match the ID using a DOM walk? That's probably the only way to get all of them.
Does it filter elements by the other attribute first, and then filter it down by the ID? That would achieve the desired behavior as well, but it would be good to know the order it does this in.
If you need to select multiple elements with same id you can simply use an attribute selector:
$( "[id='myid']" )
The attribute selector doesn't look at the attribute key for any semantics like unique ids or such.
http://jsfiddle.net/ZWm3G/
I cannot tell you what jQuery or other dom traversals will do (doubtful it will work always) but you can try this :
document.filter = function(attr, val, r) {
r = r || document.getElementsByTagName("*");
var s = [];
for(var i = 0; i < r.length; i++) {
if(r[i].getAttribute(attr) == val) {
s.push(r[i]);
}
}
return s;
};
var s = document.filter("nonstandard_attr_name", "somethingSpecific", document.filter("id", "bad_id"));
console.log(s);
http://jsfiddle.net/KGPFf/1/
Well, as seen in comments, my guess was why would it go on searching for any element. Yes
getElementById returns the first element and then stops searching, but the same doesn't look right for jQuery. It does return all the elements with that "bad" id.
As can be seen in this Fiddle,
So it is selecting all the elements, this means jQuery doesn't stop at the first element, but goes on searching the entire doument, hence IMO, you may use jQuery to select multiple elements with the common id. There shouldn't be any problem.
Use a selector that will result in something other than getElementById() being used should result in consistent results, but make sure you test it with IE8 since IE8 doesn't use document.querySelectorAll().
Using methods such as .find .children and .filter should also yield consistent results regardless of the id being unique.
Sample: http://jsfiddle.net/gb3Mz/

Get visible from jQuery collection of objects

I have this line of code:
var filterInputs = $(this).siblings('.filterInputs');
which performs some work on filterInputs. Later on, I would like to reduce my collection of filterInputs to just those which are visible.
Clearly, I could do this:
var visibleFilterInputs = $(this).siblings('.filterInputs:visible');
but that seems inefficient given the fact that I already have a reference to the collection I was hoping to reduce.
Is there a way to say something like:
//TODO: Example
var visibleFilterInputs = $(filterInputs:visible);
without having to iterate over the DOM tree again? Thanks
You're absolutely right, there's no reason to recollect the DOM elements, since you already have them in a jQuery object. So that's exactly what the .filter() method is for: http://api.jquery.com/filter/
Try this:
var visibleFilterInputs = filterInputs.filter(":visible");
Here's an example: http://jsfiddle.net/FC9sH/
Note that it's better to target a certain HTML tag, such as <div>, to make the :visible selector a little more efficient (since it isn't part of the CSS specs and can't be optimized by native methods). At least in your case, you're already using the filterInputs class. Anyways, maybe something like:
var visibleFilterInputs = filterInputs.filter("div:visible");
but only if that's applicable. I mean, even selecting multiple known element tags is probably better:
var visibleFilterInputs = filterInputs.filter("div:visible, p:visible");

Syntax error - how to get value of textbox

I have a trouble getting value from text box. Conventional javascript getElementByName returns error :undefined. I was able to use jQuery in other examples with select. But can't find a reference anywhere about input tags. This line shows syntax error:
var total = = $('input[name='+formQty+'] :text').val();
What is a jquery for picking value/text of a textbox?
you have 2 equal signs.
var total = $('input[name='+formQty+'] :text').val();
It might be easier also to stick an ID attribute on the input tag and use this
var total = $('#myInputId').val();
make sure you are calling it from a loaded dom:
$(function() {
var total = $('#myInputId').val();
});
From what I understand your query selector is incorrect.
It should be 'input[name='+formQty+']:text' the :text as you have it is trying to select any text elements underneath the current input resulting in nothing. You can even get rid of the :text and only select the element based on name. .val() should then work if you have properly selected the input element.
You should also debug this by just performing the $('...') method without the function call and see what elements are returned.
Regarding your problem getting this to work with getElementByName() - that's probably because the method is actually getElementsByName() - note the plural elementS. It returns a list of all elements with the specified name, accessible via array syntax; even if there is only one matching element you still get a list (with only one thing in it).
If you are sure there will be exactly one element with the specified name you can do this:
var elementValue = document.getElementsByName(name)[0].value;

Categories

Resources