jquery each regexp href check some strings at the same time - javascript

people!
I have this:
$('.download_video a[href*="flv"]').each(function() {
$( this ).addClass('videoCl');
});
I would like to perform many checks in a single code line like:
$('.download_video a[href*="flv|mpeg|ogg"]').each(function() {
$( this ).addClass('videoCl');
});
I've realized flv|mpeg|ogg is not working. I think it is a matter of little detail...
Anyone could help me?
Tks a lot!

You can't put multiple attribute selectors in a single selector. However, you can combine multiple selectors using comma:
$('.download_video')
.find('a[href*=flv], a[href*=mpeg] a[href*=ogg]')
.addClass('videoCl');
Notice that you don't need to use .each if you're doing the same operation to each element; jQuery automatically maps over the entire set.

Try
$.fn.attrs = function () {
var args = arguments[0];
var elem = $(this);
var map = $.map(arguments[1], function (v, k) {
return ($("[" + args + "*=" + v + "]").is(elem)
? elem[0].nodeName.toLowerCase()
+ "[" + args + "*=" + v + "]"
: null);
});
return $(map.toString());
};
$(".download_video a")
.attrs("href", ["mpeg", "flv", "ogg"]).addClass("videoCl");
jsfiddle http://jsfiddle.net/guest271314/834q1awc/

Related

Get "id" values from first three tags only and separate them with "," in output

I have a situation, hope experts here will help me to sort it out. I need to get "id" values for first three tags and than on console.log print the values with comma separated.
I have managed to get the values from tag and print it on output. However, I am not able to comma separate them, and the issue is I am getting id of all the number of articles rather than only 3.
This is the jquery code that I come up with
jQuery(document).ready(function($) {
$("article").each(function() {
var info1 = $(this).attr("id");
var info2 = info1.replace( /[^\d]/g, '');
console.log(info2);
});
});
And this is the test
http://jsfiddle.net/0mvjbkhs/1/
Please note that I am not able to do any changes to html, all I can do is to get things done using jquery.
Please help to fix my code, So my output will looks like
[155569, 155570, 155571]
Thank you,
Use the jQuery .map() method which returns an array; if you need a single comma-delimited string, use the JavaScript .join() method. Don't forget :lt(3) which say you want the first three:
var arr1st3 = $('article:lt(3)').map(function() {
return this.id.replace(/[^\d]/g, '');
}).get();
console.log( arr1st3 );//OUTPUT: ["155569", "155570", "155571"]
//If you want [155569, 155570, 155571] as output
//use return +this.id.replace(/[^\d]/g, ''); instead
DEMO
jQuery(document).ready(function($) {
// search by the attribute
var ids = $('article')
// Take only the first three items
.slice(0, 3)
// Loop them to return an array
.each(function() {
// Get just the id and put that in the array
return this.attr('id');
});
// Format your output
console.log('[' + ids.join(', ') + ']');
});
http://jsfiddle.net/0mvjbkhs/4/
jQuery(document).ready(function($) {
var articles = [];
$("article").each(function() {
var info1 = $(this).attr("id").replace( /[^\d]/g, '');
articles.push(info1);
if (articles.length == 3) {
// break;
return false;
}
});
console.log('[' + articles.join(', ') + ']');
});

Get options of a dynamic select

