add event to element after it remove itself and append itself again - javascript

I tried to remove a button and alert() when i click it, then the function will append a 'same' button to a container div, after searching senior's legacy,
i tried to use on()/live()/delegate()/ unfortunately they not work.
<body>
<div id="container"></div>
<hr>
<button onclick="clicked()">Other one</button>
<hr>
</body>
<script>
$(document).ready(function(){
var i = 0;
$("#container").append("<button id='btn_sub' onclick='clicked()'>Click Me!</button>");
$("[id='btn_sub']").delegate(this,"click",function(){
$("#container").empty();
$("#container").append("<button id='btn_sub' onclick='clicked()'>Click Me!"+i+"</button>");
i++;
});//tried click/on click/live
});
function clicked(){
alert(1);
}
</script>
Finally, in this example, the clicked function put out of $(document).ready() and the part of alert worked.
Is there any other method to do the same effect?
and why on()/live()/delegate()/ not work?
Thanks.

First off $("[id='btn_sub']") can be replaced with $("#btn_sub"), then it's actually better to use a class as you might have many buttons.
This is a working example as an illustration: https://codepen.io/antoniandre/pen/XoNNpO
$(document).ready(function(){
$("#container").on("click", '.btn_sub', function() {
removeButton(this);
});
});
function addButton() {
$("#container").append("<button class='btn_sub'>Delete Me!</button>");
}
function removeButton(btn) {
btn.remove();
}
With the on() bound on the container, you actually make sure any matching button .btn_sub will get this event attached to them when they are created in the future.
Regarding live, it does the same as on but is now deprecated so you can forget it. https://api.jquery.com/live/#live-events-handler

