jQuery find the first attribut before an element - javascript

I have the following structure:
<tr data-commercial="commercial_8">
<td class="tdCommercial">
Mister X
<h4>Planning</h4>
<ul>
<li data-day="Monday">
<i class="fa fa-plus-square fa-1"></i>
<i class="fa fa-minus-square fa-1"></i>
Lundi
<span class="number">2</span>
</li>
<li data-day="Tuesday">
<li data-day="Wednesday">
<li data-day="Thursday">
<li data-day="Friday">
</ul>
</td>
<td class="Monday"></td>
<td class="Tuesday"></td>
<td class="Wednesday"></td>
<td class="Thursday"></td>
<td class="Friday"></td>
<td class="Saturday"></td>
<td class="Sunday"></td>
</tr>
With jQuery, I am using an onClick event with the element <i class="fa fa-plus-square fa-1"></i>.
What is the best way to retrieve the data-commercial attribute on the first tr from this element ?
The structure can change, so I need something like "find the first data-commercial attribute before myElement"
Thanks !

Use .closest()
For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
Example:
var commercial = $(this).closest('tr').data('commercial');
Note: Provided this refers to element <i class="fa fa-plus-square fa-1"></i>

$('#myElement').closest('tr').attr('data-commercial');

Use closest:
$(this).closest('tr').data('commercial');

$(this).parents("tr").data("commercial")

Use .closest() in jquery
$(this).closeset('tr').data('commercial');

Related

Get innerHtml by data-id

I have many <li> with specific data-id, want to get innerHtml of first <Div>
For Example on this sample, it would to be: "World"
<li class="dd-item" data-id="1123066248731271" data-slug="" data-new="1" data-deleted="0"><div class="dd-handle">World</div> <span class="button-delete btn btn-danger btn-xs pull-right" title="Delete" data-owner-id="1123066248731271"> <i class="fa fa-times" aria-hidden="true"></i> </span><span class="button-edit btn btn-success btn-xs pull-right" title="Edit" data-owner-id="1123066248731271"><i class="fa fa-pencil" aria-hidden="true"></i></span></li>
This is my code, that doesn't help:
var target = $('[data-id="1123066248731271"]');
alert(target.firstChild.innerHTML);
document.querySelector('[data-id="1123066248731271"]').textContent
Maybe this is what you need?
Being a jquery element, you can use find() method to find all the div elements inside him, with first(), you get the first element, finally, with html(), you get its content.
var target = $('[data-id="1123066248731271"]');
alert(target.find('div').first().html());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="dd-item" data-id="1123066248731271" data-slug="" data-new="1" data-deleted="0"><div class="dd-handle">World</div> <span class="button-delete btn btn-danger btn-xs pull-right" title="Delete" data-owner-id="1123066248731271"> <i class="fa fa-times" aria-hidden="true"></i> </span><span class="button-edit btn btn-success btn-xs pull-right" title="Edit" data-owner-id="1123066248731271"><i class="fa fa-pencil" aria-hidden="true"></i></span></li>
first problem $('[data-id="1123066248731271"]') returned a object of all elements with [data-id="1123066248731271"]. for target the first element, you need add [0] after : $('[data-id="1123066248731271"]')[0]
now if you want target the div element you need specify div into $ like: $('[data-id="1123066248731271"] div')[0]. Now you got the first div and you can get innerHTML with : target.innerHTML
The full code :
var target = $('[data-id="1123066248731271"] div')[0];
alert(target.innerHTML);
and without Jquery ( more simply i think ) :
var target = document.querySelector('[data-id="1123066248731271"] div');
alert(target.innerHTML);
Perhaps you want to use firstElementChild instead of firstChild?
Or you could use the CSS selector [data-id="1123066248731271"] > div:first-child:
var target = $('[data-id="1123066248731271"] > div:first-child');
alert(target.innerHTML);
Edit:
I noticed a translation error. I don't use jQuery myself, so instead of $ I used document.querySelector. But the behavior of $ corresponds to document.querySelectorAll instead. Sorry...
This should work fine:
var target = $('[data-id="1123066248731271"] > div:first-child')[0];
alert(target.innerHTML);
or this:
var target = document.querySelector('[data-id="1123066248731271"] > div:first-child');
alert(target.innerHTML);
As a non-jQuery user, I personally prefer the latter.

