Find Element tr of a certain content

10

I'd like to know how to find a particular <tr> element in a numbered table. For example: In a table where each <tr> line has its <td> cells numbered 1-5, containing 4 lines <tr> , if I pass the number 15, I get the 3rd line <tr> , if I pass the number 17, I get the 4th line <tr> , and so on.

With table.match(/<tr>/g) , I get all 4 elements <tr> , but what I want is to get only a <tr> element, as final result, according to the numerical criteria explained above.

The goal is to apply a style to the <tr> tag, an outline, outline: solid 1px red; , to highlight.

var table = ['<table>
<tr>
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>
</tr>
<tr>
<td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
</tr>
<tr>
<td>11</td><td>12</td><td>13</td><td>14</td><td>15</td>
</tr>
<tr>
<td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>
</tr>
</table>'];

table.match(/<tr>/g); // Me devolve todos os elementos <tr>

The table is originally the function below that generates a Calendar. I've already been able to highlight the current day . Now the challenge is to do the same with the current week :

function Calendar(id, year, month) { 
  var elem = document.getElementById(id)

  var mon = month - 1
  var d = new Date(year, mon)
  var e = new Date();
  var weekDay = ["Sun", "Mon", "Tues", "Wed", "Thu", "Fri", "Sat"];
  var months = ['January', 'Frebruary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  var table = ['<table><tr>']

  table.push('<th colspan = 4>' + months[mon] + '</th>' + '<th colspan = 3>' + year + '</th>' + '</tr><tr>')
  for (var i = 0; i <= 6; i++ ) {
    table.push('<th>' + weekDay[i] + '</th>')
  }
  table.push('</tr><tr>')

  for (var i=0; i<d.getDay(); i++) {
    table.push('<td></td>')
  }

  while(d.getMonth() == mon) {

    if (d.getDate() == e.getDate()) { // Condicional para dar destaque ao dia atual
    table.push('<td class=day>'+d.getDate()+'</td>')
    } else {
    table.push('<td>'+d.getDate()+'</td>')
    }

    if (d.getDay() % 7 == 6) {
      table.push('</tr><tr>')
    }

    d.setDate(d.getDate()+1)  
  }

  for (var i=d.getDay(); i<7; i++) {
    table.push('<td></td>')
  }

  table.push('</tr></table>')

  elem.innerHTML = table.join('\n')
}

new Calendar("cal", 2015, 3);
    
asked by anonymous 30.03.2015 / 17:09

2 answers

8

I suggest doing this via HTML in the Browser which is way better than RegEx to read HTML. You do not need to join the DOM but using the Browser is more secure.

Suggestion:

Bring this HTML to a DIV:

var div = document.createElement('div');
div.innerHTML = table;

Put the arrays method into the methods of the nodeLists so you can use querySelectorAll :

NodeList.prototype.filter = Array.prototype.filter;

Use the methods you use in the DOM in this div:

var value = input.value || 0;
var tds = div.querySelectorAll('td');
var match = tds.filter(function (td) {
    return td.innerHTML == value;
});
var resultado = match && match[0].parentNode;
alert(resultado.innerHTML); // vai mostrar só a linha que queres

example: link

EDIT:

Following the clarifications added to the question the final result with my code was to add at the end of this function these lines:

// mark this week
var today = (new Date()).getDate();
var tds = elem.querySelectorAll('td');
NodeList.prototype.filter = Array.prototype.filter;
var match = tds.filter(function (td) {
    return td.innerHTML == today;
});
if (match) match[0].parentNode.style.outline = 'solid 1px red';

jsFiddle: link

    
30.03.2015 / 18:28
10

EDIT

If the table structure does not really change:

  • do not contain tables within tables
  • HTML is well formed

Then you can use regex to find the TR opening tag containing the TD with the desired number, as shown in the snippet below:

var num = 8;

var tabela = getTable();

var tabelaSubst = tabela.replace(RegExp("\<\s*tr\s*\>(?=((?!\<\s*\/tr\s*\>).)*\D\s*0*"+num+"\s*\D)", 'g'), "<TR class='achou'>");

document.getElementById("content").innerHTML = (tabelaSubst);

function encodeHtml(rawStr) {
    return rawStr && rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
        return '&#' + i.charCodeAt(0) + ';';
    });
}

function getTable() {
    var table = ['<table>' +
        '<tr>' +
        '<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>' +
        '</tr>' +
        '<tr>' +
        '<td>6</td><td>7</td><td> 08</td><td>9</td><td>10</td>' +
        '</tr>' +
        '<tr>' +
        '<td>11</td><td>12</td><td>13</td><td>14</td><td>15</td>' +
        '</tr>' +
        '<tr>' +
        '<td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>' +
        '</tr>' +
        '</table>'
    ];
    return table[0];
}
.achou {
     color: red;
}
<div id="content"></div>

jsfiddle

OLD: using XML parser

You can use broswer XML parse APIs, and use XPath for this.

What API's are these?

  • DOMParser : allows parsing of XML documents (HTML well-formed is XML), and create an AST, which contains the document structure

  • Document.evaluate : allows you to search using XPath on an XML document that has been fetched by DOMParser , or even the loaded document, ie the loaded page's own DOM

To support IE8

IE8 does not support the above APIs directly ... but it's possible to use your own:

  • ActiveXObject("Microsoft.XMLDOM") allows parsing of XML, besides applying XPath, all using a single object

