I know there are a lot of questions about this, but I didnt found exactly what I needed
This is the js I have
$j('.showCategory li a').each(function() {
var catId = $j(this).attr("data-id");
this.href += (/\?/.test(this.href) ? '&' : '?') + 'filter_category='+ catId;
});
This works great as it generate my url with the param I want. The problem is that if I click multiple times (this filter is available on all pages), it's adding the same parameter over and over, generating an url like this:
http://www.blabla.com/search?search=cat&filter_duration=short&filter_duration=medium&filter_duration=long
I tried fixing that by adding a condition like
$j('.showCategory li a').each(function() {
if(this.href.indexOf('filter_category') == -1) {
var catId = $j(this).attr("data-id");
this.href += (/\?/.test(this.href) ? '&' : '?') + 'filter_category='+ catId;
} else {
????
}
});
But in that case, it's not adding any parameter, but it's not replacing the value. How can I solve this please?
Use this pattern to do an in-place replacement with a regular expression:
} else {
this.href = this.href.replace(/filter_duration=(.+?)(&|$.*)()/, "filter_duration=" + catId + "$2"
}
This uses capture groups to find an existing filter_duration element query parameter, and replaces the existing value in place with a new value (in this case catId). This should work regardless of whether it is the last query parameter in the string or not.
That said, I wouldn't regard this solution as optimal, and you would probably be better off with storing the values that you want in your url in a client side javascript object, and then rebuild the url each time from scratch whenever anyone changes a category. That way you won't have to worry about difficult to test cases where something goes wrong with a replacement and the client getting into a bad state.
Related
I am trying to write a small jQuery / javascript function that searches through all the links on a page, identifies the type of file to which the tag links, and then adds an appropriate class. The purpose of this task is to style the links depending on the type of file at the other end of the link.
So far I have this:
$(document).ready(function(){
$('#rt-mainbody a').each(function(){
linkURL = $(this).attr('href');
var match = linkURL.match("^.*\.(pdf|PDF)$");
if(match != null){$(this).addClass('pdf');}
});
});
Fiddle me this.
And then I would continue the concept to identify, for example, spreadsheet files, Word documents, text files, jpgs, etc.
it works... but the thing is, to me this is super clunky because I have completely botched it together from odds and sods I've found around SO and the internet - I'm sure there must be a neater, more efficient, more readable way of doing this but I have no idea what it might be. Can someone give it a spit and polish for me, please?
Ideally the function should detect (a) that the extension is at the end of the href string, and (b) that the extension is preceded by a dot.
Thanks! :)
EDIT
Wow! Such a response! :) Thanks guys!
When I saw the method using simply the selector it was a bit of a facepalm moment - however the end user I am building this app for is linking to PDFs (and potentially other MIMEs) on a multitude of resource websites and has no control over the case usage of the filenames to which they'll be linking... using the selector is clearly not the way to go because the result would be so inconsistent.
EDIT
And the grand prize goes to #Dave Stein!! :D
The solution I will adopt is a "set it and leave it" script (fiddle me that) which will accommodate any extension, regardless of case, and all I need to do is tweak the CSS for each reasonable eventuality.
It's actually nice to learn that I was already fairly close to the best solution already... more through good luck than good judgement though XD
Well you don't want to use regex to search strings so I like that you narrowed it to just links. I saved off $(this) so you don't have to double call it. I also changed the regex so it's case insensitive. And lastly I made sure that the class is adding what the match was. This accomplish what you want?
$(document).ready(function(){
$('#rt-mainbody a').each(function(){
var $link = $(this),
linkURL = $link.attr('href'),
// I can't remember offhand but I think some extensions have numbers too
match = linkURL.match( /^.*\.([a-z0-9]+)$/i );
if( match != null ){
$link.addClass( match[1].toLowerCase() );
}
});
});
Oh and I almost forgot, I made sure linkURL was no longer global. :)
"Attribute ends with" selector:
$('#rt-mainbody a[href$=".pdf"], #rt-mainbody a[href$=".PDF"]').addClass('pdf')
EDIT: Or more generally and flexibly:
var types = {
doc: ['doc', 'docx'],
pdf: ['pdf'],
// ...
};
function addLinkClasses(ancestor, types) {
var $ancestor = $(ancestor);
$.each(types, function(type, extensions) {
selector = $.map(extensions, function(extension) {
return 'a[href$=".' + extension + '"]';
}).join(', ');
$ancestor.find(selector).addClass(type);
});
}
addLinkClasses('#rt-mainbody', types);
This is case sensitive, so I suggest you canonicalise all extensions to lowercase on your server.
Regex should be /^.*\.(pdf)$/i .
You can use this in your selector (to find all links to pdf files)
a[href$=".pdf"]
use this regex (without quotes):
/\.(pdf|doc)$/i
this regex matches (case insensitive) anything that ends with .pdf, .doc etc.
for dynamic class:
var match = linkURL.match(/\.(pdf|doc)$/i);
match = match ? match[1].toLowerCase() : null;
if (match != null) {
$(this).addClass(match);
}
Another answer, building off of #Amadan is:
var extensions = [
'pdf',
'jpg',
'doc'
];
$.each( extensions, function( i, v) {
$('#rt-mainbody').find( 'a[href$=".' + v + '"], a[href$=".' + v.toUpperCase() + '"]')
.addClass( extension );
});
The onyl suggestion I would make is that you can change your match to inspect what is the file extension instead of having to do a different regex search for each possible file extension:
var linkURL = $(this).attr('href'); //<--you were accidentally declared linkURL as a global BTW.
var match = linkURL.match(/\.(.*)$/);
if(match != null){
//we can extract the part between the parens in our regex
var ext = match[1].toLowerCase()
switch(ext){
case 'pdf': $(this).addClass('pdf'); break;
case 'jpg': $(this).addClass('jpg'); break;
//...
}
}
This switch statement mostly useful if you want the option of using class names that are different from your file extensions. If the file extension is always the same you can consider changing the regex to something that fits the file extensions you want
/\.(pdf|jpg|txt)$/i //i for "case insensitive"
and then just do
var ext = match[1].toLowerCase()
$(this).addClass(ext);
var search_name = location.search;
if (search_name.search("cate_no=24") > 0) {
$(".cate_new a").addClass("active");
}
});
If current document url is http://abc.com/list.html?cate_no=24,
I want to add class "active" into li a.
I searched and found these js code, but it doesn't work.
Is it wrong?
It's incorrect. search() returns the offset position of a match if a match is found, and -1 if a match isn't found.
As you are checking for whether cate_no=24 contains cate_no=24, it will return 0 if true.
Currently, your conditional checks whether the search() will return > 0, which is not what you want.
What you should be doing is check whether it is greater > -1:
if (search_name.search("cate_no=24") > -1)
Although, as I mentioned in the first revision of my answer, it would be better and faster to use indexOf() (search() is supposed to be used when dealing with regular expressions, not for simple string searches).
if (search_name.indexOf("cate_no=24") > -1)
search will only gives you the String. that will be in your case ?cate_no=24
So we leave the first part as it is and try to find the desired value in search_name as string.
var search_name = location.search;
This how we can find the index of the desired pattern.
if (search_name.indexOf("cate_no=24") > 0) {
$(".cate_new a").addClass("active");
}
My personal blog is static so I also had to figure out how to do this without PHP or some other server side code.
This bit of code grabs the path of the current URL, e.g. if you are on http://example.com/about, it would return the string '/about/'. From there you write a simple conditional to add a class to the link you select.
var currentURL = window.location.pathname.toString();
console.log(currentURL);
if (currentURL = '/about/') {
$('a#about').addClass('active')
} else if (currentURL = '/work/') {
...
}
This could be further developed to grab the href attributes from an array of links with a certain class (.nav-items, for example) and add the active class to whichever element has a href equal to the returned string.
I've got a bit of a funny problem that i'm sure others here will find easy to solve. I need to hash an entire query string, then include that hash value in the post data.
After trying it a few other ways, i'm trying to do this with javascript. Somehow it seems like the order in which the string is pulled together from the form to be hashed differs from the way that it is pulled together when it is submitted.
I'm excluding a hidden element with a specific class to build up the query string to be hashed, then setting that hidden element with the hash value before the final submit.
Any idea what i might be doing wrong, or how i could ensure the order of elements is the same both on building the string and the submit?
The relevant snippet:
var allFormDat = document.getElementById("frmPayment").elements;
var hashingString ='';
var hashVal;
for (i=0;i<allFormDat.length;i++) {
if (allFormDat[i].className!="nohash"){
hashingString+=allFormDat[i].name+'='+allFormDat[i].value+'&';
}
}
hashingString.substring(0, hashingString.length - 1);
hashingString += '[salt]';
hashVal=SHA1(hashingString);
frm.hashValue.value=hashVal;
document.getElementById('frmPayment').submit();
First of all, you're not URI-encoding the components. You probably should:
var field = allFormDat[i];
hashingString += encodeURIComponent(field.name) + '='
+ encodeURIComponent(field.value) + '&';
substring does not work in-place. You'll have to reassign:
hashingString = hashingString.substring(0, hashingString.length - 1);
Firstly I've looked at a lot of posts on Stackoverflow but I don't see one which seems to be the definitive way. Someone always seems to find a flaw in the regex.
I already have retrieved my tweets and obviously they can contain any number of hashtags in each one.
If I have an array of possible hashtags that I want to find - ["#ENGLAND","#IRELAND","#wales"] etc.
What is a RELIABLE way to check if a tweet contains these hashtags. I don't want to call the API again, I only want to check my existing tweets, as I'm clicking on buttons to change the filtering on the fly, want to avoid rate limit if they keep clicking around for ages.
EDIT:
Example: Here is a tweet that contains #ENGLAND and #someothertag
I want to search all the tweets and just show the tweets that CONTAIN one or more of my array of tags, I already cache the tweets, I don't want to make a call containing any tags just filter the existing results!
Why only hashify particular hashtags (which you need to specify and then maintain) when you can hashify any hashtag?
I usually use something like this:
var hashregex = /#([a-z0-9_\-]+)/gi,
text = text.replace(hashregex, function (value) {
return '<a target="_blank" href="http://twitter.com/#!/search?q=' + value.replace('#', '%23') + '">' + value + '</a>';
});
Then you can just use text when you set the content to the processed tweets
You could store the hashtags from the entities on the element, for instance
<div class='tweet' data-hashtags='england ireland'>some_tweet</div>
And filter like this when someone clicks your button:
$('div.tweet').hide();
$('div.tweet[data-hashtags~="ireland"]').show();
It's obviously greatly simplified, but the general approach should help you avoid having to parse out the tags yourself
// match a #, followed by either "question" or "idea"
var myregexp = /#(england|ireland|wales)\b/i;
var match = myregexp.exec(subject);
if (match != null) {
result = match[1]; // will contain "england","ireland", or "wales"
} else {
result = "";
}
If you don't know the names of the hashtags on hand
replace
var myregexp = /#(england|ireland|wales)\b/i;
with
var myregexp = /#(\w+)/; // Use this instead
I am in need of two regular expressions.
First of all I want to check if my URL contains the hashtag #videos. Then if it does, I want to get the value of the second #tag. That value could contain all kinds of characters;
http://local/default.php#videos#12345
http://local/default.php#videos#g5458f
http://local/default.php#videos#0-e4a5d
This is what I've got so far:
if (window.location.hash = 'videos') {
var url = window.location.hash,
id = url.match(regex-goes-here); // output e.g string '12345'
}
(Not sure if my extremely simple check (window.location.hash = 'videos') will work on two hashtags..? There is probably a better way of checking the URL, if so, please do tell :-)
You can get an array of tags like this:
var tags = window.location.hash.replace(/^#/, '').split('#');
In case of http://local/default.php#videos#12345, tags[0] will be videos and tags[1] will be 12345. You can use tags.length to determine how many tags there are.