表单未提交表格中嵌套元素的数据

问题描述 投票:0回答:1

我运行以下代码来从动态创建的表元素中获取值。当我提交显示时,我无法获取输入数据(请参阅控制台)。我不知道该怎么办,请指教!

console.clear();
var dimensions = [4, 4];
var controlType = [];

// empty and repopulate display with specified dimensions
function populate() {
    var table = $("#display > table > tbody");
    var tr = document.createElement("tr");
    var td = document.createElement("td");
    table.empty();

    let row = 0;
    for (let i = 0; i < dimensions[1]; i++) {
        row++;
        let column = 0;
        var newRow = $(tr).clone().appendTo(table);
        for (let i = 0; i < dimensions[0]; i++) {
            column++
            let position = row + "-" + column
            let newCell = $(td).clone().appendTo(newRow);
            $(newCell).append("<input type='button' name='" + position + "' class='on' form='display'>")
            $(newCell.children()).click(function () {
                let inputType = $("input:checked").val();
                if (inputType == "lights" && !$(this).hasClass("wall")) {
                    $(this).toggleClass("on off");
                } else if (inputType == "walls") {
                    $(this).toggleClass("wall");
                };
            });
        };
    };

    console.log("Populated display\nDimensions:", dimensions[0] + "x" + dimensions[1]);
};

// when document is ready
$(document).ready(function () {
    populate();

    // solve the puzzle input
    $("#display").submit(function (e) {
        e.preventDefault();

        let formData = $(this).serializeArray();
        console.log(formData);
    });

    // generate a dimensions list containing user input height and width on submit
    $("#options").submit(function (e) {
        e.preventDefault();

        let formData = $(this).serializeArray();
        formData.forEach(function (i) {
            let val = Math.round(i.value)
            if (i.name == "width") dimensions[0] = val;
            if (i.name == "height") dimensions[1] = val;
        });
        
        populate();
    });
});
:root {
    --font: Arial;
    --fs: 30px;
    --inputBg: whitesmoke;
    --border: 2px solid lightgrey;
}

/* always show arrow buttons on number input */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
    opacity: 1;
}

/* body formatting */
body {
    width: auto;
    height: auto;
    font-family: var(--font);
    font-size: var(--fs)
}

/* lights out puzzle formatting */
#lightsOut {
    width: fit-content;
    height: auto;
    margin: 0px;
    border: var(--border);
    display: flex;
    gap: 0.2em;
}

/* display formatting */
#display {
    & table {
        height: fit-content;
        margin-top: 0.1em;
        margin-right: 0.1em;
        border-collapse: collapse;
        & tr {
            & td {
                padding: 0px;

                & input {
                    width: 1.5em;
                    height: 1.5em;
                    font-size: inherit;
                    margin-bottom: 0.1em;
                    margin-left: 0.1em;
                    padding: 0px;
                }
                & .on {
                    background-color: var(--inputBg);
                    border: var(--border);
                }
                & .off {
                    background-color: darkgrey;
                    border: 2px solid grey;
                }
                & .wall {
                    background-color: transparent;
                    border: 2px solid transparent;
                }
            }
        }
    }
    & span {
        width: 100%-var(--margin);
        height: 1.5em;
        display: flex;
        font-size: inherit;
        text-align: center;
        margin-bottom: 0.1em;
        margin-left: 0.1em;

        & input[type="submit"] {
            width: 100%;
            height: 1.5em;
            font-size: inherit;
            background-color: var(--inputBg);
            margin-right: 0.1em;
            border: var(--border);
        }
    }
}

/* user interface */
#ui {
    display: flex;
    flex-direction: column;
    margin-top: 0.1em;
    margin-right: 0.1em;

    /* options formatting */
    & #options,
    #controls {
        display: flex;
        flex-direction: column;

        & span {
            width: 100%;
            height: 1.5em;
            display: flex;
            justify-content: left;
            font-size: inherit;
            text-align: center;
            margin-bottom: 0.1em;
            margin-left: 0.1em;

            & label {
                width: 3.25em;
                height: 1.5em;
                font-size: inherit;
                margin-right: 0.5em;
                display: flex;
                align-items: center;
            }

            & input[type="number"] {
                width: 1.5em;
                height: 1em;
                font-size: inherit;
                padding: 0px;
                align-self: center;
            }

            & input[type="radio"] {
                width: 1em;
                height: 1em;
                font-size: inherit;
                margin-left: 0px;
                align-self: center;
            }

            & input[type="submit"] {
                width: 100%;
                height: 1.5em;
                font-size: inherit;
                background-color: var(--inputBg);
                margin-right: 0.1em;
                border: var(--border);
            }
        }
    }
}
<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" href="lightsOut.css">
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script src="lightsOut.js"></script>
</head>

