3
votes

I have been trying to get an ajax call to work inside a function triggered by an onclick event. When I use event.preventDefault the page is not reloaded but the ajax call does not work, no data is added to my database. When I comment out that line the page is reloaded but everything else works.

function clickFunction(elem) {
    var var1 =  elem.id;
    var var2 =  var1.split("_");
    //  elem.preventDefault();


    if (var2[0] == "Add") {
        if (var2[1] == "Calls") {
            console.log("Calls");
            console.log(var1);
            event.preventDefault();
            var data = $(this).serialize();
            $.post('progressSheetDynamic', data).done(function (response){
                $(".1").html(parseInt($('.1').html(), 10)+1);
                Calls.update(50);

            });
        }
    }
}

Html code

<form action="{{ route("progressSheetDynamic") }}" method="post" id= {{ $addID }}>
    <input name="increment" value="increment" type="hidden"> </input>
    <input type="hidden" name="id" value= {{$activities}} >
    <button type="submit" class="styleHover styleButton" onclick="clickFunction(this)" id= {{ 'Add_'.$newText }}> + </button>
</form>

I have checked the logs and the function is going into the if statement. I have also tried using preventDefault on the button click event, by doing elem.preventDefault(); but this does not work. Neither does using return false.

3
It would be easier if you formatted your code. Don't make it harder for people to help you.Matt Burland
Fastest way: add return false; to your onclick. onclick="clickFunction(this); return false;"I.G. Pascual
You do not declare event, that is why it fails. If you do not want a form to submit, than do not use a submit button.epascarello
Change onclick="clickFunction(this)" to onclick="clickFunction(this, event)" and add the event parameter to your function, like: function clickFunction(elem, event) {...user1106925
...ah, var data = $(this).serialize(); should be var data = $(elem.form).serialize(); The this will be a reference to the window object, whereas elem is the button so elem.form will be the form to serialize (assuming that's what you wanted).user1106925

3 Answers

3
votes

The issue seems to be with this line:

var data = $(this).serialize();

It should be this instead:

var data = $(elem.form).serialize();

The this value in your function will be a reference to the window object, whereas elem is the button so elem.form will be the form to serialize (assuming that's the data you wanted).

And as noted in the comments, event is only defined as a global variable in some browsers, so you need to pass event in the attribute and receive it in the function to be safe.

Attribute:

onclick="clickFunction(this, event)"

Function:

function clickFunction(elem, event) {
  // ...
}

Note that IE8 and lower do not have event.preventDefault(), but you can set event.returnValue = false instead.

1
votes

event will not be defined because yuo haven't passed it. You're passing the button through with onclick="clickFunction(this).

Change it to onclick="clickFunction(event)".

Then change the function declaration:

function clickFunction(event) {
    console.log(event)
    ...
}

If you want both the button and the event, look at what I have:

<button type="submit" class="styleHover styleButton" onclick="clickFunction(event, this);" />

<script>
    function clickFunction(event, elem) {

        console.log(event);
        console.log(elem);
        event.preventDefault();
    }    
</script>
1
votes

Elem will be referencing the button when you pass this to clickFunction(this)

But button does not have a preventDefault() function, thus you will get a Uncaught TypeError: elem.preventDefault is not a function

Second, $(this) is referencing window, which should be $(elem.form) instead.

Below is how I fixed your original problem without changing your structure.

Html: (Not passing this in clickFunction)

<button type="submit" class="styleHover styleButton" onclick="clickFunction()" id= {{ 'Add_'.$newText }}> + </button>

Javascript: (use event.target for elem, $(elem.form) for $(this) )

function clickFunction(event) {
    var elem =  event.target; // event.target will be equivalent to your elem 
    var var1 =  elem.id;
    var var2 =  var1.split("_");
    event.preventDefault();


    if (var2[0] == "Add") {
        if (var2[1] == "Calls") {
            console.log("Calls");
            console.log(var1);
            event.preventDefault();
            var data = $(elem.form).serialize(); // should be elem.form here to get correct data
            $.post('progressSheetDynamic', data).done(function (response){
                $(".1").html(parseInt($('.1').html(), 10)+1);
                Calls.update(50);

            });
        }
    }
}