use variable for object name in Jquery - javascript

I found another similar question about this with a solution but it didn't work for me. I am new to jquery so thanks in advance for helping me solve my noobie question.
I am trying to use a variable for the class name. So that I can loop through the right fields based on this variable. My variable returns .reqfields4 but I get this error Error: Syntax error, unrecognized expression: ", if I enter the value manually, it works.
How can I achieve this? Thanks.
var reqsection='\".reqfields4\"';
$(".reqfields4").each ( function() {
//$(reqsection).each ( function() {
if(( $(this).val())==''){
some code...
}
else{
some code...
}
});

Just change var reqsection='\".reqfields4\"'; to var reqsection='.reqfields4'; - you don't need the inner string quotes.

You don't need quotes inside the value of the variable:
var reqsection = '.reqfields4';
$(reqsection).each( ... );
If you have a class name — just a class name — you can add the .:
var reqsection = 'reqfields4';
$('.' + reqsection).each( ... )

You can try like follows,
var reqsection=".reqfields4";
$(reqsection).each ( function() {
if(( $(this).val())==''){
some code...
}
else{
some code...
}
});

If you say var reqsection= '\".reqfields4\"';
then
$(reqsection).each( function() {});
Consider it like like you told jQuery this:
$(' ".reqfields4" ').each( function() {});
In other words you said: [ Please select now ".reqfields4" including the quotemarks ]. All class selectors must start with dot(.), but you just started your jQuery selector with a quotemark (") so of course it won't work at all (it won't try to select any classes, of course), and probably would throw an error from jQuery - I don't think ANY jQuery selector string can have quotemark(") as the actual first character of the selector!.
If you do this instead:
var reqsection= ".reqfields4";
$(".reqfields4").each( function() {});
$(reqsection).each( function() {});
The above two lines are equivalent.

Related

Capture class that was matched in jQuery callback function

