Home > Blockchain >  How to clone or create a nested DOM node and change all its containing id values according to a curr
How to clone or create a nested DOM node and change all its containing id values according to a curr

Time:12-08

I need to display some numbers, strings from a class named Student, but i can't figure it out how i can change the id from children element. I have to use JavaScript.

what i tried to do:

class Student{
    static count = 0;
    constructor(nume, prenume, data_nasterii, foaie_matricola){
        this.IdClasa =   Student.count;
        //definirea atributelor
        this.nume = nume; 
        this.prenume = prenume;
        this.data_nasterii = data_nasterii;
        this.foaie_matricola = foaie_matricola;
    }
    afiseazaVarsta(){
    
    }
    afiseazaNotele(){
        
    }
    calculeazaMedia(){
        
    }
    adaugaNota(nota_noua){
        
    }
}
var Stud = [new Student("Name", "Name1", "2000.01.01", "0123123"), 
            new Student("Green", "Blue", "2022/12.12", "321321")];

function afisareStudenti(){
    let i = 0; let bol = false;
    for(let x=1; x<=Student.count; x  ) {
        console.log(document.getElementById("AfisareStudenti" x)==null);
        if(document.getElementById("AfisareStudenti" x)==null)
        {
            i = x;
            bol = true;
            break;
        } else {
            bol = false;
        }
            
    }
    

    if((i<=Student.count)&&(bol==true)){
        for(i; i<=Student.count; i  ) {
            console.log("i=" i);
            var div = document.querySelector('#AfisareStudenti1');
            var divClone = div.cloneNode(true);
            console.log(divClone);
            divClone.id = 'AfisareStudenti' (i);
            div.after(divClone);
            var NumeStud = document.getElementById("NumeStudent" (i-1));
            var PrenumeStud = document.getElementById("PrenumeStudent" (i-1));
            var dataNastStud = document.getElementById("intData" (i-1));
            var FoaiaMatStud = document.getElementById("FoaiaMatStud" (i-1));
            NumeStud.id = "NumeStudent" (i);
            PrenumeStud.id = "PrenumeStud" (i);
            dataNastStud.id = "intData" (i);
            FoaiaMatStud.id = "FoaiaMatStud" (i);
        }
    }
}

and this is the html file(the div that i want to clone):

<!--AFISARE-->
<div id="AfisareStudenti1">
    <h2> Afisare Student 1</h2>
    <label>Ce student doriti sa modificati?&emsp;</label>
    <form>
          <label>Nume:</label><br>
          <input type="text" id="NumeStudent1"><br>
          
          <label>Prenume:</label><br>
          <input type="text" id="PrenumeStudent1"><br>
          
          <label>Data Nasterii:</label><br>
          <input type="date" id="intData1"><br>
          
          <label>Foaie matricola:</label><br>
          <input type="text" id="FoaiaMatStud1"><br><br>
          
          <input  type="submit" value="Afisare"
                 onclick="afisareMeniuAfisStudenti()">
    </form>
</div>

