what to know little about the arguments for given code .....? - javascript

$('.selector:contains("'+ filterText +'")').show()
for showing div based on the bases of string "search" now it's working fine with the exact character case of lowercase and upper case
now here i googled my issue many links i found and in almost all sites and event stackoverflow i found similar code like below code..
jQuery.expr[':'].Contains = function(a,i,m){
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())> -1;
};
so here i am interested in this a, i, and m parameters
also that how can i use the $(".selector":contains('"+ search +"')).show() with any case sensitivity ( lowercase or upper case ).
the use this code with what i have written will be better one
and alternative solutions about free text search with key press will be the best on but but but
no use of third party plugins.
i think You guys need to refer bellow link
http://jsfiddle.net/potherca/ympBL/

There are many ways to filter an element that contains the give text. One form is the following.
$(".selector:contains('"+ search +"')").show();
But this is case sensitive. If you'd like a case insensitive match, you may want to write a custom filter method by extending the filter expressions of jQuery, like below.
jQuery.extend(jQuery.expr[':'], {
icontains: function(elem, index, arr){
return jQuery(elem).text().toLowerCase().indexOf(arr[3].toLowerCase()) !== -1
}
});
In the method you create for any jQuery expression, you are given three arguments. The first is the DOM element for that particular iteration. Second is the index of the DOM element relative to the original collection the expression was called on. Last is an array similar to what you'd get from a RegExp exec method call. The full expression is the first array position, second is the text from the selector between the colon and opening paren, and the last is the string that occurs within the parens.
Then use it as:
$(".selector:icontains('" + search + "')").show();

I would suggest you learn to use filter(fn) which offers lots of control over how you filter elements.
$(".selector").filter(function(){
return $(this).toLowerCase().indexOf(search.toLowerCase()) >-1;
}).show();

Related

Identify css selector string vs XPath string

I'm working on a small querying module (in js) for html and I want to provide a generic query(selector) function supporting both, css selectors and XPath selectors as string argument.
Regardless of how each kind of selection is done, my problem here is how to identify whether a given string is an xpath or a css selector. We can assume that the function would be something like this:
function query(selector){
selectorKind = identifySelectorKind(selector); // I want to know how to code this particular function
if(selectorKind==="css") return queryCss(selector);
if(selectorKind==="xPath") return queryXPath(selector); //Assume both functions exists and work
}
My first approach (given my limited knowledge of xPath queries) was to identify the query kind by checking if the first character is / (here I am assuming all relevant xPath queries begin with /)
So, identifySelectorKind would go a bit like this:
function identifySelectorKind(selector){
if (selector[0] === "/") return "xPath";
else return "css";
}
Note that I don't need to validate neither css nor xpath selectors, I only need an unambiguous way to differentiate them. Would this logic be enough? (in other words, all xPath selectors begin with / and no css selector begins the same way?), if not, is there a better way or some considerations I may want to know?
You can't necessarily. For example, * is a valid xpath and a valid css selector, but it matches a different set of elements in each.
If you're absolutely sure your XPath selector will always begin with /, then yes, it's fine. Note that an XPath selector doesn't have to begin with a /, but if yours always selects from the root, then it's fine.

JQuery: What's the difference between referencing an element using #[objectId] or [id=objectId]

