Search code examples
javascriptgoogle-chromeelement

Loop on element and extract all child properties


I have the attached HTML HTML I would like a javascript code to execute on chrome console that 1 - go on all the below span

enter image description here

enter image description here

that have a child go recursively run on child and extract property

the output that i woudl like to have is


id="preview:section:subSectionF55group13:subSectionTabF55group13" --> class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" --> data-form-designer-id="" --> "Group 13 Parties"
id="preview:section:subSectionF55group13:subSectionF55-10"--> class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" --> data-form-designer-id="" --> "(05) [3/17] Declarant"
id="preview:section:subSectionF55group13:subSectionF55-10:F55-10-2" ---> class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all other ui-state-hover" --> data-form-designer-id="F55-10-2" --> role="textbox" --> label="(05 016) [3/17a] Name"
id="preview:section:subSectionF55group13:subSectionF55-10:F55-10-3" ---> class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all other ui-state-hover" --> data-form-designer-id="F55-10-3" --->  role="textbox" --> label="(05 017) [3/18] Declarant identification No. "

the label is on the span element on the previous object

i have this code

const myElement = document.getElementById('preview:section:subSectionF55group13');
let child = myElement.querySelector('[class*="ui-accordion-header"]');
let menuName = ""
let contentName = ""
for (let i = 0; i < myElement.children.length; i++) {
  if (myElement.children[i].className == ('ui-accordion-header ui-helper-reset ui-state-default ui-state-active ui-corner-top')){
      menuName=myElement.children[i].innerText
      console.log('ui-accordion-header ' + menuName)
  }
  if (myElement.children[i].className == ('ui-accordion-content ui-helper-reset ui-widget-content')){
      const myContentsElements = document.getElementById(myElement.children[i].id);
      console.log(myContentsElements.children);
      for (let x = 0; x < myContentsElements.children.length; x++) {
        contentName=myContentsElements.children[x].id;
        console.log(myContentsElements.children);
        console.log('ui-accordion-content ' + contentName);
      }
  }
}

I am in particular looking for

0: {id: 'preview:section:subSectionF55group13:subSectionF55-10:F55-10-2', text:'Group 13 Parties', text:(05) [3/17] Declarant, text: '(05 016) [3/17a] Name'} 
1: {id: 'preview:section:subSectionF55group13:subSectionF55-10:F55-10-3', text:'Group 13 Parties', text:(05) [3/17] Declarant, text '(05 017) [3/18] Declarant identification No.'} 

where the id is the id of the input/select near to the label

enter image description here


Solution

  • I believe you want this

    https://jsfiddle.net/mplungjan/cbdu10zp/

    const myElement = document.getElementById('preview:section:subSectionF55group13');
    let headers = [...myElement.querySelectorAll('[class*="ui-accordion-header"]')].map(elem => elem.textContent);
    let labelsAndInput = [...myElement.querySelectorAll('[class*="ui-accordion-content"] *')]
      .filter(elem => elem.tagName === "LABEL" || elem.tagName === "INPUT")
      .filter(elem => elem.id || elem.textContent.trim())
      .map(elem => ({
        type: elem.tagName,
        role: elem.getAttribute('role'),
        dataformdesignerid: elem.getAttribute('data-form-designer-id'),
        id: elem.id,
        text: elem.textContent.trim()
      }));
    console.log(labelsAndInput)
    const contents = labelsAndInput.reduce((acc, cur, i) => {
      if (cur.type === "INPUT") {
        const elem = labelsAndInput[i - 1];
        acc[cur.id] = {
          id: elem.id,
          text: elem.text,
          role: cur.role,
          dataformdesignerid: elem.dataformdesignerid,
        }  
      }  
      return acc
    }, {});
    
    console.log(headers)
    console.log(contents)