Clone works just once - javascript

I have a div with class item that I want to clone as many times as the user click on a div with add id
Here is my HTML
<div class="clone">clone me</div>
<div id="add">add</div>
And here is my JavaScript code
$(function(){
var request = $('.clone').clone();
$('.clone:last').addClass('test'); // i don't want my new div have the new added class test just clone
$('#add').click(function () {
console.log('clicked');
request.insertAfter($('.clone:last'));
// $('.item:last').after(request); // this doesn't work as well
});
});
it print to the console clicked as many times as I click on add
But doesn't clone the div more than once
i will be making changes to clone div that don't wanna be done to the new ones

As request refers to same element, move it inside the click handler. Also use :first selector to select the first element.
Use
$('#add').click(function() {
//Create then object the click handler
var request = $('.clone:first').clone();
request.insertAfter($('.clone:last'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clone">clone me</div>
<div id="add">add</div>
If you don't want changes to the original one to affected the new one. Create object as you have created originally. However create a clone() before using .insertAfter()
var request = $('.clone:first').clone();
$('#add').click(function() {
request.clone().insertAfter($('.clone:last'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clone">clone me</div>
<div id="add">add</div>

Put the request inside the function, so that it clones again and again. Right now the request contains only one element and if you are inserting it after (which it is already), there's no effect:
$(function(){
$('#add').click(function () {
var request = $('.clone').clone().removeClass("clone");
console.log('clicked');
request.insertAfter($('.clone:last'));
// $('.item:last').after(request); // this doesn't work as well
});
});

Or you can do same thing without clone.
$(function(){
var request = $('<div class="clone">clone me</div>');
$('#add').click(function () {
console.log('clicked');
request.insertAfter($('.clone:last'));
});
});

There're 2 issue:
You have to put var request = $('.clone:first').clone(); inside.
You need to clone only first div so use $('.clone:first').clone().
Here you go:
$('#add').click(function () {
var request = $('.clone:first').clone();
console.log('clicked');
request.insertAfter($('.clone:last'));
});
JS FIddle DEMO

Related

Is it allowed to use jQuery $(this) selector twice in a function and in an included each loop?

I have a list, which contents x columns of data. When clicking an edit button in a row, I want to set the html content of each column of this row, which has a name attribute into an array, which key is named by the columns name attributes value.
data['id'] = '123';
data['name'] = 'John Doe';
data['city'] = 'Arlington';
For that I'm starting a click event on the edit div. Inside this function I'm working with $(this) selector for setting up an each() loop over all elements having a name attribute.
Inside this loop I'm catching the names and values of each matched element with $(this) selector again.
So, my question: although it works - is it allowed to do it this way? Using $(this) for two different things inside the same function?
Is there a different way?
Here is my working example code
$( document ).ready(function() {
$(document).on( "click", ".edit", function() {
var data = {};
$(this).closest('.row').children('div[name]').each(function() {
//form_data.append($(this).attr('name'), $(this).html());
data[$(this).attr('name')] = $(this).html();
});
$('#result').html(JSON.stringify(data, null, 4));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div name="id">123</div>
<div name="name">John Doe</div>
<div name="city">Berlin</div>
<div class="edit">> edit <</div>
</div>
<br clear="all">
<div id="result"></div>
Is it allowed?
It works, so of course.
Depends on what you mean by "allowed".
Is it confusing - perhaps.
Can it cause problems - definitely.
(There are plenty of questions on SO with this or problems caused by this that confirm it causes problems).
Reusing variable names ('this' in this case) is common and is based on scope.
It's hard to tell if you have a bug because you actually wanted the ".edit" html or the ".edit" attr rather than the div, so you can remove that confusion by copying this to a variable:
$(document).on( "click", ".edit", function() {
var data = {};
var btn = $(this); // the button that was clicked
btn.closest('.row').children('div[name]').each(function() {
// Do you mean the div or did you really mean the clicked button?
data[$(this).attr('name')] = $(this).html();
var div = $(this); // the child div
// clearly not what is desired
// `btn` variable referring to the outer `this`
data[div.attr('name')] = btn.html();
// intention clear
data[div.attr('name')] = div.html();
});
$('#result').html(JSON.stringify(data, null, 4));
});
In this case, it's "clear" as you wouldn't use the btn html on all the data entries (or would you? I don't know your requirements...). So "unlikely".
But it's easy to see how, in another scenario, you would want to refer to what was clicked btn==this inside the nested .each.
Try this trick:
$( document ).ready(function() {
$(document).on( "click", ".edit", function() {
var data = {};
var that = this; // trick here
$(this).closest('.row').children('div[name]').each(function() {
//form_data.append($(this).attr('name'), $(this).html());
data[$(this).attr('name')] = $(that).html();// replace this = that if you want to get parent element
});
$('#result').html(JSON.stringify(data, null, 4));
});
});
there is nothing wrong, what you do is simply this
function setDivs() {
//form_data.append($(this).attr('name'), $(this).html());
data[$(this).attr('name')] = $(this).html();
}
function docClick(){
var data = {};
$(this).closest('.row').children('div[name]').each(setDivs);
$('#result').html(JSON.stringify(data, null, 4));
}
function docReady(){
$(document).on( "click", ".edit", docClick)
}
$( document ).ready(docReady);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div name="id">123</div>
<div name="name">John Doe</div>
<div name="city">Berlin</div>
<div class="edit">> edit <</div>
</div>
<br clear="all">
<div id="result"></div>

jQuery: add click event to specific id

I have a small jquery problem:
My code is like this:
<div id="select-word-5" class="select-word-link"> - some content - </div>
<div id="select-5" class="select"> - some content - </div>
I have throughout my document several select-word-link and select divs.
I want to add a click event to the first div, that reacts just to the second div.
My idea was to loop through all the "select-x" elements, but i think there is a much better way?
$('.select-word-link').each(function()
{
var id = this.id;
var idLink = this.id.replace("-word", "");
$('.select').each(function()
{
if (idLink == this.id)
{
$(id).click(function() {
alert("this does not work");
});
});
});
You can do this easier by triggering an action on an event.
$('#select-5').click(function(){
alert('Does this work?');
});
$('.select-word-link').click(function(){
$('#select-5').trigger('click'); // will behave as if #select-5 is clicked.
});
Info: http://api.jquery.com/trigger/
More advanced:
$('#select-5').click(function(){
alert('Does this work?');
});
$('#select-6').click(function(){
alert('Does this work?');
});
// etc
$('.select-word-link').click(function(){
var selectId = this.id.replace('-word', '');
$('#'+selectId).trigger('click'); // will behave as if #select-5 is clicked.
});
maybe this code help you
$(".select-word-link").click(function(){
$(this).next().hide();
});
});
try
$('.select-word-link').first().on('click',function(){
// you code goes here
})
jQuery as CSS uses # selector to identify that this string is an Id.
e.g.
<div id="someId"></div>
and you execute this code:
$('#someId')
this will select the DOM object that has the Id someId
while id property returns the id of the DOM object without the selector # i.e. this jQuery code:
var id = $('#someId').get(0).id
will initialize the variable id to 'someId'
Thus, in your code add '#' in the selector
$('#' + id).click(function() {
alert("this does not work");
});
You have to trigger click next() element not all .select
$(".word").click(function() {
var selectId = this.id.replace('-word', '');
console.log(selectId);
$('#'+selectId).trigger('click');
});
$(".next").click(function() {
alert($(this).html());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="select-word-5" class="select-word-link word">- some content 5-</div>
<div id="select-word-6" class="select-word-link word">- some content 6-</div>
<div id="select-word-7" class="select-word-link word">- some content 7-</div>etc.
<div id="select-5" class="select-word-link next">- some content next 5-</div>
<div id="select-6" class="select-word-link next">- some content next 6-</div>
<div id="select-7" class="select-word-link next">- some content next 7-</div>
very simple solution
$('#select-5 , .select-word-link').click(function () {
// your code
});
If you want trigger same functionality from 2 or more different div ids or classes or combination of both then put separated by , like '#select-5 , .select-word-link' as shown in above example.

How to decide which element is being clicked in jQuery?

I have more similar elements in HTML which are being added continously with PHP. my question is the following:
With jQuery, I would like to add a click event to each of these <div> elements. When any of them is being clicked it should display it's content. The problem is that I guess I need to use classes to specify which elements can be clickable. But in this case the application will not be able to decide which specific element is being clicked, right?
HTML:
<div class="test">1</div>
<div class="test">2</div>
<div class="test">3</div>
<div class="test">4</div>
<div class="test">5</div>
jQuery try:
$("test").on("click", function()
{
var data = ???
alert(data);
});
UPDATE - QUESTION 2:
What happens if I'm placing <a> tags between those divs, and I want to get their href value when the DIV is being clicked?
I always get an error when I try that with this.
this refers to the element triggering the event. Note that it is a regular js element, so you'll need to convert it to a jQuery object before you can use jQuery functions: $(this)
$(".test").on("click", function()
{
var data = $(this).text();
alert(data);
});
Like this:
$(".test").on("click", function(event)
{
var data = $(event.target);
alert(data.text());
});
this variable contains the reference of current item
$(document).ready(function() {
$(".test").click(function(event) {
var data = $(this).text();
alert(data);
});
})
;
The class selector in jquery is $(".ClassName") and to access the value, use $(this) as such:
$(".test").on("click", function(){
var data = $(this).text();
alert(data);
});
You can use this inside the function which mean clicked div
DEMO
$(".test").on("click", function () {
alert($(this).html());
});

jquery Multiple alerts

How can i count element once?
Right now, evert time, when i click #totalItems, alert is rised as many times, as many element are in #photoId ?
<script type="text/javascript">
$(document).ready(function(){
photoId = $('.photoId');
totalItems = $('#totalItems');
$(photoId).on('click', function(){
//alert ($(this).html());
$(this).clone().appendTo(totalItems);
$('#count').on('click', function(e){
sizes = (totalItems.children().size());
alert (sizes);
});
$('#count').off('click', function(e){
sizes = (totalItems.children().size());
alert (sizes);
});
});
});
</script>
Replace this line :
$(photoId).on('click', function(){
By :
photoId.on('click', function(){
You are attaching $('#count').on('click', function() { ... handler on every click on .photoId. Make sure it is only done once from within the document's ready event.
In case your #count is actually inside the DOM being cloned, you need to
get rid of ID and replace it with class.
bind event to the top level container with CSS filter
I.e. something like this:
$("#totalItems").on("click", ".count", function() { ...

Jquery append input element and send data from that input element

I have this simple HTML code:
<div id="new_gallery">
<p id="add_gallery">Add new gallery</p>
</div>
and jQuery code:
<script>
$("#add_gallery").click(function() {
$("#new_gallery").append('<input name"new_gallery" />Add');
$(this).remove();
});
$("#create_new_gallery").on('click', function(){
alert('1');
});
</script>
First function is working, but second one is not. I need to create new input element, send data via ajax, and then delete the input element and append a p element once again. How can I do this?
When the second statement runs, the element #create_new_gallery does not exist yet so it does nothing.
You can do the binding to the click event after you created the element for instance, this ensures the element exists in the DOM:
$("#add_gallery").click(function() {
$("#new_gallery").append('<input name="new_gallery" />Add');
$(this).remove();
$("#create_new_gallery").on('click', function() {
alert('1');
});
});​
DEMO
Here is a little bit more optimized version. It's a bit non-sense to append an element and have to re-query for it (event though querying by id is the fastest method. Besides, it's best to use the chaining capabilities of jQuery afterall:
$("#add_gallery").click(function() {
var $gallery = $("#new_gallery");
$('<input name="new_gallery" />').appendTo($gallery);
$('Add')
.on('click', function() {
alert('1');
})
.appendTo($gallery);
$(this).remove();
});​
DEMO
#create_new_gallery doesn't exist when you bind its click event.
Here is what your code should look like:
$("#add_gallery").click(function() {
var newG = $("#new_gallery");
$('<input name"new_gallery" />').appendTo(newG);
$('Add').appendTo(newG).on('click',
function() {
alert('1');
});
$(this).remove();
});
Notice that getting $("#new_gallery") into a variable avoid to look for it twice.
$(document).ready(function () {
$("#add_gallery").click(function() {
$("#new_gallery").append('<input name"new_gallery" />Add');
$(this).remove();
$("#create_new_gallery").on('click', function(){
alert('1');
});
});
});
DEMO: http://jsfiddle.net/39E4s/2/
​
Try live to handle the events fired for elements added after the page has loaded.
$("#create_new_gallery").live('click', function(){
alert('1');
});
http://api.jquery.com/live/

Categories

Resources