JQuery Attribute Wildcards Contains space separated - javascript

is there a way to get a element that have a attribute with a value. The attribute have multiple values. The values are space separated.
<div data-bind-contains="Header-Logo Footer-Logo"></div>
The problem with $('[data-bind-contains*=Header-Logo]') it will return all. That elements $('[data-bind-contains*=Header-Logo-Something]'), too.
<div data-bind-contains="Header-Logo Footer-Logo"></div>
<div data-bind-contains="Header-Logo-Looper"></div>
The selector $('[data-bind-contains*=Header-Logo]') will return both what is not my intention.

Use ~ (Attribute contains word) match selector
$('[data-bind-contains~=Header-Logo]')
This will give you exact word matched within the attribute value, so this should exclude yourword-something.
Fiddle to demonstrate the difference.
Doc

From your question, you seem have no guarantee that "Header-Logo" is the first string in your list of values.
It's surely not a problem to more specifically test the value against a proper regex in the function called by the selector, is it? This may be a bit longer than needed but shows the idea....
$('[data-bind-contains*=Header-Logo]').click( function() {
var str = $(this).attr('data-bind-contains');
var pat=/\bHeader-Logo\b/;
if (str.match( pat)) {
// do some stuff
}
});

Try this
$('[data-bind-contains*="Header-Logo "]')
This return elements that have data-bind-contains attribute value start with "Header-Logo "
Put a space at the and of attribute value in jQuery so it only returns element that have value "Header-Logo<space>+<some_other_class>"

Related

How to apply range of values to a partial attribute selector? [duplicate]

I am after documentation on using wildcard or regular expressions (not sure on the exact terminology) with a jQuery selector.
I have looked for this myself but have been unable to find information on the syntax and how to use it. Does anyone know where the documentation for the syntax is?
EDIT: The attribute filters allow you to select based on patterns of an attribute value.
You can use the filter function to apply more complicated regex matching.
Here's an example which would just match the first three divs:
$('div')
.filter(function() {
return this.id.match(/abc+d/);
})
.html("Matched!");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="abcd">Not matched</div>
<div id="abccd">Not matched</div>
<div id="abcccd">Not matched</div>
<div id="abd">Not matched</div>
James Padolsey created a wonderful filter that allows regex to be used for selection.
Say you have the following div:
<div class="asdf">
Padolsey's :regex filter can select it like so:
$("div:regex(class, .*sd.*)")
Also, check the official documentation on selectors.
UPDATE: : syntax Deprecation JQuery 3.0
Since jQuery.expr[':'] used in Padolsey's implementation is already deprecated and will render a syntax error in the latest version of jQuery, here is his code adapted to jQuery 3+ syntax:
jQuery.expr.pseudos.regex = jQuery.expr.createPseudo(function (expression) {
return function (elem) {
var matchParams = expression.split(','),
validLabels = /^(data|css):/,
attr = {
method: matchParams[0].match(validLabels) ?
matchParams[0].split(':')[0] : 'attr',
property: matchParams.shift().replace(validLabels, '')
},
regexFlags = 'ig',
regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g, ''), regexFlags);
return regex.test(jQuery(elem)[attr.method](attr.property));
}
});
These can be helpful.
If you're finding by Contains then it'll be like this
$("input[id*='DiscountType']").each(function (i, el) {
//It'll be an array of elements
});
If you're finding by Starts With then it'll be like this
$("input[id^='DiscountType']").each(function (i, el) {
//It'll be an array of elements
});
If you're finding by Ends With then it'll be like this
$("input[id$='DiscountType']").each(function (i, el) {
//It'll be an array of elements
});
If you want to select elements which id is not a given string
$("input[id!='DiscountType']").each(function (i, el) {
//It'll be an array of elements
});
If you want to select elements which name contains a given word, delimited by spaces
$("input[name~='DiscountType']").each(function (i, el) {
//It'll be an array of elements
});
If you want to select elements which id is equal to a given string or starting with that string followed by a hyphen
$("input[id|='DiscountType']").each(function (i, el) {
//It'll be an array of elements
});
If your use of regular expression is limited to test if an attribut start with a certain string, you can use the ^ JQuery selector.
For example if your want to only select div with id starting with "abc", you can use:
$("div[id^='abc']")
A lot of very useful selectors to avoid use of regex can be find here: http://api.jquery.com/category/selectors/attribute-selectors/
var test = $('#id').attr('value').match(/[^a-z0-9 ]+/);
Here you go!
Add a jQuery function,
(function($){
$.fn.regex = function(pattern, fn, fn_a){
var fn = fn || $.fn.text;
return this.filter(function() {
return pattern.test(fn.apply($(this), fn_a));
});
};
})(jQuery);
Then,
$('span').regex(/Sent/)
will select all span elements with text matches /Sent/.
$('span').regex(/tooltip.year/, $.fn.attr, ['class'])
will select all span elements with their classes match /tooltip.year/.
ids and classes are still attributes, so you can apply a regexp attribute filter to them if you select accordingly. Read more here:
http://rosshawkins.net/archive/2011/10/14/jquery-wildcard-selectors-some-simple-examples.aspx
$("input[name='option[colour]'] :checked ")
I'm just giving my real time example:
In native javascript I used following snippet to find the elements with ids starts with "select2-qownerName_select-result".
document.querySelectorAll("[id^='select2-qownerName_select-result']");
When we shifted from javascript to jQuery we've replaced above snippet with the following which involves less code changes without disturbing the logic.
$("[id^='select2-qownerName_select-result']")
If you just want to select elements that contain given string then you can use following selector:
$(':contains("search string")')

