I am using a lot of hashes in my URL for displaying messages and stuff, but I have a problem. It is fine when you click on a conversation to read it:
But, look what happens when the user attaches another hash to the end: (the subject disappears because the JavaScript gets confused)
(Click images to view larger versions)
How can I remove that second hash if there is one? I did this in Gmail before and it automatically removed them. So, how can I do this with my system? Here's my hash code:
if (window.location.hash) {
var messageID = window.location.hash.replace('#!/message/', '');
var msgSubject = $('#subject_' + messageID).text();
//the below code checks if conversation exists
$.get('tools.php?type=id_check&id=' + messageID, function(data) {
if (data == 'true') {
setTimeout(function() {
readMessage(messageID, msgSubject);
}, 200);
}
else {
alertBox('The requested conversation does not exist.', 2500);
window.location = '#';
}
});
}
Thanks in advance!
You can try
var matches = window.location.hash.match(/#!\/message\/(\d+)/);
if (matches) {
var messageId = matches[1];
// ...
}
This will capture a series of only digits after #!/message/. If the hash contains #!/message/123, then matches will be an array
['#!/message/123', '123']
and so matches[1] will contain the message id. If there is anything before or after it in the hash, it will be ignored. If there are no matches, matches will be null.
Related
I'm showing hidden divs based on the contents of a query string parameter that's being parsed from another page, using indexof to check if a value is present - then displaying that value's corresponding div.
Query string: index.html?q1=bag1,bag2,bag3
var urlParams;
(window.onpopstate = function () {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();
Then using indexOf to show divs based on the value:
if ((urlParams["q1"]).indexOf("bag1") >= 0) {
$(".content1").show();
} else
if ((urlParams["q1"]).indexOf("bag2") >= 0) {
$(".content2").show();
} else
if ((urlParams["q1"]).indexOf("bag3") >= 0) {
$(".content3").show();
}
However, it's only displaying the first div and not the second or third.
I know it'll be a simple solution - bit stuck on it. Any help appreciated!
You need to remove the else clauses, as the interpreter will stop after the first if is true. So your code should look like
if ((urlParams["q1"]).indexOf("bag1") >= 0) {
$(".content1").show();
}
if ((urlParams["q1"]).indexOf("bag2") >= 0) {
$(".content2").show();
}
if ((urlParams["q1"]).indexOf("bag3") >= 0) {
$(".content3").show();
}
I'd suggest using your bag1 etc values as IDs instead of classes to identify the separate content sections. If a class only identifies one element then you're doing it wrong.
You should then tag all of your content elements with the same class (e.g. content) so that you can .hide() on all of them before running .show on the ones that you want to remain visible. As written any elements that are already visible will remain visible when you pop state even if they weren't supposed to be.
Your parameter extracting code is OK, but having got your q1 value I would just do this:
var q1 = urlParams.q1;
if (q1 !== undefined) {
$('.content').hide(); // show nothing
q1.split(',').forEach(function(id) {
$('#' + id).show();
});
}
thereby removing all of the (broken) conditional logic.
I am creating a submittal form, sending the form to a php form, and after the form completes having it redirect to the initial page with an additional "?s=1" in the url.
Basically what I am trying to do is create an alert box pop up on loading the page with the "?s=1" in the url.
It is a very brute force method to use I know, but i can't seem to get the small script to work correctly. I know for certain everything works and loads to the point and reloads the initial page with ?s=1 in it.
Here is the code i'm using to try and prompt the alert box
enter code here <script type="text/javascript">
var Path = window.location.href;
if (Path == "mywebsite.html?s=1")
{
alert("Your Form Has Been Submitted.")
}
else()
{
}
</script>
Does anybody know why the box will not appear? Or possibly an alternate method for what I am attempting to do? Thanks.
window.location.href contains the complete URL, including the domain, and the full path, so a basic equality comparison won't work unless you're exaclty matching it, and even still this could cause problems (e.g. www. versus a naked domain, https:// versus http://, etc.). A possible solution is to use RegEx.
var pathRegex = /mywebsite\.html\?s\=1/;
if (pathRegex.test(window.location.href)) {
alert("Your Form Has Been Submitted.")
}
As a note, you can have an if statement without an accompanying else, and else statements don't take any arguments in parentheses like if, unless you're talking about else if.
Here is some code I wrote up for one of my projects that lets you pull a parameter and value out of the url.
function GetURLParameter(urlParameter){
var url = window.location.search.substring(1);
var urlVariables = url.split('&');
for (var i = 0; i < urlVariables.length; i++){
var parameter = urlVariables[i].split('=');
if (parameter[0] == urlParameter){
return parameter[1];
}
}
}
It's easy to use:
For mywebsite.com?s=1
It would just be
var k = GetURLParameter('s');
if (k == 1){
alert("Your Form Has Been Submitted.")
}
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
And then check like...
if (getParameterByName("s")=="1")
{
alert("Your Form Has Been Submitted.")
}
else
{
}
Here what the textbox result looks like,
Please add the following DNS entries
144.68.238.87 name.domain
144.68.238.88 name.domain
144.68.238.89 name.domain
The goal is to validate name.domain by making sure that the user replace name.domain to server name on textbox before submit it. If the user doesn't replace name.domain with their server name, then it will send alert message and return false until user replace it correctly.
Here is my codes,
function DomainValidate() {
var arrayOfLines = document.getElementById('txt').value.split('/n');
arrayOfLines.shift(); //use shift to skip the first line
for (i = 0; i < arrayOfLines.length; i++) {
//somewhere here need to split to get name.domain and then verify it
var domainName = arrayOfLines[i].split(" ", 2);
if(domainName.Equals("name.domain")
{
alert("You must replace name.domain to your new server name");
return false;
}
}
}
I am not sure if these are correct since I couldn't debug the javascript.
First issue I can see is that your character for the newline is incorrect. It should be \n not /n. Second issue I see is that i is a global variable, when it should be local. Third issue is that arrayOfLines[i].split(' ', 2); returns an array, but you are treating it like it returns a string on the next line if (domainName.Equals('name.domain').
With those corrections your code would look more like this:
function domainValidate() {
var arrayOfLines = document.getElementById('txt').value.split('\n');
arrayOfLines.shift(); //use shift to skip the first line
for (var i = 0; i < arrayOfLines.length; i++) {
var line = arrayOfLines[i].trim();
// Grab the second part of the split line, which represents the domain name
var parts = line.split(' ');
var domainName = parts[parts.length - 1];
if (!domainName || domainName === 'name.domain') {
alert("You must replace name.domain to your new server name");
return false;
}
}
}
As far as I can tell without testing, this should work as expected. The best way to test this though is with jsfiddle. Add your html and this script and call it to see if it produces the expected result.
Easiest way that I think
Suppose the id of textbox is domainTxt
src = document.getElementById("domainTxt");
if(verifyInput(src.value)){
//submit your form here
} else
{
return false;
}
function verifyInput(txtVal){
if(txtVal.indexOf("name.domain") >-1){
return false;
}else {
return true;
}
}
I am adding a Search feature, and if the user is on the search results and they refresh the page I want it to stay at that search. I already put the search query into the URL, but I don't know how to retrieve it. It will most likely require a regexp so anyone that is experienced with regexp, please help.
Here is how I put it into the URL:
function trimspace(str) {
str = str.replace(/ +(?= )/g, '');
return str;
}
function searchMail() {
var query = trimspace($('#search_input').val());
if (query == '' || !query || query == null) {
$('#search_input').focus();
}
else {
window.location.hash = '#!/search/' + query;
$('#loader').show();
$.get('tools.php?type=search', { q: query }, function(data, textStatus) {
$('#loader').hide();
if (textStatus == 'success') {
hideAllTabs();
$('#search_results').html(data).show();
document.title = "Search results - WeeBuild Mail";
}
else {
alertBox('Search failed. Please try again in a few minutes.', 2500);
}
});
}
}
And besides just retreiving the query I need to be able to detect if the hash is #!/search/query.
Thanks in advance!
Detect if query is #!/search/query:
location.hash==='#!/search/query'
Finding out about the query parts assuming the query is #!/search/query:
var parts = location.hash.split('/');
parts[0] is #!. parts[1] is search and parts[2] is test. Doing with the parts want you want should now be trivial enough.
In response to the comments:
function getPartAndRemainder(){
var parts = location.hash.split('/');
if(parts[0]!=='#!' || parts.length<2){
// Value after # does not follow the expected pattern #!/part/any_parameters
throw new Error('Cannot parse application part.');
}
return {
// Contains the part of your application (word after first slash after #)
part: parts[1],
// Contains everything after second slash after # or the empty string
remainder: location.hash.substring(
// Length of #! (or whatever somebody might use instead)
parts[0].length
// Length of first slash
+1
// Length of your application part's name
+parts[1].length
// Length of the second slash
+1)
};
}
The function gives back an object that contains the part of your application at the key part and the remainder key will contain the rest. So, if your URI would be something#!/search/test the function would return {part:'search', remainder:'test'}.
In case the URI can't be parsed, you'll get an error and you should then use a sensible default instead.
You would use the method as follows whenever the hash changes or at some other event (point in time) where you are interested in the hash value:
try {
var hashValue = getPartAndRemainder();
if(hashValue.part==='search'){
var query = hashValue.remainder;
alert('You searched: '+query)
}
if(hashValue.part==='inbox'){
alert('You are in inbox, now');
}
} catch(e){
// It was not possible to parse the value after the # from URI according to our expected pattern.
alert('No idea what to do with: '+location.hash);
}
This regex will match anything after the search param, is this what you are looking for?
/#1/search/(.*)/
var match = /\/.*\/.*\/(.*)\//i.exec(location.hash)
//match contain the query
I've made a function (in JavaScript) that takes an URL from either YouTube or Vimeo. It figures out the provider and ID for that particular video (demo: http://jsfiddle.net/csjwf/).
function parseVideoURL(url) {
var provider = url.match(/http:\/\/(:?www.)?(\w*)/)[2],
id;
if(provider == "youtube") {
id = url.match(/http:\/\/(?:www.)?(\w*).com\/.*v=(\w*)/)[2];
} else if (provider == "vimeo") {
id = url.match(/http:\/\/(?:www.)?(\w*).com\/(\d*)/)[2];
} else {
throw new Error("parseVideoURL() takes a YouTube or Vimeo URL");
}
return {
provider : provider,
id : id
}
}
It works, however as a regex Novice, I'm looking for ways to improve it. The input I'm dealing with, typically looks like this:
http://vimeo.com/(id)
http://youtube.com/watch?v=(id)&blahblahblah.....
1) Right now I'm doing three separate matches, would it make sense to try and do everything in one single expression? If so, how?
2) Could the existing matches be more concise? Are they unnecessarily complex? or perhaps insufficient?
3) Are there any YouTube or Vimeo URL's that would fail being parsed? I've tried quite a few and so far it seems to work pretty well.
To summarize: I'm simply looking for ways improve the above function. Any advice is greatly appreciated.
Here's my attempt at the regex, which covers most updated cases:
function parseVideo(url) {
// - Supported YouTube URL formats:
// - http://www.youtube.com/watch?v=My2FRPA3Gf8
// - http://youtu.be/My2FRPA3Gf8
// - https://youtube.googleapis.com/v/My2FRPA3Gf8
// - Supported Vimeo URL formats:
// - http://vimeo.com/25451551
// - http://player.vimeo.com/video/25451551
// - Also supports relative URLs:
// - //player.vimeo.com/video/25451551
url.match(/(https?\/\/)(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
var type = null;
if (RegExp.$3.indexOf('youtu') > -1) {
type = 'youtube';
} else if (RegExp.$3.indexOf('vimeo') > -1) {
type = 'vimeo';
}
return {
type: type,
id: RegExp.$6
};
}
Regex is wonderfully terse but can quickly get complicated.
http://jsfiddle.net/8nagx2sk/
function parseYouTube(str) {
// link : //youtube.com/watch?v=Bo_deCOd1HU
// share : //youtu.be/Bo_deCOd1HU
// embed : //youtube.com/embed/Bo_deCOd1HU
var re = /\/\/(?:www\.)?youtu(?:\.be|be\.com)\/(?:watch\?v=|embed\/)?([a-z0-9_\-]+)/i;
var matches = re.exec(str);
return matches && matches[1];
}
function parseVimeo(str) {
// embed & link: http://vimeo.com/86164897
var re = /\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i;
var matches = re.exec(str);
return matches && matches[1];
}
Sometimes simple code is nicer to your fellow developers.
https://jsfiddle.net/vkg02mhp/1/
// protocol and www nuetral
function getVideoId(str, prefixes) {
const cleaned = str.replace(/^(https?:)?\/\/(www\.)?/, '');
for(const prefix of prefixes) {
if (cleaned.startsWith(prefix))
return cleaned.substr(prefix.length)
}
return undefined;
}
function getYouTubeId(url) {
return getVideoId(url, [
'youtube.com/watch?v=',
'youtu.be/',
'youtube.com/embed/'
]);
}
function getVimeoId(url) {
return getVideoId(url, [
'vimeo.com/'
]);
}
Which do you prefer to update?
I am not sure about your question 3), but provided that your induction on the url forms is correct, the regexes can be combined into one as follows:
/http:\/\/(?:www.)?(?:(vimeo).com\/(.*)|(youtube).com\/watch\?v=(.*?)&)/
You will get the match under different positions (1st and 2nd matches if vimeo, 3rd and 4th matches if youtube), so you just need to handle that.
Or, if you are quite sure that vimeo's id only includes numbers, then you can do:
/http:\/\/(?:www.)?(vimeo|youtube).com\/(?:watch\?v=)?(.*?)(?:\z|&)/
and the provider and the id will apprear under 1st and 2nd match, respcetively.
Here is my regex
http://jsfiddle.net/csjwf/1/
For Vimeo, Don't rely on Regex as Vimeo tends to change/update their URL pattern every now and then. As of October 2nd, 2017, there are in total of six URL schemes Vimeo supports.
https://vimeo.com/*
https://vimeo.com/*/*/video/*
https://vimeo.com/album/*/video/*
https://vimeo.com/channels/*/*
https://vimeo.com/groups/*/videos/*
https://vimeo.com/ondemand/*/*
Instead, use their API to validate vimeo URLs. Here is this oEmbed (doc) API which takes an URL, checks its validity and return a object with bunch of video information(check out the dev page). Although not intended but we can easily use this to validate whether a given URL is from Vimeo or not.
So, with ajax it would look like this,
var VIMEO_BASE_URL = "https://vimeo.com/api/oembed.json?url=";
var yourTestUrl = "https://vimeo.com/23374724";
$.ajax({
url: VIMEO_BASE_URL + yourTestUrl,
type: 'GET',
success: function(data) {
if (data != null && data.video_id > 0)
// Valid Vimeo url
else
// not a valid Vimeo url
},
error: function(data) {
// not a valid Vimeo url
}
});
about sawa's answer :
a little update on the second regex :
/http:\/\/(?:www\.)?(vimeo|youtube)\.com\/(?:watch\?v=)?(.*?)(?:\z|$|&)/
(escaping the dots prevents from matching url of type www_vimeo_com/… and $ added…)
here is the same idea for matching the embed urls :
/http:\/\/(?:www\.|player\.)?(vimeo|youtube)\.com\/(?:embed\/|video\/)?(.*?)(?:\z|$|\?)/
FWIW, I just used the following to validate and parse both YouTube and Vimeo URLs in an app. I'm sure you could add parentheses to parse out the specific things you're looking for...
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$|^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/
^^ This is just a combination of 2 separate expressions using | (or) to join them. Here are the original 2 expressions separately:
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/
/^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/
I'm no expert, but it seems to work according to Rubular. Hopefully this helps someone out in the future.
3) Your regex does not match https url's. I haven't tested it, but I guess the "http://" part would become "http(s)?://". Note that this would change the matching positions of the provider and id.
Just in case here is a php version
/*
* parseVideo
* #param (string) $url
* mi-ca.ch 27.05.2016
* parse vimeo & youtube id
* format url for iframe embed
* https://regex101.com/r/lA0fP4/1
*/
function parseVideo($url) {
$re = "/(http:|https:|)\\/\\/(player.|www.)?(vimeo\\.com|youtu(be\\.com|\\.be|be\\.googleapis\\.com))\\/(video\\/|embed\\/|watch\\?v=|v\\/)?([A-Za-z0-9._%-]*)(\\&\\S+)?/";
preg_match($re, $url, $matches);
if(strrpos($matches[3],'youtu')>-1){
$type='youtube';
$src='https://www.youtube.com/embed/'.$matches[6];
}else if(strrpos($matches[3],'vimeo')>-1){
$type="vimeo";
$src='https://player.vimeo.com/video/'.$matches[6];
}else{
return false;
}
return array(
'type' => $type // return youtube or vimeo
,'id' => $matches[6] // return the video id
,'src' => $src // return the src for iframe embed
);
}
I had a task to enable adding a dropbox videos. So the same input should take href, check it and transform to the playable link which I can then insert in .
const getPlayableUrl = (url) => {
// Check youtube and vimeo
let firstCheck = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
if (firstCheck) {
if (RegExp.$3.indexOf('youtu') > -1) {
return "//www.youtube.com/embed/" + RegExp.$6;
} else if (RegExp.$3.indexOf('vimeo') > -1) {
return 'https://player.vimeo.com/video/' + RegExp.$6
}
} else {
// Check dropbox
let candidate = ''
if (url.indexOf('.mp4') !== -1) {
candidate = url.slice(0, url.indexOf('.mp4') + 4)
} else if (url.indexOf('.m4v') !== -1) {
candidate = url.slice(0, url.indexOf('.m4v') + 4)
} else if (url.indexOf('.webm') !== -1) {
candidate = url.slice(0, url.indexOf('.webm') + 5)
}
let secondCheck = candidate.match(/(http:|https:|)\/\/(player.|www.)?(dropbox\.com)\/(s\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*\/)?(.*)/);
if (secondCheck) {
return 'https://dropbox.com/' + RegExp.$4 + RegExp.$5 + RegExp.$6 + '?raw=1'
} else {
throw Error("Not supported video resource.");
}
}
}
I based myself the previous answers but I needed more out the regex.
Maybe it worked in 2011 but in 2019 the syntax has changed a bit. So this is a refresh.
The regex will allow us to detect weather the url is Youtube or Vimeo.
I've added Capture group to easily retrieve the videoID.
If ran with Case insensitive setting please remove the (?i).
(?:(?i)(?:https:|http:)?\/\/)?(?:(?i)(?:www\.youtube\.com\/(?:embed\/|watch\?v=)|youtu\.be\/|youtube\.googleapis\.com\/v\/)(?<YoutubeID>[a-z0-9-_]{11,12})|(?:vimeo\.com\/|player\.vimeo\.com\/video\/)(?<VimeoID>[0-9]+))
https://regex101.com/r/PVdjg0/2
Use this Regex devs:This works like Makhan(react js,Javascript)
^(http\:\/\/|https\:\/\/)?((www\.)?(vimeo\.com\/)([0-9]+)$)|((www\.youtube\.com|youtu\.be)\/.+$)