1

Suppose i have a textarea in a form named urlslist where the user will input a list of urls , one on each line.I handle the submit via ajax with query as follows.

$(function () {
    $("#urlslist").submit(function(e) {

        //prevent Default functionality
        e.preventDefault();

        //get the action-url of the form
        var actionurl = e.currentTarget.action;

        //do your own request an handle the results
        $.ajax({
            url: actionurl,
            type: 'post',
            dataType: 'json',
            data: $("#urlslist").serialize(),
            success: function(data) {
                //put the result in another textarea here
            }
        });

    });

});

Then i display the result of my processing (i.e another url for each input) in another textarea. It works well but i want to improve it so that old urls don't get submitted to the server via ajax while not clearing either of the textareas.

Edit 1

I think i need to demonstrate this with an example.

Suppose that the urlslist textarea contain one url.I click on submit and i get a result.Now i add another url in the urlslist and click on submit again.Now there will be 2 urls in the post request.How can i make sure that only new urls are sent.

user2650277
  • 6,289
  • 17
  • 63
  • 132

4 Answers4

1

Using the Do something only once lib from Mozilla :

function executeOnce() {
  var argc = arguments.length,
    bImplGlob = typeof arguments[argc - 1] === "string";
  if (bImplGlob) {
    argc++;
  }
  if (argc < 3) {
    throw new TypeError("executeOnce - not enough arguments");
  }
  var fExec = arguments[0],
    sKey = arguments[argc - 2];
  if (typeof fExec !== "function") {
    throw new TypeError("executeOnce - first argument must be a function");
  }
  if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
    throw new TypeError("executeOnce - invalid identifier");
  }
  if (decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) === "1") {
    return false;
  }
  fExec.apply(argc > 3 ? arguments[1] : null, argc > 4 ? Array.prototype.slice.call(arguments, 2, argc - 2) : []);
  document.cookie = encodeURIComponent(sKey) + "=1; expires=Fri, 31 Dec 9999 23:59:59 GMT" + (bImplGlob || !arguments[argc - 1] ? "; path=/" : "");
  return true;
}

You can make the following :

     // some custom helper
String.prototype.s2b64 = function() { // make base64 from string
  return window.btoa(unescape(encodeURIComponent(this)));
}
String.prototype.replaceArray = function(find, replace) { // replace by array
  var replaceString = this;
  for (var i = 0; i < find.length; i++) {
    replaceString = replaceString.replace(find[i], replace[i]);
  }
  return replaceString;
};
     // here we start :
  var output = [];
  $.each($("#urlslist textarea").first().val().split(/\n/), function(index, value) {
    alert(index + ": " + value);
    if (value != '')
      executeOnce(function(v) {
        output.push(value);
      }, null, value, 'urldone_' + value.s2b64().replaceArray(
        ["expires", "path", "domain", "secure"], 
        ["e_xpires", "p_ath", "d_omain", "s_ecure"]) + '');
  });

  alert(output);

Some part may look a bit odd, but it's all about bullet-proofing the manual setCookie (like the use of b64 and the search & replace in case we are really unlucky and randomly get a cookie keyword from the b64 output)

And if you want to remove all the saved value, here is the code :

  var cookieNames = document.cookie.split(/=[^;]*(?:;\s*|$)/);

  // Remove any that match the pattern
  for (var i = 0; i < cookieNames.length; i++) {
    if (/^urldone_/.test(cookieNames[i])) {
      document.cookie = cookieNames[i] + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
    }
  }

JSfiddle

This is a Cookie based answer (by browser, refresh & restart proof).

Blag
  • 5,818
  • 2
  • 22
  • 45
  • it works great but can you please update your answer to reset the "Do something only once" as well – user2650277 Apr 10 '17 at 06:06
  • @user2650277 do you want a global reset or a key (url) by key one ? BTW, I'll update my function, as if you try, `expires|max\-age|path|domain|secure` are not valid part of url / cookie key. a base64_encore should make the trick ;) – Blag Apr 10 '17 at 06:48
  • I am looking at a global reset here...say the user delete all urls in the result textarea , i need to reset it – user2650277 Apr 10 '17 at 14:09
  • @user2650277 ok, i'll take a look this evening if can (I've got some problem with me internet connexion right now) – Blag Apr 11 '17 at 08:49
  • @user2650277 here you go ! answer updated with a bullet proof jacket and an additional "removeAll" function (check the JSFiddle for how-to) – Blag Apr 11 '17 at 20:43
0

Here is working example developed form this link http://jsfiddle.net/userdude/2hgnZ/

$('form#id').submit(function(e){
    var form = $(this);
form.children('input[type=submit]').attr('disabled', 'disabled');
// this is just for demonstration
e.preventDefault(); 
$.ajax({
  url: ' http://fiddle.jshell.net/_display/',
  type: 'get',
  success: function(data) {
    alert(data);
     form.children('input[type=submit]').removeAttr('disabled');
  }
});
return false;
});
Richardson. M
  • 852
  • 2
  • 17
  • 28
0
    var map = []
        map['www.google.com'] = 'www.google.com';
        var urls = ['www.google.com', 'www.yahoo.com']; //this is form text area
        for (var i = 0; i< urls.length; i++) {
            if (map[urls[i]] !== urls[i]) {
            console.log('post ' +);
            map[urls[i]] = urls[i];
          } else {
            console.log('don not post ' + urls[i]);
          }
        }

Read the above console code you may got some idea Here i keep
step 1) var map = [] global
step 2) map['www.google.com'] = 'www.google.com'; this line demonstrate already posted
step 3) loop through var urls which is your text area
step 4) if (map[urls[i]] !== urls[i]) check the current link already posted if not post else do not post

Richardson. M
  • 852
  • 2
  • 17
  • 28
0

My suggestion would be to use the .one() method.

The .one() method is identical to .on(), except that the handler for a given element and event type is unbound after its first invocation. http://api.jquery.com/one/

$("form").one('submit',function(e) {

    //prevent Default functionality
    e.preventDefault();

    //save current element to var for speed
    var self = $(this);

    //do your own request an handle the results
    $.ajax({
        url: self.attr('action'),
        type: self.attr('method'),
        dataType: 'json',
        data: $("#urlslist").serialize(),
        success: function(data) {
            //put the result in another textarea here
        }
    });

});

EDIT:

As for duplications, you would need to control this with your server sided (action) script to check against the database to make sure that each new URL is unique. What language are you using back end?

PHP

$con = //database connection
if(isset($_POST['urlslist'] && $_POST['urlslist'] != '') {
    $urls = explode("\n",$_POST['urlslist']);
    foreach($urls as $url) {
        if($exists = mysqli_query($con,"SELECT * FROM urls_table WHERE url = '$url'")) {
            // run update or ignore
        } else {
            // insert into db
        }
    }
}
JohnV
  • 59
  • 6