user2650277
user2650277

Reputation: 6739

Preventing double submission of data in forms

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.

Upvotes: 1

Views: 136

Answers (4)

Blag
Blag

Reputation: 5894

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).

Upvotes: 1

JohnV
JohnV

Reputation: 59

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
        }
    }
}

Upvotes: 0

Richardson. M
Richardson. M

Reputation: 932

    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

Upvotes: 0

Richardson. M
Richardson. M

Reputation: 932

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;
});

Upvotes: 0

Related Questions