Selecting child text with jQuery - javascript

I have a structure like the following:
<form>
<input type="text" />
<input type="text" />
...
<input type="radio" />
<input type="whatever" />
Here I have some text
</form>
I cannot change the structure of the HTML. I need to remove via Javascript the text inside the form, and the problem is to select it, since it is not wrapped inside any tag.
My solution (more a hack actually) using jQuery is the following
$('form').contents().filter(function(){
return (this.toString() == '[object Text]')
}).remove();
but it's not very robust. In particular it fails on IE (all versions), where this.toString() applied to a chunk of text returns the text itself. Of course I could try
$('form').contents().filter(function(){
return (this.toString() != '[object]')
}).remove();
but I'm looking for a better solution.
How am I supposed to remove the text?
Both a solution using jQuery or plain Javascript is good for me.

You filter for this.nodeType == Node.TEXT_NODE. Take a look at this answer.

Try this, instead of just "this.toString()":
return (Object.prototype.toString.call(this) == '[object Text]');
You could also check the node type, but I never can remember how to do that; I'll go look it up but somebody's going to beat me to it :-)
edit told ya!

If you use version 1.4 you can
var $temp= $('form').children().detach();
$('form').empty().append($temp);
It will remove all children elements, empty the form (the text..) and reinsert the elements..
the same in 1.3.x would require an additional step..
var $temp= $('<div />');
$('form').children().appendTo($temp);
$('form').empty().append($temp.children());
[Update] in regards to Andrea's comment
quoting jquery contents()
The .contents() and .children()
methods are similar, except that the
former includes text nodes as well as
HTML elements in the resulting jQuery
object.

How about:
$('form').contents().filter(function(){
return !this.outerHTML;
}).remove();

Related

Match specific text only - jQuery string

I am using the below code to change a class name of a button. However, I only want to do this for one button with the text 'Upload' and not another button that says 'Upload Database'.
Is it possible to change this from a 'Contains' to an exact match only?
<script>
$( ".sitebutton:contains('Upload')" ).addClass('siteButton2').removeClass('sitebutton');
</script>
You cannot do this with :contains as it's a 'hungry' match. An alternative is to use filter(), where you can do an exact match:
$('.sitebutton').filter(function() {
return $(this).text().trim() == 'Upload';
}).toggleClass('siteButton2 sitebutton');
If possible, a much better solution would be to just put an id or class on the required button element and select via that.
Just use a jQuery filter on the elements:
$('.sidebutton')
.filter((i, e) => $(e).text() === 'Upload')
.addClass('sideButton2')
.removeClass('sideButton');
You might need to trim the text, as there could be some extra whitespace floating around.
You can use .filter() to check the .textContent of the element, :contains() checks if the text is included within the .textContent or .innerText in any form by using .indexOf() internally
$(".sitebutton").filter(function(i, el) {
return el.textContent === "Upload"
})
.removeClass('sitebutton')
I think you're generally making it harder on yourself, but you can do something like this:
$(".sitebutton.Upload").not(".Database").addClass('siteButton2').removeClass('sitebutton');
Just put a specific id for the button and then call the needed code to change the class.
Check this Plunker
This is the code
HTML:
<input type=button id="upload" value="Upload" class="sitebutton">
<input type=button id="uploaddb" value="Upload Database" class="sitebutton">
Script
$('#upload').click(function() {
$('#upload').addClass('siteButton2').removeClass('sitebutton');
});

How to get html content of a input tag?

