Get image src using jQuery - javascript

I'm trying to get the src attribute of an html image. It seems like I can find the img element in the DOM but the src attribute is undefined, any ideas why?
HTML:
<table id="comboTable" style="width: 100%; height: 100%; margin-bottom: 10px;" data-bind="click: $root.selectCombo">
<tr>
<td>
<img class="selector" src="~/Images/roundOffButton.png" style="position: absolute;margin-left: -57px; margin-top: -35px;" />
</td>
<td style="height: 35px;">
<table style="width: 100%; background-color: #0097D8;padding:5px;">
<tr style="padding:5px;">
<td style="height: 36px; padding-left: 14px; font-weight: bold;color: black; margin: 1px; width: 70%; text-align:left;">
<span data-bind="text: Description" style="padding-left: 5px;" />
</td>
<td style="width: 30%;padding:8px; text-align: center;color: white; background-color:black;">
<span data-bind="text: formatCurrency(Price)" style="font-size: 14px; white-space: nowrap;
font-weight: bold;" />
</td>
</tr>
</table>
</td>
</tr>
</table>
Javascript:
var comboSpan = $("span:contains('" + description + "')");
var img = $(comboSpan).closest(".selector");
alert('Image object - ' + img);
var src = $(img).attr('src');
alert(src); //src is undefined

Working Demo
Use a valid selector for img, img and span have different parent, so you can't use closest() directly in this case.
Also comboSpan,img is already a jQuery objects. You don't need it like $(comboSpan)
Use .closest('#comboTable') as your hierarcy has a table inside a table.
<table>
<tr>
<td>
<img> //You need this.
</td>
<td>
<table>
<tr>
<td>
<span> //You have this.
</td>
</tr>
</table>
</td>
</tr>
</table>
Final code:
var comboSpan = $("span:contains('" + description + "')");
var img = comboSpan.closest('#comboTable').find('.selector'); //Change this line
alert('Image object - ' + img);
var src = img.attr('src');
alert(src); //src is undefined

You need to find closest tr and then .selector img :
var comboSpan = $("span:contains('" + description + "')");
var img = $(comboSpan).closest("tr").find(".selector");// find tr and then img
alert('Image object - ' + img);
var src = $(img).attr('src');
alert(src); //src is undefined

You first try to find tr and then it's child img (i.e .selector)
var img = $(comboSpan).closest('tr').find('.selector');
Try this:
var comboSpan = $("span:contains('" + description + "')");
var img = $(comboSpan).closest('tr').find('.selector');
alert('Image object - ' + img);
var src = $(img).attr('src');
alert(src);

Use this:
var img = comboSpan.closest('tr').find('.selector');
// no need to wrap comboSpan with jquery as comboSpan is already a jquery object

Check it out with this.
$('.img1 img').attr('src');

Simply you use as below:
var src = $('.selector').attr('src');
alert(src);

My answer is belove
$('.img1 img').attr('src');

Related

Create and stylize a table with JSON