<body>
    <div id="lightsOut">
        <form id="display">
            <table>
                <tbody>
                </tbody>
            </table>
            <span class="submit">
                <input value="Solve" type="submit">
            </span>
        </form>
        <span id="ui">
            <form id="options">
                <span class="number">
                    <label for="width">Width:</label>
                    <input name="width" id="width" type="number" value="4" min="3" max="15">
                </span>
                <span class="number">
                    <label for="height">Height:</label>
                    <input name="height" id="height" type="number" value="4" min="3" max="15">
                </span>
                <span class="submit">
                    <input value="Apply" type="submit">
                </span>
            </form>
            <form id="controls">
                <span class="radio">
                    <input name="type" id="lights" type="radio" value="lights" checked>
                    <label for="lights">Lights</label>
                </span>
                <span class="radio">
                    <input name="type" id="walls" type="radio" value="walls">
                    <label for="walls">Walls</label>
                </span>
            </form>
        </span>
    </div>
</body>

</html>

当您点击“求解”按钮时,控制台将显示一个空列表,而不是所有输入。我尝试为每个输入添加一个值,但这没有帮助。

javascript html jquery
1个回答
0
投票

这是一个解决方案......

它包括解析表格的所有单元格以获取

className
的不同值并将它们放入数组中。

抱歉,我失去了一点时间来恢复您的界面...

const
  formOptionsControls = document.querySelector('#options-controls')
, lightsOut_Table     = document.querySelector('#lightsOut > table > tbody')
, lightsOut_Solve     = document.querySelector('#lightsOut > table > caption')
  ;
setTableDims();
formOptionsControls.addEventListener('submit',setTableDims);

lightsOut_Table.addEventListener('click',({target: TDx}) => 
  {
  if (!TDx.matches('td')) return;

  let xClassName = formOptionsControls.type.value === 'wall' ? 'wall' : 'off';

  TDx.classList.toggle(xClassName);
  // console.log( TDx.closest('tr').rowIndex, TDx.cellIndex );
  })

lightsOut_Solve.addEventListener('click', e => 
  {
  let 
    xRows = lightsOut_Table.rows.length
  , xCols = lightsOut_Table.rows[0].cells.length
  , resp  = []
    ; 
  for( let r = 0; r < xRows; r++)
    {
    resp.push([]);
    for( let c = 0; c < xCols; c++)
      resp[r].push( lightsOut_Table.rows[r].cells[c].className || 'on');
    }
  console.clear();
  console.log( JSON.stringify({xRows,xCols}) );
  console.log( JSON.stringify(resp,0,2) );
  })

function setTableDims(e)
  {
  if (!!e) e.preventDefault();

  let dimensions = [ formOptionsControls.width.valueAsNumber, formOptionsControls.height.valueAsNumber ];
  console.clear();
  console.log("Populated display\nDimensions:", dimensions[0] + "x" + dimensions[1]);

  while (lightsOut_Table.rows.length ) lightsOut_Table.deleteRow(-1);

  for (let r=0;r<formOptionsControls.height.valueAsNumber; r++)
    {
    let newRow = lightsOut_Table.insertRow();
    for(let c = formOptionsControls.width.valueAsNumber; c--;) newRow.insertCell();
    }
  }
body {
  font-family : Arial, Helvetica, sans-serif;
  font-size   : 30px;
  }
#lightsOut {
  border      : 0.1em solid lightgrey;
  display     : flex;
  gap         : 0.2em;
  width       : fit-content;
  line-height : 1.5em;
  }
table {
  border-collapse : separate;
  border-spacing  : 0.1em;
  background      : white;
  height          : fit-content;
  }
td, caption {
  cursor      : pointer;
  height      : 1.5em;
  background  : whitesmoke;
  box-sizing  : border-box;
  border      : 0.1em solid lightgrey;
  }
td { 
  width     : 1.5em;
  }
td.off {
  background   : darkgrey;
  border-color : grey;
  }
td.wall {
  background   : white !important;
  border-color : white !important;
  }
caption {
  caption-side : bottom;
  margin       : 0 .1em .1em .1em;
  }
form#options-controls {
  width   : 6em;
  padding : .2em .2em 0 0;
  }
label { 
  display : block;
  }
label > input[type="number"] {
  font-size  : .9em;
  text-align : center;
  float      : inline-end;
  padding    : 0;
  width      : 2.3em;
  }
button { 
  display    : block;
  width      : 6em;
  font-size  : 1em;
  padding    : 0;
  height     : 1.5em;
  background : whitesmoke;
  box-sizing : border-box;
  border     : 0.1em solid lightgrey;
  margin     : .1em 0 .3em 0;
  cursor     : pointer;
  }
input[type="radio"] {
  width       : 1em;
  height      : 1em;
  font-size   : inherit;
  margin-left : .2em;
  align-self  : center;
  }
label:has(input[type="radio"]) {
  cursor      : pointer;
  }  
td:hover, caption:hover, button:hover {
  background  : #b5d11566;
  }
<div id="lightsOut">
  <table>
    <caption> Solve </caption>
    <tbody></tbody>
  </table>
  <form id="options-controls">
    <label>
      Width:
      <input name="width" type="number" value="4" min="3" max="15" required>
    </label>
    <label>
      Height:
      <input name="height" type="number" value="4" min="3" max="15" required>
    </label>
    <button> Apply </button>
    <label>
      <input name="type" type="radio" value="light" checked >
      Lights 
    </label>
    <label>
      <input name="type" type="radio" value="wall" >
      walls 
    </label>
  </form>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.