XPath

This is the default language for querying XML documents. But do not get discouraged by the word Path as XPath is far from being a simple path selector.

Example

function getTrsModernBrowser() {
    var parser = new DOMParser();
    var frag = parser.parseFromString(getTable()[0], "text/xml");
    var xpathResult = frag.evaluate("//tr[td[text()=17]]", frag, null, XPathResult.ANY_TYPE, null);

    var trs = [];
    var result = xpathResult.iterateNext();
    while (result) {
        trs.push(result);
        result = xpathResult.iterateNext();
    }
    return trs;
}

function getTrsIE8() {
    var frag = new window.ActiveXObject("Microsoft.XMLDOM");
    frag.async = "false";
    frag.loadXML(getTable()[0]);
    frag.setProperty("SelectionLanguage", "XPath");
    var results = frag.selectNodes("//tr[td[text()=17]]");
    var trs = [];
    for (it = 0; it < results.length; it++)
        trs.push(results[it]);
    debugger;
    return trs;
}

function getTrs() {
    return window.ActiveXObject ? getTrsIE8() : getTrsModernBrowser();
}

var trs = getTrs();
for (var itTr = 0; itTr < trs.length; itTr++) {
    document.getElementById("content").innerHTML = encodeHtml(
        trs[itTr].outerHTML // browsers que suportam a API DOMParser
        || trs[itTr].xml // IE8
    );
}

function encodeHtml(rawStr) {
    return rawStr && rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
        return '&#' + i.charCodeAt(0) + ';';
    });
}

function getTable() {
    var table = ['<table>' +
        '<tr>' +
        '<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>' +
        '</tr>' +
        '<tr>' +
        '<td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>' +
        '</tr>' +
        '<tr>' +
        '<td>11</td><td>12</td><td>13</td><td>14</td><td>15</td>' +
        '</tr>' +
        '<tr>' +
        '<td>16</td><td>17</td><td>18</td><td>19</td><td>20</td>' +
        '</tr>' +
        '</table>'
    ];
    return table;
}
<div id="content"></div>

jsfiddle, what do you like to play there instead of the SOPT snippet

Dissecting XPath above example

  • //tr[td[text()=17]]

  • // at beginning instructs the engine to fetch nodes at all levels, not just at the root
  • tr is the element to be found, and could be the name of any element
  • [ condição ] this operator is an assertion about the previous element, only tr s will be selected with the characteristics defined inside the []
  • text()=17 indicates that the text of the element being parsed should be number 17 . Attention to what I said: "THE NUMBER 17" ... will be used numerical comparator. Therefore, the text of the element can be "017", "00017", "17", etc.
30.03.2015 / 17:52
___ ___ erkimt What are the data transfer forms available to JavaScript? ______ qstntxt ___

It is common to find questions, answers and tutorials talking about AJAX, which is nothing more than %code% , as a way of transferring data between two computers.

I would like to know if there are other forms , whether standard or proprietary, limited in some condition or open to any user and site. An example of a limited form, if any, would be an API restricted to extensions.

In particular, but not restricting, I'm looking for a way to transfer data - something between 10 and 30 bytes - in the fastest way possible between two computers within the same network. Peer-to-Peer would be ideal, but I do not know if JS supports it. I have already tried testing services such as Firebase , which allowed a minimum response time, however, using a server out of network and with occasional loss of data.

Knowing other ways I wanted to find one that would fit better with what I'm developing. It does not look like the answer will be anything big: the options seem to be quite limited, since it looks like only AJAX is used.

    
______ azszpr8188 ___

There are several APIs that will allow you to transport data via Javascript.

Some will only allow you to receive data, others will allow you to send and receive.

The ones that allow you to send and receive data are:

  • %code%
    • Requests via HTTP protocol
  • %code%
    • It is a cross-compatible HTTP protocol focused on message exchanges lighter and faster than request, but it does not have a state resolution as efficient as %code%
    • W3C Specification
  • %code%
    • Peer-to-peer data exchange protocol was created to solve the problem of video and audio transmissions between browsers.
    • W3C Specification

If the data transmission needs to be p2p, the ideal is to use WebRTC, but it is still rather complex to create a server that will make the handshake between two browsers and start communication.

A simpler solution is to use WebSockets , but all information will go through a server that will receive data from one client and send it to another or other clients. But the websocket has the constraint of working with UTF-8, however it is possible to use data converters to convert binary data to UTF-8 before being transmitted and back to the original format when received, there are several ways, one of them is using the %code% .

    
______ azszpr8194 ___

I suggest using Socket IO, a javascript extension already adapted for use in cross-browser and that has an extra advantage, it chooses the most efficient way to carry data between the technologies below (which are the answer to your question) :

1) WebSocket;
2) Adobe Flash Socket;
3) AJAX long polling;
4) AJAX multipart streaming;
5) Forever iframe;
6) JSONP Polling.

Still, this extension has excellent compatibility: IE 5.5+; Safari 3+; Chrome 4+; Firefox 3+; Opera 10.61+; Iphone / Ipad Safari; Android Webkit and Webkits Webkit.

link

I have had excellent experiences with this extension. When you opt for a path where fallbacks are already included, everything gets easier!

Good Luck!

    
___ What's the difference between System.Web.Http and System.Web.Mvc?