Given a list of <a>s like this:
<tr>
<th style="padding-right:1em">Location</th>
<td>
<span class="location">Lower reaches of the Geum River, Korea</span>
</td>
</tr>
JS
function countryList(string) {
let pattern = new RegExp('^.+\/wiki\/'); // adjust `RegExp`
countryListLinks = string.replace(pattern, '');
}
I tried this but I get nothing:
countryLinks.each(function(){
console.log(countryList);
});
I tried this but I only get one item and the other undefined
countryLinks.forEach(countryList);
I am trying to output each href but without /wiki/ individually so that I can use them:
Geum_River Korea
Use map function
function countryList(string) {
let pattern = new RegExp('^.+\/wiki\/'); // adjust `RegExp`
return string.replace(pattern, '');
}
var result = Array.prototype.slice.call(document.getElementsByTagName('a')).map(function(a){return a.href}).map(countryList);
console.log(result)
<tr>
<th style="padding-right:1em">Location</th>
<td>
<span class="location">Lower reaches of the Geum River, Korea</span>
</td>
</tr>
Try this:
let word = '/wiki/';
$('[href]').map(function(i, e) {
var href = $(e).attr('href');
console.log(href.substring(href.indexOf(word) + word.length, href.length));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<th style="padding-right:1em">Location</th>
<td>
<span class="location">Lower reaches of the Geum River, Korea</span>
</td>
</tr>
follow this simple code and then parse using replace method
$('.location').find('a').each(function() {
console.log($(this).attr('href'));
});
Related
I am wanting to concatenate strings from 2 separate elements and have them stored in a variable.
Currently my code is setting the variable equal to:
"Daily: 1070300, Weekly: 1070300, Monthly: 1070300"
My goal is to make the variable in the console equal to:
"Daily: 10, Weekly: 70, Monthly: 300"
$(document).ready(function() {
var str = '';
$('tbody > tr').each(function() {
$(this).find('.key').each(function() {
str += $(this).text() + ": " + $(this).parents().siblings('tr').find('.value').text() + ", ";
})
});
console.log(str);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
</table>
Thank you for your help all!
Each time through the key loop, you're grabbing the content of all three value cells (since $(this).parents().siblings('tr').find('.value') matches all three). There are many ways to fix this but one easy one I see is to use the index argument on the inner loop to select the value cell corresponding to the current key (using jQuery's eq function):
$(document).ready(function() {
var str = '';
$('tbody > tr').each(function() {
$(this).find('.key').each(function(index) {
str += $(this).text() + ": " + $(this).parents().siblings('tr').find('.value').eq(index).text() + ", ";
})
});
console.log(str);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
</table>
The code is very inefficient when you keep looking up stuff in the loop. So fixing it to read the index would work, it just causes the code to do more work than needed.
How can it be improved. Look up the two rows and one loop using the indexes.
var keys = $("table .key") //select the keys
var values = $("table .value") //select the values
var items = [] // place to store the pairs
keys.each(function(index, elem){ //loop over the keys
items.push(elem.textContent + " : " + values[index].textContent) // read the text and use the index to get the value
})
console.log(items.join(", ")) // build your final string by joing the array together
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
</table>
Collect the .key and .value classes into a NodeList convert the NodeList into arrays. Then merge the 2 arrays into key/value pairs stored in an Object Literal. Finally convert the object into a string so it can be displayed.
Demo
Details are commented in Demo
// Collect all th.key into a NodeList and turn it into an array
var keys = Array.from(document.querySelectorAll('.key'));
// As above with all td.value
var vals = Array.from(document.querySelectorAll('.value'));
function kvMerge(arr1, arr2) {
// Declare empty arrays and an object literal
var K = [];
var V = [];
var entries = {};
/* map the first array...
|| Extract text out of the arrays
|| Push text into a new array
|| Then assign each of the key/value pairs to the object
*/
arr1.map(function(n1, idx) {
var txt1 = n1.textContent;
var txt2 = arr2[idx].textContent;
K.push(txt1);
V.push(txt2);
entries[K[idx]] = V[idx];
});
return entries;
}
var result = kvMerge(keys, vals);
console.log(result);
// Reference the display area
var view = document.querySelector('.display');
// Change entries object into a string
var text = JSON.stringify(result);
// Clean up the text
var final = text.replace(/[{"}]{1,}/g, ``);
// Display the text
view.textContent = final
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class='display' colspan='3'></td>
</tr>
</tfoot>
</table>
You can also solve that using unique ids, like that:
$(document).ready(function() {
var str = '';
$('tbody > tr').each(function() {
$(this).find('.key').each(function() {
var index = $(this).attr('id').slice(3)
str += $(this).text() + ": " + $('#value'+index).text() + ", ";
})
});
console.log(str);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key" id="key1">Daily</th>
<th class="key" id="key2">Weekly</th>
<th class="key" id="key3">Monthly</th>
</tr>
<tr>
<td class="value" id="value1">10</td>
<td class="value" id="value2">70</td>
<td class="value" id="value3">300</td>
</tr>
</tbody>
</table>
I have been asked to implement a small validation on values and if the values are greater or less than 0 i need to change or add/remove the css for the td and i tag
My table looks something like this
<table class="table table-hover" id="studentweek">
<thead>
<tr>
<th>Year</th>
<th">Weeks</th>
</tr>
</thead>
<tbody>
<tr>
<td>VAR (%)</td>
<td class="text-warning"> <i class="classname">-10.65%</i></td>
</tr>
<tr>
<td>VAR (diff)</td>
<td class="text-warning"> <i class="classname">-13,953</i></td>
</tr>
<tr>
<td>VAR (%)</td>
<td class="text-navy"> <i class="classname">8.81%</i></td>
</tr>
<tr>
<td>VAR (diff)</td>
<td class="text-navy"> <i class="classname">11,320</i></td>
</tr>
</tbody>
</table>
currently i am hard coding the css but i would like to be able to dynamicly change these as the values change automatically, can someone suggest the best way to archive this?
i was thinking in my Ajax request to do something like this:
var sdlyvar = $(parseFloat(".classname").text());
if (sdlyvar < 0){
$('.classname').removeClass(".classname").addClass("fa-level-down");
} else {
$('.classname').removeClass(".classname").addClass("fa-level-up");
}
Use JavaScript parseFloat for parsing percentage (http://www.w3schools.com/jsref/jsref_parsefloat.asp).
var percent = $('#sdlyvar').text();
var result = parseFloat(percent) / 100.0;
if (result < 0){
$('#sdlyvar').removeClass("fa-level-up");
$('#sdlyvar').addClass("fa-level-down")
} else {
$('#sdlyvar').removeClass("fa-level-down");
$('#sdlyvar').addClass("fa-level-up")
}
Your first problem is that you can't compare a string like "-10.95%" with an integer, because of the final % symbol. You have to use parseFloat on tha value:
var sdlyvar = parseFloat($('#sdlyvar').text());
It will take care of all the non-numeric stuff after the number.
Then, you'd probably want to remove the opposite class when updating:
if (sdlyvar < 0){
$('#sdlyvar').removeClass("fa-level-up").addClass("fa-level-down");
} else {
$('#sdlyvar').removeClass("fa-level-down").addClass("fa-level-up");
}
A few random suggestions:
Make clear what's wrong in your code when posting on StackOverflow
When referring an element more than once with jQuery, consider putting the selection in a variable, like var $sdlyvar = $("sdlyvar");: faster to type and execute.
Save us some whitespaces when posting code :/
Here .slice will remove the % sign in this code and the rest of the code will compare the value and assign or remove class
var sdlyvar = $('#sdlyvar').text();
if (sdlyvar.slice(0,-1) < 0){
$('#sdlyvar').removeClass("fa-level-up");
$('#sdlyvar').addClass("fa-level-down");
} else {
$('#sdlyvar').removeClass("fa-level-down");
$('#sdlyvar').addClass("fa-level-up");
}
var lis=document.querySelectorAll("tr td i");
for(var i in lis){
if(parseInt(lis[i].innerHTML)<0){
lis[i].className+=" fa-level-down";
}
else{
lis[i].className+=" fa-level-up";
}
}
I'm using a table to display items, an onclick event on cell[0] should output (alert) the data from cell[1] and cell[2].
I'm not sure with which approach I could access them.
Here is my code so far
http://jsfiddle.net/5uua7eyx/3/
Perhaps there is a way to use my variable input
HTML
<table id="items">
<tr>
<td onclick="ClickPic(this)">Picture0</td>
<td>Name0</td>
<td>Price0</td>
</tr>
<tr>
<td onclick="ClickPic(this)">Picture1</td>
<td>Name1</td>
<td>Price1</td>
</tr>
</table>
JS
function ClickPic(e) {
"use strict";
var input = e.target;
alert("Clicked!");
}
Thank you
You're passing this, which represents the element clicked, not the event object.
All you need to do is use the parameter to get the sibling .cells from the .parentNode, then use the elem.cellIndex to figure out the next indices:
function ClickPic(elem) {
"use strict";
var cells = elem.parentNode.cells;
var currIdx = elem.cellIndex;
alert(cells[currIdx + 1].textContent + " " + cells[currIdx + 2].textContent);
}
<table id="items">
<tr>
<td onclick="ClickPic(this)">Picture0</td>
<td>Name0</td>
<td>Price0</td>
</tr>
<tr>
<td onclick="ClickPic(this)">Picture1</td>
<td>Name1</td>
<td>Price1</td>
</tr>
</table>
x
If you know the index numbers will always be 1 and 2, then you can shorten it.
alert(cells[1].textContent + " " + cells[2].textContent);
you can change your js function to something like this
<script type="text/javascript">
function ClickPic(e) {
var s = '';
$(e).siblings().each(function() {
s = s + ',' + $(this).text()
});
alert(s);
}
I'm somewhat new to jQuery and am just wondering how I go about passing in a string value rather than what appears to be a reference to a jQuery item from a selector? I'm having a hard time explaining so here's a sample demo. Don't even know what to title this so please have at editing the title if you can think of a better one.
At the line where I do $("td").filter(function(str){ the str that is passed in becomes an index position of which TD I'm in. So while debugging the first time in it's a 0 the next time a 1 and so on. I tried google but I'm not even sure what to search for, any documentation/code help would be much appreciated
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("select[name='showTeam']").change(function () {
$("select[name='showTeam'] option:selected").each(function () {
var str = $(this).val().toLowerCase();
//str = what it was set to up there
//alert(str);
$("td").filter(function(str) {
//str = becomes a number = to position of TD.. ie for 5th TD match STR = 4 (starts at index 0)
return $(this).text().toLowerCase().indexOf(str) != -1;
}).css('background','red');
});
})
});
</script>
Show Team: <select id="showTeam" name="showTeam">
<option>All</option>
<option>Chelsea</option>
</select>
<div id="games">
<table border="1">
<tbody>
<tr>
<th>ID</th>
<th>Game date</th>
<th>Field</th>
<th>Home team</th>
<th>Home team score</th>
<th>Away team</th>
<th>Away team score</th>
<th>Game type</th>
</tr>
<tr class="odd_line" id="game_460">
<td>459</td>
<td>03 Nov 19:00</td>
<td>Field 2</td>
<td>Madrid </td>
<td>3</td>
<td>Bayern Munich </td>
<td>1</td>
<td>Season</td>
</tr>
<tr class="odd_line" id="game_461">
<td>460</td>
<td>03 Nov 19:00</td>
<td>Field 3</td>
<td>chelsea</td>
<td>5</td>
<td>arsenal</td>
<td>4</td>
<td>Season</td>
</tr>
</div>
$(document).ready(function(){
$("#showTeam").change(function () {
var searchFor = $(this).val().toLowerCase();
$("#games table tbody tr td:contains('" + searchFor + "')").parent().css('background','red');
})
});
Demo
Well, yes. The first parameter will refer to the index of the element in the set of matched elements. Just do:
...
$("select[name='showTeam'] option:selected").each(function() {
var str = $(this).val().toLowerCase();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(str) != -1;
}).css('background', 'red');
...
since str will already be available within the scope of the filter callback function.
From the docs:
.filter( function(index) )
function(index)A function used as a test for each element in the set.
this is the current DOM element.
$(document).ready(function(){
$("#showTeam").change(function() {
var target = $("#showTeam").val();
$("#games td:contains(" + target + ")").css('background','red');
});
});
I've made a jsfiddle to demonstrate this.
http://jsfiddle.net/Zf5dA/
Notes:
:contains() is case sensitive so I had to make "Chelsea" capitalized in the table.
I simplified the selector on the select element - it has an id, so I selected that. Faster and simpler.
This will find td cells that contain the text, but they can also contain other text. This will get you started.
i am developing a gadget and i am using JavaScript to change innerHTML of span, but after some operations i need to read that value. Additionally i am using pre-entered value for spans but when i try to read new data function loads pre-entered one.
Is there any solution for that?
JS:
function read_write(condition,filename){
var fso = new ActiveXObject('Scripting.FileSystemObject');
var fh = fso.OpenTextFile(System.Gadget.path+'\\'+filename+'.txt',condition, true,-2);
if (condition == 1) {
var result = fh.ReadLine();
return result;
}
else if (condition == 2) {
var spn1 = document.getElementById('span1').innerHTML;
fh.WriteLine(spn1+','+document.getElementById('span2').innerHTML);
}
fh.Close();
}
HTML:
<table id="sonuc">
<tbody>
<tr>
<td style="width:50%" valign="top">
<span class="result" id="span1"></span><br/>
<span class="result" id="span2"></span>
</td>
</tr>
</tbody>
</table>
If you're using innerHTML to write to the span element, you should be able to use it again to read. How are you trying to read until now?