the class is saved in a dynamic array (could be n object of the class) so i have to make somehow to display the information dynamic. My version changes the id from all elements with the same id (every incrementation of i, the idnumber from id is incremented also). I tried to create that div with document.createElement but is impossible(at least for me) xD . I started coding in javascript 2 days ago, so please take it slow on me :(

I think i found the problem, but it doesn't solve it. (i need to put (i-1) when calling for getting the ids). (Newbie mistake)

CodePudding user response:

To change the id attribute of children elements, you could use Element.querySelector() on divClone.

Because if you use Document.querySelector() or Document.getElementById() you will get the first element that matches your selector (i.e.children of div#AfisareStudenti1).

let i = 2;
var div = document.querySelector('#AfisareStudenti1');
var divClone = div.cloneNode(true);
divClone.id = 'AfisareStudenti' (i);
divClone.querySelector("h2").innerText = "Afisare Student "   i;
var NumeStud = divClone.querySelector("#NumeStudent1");
var PrenumeStud = divClone.querySelector("#PrenumeStudent1");
var dataNastStud = divClone.querySelector("#intData1");
var FoaiaMatStud = divClone.querySelector("#FoaiaMatStud1");
NumeStud.id = "NumeStudent" (i);
PrenumeStud.id = "PrenumeStud" (i);
dataNastStud.id = "intData" (i);
FoaiaMatStud.id = "FoaiaMatStud" (i);
div.after(divClone);
<div id="AfisareStudenti1">
  <h2> Afisare Student 1</h2>
  <label>Ce student doriti sa modificati?&emsp;</label>
  <form>
    <label>Nume:</label><br>
    <input type="text" id="NumeStudent1" /><br>
    <label>Prenume:</label><br>
    <input type="text" id="PrenumeStudent1" /><br>
    <label>Data Nasterii:</label><br>
    <input type="date" id="intData1" /><br>
    <label>Foaie matricola:</label><br>
    <input type="text" id="FoaiaMatStud1" /><br><br>
    <input  type="submit" value="Afisare" onclick="afisareMeniuAfisStudenti()" />
    </form>
</div>

CodePudding user response:

Tom's answer above is what you want for the element id problem that you asked about.

For your code in particular, you are going to have a couple other problems:

Because the final input is type="submit", its going to reload the page by default when it is clicked. The name of the "onclick" function also needs to match the function you defined (afisareStudenti).

You have:

<input  type="submit" value="Afisare" onclick="afisareMeniuAfisStudenti()">

Change this to:

<input  type="submit" value="Afisare" onclick="afisareStudenti(event)">

Now, when you click that button, it will call the afisareStudenti function and pass in the "event". So if you change:

 function afisareStudenti(){
   let i = 0; let bol = false;

to:

 function afisareStudenti(event){
   event.preventDefault()
   let i = 0; let bol = false;

This will correctly call your function, and prevent the "default" action of that submit button from reloading the page.

CodePudding user response:

Having commented ...

"I have the feeling that if provided with the broader picture the audience could be of much more help since the OP could be provided back with leaner/cleaner and better maintainable approaches."

... I nevertheless hereby lately provide a template-based approach which, besides supporting the OP's id based querying of student-items, is also easier to read and to maintain.

The code provided within the example-code's main function does not just implement the usage of the template-based node-creation via template literals and DOMParser.parseFromString but also prevents the default behavior of each student-form's submit-button by making use of event-delegation.

function createStudentElement(studentId) {
  const markup =
    `<div  id="AfisareStudenti${ studentId }">
      <h2> Afisare Student ${ studentId }</h2>
      <label>Ce student doriti sa modificati?&emsp;</label>
      <form>
        <label>Nume:</label><br>
        <input type="text" id="NumeStudent${ studentId }"><br>

        <label>Prenume:</label><br>
        <input type="text" id="PrenumeStudent${ studentId }"><br>

        <label>Data Nasterii:</label><br>
        <input type="date" id="intData${ studentId }"><br>

        <label>Foaie matricola:</label><br>
        <input type="text" id="FoaiaMatStud${ studentId }"><br><br>

        <input
           type="submit" value="Afisare"
          onclick="afisareMeniuAfisStudenti(${ studentId })"
        >
      </form>
    </div>`;

  const doc = (new DOMParser).parseFromString(markup, 'text/html');

  return doc.body.removeChild(doc.body.firstElementChild);
}

// the button click handler.
function afisareMeniuAfisStudenti(studentId) {
  console.log({ studentId })
}


function main() {
  const itemsRoot = document.querySelector('.student-items');

  // - prevent any form-submit by making use of event-delegation.
  itemsRoot.addEventListener('submit', evt => evt.preventDefault());

  // - just for demonstration purpose ...
  //   ... create student-items from a list of student IDs.
  [1, 2, 3, 4, 5].forEach(studentId =>
    itemsRoot.appendChild(
      createStudentElement(studentId)
    )
  );
}

main();
.as-console-wrapper { left: auto!important; width: 50%; min-height: 100%; }
<div ></div>

  • Related