Ignorning an Anchor in a JScript search function - html

I have this function for searching a table and displaying the rows that match my search input
function searchTable() {
var input, filter, found, table, tr, td, i, j;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td");
for (j = 0; j < td.length; j++) {
if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
}
}
if (found) {
tr[i].style.display = "";
found = false;
} else {
tr[i].style.display = "none";
}
}
}
I would like to make one of the strings in the data clickable with a hyper link.
However this affects my search because the the link is inside my table data . So even thought it is not visible it is skewing the search results.
What argument could I add to my function to ignore the contents of my bracket and still find the text string in my table. Or how could I place my anchor outside my table data brackets and still have the string be a clickable anchor.
Ex of table row:
<tr>
<td>Abcès au cerveau</td>
<td>Neurologique</td>
<td></td>
</tr>
Sorry beginner question. I am also looking for an argument to highlight the results of my search if anyone has it.

Related

How can I change with onclick event of a <td>the color of the td? The critical point is that the td elements are generated dynamically with code

In my Blazor server app, I am reading the CNC Files of a remote machine and listing them in the table's rows.
So far everything is OK.
When the user clicks on one TD element, the content of the CNC file will be shown on the screen in another table(This part I have not shown because it is not related to my problem)
I want that the last choosen CNC file (last clicked ) should be highlighted (font=red).
That means each time when the user selects another CNC-File, just the related should be higlighted all others should be in default color (black).
If I would have a static table I would use the a:focus. But my problem is that my td's will be generated dynamically. And I have to apply the a:focus function for just one td (that was clicked).
How can I do that?
I have tried to call a function in the style of the td style="#Style_CNC_File()" but the colors that I define in the function are applied to all of the td's.
Here is my code:
<table >
<tr>
<td>CNC Files</td>
</tr>
#{ if (Deltalogic.Return_Read_CNC_File == 0 && Deltalogic.Selected_CNC_File_Path_Type == "file")
{
for (var i = 0; i < Deltalogic.CNC_File_Array_lenght_dir - 1; i++)
{
var arg0 = "abc";
var arg1 = "def";
var arg2 = "ghi";
<tr >
<td style="#Style_CNC_File()" #onclick='#(e => Read_CNC_Files(arg0,arg1,arg2))'>/#Deltalogic.CNC_File_Out_Array_dir[i]</td>
</tr>
}
}
}
</table>
In my razor.cs file:
public string Style_CNC_File()
{
if (var_clicked == true)
{
return "color:#FF0000";
}
else
{
return "color:#000000";
}
}
Maybe you can set an id to your td and store the selected id :
<tr>
<td>CNC Files</td>
</tr>
#{ if (Deltalogic.Return_Read_CNC_File == 0 && Deltalogic.Selected_CNC_File_Path_Type == "file")
{
for (var i = 0; i < Deltalogic.CNC_File_Array_lenght_dir - 1; i++)
{
var arg0 = "abc";
var arg1 = "def";
var arg2 = "ghi";
<tr >
<td #onclick='#(e => HandleClick(i, arg0,arg1,arg2))' style="#Getstyle(i)">/#Deltalogic.CNC_File_Out_Array_dir[i]</td>
</tr>
}
}
}
</table>
#code {
int selectedId = -1;
void HandleClick(int id, string args0, string args1, string args2)
{
selectedId = i;
Read_CNC_Files(arg0,arg1,arg2);
}
void Getstyle(int id)
{
if (selectedId == i)
return "background-color:red;";
return string.Empty;
}
}
You can change the class or style as you want according to the index of the line.

Can I make an object to repeat in a loop?