Use on function to attach event.http://api.jquery.com/on/
$(document).ready(function () {
var i = 0;
$("#container").append("<button id='btn_sub' onclick='clicked()'>Click Me!</button>");
$("#container").on("click", "[id='btn_sub']", function(){
$("#container").empty();
$("#container").append("<button id='btn_sub' onclick='clicked()'>Click Me!" + i + "</button>");
i++;
});
});
function clicked() {
alert(1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div id="container"></div>
<hr>
<button onclick="clicked()">Other one</button>
<hr>
</body>

var i = 0;
var btn = "<button id='btn_sub' onclick='clicked()'>Click Me!</button>";
($(function(){
$("#container").append(btn);
$("#container").on("click", '#btn_sub', function() {
$("#container")
.empty()
.append($(btn).text($(btn).text() + " " + i++));
});
}));
function clicked() {
alert(i);
}
<body>
<div id="container"></div>
<hr>
<button onclick="clicked()">Other one</button>
<hr>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

How can I use effects like `.show('slow')`

How can I use .append() with effects like .show('slow')
Having effects on append doesn't seem to work at all, and it give the same result as normal show(). No transitions, no animations.
$(function () {
var html = "<div id='str'>Hello</div>";
$('#btn').click(function () {
$('#cont').append(html);
});
});
<button id='btn'>click</button>
<div id='cont'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
try this:
$(function () {
$('#str').hide();
var html = "";
$('#btn').click(function () {
$('#str').toggle(1000);
});
});
<button id='btn'>click</button>
<div id='cont'></div>
<div style="display:none" id='str'>Hello</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If you really are desperate about the adding HTML
$(function () {
$('#str').hide();
var html = "";
$('#btn').click(function () {
$('str').innerHTML ="Hello"
$('#str').toggle(1000);
if($('str').style.display=="none"){
$('str').innerHTML =""
}
});
});
<button id='btn'>click</button>
<div id='cont'></div>
<div style="display:none" id='str'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Change/Add HTML Text To Button On Click For Multiple Buttons (Alike)

I'm creating 3-4 coupon button with the text "COPY CODE", and when people click on it, it copies the coupon and change the text to "COPIED < span>some svg icon here</ span>" for 2 seconds and then change back to "COPY CODE", and will change again when clicked.
I managed to find Javascripts to copy code, but the code that changes texts are repeating, and I can't use setTimeout() to achieve the 2-second result I want.
Hope you can help me out. Here are my codes:
HTML
<p class="code" id="code10">OFF10</p>
<button onclick="copyToClipboard('#code10');changeText1()" id="button1">COPY CODE</button>
<p class="code" id="code20">OFF20</p>
<button onclick="copyToClipboard('#code20');changeText2()" id="button2">COPY CODE</button>
<p class="code" id="code35">OFF35</p>
<button onclick="copyToClipboard('#code35');changeText3()" id="button2">COPY CODE</button>
Javascript
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
function copyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
$temp.remove();
}
function changeText1() {
document.getElementById("button1").innerHTML = "COPIED!";
}
function changeText2() {
document.getElementById("button2").innerHTML = "COPIED!";
}
function changeText3() {
document.getElementById("button3").innerHTML = "COPIED!";
}
The scripts above works but they're repeating. And then I tried setTimeout() function but it's not what I expected, and I know I understood this function wrong, I'm not familiar with Javascript, just enough to understand ~10%. Here is the script I tried
function changeText1() {
setTimeout(function() {
document.getElementById("button1").innerHTML = "COPIED!";
},2000)
}
Here is the final solution.. you don't onclick event in each button go as simple and clear
$(document).ready(function(){
$('button').on('click', function(){
var elem = $(this);
var data_id = elem.attr('data-id');
var $temp = $("<input>");
$("body").append($temp);
$temp.val(elem.prev('div').find('#'+elem.attr('data-id')).text()).select();
document.execCommand("copy");
$temp.remove();
changeText(elem);
})
})
function changeText(elem) {
$(elem).text('copied');
changeBack(elem);
}
function changeBack(elem) {
setTimeout(function() {
$(elem).text('Copy Code');
},2000)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p class="code" id="code10">OFF10</p>
</div>
<button data-id="code10" type="button">COPY CODE</button>
<div>
<p class="code" id="code20">OFF20</p>
</div>
<button type="button" data-id="code20">COPY CODE</button>
<div>
<p class="code" id="code35">OFF35</p>
</div>
<button type="button" data-id="code35">COPY CODE</button>
You do not have to use separate function to change the text, as it will be a major pain when you have a lot of these buttons in your page.
Here is my solution:
HTML:-
<p class="code" id="code10">OFF10</p>
<button onclick="copyToClipboard('#code10', 'button1')" id="button1">COPY CODE</button>
<p class="code" id="code20">OFF20</p>
<button onclick="copyToClipboard('#code20', 'button2')" id="button2">COPY CODE</button>
<p class="code" id="code35">OFF35</p>
<button onclick="copyToClipboard('#code35', 'button3')" id="button3">COPY CODE</button>
Javascript:-
<script type="text/javascript">
function copyToClipboard(element, button) {
console.log($(element).text());
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
$temp.remove();
// waiting some time before changing the text
setTimeout(function() {
changeText(button);
},2000);
}
function changeText(button) {
document.getElementById(button).innerHTML = "COPIED!";
}
</script>
Have found solution for your text change , Refer to this to copy text
function changeText(reed) {
reed.innerHTML = "COPIED!";
var reedText = reed.previousSibling;
navigator.clipboard.writeText(reedText.textContent);
setTimeout(function() {
reed.innerHTML = "COPY CODE";
}, 2000)
}
<p class="code" id="code10">OFF10</p>
<button onclick="changeText(this)" id="button1">COPY CODE</button>
<p class="code" id="code20">OFF20</p>
<button onclick="changeText(this)" id="button2">COPY CODE</button>
<p class="code" id="code35">OFF35</p>
<button onclick="changeText(this)" id="button2">COPY CODE</button>
You can reduce your dependency on jQuery by using the new Clipboard API but be aware of its browser compatibility.
If you move your ids to your buttons as data attributes you can reduce the repetition of your code, and also clean up your markup (removing the inline JS from the HTML).
Use event delegation. Put the markup inside a container element and attach one event listener to that. Click events from the buttons will "bubble up" the DOM and that listener will catch them. Then you just need to extract the id from the button.
// Add one listener to the container element
const container = document.querySelector('#container');
container.addEventListener('click', handleClick, false);
function handleClipboard(id) {
if (navigator.clipboard) {
navigator.clipboard.writeText(id).then(function() {
console.log(`${id}: code copied`);
}, function() {
console.log('Error');
});
}
}
function handleClick(e) {
// Grab the id from the button
const { id } = e.target.dataset;
// Call the clipboard function with the id
handleClipboard(id);
// Change the text content of the button
e.target.textContent = 'COPIED';
// Wait two seconds, and then change it back
setTimeout(() => e.target.textContent = 'COPY CODE', 2000);
}
<div id="container">
<p class="code">OFF10</p>
<button data-id="code10">COPY CODE</button>
<p class="code">OFF20</p>
<button data-id="code20">COPY CODE</button>
<p class="code">OFF35</p>
<button data-id="code35">COPY CODE</button>
</div>

Event when a pair of elements are clicked

I have 5 elements with class .home and unique id's, and a button with class .btn1. When .home is clicked after .btn1 and vice versa, a function should be executed. I don't know what jQuery method i should use.
Try this :
<!DOCTYPE html>
<html>
<head>
<style>
.active {
background-color: skyblue;
}
</style>
</head>
<body>
<div class="home">I am Div1</div>
<div class="home">I am Div2</div>
<div class="home">I am Div3</div>
<div class="home">I am Div4</div>
<div class="home">I am Div5</div>
<button class="btn">Run</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
var divReady = false;
var btnReady = false;
$(".btn").on("click",function(){
btnReady = true;
$(this).addClass("active");
if (divReady)
fun();
})
$("div").on("click",function(){
divReady = true;
$("div").removeClass("active");
$(this).addClass("active");
if (btnReady)
fun();
})
function fun() {
alert("I am working!")
$(".btn,div").removeClass("active");
btnReady = false;
divReady = false;
}
})
</script>
</body>
</html>
I don't think there's a specific jQuery trick for that.
Why not use classes to store state?
$(function() {
$(".home").click(function () {
$(this).addClass("active");
if ($(".btn1").hasClass("active")) {
console.log("Doing something");
}
});
$(".btn1").click(function () {
$(this).addClass("active");
if ($(".home").hasClass("active")) {
console.log("Doing something");
}
}
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class = 'home'>
Home
</div>
<div>
Stuff
</div>
<button class = 'btn1' >Button</button>
<div class = 'home'>
Home
</div>
<div>
Stuff
</div>
<div class = 'home'>
Home
</div>
<div>
Stuff
</div>
<div class = 'home'>
Home
</div>
<div>
Stuff
</div>
Simply count the times an event occured, and store the events. That can be easily done with an Array:
//create an array to store events
events=[];
//create a handler function
function handler(event){
//add the event to our array
events.push(event);
if(events.length==2){
//two events fired:
//first event:
a=events[0];
//second:
b=events[1];
//do whatever
}
}
//add an eventlistener that calls our handler and passes 'documentclick'
document.addEventListener("documentclick",function(){handler("click")});

This is about jquery 'append', i want know why and how to solve it

first, there are codes I wrote.
<body>
add
<div class="panel">
<div class="box"></div>
</div>
<div class="popup">
sure
cancel
</div>
<script>
$(function(){
$('#btn').click(function(){
$('.popup').show();
$('#sure').on('click', function(){
var $box = "<div class='box'></div>";
$('.panel').append($box);
});
$('#cancel').on('click', function(){
$('.popup').hide();
});
});
})
</script>
</body>
then,there are steps i did.
the result
why i click the cancel button at first, and next time i click Sure button, there appears two DIVs actually.I just want one div.
How to solve this problem?
Do not add the event-handler as many times you click on #btn.
Bind click handlers for "sure" and "cancel" out of the click handler for "#btn"
$(function() {
$('#btn').click(function() {
$('.popup').show();
});
$('#sure').on('click', function() {
var $box = "<div class='box'>Added</div>";
$('.panel').append($box);
});
$('#cancel').on('click', function() {
$('.popup').hide();
});
})
.popup {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
add
<div class="panel">
<div class="box"></div>
</div>
<div class="popup">
sure
cancel
</div>
If elements in the pop-up are created dynamically, Use Event delegation
$(function() {
$('#btn').click(function() {
$('.popup').show();
});
$(document).on('click', '#sure', function() {
var $box = "<div class='box'>Added</div>";
$('.panel').append($box);
});
$(document).on('click', '#cancel', function() {
$('.popup').hide();
});
})
.popup {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
add
<div class="panel">
<div class="box"></div>
</div>
<div class="popup">
sure
cancel
</div>

How to add a link to eliminate a set of boxes using ajax

I am having trouble with this code. I am trying to add an eliminate link at the end but I cant seem to eliminate all of the boxes within the set of 5 that appear when I press the add link. I want to be able to delete all the boxes that are within the set of five and nothing else. What I have tried to do is put this line of code at the end of the var box_html5 but it does not work. This is the function that deletes a box I want it to delete the boxes.
Remove
I have tried to make a loop within the statement but it is not coming out right.
I have also thought about making an if statement where the above piece of code would be inside it and state that if that link is pressed then remove box_html1, box_html2, box_html3... etc. For the set of 5 chosen. I have also tried to echo the code like this:
echo ('Remove');
and it still does not seem to work.
<?php
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="//code.jquery.com/jquery-latest.js"></script>
<style type="text/css">
<!--
#main {
max-width: 800px;
margin: 0 auto;
}
-->
</style>
</head>
<body>
<div id="main">
<h1>Movie Night</h1>
<div class="my-form">
<form role="form" method="post">
<p class="text-box">
<label for="box1">Genre<span class="box-number">1</span></label>
<input type="text" name="boxes[]" value="" id="box1" />
<a class="add-box" href="#">Add More</a>
</p>
<p><input type="submit" value="Submit" /></p>
</form>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('.my-form .add-box').click(function(){
var n = $('.text-box').length + 1;
if( 15 < n ) {
alert('Too many. Not enought Time to watch');
return false;
}
var box_html1 = $('<p class="text-box">Movie<input name="mov1" type="text"></p>');
box_html1.hide();
$('.my-form p.text-box:last').after(box_html1);
box_html1.fadeIn('slow');
var box_html2 = $('<p class="text-box">Movie<input name="mov2" type="text"></p>');
box_html2.hide();
$('.my-form p.text-box:last').after(box_html2);
box_html2.fadeIn('slow');
var box_html3 = $('<p class="text-box">Movie<input name="mov3" type="text"></p>');
box_html3.hide();
$('.my-form p.text-box:last').after(box_html3);
box_html3.fadeIn('slow');
var box_html4 = $('<p class="text-box">Movie<input name="mov4" type="text">Remove</p>');
box_html4.hide();
$('.my-form p.text-box:last').after(box_html4);
box_html4.fadeIn('slow');
var box_html5 = $('<p class="text-box">Movie<input name="mov5" type="text"></p>');
box_html5.hide();
$('.my-form p.text-box:last').after(box_html5);
box_html5.fadeIn('slow');
<!--Remove-->
return false;
});
$('.my-form').on('click', '.remove-box', function(){
$(this).parent().css( 'background-color', '#FF6C6C' );
$(this).parent().fadeOut("slow", function() {
$(this).remove();
$('.box-number').each(function(index){
$(this).text( index + 1 );
});
});
return false;
});
});
</script>
</body>
</html>
You need to explore index and slice jquery functions.
Remove action handler in this case:
$('.my-form').on('click', '.remove-box', function(event)
{
var index = $(this).parent().index();
$('.text-box').slice( index - 3, index + 2 ).remove();
event.preventDefault();
});
FIDDLE: http://jsfiddle.net/ejcXd/4/

Categories