problem with use of val() in jQuery sometimes failing and setting elements with array id's

I have a project where a form is required for inputs for a week, so for efficiency elsewhere an array of inputs is used (i.e. start[0] etc) this seems to have exacerbated the issue.
The problem is when validating a form where some inputs are given initial values (its an update) jQuery only returns those initial values instead of changed ones unless use of 'this' is feasible. I found to resolve that I had to use:
$(".weekdays").change(function(){
var newval = $(this).attr('value');
$(this).attr('value', newval);
});
Which seems a crazy thing to have to do! Its here I found using $(this).val(newval); always fails except when setting initial values, though its the common given solution?
In the same vein setting check-boxes seems also problematical, using:
var id = $(this).attr('pid');
$("#choice["+id+"]").prop('checked', false);
$("#choiceLabel["+id+"]").css('background-image','url("images/Open.png")');
Always fails, yet reverting to javascript with:
var id = $(this).attr('pid');
document.getElementById("choice["+id+"]").checked = false;
document.getElementById("choiceLabel["+id+"]").style.backgroundImage = 'url("images/Open.png")';
Works fine!
So does jQuery not like inputs with id's in array form? or am I getting things wrong somewhere?
When attempting to select an element with an id that contains special characters, such as [], you have to remember to escape them for jQuery. For instance..
var id = 12;
console.log(
$('#choice\\['+ id +'\\]').get()
);
console.log(
$('#choice[data-something]').get()
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="choice[12]">weee</div>
<div id="choice" data-something>dang!</div>
Otherwise, jQuery will treat them as special characters, in this case, assuming you are trying to find an element that has an id and has an attribute matching your variable value.

Traversing elements in javaScript

I need to change the href of link in a box. I can only use native javaScript. Somehow I have problems traversing through the elements in order to match the correct <a> tag.
Since all the a tags inside this container are identical except for their href value, I need to use this value to get a match.
So far I have tried with this:
var box = document.getElementsByClassName('ic-Login-confirmation__content');
var terms = box.querySelectorAll('a');
if (typeof(box) != 'undefined' && box != null) {
for (var i = 0; i < terms.length; i++) {
if (terms[i].href.toLowerCase() == 'http://www.myweb.net/2/') {
terms[i].setAttribute('href', 'http://newlink.com');
}
}
}
However, I keep getting "Uncaught TypeError: box.querySelectorAll is not a function". What do I need to do in order to make this work?
Jsfiddle here.
The beauty of querySelectorAll is you dont need to traverse like that - just use
var terms = document.querySelectorAll('.ic-Login-confirmation__content a');
And then iterate those. Updated fiddle: https://jsfiddle.net/4y6k8g4g/2/
In fact, this whole thing can be much simpler
var terms = document.querySelectorAll('.ic-Login-confirmation__content a[href="http://www.myweb.net/2/"]');
if(terms.length){
terms[0].setAttribute('href', 'http://newlink.com');
}
Live example: https://jsfiddle.net/4y6k8g4g/4/
Try This:
var box = document.getElementsByClassName('ic-Login-confirmation__content')[0];
Since you are using getElementsByClassName ,it will return an array of elements.
The getElementsByClassName method returns returns a collection of all elements in the document with the specified class name, as a NodeList object.
You need to specify it as follows for this instance:
document.getElementsByClassName('ic-Login-confirmation__content')[0]
This will ensure that you are accessing the correct node in your HTML. If you console.log the box variable in your example you will see an array returned.
you can select by href attr with querySelector,
try this:
document.querySelector('a[href="http://www.myweb.net/2/"]')
instead of defining the exact href attribute you can simplify it even more :
document.querySelector('a[href?="myweb.net/2/"]'
matches only elments with href attribute that end with "myweb.net/2/"

$("selector").find(":psuedo-class") does not return desired elements

I have the following declaration:
var optionsWithAttribute = $(element).find("option[data-attribute]");
I now want to grab the selected options from that set, so I write:
var selectedOptions = optionsWithAttribute.find(":selected");
However this yields the effective selector:
"option[data-attribute] :selected"
which obviously matches nothing (thanks to jquery.whiny for helping me to solve this). The correct selector would be:
"option[data-attribute]:selected"
(note lack of space after the ]).
Obviously this is because subsequent calls to .find() prepend a space so that (for example) the expression $("select").find("option") yields the selector select option as opposed to selectoption. Either I'm doing something wrong - in which case please educate me - or .find() should be changed to not insert a space if the passed-in selector is a pseudo-class (i.e. begins with a colon).
You need to use filter as optionsWithAttribute contains the option elements, find() will look for a matching descendant element
var selectedOptions = optionsWithAttribute.filter(":selected");
.find() selects children of the parent element , you need to use .filter() which will give you only the items with the select attribute
When you use this code var selectedOptions = optionsWithAttribute.find(":selected"); jquery will search all the elements with the attribute selected from the tag options (optionsWithAttribute)
try to use filter() method
Reduce the set of matched elements to those that match the selector or
pass the function's test.
var selectedOptions = optionsWithAttribute.filter(":selected");
"option[data-attribute] :selected"
which obviously matches nothing
Absolutely because that is incorrect, you can't find selected option inside options, so change it to:
var optionsWithAttribute = $(element).find("option[data-attribute]:selected");
console.log(optionsWithAttribute)

Is jquery ":contains" selector accepts this kind of value "Banking and Finance"?

I'm having problem with the contains in jquery. It seems that it only accepts one word. Not a phrase or two words.
Example:
$('#div:contains('Word')'); --> This is okay
$('#div:contains('Just another word')'); --> This will return empty/this will not match.
Do you have any experience with this kind of problem?
Your reply is greatly appreciated.
What you need, is to use double quotes (instead those single quotes wrapping the whole selector), for example:
$("p:contains('John Resig')");
this will select the correct paragraph, with string 'John Resig' inside
or you can inverse it:
$('p:contains("John Resig")');
or you can use an old good escaping:
$('p:contains(\'John Resig\')');
Try it without the # and avoid using the same quoting within the code:-
$("div:contains('Just another word')");
Assuming you didn't already solve this, from your comment which included:
var selected = $(this).find(':selected').text();
if (selected.toLowerCase() != "all industries") {
if (trim(selected).length > 0) {
$("#contact-list-selectable li .contact-info-industry").parent().css("display", "none");
$("#contact-list-selectable li .contact-info-industry:contains('" + selected + "')").parent().css("display", "block");
alert($("li[style='display: block;']").text());
}
I'll assume you meant to use trim as a method on the string, or if not that you have a trim function defined somewhere else. If this is actually how your code looks and you have no custom trim function, then that's going to be your first problem, it should be: selected.trim().length
One potential issue is that while you check that the trim of selected is > 0, you don't use a trimmed version of selected when checking the contains. If you have any spaces/etc in your selected variable, it will fail for contains.
Here is an example. Note the trailing space in selected = "computer science "; that is intentional to demonstrate what happens in that case.
if you change
$("#contact-list-selectable li .contact-info-industry:contains('" + selected + "')").parent().css("display", "block");
to
$("#contact-list-selectable li .contact-info-industry:contains('" + selected.trim() + "')").parent().css("display", "block");
you can avoid this issue (working example, see here, note the trailing space is still there).
The only other issue I could think of would be if you were incorrectly forming any of your selectors and they did not actually match your DOM structure. Otherwise everything works fine in current jquery.

Categories