My current code look like this:
var that = $(this).closest('tr');
for (var i = 0; i < data.length; i++) {
that.next().find("[name='prod_code']").val(data[i]["prd_code"]);
that.next().find("[name='prod_desc']").val(data[i]["prd_desc"]);
that.next().find("[name='prod_qty']").val(data[i]["prd_qty"]);
}
What it does is to set the value from the array to the input inside a table.
But currently it can only set 1 row with the last element in the array.
I found out that if I add next() function repeatedly it can insert all the product in the table, but it kinda look dumb to do that manually.
My expectation of loop (I have tried but it doesn't work):
var that = $(this).closest('tr');
for (var i = 0; i < data.length; i++) {
var next = "next()";
that.next.find("[name='prod_code']").val(data[i]["prd_code"]);
that.next.find("[name='prod_desc']").val(data[i]["prd_desc"]);
that.next.find("[name='prod_qty']").val(data[i]["prd_qty"]);
next++;
}
Someone please point out what am I missing.
Thanks in advance!!
Given that you have the i index of the row which can be aligned with the index of the object within the array, then you can use eq() to find the tr by that index in order to update the form controls within it:
var $rows = $('#yourTable tbody tr');
for (var i = 0; i < data.length; i++) {
$rows.eq(i).find('[name="prod_code"]').val(data[i]['prd_code']);
$rows.eq(i).find('[name="prod_desc"]').val(data[i]['prd_desc']);
$rows.eq(i).find('[name="prod_qty"]').val(data[i]['prd_qty']);
}
Alternatively you could loop over the tr and use their index to find the object within the array:
$('#yourTable tbody tr').each((i, tr) => {
let $tr = $(tr);
$tr.find('[name="prod_code"]').val(data[i]['prd_code']);
$tr.find('[name="prod_desc"]').val(data[i]['prd_desc']);
$tr.find('[name="prod_qty"]').val(data[i]['prd_qty']);
});

Delete slides that contain a specific text string

I'm working on an automated slide setup and depending on some opt-out variables I need to remove some of the slides if they are not desired in the final output. To solve this I have created a script that adds a simple text string {{remove-this-slide}} to the slides that need to be deleted.
However, when trying to get a script to delete the slides containing that string it keeps deleting my entire presentation...
This is what I have:
function deleteFunction() {
var currentPresentationSlide = SlidesApp.getActivePresentation().getSlides();
for (i = 0; i < currentPresentationSlide.length; i++) {
if (currentPresentationSlide[i].getPageElements().indexOf('{{remove-this-slide}}') > -1); {
currentPresentationSlide[i].remove();
}
}
}
Can anyone figure out what's going wrong here?
How about this modification?
Modification points :
The reason that the entire slides are deleted is ; after if (currentPresentationSlide[i].getPageElements().indexOf('{{remove-this-slide}}') > -1);. By this ;, if doesn't work and currentPresentationSlide[i].remove(); is always run.
The text data cannot be retrieved from currentPresentationSlide[i].getPageElements(). When you want to search the text from the text box, please use currentPresentationSlide[i].getShapes().
From your question, I was not sure where you want to search the text from. So I supposed that you want to search the text from shapes. The shape includes the text box.
Modified script :
function deleteFunction() {
var currentPresentationSlide = SlidesApp.getActivePresentation().getSlides();
for (i = 0; i < currentPresentationSlide.length; i++) {
var shapes = currentPresentationSlide[i].getShapes();
for (j = 0; j < shapes.length; j++) {
if (shapes[j].getText().asString().indexOf('{{remove-this-slide}}') > -1) {
currentPresentationSlide[i].remove();
}
}
}
}
Reference :
getShapes()
If I misunderstand your question, I'm sorry.
There is a small bug in the code from #Tanaike. Because there might be more shapes in the same slide, you have to break the loop after deleting the slide.
Otherwise the code tries to traverse the shapes of a deleted slide, producing an error.
So the correct snippet looks like:
function deleteFunction() {
var currentPresentationSlide = SlidesApp.getActivePresentation().getSlides();
for (i = 0; i < currentPresentationSlide.length; i++) {
var shapes = currentPresentationSlide[i].getShapes();
for (j = 0; j < shapes.length; j++) {
if (shapes[j].getText().asString().indexOf('{{remove-this-slide}}') > -1) {
currentPresentationSlide[i].remove();
break;
}
}
}
}

Section Word Count in Google Docs

Is it possible for a Google Docs add-on to count word per heading (section)? The following image shows what I want.
Is there a way to display this kind of word count information in a sidebar or any other way?
Here is a script that does this. In Google Docs, headings are a kind of paragraph distinguished by their getHeading() attribute. There are thus 9 levels of paragraphs: title, subtitle, h1... h6, and normal.
The script first finds the level of each paragraph and the word count of each paragraph. Then, for each paragraph, it loops over all subsequent "normal" paragraphs, adding their word counts; this stops when another paragraph of equal or higher level is reached.
My understanding that the words in headings themselves should not be included in word counts, but that can be changed if desired.
Since this is not an add-on, there is no sidebar to display information in. I just append the results at the end, copying each heading there and appending (X words) to its text. It looks like this:
Book title (108 words)
Chapter 1 (54 words)
Section 1 (15 words)
Section 2 (20 words)
Chapter 2 (54 words)
Section 1 (54 words)
Subsection 1 (31 words)
Subsection 2 (13 words)
In my sample text, Chapter 1 has some "intro" normal text before its first section, which is why its word count is higher than the sum of word counts of its two sections.
Script:
function countPerSection() {
var body = DocumentApp.getActiveDocument().getBody();
var para = body.getParagraphs();
var levels = para.map(function(p) {
return [DocumentApp.ParagraphHeading.TITLE,
DocumentApp.ParagraphHeading.SUBTITLE,
DocumentApp.ParagraphHeading.HEADING1,
DocumentApp.ParagraphHeading.HEADING2,
DocumentApp.ParagraphHeading.HEADING3,
DocumentApp.ParagraphHeading.HEADING4,
DocumentApp.ParagraphHeading.HEADING5,
DocumentApp.ParagraphHeading.HEADING6,
DocumentApp.ParagraphHeading.NORMAL].indexOf(p.getHeading());
});
var paraCounts = para.map(function (p) {
return p.getText().split(/\W+/).length;
});
var counts = [];
for (var i = 0; i < para.length; i++) {
var count = 0;
for (var j = i+1; j < para.length; j++) {
if (levels[j] <= levels[i]) {
break;
}
if (levels[j] == 8) {
count += paraCounts[j];
}
}
counts.push(count);
}
for (var i = 0; i < para.length; i++) {
if (levels[i] < 8) {
body.appendParagraph(para[i].copy()).appendText(" (" + counts[i] + " words)");
}
}
}
I edited the previous answer to put the word count next to each header instead of all at the bottom, and you'll see it in the outline too. I also added a function that will remove all of the counts as well, so you can keep them without having to worry about CTRL-Z 'ing or manually deleting them. Hopefully this is useful for somebody else!
function countPerSection() {
var body = DocumentApp.getActiveDocument().getBody();
var para = body.getParagraphs();
var levels = para.map(function(p) {
return [DocumentApp.ParagraphHeading.TITLE,
DocumentApp.ParagraphHeading.SUBTITLE,
DocumentApp.ParagraphHeading.HEADING1,
DocumentApp.ParagraphHeading.HEADING2,
DocumentApp.ParagraphHeading.HEADING3,
DocumentApp.ParagraphHeading.HEADING4,
DocumentApp.ParagraphHeading.HEADING5,
DocumentApp.ParagraphHeading.HEADING6,
DocumentApp.ParagraphHeading.NORMAL].indexOf(p.getHeading());
});
var paraCounts = para.map(function (p) {
return p.getText().split(/\W+/).length;
});
// var counts = [];
for (var i = 0; i < para.length; i++) {
var count = 0;
for (var j = i+1; j < para.length; j++) {
if (levels[j] <= levels[i]) {
break;
}
if (levels[j] == 8) {
count += paraCounts[j];
}
}
if (levels[i] < 8) {
para[i].appendText(" (" + count + " words)");
}
}
}
function removeCountPerSection(){
var docBody = DocumentApp.getActiveDocument().getBody();
docBody.replaceText('\\([0123456789]* words\\)', "");
}

Auto hide rows in HTML table when entire row is empty

In a HTML table how can I auto hide an entire row if all the cells (columns) within that row are empty?
I presume there is something I can add to the tag that would do this, but I cannot seem to find a solution anywhere.
In HTML, you can use the hidden attribute, as in <tr hidden>, but this is an HTML5 novelty and has limited browser support. But if you can directly change the HTML markup, the best way to hide an element is to remove it.
Assuming you want something that still lets you have the row there in the markup, for some reason, then you can use JavaScript e.g. as follows:
<script>
function emptyCellsOnly(row) {
var cells = row.cells;
for(var j = 0; j < cells.length; j++) {
if(cells[j].innerHTML !== '') {
return false;
}
}
return true;
}
var rows = document.getElementsByTagName('tr');
for(var i = 0; i < rows.length; i++) {
if(emptyCellsOnly(rows[i])) {
rows[i].style.display = 'none';
}
}
</script>
The test if(cells[j].innerHTML !== '') checks whether cell is completely empty, as in <td></td>. A space character, or a line break, is not counted as empty. If they should be, modify the condition as needed.
The code rows[i].style.display = 'none' hides the row by setting its display property to none, so CSS-enabled browsers will show the page as if the element were not there, but it is still accessible to scripts, etc. You could alternative remove the element completely from the DOM.
You can use a javascript like this
$('tr').each(function() {
if($(this).find('td').length == 0) {
$(this).hide();
}
});
After some research I found this sollution, which has the advantage over empty-cells:hide, that it completely removes the space an empty cell would take up.
<style type="text/css">
table {
border-spacing: 0px; // removes spaces between empty cells
border: 1px solid black;
}
tr, td {
border-style: none; // see note below
padding: 0px; // removes spaces between empty cells
line-height: 2em; // give the text some space inside its cell
height: 0px; // set the size of empty cells to 0
}
</style>
Unfortunately you have to set border-style: none;, else the borders of empty cells will be painted anyway (which results in thick lines).
I tried additional code like:
td:empty {
display: none;
border-style: none;
}
But in my table of 2 columns it removes the borders of either the left or the right column, but never of both...
Any hint at how to remove the borders of empty rows would be appreciated.
in my case cells have Spaces tabs . they are not data.
areAllCellsEmpty : true if, all cells.textContent are empty or Whitespace
innerHTML didnt give the result i wanted.
usage:
hideEmptyRows_ofTableById("myTable_id"); /* <- your table id here */
code:
function isEmptyOrSpaces(str){
return str === null || str.trim() === '' ;
}
function areAllCellsEmpty(row) {
var cells = row.cells;
var anyCellFull = false;
for(var j = 0; j < cells.length; j++) {
if( ! isEmptyOrSpaces(cells[j].textContent) ) {
anyCellFull =true;
break;
}
}
return !anyCellFull;
}
function hideEmptyRows_ofTableById(elem_id){
var table = document.getElementById(elem_id);
var rows = table.getElementsByTagName('tr');
for(var i = 0; i < rows.length; i++) {
if( areAllCellsEmpty(rows[i]) ) {
rows[i].style.display = 'none';
}
}
}