I have an input tag:
<input type="text" value="04/09/2013" class="date-time-date width-100 hasDatepicker" name="booking_info[to_time_24_date]" id="to_time_24_date" readonly="readonly">
i need to get all the content in input tag (all content shown above) but when i use
$('#to_time_24_date').html();
it returns nothing. How can i get this content?
Try this:
document.getElementById('to_time_24_date').outerHTML;
Use this simple method in order to get all of your input field HTML:
$('#to_time_24_date').get(0).outerHTML;
I have made a JsFiddle Test Demo for you, Please follow this link. It will give the same thing you are looking for, in alert.
http://jsfiddle.net/jpaYK/
You may try the outerHTML property.
$('#to_time_24_date').get(0).outerHTML
you can use outerHTML
$('#to_time_24_date').get(0).outerHTML; // $('#to_time_24_date')[0].outerHTML;
Demo: Fiddle
without jQuery
document.getElementById('to_time_24_date').outerHTML
html() gets the inner HTML, HTML of the elements inside this element.
Check the answer here:
Get selected element's outer HTML
The accepted answer uses a nice trick in the answer to this question. It creates another element (but doesn't add it to the page), clones the element it wants inside the created element, and then gets the inner HTML of the created element, which is the HTML of the clone, which is the same HTML of the element we want.
$("<div>").append($('#to_time_24_date').eq(0).clone()).html();
// or
$("<div>").append(document.getElementById('#to_time_24_date').clone()).html();
However, see other answers as well, turns out there is a simpler way you can try too, there's a property outerHTML you can use as:
$('#to_time_24_date')[0].outerHTML
Which has decent browser support as per:
https://developer.mozilla.org/en-US/docs/Web/API/element.outerHTML?redirectlocale=en-US&redirectslug=DOM%2Felement.outerHTML
var html = "<input";
$.each($("#"+to_time_24_date)[0].attributes, function(i, attr){
html += ' '+attr.name+'="'+attr.value+'"';
});
html += " />";
alert(html);
jsfiddle
<input type="text" value="04/09/2013" class="date-time-date width-100 hasDatepicker" name="booking_info[to_time_24_date]" id="to_time_24_date" readonly="readonly">
This does not have any "Content" or "HTML" it does have attributes, and you can get the attributes with the attr method from jQuery.. $('input[type="text"]').attr('id'); would return the id attribute.
If you are just looking for the entered value of the input tag (what is typed in) then use $('input[type="text"]').val(); to get the value.
I hope this helps
here's a jsfiddle example
http://jsfiddle.net/LUep8/

Cleanest way to query for parent class using JQuery

I'm having trouble coming up with a solution that pleases me.
I'm working with some composite components, and I don't have full control over them, and now I have to set values to them using JavaScript, and I thought JQuery would serve me well, as it did.
What happens is that the component's HTML output has a structure simlar to this:
<span id="externalSpan">
<span id="internalSpan">
<input type="text" class="component-value" />
</span>
</span>
So all I had to do was check the component-value input, and if it's empty, I set the default value to it.
I solved it like this:
$(document).ready(function(){
var defaultValue = $('#defaultValue').val();
$('.component-value').each(function(){
if(!$(this).val()){
$(this).val(defaultValue);
}
});
});
And that worked fine, but now there's a new condition I need to evaluate. If the component has the manualInput CSS class, I cannot set it's value, but the class is set on the externalSpan which is the input's grandfather component, and it looks like this:
<span id="externalSpan" class="manualInput">
<span id="internalSpan">
<input type="text" class="component-value" />
</span>
</span>
The simplest way that I found to do it was this:
if(!$(this).parent().parent().hasClass('manualInput')){ ... }
And it works, but it seems really smelly to me, another solution was to invoke parents() with a class selector and check the length, but it seems odd too.
Is there a cleaner way for me to do this? And if not, which of the 2 options described above is a better solution?
So add the check to the selector
$('span:not(.manualInput) > span > .component-value').each(function(){
Example JSFiddle
I would use closest :
if(!$(this).closest('#externalSpan').hasClass('manualInput')){ ... }
Source : http://api.jquery.com/closest/
You can do this --
if($(this).closest('.manualInput').length > 0){
// do your stuff
}
A much better solution, use a selector that avoids .component-value elements that are descendants of .manualInput:
$('.component-value:not(.manualInput .component-value)').each(...)
Ideally the grandparent element would have a consistent class such that you could call .closest():
if ($(this).closest('.component-value-grandfather').hasClass('manualInput')) {...}
Alternatively you could check to see if there is a .manualInput ancestor at all:
if ($(this).closest('.manualInput').length) {...}
I'd recommend the following
$('span:not(.manualInput) > span').find('.component-value:empty').each(function () {
$(this).val(defaultValue);
});
Or better yet,
$('.component-value:empty', 'span:not(.manualInput) > span').val(defaultValue);
Probably, the shorted piece of code to achieve what you desire.
Alternatively you could use
if ($(this).parents('.manualInput').length) {/*...*/}
See jquery documentation. I suppose this is the shortest way to find the parent(s) of a given element

How to get the name of an element with Javascript?

I'm trying to get the name of an element in Javascript. Meaning if the element is <div />, then "div" would be returned. If it's <img src="" /> then "img" would be returned. I'm using jquery to select a bunch of elements and then calling a custom function on all of them. Within that function I want to know what I'm dealing with. How do I do this?
Seems like a simple thing. And I think I've done it before but I just can't find it. Google results keep giving me "get element by name" no matter how I phrase it.
Use nodeName (see this note about tagName):
"My advice is not to use tagName at all.
nodeName contains all functionalities of tagName, plus a few more. Therefore nodeName is always the better choice."
tagName or nodeName
$(selector).each(function() {
switch (this.tagName) {
// Handle cases
}
});
You want element.nodeName Or, within jQuery:
$(".includeMe").each(function(){
alert(this.nodeName);
});
<img class="includeMe" src="puppies.jpg" />
<div class="includeMe">Hello World</div>
<p class="includeMe">Don't forget me as well</p>
For element.tagName and element.nodeName return the name of your tag, in uppercase.
If you want it in lowercase, just use element.tagName.toLowerCase() or element.nodeName.toLowerCase().

jQuery selector bug? composed selector vs. simple selector & find()

Something is very awkward about my situation... i have something like this:
<div id="selector">
<input type='radio' />
<input type='radio' />
<input type='radio' />
</div>
if I use $("#selector input[type=radio]") all three elements are found, but if I use $("#selector").find("input[type=radio]") or even find("input") only the first one is found.
Is this a bug in jQuery? Am I not using find() properly?
Clarification : I want to use find() to get all the inputs, but anything I try finds only the first one.
edit: i'm using jquery 1.3.2
What you really want is:
$("#selector > :radio")
As for why you're getting only one, I'd need to see the actual code that's being run because find() doesn't stop at one and will find all matches so it may be how you're using it afterwards that is the issue.
The two code fragments should return the same result.
Are you saying that when you run the following code, the first alert will show "3" and the second "1" ?
var a = $("#selector input[type=radio]");
var b = $("#selector").find("input[type=radio]");
alert(a.length);
alert(b.length);
Can you please verify?
Try
$("#selector").find("input[type=radio]")
See here
All the three returns the same result!
$(function() {
console.log($("#selector input[type=radio]")); // 3
console.log($("#selector").find("input[type=radio]")); // 3
console.log($("#selector").find("input")); // 3
});
$("#selector").children("input[#type=radio]")

Categories

Resources