Getting an element as jQuery object from a set of elements - javascript

Is there a way to get an element from a jQuery object, but as jQuery object?
If I wanted to get the text of elements, presently I'd write it like this:
var elements = $(".set");
for (var idx=0; idx<elements.size(); idx++) {
var text = $(elements.get(idx)).text();
// do something with text
}
Note that I have to wrap elements.get(idx) in another jQuery call $().
I realize this isn't that big a deal, I just want to make sure I'm not doing extra work if there is an easier way.

Have a look at .eq() [docs]:
// returns the third div (zero-indexed) in a jQuery wrapper
var $mydiv = $('div').eq(2);
Is this what you mean?

Why not go with:
$(".set").each(function (idx) {
var text = $(this).text();
// do something with text
});

you can use:
$(".set").each( function () {
var text = $(this).text();
// do stuff
});

Related

$.grep filter with contains

I am trying to filter an array with grep to apply CSS. My code is like below.
var depos = $('.panel-default > .panel-heading');
var chkd = ['ABC','XYZ'];
var found_p = $.grep(depos, function(v) {
return jQuery.inArray(v.innerText,chkd);
});
The first issue is that found_p is not filtering the needed array values from chkd. After filtering it, how can I apply CSS? I tried like below but it fails
$(found_p[0]).css('background-color', 'red');
Can anybody help me out with this.
Assuming from your code that you're trying to find the elements that have innerText matching a value in the chkd array, you can use the filter() method. Try this:
var $depos = $('.panel-default > .panel-heading');
var chkd = ['ABC','XYZ'];
var $found_p = $depos.filter(function() {
return $.inArray($(this).text(), chkd) != -1;
});
The $found_p variable will then hold a jQuery object with all matched elements. You can apply CSS to them like this:
$found_p.css('background-color', 'red');
Example fiddle
However, I would suggest using CSS classes instead of adding inline styles as it is much better practice.

Using JQuery's .attr() When Selector Returns Multiple elements

