1

This selector doc.getElementsByClassName('value') needs to target the td element which is the next sibling of another td which has the text "sign here" so that the image appended after the "abc:".

How can it be done? Thanks

let w = window.open();
let doc = w.document;
doc.write(raw_html);
doc.close();
let sigImg = new Image();
sigImg.src = signature;
doc.getElementsByClassName('value').appendChild(sigImg); //wrong selector

There are many of td and tr element with different class and values.

<tr>
  <td class="label">sign here</td>
  <td class="value">abc:</td>
</tr>

edit
The element index is not known in advance. only that it is after another td element which has its text equal to "sign here"

7
  • what is signature? Commented Aug 10, 2016 at 4:26
  • getElementsByClassName returns an array-like nodelist. Just access whichever element thru subscript Commented Aug 10, 2016 at 4:26
  • getElementsByClassName returns a NodeList. Try querySelector which takes a CSS selector and returns the first element that matches. Commented Aug 10, 2016 at 4:27
  • @kamoroso94 would the querySelector filter out the results by the text inside the td being "sign here"? and if so, how? can you show in an answer? thx Commented Aug 10, 2016 at 4:31
  • No you can't use CSS selectors to match elements containing a certain text. If I were you, I'd put an id on the element you need and be done with it. Commented Aug 10, 2016 at 4:33

2 Answers 2

1

document.getElementsByClassName returns an HTMLCollection. Use bracket notation to select element at specific index; e.g., [0] to select element at index 0 of returned collection

doc.getElementsByClassName('value')[0].appendChild(sigImg);

To select element where previous element text contains "sign here" you can iterate all elements having className "value", check if element .previousElementSibling .textContent is equal to required text

<table>
  <tbody>
    <tr>
      <td class="label">sign here</td>
      <td class="value">abc:</td>
    </tr>
    <tr>
      <td class="label">do not sign here</td>
      <td class="value">def:</td>
    </tr>
  </tbody>
</table>
<script>
  var sigImg = new Image;
  sigImg.src = "http://lorempixel.com/50/50";
  for (var elem of document.getElementsByClassName("value")) {
    if (elem.previousElementSibling.textContent === "sign here") {
      elem.appendChild(sigImg); break;
    }
  }
</script>

Sign up to request clarification or add additional context in comments.

2 Comments

Why new Image; instead of new Image(); ?
@Rayon Either returns same result function fn() { this.name = 123 } var n = new fn; console.log(n) "The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function."
0

Since there will be many td.labels and td.values, I'd select every td.label and loop trough them comparing their textContent to "sign here" then grab the next element to work with.

var tdLabels = document.querySelectorAll("td.label");
var tdValue = null;
for(var i=0; i<tdLabels.length; i++) {
    var td = tdLabels[i];
    if(td.textContent=="sign here") {
        tdValue = td.parentNode.querySelector("td.value");
        break;
    }
}
// use tdValue somehow, but null if not found

This will find the element you're looking for and store a reference to it in tdValue. If such an element doesn't exist, it will be set to null.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.