1

I would like to build a form (VIA POST METHOD) with just one field (url - link shortening). Now the question is how and if is it possible to build a form that detects the value of the URL field is a link and automatically shortens it rather than waiting you click Send (for exmaple like the web of Bit.ly).

The main idea is once the field is an identifier that value is a proper Hyperlink is directly sends and shortens (And the field is replaced by a shortened link) it without waiting for the click on the SEND.

index.html

<html>
<head>
<script>
function showHint(str) {
    if (str.length == 0) { 
        document.getElementById("txtHint").innerHTML = "";
        return;
    } else {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                document.getElementById("txtHint").innerHTML = this.responseText;
            }
        };
        xmlhttp.open("GET", "gethint.php?q=" + str, true);
        xmlhttp.send();
    }
}
</script>
</head>
<body>

<p><b>Start typing a url in the input field below:</b></p>
<form> 
Url: <input type="text" onkeyup="showHint(this.value)">
</form>
<p><span id="txtHint"></span></p>
</body>
</html>

gethint.php

 <?php  
// get the q parameter from URL 

    $q = $_REQUEST["q"];

        $hint = "";

    if (!filter_var($q, FILTER_VALIDATE_URL) === FALSE) {    

    // short the link 

    $rand = rand(1,1000); 

    $hint = 'http://domain.com/'.$rand;    }

    echo $hint === "" ? "Not a valid URL" : $hint; ?>
AnnaLA
  • 155
  • 1
  • 11

1 Answers1

1

I'd use jQuery for the event triggering/AJAX and https://gist.github.com/dperini/729294 for weburl regex.

I'm not that at home on pure JavaScript AJAX calls, but is

xmlhttp.open("GET")

the right way to go at it if you want to make a POST?

Anyway the main thing you're missing is

function isUrl(url){
        var regex = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
        if(regex.test(url)){
             return regex.test(url);
        }else{
             return regex.test("http://"+url);
        }
}

So this should be your new index.html

<html>
<head>
<script>
var extensions = [".aero",".biz",".cat",".com",".coop",".edu",".gov",".info",".int",".jobs",".mil",".mobi",".museum",".name",".net",".org",".travel",".ac",".ad",".ae",".af",".ag",".ai",".al",".am",".an",".ao",".aq",".ar",".as",".at",".au",".aw",".az",".ba",".bb",".bd",".be",".bf",".bg",".bh",".bi",".bj",".bm",".bn",".bo",".br",".bs",".bt",".bv",".bw",".by",".bz",".ca",".cc",".cd",".cf",".cg",".ch",".ci",".ck",".cl",".cm",".cn",".co",".cr",".cs",".cu",".cv",".cx",".cy",".cz",".de",".dj",".dk",".dm",".do",".dz",".ec",".ee",".eg",".eh",".er",".es",".et",".eu",".fi",".fj",".fk",".fm",".fo",".fr",".ga",".gb",".gd",".ge",".gf",".gg",".gh",".gi",".gl",".gm",".gn",".gp",".gq",".gr",".gs",".gt",".gu",".gw",".gy",".hk",".hm",".hn",".hr",".ht",".hu",".id",".ie",".il",".im",".in",".io",".iq",".ir",".is",".it",".je",".jm",".jo",".jp",".ke",".kg",".kh",".ki",".km",".kn",".kp",".kr",".kw",".ky",".kz",".la",".lb",".lc",".li",".lk",".lr",".ls",".lt",".lu",".lv",".ly",".ma",".mc",".md",".mg",".mh",".mk",".ml",".mm",".mn",".mo",".mp",".mq",".mr",".ms",".mt",".mu",".mv",".mw",".mx",".my",".mz",".na",".nc",".ne",".nf",".ng",".ni",".nl",".no",".np",".nr",".nu",".nz",".om",".pa",".pe",".pf",".pg",".ph",".pk",".pl",".pm",".pn",".pr",".ps",".pt",".pw",".py",".qa",".re",".ro",".ru",".rw",".sa",".sb",".sc",".sd",".se",".sg",".sh",".si",".sj",".sk",".sl",".sm",".sn",".so",".sr",".st",".su",".sv",".sy",".sz",".tc",".td",".tf",".tg",".th",".tj",".tk",".tm",".tn",".to",".tp",".tr",".tt",".tv",".tw",".tz",".ua",".ug",".uk",".um",".us",".uy",".uz", ".va",".vc",".ve",".vg",".vi",".vn",".vu",".wf",".ws",".ye",".yt",".yu",".za",".zm",".zr",".zw"];

var delay = (function(){
    var timer = 0;
    return function(callback, ms){
       clearTimeout (timer);
       timer = setTimeout(callback, ms);
    };
 })();

function isUrl(url){
        var regex = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
        if(regex.test(url)){
             return regex.test(url);
        }else{
             return regex.test("http://"+url);
        }
}
function showHint(str) {
 delay(function(){
      str = str.toLowerCase();
      var dot = str.lastIndexOf(".");
      var extension = str.substr(dot);
      extension = extension.split('/')[0];
      var found = $.inArray(extension, extensions) > -1;
         if (!isUrl(str)||!found) { 
             document.getElementById("txtHint").innerHTML = "";
             return;
         } else {
             var xmlhttp = new XMLHttpRequest();
             xmlhttp.onreadystatechange = function() {
                 if (this.readyState == 4 && this.status == 200) {
                     document.getElementById("txtHint").innerHTML = this.responseText;
                 }
             };
             xmlhttp.open("GET", "gethint.php?q=" + str, true);
             xmlhttp.send();
         }
     }, 500)
 }