I wanted to get the following code dynamic:
var items = $("#scenario_select option");
Above should become (with dropDownObj= $("#scenario_select"); :
function someFunction(dropDownObj){
var items = $(dropDownObj + " option");
var items = $("#" + dropDownObj + " option");
}
This both doesn't work. I did not find any help on that (only without the options tag)
Any help is greatly appreciated.
Try this:
function someFunction(dropDownObj){
var items = $('#' + dropDownObj.prop('id') + " option");
}
But I suppose a more 'proper' way to do it would be to use find as suggested by #Exception, or use:
function someFunction(dropDownObj){
var items = $("option", dropDownObj);
}
Which basically does the same thing as .find(). See This SO question for a comparison between the two (tl;dr: They are pretty much equivalent).
To find the number of items (as you noted in the comments) you could also use:
function someFunction(dropDownObj){
var items = $("option", dropDownObj).length;
}
Which is a bit shorter than the solution you posted in the comments.
You should also note that since
dropDownObj= $("#scenario_select");
It is already a jQuery object, and you don't need to wrap it using $. With this in mind you solution becomes:
var items = dropDownObj.children('option').length;
This should work.
var dropDownObj = $('#yourDropDownID');
dropDownObj.find('option')

How to make an array of CSS classes

How do I make an array of CSS classes, not the CSS class names? I need the "." and everything.
I need users to be able to click on certain buttons, and add the classes the button belongs to into an array.
I used this before:
var myPicks[];
$('.button').click( function() {
var hello = " " + $(this).attr('class').split(' ')[0];
myPicks.push(hello);
}
But that seems to add the name of the classes, not the classes themselves. It's possible I'm wrong and there's something wrong with another part of my JQuery code.
Try
var myPicks = [];
$('.button').click( function() {
Array.prototype.push.apply(myPicks, $.map($(this).attr('class').split(' '), function(value, idx){
return '.' + value
}))
console.log('myPicks', myPicks)
});
if you want only unique classes
var myPicks = [];
$('.button').click( function() {
$.each($(this).attr('class').split(' '), function(idx, value){
var selector = '.' + value;
if($.inArray(selector, myPicks) == -1){
myPicks.push(selector)
}
})
console.log('myPicks', myPicks)
});
Demo: Fiddle
I will not recommend save the name of the class with the dot included into that array(), It will be useless if you need it later for something else.
(Or your goint to need to split it again)
Instead, I suggest to save it like you have now and then and only when you needed, add the dot to that value
like:
var myPicks = new Array();
myPicks[0] = "something";
// original value:
var newValue = myPicks[0]; // newValue == 'something'
//used as ID:
var newValue = '#' + myPicks[0]; // newValue == '#something'
// used as a class:
var newValue = '.' + myPicks[0]; // newValue == '.something'
BUT, of course if you need that way... just replace the PUSH function and add the dot to it:
var newHello = '.' + hello;
myPicks.push(newHello);

How to change the id of deep nested elements with jQuery

I have this recursive code that transverses the DOM and adds a prefix to the id for all input tags.
I would like to change this to a more elegant jQuery, but I'm not sure how to structure the selectors or if the selectors need to be recursive..
cheers,
function set_inputs(obj, prefix){
for (var s=0;s< obj.childNodes.length; s++){
var node = obj.childNodes[s];
if(node.tagName == "INPUT"){
node.id= prefix +'_' + node.id;
node.name= prefix +'_' + node.name;
}
else{
set_inputs(node,prefix);
}
}
}
For the entire DOM.
It would be as simple as:
var prefix;
$("input").each(function(i,elem)
{
$(elem).attr("id", prefix + "_" + $(elem).attr("id"));
});
You could change the selector : $("input") - which selects all the doms inputs, to any other selector to target different elements.
If you wanted it separately in a function then:
function() set_inputs(col, prefix) {
col.each(function(i,elem)
{
$(elem).attr("id", prefix + "_" + $(elem).attr("id"));
});
}
You would then use it like this:
set_inputs($("input"), "abc");//prefix ALL the DOM's inputs with abc
set_inputs($("input.btn"), "abc");//prefix inputs with the css-class btn
No particular need to use jQuery for this either. It could be done in plain javascript without recursion using getElementsByTagName() like this:
function set_inputs(obj, prefix) {
var nodes = obj.getElementsByTagName("input");
for (var i = 0, len = nodes.length; i < len; i++) {
if (nodes[i].id) {
nodes[i].id = prefix + '_' + nodes[i].id;
}
if (nodes[i].name) {
nodes[i].name = prefix + '_' + nodes[i].name;
}
}
}
P.S. I added protection in the code that your code did not have in case input tags exist without an id or a name attribute so the code won't error out if it encounters that. If you didn't want that protection, the code would be shorter like this:
function set_inputs(obj, prefix) {
var nodes = obj.getElementsByTagName("input");
for (var i = 0, len = nodes.length; i < len; i++) {
nodes[i].id = prefix + '_' + nodes[i].id;
nodes[i].name = prefix + '_' + nodes[i].name;
}
}
You call this function by passing it two arguments, the DOM object that represents the top of the part of the DOM tree you want to search for input tags in and the prefix you want to add to the IDs. If you do something like this: set_inputs(document.body, "test") it will search the entire document. If you do something like this: set_inputs(document.getElementById("top"), "test"), it will only search a portion of the DOM tree (the part under the id=top element). You can pass it any arbitrary DOM object and it will only search the nodes in that hierarchy.
Just want to suggest a small change
$('input').each(function(){
this.id = prefix + this.id;
});
To pull the deep nested inputs, use jquery find(). This solution is much simpler code than recursive javascript. I did leave out the steps verifying the existence of id and name attributes which should be done for production code.
$(obj).find("input").each(function(){
$(this).attr('id',prefix + "_" + $(this).attr('id'));
$(this).attr('name',prefix + "_" + $(this).attr('name'));
});

Remove all classes that begin with a certain string

I have a div with id="a" that may have any number of classes attached to it, from several groups. Each group has a specific prefix. In the javascript, I don't know which class from the group is on the div. I want to be able to clear all classes with a given prefix and then add a new one. If I want to remove all of the classes that begin with "bg", how do I do that? Something like this, but that actually works:
$("#a").removeClass("bg*");
A regex splitting on word boundary \b isn't the best solution for this:
var prefix = "prefix";
var classes = el.className.split(" ").filter(function(c) {
return c.lastIndexOf(prefix, 0) !== 0;
});
el.className = classes.join(" ").trim();
or as a jQuery mixin:
$.fn.removeClassPrefix = function(prefix) {
this.each(function(i, el) {
var classes = el.className.split(" ").filter(function(c) {
return c.lastIndexOf(prefix, 0) !== 0;
});
el.className = $.trim(classes.join(" "));
});
return this;
};
2018 ES6 Update:
const prefix = "prefix";
const classes = el.className.split(" ").filter(c => !c.startsWith(prefix));
el.className = classes.join(" ").trim();
With jQuery, the actual DOM element is at index zero, this should work
$('#a')[0].className = $('#a')[0].className.replace(/\bbg.*?\b/g, '');
I've written a simple jQuery plugin - alterClass, that does wildcard class removal.
Will optionally add classes too.
$( '#foo' ).alterClass( 'foo-* bar-*', 'foobar' )
You don't need any jQuery specific code to handle this. Just use a RegExp to replace them:
$("#a").className = $("#a").className.replace(/\bbg.*?\b/g, '');
You can modify this to support any prefix but the faster method is above as the RegExp will be compiled only once:
function removeClassByPrefix(el, prefix) {
var regx = new RegExp('\\b' + prefix + '.*?\\b', 'g');
el.className = el.className.replace(regx, '');
return el;
}
Using 2nd signature of $.fn.removeClass :
// Considering:
var $el = $('<div class=" foo-1 a b foo-2 c foo"/>');
function makeRemoveClassHandler(regex) {
return function (index, classes) {
return classes.split(/\s+/).filter(function (el) {return regex.test(el);}).join(' ');
}
}
$el.removeClass(makeRemoveClassHandler(/^foo-/));
//> [<div class=​"a b c foo">​</div>​]
For modern browsers:
let element = $('#a')[0];
let cls = 'bg';
element.classList.remove.apply(element.classList, Array.from(element.classList).filter(v=>v.startsWith(cls)));
An approach I would use using simple jQuery constructs and array handling functions, is to declare an function that takes id of the control and prefix of the class and deleted all classed. The code is attached:
function removeclasses(controlIndex,classPrefix){
var classes = $("#"+controlIndex).attr("class").split(" ");
$.each(classes,function(index) {
if(classes[index].indexOf(classPrefix)==0) {
$("#"+controlIndex).removeClass(classes[index]);
}
});
}
Now this function can be called from anywhere, onclick of button or from code:
removeclasses("a","bg");
http://www.mail-archive.com/jquery-en#googlegroups.com/msg03998.html says:
...and .removeClass() would remove all classes...
It works for me ;)
cheers
I was looking for solution for exactly the same problem. To remove all classes starting with prefix "fontid_" After reading this article I wrote a small plugin which I'm using now.
(function ($) {
$.fn.removePrefixedClasses = function (prefix) {
var classNames = $(this).attr('class').split(' '),
className,
newClassNames = [],
i;
//loop class names
for(i = 0; i < classNames.length; i++) {
className = classNames[i];
// if prefix not found at the beggining of class name
if(className.indexOf(prefix) !== 0) {
newClassNames.push(className);
continue;
}
}
// write new list excluding filtered classNames
$(this).attr('class', newClassNames.join(' '));
};
}(fQuery));
Usage:
$('#elementId').removePrefixedClasses('prefix-of-classes_');
In one line ...
Removes all classes that match a regular expression someRegExp
$('#my_element_id').removeClass( function() { return (this.className.match(/someRegExp/g) || []).join(' ').replace(prog.status.toLowerCase(),'');});
I know it's an old question, but I found out new solution and want to know if it has disadvantages?
$('#a')[0].className = $('#a')[0].className
.replace(/(^|\s)bg.*?(\s|$)/g, ' ')
.replace(/\s\s+/g, ' ')
.replace(/(^\s|\s$)/g, '');
Prestaul's answer was helpful, but it didn't quite work for me. The jQuery way to select an object by id didn't work. I had to use
document.getElementById("a").className
instead of
$("#a").className
I also use hyphen'-' and digits for class name. So my version include '\d-'
$('#a')[0].className = $('#a')[0].className.replace(/\bbg.\d-*?\b/g, '');
(function($)
{
return this.each(function()
{
var classes = $(this).attr('class');
if(!classes || !regex) return false;
var classArray = [];
classes = classes.split(' ');
for(var i=0, len=classes.length; i<len; i++) if(!classes[i].match(regex)) classArray.push(classes[i]);
$(this).attr('class', classArray.join(' '));
});
})(jQuery);
The top answer converted to jQuery for those wanting a jQuery only solution:
const prefix = 'prefix'
const classes = el.attr('class').split(' ').filter(c => !c.startsWith(prefix))
el.attr('class', classes.join(' ').trim())
$("#element").removeAttr("class").addClass("yourClass");

Categories