How to change data attribute of adjacent td in jQuery?

I have a code like this with two td columns , if i click on the fa icon
<i class="fa pad5 fa-unlock-alt" ></i>
then i need to change the data-invoice-lock="0".
i tried this
$(this).closest('td').find('.invoiceCostCol').attr('data-invoice-lock','0');
but not getting the result
INPUT
<td rowspan="1" class="reportSmallWd invoiceCostCol" data-invoice-lock="1"></td>
<td rowspan="1" class="reportSmallWd">
<i class="fa pad5 fa-unlock-alt" ></i>
</td>
The OUTPUT required
<td rowspan="1" class="reportSmallWd invoiceCostCol" data-invoice-lock="0"></td>
<td rowspan="1" class="reportSmallWd">
<i class="fa pad5 fa-unlock-alt" ></i>
</td>
The closest of target td is tr. You should change closest('td') to closest('tr'). The code should changed to
$(this).closest('tr').find('.invoiceCostCol').attr('data-invoice-lock','0');
Or use
$(this).parent().prev().attr('data-invoice-lock','0');
If structure of your html is constant.
Try this:
$(this).closest('tr').find('.invoiceCostCol').removeAttr('data-invoice-lock').attr('data-invoice-lock','0');
Well in general you need to find the closest tr and then find your element within this tr.
However I wrote this additional answer to call your attention to the data() method in jQuery. With this method you can manipulate data attributes in your elements like setting and getting values. Why is this often times "better" than using attr() or prop()?
Short answer:
Using data() you can return a JavaScript object that can contain lots of keys and values and it is much easier to process. However when you use data() instead of attr() you won't actually see the change of a value in your browser inspector. But just use console.log() to show the actual value and you'll see it is changes.
The fiddle below features both methods for testing, however attr() is commented out at the moment. Just play with it and see how it works.
Here you go with the working fiddle:
$(function(){
$('i.fa-unlock-alt').on('click', function(){
$(this).closest('tr').find('td.invoiceCostCol').data('invoice-lock','0');
//$(this).closest('tr').find('td.invoiceCostCol').attr('data-invoice-lock','0');
console.log($('td.invoiceCostCol').data('invoice-lock'));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<table>
<tr>
<td rowspan="1" class="reportSmallWd invoiceCostCol" data-invoice-lock="1">
</td>
<td rowspan="1" class="reportSmallWd">
<i class="fa pad5 fa-unlock-alt" ></i>
</td>
</tr>
</table>
You can also user data in place of attr :
$(this).closest('tr').find('.invoiceCostCol').data('invoice-lock', '0');
Here is working example:
$('.pad5').click(function() {
$(this).closest('tr').find('.invoiceCostCol').data('invoice-lock', '0');
alert($(this).closest('tr').find('.invoiceCostCol').data('invoice-lock'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<table>
<tr>
<td rowspan="1" class="reportSmallWd invoiceCostCol" data-invoice-lock="1">
</td>
<td rowspan="1" class="reportSmallWd">
<i class="fa pad5 fa-unlock-alt"></i>
</td>
</tr>
</table>

Take the value of a child element

I have this structure:
<td class=​"prd-var-price">
​<div class=​"price-total">​
<span class=​"price-unit">​€​</span>
​<span class=​"price-value">​
<span class=​"price-value-int">​1.760​</span>
​<span data-decimalseparator=​"," class=​"price-value-cent">​,00​</span>​
</span>
​</div>​
</td>​
when I write in the console:
a.getElementsByClassName("prd-var-price")
I would to take the value of price-value-int element (1760), I tried with:
$(a.getElementsByClassName("prd-var-price").getElementsByClassName("price-value-int"));
but this not work.
getElementsByClassName returns an array of elements, if you want only the first one (and in your example - you do) you should use a.getElementsByClassName("prd-var-price")[0].getElementsByClassName("price-value-int")[0]
but since you are using jQuery, a simpler approach would be:
$('.prd-var-price .price-value-int');
jQuery uses css selector syntax to grab elements, you'll still get an array if more then one of this class structure exists
You can use jQuery FIND function to achieve your Goal
$(".prd-var-price").find(".price-value-int").text();
Demo
Better to use $('.prd-var-price .price-value-int) instead of using $(a.getElementsByClassName("prd-var-price").getElementsByClassName("price-value-int"));
You might have multiple td with same class.
Better to use parent > child selection with find()
$('.prd-var-price').find('.price-value-int').text();
In each()
$('.prd-var-price').each(function(){
console.log($(this).find('.price-value-int').text());
});
$('td.prd-var-price').each(function(key, value){
console.log($(this).find('.price-unit').text());
console.log($(this).find('.price-value-int').text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td class="prd-var-price">
<div class="price-total">
<span class="price-unit">€</span>
<span class="price-value">
<span class="price-value-int">1.760</span>
<span data-decimalseparator="," class="price-value-cent">00</span>
</span>
</div>
</td>
<td class="prd-var-price">
<div class="price-total">
<span class="price-unit">#</span>
<span class="price-value">
<span class="price-value-int">2.760</span>
<span data-decimalseparator="," class="price-value-cent">00</span>
</span>
</div>
</td>
</tr>
</table>
By using JQuery:
$("tr.prd-var-price").find('div.price-total span.price-value span:first-child").text();

JavaScript - Copy text with clipboard.js based on class name

I'm trying to get a copy-to-clipboard function to work for below HTML-code
using the Clipboard.js library:
<table id="test">
<tr><td class="c2c"><a id="1" class="btn fa fa-clipboard fa-2x" data-clipboard-action="copy" data-clipboard-target="1" data-value="http://some/link/1"></a></td></tr>
<tr><td class="c2c"><a id="2" class="btn fa fa-clipboard fa-2x" data-clipboard-action="copy" data-clipboard-target="2" data-value="http://some/link/2"></a></td></tr>
<tr><td class="c2c"><a id="3" class="btn fa fa-clipboard fa-2x" data-clipboard-action="copy" data-clipboard-target="3" data-value="http://some/link/3"></a></td></tr>
</table>
As you can see the value/ID changes for each td or a-element.
Instead of ID can I also use a class element to work with clipboard.js?
With this code I get the correct values but I cannot get it to work with clipboard.js:
$("#test").on('click', '.btn', function (e) {
e.preventDefault();
var id = $(this).data('value');
console.log(id)
});
How can I get the value of the data-value attribute for each td and have it copied with clipboard.js?
Thank you.

delete the current <tr> and also delete the <tr> before it using plain javascript

I have this HTML structure:
<tr class="project-details">REMOVE THIS</tr>
<tr class="project-description">
<td colspan="6">
<div class="project-desc-inner">
<div class="project-synopsis">
<p class="trunk8">This is an entry</p>
</div>
<div class="project-verification">
<span class="verfied-badge"> <~~~~~~~~~~ THIS SPAN
<span class="currency-symbol">$</span>
<span class="icon-tick"></span>
Verified
</span>
</div>
<div class="project-actions">
<a href="#">
<button class="btn">LOL</button>
</a>
</div>
</div>
</td>
</tr>
And I hope that the entire <tr class="project-details">REMOVE THIS</tr> plus its contents will be remove completely
This is what I have so far:
function showAlert()
{
var projectDescriptions = document.querySelectorAll('tr.project-description'),
projectDescriptions = Array.prototype.slice.call(projectDescriptions);
projectDescriptions.forEach(function(el) {
if (el.querySelector('span.verfied-badge')) {
}else {
el.parentNode.removeChild(el);
el.prev('tr').remove();
}
});
}
What it does is select the <tr> with the <span> I am looking for, then delete the entire span. This part el.prev('tr').remove(); is not working, any alternative?
Thanks!
The body of the else clause:
(function removePreviousSibling(sibling) {
if (sibling.nodeName === 'TR' && sibling.classList.contains('project-details')) {
return sibling.parentNode.removeChild(sibling);
}
removePreviousSibling(sibling.previousSibling);
}(el.previousSibling));
el.parentNode.removeChild(el);
The IIFE ensures if there is an extra text node between the two <tr> elements that the text node will be skipped and not deleted if you just did called a removeChild on the previousSibling of the target element.
Take a look over the information at MDN's DOM page. It's got a great set of interface documentation and tutorials.
prev is a method of a jQuery object. HTMLElement object has no prev method. For selecting the previous element sibling you can use the previousElementSibling property.

Categories

Resources