</script>
</head>
<body>

<p><b>Start typing a url in the input field below:</b></p>
<form> 
Url: <input type="text" onkeyup="showHint(this.value)">
</form>
<p><span id="txtHint"></span></p>
</body>
</html>

edit: Say you will start typing in http://www.example.net.. The AJAX will trigger on "http://www.example.ne" and then again when you add the last letter. To avoid that, you might try "change" instead of "keyup" event.

edit2: Now checks against list of valid domain extensions

edit3: Now waits half a second before posting the result.

edit4: Small oversight while checking for extensions, fixed with extension = extension.split('/')[0];

Also if you want to enable users to write URL's without "http://" and similar, you'll need an edited regex or write a small hack that adds that to your string before you send it into "isUrl()".

McCuz
  • 227
  • 1
  • 12
  • Thank you a lot ... can you edit the answer and write the full code pls. TIA @McCuz – AnnaLA Dec 01 '16 at 13:55
  • can you tell me how to do the "keyup" event so in case of walla.co and walla.com it will not send it twice. tia – AnnaLA Dec 15 '16 at 11:35
  • I've edited the index.html to include most of known extensions (i've stolen a list from http://xaviesteve.com/2094/internet-top-level-domains-in-php-javascript-array/). I've also added some checks into your index.html that find the url's extension and then check if the extension is found in that list. But here's the catch, ".co" is also a valid domain, so if you want to ignore it and not post twice when someone start typing walla.com, you'd have to remove .co from list of valid domains. I didnt get to test this well, let me know if it works. – McCuz Dec 15 '16 at 12:57
  • I did a quick update using the answer from http://stackoverflow.com/questions/1909441/jquery-keyup-delay to add a delay of 500 milliseconds before AJAX triggers. That should allow people to finish typing before the url is posted. (Unless they press less than 2 keys a second) – McCuz Dec 15 '16 at 13:09
  • Thnak you so much@McCuz.. but there are 1 small problem... When i put a link like this [link]http://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=2&toolid=10039&campid=5338007190&item=231732849370&vectorid=229466&lgeo=1[/link] (maybe... " & / = ? ") its not working at all. TIA – AnnaLA Dec 19 '16 at 07:05
  • it's the "http://" thing missing, not other characters. I've tried the regex and it validates your url with the http:// added. I've updated the "isUrl" function in your index to also test with "http://" added if the 1st result returns false. Does this help? – McCuz Dec 19 '16 at 07:40
  • No its still not working @McCuz .. when im putting the url [link]http://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=2&toolid=10039&campid=5338007190&item=231732849370&vectorid=229466&lgeo=1[/link] inside the php its working... [link]http://eebay.ga [/link] direct link to the shortlink web. – AnnaLA Dec 19 '16 at 09:30
  • when im putting http://rover.ebay.com is working but when i put http://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=2&toolid=10039&campid=5338007190&item=231732849370&vectorid=229466&lgeo=1 its not (with/without http://) – AnnaLA Dec 19 '16 at 09:58
  • When I'm putting that url into a test jsfiddle https://jsfiddle.net/2b65svgr/ it seems to detect a working link. Can you provide more information? – McCuz Dec 19 '16 at 10:25
  • 1
    Hi @McCuz... http://eebay.ga when im tring to put rover.ebay.com its working but when i put the full link its not working at all (with or without http) http://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=2&toolid=10039&campid=5338007190&item=231732849370&vectorid=229466&lgeo=1 .... the test that you provide is different from your function that you have posted ( function showHint(str) ) – AnnaLA Dec 19 '16 at 10:39
  • 1
    The main thing being regex, that stayed the same. The function in that jsfiddle is very simple, and is a dumbed down version of this here (without the ajax call). If you don't find a solution before tomorrow I'll take a bit more time and check again. – McCuz Dec 19 '16 at 11:16
  • Got it, 2 lines were missing (has to do with extensions - 2 lines under var extension = ...). I've updated the index.html code for you. – McCuz Dec 20 '16 at 07:55
  • Working TNX so much @McCuz – AnnaLA Dec 20 '16 at 08:24
  • Hi just a small thing... in case the URL is in uppercase (capital letter) its not working at all. – AnnaLA Dec 20 '16 at 10:09
  • In that case lets add str = str.toLowerCase() when we start our timeout function. This will transform every input into lowercase before it will start working with it. If you dont need url's saved in original case, this would be the best and easiest solution. (Updated index.html) – McCuz Dec 20 '16 at 10:48
  • Ok perfect thank you... but still a small problem but this link [link]http://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=4&pub=5575248592&toolid=10001&campid=5338009747&customid=&mpre=http%3A%2F%2Fwww.ebay.com%2Fitm%2FNEW-Vegetarian-Cookbook-Vegan-Cookbooks-of-Meat-Free-Recipes-for-Vegetarian-and-%2F391113790853%3Fhash%3Ditem5b1032d585%3Ag%3ARzIAAOSwBahVK-tR[/link] not working – AnnaLA Dec 21 '16 at 07:37
  • I think at this point it's best if you just change your "if (!isUrl(str)||!found) { " with "if(!isUrl(str)) {" and ignore the extension list. This url you've posted has a problem cuz it has "double" url inside and it reads the 2nd extension. – McCuz Dec 21 '16 at 09:18