I have this JSON from which I need to create a table. This table must be a legend for a webmap created with OpenLayers 6. As you have seen the JSON comes from Geoserver.
Below my code:
let updateLegend = function(resolution) {
let graphicUrl = strutturale_puc.getSource().getLegendUrl(
resolution,
{'FORMAT': 'application/json'}
);
if(graphicUrl) {
fetch(graphicUrl)
.then(function (response) {
return response.text();
})
.then(function (data) {
const jsonData = JSON.parse(data);
const legendData = jsonData.Legend[0].rules;
const table = document.getElementById("table");
const footer = table.createTFoot();
legendData.forEach((value) => {
cellStroke = value.symbolizers[0].Polygon.stroke;
cellFill = value.symbolizers[0].Polygon.fill;
cellContent = value.name;
const tableRaw = footer.insertRow(value);
tableRaw.insertCell(0).innerHTML = '<td style="border: 4px solid ' + cellStroke + '; background-color: ' + cellFill + '; max-width: 10px;"></td>';
tableRaw.insertCell(1).innerHTML = '<td style="border: none;">' + cellContent + '</td>';
console.log(tableRaw);
});
}).catch((error) => {
console.error(error)
});
}
The table is inside a div:
<div class="" id="legend">
<table class="table" id="table">
</table>
</div>
My problem is that I can't see any style when the table is created, I can see only the text(cellContent). For me is strange because if I use this:
<div class="">
<table>
<tr>
<td style="border: 4px solid #791919; background-color: #A71C1C; max-width: 10px;"></td>
<td style="border: none;">Item</td>
</tr>
</table>
</div>
I can see all correctly. What I wrong?
.insertCell creates a <td> element, inserts it into the table, and returns a reference to it (per the spec).
You then set the contents of that <td> to contain another <td> where you add the styling rule.
So now you essentially have:
<td>
<td style="border: 4px solid #791919; background-color: #A71C1C; max-width: 10px;"></td>
</td>
You can only have a <td> tag within a <tr> tag, so the browser removes the internal <td> tag (along with its styling), and adds its contents to the original <td>.
To solve the issue, you need to add the styling to the <td> that it makes for you. For example:
let firstCell = tableRaw.insertCell(0);
firstCell.setAttribute("style", 'border: 4px solid ' + cellStroke + '; background-color: ' + cellFill + '; max-width: 10px;');
firstCell.innerHTML = "";
Code quality notes:
You should use CSS classes rather that inline styles.
You should use template literals rather than inline string concatenation.

How to get 'this.parent' element value by class name?

I have 'td' element in this object how to get parent element value by class name?
console.log($this.parent().html())
show in console:
<td class="nr"><div contenteditable="true">7</div></td><td class="abc"><div contenteditable="true">A</div></td><td class="nazwa"><div contenteditable="true" class="xyz">logic lvl convert</div></td><td class="opis">3.3V to 5V</td><td class="symbol"> </td><td class="ilosc">6</td><td class="nowy">TAK</td><td class="ds"></td>
I try to find how to get value from td with specified class but after long time spended on gogle I don't know how to do that :/
I need to get value elements with class #nr, #abc and #ds
If you are wanting to manually get the values of .nr, .abc and .ds..
var trJqObject = $('tr');
$('.clicker.string').click(function() {
var theValuesAsString; // will be a string
var separator = ', ';
theValuesAsString = $('.nr div', trJqObject).text() + separator;
theValuesAsString += $('.abc div', trJqObject).text() + separator;
theValuesAsString += $('.ds', trJqObject).text();
alert(theValuesAsString);
})
$('.clicker.array').click(function() {
var theValuesAsArray = []; // will be an array
theValuesAsArray.push($('.nr div', trJqObject).text());
theValuesAsArray.push($('.abc div', trJqObject).text());
theValuesAsArray.push($('.ds', trJqObject).text());
$.each(theValuesAsArray, function() {
alert(this);
})
})
.clicker {
position: fixed;
bottom: 0;
padding: 2px 6px 1px 6px;
background-color: hsla(188, 100%, 50%, 1);
cursor: pointer;
}
.clicker:hover {
background-color: hsla(287, 100%, 72%, 1);
}
.clicker.string {
left: 0;
}
.clicker.array {
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td class="nr">
<div contenteditable="true">7</div>
</td>
<td class="abc">
<div contenteditable="true">A</div>
</td>
<td class="nazwa">
<div contenteditable="true" class="xyz">logic lvl convert</div>
</td>
<td class="opis">3.3V to 5V</td>
<td class="symbol"></td>
<td class="ilosc">6</td>
<td class="nowy">TAK</td>
<td class="ds">empty</td>
</tr>
</table>
<div class="clicker string">click to show values as string</div>
<div class="clicker array">click to loop values array</div>
If you reply to this question with more information about what you want to get and what you want to do with it and I'll update this fiddle.
fiddle
https://jsfiddle.net/Hastig/4uakr7mn/

Next button only brings the first image and stops

I have been trying to create a next and back buttons that go through the images one by one that are in the table.
But the next button, it only brings the first image and stops.
How can the same button "next" have the function of going through all the images?
<p id = "slider"></p>
<div id="galDiv">
<style>
table, th, td {
border: 1px solid black;}
</style>
<table>
<tr>
<td id="1"><img src="gallery/a.jpg" style="width:100px;height:100px;"></td>
<td id="2"><img src="gallery/k.jpg" style="width:100px;height:100px;"></td>
<td id="3"><img src="gallery/2.jpg" style="width:100px;height:100px;" ></td>
<td id="4"><img src="gallery/3.jpg" style="width:100px;height:100px;" ></td>
</tr>
</table>
</div>
<button id="nxt">NEXT</button>
<script>
document.getElementById("nxt").onclick = function()
{myFunction()};
function myFunction() {
var div = document.getElementById('galDiv');
var nextSibling = div.nextSibling;
while(nextSibling && nextSibling.nodeType != 1) {
nextSibling = nextSibling.nextSibling }
}
</script>
How can also create a back button ?
If you are trying to create a facebook like image viewer, you shouldn't use table element.
In order to create such thing you should create a div with container fixed side ,within this div you should have a div with floating images and then your button should change the right position of the inner div.
Or you could use a jquery library such as http://www.jacklmoore.com/colorbox
Your code does nothing. The next sibling to #galDiv is the <button>.
Is this what you wanted?
document.getElementById("nxt").onclick = myFunction;
function myFunction() {
var picture = [
"firstPicture",
"secondPicture",
"thirdPicture",
"fourthPicture"
];
var place = {
"firstPicture": 0,
"secondPicture": 1,
"thirdPicture": 2,
"fourthPicture": 3
};
var table = document.querySelector('table');
if (!table.className) {
table.className = "firstPicture";
}
var nextPicture = (place[table.className] + 1) % 4;
table.className = picture[nextPicture];
}
img[src="gallery/a.jpg"] {
border: 5px solid red;
}
img[src="gallery/k.jpg"] {
border: 5px solid green;
}
img[src="gallery/2.jpg"] {
border: 5px solid blue;
}
img[src="gallery/3.jpg"] {
border: 5px solid black;
}
table {
border-collapse: collapse;
position: absolute;
padding: none;
border: none;
}
#galDiv {
width: 113px;
height: 113px;
overflow: hidden;
position: relative;
}
.firstPicture {
left: 0;
}
.secondPicture {
left: -112px;
}
.thirdPicture {
left: -224px;
}
.fourthPicture {
left: -336px;
}
<p id = "slider"></p>
<div id="galDiv">
<table>
<tr>
<td id="1"><img src="gallery/a.jpg" style="width:100px;height:100px;"></td>
<td id="2"><img src="gallery/k.jpg" style="width:100px;height:100px;"></td>
<td id="3"><img src="gallery/2.jpg" style="width:100px;height:100px;" ></td>
<td id="4"><img src="gallery/3.jpg" style="width:100px;height:100px;" ></td>
</tr>
</table>
</div>
<button id="nxt">NEXT</button>
I added the curimg attribute to the slider. Read the script for yourself. You'll need to add in modulus arithmetic to round around the table entries. As for the 'prev' function. Figure out the same thing with a -1 when selecting the tdnode.
Don't forget to set the curimg attribute after you append the child.
Good luck!
<p id = "slider" curimg='1'></p>
<div id="galDiv">
<style>
table, th, td {
border: 1px solid black;}
</style>
<table>
<tr>
<td id="1"><img src="gallery/a.jpg" style="width:100px;height:100px;"></td>
<td id="2"><img src="gallery/k.jpg" style="width:100px;height:100px;"></td>
<td id="3"><img src="gallery/2.jpg" style="width:100px;height:100px;" ></td>
<td id="4"><img src="gallery/3.jpg" style="width:100px;height:100px;" ></td>
</tr>
</table>
</div>
<button id="nxt">NEXT</button>
<script>
document.getElementById("nxt").onclick = function()
{myFunction()};
function myFunction() {
//Get the slider, parse the int of the 'curimg' attribute
cid = document.getElementById('slider');
current_image = parseInt( cid.getAttribute('curimg') );
//Get the td of that id+1
tdnode = document.getElementById(current_image + 1);
//Clone the image childNode into the slider.
cid.appendChild( td.childNodes[0].cloneNode() );
}
</script>

Div containing a row of div are wrapping instead of overflowing

I am using JavaScript to insert elements inside a container div:
<tr>
<td align="left">
</td>
<td style="background-color:#5D7B9D">
<div id="headerMasterDiv">
</div>
</td>
<td style="width: 18px; height: 18px;">
</td>
</tr>
for (var i=0; i < len; i++ )
{
id = "headerColumn_" + i.toString();
width = columnWidths[i];
text = columnTexts[i];
html = " <div id=\""+id+"\" class=\"test\">"+text+"</div> ";
header.innerHTML += html;
}
However I would like the inner to overflow, so I can activate an horizontal scrollbar. But instead they are wrapping:
Tx.
Just add the overflow:auto to your div.
In the test class :
.test
{
overflow:auto;
}
Or inline style, i suggest using quot and double quot it's more readable :
' <div id="'+id+'" class="test" style="overflow:auto">'+text+'</div> ';

How do I get div not to display if value in another div is empty in Javascript?

Here is my code. I have tried everything I can think of. I have tried using just div ID's and have now tried classes. Nothing seems to work. I just want the number 2 not to be visible if there is no entry beside it. It doesn't matter if it is in a table or not.
Thanks.
<style type="text/css">
<!--
.leftone {
float: left;
height: auto;
width: auto;
}
.rightone {
float: left;
height: auto;
width: auto;
}
.lefttwo {
float: left;
height: auto;
width: auto;
}
.righttwo {
float: left;
height: auto;
width: auto;
}
-->
</style>
<table width="400" border="0" cellpadding="0" cellspacing="3" id="tableONE">
<tr>
<td width="200" height="50"><div class="leftone">1.)</div></td>
<td width="200" height="50"><div class="rightone">The Number One</div></td>
</tr>
<tr>
<td width="200" height="50"><div class="lefttwo">2.)</div></td>
<td width="200" height="50"><div class="righttwo"></div></td>
</tr>
</table>
<p> </p>
<script type="text/javascript">
<!--
function shownumbers() {
var myNum1 = '[.rightone]';
if(myNum1 != ''){
document.getElementById('.leftone').style.display = "block";
}
else if(myNum1 == ''){
document.getElementById('.leftone').style.display = "none";
}
var myNum2 = '[.righttwo]';
if(myNum2 != ''){
document.getElementById('.lefttwo').style.display = "block";
}
else if(myNum2 == ''){
document.getElementById('.lefttwo').style.display = "none";
}
}
//-->
</script>
You cannot use getElementById with classes. Also, you don't need the '.' or '#' when using these methods in javascript. Below should do what you are asking. Although if there is only ever 1 item of class 'rightone' and 'leftone' you should use ID's.
var myNum1 = document.getElementsByClassName('rightone')[0].innerHTML;
if(myNum1 != ''){
document.getElementsByClassName('leftone')[0].style.display = 'block';
} else if(myNum1 == ''){
document.getElementsByClassName('leftone')[0].style.display = 'none';
}
A more elegant solution would be:
HTML:
<table width="400" border="0" cellpadding="0" cellspacing="3" id="tableONE">
<tr>
<td><div class="left">1.)</div></td>
<td><div class="right">The Number One</div></td>
</tr>
<tr>
<td><div class="left">2.)</div></td>
<td><div class="right"></div></td>
</tr>
</table>
JS:
var right = document.getElementsByClassName('right');
for(var i=0;i<right.length;i++){
if(!right[i].innerHTML){
right[i].parentNode.parentNode.getElementsByClassName('left')[0].style.display = 'none';
} else {
right[i].parentNode.parentNode.getElementsByClassName('left')[0].style.display = 'right';
}
}
Kinda similar to Jason's, but I spent the time so I'mma post it. ;)
JSFiddle: http://jsfiddle.net/H3UNH/1/
HTML:
<table id="tableONE">
<tr>
<td width=50>1.)</td>
<td >The Number One</td>
</tr>
<tr>
<td>2.)</td>
<td></td>
</tr>
</table>
(I do still like the width attribute for cells in tables; it can be moved to CSS but this is one of those exceptions for me where the markup and presentation can have a tiny bit of overlap. Move everything else to CSS. Your mileage may vary.)
CSS:
td { padding: 3px; text-align:left; height: 50px;}
JavaScript:
function shownumbers() {
var rows = document.getElementsByTagName('tr');
for(var i=0,len=rows.length;i<len;i++) {
var _this = rows[i];
var rowCells = _this.getElementsByTagName('td');
if(rowCells[1].innerHTML == "") {
_this.style.display = "none";
}
}
}
shownumbers();
(for the purpose of the demo, I just separately call shownumbers. If you want it to be automatic, make it self-invoking. Otherwise call it from wherever it makes sense)
I think the more important lesson here isn't the JavaScript, actually. ;) I understand that not everyone is writing perfect JavaScript (heck, mine's not perfect either). But you really need to understand the purpose of CSS and classes in general to write good maintainable markup and presentation for the web! I hope that doesn't sound too condescending or anything; it wasn't meant to be.
By using the :empty selector.
var els = document.querySelectorAll('td div:empty'),
i = els.length,
el;
for(;i--; ) {
el = els[i];
do {
el = el.parentNode;
} while ( el.nodeName != 'TR' )
el.style.display = 'none';
}
Fiddle: http://jsfiddle.net/uAUt8/

Categories

Resources