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.
Related
I have a working row clone scenario (multiple dynamic rows) after an inventory number is confirmed from mysql database. What I want to do (but can't figure out), is how to insert the inventory data to only the next DIV batch_item_desc which has the same class name as all because of the clone. What keeps happening is the inventory data is inserted to every row, and not "this" row.
HTML :
<div class="multi-field-wrapper">
<div class="multi-fields">
<div class="multi-field row">
<div class="col-md-2 item_num_div">
<div class="form-group">
<input type="text" class="form-control input-sm batch_item_num"
name="item_num[]">
</div>
</div>
<div class="col-md-2 batch_item_desc"></div>
<div class="col-md-2">
<button type="button" class="btn btn-danger remove-field btn-sm">
<span class="glyphicon glyphicon-minus"></span>
</button>
</div>
</div> <!-- End Div multi-field && row -->
</div> <!-- End div multi-fieldS -->
</div> <!-- end div wrapper -->
jQuery:
$('.multi-field-wrapper').each(function() {
var $wrapper = $('.multi-fields', this);
$('.multi-field .remove-field', $wrapper).click(function() {
if ($('.multi-field', $wrapper).length > 1)
$(this).parent('.multi-field').remove();
});
//-------- Batch Inventory --------------
$(".batch_item_num", $(this)).keyup(function(e) {
var item_num = $(this).val();
if (item_num.length == 9) {
$.get('inventory/api.php', {"action":"batch_item_num","item_num":item_num},
function(data, result) {
var desc = data;
$('.item_num_div').next('.batch_item_desc').html(desc);
$('.multi-field:first-child', $wrapper).clone(true).appendTo($wrapper).find('input').val('').focus();
});
}
});
});
I can't for the life of me get this line working to display inventory data for JUST the single row in question, it inserts to all rows.
$('.item_num_div').next('.batch_item_desc').html(desc);
You should use the current jQuery element $(this) instead of the class item_num_div selector that will select all elements with this class :
$(this).next('.batch_item_desc').html(desc);
Also you should go up to the parent row then select the batch_item_desc since it not a sibling of batch_item_num :
$(this).closest('.row').find('.batch_item_desc').html(desc);
Note that the $(this) inside the $.get callback doesn't refer to the current element no more, you should store the $(this) in another variable before the request e.g :
var item_num = $(this).val();
var _this = $(this);
Then use this variable instead of $(this) inside the callback :
_this.closest('.row').find('.batch_item_desc').html(desc);
Hope this helps.
You could use .first() to only select the first element in the set of matched elements:
$('.item_num_div').next('.batch_item_desc').first().html(desc);
I've got the follwoing HTML structure (I do not have the IDs of the following elements because they are dynamically created):
<fieldset>
<div class="classA">
<select onchange="updateInputBox()">
<option>a</option>
<option>b</option>
<option>c</option>
<option>d</option>
</selects>
</div>
<div class="classB">
<input data-myAttribute="case1">
</div>
<div class="classC">
<a type="button">
<i class="fa fa-remove">x</i>
</a>
</div>
</fieldset>
The filedset and it's children is dynamically created. I want to change the attribute in the inputBox depending on what the user selected in the selectBox.
Here is an example how I would have done if the element fieldset would not have been dynamic (the following contains elements have IDs, but only because I want to demonstrate what I want; in reality I don't have IDs because they are dynamically created by clicking a button, that I do not show here):
https://jsfiddle.net/thadeuszlay/6bsgazvv/4/
But unfortunately I don't have the id of the fieldset, because it is dynamically created. Is there a way how you can get the position of the current element?
I tried to pass itself in the updateInputBox-function:
<select id="selectBox" onchange="updateInputBox('+ this +')">
I also tried with jQuery:
$(this).parent().parent()
but in both cases the console would say
"Unexpected identifier"
Update:
Inside the function doing something like this (currentElement is the selectBox/DropDownBox):
currentElement.parent().parent().setAttribute("data-myAttribute", "hello");
Uncaught TypeError: selectBox.parent is not a function
You can use jquery 'closest' for this as below.
HTML
<select id="selectBox" onchange="updateInputBox(this)">
JS
function updateInputBox(selectElm) {
var inputElm = $(selectElm).closest('fieldset').find('input');
inputElm.attr('data-myAttribute', $(selectElm).val());
}
// instead of inline onchange event and the above code, you can use the below to trigger the event
$(document).on('change', 'fieldset select', function () {
var inputElm = $(this).closest('fieldset').find('input');
inputElm.attr('data-myAttribute', $(this).val());
});
In updateInputBox, simply look at the selectedIndex of #selectBox
<select id="selectBox" onchange="updateInputBox(this)">
function
function updateInputBox(dropdowntBox) {
var inputBoxField = document.getElementById("inputBox").setAttribute("data-myAttribute", dropdowntBox.value);
}
Here is jquery version:solution
You need to trigger change() event for select with ID selectBox
$(document).on('change','select',function(){
var value=$(this).val();
$(this).parents('fieldset').find('input').attr('data-myAttribute',value);
});
I'm about lose my mind with this problem. No form of jQuery selector seems to work in dynamically finding any elements above the link. I'm trying to access an element above the link and hide it. Using things like parent(), prev(), before(), closest(), ect. will show a non-null object but it won't respond to the hide() method.
<div class="row">
<div class="col-xs-5">
<div id="test_fields">
<li id="test_input" class="string input optional stringish">
<label class="label" for="test_input">Ingredient name</label>
<input type="text" name="test_input" value="afsfasf" id="test_input">
</li>
</div>
<input type="hidden" id="recipe_recipe_ingredients_attributes_0__destroy" name="recipe[recipe_ingredients_attributes][0][_destroy]">
Remove Ingredient
</div>
</div>
function remove_fields(link)
{
$(link).prev("input[type=hidden]").val('1'); // this doesn't work
var divToHide = $(link).prev('div');
$(divToHide).hide() // this doesn't work
//$('#test_fields').hide(); //this works
}
Try replacing the link as below:
Remove Ingredient
I'm not sure. But maybe this is the problem. Because I remember that I have had problem with 'this'previously and when I replaced that, it performed the job.
you can try .closest() and .find()
function remove_fields(link) {
$(link).closest('div[class^="col-xs"]').find("input[type=hidden]").val('1');
var div_to_hide = $(link).closest('div[class^="col-xs"]').find('#test_fields');
$(div_to_hide).hide();
//$('#test_fields').hide(); //this works
}
You can't change hidden input's "value" attribute by using .val(). You need to use:
$(link).prev("input[type=hidden]").attr('value', '1');
As I'm not really sure what do you want to do with this input, I'll just let it go like this.
.prev() fn goes only one previous element in the structure. As input is a <a>'s previous element, you can't select div like that. You can use .siblings() for instance.
$(link).siblings('div').hide();
If you break the code in pieces, it gets easier.
First I took the 'Link', from it I grabbed the nearest div above it, then I picked up the input.
I did not make many changes to your code.
function remove_fields(link)
{
var $link =$(link);
var $divToHide = $link.closest('div');
$divToHide.find("input[type='hidden']").val('1');
$divToHide.hide()
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="row">
<div class="col-xs-5">
<div id="test_fields">
<li id="test_input" class="string input optional stringish">
<label class="label" for="test_input">Ingredient name</label>
<input type="text" name="test_input" value="afsfasf" id="test_input">
</li>
</div>
<input type="hidden" id="recipe_recipe_ingredients_attributes_0__destroy" name="recipe[recipe_ingredients_attributes][0][_destroy]">
Remove Ingredient
</div>
</div>
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();
});
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/