I'm trying to find the next closest input to my element, Get its value and remove a string from it.
The value that I need to remove is a data-id of the element thats been clicked on.
Ive tried the following but this throws an error in the console which means it cannot find the input:
$(document).on('click', '.deletImg', function() {
var id = $(this).attr('data-id');
$('[data-id="' + id + '"]').remove();
var $this = (this);
var removeValue = function(list, value, separator) {
separator = separator || ",";
var values = list.split(separator);
for (var i = 0; i < values.length; i++) {
if (values[i] == value) {
values.splice(i, 1);
return values.join(separator);
}
}
return list;
}
var inp = $($this).parents().eq(1).find(".input").val();
inp = removeValue(inp, id);
$($this).parents().eq(1).find(".input").val(inp);
});
.addedImg {
width: 100px;
height: 100px;
position: relative;
display: inline-block;
margin-right: 12px;
}
.imgHolder {
height: auto;
overflow-y: hidden;
overflow-x: scroll;
min-width: 1000px;
width: auto;
}
.myBlock {
overflow-y: hidden;
overflow-x: scroll;
margin-bottom: 10px;
}
.addedImg img {
width: 100%;
border-radius: 4px;
}
.deletImg {
position: absolute;
width: 25px;
height: 25px;
text-align: center;
line-height: 25px;
background: black;
color: white;
top: 10px;
right: 10px;
border-radius: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="row" style="margin-bottom:10px;"></div>
<div class="block block-strong myBlock">
<div class="imgHolder">
<div data-id="dd" class="addedImg">
<div class="deletImg" data-id="dd">X</div><img class="tappableImg" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Test-Logo.svg/783px-Test-Logo.svg.png"></div>
</div>
</div>
<input type="text" class="input" value="22,44,66,99,dd" />
Can someone please advice on this?
$($this).parents().eq(1) is the .imgHolder div. .input isn't a descendant of that div, so $($this).parents().eq(1).find(".input") doesn't find anything.
.input isn't contained in any of the same containers as .deletImg. It's the next element after the .myBlock container, so use $(this).closest(".myBlock").next().val() to get the input's value.
Also, you have to move the .remove() call to the end. You're removing the element that contains $(this), so you can't find the container after it's disconnected from the DOM.
$(document).on('click', '.deletImg', function() {
var id = $(this).attr('data-id');
var removeValue = function(list, value, separator = ",") {
var values = list.split(separator);
let index = values.indexOf(value);
if (index != -1) {
values.splice(index, 1);
return values.join(separator);
}
return list;
}
var inp = $(this).closest(".myBlock").next().val();
inp = removeValue(inp, id);
$(this).closest(".myBlock").next().val(inp);
$('[data-id="' + id + '"]').remove();
});
.addedImg {
width: 100px;
height: 100px;
position: relative;
display: inline-block;
margin-right: 12px;
}
.imgHolder {
height: auto;
overflow-y: hidden;
overflow-x: scroll;
min-width: 1000px;
width: auto;
}
.myBlock {
overflow-y: hidden;
overflow-x: scroll;
margin-bottom: 10px;
}
.addedImg img {
width: 100%;
border-radius: 4px;
}
.deletImg {
position: absolute;
width: 25px;
height: 25px;
text-align: center;
line-height: 25px;
background: black;
color: white;
top: 10px;
right: 10px;
border-radius: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="row" style="margin-bottom:10px;"></div>
<div class="block block-strong myBlock">
<div class="imgHolder">
<div data-id="dd" class="addedImg">
<div class="deletImg" data-id="dd">X</div><img class="tappableImg" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Test-Logo.svg/783px-Test-Logo.svg.png"></div>
</div>
</div>
<input type="text" class="input" value="22,44,66,99,dd" />
You can take a list of all elements in the DOM traversed in a DFS way and find nearest input regardless to the hierarchical position in the tree.
document.addEventListener('click', evt => {
const id = evt.target.getAttribute('data-id');
// Apply logic only if clicked element has 'data-id' attribute
if (id) {
// Convert HTMLAllCollection to Array to use indexOf, slice and find
const all = Array.from(document.all);
// Index of clicked element
const idx = all.indexOf(evt.target);
// The "closest" input would be the next input in the plain
// list of all elements after the clicked element
const input = all.slice(idx).find(el => el.tagName === 'INPUT');
// Remove data-id from input value
const value = input.value.split(',').reduce((acc, cur) => {
if (cur !== id) {
acc.push(cur);
}
return acc;
}, []).join(',');
input.value = value;
// Remove clicked element
evt.target.remove();
}
});