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

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/

Related

Trigger an event on a shadow DOM element that is overlaid by an element in the light DOM (not a parent)

I am trying to get the coordinates of a shadow DOM table cell that may (or may-not) have overlay elements displayed in front of it. The clickable overlay elements may span over multiple cells so they will not necessarily be children of the cell I need the coordinates from.
I can't get the event to bubble through the table like I expect. I believe event re-targeting of the shadow DOM is preventing the event from ever hitting the cells when the event originates in the light DOM (I kinda think that this is the wrong approach anyways as the overlay element is not a child of the cell I want the coordinates from to begin with)
The "pointer-events: none;"property pretty much does what I want, however, I need the event to also trigger on the light DOM overlay element so I don't know if that is an option.
I am thinking it is a good idea to avoid attaching a listener to every cell for performance issues (in the final application there will be hundreds of cells)
I am using vanilla JavaScript
In the provided example, is it possible to get the correct coordinates of the underlying table cell when the overlying div grey is clicked?
class Custom_Grid extends HTMLElement {
constructor() {
super();
this.attachShadow({
mode: 'open'
});
this.shadowRoot.innerHTML = `
<style>
td {
height:50px; width:50px; border: 1px solid grey;
}
</style>
<table>
<tr>
<td id='x0y0'><slot name='x0y0'></slot></td>
<td id='x0y1'><slot name='x0y1'></slot></td>
<td id='x0y2'><slot name='x0y2'></slot></td>
</tr>
<tr>
<td id='x1y0'><slot name='x1y0'></slot></td>
<td id='x1y1'><slot name='x1y1'></slot></td>
<td id='x1y2'><slot name='x1y2'></slot></td>
</tr>
<tr>
<td id='x2y0'><slot name='x2y0'></slot></td>
<td id='x2y1'><slot name='x2y1'></slot></td>
<td id='x2y2'><slot name='x2y2'></slot></td>
</tr>
`;
}
connectedCallback() {
this.shadowRoot.addEventListener("click", (e) => {
if (e.target.matches('td'))
console.log(`Grid Cell: ${e.target.id}`)
});
}
}
window.customElements.define('custom-grid', Custom_Grid);
document.getElementById('grid_overlay').addEventListener("click", (e) => {
console.log("#overGrid Click")
});
#grid_overlay {
width: 100px;
height: 100px;
background-color: grey;
position: absolute;
/*pointer-events: none; <-- not an option?*/
}
<custom-grid>
<div slot='x1y0' id='grid_overlay'></div>
</custom-grid>
A solution is to hide the overlay element temporarily in order to get the covered element thanks to the elementFromPoint() method.
if ( e.target.id === 'grid_overlay' ) {
console.log( 'overlay click' )
e.target.hidden = true
var el = this.shadowRoot.elementFromPoint( e.x, e.y )
if (el.id)
console.log( 'under: ', el.id )
e.target.hidden = false
}
class Custom_Grid extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
td {
height:50px; width:50px; border: 1px solid grey;
}
</style>
<table>
<tr>
<td id='x0y0'><slot name='x0y0'></slot></td>
<td id='x0y1'><slot name='x0y1'></slot></td>
<td id='x0y2'><slot name='x0y2'></slot></td>
</tr>
<tr>
<td id='x1y0'><slot name='x1y0'></slot></td>
<td id='x1y1'><slot name='x1y1'></slot></td>
<td id='x1y2'><slot name='x1y2'></slot></td>
</tr>
<tr>
<td id='x2y0'><slot name='x2y0'></slot></td>
<td id='x2y1'><slot name='x2y1'></slot></td>
<td id='x2y2'><slot name='x2y2'></slot></td>
</tr>
`;
}
connectedCallback() {
this.shadowRoot.addEventListener("click", (e) => {
if (e.target.matches('td'))
console.log(`Grid Cell: ${e.target.id}`)
else if (e.target.id === 'grid_overlay' ) {
console.log( 'overlay click ' )
e.target.hidden = true
var el = this.shadowRoot.elementFromPoint( e.x, e.y )
if (el.id)
console.log( 'under: ', el.id )
e.target.hidden = false
}
});
}
}
window.customElements.define('custom-grid', Custom_Grid);
#grid_overlay {
width: 100px;
height: 100px;
background-color: grey;
position: absolute;
}
<custom-grid>
<div slot='x1y0' id='grid_overlay'></div>
</custom-grid>

Filtering with different price ranges and one attribute

I'm looking for a working example or fiddle that has filtering for price ranges along with some properties (such as 'On Sale'). Basically, I would like to filter an item to it's price range and to also see products that are on sale too in that price range. I have the price ranges working but how do I implement multiple ranges when the multiple checkboxes are checked. Also, how can I implement filtering the sale attribute?
Any help is appreciated.
The structure of the HTML and assignment of data-* attributes are sloppy and cluttered. Using a ton of divs makes the code difficult to ascertain purpose (if any).
Attributes such as [data-date] is not necessary in regards to the question (and probably not necessary in the real code either). Although functioning, attributes [min] and [max] are not standard on checkboxes, use [data-min] and [data-max] and make sure when using any attribute with a number value be converted into a true number.
The usefulness concerning something on sale and within a selected price range is dubious since the sale item is in a price range regardless. The sale items should simply be shown if a .sale class is assigned. Details are commented in demo.
// Clicking summary calls toggleFilters()
$('summary').on('click', toggleFilters);
/*
Any changes to form.filter calls filterItems()
The second parameter (event.data) indicates what is considered $(this)
*/
$('.filter').on('change', ':checkbox', filterItems);
// If details is closed, the table cells are shown and the .filter is reset
function toggleFilters(e) {
if (!!$(this).parent('details').attr('open')) {
$('tbody td').show();
$('.filter')[0].reset();
}
}
/*
//A Hide all cells in tbody
//B On each checkbox...
if it is checked and has class .priceRange...
...get its [data-min] and [data-max] into an array and add that to the ranges array
//C if it is checked and has class .saleItems sales flag is true
*/
function filterItems(e) {
let ranges = [];
let sales = false;
$('tbody td').hide(); //A
$(':checkbox').each(function() {
if (this.checked) {
if ($(this).is('.priceRange')) { //B
let min = Number($(this).data('min'));
let max = Number($(this).data('max'));
ranges.push([min, max]);
}
if ($(this).is('.saleItems')) { //C
sales = true;
}
}
});
/*
//A On each [data-price] cell...
//B Collect all [data-item] cells into an array
//C Collect all .img cells into an array
//D if [data-price] has .sale class use the [data-sale] value
//E for each sub array in the ranges array...
//F Run between() first param is price, second param is min of sub array third param
is max of sub array
//G if true then show cells [data-price], [data-item], and .img cells associated with
current index of the arrays images and items
//H if sales flag is true and current checkbox is checked and has the .saleItems class...
do the same as line G
*/
$('.products').find('[data-price]').each(function(index) {
const items = $('[data-item]').toArray();
const images = $('.img').toArray();
let price = this.matches('.sale') ?
Number($(this).data('sale')) : Number($(this).data('price'))
for (let range of ranges) {
if (between(price, range[0], range[1])) {
$(this).show();
$(images[index]).show();
$(items[index]).show();
}
}
if (sales && $(this).is('.sale')) {
$(this).show();
$(images[index]).show();
$(items[index]).show();
}
});
}
/*
Utility function that determines if a given number is in a given range
*/
function between(num, min, max) {
return num >= min && num <= max;
}
/*
Utility function that will set the images of .img cells with an array of urls
*/
function setImages(array) {
$('.img').each(function(index) {
$(this).css('background-image', `url(${array[index]})`);
});
}
/* Utility function that sets colspan values according to max number of cells in a row
*/
function tableStructure() {
let cs = [];
$('tr').each(function() {
let size = $(this).children().length;
cs.push(size);
});
let sorted = cs.sort();
$('.cs').attr('colspan', sorted[sorted.length - 1]);
$('tbody').find('tr').last().prev('tr').find('td').css('border-bottom', '0');
}
const images = ['https://www.dhresource.com/webp/m/0x0s/f2-albu-g6-M00-F1-0F-rBVaSFqzohOAJ_2FAAFgtbG9J2U328.jpg/women-new-large-size-casual-tops-loose-ladies.jpg', 'https://www.sherainbow.com/1634-large_default/pogt-casual-long-sleeve-t-shirt-women-loose-fit-wifey-print-slouchy-shirt-top-pink-cb12e6qb3bp.jpg', 'https://sc02.alicdn.com/kf/HTB1ZlLYbHsTMeJjy1zeq6AOCVXar/New-Fashion-Design-Women-plain-black-t.jpg', 'https://aritzia.scene7.com/is/image/Aritzia/large/s19_07_a06_63877_16624_on_a.jpg', 'https://cdn.forcast.com.au/media/catalog/product/cache/image/e9c3970ab036de70892d86c6d221abfe/1/8/18p928blk_18t946sto_frontfull_117_cm_2_7.jpg', 'https://image.skechers.com/img/productimages/xlarge/52675_NVOR.jpg', 'https://static.enko-running-shoes.com/2019/img/v5/chaussure-running-enko.jpg'];
tableStructure();
setImages(images);
.products {
table-layout: fixed;
}
caption,
th {
text-align: left;
font-size: 1.15rem;
}
caption {
font-size: 1.5rem;
font-weight: 700
}
td {
border-bottom: 3px ridge grey;
}
tbody td {
padding-bottom: 5px
}
.dept tr:first-of-type>th::before {
content: attr(data-dept);
font-size: 1.25rem
}
.category th::before {
content: attr(data-cat)
}
.item>td::before {
content: attr(data-item);
font-size: 1.2rem
}
.price>td::before {
content: '$'attr(data-price)
}
.price>td::after {
content: '\a0'
}
.price>td.sale::before {
content: '$'attr(data-price);
text-decoration: line-through red
}
.price>td.sale::after {
content: '$'attr(data-sale);
color: green
}
.img {
background-size: contain;
background-repeat: no-repeat;
background-position: center;
min-width: 100px;
min-height: 100px;
}
label {
display: inline-block;
width: 150px;
margin: 0 5px;
border-bottom: 1px solid black;
}
details {
cursor: pointer
}
tbody tr:last-of-type td {
border-bottom: 0;
}
summary {
font-size: 1.25rem;
border-top: 3px ridge grey
}
<table class="products">
<caption>Shop</caption>
<tbody class='dept'>
<tr>
<th class='cs' data-dept='Apparel'></th>
</tr>
<tr class='category'>
<th class='cs' data-cat='Shirts'></th>
</tr>
<tr class='item'>
<td data-item='item 1'></td>
<td class='img' rowspan='2'></td>
<td data-item='item 2'></td>
<td class='img' rowspan='2'></td>
<td data-item='item 3'></td>
<td class='img' rowspan='2'></td>
</tr>
<tr class='price'>
<td data-price='9.99'><br></td>
<td data-price='23.99'><br></td>
<td class='sale' data-price='32.99' data-sale='17.99'><br></td>
</tr>
<tr class='category'>
<th class='cs' data-cat='Pants'></th>
</tr>
<tr class='item'>
<td data-item='item 4'></td>
<td class='img' rowspan='2'></td>
<td data-item='item 5'></td>
<td class='img' rowspan='2'></td>
</tr>
<tr class='price'>
<td class='sale' data-price='39.99' data-sale='12.99'><br></td>
<td data-price='75.99'><br></td>
</tr>
<tr class='category'>
<th class='cs' data-cat='Shoes'></th>
</tr>
<tr class='item'>
<td data-item='item 6'></td>
<td class='img' rowspan='2'></td>
<td data-item='item 7'></td>
<td class='img' rowspan='2'></td>
</tr>
<tr class='price'>
<td data-price='39.99'><br></td>
<td class='sale' data-price='125.99' data-sale='77.99'><br></td>
</tr>
</tbody>
<tfoot>
<tr>
<td class='cs'>
<form class='filter'>
<details>
<summary>Filters</summary>
<label><input class="priceRange" data-min='0' data-max='9.99' type="checkbox" value='true'>Under $10</label>
<label><input class="priceRange" data-min='10' data-max='19.99' type="checkbox">$10 to $20</label>
<label><input class="priceRange" data-min='20' data-max='29.99' type="checkbox">$20 to $30</label>
<label><input class="priceRange" data-min='30' data-max='39.99' type="checkbox">$30 to $40</label>
<label><input class="priceRange" data-min='40' data-max='999' type="checkbox">Over $40</label>
<label><input class="saleItems" type="checkbox" value='true'>On Sale</label>
</details>
</form>
</td>
</tr>
</tfoot>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I'm not really sure what the desired behavior of the sale filter is, but this should put you in the right direction:
updated plunkr
$('.priceFilter').on('change', (e) => {
var filters = $('.priceRange:checked')
.toArray()
.map(el => ({
min: $(el).attr('min'),
max: $(el).attr('max'),
sale: $(el).attr('data-sale')
}));
if (!filters.length) {
$('.item').show();
} else {
$('.item').hide();
var sale = filters.some(el => el.sale == 'True') ? 'True' : 'False';
filters
.forEach(elm => $('.item')
.filter((i, el) =>
parseFloat($(el).attr('data-price')) >= elm.min &&
parseFloat($(el).attr('data-price')) <= elm.max &&
$(el).attr('data-sale') == sale)
.show());
}
});

How to change class of specified <td>?

function change() {
var tds = document.getElementsByTagName("td");
var tds2 = tds.className;
console.log(tds);
for (var i = 0; i < tds.length; i++) {
if (tds[i].className === "marked") {
tds[i].className = "UNmarked";
} else {
tds[i].className = "marked";
}
}
}
function generTab(rows, cols) {
var html = "<table id='tb01'>";
for (var i = 1; i <= rows; i++) {
html += "<tr>"
for (var j = 1; j <= cols; j++) {
html += "<td class='marked' onclick='change()'>" + "</td>";
}
html += "</tr>"
}
return html + "</table>";
}
td.marked {
height: 50px;
width: 50px;
border: solid thin black;
cursor: pointer;
background-color: white;
}
td.UNmarked {
height: 50px;
width: 50px;
border: solid thin black;
cursor: pointer;
background-color: purple;
}
<div class="line">
Number of rows:
<input type="text" id="rows" />
</div>
<div class="line">
Number of cols:
<input type="text" id="cols" />
<span class="error"></span>
</div>
<input type="button" value="Generuj" id="gener" />
</div>
<div id="scene"></div>
I'm generating table by my own, and I want to change class of specified <td> by clicking on on it. The problem is that when I click on whichever <td> it is changing the classes of all of them, but I want to change that <td> class which I click.
May be you can do some thing like the following with a single class:
var tds = document.querySelectorAll("td");
tds.forEach(function(td){
td.addEventListener('click', function(){
this.classList.toggle('marked')
});
});
td {
border: 1px solid lightgray;
padding: 10px;
font-size: 20px;
}
.marked{
background-color: #4CAF50;
color: white;
}
<table>
<tr>
<td>1</td><td>2</td><td>3</td>
</tr>
<tr>
<td>4</td><td>5</td><td>6</td>
</tr>
</table>
Add click event listeners to all the td elements and implement a simple onClick function which adds/removes the desired css class.
const tds = Array.from(document.querySelectorAll('td'));
const onClick = ({ target }) => {
tds.forEach(td => td === target ? td.classList.add('active') : td.classList.remove('active'))
}
tds.forEach(td => td.addEventListener('click', onClick));
.active {
color: red;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
</body>
</html>
The code you've written should be toggling the class of all tds in the document. I believe you're trying to change the class of the td that is being clicked. To do that, try something like (apologies in advance as I'm on my phone):
function change(e) {
let td = e.target;
if (td.classList.contains('marked')) {
td.className = 'UNmarked';
} else {
td.className = 'marked';
}
}
and be sure that that change is bound as the click event for each td.
If you can use jQuery...
$("td").click(function(){
$(this).toggleClass("marked")
.toggleClass("UNmarked");
});

Selenium and Chrome, having trouble selecting element

I'm using Selenium and Chrome to write a script. I'm having trouble getting Selenium to select and click on two elements. Here's the element I'm trying to select:
HTML of Element 1:
<td class="menuItem" id="tWlans" style=""><a href="frameWlan.html"
id="cWlans" accesskey="W" onmouseover="highlight('Wlans')"
onmouseout="removeHighlight('Wlans')" onclick="selectTab('Wlans')"
onfocus="highlight('Wlans')" onblur="removeHighlight('Wlans')"
target="mainFrame"><u>W</u>LANs</a></td>
HTML of Element 2:
<td class="listNoPad">
<input type="TEXT" name="1.6.7.wlan_id" class="statictextboxlink"
onclick="editThisWlan(this.value,this.name)" readonly="" size="7" value="7">
</td>
I've tried selecting the element by id and by XPath, neither of which works.
function siteNavigate() {
sleep(4500);
driver.findElement(By.xpath('//*[#id="cWlans"]')).click();
//driver.findElement(By.id('cWlans')).click();
}
Thanks in advance for any help and suggestions.
Edit:
function helpAction(pageId, startpage) {
var baseHref = window.location.href;
var index = baseHref.indexOf("/screens");
baseHref = baseHref.substring(0, index);
var href = "/helpfiles/oweb/index.html";
var editWindow = window.open(baseHref + href, "editWindow", "left=100 top=50 menubar=no,toolbar=yes,width=800,height=600,status=yes,resizable=yes");
if (navigator.appName != "Netscape") {
editWindow.location.href = baseHref + href;
editWindow.location.reload(true);
}
editWindow.focus();
}
function feedbackAction() {
var URL = 'http://www.cisco.com/go/wireless-feedback';
var feedbackWindow = window.open(URL, "FeedbackWindow", "left=100 top=50 menubar=no,toolbar=no,scrollbars=yes,titlebar=yes,width=800,height=800,status=yes,resizable=yes");
feedbackWindow.focus();
}
function selectTab(tabName) {
// All this function does is update the value of the hidden field and call the updatePage() function
// Obtain object reference to hidden field
var fieldObj = document.getElementById("hSelectedTab");
// Store the new tab selection in the hidden field
fieldObj.value = tabName;
updatePage();
}
function highlight(tabName) {
//remove highlight for all the tabs
removeHighlightAll();
var highlightObj = document.getElementById("t" + tabName);
// Only highlight if srcElement is a tab object.
highlightObj.style.backgroundColor = "#25546B";
}
function removeHighlight(tabName) {
var highlightObj = document.getElementById("t" + tabName);
highlightObj.style.backgroundColor = "";
}
function removeHighlightAll() {
document.getElementById("tMonitor").style.backgroundColor = "";
document.getElementById("tWlans").style.backgroundColor = "";
document.getElementById("tSwitch").style.backgroundColor = "";
document.getElementById("tWireless").style.backgroundColor = "";
document.getElementById("tSecurity").style.backgroundColor = "";
document.getElementById("tManagement").style.backgroundColor = "";
document.getElementById("tCommands").style.backgroundColor = "";
document.getElementById("tHelp").style.backgroundColor = "";
document.getElementById("tFeedback").style.backgroundColor = "";
}
function updatePage() {
// Clear the current tab selection
removeSelection();
// Obtain object reference to hidden field
var fieldObj = document.getElementById("hSelectedTab");
// Retrieve the selected tab
var selectedTab = fieldObj.value;
// Highlight the selected tab
cellObj = document.getElementById("t" + selectedTab);
cellObj.className = "selected";
}
function removeSelection() {
removeHighlightAll();
// Brute force method to clear the tab selection
document.getElementById("tMonitor").className = "menuItem";
document.getElementById("tWlans").className = "menuItem";
document.getElementById("tSwitch").className = "menuItem";
document.getElementById("tWireless").className = "menuItem";
document.getElementById("tSecurity").className = "menuItem";
document.getElementById("tManagement").className = "menuItem";
document.getElementById("tCommands").className = "menuItem";
document.getElementById("tHelp").className = "menuItem";
document.getElementById("tFeedback").className = "menuItem";
}
function DisplayMsgIfAny() {
if (document.forms[0].err_flag.value == 1) {
alert(document.forms[0].err_msg.value);
} else if (document.forms[0].result_flag.value == 1) {
alert(document.forms[0].cmd_result.value);
}
document.forms[0].err_flag.value = 0;
document.forms[0].result_flag.value = 0;
document.forms[0].buttonClicked.value = 0;
}
//need to get image for the OEMS and change the logo image.
function getLogoImage() {}
A {
TEXT-DECORATION: none
}
#home_icon {
height: 12px;
}
A:link {
COLOR: #ffffff;
TEXT-DECORATION: none
}
A:hover {
COLOR: #ffffff;
TEXT-DECORATION: none
}
A:active {
COLOR: #000000;
TEXT-DECORATION: none
}
A:visited {
COLOR: #ffffff;
TEXT-DECORATION: none
}
A.command {
COLOR: #ffffff;
TEXT-DECORATION: none
}
A.command:hover {
COLOR: #ff9100;
TEXT-DECORATION: underline
}
P {
FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
}
TD {
FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
}
P {
FONT-SIZE: 11px;
MARGIN: 0px;
COLOR: #333366
}
TD {
FONT-SIZE: 12px
}
TD.menuItem {
PADDING-RIGHT: 10px;
PADDING-LEFT: 10px;
PADDING-BOTTOM: 4px;
PADDING-TOP: 5px;
BORDER-BOTTOM: #000000 5px solid;
width: 1%;
white-space: nowrap;
}
TD.selected {
PADDING-RIGHT: 10px;
PADDING-LEFT: 10px;
PADDING-BOTTOM: 4px;
COLOR: #000000;
PADDING-TOP: 5px;
BORDER-BOTTOM: #ff9100 5px solid;
width: 1%;
white-space: nowrap;
}
TD.space {
WIDTH: 50%;
}
.style2 {
COLOR: #ffffff
}
<script language="JavaScript" src="../servicescript41.js"></script>
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" onload="updatePage(); DisplayMsgIfAny();">
<table width="100%" height="53" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="PADDING-BOTTOM: 4px" align="middle" background="../images/background_web41.jpg" width="180">
<img src="../images/cisco/cisco-logo-2007.gif" width="67" height="40" alt="logo" />
</td>
<td valign="bottom" background="../images/background_web41.jpg">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td class="menuItem" id="tMonitor" style=""><u>M</u>ONITOR</td>
<td class="selected" id="tWlans" style=""><u>W</u>LANs</td>
<td class="menuItem" id="tSwitch" style=""><u>C</u>ONTROLLER</td>
<td class="menuItem" id="tWireless" style="">W<u>I</u>RELESS</td>
<td class="menuItem" id="tSecurity" style=""><u>S</u>ECURITY</td>
<td class="menuItem" id="tManagement" style="">M<u>A</u>NAGEMENT</td>
<td class="menuItem" id="tCommands" style="">C<u>O</u>MMANDS</td>
<td class="menuItem" id="tHelp">HE<u>L</u>P</td>
<td class="menuItem" id="tFeedback" style=""><u>F</u>EEDBACK</td>
<td class="space"> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<div style="position:absolute; right:0px; top:0px; margin: 3px 10px 0px 0px">
<p>Sa<u>v</u>e Configuration | <u>P</u>ing | <a class="command" href="#" accesskey="g" onclick="javascript:logoutAction();">Lo<u>g</u>out</a> | <u>R</u>efresh</p>
</div>
<form method="post" action="/screens/banner.html">
<input type="hidden" name="access_control" size="16" maxlength="15" value="1">
<input name="hSelectedTab" type="hidden" id="hSelectedTab" value="Wlans">
<input type="hidden" name="err_flag" size="16" maxlength="15" value="0">
<input type="hidden" name="err_msg" size="512" maxlength="511" value="">
<input type="hidden" name="result_flag" size="16" maxlength="15" value="0">
<input type="hidden" name="cmd_result" size="512" maxlength="511" value="Config Saved">
<input type="hidden" name="ping_address" size="50" maxlength="50" value="">
<input type="hidden" name="interfaceType" size="11" maxlength="11" value="">
<input type="hidden" name="buttonClicked" size="16" maxlength="15" value="0">
</form>
</body>
Edit 2:
Error message from Node.js:
NoSuchElementError: no such element: Unable to locate element: {"method":"css selector","selector":"*[id="cWlans"]"}
(Session info: chrome=61.0.3163.100)
(Driver info: chromedriver=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f),platform=Windows NT 10.0.15063 x86_64)
at WebDriverError (C:\Selenium\node_modules\selenium-webdriver\lib\error.js:27:5)
at NoSuchElementError (C:\Selenium\node_modules\selenium-webdriver\lib\error.js:192:5)
at Object.checkLegacyResponse (C:\Selenium\node_modules\selenium-webdriver\lib\error.js:546:15)
at parseHttpResponse (C:\Selenium\node_modules\selenium-webdriver\lib\http.js:509:13)
at doSend.then.response (C:\Selenium\node_modules\selenium-webdriver\lib\http.js:441:30)
at process._tickCallback (internal/process/next_tick.js:109:7)
From: Task: WebDriver.findElement(By(css selector, *[id="cWlans"]))
at thenableWebDriverProxy.schedule (C:\Selenium\node_modules\selenium-webdriver\lib\webdriver.js:807:17)
at thenableWebDriverProxy.findElement (C:\Selenium\node_modules\selenium-webdriver\lib\webdriver.js:1014:17)
at siteNavigate (C:\Selenium\byot.js:29:8)
at sleep.then (C:\Selenium\byot.js:21:5)
From: Task: WebElement.click()
at thenableWebDriverProxy.schedule (C:\Selenium\node_modules\selenium-webdriver\lib\webdriver.js:807:17)
at WebElementPromise.schedule_ (C:\Selenium\node_modules\selenium-webdriver\lib\webdriver.js:2010:25)
at WebElementPromise.click (C:\Selenium\node_modules\selenium-webdriver\lib\webdriver.js:2092:17)
at siteNavigate (C:\Selenium\byot.js:29:37)
at sleep.then (C:\Selenium\byot.js:21:5)
Ok, I apologize in advance. I didn't realize initially that the page had several iframes nested inside the page. To make a very long story short, the frames ended up being the problem the whole time. The site was set up with four frames, some of which changed depending on context and some that essentially stayed static after the initial login. The hardest part was knowing which frame to switch to, and keeping track of which context I was currently focused in on.
Here's what I ended up with:
const {Builder, By, until} = require('selenium-webdriver');
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
driver.get('http://sitetonavigate.com');
driver.manage().window().maximize();
driver.findElement(By.name('bSubmit ')).click();
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
// Wait until Chrome is fully loaded to launch AutoIT login script
sleep(4500).then(() => {
autoIT();
});
function autoIT() {
var child_process = require('child_process');
var workerProcess = child_process.execFile("C:\\Selenium\\autoITscript.exe");
sleep(2500).then(() => {
siteNavigate();
});
}
function siteNavigate() {
driver.switchTo().frame("banner");
driver.findElement(By.id('cWlans')).click();
//Select correct WLAN
sleep(2500).then(() => {
driver.switchTo().defaultContent();
driver.switchTo().frame("mainFrame");
driver.switchTo().frame("content");
driver.findElement(By.xpath('/html/body/form/table[3]/tbody/tr[8]/td[2]/input')).click();
});
}
You can use:
Element1 :
driver.findElement(By.id('tWlans')).click();
Element2 :
driver.findElement(By.name('1.6.7.wlan_id')).click();
You are clicking on the TD because it has the ID, tWlans. You (presumably) want to click on the A tag contained within. I would suggest the CSS selector, #tWlans > a. The code is below. I added a wait but it may or may not be needed.
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#tWlans > a"))).click();
As for the second element, it wasn't in your full HTML posted so I'm not sure if it's unique but you can try these couple CSS selectors:
input[name='1.6.7.wlan_id']
input[onlick^='editThisWlan']

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>

Categories

Resources