So I've seen several posts explaining how to use a variable in a value for attribute selection. i.e. (where the JS event refers to the div (making it $(this):
HTML
<div id="item1"></div>
<div id="item1" style="display: none;"></div>
JS
var find = $(this).attr("id")
$('div[id="'+find+'"]').show();
But I would like to know how to use a variable in a jquery selector to find something with a similar string to the value of the variable. i.e. finding an element from the example above but looking for "#item1div", where the event target is still "#item1"
HTML
<div id="item1"></div>
<div id="item1div" style="display: none;"></div>
JS
var find = $(this).attr("id")
$('div[id="'+find+"div"'"]').show(); // incorrect syntax
So my question is: How do I correct the above syntax to include an additional string in the attribute check?
I can't find any reference to the correct syntax for how to add compile a string of the value of a variable and an explicit string then check that as the value for x attribute.
I know I can use [id*="'+find+'"] here because the alternate id contains the same characters as the basic one, but I want to know how to target a specific other id based on the first one. For example if I had #item1, #item1div, and #item1img, how can I use an event on "#item1" to find attribute values equal to "item1div" and/or "item1img"
EDIT: I also just realized I can just use [id|="'+find+'"] if I name the divs accordingly with hyphens, but again doesn't solve ids with different endings (or different strings that come after the hyphen)
$('div[id="'+find+"div"'"]') isn't valid Javascript syntax:
$( // jQuery function
'div[id="' // String
+ find // Add variable
+ "div" // Add String
'"]' // Unexpected string! - Error
One example of valid syntax would be:
$('div[id="'+find+'div"]')
However, since it's an id, you can use the id selector instead:
$('div#'+find+'div')
the question is very unclear, but I assume your question boils down to :
Q:how do you search all the elements where it starts with string x ?
A:To get all the elements starting with "item1" you should use:
$("[id^=item1]")
You should use ID selector like below to find an element by ID,
$('#' + find).show();
To find item1div or the dynamic first part - $('#' + find + 'div')
Note: the incorrect syntax you had mentioned is because of a missing + - It should be
// V-- you missed this
$('div[id="'+find+"div"+'"]').show();
To add the explicit string to the attr value you can write as follows
$('[attr="'+attrVal+'extraString"]')
For evample in case of id of div itemdiv
var item1ID = $('#item1').attr('id'); // item1
$('[id="'+item1ID+'div"]') // valid selector to select #item1div
Related
I have a CSS rule for hiding elements with a class="hidden" and I'm using jQuery to toggle this class on and off on whatever ID i click on so I can make elements disappear.
Why does this not work?
$(this).attr('id').toggleClass("hidden");
but this does?
var x = "#" + $(this).attr('id');
$(x).toggleClass("hidden");
I know that the id is being taken correctly on the first example, but it seems that to toggle the class I have to add a "#". I haven't seen any examples of others having to resort to this so I'm wondering what madness I have here.
Many thanks
$(this).attr('id').toggleClass("hidden");
You are chaining events here. $(this).attr('id') already returns you a string. So you are technically doing "someid".toggleClass("hidden") which doesn't makes sense.
In your second example, you are actually selecting the same element again via id and firing your method, which is right
.attr('id') returns a string, not an element.
Let's pretend your element has an ID of myThing. Here's what your code translates to:
// 1
"myThing".toggleClass("hidden");
// 2
var x = "#myThing";
$("#myThing").toggleClass('hidden');
But really, if you're getting the ID from this, there's no reason to extract the ID in the first place. Just use this directly.
$(this).toggleClass('hidden');
You can simply use:
$(this).toggleClass("hidden");
$(this) is the actual element you're working with, so you can use this to directly toggle classes with.
In your examples, $(this).attr('id') is a string, and not an element.
This code works, because you're taking the ID (As a string), and selecting the ID on the webpage.:
//Store the id into a string
var x = "#" + $(this).attr('id');
//Pass the ID back into jQuery, and find the element
$(x).toggleClass("hidden");
I need to be able to select and modify an element in an HTML document. The usual way to find an element using jQuery is by using a selector that selects by attribute, id, class or element type.
However in my case I have the element's HTML DOM and I want to find the element on my document that matches this DOM.
Important :
I know I can use a class selector or ID selector etc.. but sometimes the HTMLs I get don't have a class or an ID or an attribute to select with, So I need to be able to select from the element's HTML.
For example here is the element I need to find :
<span class='hello' data='na'>Element</span>
I tried to use jQuery's Find() but it does not work, here is the jsfiddle of the trial : https://jsfiddle.net/ndn9jtbj/
Trial :
el = jQuery("<span class='hello' data='na'>Element</span>");
jQuery("body").find(el).html("modified element");
The following code does not make any change on the element that is present in my HTML and that corresponds to the DOM I have supplied.
Is there any way to get the desired result either using native Javascript or jQuery?
You could filter it by outerHTML property if you are sure how browser had parsed it:
var $el = jQuery("body *").filter(function(){
return this.outerHTML === '<span class="hello" data="na">Element</span>';
});
$el.html("modified element");
el = jQuery('<i class="fa fa-camera"></i>');
This does not say "find the element that looks like <i class="fa fa-camera"></i>". It means "create a new i element with the two classes fa and fa-camera. It's the signature for creating new elements on the fly.
jQuery selectors look like CSS, not like HTML. To find the i element with those two classes, you need a selector like i.fa.fa-camera.
Furthermore $("document") looks for an HTML element called document. This does not exist. To select the actual document, you need $(document). You could do this:
$(document).find('i.fa.fa-camera').html("modified html")
or, more simply, you could do this:
$('i.fa.fa-camera').html('modified html');
You indicate in a comment to your question that you need to find an element based on a string of HTML that you receive. This is, to put it mildly, difficult, because, essentially, HTML ceases to exist once a browser has parsed it. It gets turned into a DOM structure. It can't just be a string search.
The best you can do is something like this:
var searchEl = jQuery('<i class="fa fa-camera"></i>');
var tagName = searchEl.prop('tagName');
var classes = [].slice.apply(searchEl.prop('classList'));
$(tagName + "." + classes.join('.')).html('modified html');
Note that this will only use the tag name and class names to find the element. If you also want IDs or something else, you'd need to add that along the same lines.
You should use Javascript getting the elements by something like
document.getElementById...
document.getElementsByClassName...
document.getElementsByTagName...
Javascript is returning the elements with the Id, Class or Tag Name you chose.
You can get en element with document.querySelector('.fa-camera')
with querySelector you can select IDs and Classes
You can simply refer to it by its class names.
$('.fa.fa-camera').html("modified html");
Similar to this answer https://stackoverflow.com/a/1041352/409556
Here is a full example:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('.fa.fa-camera').html("modified html");
});
</script>
</head>
<body>
<i class="fa fa-camera"><h1>Some HTML</h1></i>
</body>
</html>`
The one thing that you could use is to check attributes (class and id goes here too in some way) that element have, and the build jQuery selector or DOM querySelector to find the element you need. The hardest part would be to find element based on innerHTML property - "Element" text inside it, for this one you'll probably have to grab all similar element and then search through them.
<span class='hello' data='na'>Element</span>
jQuery('body').find('span.hello[data=\'na\']').html('modified element')
Take notice of 'span' - that's tag selector, '.hello' - class, '[data="na"]' data attribute with name of data.
Jsfiddle link here that extends your example;
I am writing a small library where I am in need of selecting a relative element to the targeted element through querySelector method.
For example:
HTML
<div class="target"></div>
<div class="relative"></div>
<!-- querySelector will select only this .target element -->
<div class="target"></div>
<div class="relative"></div>
<div class="target"></div>
<div class="relative"></div>
JavaScript
var target = document.querySelectorAll('.target')[1];
// Something like this which doesn't work actually
var relativeElement = target.querySelector('this + .relative');
In the above example, I am trying to select the .relative class element relative only to the .target element whose value is stored in target variable. No styles should apply to the other .relative class elements.
PS: the selectors can vary. So, I can't use JavaScript's predefined methods like previousElementSibling or nextElementSibling.
I don't need solution in jQuery or other JavaScript libraries.
Well it should be ideally:
var relativeElement = target.querySelector('.relative');
But this will actually try to select something inside the target element.
therefore this would only work if your html structure is something like:
<div class="target">
<div class="relative"></div>
</div>
Your best bet would probably in this case be to use nextElementSibling which I understand is difficult for you to use.
You cannot.
If you insist on using the querySelector of the subject element, the answers is there is no way.
The spec and MDN both says clearly that Element.querySelector must return "a descendant of the element on which it is invoked", and the object element you want does not meet this limitation.
You must go up and use other elements, e.g. document.querySelector, if you want to break out.
You can always override Element.prototype.querySelector to do your biddings, including implementing your own CSS engine that select whatever element you want in whatever syntax you want.
I didn't mention this because you will be breaking the assumption of a very important function, easily breaking other libraries and even normal code, or at best slowing them down.
target.querySelector('.relative');
By using querySelector on the target instead of document, you scope the DOM traversal to the target element.
It is not entirely clear from your explanation, but by related i assume you mean descendant?
To get all target elements you can use
document.querySelectorAll('.target')
And then iterate the result
I found a way which will work for my library.
I will replace "this " in the querySelector with a unique custom attribute value. Something like this:
Element.prototype.customQuerySelector = function(selector){
// Adding a custom attribute to refer for selector
this.setAttribute('data-unique-id', '1');
// Replace "this " string with custom attribute's value
// You can also add a unique class name instead of adding custom attribute
selector = selector.replace("this ", '[data-unique-id="1"] ');
// Get the relative element
var relativeElement = document.querySelector(selector);
// After getting the relative element, the added custom attribute is useless
// So, remove it
this.removeAttribute('data-unique-id');
// return the fetched element
return relativeElement;
}
var element = document.querySelectorAll('.target')[1];
var targetElement = element.customQuerySelector('this + .relative');
// Now, do anything with the fetched relative element
targetElement.style.color = "red";
Working Fiddle
I have a little problem. I have a code with a form input, but the form input class is named
text-input small-input
I can't change this because of CSS issues and this is the problem, because when I add the space in my javascript code, my code doesn't work anymore
Javascript code
$(document).ready(function() {
$('.text-input*small-input').keyup(function() {
var search_term = $(this) .val();
$.post('search.php', {search_term:search_term}, function(data) {
$('.result').html(data);
$('.result li').click(function() {
var result_value = $(this).text();
$('.text-input*small-input') .val(result_value);
$('.result').html(' ');
});
});
});
});
So at the * sign, there needs to be a space. Any way to solve this? Thanks!
you do not want a space, you want nothing there. just .text-input.small-input to tell the selector engine to look for an element with both of those classes.
here is a very good article explaining multiple part selectors.
You had two issues. You don't want a space and you do want a dot on the second class.
To specify a requirement of two classes on the same object in a CSS selector, you put no space between the two class names:
$('.text-input.small-input') // find single object with both classes on it
With a space, it does something different:
$('.text-input .small-input') // find .small-input with ancestor .text-input
When you put a space between them, that creates a selector that finds an object that matches .text-input and a child that matches .small-input and the matched object is the child. No space between them means both classes must be on the same object. This is how CSS specifications work and isn't jQuery-specific.
FYI, what you were trying to do with this:
$('.text-input small-input') // find <small-input> with ancestor that is .text-input
was trying to find an object with a tag of <small-input> that had an ancesotr of .text-input because you put no special character in front of small-input so it was interpreted as a tag name.
I'm trying to do something similar to this question, but it's a bit different, so the solution there isn't working for me.
<span class="a-class another-class test-top-left"></span>
I have an element (this code shows a span but it could be div span or anything). This element has a class beginning with test- (test-top-left, test-top-right etc.) I've triggered a click event on classes starting with test- and saved the clicked object as var object = this;. Simple stuff so far.
What I'm trying to do now is get the full name of that class (test-top-left). I know it starts with test- but what's the full name. The thing is that there are other classes a-class another-class and test-top-left. Can hasClass be used to get the full name of the class? I'd prefer not to use find() or filter() just because there may be additional elements within that also have class="test-"
Edit:
The code I have now is, but it gives me ALL the classes. What I need is the single class beginning with test-.
var object = this;
$(object).attr('class');
So now I for loop through all the classes and test each one separately, which seems like a lot of unnecessary code. I'm hoping jQuery has a clever way to get the exact class that was clicked right away.
Description
You can use jQuerys Attribute Contains Selector, .attr() and .click() method.
Attribute Contains Selector - Selects elements that have the specified attribute with a value containing the a given substring.
.attr() - Get the value of an attribute for the first element in the set of matched elements.
.click() - Bind an event handler to the "click" JavaScript event, or trigger that event on an element.
Sample
html
<span class="anyclass test-hello">Hello World</span>
jQuery
$("[class*='test']").click(function() {
var object = $(this);
alert(object.attr("class").match(/(test-.*?)(?:\s+|$)/)[1])
;});
Check out the updated jsFiddle
Update
If you dont want to use regex you can do this.
$("[class*='test']").click(function() {
var object = $(this);
alert("test-" + object.attr("class").split("test-")[1].split("-"))
;});
More Information
jQuery - Attribute Contains Selector
jQuery - .attr()
jQuery - .click()
jsFiddle Demonstration
This should work for you:
var object = this;
var className = object.className.match(/(test-.*?)(?:\s+|$)/)[1];
Class name is the name of the class you are looking for.
If you don't want to use split or regex, you can try having the class in a separate attribute
<span class="someclass test-something" _rel="test-something">test<span>
or
<span class="someclass" _rel="test-something">test<span>
with the script
$("[_rel*='test-']").click(....
And to retrieve the attribute, use $(this).attr("_rel")