I'm trying to access the class that was matched by a jQuery selector in a callback function. For example, if I have the following HTML,
<p class="someclass sorted-1 anotherclass">test</p>
I'd like to match this element and get the sorted-1 class name. The value 1 is arbitrary. Something like the following. getMatchedClass() is pseudo code. I thought I could get the value from $(this), but I'm not seeing it.
$('[class*=sorted-]').on('click', function() {
var className = getMatchedClass();
console.log(className); // should output 'sorted-1'
});
Does anyone know if this is possible? I'm having a hard time coming up with search terms. I keep getting results on selected values which isn't what I want.
Thanks
Update
Based on #maheer-ali's answer I came up with the following solution.
$(function() {
function column(className) {
const regex = /sorted-([0-9]+)/;
return className.match(regex)[0].replace(regex, '$1');
}
$('[class*=sorted-]').each(function(i, r) {
// col is the dashed number after sorted
// if parsing `sorted-42`, `col` would equal 42
const col = column($(r).context.className);
// Use the `col` value here.
$(r).doSomething({ column: col });
});
});
You can use a match() and regular expression. And get the first element of result array.
$('[class*=sorted-]').on('click', function() {
var className = this.className.match(/sorted-[0-9]+/)[0];
console.log(className); // should output 'sorted-1'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="someclass sorted-1 anotherclass">test</p>
The other way is to use split() and startsWith(). split() the className by " " and use find() to get element element with startsWith the string "sorted-"
$('[class*=sorted-]').on('click', function() {
var className = this.className.split(' ').find(x => x.startsWith('sorted-'))
console.log(className); // should output 'sorted-1'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="someclass sorted-1 anotherclass">test</p>
The callback function that you're passing is called with the event that triggered it.
You can access event.target.classList to get an array of all of the classes on that object. If you have a fixed set of class patterns you're looking for, you could search that list for the class.
Hope this helped!

Modifying a string of html in javascript [duplicate]

I'm trying to get the HTML of a selected object with jQuery. I am aware of the .html() function; the issue is that I need the HTML including the selected object (a table row in this case, where .html() only returns the cells inside the row).
I've searched around and found a few very ‘hackish’ type methods of cloning an object, adding it to a newly created div, etc, etc, but this seems really dirty. Is there any better way, or does the new version of jQuery (1.4.2) offer any kind of outerHtml functionality?
I believe that currently (5/1/2012), all major browsers support the outerHTML function. It seems to me that this snippet is sufficient. I personally would choose to memorize this:
// Gives you the DOM element without the outside wrapper you want
$('.classSelector').html()
// Gives you the outside wrapper as well only for the first element
$('.classSelector')[0].outerHTML
// Gives you the outer HTML for all the selected elements
var html = '';
$('.classSelector').each(function () {
html += this.outerHTML;
});
//Or if you need a one liner for the previous code
$('.classSelector').get().map(function(v){return v.outerHTML}).join('');
EDIT: Basic support stats for element.outerHTML
Firefox (Gecko): 11 ....Released 2012-03-13
Chrome: 0.2 ...............Released 2008-09-02
Internet Explorer 4.0...Released 1997
Opera 7 ......................Released 2003-01-28
Safari 1.3 ...................Released 2006-01-12
No need to generate a function for it. Just do it like this:
$('a').each(function(){
var s = $(this).clone().wrap('<p>').parent().html();
console.log(s);
});
(Your browser's console will show what is logged, by the way. Most of the latest browsers since around 2009 have this feature.)
The magic is this on the end:
.clone().wrap('<p>').parent().html();
The clone means you're not actually disturbing the DOM. Run it without it and you'll see p tags inserted before/after all hyperlinks (in this example), which is undesirable. So, yes, use .clone().
The way it works is that it takes each a tag, makes a clone of it in RAM, wraps with p tags, gets the parent of it (meaning the p tag), and then gets the innerHTML property of it.
EDIT: Took advice and changed div tags to p tags because it's less typing and works the same.
2014 Edit : The question and this reply are from 2010. At the time, no better solution was widely available. Now, many of the other replies are better : Eric Hu's, or Re Capcha's for example.
This site seems to have a solution for you :
jQuery: outerHTML | Yelotofu
jQuery.fn.outerHTML = function(s) {
return s
? this.before(s).remove()
: jQuery("<p>").append(this.eq(0).clone()).html();
};
What about: prop('outerHTML')?
var outerHTML_text = $('#item-to-be-selected').prop('outerHTML');
And to set:
$('#item-to-be-selected').prop('outerHTML', outerHTML_text);
It worked for me.
PS: This is added in jQuery 1.6.
Extend jQuery:
(function($) {
$.fn.outerHTML = function() {
return $(this).clone().wrap('<div></div>').parent().html();
};
})(jQuery);
And use it like this: $("#myTableRow").outerHTML();
I agree with Arpan (Dec 13 '10 5:59).
His way of doing it is actually a MUCH better way of doing it, as you dont use clone. The clone method is very time consuming, if you have child elements, and nobody else seemed to care that IE actually HAVE the outerHTML attribute (yes IE actually have SOME useful tricks up its sleeve).
But I would probably create his script a bit different:
$.fn.outerHTML = function() {
var $t = $(this);
if ($t[0].outerHTML !== undefined) {
return $t[0].outerHTML;
} else {
var content = $t.wrap('<div/>').parent().html();
$t.unwrap();
return content;
}
};
To be truly jQuery-esque, you might want outerHTML() to be a getter and a setter and have its behaviour as similar to html() as possible:
$.fn.outerHTML = function (arg) {
var ret;
// If no items in the collection, return
if (!this.length)
return typeof arg == "undefined" ? this : null;
// Getter overload (no argument passed)
if (!arg) {
return this[0].outerHTML ||
(ret = this.wrap('<div>').parent().html(), this.unwrap(), ret);
}
// Setter overload
$.each(this, function (i, el) {
var fnRet,
pass = el,
inOrOut = el.outerHTML ? "outerHTML" : "innerHTML";
if (!el.outerHTML)
el = $(el).wrap('<div>').parent()[0];
if (jQuery.isFunction(arg)) {
if ((fnRet = arg.call(pass, i, el[inOrOut])) !== false)
el[inOrOut] = fnRet;
}
else
el[inOrOut] = arg;
if (!el.outerHTML)
$(el).children().unwrap();
});
return this;
}
Working demo: http://jsfiddle.net/AndyE/WLKAa/
This allows us to pass an argument to outerHTML, which can be
a cancellable function — function (index, oldOuterHTML) { } — where the return value will become the new HTML for the element (unless false is returned).
a string, which will be set in place of the HTML of each element.
For more information, see the jQuery docs for html().
You can also use get (Retrieve the DOM elements matched by the jQuery object.).
e.g:
$('div').get(0).outerHTML;//return "<div></div>"
As extension method :
jQuery.fn.outerHTML = function () {
return this.get().map(function (v) {
return v.outerHTML
}).join()
};
Or
jQuery.fn.outerHTML = function () {
return $.map(this.get(), function (v) {
return v.outerHTML
}).join()
};
Multiple choice and return the outer html of all matched elements.
$('input').outerHTML()
return:
'<input id="input1" type="text"><input id="input2" type="text">'
To make a FULL jQuery plugin as .outerHTML, add the following script to any js file and include after jQuery in your header:
update New version has better control as well as a more jQuery Selector friendly service! :)
;(function($) {
$.extend({
outerHTML: function() {
var $ele = arguments[0],
args = Array.prototype.slice.call(arguments, 1)
if ($ele && !($ele instanceof jQuery) && (typeof $ele == 'string' || $ele instanceof HTMLCollection || $ele instanceof Array)) $ele = $($ele);
if ($ele.length) {
if ($ele.length == 1) return $ele[0].outerHTML;
else return $.map($("div"), function(ele,i) { return ele.outerHTML; });
}
throw new Error("Invalid Selector");
}
})
$.fn.extend({
outerHTML: function() {
var args = [this];
if (arguments.length) for (x in arguments) args.push(arguments[x]);
return $.outerHTML.apply($, args);
}
});
})(jQuery);
This will allow you to not only get the outerHTML of one element, but even get an Array return of multiple elements at once! and can be used in both jQuery standard styles as such:
$.outerHTML($("#eleID")); // will return outerHTML of that element and is
// same as
$("#eleID").outerHTML();
// or
$.outerHTML("#eleID");
// or
$.outerHTML(document.getElementById("eleID"));
For multiple elements
$("#firstEle, .someElesByClassname, tag").outerHTML();
Snippet Examples:
console.log('$.outerHTML($("#eleID"))'+"\t", $.outerHTML($("#eleID")));
console.log('$("#eleID").outerHTML()'+"\t\t", $("#eleID").outerHTML());
console.log('$("#firstEle, .someElesByClassname, tag").outerHTML()'+"\t", $("#firstEle, .someElesByClassname, tag").outerHTML());
var checkThisOut = $("div").outerHTML();
console.log('var checkThisOut = $("div").outerHTML();'+"\t\t", checkThisOut);
$.each(checkThisOut, function(i, str){ $("div").eq(i).text("My outerHTML Was: " + str); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://rawgit.com/JDMcKinstry/ce699e82c7e07d02bae82e642fb4275f/raw/deabd0663adf0d12f389ddc03786468af4033ad2/jQuery.outerHTML.js"></script>
<div id="eleID">This will</div>
<div id="firstEle">be Replaced</div>
<div class="someElesByClassname">At RunTime</div>
<h3><tag>Open Console to see results</tag></h3>
you can also just do it this way
document.getElementById(id).outerHTML
where id is the id of the element that you are looking for
I used Jessica's solution (which was edited by Josh) to get outerHTML to work on Firefox. The problem however is that my code was breaking because her solution wrapped the element into a DIV. Adding one more line of code solved that problem.
The following code gives you the outerHTML leaving the DOM tree unchanged.
$jq.fn.outerHTML = function() {
if ($jq(this).attr('outerHTML'))
return $jq(this).attr('outerHTML');
else
{
var content = $jq(this).wrap('<div></div>').parent().html();
$jq(this).unwrap();
return content;
}
}
And use it like this: $("#myDiv").outerHTML();
Hope someone finds it useful!
// no cloning necessary
var x = $('#xxx').wrapAll('<div></div>').parent().html();
alert(x);
Fiddle here: http://jsfiddle.net/ezmilhouse/Mv76a/
If the scenario is appending a new row dynamically, you can use this:
var row = $(".myRow").last().clone();
$(".myRow").last().after(row);
.myrow is the classname of the <tr>. It makes a copy of the last row and inserts that as a new last row.
This also works in IE7, while the [0].outerHTML method does not allow assignments in ie7
node.cloneNode() hardly seems like a hack. You can clone the node and append it to any desired parent element, and also manipulate it by manipulating individual properties, rather than having to e.g. run regular expressions on it, or add it in to the DOM, then manipulate it afterwords.
That said, you could also iterate over the attributes of the element to construct an HTML string representation of it. It seems likely this is how any outerHTML function would be implemented were jQuery to add one.
I've used Volomike's solution updated by Jessica. Just added a check to see if the element exists, and made it return blank in case it doesn't.
jQuery.fn.outerHTML = function() {
return $(this).length > 0 ? $(this).clone().wrap('<div />').parent().html() : '';
};
Of course, use it like:
$('table#buttons').outerHTML();
You can find a good .outerHTML() option here https://github.com/darlesson/jquery-outerhtml.
Unlike .html() that returns only the element's HTML content, this version of .outerHTML() returns the selected element and its HTML content or replaces it as .replaceWith() method but with the difference that allows the replacing HTML to be inherit by the chaining.
Examples can also be seeing in the URL above.
This is quite simple with vanilla JavaScript...
document.querySelector('#selector')
Note that Josh's solution only works for a single element.
Arguably, "outer" HTML only really makes sense when you have a single element, but there are situations where it makes sense to take a list of HTML elements and turn them into markup.
Extending Josh's solution, this one will handle multiple elements:
(function($) {
$.fn.outerHTML = function() {
var $this = $(this);
if ($this.length>1)
return $.map($this, function(el){ return $(el).outerHTML(); }).join('');
return $this.clone().wrap('<div/>').parent().html();
}
})(jQuery);
Edit: another problem with Josh's solution fixed, see comment above.
Anothe similar solution with added remove() of the temporary DOM object.
I have made this simple test with outerHTML being tokimon solution (without clone), and outerHTML2 being jessica solution (clone)
console.time("outerHTML");
for(i=0;i<1000;i++)
{
var html = $("<span style='padding:50px; margin:50px; display:block'><input type='text' title='test' /></span>").outerHTML();
}
console.timeEnd("outerHTML");
console.time("outerHTML2");
for(i=0;i<1000;i++)
{
var html = $("<span style='padding:50px; margin:50px; display:block'><input type='text' title='test' /></span>").outerHTML2();
}
console.timeEnd("outerHTML2");
and the result in my chromium (Version 20.0.1132.57 (0)) browser was
outerHTML: 81ms
outerHTML2: 439ms
but if we use tokimon solution without the native outerHTML function (which is now supported in probably almost every browser)
we get
outerHTML: 594ms
outerHTML2: 332ms
and there are gonna be more loops and elements in real world examples, so the perfect combination would be
$.fn.outerHTML = function()
{
$t = $(this);
if( "outerHTML" in $t[0] ) return $t[0].outerHTML;
else return $t.clone().wrap('<p>').parent().html();
}
so clone method is actually faster than wrap/unwrap method
(jquery 1.7.2)
Here is a very optimized outerHTML plugin for jquery:
(http://jsperf.com/outerhtml-vs-jquery-clone-hack/5 => the 2 others fast code snippets are not compatible with some browsers like FF < 11)
(function($) {
var DIV = document.createElement("div"),
outerHTML;
if ('outerHTML' in DIV) {
outerHTML = function(node) {
return node.outerHTML;
};
} else {
outerHTML = function(node) {
var div = DIV.cloneNode();
div.appendChild(node.cloneNode(true));
return div.innerHTML;
};
}
$.fn.outerHTML = function() {
return this.length ? outerHTML(this[0]) : void(0);
};
})(jQuery);
#Andy E => I don't agree with you. outerHMTL doesn't need a getter AND a setter: jQuery already give us 'replaceWith'...
#mindplay => Why are you joining all outerHTML? jquery.html return only the HTML content of the FIRST element.
(Sorry, don't have enough reputation to write comments)
Short and sweet.
[].reduce($('.x'), function(i,v) {return i+v.outerHTML}, '')
or event more sweet with help of arrow functions
[].reduce.call($('.x'), (i,v) => i+v.outerHTML, '')
or without jQuery at all
[].reduce.call(document.querySelectorAll('.x'), (i,v) => i+v.outerHTML, '')
or if you don't like this approach, check that
$('.x').get().reduce((i,v) => i+v.outerHTML, '')
This is great for changing elements on the dom but does NOT work for ie when passing in a html string into jquery like this:
$('<div id="foo">Some <span id="blog">content</span></div>').find('#blog').outerHTML();
After some manipulation I have created a function which allows the above to work in ie for html strings:
$.fn.htmlStringOuterHTML = function() {
this.parent().find(this).wrap('<div/>');
return this.parent().html();
};
$.html = el => $("<div>"+el+"</div>").html().trim();
I came across this while looking for an answer to my issue which was that I was trying to remove a table row then add it back in at the bottom of the table (because I was dynamically creating data rows but wanted to show an 'Add New Record' type row at the bottom).
I had the same issue, in that it was returning the innerHtml so was missing the TR tags, which held the ID of that row and meant it was impossible to repeat the procedure.
The answer I found was that the jquery remove() function actually returns the element, that it removes, as an object. So, to remove and re-add a row it was as simple as this...
var a = $("#trRowToRemove").remove();
$('#tblMyTable').append(a);
If you're not removing the object but want to copy it somewhere else, use the clone() function instead.
jQuery plugin as a shorthand to directly get the whole element HTML:
jQuery.fn.outerHTML = function () {
return jQuery('<div />').append(this.eq(0).clone()).html();
};
And use it like this: $(".element").outerHTML();
Pure JavaScript:
var outerHTML = function(node) {
var div = document.createElement("div");
div.appendChild(node.cloneNode(true));
return div.innerHTML;
};
$("#myNode").parent(x).html();
Where 'x' is the node number, beginning with 0 as the first one, should get the right node you want, if you're trying to get a specific one. If you have child nodes, you should really be putting an ID on the one you want, though, to just zero in on that one. Using that methodology and no 'x' worked fine for me.
Simple solution.
var myself = $('#div').children().parent();
$("#myTable").parent().html();
Perhaps I'm not understanding your question properly, but this will get the selected element's parent element's html.
Is that what you're after?

Get id that starts with some string, inside a jQuery loop

The context:
I need to get some dynamic ids that are inside a TD element, to pass it as a parameter and call an specific function.
I added a class (.calcStartPrice) to the TD, so that it helps me iterating inside its elements:
var inputEl, eventStartPrice, exchangeRate, convertedStartPriceEl, currSymbol, decimalPlaces;
jQuery(".calcStartPrice").each(function (i,e) {
jQuery(e).find('span, input').each(function (a,b) {
console.info(b.id);
});
});
When I run this code, I have the following ids:
eventStartPrice_S20_L10140
S20_L10140_startPrice
exchangeRate_S20_L10140
curSymbol_S20_L10140
decPlaces_S20_L10140
converted_StartPrice_S20_L10140
Now, what I want to do is to check whether the id starts with eventStartPrice, for example, so that I'll attribute the id to a variable.
What I tried:
var eventStartPrice;
jQuery(".calcStartPrice").each(function (i,e) {
jQuery(e).find('span, input').each(function (a,b) {
//console.info(b.id);
if (jQuery(b[id^="eventStartPrice"])) { //this is wrong!!!
eventStartPrice = b.id;
console.info(eventStartPrice);
}
});
});
But it didn't work...
How can I check inside that second iteration if the id starts with some string?
Replace :
if (jQuery(b[id^="eventStartPrice"])) { //this is wrong!!!
With :
if (/^eventStartPrice/.test(b.id)) {
You can use regexp :
if (b.id.match(/^eventStartPrice/)))
Try this:
$(b).is("[id^='eventStartPrice']")
basically, b is not a normal object, you need to wrap it into a jQuery object so that you can perform operations on it. Or, more accurately, you're trying to access b as a jQuery object when it isn't.
Use the jquery split method
id_val = b.id
name = id_val.split('_');
Now name[0] will contain characters before '_'.
You can easily compare it using if statement
if(name[0] == "eventStartPrice")
{
......
}
When u use jQuery each u get the dom element as this. If u then create a jQuery object of that u can apply all the magic to it. Thats what ur missing in ur code. So here is my sugestion how to rewrite ur function.
var eventStartPrice;
jQuery(".calcStartPrice").each(function (i,e) {
jQuery(e).find('span, input').each(function (a,b) {
var $this = jQuery(this);
if ($this.is("[id^=eventStartPrice]")) {
eventStartPrice = $this.attr("id");
console.info(eventStartPrice);
}
});
});
U can test it out in this fiddle

How to find a jQuery selector (using :contains) result set's complement

What is the best way to get the complement of a jQuery selector's result set? I want to do something like the following:
jQuery(this).find("div:contains('someValue')").show();
But I want the complement of this selection hidden:
jQuery(this).find("div:not(:contains('someValue'))").hide();
Is there a more elegant solution to this than just executing the complementary selector? An alternative I can see is finding all divs first, storing the result, and filter this:
var results = jQuery(this).find("div");
results.find(":contains('someValue')").show();
results.find(":not(:contains('someValue'))").hide();
But that doesn't seem that much better. Any ideas?
var results = jQuery(this).find("div"),
selector = ":contains('someValue')";
results.filter(selector).show();
results.not(selector).hide();
as #Simon mentioned in the comments there is a way to improve this particular solution:
var results = jQuery("div", this),
selector = ":contains('someValue')";
results.filter(selector).show();
results.not(selector).hide();
Try like this,
jQuery(this).find("div").hide();
jQuery(this).find("div:contains('someValue')").show();
Well, I think your code is fairly good, but another option could be running this single statement:
jQuery(this).find("div").each(
function() {
var me = $(this);
var f = me.is(":contains('someValue')") ? "show" : "hide";
me[f]();
}
);
/** $.grepl
* uses a regular expression for text matching within an internal $.grep.
*/
$.extend({
"grepl": function(el, exp){
exp=new RegExp(exp,'gi'); // create RegExp
return $(
this.grep( el, function(n,i){ // run internal grep
return el[i].textContent.match(exp) != null; // match RegExp against textContent
})
);
}
});
$.grepl( $('div'), '^.*someRegexp.*$' ).css('display','none'); // usage of the function
I know that this does not exactly use the ":contains" expression, but the result should be the same.

reading attr class, but I need only one of them

I have a div that has many classes. I select them all with
$('#mydiv').attr('class'); //outputs 'redball blueball greenbrick whitesquare'
What I actually need is the class that starts with 'red' so I really want to output only 'redball'. Is there an easy way to do this?
Like has already been said, split on spaces and find your matching class. Here's an example function:
<script language="javascript">
$(document).ready(function() {
var list = $('#mydiv').attr('class').split(/\s+/);
for (i = 0; i < list.length; i++) {
if (/red.*/.test(list[i])) {
alert(list[i]);
}
}
});
</script>
try to extract it with a regular expression:
split the output into an array an while itreating the array values try to test with some regulr expression (like this: /red[a-zA-Z09]*/)
hope it helps you
You can try the .hasClass() method to help you decide.
if( $( '#myDiv' ).attr( 'class' ).hasClass( 'redball' ) ) {
// call method to serve the redball...
}
Alternatively, using .split() and regex as suggested by the others can also work -- depends on how you want to use your output.
BONUS:
But for efficiency sake, it's better to cache the DOM object in a local variable and access that if you need to do more with the element. This is so that Javascript doesn't have to go back to the DOM tree and fetch the same object every time you want to use it.
var myDiv = $( '#myDiv' ); // store the <div> object in the variable
var classNames = myDiv.attr( 'class' );
switch( classNames ) {
case 'redball':
serveBall( 'red' );
break;
case 'blueball':
serveBall( 'blue' );
break;
.....
}

Categories

Resources