I am trying to pull 2 pieces of data from each of several fields. All the fields have been given the same "name" so as to allow them to be referenced easily.
<input type="text" name="common_name" data-X='ABC'>
The first piece of data I am pulling is their values, which does seem to be working. My issue is when I try to use attr(). It just stops dead in the water at that point.
var length = $('[name=common_name]').size();
for(var i=0; i < length; i++){
var value = parseInt($('[name=common_name]').get(i).value); //doesn't kill the script
var dataX = $('[name=common_name]').get(i).attr('data-X'); //Script is killed here
}
Since I'm not having issues with using attr() in general when the selector is selecting the element based on an id, I would think the issue has to do with the fact that in this case multiple elements are being returned by jQuery. What I am confused by is that I thought that get(#) is supposed to grab a specific one…in which case I don't see what the problem would be. (After all, using get(#) DOES work when I use val()).
So…why doesn't attr() work here?
.get() returns a dom element reference which does not have the .attr() method, so you can use the .eq() method which will return a jQuery object
var length = $('[name=common_name]').size();
for (var i = 0; i < length; i++) {
var value = parseInt($('[name=common_name]').eq(i).val()); //doesn't kill the script
var dataX = $('[name=common_name]').eq(i).attr('data-X'); //Script is killed here
}
The correct way to iterate over an jQuery object collection is to use the .each() method where the callback will be invoked for each element in the jQuery collection
$('[name=common_name]').each(function () {
var $this = $(this);
var value = parseInt($this.val()); //or this.value
var dataX = $this.attr('data-X'); //or $this.data('X')
})
Suppose the html is like this
<input type="text" name="common_name" data-X='ABC'>
<input type="text" name="common_name" data-X='DEF'>
<input type="text" name="common_name" data-X='GHI'>
Now the script part
$('input[name="common_name"]').each(function() {
var el = $(this);
text_val = el.val();
data = el.attr('data-X');
console.log(text_val);
console.log(data);
});
attr is a jquery fn, should call by jquery object
use like this
$('[name=common_name]').attr('data-X')
so try
dataX = $($('[name=common_name]').get(i)).attr('data-X');

Selecting inside a DOM element

This is the html code
<div class="extra-sub-block sub-block-experience">
<h6 style="display:inline;" id="exp-pos-0" class="extra-sub-block-head sub-block-head-experience">CEO</h6>
</div>
<div class="extra-sub-block sub-block-experience">
<h6 style="display:inline;" id="exp-pos-1" class="extra-sub-block-head sub-block-head-experience">COO</h6>
</div>
There are several such similar structures. Now I try to extract the values from each block.
var temp=document.getElementsByClassName('sub-block-experience');
var result=$(temp[0]+"#exp-pos-0");
This throws an error. I followed selecting element inside another DOM
I also tried
var temp=document.getElementsByClassName('sub-block-experience');
var result=temp[0].find('h6');
This doesn't work as well. What am I doing wrong here. Help?
For extracting the values from all blocks, you can use .map() function as follows:
var results = $('.extra-sub-block-head').map(function(){
return $(this).text();
})
Demo
side note: Since id is unique in a document, you can directly access the element using id selector like var result= $("#exp-pos-0");instead of var result=$(temp[0]+"#exp-pos-0");
Try, var result=$(temp[0]).find('h6');
Even, in the documentation link that you gave in question, it shows that you should wrap your result from document.getElementById in $() to be applied with jQuery. What it does is, that it converts the native javascript object into a jquery object.
Demo
function testIt(){
var tags, index;
tags = document.getElementsByTagName('h6');
for (index = 0; index < inputs.length; ++index) {
//do something ...
}
}
If I am correct you are trying to get ceo and coo?.If that's the case then with jquery:
var x= $('.extra-sub-block h6');
//values are
$(x[O]).html();
$(x[1]).html();
You could also use plain javascript:
var result = document.querySelectorAll('.sub-block-experience h6');
Or if you like it separate:
var temp = document.querySelectorAll('.sub-block-experience');
var result = [];
for(var i = 0, elem; elem = temp[i]; i++) {
result = result.concat(elem.querySelectorAll('h6'));
}
But be aware of the browser compatability of querySelectorAll and querySelector.

Javascript regex to replace text div and < >

var text='<div id="main"><div class="replace">< **My Text** ></div><div>Test</div></div>'
I want to replace div with class="replace" and html entities < > comes inside that div with some other text.
I.e the output :
'<div id="main"> Hello **My Text** Hello <div>Test</div> </div>'
I've tried
var div = new RegExp('<[//]{0,1}(div|DIV)[^><]*>', 'g');
text = text.replace(div, "Hello");
but this will replace all div.
Any help gratefully received!
If a Jquery solution is acceptable:
text = $(text) // Convert HTML string to Jquery object
.wrap("<div />") // Wrap in a container element to make...
.parent() // the whole element searchable
.find("div.replace") // Find <div class="replace" />
.each(function() // Iterate over each div.replace
{
$(this)
.replaceWith($(this).html() // Replace div with content
.replace("<", "<sometext>")
.replace(">", "</sometext>")); // Replace text
})
.end().html(); // return html of $(text)
This sets text to:
<div id="main"><sometext> My Text </sometext><div>Test</div></div>
And to replace it back again:
text = text.replace('<sometext>', '<div class="replace"><')
.replace('</sometext>', '></div>');
http://api.jquery.com/jquery/#jQuery2
http://api.jquery.com/each/
http://api.jquery.com/find/
http://api.jquery.com/html/
In pure JS it will be something like this:
var elements = document.getElementsByClassName('replace');
var replaceTag = document.createElement('replacetext');
for (var i = elements.length - 1; i >= 0; i--) {
var e = elements[i];
e.parentNode.replaceChild(replaceTag, e);
};​
Here is one crazy regex which matches what you want:
var text='<div id="main"><div class="replace">< **My Text** ></div><div>Test</div></div>'
var r = /(<(div|DIV)\s+class\s*?=('|")\s*?replace('|")\s*?>)(\s*?<)(.*?)(>\s*?)(<\/(div|DIV)\s*?>)/g;
The whole replacement can be made with:
text.replace(r, function () {
return 'Hello' + arguments[6] + 'Hello';
});
Please let me know if there are issues with the solution :).
Btw: I'm totally against regexes like the one in the answer...If you have made it with that complex regex there's probably better way to handle the problem...
Consider using the DOM instead; you already have the structure you want, so swap out the node itself (borrowing heavily from #maxwell's code, but moving children around as well):
var elements = document.getElementsByClassName('replace');
for(var i = elements.length-1; i>= 0; --i) {
var element = elements[i];
var newElement = document.createElement('replacetext');
var children = element.childNodes;
for(var ch = 0; ch < children.length; ++i) {
var child = children[ch];
element.removeChild(child);
newElement.appendChild(child);
}
element.parentNode.insertBefore(newElement,element);
element.parentNode.removeChild(element);
}
For each element of the given class, then, it will move each of its children over to the new element before using that element's position to insert the new element and finally removing itself.
My only questionmark is whether the modification of items in the array return by getElementByClassName will cause problems; it might need an extra check to see if the element is valid before processing it, or you may prefer to write this as a recursive function and process the tree from deepest node first.
It may seem like more work, but this should be faster (no re-parsing of the html after you've changed it, element moves are just reference value assignments) and much more robust. Attempting to parsing HTML may damage your health.
Rereading the question (always a good plan), you begin with the text in a string. If that is truly the start point (i.e. you're not just pulling that out of an innerHTML value), then to use the above just create a temporary parent element:
var fosterer = document.createElement('div');
fosterer.innerHTML = text; // your variable from the question
And then proceed using fosterer.getElementsByClassName.

jQuery, Looping through paragraphs and getting text

So basically with jQuery, I am trying to loop through 3 paragraphs containing tweets. The 3 paragraphs are all of class .tweet-text
For some reason, in the following code, $test2 will be set properly to the first tweet's text, but in the each loop, the js crashes whenver i try to set str. Why is this?
var $tweets = $(".sidebar-tweet .tweet-text");
var $test2 = $tweets.text();
alert($test2);
$tweets.each(function(i, $tweet){
var str = $tweet.text();
alert(str);
});
I've been trying to debug this with Firebug but to no avail. Thanks for the help.
var $tweets = $(".sidebar-tweet .tweet-text");
$tweets.each(function(i, current){
var str = $(current).text();
alert(str);
});
The issue was that the current object is not by defalt a jquery object, you must wrap it $(current) ... to use the jquery methods
try this instead
var str = $(this).text();
Because $tweet will be a regular javascript object, not a jQuery object. You'll need to wrap it like:
var str = $($tweet).text();
The second argument to the .each method is not a jquery object, but the actual DOM element.
So you need to wrap it in jQuery again..
var $tweets = $(".sidebar-tweet .tweet-text");
var $test2 = $tweets.text();
alert($test2);
$tweets.each(function(i, tweet){
var str = $(tweet).text();
alert(str);
});
demo: http://jsfiddle.net/gaby/xjmZy/

Categories

Resources