JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

square attempt. choose up to 3 loci to cross.<br>

<div class='mother_bg'>
    Mother: <span id='punnett_mother'>(img here)</span> 
    <div id='mother_dropdowns'>(Mother inputs here)</div>
</div>
<div class='father_bg'>
    Father: <span id='punnett_father'>(img here)</span> 
    <div id='father_dropdowns'>(Father inputs here)</div>
</div>

How many loci to use? (remove later, or use a few checkboxes)
<select id='loci_use'>
    <option value='1'>E</option>
    <option value='2'>E,A</option>
    <option value='3'>E,A,Cr</option>
</select>

<div id='punnett_table'></div>

<div id='punnett_list'></div>

CSS

#punnett_table table {
    width: 100%;
    margin: 20px 0px;
    border-collapse: collapse;
}

#punnett_table table td {
    border: 1px solid grey;
    padding: 5px;
    text-align: center;
}

.father_bg {
    background-color: powderblue;
}
.mother_bg {
    background-color: lightpink;
}

.bold {
    font-weight: bold;
}

JavaScript

let genome = {
    e: {name: "Extension", wt: "E", alleles: ["E","e"]},
    a: {name: "Agouti", wt: "A", alleles: ["A","a"]},
    cr: {name: "Cream", wt: "cr", alleles: ["Cr","cr","prl"]},
    ch: {name: "Champagne", wt: "ch", alleles: ["Ch","ch"]}
};

/*
* Can use 1-3 loci. Create HTML table of results,
* And also list with each outcome's chance %.
*/
class Punnett {
    
    constructor(loci = ["e"]){
        this.loci = loci;
        this.generateDropdowns();
        //this.getInputs();
        //this.updateParents();
        //this.generateTable();
    }
    
    setMother(g){
        this.mother = g;
    }
    setFather(g){
        this.father = g;
    }
    setLoci(array){
        this.loci = array;
    }
    
    // Changed a checkbox, which loci to use
    changeLoci(){
        let count = $("#loci_use").val();
        this.loci = ["e"];
        if(count > 1){ this.loci.push("a"); }
        if(count > 2){ this.loci.push("cr"); }
        this.generateDropdowns();
    }
    
    // Changed an allele dropdown, regen parents
    updateParents(){
        this.getInputs();
        this.updateParent("mother");
        this.updateParent("father");
        
        this.offsprings = [];
        // remove later
        this.generateTable();
    }
    
    // their alleles were changed. regen img/desc
    updateParent(parent){
        $("#punnett_" + parent).html(JSON.stringify(this[parent]));
    }
    
    // similar to dropdown func, but need 2 sets, m/f
    generateDropdowns(){
        let htmlM = "";
        let htmlF = "";
        for(let index in this.loci){
            let locusName = this.loci[index];
            let locus = genome[locusName];
            locus.code = locusName;
            htmlM += this.generateDropdown("m", locus, 1);
            htmlM += this.generateDropdown("m", locus, 2);
            htmlF += this.generateDropdown("f", locus, 1);
            htmlF += this.generateDropdown("f", locus, 2);
        }
       ...