This is what I have right now. I'm trying to add fields to the form dynamically using jQuery add() and append() method. But I want to remove the particular added field when the remove button is clicked.
<div class="col-md-12">
<h3>Added Description Fields</h3>
<div class="col-md-12" id="descFields">
</div>
</div>
JS
$(document).ready(function() {
console.log(descFields);
$('#addDesc').click(function(e) {
var descFields = $('#descFields');
var descLabel = $('#descLabel').val();
var large = '<div class="form-group" id="descField"><div class="input-group"><input type="text" class="form-control" placeholder="Enter Value For ' + descLabel + '" /><span class="input-group-btn"><button class="btn btn-danger" id="removeDesc" type="button">Remove</button></span></div>';
descFields.add(large).appendTo(descFields);
e.preventDefault();
});
$('#removeDesc').click(function(e) {
$(this).remove();
});
});
When the user click on the #removeDesc button , the the field that is added should be removed. I cannot figure out how to achieve this.
There are many ways of doing this, but the simpler for your problem is this one:
$(document).ready(function() {
console.log(descFields);
$('#addDesc').click(function(e) {
var descFields = $('#descFields');
var descLabel = $('#descLabel').val();
var large = '<div class="form-group" id="descField"><div class="input-group"><input type="text" class="form-control" placeholder="Enter Value For ' + descLabel + '" /><span class="input-group-btn"><button class="btn btn-danger" id="removeDesc" type="button">Remove</button></span></div>';
descFields.add(large).appendTo(descFields);
e.preventDefault();
});
$('#descFields').on('click', '#removeDesc', function(e) {
$(this).parents('.form-group').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="descLabel"/>
<button id="addDesc">Add Desc</button>
<div class="col-md-12">
<h3>Added Description Fields</h3>
<div class="col-md-12" id="descFields">
</div>
</div>
Your problem is in the callback to delete the rows. When the document has finished loading you are trying to attach a click event to an object #removeDesc that is still not present in the DOM because it's created on the fly when the user clicks the #addDesc.
That's why you should use:
$('#descFields').on('click', '#removeDesc', function(e) {
$(this).parents('.form-group').remove();
});
As #vijayP suggested before you can use the on() to attach an event handler to the container where you'll be adding the object that is still not present in the DOM. Then you pass in the query selector as the second parameter to filter in execution time which of its children will trigger the event and execute the callback.
My additional trick is that I'm using .parents('.form-group') to select the div containing the group and remove all of the fields that were added instead of removing only the button.
Happy coding!
Add click event for remove button like follows:
$(document).on("click","#removeDesc",function(e) {
$(this).remove();
});
Related
I tried to get value from input text with jQuery, but I only got the first value. Input text is looped.
Here's the HTML:
<div class="item-container-add">
#foreach($cartCollection as $cart)
#if($cart['name'] != 'asdfghjklkjgfds123890')
<div class="row row-add mr-1">
<div class="col-sm-6">
<input type="text" class="id_delete" name="id_delete" id="id_delete" value="{{ $cart['id'] }}">
</div>
<div class="col-sm-2 border-cart">
<button class="btn btn-del delete_button" name="delete_button" type="submit">Hapus<img class="icon-delete" src="./svg/delete.svg"></button>
</div>
</div>
#endif
#endforeach
</div>
From those HTML, I've got 4 different IDs with their own delete button. When I try to click Delete, my jQuery function only get the first ID from those loop. It is supposed to get the ID where I click the button. Here's my jQuery function:
$(document).on('click', '.delete_button', function(e) {
var a = $("#id_delete").val();
alert(a);
$.ajax({
/* some ajax function */
});
});
Image reference: https://imgur.com/mX1WHwM
Firstly you need to remove the id attributes from the HTML elements you create in the loop. id values must be unique within the DOM. Use the common classes on the elements to select them instead.
The reason for your problem is because in the click event handler you're selecting the element by its id. As this is a duplicate, only the first element with that id is found, hence you only ever get the first value. To address this you can use the this keyword in the click event handler to refer to the element which raised the event. Then you can use DOM traversal methods, such as closest() and find(), to retrieve the value from the related field. Try this:
<div class="item-container-add">
#foreach($cartCollection as $cart)
#if($cart['name'] != 'asdfghjklkjgfds123890')
<div class="row row-add mr-1">
<div class="col-sm-6">
<input type="text" class="id_delete" name="id_delete" value="{{ $cart['id'] }}">
</div>
<div class="col-sm-2 border-cart">
<button class="btn btn-del delete_button" name="delete_button" type="submit">Hapus<img class="icon-delete" src="./svg/delete.svg"></button>
</div>
</div>
#endif
#endforeach
</div>
$(document).on('click', '.delete_button', function(e) {
var a = $(this).closest('.row').find('.id_delete').val();
console.log(a);
});
Firstly, ID needs to be unique. You can refactor your code as below.
$(document).on('click', '.delete_button', function(e) {
var val = $(this).val();
var id = $(this).attr('id');
console.log(val, id);
});
$(document).on('click', '.delete_button', function(e) {
var a = $(this).closest('.row').find('input.id_delete').val();
console.log(a);
});
That takes the button you clicked, this, and finds the nearest ancestor matching .row, looks through the descendants to find the matching input.
I have the following HTML :
<button type="button" id="Button">Go</button>
<div id="validation"></div>
I'm trying to add event handlers to dynamically generated elements in the following way :
Click button -> Generate element X inside div #validation -> Attach event handler to element X
$(document).ready(function(){
ID = 1;
$("#Button").click(function(){
/*generate new div inside div #validation with id #validationID
1st one would be #validation1
it contains a form with name accepterID and a button with name refuserID
1st ones would be accepter1 and refuser1*/
var newline = `
<div id="validation${ID}">
<form name="accepter${ID}">
<input type="hidden" name="name" value="phoegasus">
<button type="submit" value="valider">
</form>
<button name="refuser${ID}">refuser</button>
</div>
`
$("#validation").append(newline);
/*attach event handlers to the generated elements
1st iteration would attach handlers to accepter1 and refuser1 */
$("#validation").on('submit',"form[name^='accepter"+ID+"']",function(e){
$("#validation" + ID).remove();
//remove div validationID after submitting form
});
$("#validation").on('click',"button[name^='refuser"+ID+"']",function(){
$("#validation" + ID).remove();
//remove div validationID
});
ID++;
});
});
When I submit the form or I click the generated button I want to remove the div that contains them. If I press the button refuser1, it should delete the div #validation1.
When the elements are generated the handlers aren't attached to them.
The code doesn't work when it's executed during the onclick event but when I execute it in the navigator console it works.
I tried using DOMSubtreeModified on the div with id #validation, but it didn't work.
you can manage it by using a class (or another element) in second argument of your on function.
For that, DO NOT declare your event listeners inside your add event.
This is a full working example :
$("#validation").on('submit',"form.validation-form",function(e){
e.preventDefault();
console.log('form', $(this).attr('data-id'), ' submitted');
});
$("#validation").on('click',"button.validation-refuser",function(){
console.log('clicked on refuser for form ', $(this).attr('data-value'));
//code
});
var ID = 1;
$('#my-adder').on('click', function () {
$('#validation').append('<form name="accepter'+ID+'" class="validation-form" data-id="'+ID+'"><input type="text" placeholder="my text field" /><button class="validation-refuser" name="refuser'+ID+'" data-value="'+ID+'">Refuser button</button><button type="submit">SUBMIT</button></form>');
ID++;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="validation">
<form name="accepter0" class="validation-form" data-id="0">
<input type="text" placeholder="my text field" />
<button type="button" class="validation-refuser" name="refuser0" data-value="0">Refuser button</button>
<button type="submit">SUBMIT</button>
</form>
</div>
<button id="my-adder">ADD A FORM</button>
Hope it helps
I am attempting to use jQuery to add the dynamic form elements to my page. At the moment I can get one of my form elements to be added when the user clicks the button but the second element isn't being added alongside it.
I do this by appending some html to divs with a specific class when a button is clicked.
I have created a JSfiddle. As you can see the 'ingredient' part is working, however the quantities is not.
https://jsfiddle.net/fe0t3by2/
$('.recipe-ingredients #addNewIngredient').on('click', function () {
var i = $('.recipe-ingredients .ingredient').size() + 1;
$('<div class="form-group ingredient"><label class="control-label" for="searchinput">Ingredients</label><div><input id="ingredient_' + i + '" name="ingredients[]" type="text" placeholder="Ingredients" class="form-control input-md"></div></div>Add Ingredient</div>').appendTo($('.recipe-ingredients .ingredients'));
$('<div class="form-group"><label class="control-label" for="buttondropdown">Quantity</label><div class="input-group"><input id="quantity_' + i + '" name="quantity[]" class="form-control" placeholder="Quantity" type="text"><div class="input-group-btn"><button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Measure<span class="caret"></span></button><ul class="dropdown pull-right"><li>Grams</li><li>Ounces</li><li>Option three</li></ul></div></div>').appendTo($('.recipe-quantities .quantities'));
});
Thank you
You have misspelled the 'recipe-quantities' class on your quantities div.
<div class="col-md-6 recipe-quantites">
changed to
<div class="col-md-6 recipe-quantities">
At the moment I can get one of my form elements to be added when the user clicks the button but the second element isn't being added alongside it.
With dynamically added content you should delegate the click to the document for example (something where the object is contained in).
jQuery documentation .on()
$(document).on('click', '.recipe-ingredients #addNewIngredient', function () {
JSFiddle demo
I'm attempting to create a todo list app in HTML, CSS, and jQuery, and I'd like to be able to add, edit, and delete tasks. I'm able to add new tasks to the list, but I'm unable to edit or delete them when I click the "Edit" and "Delete" buttons, and I'm not sure why it isn't working.
I've uploaded a copy of my code to jsfiddle (https://jsfiddle.net/LearningToCode/nndd1byt/6/) and included a copy below.
Any help you can offer would be greatly appreciated. Thanks!
Expected Behavior:
Clicking the "Delete" button next to a task should allow a user to delete that task.
Clicking the "Edit" button next to a task should allow a user to edit the text of that task.
Actual Behavior:
Clicking the "Delete" button does nothing.
Clicking the "Edit" button does nothing.
Code Examples:
HTML
<h1>Todo List</h1>
<input type="text" id="enter_task" placeholder="Enter Task">
<input type="submit" id="add" value="Add Task">
<p>
<ul id="todo_list">
</ul>
</p>
JavaScript
function enter_task () {
var text = $('#enter_task').val();
$('#todo_list').append('<li>'+ text + ' <input type="submit" id="edit" value="Edit">' + '<input type="submit" class="done" id="delete" value="Delete">' +'</li>');
};
$('#edit').click(function(){
$('li').attr('contenteditable','true');
});
$('#delete').click(function(){
$('li').remove();
});
$(function() {
$('#add').on('click', enter_task);
});
The problem is that your delete buttons are dynamically created. During page load, $('#delete') returns an empty set because there's no one there yet. When you finally have list items, their delete buttons are not bound to anything.
What you can do is delegate the event handler to an ancestor that exists during page load. Events "bubble" to its ancestors, making ancestors aware that you clicked a descendant. In this case, you can attach the handler to <ul>, and have it listen for clicks on .delete.
In addition, IDs are supposed to be unique. You can only have one of them on the page. Having more than one might lead to unpredictable behavior. Use classes instead.
Also, $('li') will select all <li> on the page. You might want to scope down your selection. You can remove the <li> containing your button using $(this).closest('li').remove()
The code you need should be this, plus add delete as the button class. Apply the same concept for the edit.
$('#todo_list').on('click', '.delete', function(){
$(this).closest('li').remove()
});
I've created a working example - https://jsfiddle.net/nndd1byt/7/
function enter_task () {
var text = $('#enter_task').val();
$('#todo_list').append('<li>'+ text + ' <input type="submit" class="edit" value="Edit">' + '<input type="submit" class="done delete" value="Delete">' +'</li>');
};
$('#todo_list').on('click', '.edit', function(){
$(this).parent().attr('contenteditable','true');
});
$('#todo_list').on('click', '.delete',function(){
$(this).parent().remove();
});
$(function() {
$('#add').on('click', enter_task);
});
Try adding the jquery function initializers into the enter_task function, this way they are refreshed with each new line.
var counter = 1;
function enter_task () {
var text = $('#enter_task').val();
$('#todo_list').append('<li><span>'+ text + ' </span><input type="submit" id="edit' + counter + '" value="Edit">' + '<input type="submit" class="done" id="delete' + counter + '" value="Delete">' +'</li>');
$('#edit' + counter).click(function(){
$(this).prev().attr('contenteditable','true');
$(this).prev().focus();
});
$('#delete' + counter).click(function(){
$(this).parent().remove();
});
counter++;
};
$(function() {
$('#add').on('click', enter_task);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Todo List</h1>
<input type="text" id="enter_task" placeholder="Enter Task">
<input type="submit" id="add" value="Add Task">
<p>
<ul id="todo_list">
</ul>
</p>
Hello guys i have the below html for a number of products on my website,
it displays a line with product title, price, qty wanted and a checkbox called buy.
qty input is disabled at the moment.
So what i want to do is,
if the checkbox is clicked i want the input qty to set to 1 and i want it to become enabled.
I seem to be having some trouble doing this. Could any one help
Now i can have multiple product i.e there will be multiple table-products divs within my html page.
i have tried using jQuery to change the details but i dont seem to be able to get access to certain elements.
so basically for each table-product i would like to put a click listener on the check box that will set the value of the input-text i.e qty text field.
so of the below there could be 20 on a page.
<div class="table-products">
<div class="table-top-title">
My Spelling Workbook F
</div>
<div class="table-top-price">
<div class="price-box">
<span class="regular-price" id="product-price-1"><span class="price">€6.95</span></span>
</div>
</div>
<div class="table-top-qty">
<fieldset class="add-to-cart-box">
<input type="hidden" name="products[]" value="1"> <legend>Add Items to Cart</legend> <span class="qty-box"><label for="qty1">Qty:</label> <input name="qty1" disabled="disabled" value="0" type="text" class="input-text qty" id="qty1" maxlength="12"></span>
</fieldset>
</div>
<div class="table-top-details">
<input type="checkbox" name="buyMe" value="buy" class="add-checkbox">
</div>
<div style="clear:both;"></div>
</div>
here is the javascript i have tried
jQuery(document).ready(function() {
console.log('hello');
var thischeck;
jQuery(".table-products").ready(function(e) {
//var catTable = jQuery(this);
var qtyInput = jQuery(this).children('.input-text');
jQuery('.add-checkbox').click(function() {
console.log(jQuery(this).html());
thischeck = jQuery(this);
if (thischeck.is(':checked'))
{
jQuery(qtyInput).first().val('1');
jQuery(qtyInput).first().prop('disabled', false);
} else {
}
});
});
// Handler for .ready() called.
});
Not the most direct method, but this should work.
jQuery(document).ready(function() {
jQuery('.add-checkbox').on('click', function() {
jQuery(this)
.parents('.table-products')
.find('input.input-text')
.val('1')
.removeAttr('disabled');
});
});
use
jQuery('.add-checkbox').change(function() {
the problem is one the one hand that you observe click and not change, so use change rather as it really triggers after the state change
var qtyInput = jQuery(this).children('.input-text');
another thing is that the input is no direct child of .table-products
see this fiddle
jQuery('input:checkbox.add-checkbox').on('change', function() {
jQuery(this)
.parent()
.prev('div.table-top-qty')
.find('fieldset input:disabled.qty')
.val(this.checked | 0)
.attr('disabled', !this.checked);
});
This should get you started in the right direction. Based on jQuery 1.7.2 (I saw your prop call and am guessing that's what you're using).
$(document).ready(function() {
var thischeck;
$('.table-products').on('click', '.add-checkbox', function() {
var qtyInput = $(this).parents('.table-products').find('.input-text');
thischeck = $(this);
if (thischeck.prop('checked')) {
$(qtyInput).val('1').prop('disabled', false);
} else {
$(qtyInput).val('0').prop('disabled', true);
}
});
});
Removing the property for some reason tends to prevent it from being re-added. This works with multiple tables. For your conflict, just replace the $'s with jQuery.
Here's the fiddle: http://jsfiddle.net/KqtS7/5/