I would like to read the values of HTML td using prototype. For example, say you have a table as follows
<table id="myTable">
<tr>
<td>apple</td>
<td>orange</td>
</tr>
<tr>
<td>car</td>
<td>bus</td>
</tr>
</table>
I would like to read the values - apple, orange, car and bus alone. I am unable to find a
way to do it? Any help would be of great help.
Thanks,
J
This should work:
var values = $$('#myTable td').collect(function(element) {
// stripTags(), if you're only interested in the actual content
return element.innerHTML.stripTags();
});
The following returns an array of strings.
$$('#myTable td').pluck('innerHTML');
Related
I'm struggling to wrap my head around how to get this regex working in Visual Studio Code.
I'm trying to match every 7th instance of <td> tag to then replace it with <td data-order="">.
Original
<tr>
<td>1</td>
<td>Name</td>
<td>Owner</td>
<td>Value</td>
<td>Total</td>
<td>Percent</td>
<td>Ratio</td>
<td>Final</td>
</tr>
What I want
<tr>
<td>1</td>
<td>Name</td>
<td>Owner</td>
<td>Value</td>
<td>Total</td>
<td>Percent</td>
<td data-order="">Ratio</td>
<td>Final</td>
</tr>
I've tried variations on ((?:.*<td>){1}), but any number greater than 1 just gives me a "No results" message.
[You say "match every 7th instance" but I think you mean match the seventh instance, not the 7th, 14th, 21st, etc. Assuming that you mean the 7th only..."]
If your data is really as regular and structured as you showed, you could use this as the regex in a Find
Find: (?<=<tr>\n(?:<td>.*<\/td>\n){6})(<td)
Replace: <td data-order=""
If you might have newlines within a <td>...\n...</td> tag, use this
Find: (?<=<tr>\n(?:<td>[^/]*<\/td>\n){6})(<td)
Replace: <td data-order=""
Vscode's find/replace (in one file) can use a non-fixed length lookbehind like
(?<=<tr>\n(?:<td>.*<\/td>\n){6})
The search across files cannot do that so this regex would not work there. Also sites like regex101.com can't use it either so I'll show a demo in vscode itself:
You can use the extension Select By. And use the command moveby.regex.
In your keybindings.json define a keybinding to search for the next <td> tag.
{
"key": "ctrl+i ctrl+u", // or any other key combo
"when": "editorTextFocus",
"command": "moveby.regex",
"args": {
"regex": "<td[^>]*>",
"properties": ["next", "end"]
}
}
Select the first <tr> tag of where you want to start
Select every following <tr> tag with:
command: Add Selection to Next Find Match(Ctrl+D - editor.action.addSelectionToNextFindMatch)
menu option: Selection > Select All Occurrences
Apply the key binding as many times as you want
Your cursors are now after the n-th <td> tag
Make any edits you want
Press Esc to leave Multi Cursor mode
In Select By v1.2.0 you can specify a repeat count. The count can be fixed or asked from the user.
{
"key": "ctrl+i ctrl+u", // or any other key combo
"when": "editorTextFocus",
"command": "moveby.regex",
"args": {
"regex": "<td[^>]*>",
"properties": ["next", "end"],
"repeat": "ask"
}
}
If you leave out the property "regex" you are asked for a regular expression too.
Edit
Using a regular expression takes quite some time to get it correct
let testStr =`<tr>
<td>1</td>
<td>Name</td>
<td>Owner</td>
<td>Value</td>
<td>Total</td>
<td>Percent</td>
<td>Ratio</td>
<td>Final</td>
</tr>`;
var replace = '$1<td class="red">$2';
var regex = new RegExp("(<tr>[\n\r\s]*(?:<td[^>]*>(?:.|[\n\r\s])*?</td>[\n\r\s]*){6})<td>((?:.|[\n\r\s])*</tr>)");
var newstr=testStr.replace(regex,replace);
console.log(newstr);
document.getElementById("test").innerHTML=newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>
I was interested in this as I don't know much of regex and need to learn, but I manged to make it so in two goes.
I hope someone will correct me and help with correct one way.
I tried to folow this: but cant make it to work: Find Nth Occurrence of Character
let testStr = '<td>1</td><td>Name</td><td>Owner</td><td>Value</td><td>Total</td><td>Percent</td><td>Ratio</td><td>Final</td>';
var replace = '<td class="red">';
var regex = new RegExp("((<td>.*?)){7}");
// tried with a lot of (?:...) combinations here but none works :(
var newstr=testStr.replace(regex,replace);
var regex2 = new RegExp("((</td>.*?)){6}");
var newstr2=testStr.match(regex2);
console.log(newstr);
console.log(newstr2[0]);
document.getElementById("test").innerHTML=newstr2[0]+newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>
EDIT:
Got something :)
let testStr = '<td>1</td><td>Name</td><td>Owner</td><td>Value</td><td>Total</td><td>Percent</td><td>Ratio</td><td>Final</td>';
var replace = '<td class="red">';
var regex = new RegExp("(?:[</td>]){6}(<td>)");
var newstr=testStr.replace(regex,replace);
console.log(newstr);
document.getElementById("test").innerHTML=newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>
And with #rioV8's help:
let testStr = '<td>1</td><td>Name</td><td>Owner</td><td>Value</td><td>Total</td><td>Percent</td><td>Ratio</td><td>Final</td>';
var replace = '$1<td class="red">';
var regex = new RegExp("((?:.*?</td>){6})<td>");
var newstr=testStr.replace(regex,replace);
console.log(newstr);
document.getElementById("test").innerHTML=newstr
.red {
color: red
}
<table>
<tbody >
<tr id="test">
</tr>
</tbody>
</table>
I'm trying to create a table in Angular with a dynamic number of columns and rows. I've found this easy to accomplish using the HTML table element by doing something like this:
<table class="html-table">
<tr class="headers">
<th>Name</th>
<th>Age</th>
<th>Sex</th>
<th *ngIf="columns == 4">Species</th>
</tr>
<tr>
<td>Ryan</td>
<td>30</td>
<td>M</td>
<td *ngIf="columns == 4">Human</td>
</tr>
</table>
In this example there might be some button that toggles the value of columns between 3 and 4.
Every explanation I have looked at online involves changing CSS variables, which seems like a somewhat hacky way to accomplish something that should be simple. Is there some way I can specify that something should be a new column in CSS grid rather than that having to specify the number of columns in grid-template-columns?
In Angular you can use ng-repeat to have a dynamic table
A typical example could be
<table ng-table="tableParams" class="table table-striped">
<tr ng-repeat="data in datas">
<td title="Title_Of_First_Variable">{{data.variable1}}</td>
<td title="Title_Of_Second_Variable">{{data.variable2}}</td>
<td title="Title_Of_Third_Variable">{{data.variable3}}</td>
...
</tr>
</table>
Of course with your controller you should pass your dynamic data into the correct $scope, in this case should be $scope.datas (usually an object)...maybe something like this, using NodeJS:
$http.post('route_of_your_method')
.success(function (result) {
$scope.datas = result;
})
.error(function (err) {
...
});
I explained fastly but i hope this is enough
I have a table in html. I want to round cell content to 2 decimal digits only.
<table>
<thead>
<tr>
<th>Item</th>
<th>Price</th>
</tr>
</thead>
<tr>
<td>Laptop</td>
<td>2000.0000</td>
</tr>
<tr>
<td>Mobile</td>
<td>1000.0000</td>
</tr>
</table>
I have option to use CSS only. Is that possible in CSS?
Using jQuery it would be something like this, assuming each cell containing a number had the number class:
$('tr.number').each( function () {
// get value of table cell and convert to number...
var val = parseFloat($(this).text());
// put it back as fixed point value
$(this).text(val.toFixed(2));
});
<table border="1">
<tbody>
<tr>
<th>ID</th>
<th>Product</th>
<th>Color</th>
<th>Model</th>
</tr>
<tr>
<td>22</td>
<td>Car</td>
<td>blue</td>
<td>
<ul>
</ul>
</td>
</tr>
</tbody>
</table>
Above is a snippet of a highly nested html document. To get the table level I have used the following xpath
//th[contains(text(), "ref_code")]/following-
sibling::td[contains(text(), "197")]/ancestor::table[2]
How then can I edit the same xpath and select a specific table header data and the corresponding table data column like so using xpath:
ID |Product |Color
22 |Car |Blue
Any help will be appreciated
From your comments to the answers given here:
I assume that you get the above table from an existing xpath which is :
//th[contains(text(), "ref_code")]/following-
sibling::td[contains(text(), "197")]/ancestor::table[2]
Now you want to add/edit to this xpath such that you get the values of td given a column for e.g. Color, then the below xpath should give you the td values for all columns given Color as input:
//td[position()<=(count(//tr/th[.='Color']/preceding-sibling::*)+1) ]
Assuming your first xpath works correctly, add the above xpath to that like:
//th[contains(text(), "ref_code")]/following-
sibling::td[contains(text(), "197")]/ancestor::table[2]//td[position()<=(count(//tr/th[.='Color']/preceding-sibling::*)+1) ]
Output:
<td>22</td>
<td>Car</td>
<td>blue</td>
If you want just the Color, use xpath :
//td[(count(//tr/th[.='Color']/preceding-sibling::*)+1) ]
If you want just the Product use xpath :
//td[(count(//tr/th[.='Product']/preceding-sibling::*)+1) ]
If you want just the ID use xpath :
//td[(count(//tr/th[.='ID']/preceding-sibling::*)+1) ]
Note that the xpath changes at th[.='XXX'] where XXX is the selected element.
But if you want the output to be in the form of a table , you need to use XSLT, because you are trying to get a transformed view of your html , not just selected elements.
We seach for table data //table//td by position in header of column //table//th[text()='Color']
That [count(element/preceding-sibling::*) +1] is how to find element's index
So result is:
//table//td[count(//table//th[text()='Color']/preceding-sibling::*) +1]
Here is my HTML code:
<table id="laptop_detail" class="table">
<tr>
<td style="padding-left:18px" class="ha">Touchscreen</td>
<td class="val"><span class="no_icon">No</span></td>
</tr>
<tr>
<td style="padding-left:18px" class="ha">Water Dispenser</td>
<td class="val"><span class="no_icon">No</span></td>
</tr>
<tr>
<td style="padding-left:18px" class="ha">Colour / Material</td>
<td class="val">Grey</td>
</tr>
</table>
Here is my xpath:
$x('//*[#id="laptop_detail"]//tr/td[contains(. ,"Touchscreen")]/following-sibling::td[1]/span/text() and //*[#id="laptop_detail"]//tr/td[contains(. ,"Water Dispenser")]/following-sibling::td[1]/span/text() and //*[#id="laptop_detail"]//tr/td[contains(. ,"Colour")]/following-sibling::td[1]/text()')
But my xpath returns "true" instead of my requirement "No, No, Grey". I know there is something wrong with my xpath but i am unable to understand it.
EDIT: Okay i had a little success, I was able to get "No, No" using this xpath:
$x('//*[#id="laptop_detail"]//tr/td[contains(. ,"Touchscreen") or contains(. ,"Water")]/following-sibling::td[1]/span/text()')
but unable to get "Grey" as that value is not inside span tag.
Here is a fix to your solution (I've added | operator):
//*[#id="laptop_detail"]/tr/td[contains(. ,"Touchscreen") or contains(. ,"Water")]/following-sibling::td[1]/span/text() | //*[#id="laptop_detail"]/tr/td[contains(. ,"Colour / Material")]/following-sibling::td[1]/text()
You can use little bit more easy syntax (run faster) if it is acceptable for your logic.
/table[#id="laptop_detail"]/tr/td[#class='val']/span/text() | /table[#id="laptop_detail"]/tr/td[#class='val']/text()