2

I am having trouble with the jQuery $ onclick event

by onclick i mean:

const $trigger = $('<button class="button primary" onclick="callback()">');

but for some reason, the callback is not "calling"

here is some example code (simplified)

$(function() {
  const $add = $('.add-item');
  const $container = $('.container');
  
  $add.click(() => {
    function callback() { // here is the error (not defined)
      console.log(privateData); // but obviously this is defined...
    }
  
    const $item = $(`<li class="button" onclick="callback()">Click Me</li>`);
    
    $container.append($item);
  });
});
* {
  box-sizing: border-box;
  font-family: Roboto;
}

ul, li {
  margin: 0;
  padding: 0;
}

ul {
  margin-top: 20px;
}

body, html {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
}

.button {
  list-style: none;
  padding: 10px 20px;
  background: #2980b9;
  border-radius: 8px;
  cursor: pointer;
  color: #fff;
}

.button.primary {
  background: #c0392b;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a class="button primary add-item">Add Item</a>
  <ul class="container"></ul>
</div>

note that the only thing in the demo that matters is the javascript, which produces the following error:

{
  "message": "Uncaught ReferenceError: callback is not defined",
  "filename": "https://stacksnippets.net/js",
  "lineno": 1,
  "colno": 1
}

any helpz?

3 Answers 3

3

The issue is because you're using a onclick event attribute. This means that the function called must be available from within the scope of the window - which your callback function is not.

To solve this problem, don't use on* event attributes unless there is literally no alternative. You can attach the click event at the point the element is created instead:

const $item = $(`<li class="button">Click Me</li>`).on('click', callback);

Alternatively you can use a single delegated event on all current and future elements:

$(function() {
  const $add = $('.add-item');
  const $container = $('.container').on('click', 'li.button', callback);
  
  function callback() { // here is the error (not defined)
    var privateData = 'foo';
    console.log(privateData); // but obviously this is defined...
  }

  $add.click(() => {
    const $item = $(`<li class="button">Click Me</li>`);
    $container.append($item);
  });
});
* {
  box-sizing: border-box;
  font-family: Roboto;
}

ul,
li {
  margin: 0;
  padding: 0;
}

ul {
  margin-top: 20px;
}

body,
html {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
}

.button {
  list-style: none;
  padding: 10px 20px;
  background: #2980b9;
  border-radius: 8px;
  cursor: pointer;
  color: #fff;
}

.button.primary {
  background: #c0392b;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a class="button primary add-item">Add Item</a>
  <ul class="container"></ul>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, worked, I will accept as soon as it lets me :)
how would this be changed if my callback function had arguments?
In that case you'd need to wrap the call in an anonymous function: .on('click', 'li.button', function() { callback('arg1', 'arg2'); });
0

just put your callback() method outside of $add.click, in your case the scope of callback() method is going to be limited to $add.click that's why onclick is showing reference error

function callback() { // here is the error (not defined)
  console.log("calling callback() method"); // but obviously this is defined...
}
$(function() {
  const $add = $('.add-item');
  const $container = $('.container');
  
  $add.click(() => {
    callback();
  
    const $item = $(`<li class="button" onclick="callback()">Click Me</li>`);
    
    $container.append($item);
  });
});
* {
  box-sizing: border-box;
  font-family: Roboto;
}

ul, li {
  margin: 0;
  padding: 0;
}

ul {
  margin-top: 20px;
}

body, html {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
}

.button {
  list-style: none;
  padding: 10px 20px;
  background: #2980b9;
  border-radius: 8px;
  cursor: pointer;
  color: #fff;
}

.button.primary {
  background: #c0392b;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a class="button primary add-item">Add Item</a>
  <ul class="container"></ul>
</div>

Comments

0

This is working but u need to define 'privateData'

function callback() { // here is the error (not defined)
      console.log(privateData); // but obviously this is defined...
    }
$(function() {
  const $add = $('.add-item');
  const $container = $('.container');

  $add.click(() => {


    const $item = $(`<li class="button" onclick="callback()">Click Me</li>`);

    $container.append($item);
  });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.