Can anybody tell me what's the difference between referencing an element using #[objectId] or [id=objectId]?
The first one is very fast, as jQuery internally uses getElementById when it recognizes the pattern (using a regular expression).
The second one asks jQuery to iterate over all objects having an id. It's very slow. jQuery doesn't even stop iterating when it find one match in that case.
The only legitimate reason to use a [id... selector is when you don't just search by an exact id, for example you might want to search all elements whose id starts with "something" using $('[id^=something]').
Assuming you have a valid HTML (no reused id) and a valid id, you can still have problems with $('#'+someId) (for example when your id contains a quote, or anything that breaks Sizzle's pattern recognition system). In that case, use $(document.getElementById(someId)).
Following your comment : Yes, a "#" in an ID makes it impossible for Sizzle (jQuery's selector engine) to understand your selector. Sizzle uses the following regex :
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
and /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/.test('#som#thing') returns false.

jQuery regex match help (optional condition)

I've got something like that:
[#parameter='value']
and
[#parameter]
and I need regexp to parse both cases,
in first returns parameter & value in the second only parameter
Now, I've got something like that
"[#short-name='shorty']".match(/\[\#(.*)\=\'(.*)\'\]/)
which returns
["[#short-name='shorty']", "short-name", "shorty"]
its great but only in first case, please help
EDIT:
I just figured that probably two matches could be replaced by one so if it's possible, a little extension of current solution will be great.
match something like:
PARENT//CHILD[#parameter='value']
or
PARENT//CHILD[#parameter]
or
PARENT//CHILD
should returns
[ parent, child, parameter, value ]
[ parent, child, parameter ]
[ parent, child ]
Thanks a lot!
EDIT 2:
Allright it's easy
/([A-Z]+)\/\/([A-Z]+)(\[#([^=\]]*)(?:='(.*)'])?)?/
if it's possible to do it easier, please show me how
This will work for your general case:
/\[#([^=\]]*)(?:='(.*)'])?/
I removed a lot of the unnecessary escaping you were doing. The value is in parentheses (not captured because of ?:) and then made optional. The \[#.* has to be changed to \[#[^=\]] so that it will only try to capture up to the equals or the close brace (either of which may be there).
You can also update this to correctly match quotes, or even omit them
/\[#([^=\]]*)(?:=(['"]?)(.*)\2])?/
EDIT: You can also match multiple values per line using a similar expression; just add .*? for the capture of the value.
"[#short-name='shorty'] [#long-name=\"longy\"] [#longest]".replace(
/\[#([^=\]]*)(?:=(['"]?)(.*?)\2])?/g,
function () { console.log(arguments[1], arguments[3]); })
This will yield "short-name, shorty", "long-name longy", "longest undefined"
Let the second part be optional.
Put some spaces to best view.
"[#short-name]".match(/\[\#(.*) (\=\'(.*)\')? \]/)
Wrapping the code with parentheses and adding a ? will do the trick.
http://metahtml.sourceforge.net/documentation/regex/regex_3.mhtml#SEC14

JQuery multiple attributes in selection

I stumbled upon this form of selector. Notice the quotes, its two attributes.
$('#item1','#item2')
It seems to return only first element, which is different from $('#item1, #item2') result. I couldn't find any documentation on what exactly this does. Can somebody explain this or link to documentation with examples please
It's called context, and it's the same as find(), so this:
$('#item1','#item2')
would equal :
$('#item2').find('#item1');
in other words, it searched inside #item2 for an element with the ID #item1
To select both elements with ID's #item1 and #item2, you would do:
$('#item1, #item2')
notice the difference in quotes.
Selector in Jquery $(param) supports single string parameter and then it split parameter string and then do work for selecting element..
$('#item1','#item2') //treat first one param
$('#item1,#item2') //treat one param and splits passed string and will select both
You can specify any number of selectors to combine into a single result.
This multiple expression combinator is an efficient way to select disparate elements.
multiple-selector
multiple-selector-2
var list = $("div,p,span").map(function () {
return this.tagName;
}).get().join(", ");
$("b").append(document.createTextNode(list));

Getting the "match" object in a Custom Filter Selector in jQuery 1.8

For reference, here's an article on Creating a Custom Filter Selector with jQuery.
Introduction:
For those not familiar with jQuery's Custom Filter Selectors, here's a quick primer on what they are:
If you need a reusable filter, you can extend jQuery’s selector expressions by adding your own functions to the jQuery.expr[':'] object.
The function will be run on each element in the current collection and should return true or false (much like filter). Three bits of information are passed to this function:
The element in question
The index of this element among the entire collection
A match array returned from a regular expression match that contains important information for the more complex expressions.
Once you've extended jQuery.expr[':'], you can use it as a filter in your jQuery selector, much like you would use any of the built-in ones (:first, :last, :eq() etc.)
Here's an example where we'll filter for elements that have more than one class assigned to them:
jQuery.expr[':'].hasMultipleClasses = function(elem, index, match) {
return elem.className.split(' ').length > 1;
};
$('div:hasMultipleClasses');
Here's the fiddle: http://jsfiddle.net/acTeJ/
In the example above, we have not used the match array being passed in to our function. Let's try a more complex example. Here we'll create a filter to match elements that have a higher tabindex than the number specified:
jQuery.expr[':'].tabindexAbove = function(elem, index, match) {
return +elem.getAttribute('tabindex') > match[3];
};
$('input:tabindexAbove(4)');
Here's the fiddle: http://jsfiddle.net/YCsCm/
The reason this works is because the match array is the actual array returned from the regex that was used to parse the selector. So in our example, match would be the following array:
[":tabIndexAbove(4)", "tabIndexAbove", "", "4"]
As you can see, we can get to the value inside the parentheses by using match[3].
The Question:
In jQuery 1.8, the match array is no longer being passed in to the filter function. Since we have no access to the info being passed in, the tabindexAbove filter does not work anymore (the only difference between this fiddle and the one above, is that this uses a later version of jQuery).
So, here are several points I'd like clarified:
Is this expected behavior? Is it documented anywhere?
Does this have anything to do with the fact that Sizzle has been updated (even though it clearly states that "the old API for Sizzle was not changed in this rewrite". Maybe this is what they mean by "the removal of the now unnecessary Sizzle.filter")?
Now that we have no access to the match array, is there any other way to get to the info being passed in to the filter (in our case, 4)?
I never found any documentation in the jQuery Docs about the custom filter selectors, so I don't know where to start looking for information about this.
jQuery has added a utility for creating custom pseudos in Sizzle. It's a little more verbose, but it's much more readable than using match[3]. It also has the advantage of being more performant as you can avoid repeating tedious calculations every time an element is tested. The answer that has already been accepted is a good answer, but let me add a note to say that you can use $.expr.createPseudo instead of setting the sizzleFilter property yourself, which will save a little space.
jQuery.expr[':'].tabIndexAbove = $.expr.createPseudo(function( tabindex ) {
return function(elem) {
return +elem.getAttribute('tabindex') > tabindex;
}
});
$('input:tabIndexAbove(4)').css('background', 'teal');
jsfiddle: http://jsfiddle.net/timmywil/YCsCm/7/
This is all documented on Sizzle's github:
https://github.com/jquery/sizzle/wiki/Sizzle-Documentation
By looking at the jQuery 1.8 beta2 source and the "Extensibility" section of The New Sizzle, you have to set fn.sizzleFilter to true in order to get the pseudo argument and the context. If not, you'll just get all the elements in the arguments.
Here is the code that does the same thing as your example. Use the selector parameter passed in the function to get the pseudo argument.
Here is the working example on jsfiddle.
As mentioned in the blog post above, you can even pre-compile and cache the your selector.
var sizzle = jQuery.find;
var tabIndexAbove = function( selector, context, isXml ) {
return function( elem ) {
return elem.getAttribute("tabindex") > selector;
};
};
/*
fn.sizzleFilter is set to true to indicate that tabIndexAbove
is a function that will return a function for use by the compiler
and should be passed the pseudo argument, the context, and
whether or not the current context is xml. If this property is
not set, adding pseudos works similar to past versions of Sizzle
*/
tabIndexAbove.sizzleFilter = true;
sizzle.selectors.pseudos.tabIndexAbove = tabIndexAbove;
$('input:tabIndexAbove(4)').css('background', 'teal');
Just a note, if you're looking at the source, jQuery slightly changed the structure that the public-facing interface points to.
In jQuery 1.7.2:
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;
In jQuery 1.8b2:
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;

Categories

Resources