gpt4 book ai didi

javascript - 如何在多步 javascript 表单中添加单选按钮、复选框和选择字段?

转载 作者:行者123 更新时间:2023-12-04 11:04:04 26 4
gpt4 key购买 nike

我有以下片段,我通过多步骤表单接受详细信息。问题是目前它只接受文本输入字段。如您所见,问题数组包含以下问题类型:

  • 问题 1 可以作为文本输入,因为它可以接受名称。
  • 问题 2 应该是一个单选按钮,因为它会接受性别。
  • 问题 3 应该再次是文本输入字段,带有 DOB 的日期选择器,
  • 问题 4 应该是从列表中选择国家的选择框,最后是
  • 问题 5 的输入类型应为选中所有用户有兴趣看到的复选框(男性、女性、其他)。

  • 但是,由于我是 JavaScript 新手,所以我坚持实现这一点。我该如何实现?
    JavaScript的相关部分是:
    // load the next question
    function putQuestion() {
    inputLabel.innerHTML = questions[position].question
    inputField.type = questions[position].type || 'text'
    inputField.value = questions[position].answer || ''
    inputField.focus()

    // set the progress of the background
    progress.style.width = position * 100 / questions.length + '%'
    previousButton.className = position ? 'ion-android-arrow-back' : 'ion-person'
    showCurrent()
    }
    完整的工作片段。

    var questions = [
    {question: "What's your full name?"}, // TEXT INPUT FIELD
    {question: "What's your gender?"}, // RADIO BUTTONS {male, female, other}
    {question: "What's your date of birth?"}, // TEXT INPUT FIELD WITH id="datepicker"
    {question: "What's your country?"}, // SELECT BOX WITH LIST OF COUNTRIES IN IT
    {question: "Interested in?"} // CHECKBOXES {male, female, other}
    ]

    //do something after the questions have been answered
    var onComplete = function() {
    var h1 = document.createElement('h1')
    h1.appendChild(document.createTextNode('Thanks ' + questions[0].answer + ' for checking this pen out!'))
    setTimeout(function() {
    register.parentElement.appendChild(h1)
    setTimeout(function() { h1.style.opacity = 1 }, 50)
    }, 1000)
    }

    ;(function(questions, onComplete) {
    var tTime = 100 // transition transform time from #register in ms
    var wTime = 200 // transition width time from #register in ms
    var eTime = 1000 // transition width time from inputLabel in ms

    // init
    if (questions.length == 0) return
    var position = 0
    putQuestion()

    forwardButton.addEventListener('click', validate)
    inputField.addEventListener('keyup', function(e) {
    transform(0, 0) // ie hack to redraw
    if (e.keyCode == 13) validate()
    })

    previousButton.addEventListener('click', function(e) {
    if (position === 0) return
    position -= 1
    hideCurrent(putQuestion)
    })

    // load the next question
    function putQuestion() {
    inputLabel.innerHTML = questions[position].question
    inputField.type = questions[position].type || 'text'
    inputField.value = questions[position].answer || ''
    inputField.focus()

    // set the progress of the background
    progress.style.width = position * 100 / questions.length + '%'
    previousButton.className = position ? 'ion-android-arrow-back' : 'ion-person'
    showCurrent()
    }

    // when submitting the current question
    function validate() {
    var validateCore = function() {
    return inputField.value.match(questions[position].pattern || /.+/)
    }

    if (!questions[position].validate) questions[position].validate = validateCore
    // check if the pattern matches
    if (!questions[position].validate())
    wrong(inputField.focus.bind(inputField))
    else ok(function() {
    // execute the custom end function or the default value set
    if (questions[position].done) questions[position].done()
    else questions[position].answer = inputField.value
    ++position
    // if there is a new question, hide current and load next
    if (questions[position]) hideCurrent(putQuestion)
    else hideCurrent(function() {
    // remove the box if there is no next question
    register.className = 'close'
    progress.style.width = '100%'
    onComplete()
    })
    })
    }

    // helper
    function hideCurrent(callback) {
    inputContainer.style.opacity = 0
    inputLabel.style.marginLeft = 0
    inputProgress.style.width = 0
    inputProgress.style.transition = 'none'
    inputContainer.style.border = null
    setTimeout(callback, wTime)
    }

    function showCurrent(callback) {
    inputContainer.style.opacity = 1
    inputProgress.style.transition = ''
    inputProgress.style.width = '100%'
    setTimeout(callback, wTime)
    }

    function transform(x, y) {
    register.style.transform = 'translate(' + x + 'px , ' + y + 'px)'
    }

    function ok(callback) {
    register.className = ''
    setTimeout(transform, tTime * 0, 0, 10)
    setTimeout(transform, tTime * 1, 0, 0)
    setTimeout(callback, tTime * 2)
    }
    function wrong(callback) {
    register.className = 'wrong'
    for (var i = 0; i < 6; i++) // shaking motion
    setTimeout(transform, tTime * i, (i % 2 * 2 - 1) * 20, 0)
    setTimeout(transform, tTime * 6, 0, 0)
    setTimeout(callback, tTime * 7)
    }
    }(questions, onComplete))
    @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap');
    body {
    margin: 0;
    background: #fbc02d;
    font-family: 'Roboto', sans-serif;
    overflow-x: hidden;
    }

    h1 {
    position: relative;
    color: #fff;
    opacity: 0;
    transition: .8s ease-in-out;
    }

    #progress {
    position: absolute;
    background: #c49000;
    height: 100vh;
    width: 0;
    transition: width 0.2s ease-in-out;
    }

    .center {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    }


    #register {
    background: #fff;
    position: relative;
    width: 550px;
    box-shadow: 0 16px 24px 2px rgba(0,0,0,0.14), 0 6px 30px 5px rgba(0,0,0,0.12), 0 8px 10px -5px rgba(0,0,0,0.3);
    transition: transform .1s ease-in-out;
    }

    #register.close {
    width: 0;
    padding: 0;
    overflow: hidden;
    transition: .8s ease-in-out;
    box-shadow: 0 16px 24px 2px rgba(0,0,0,0);
    }

    #forwardButton {
    position: absolute;
    right: 20px;
    bottom: 5px;
    font-size: 40px;
    color: #fbc02d;
    float: right;
    cursor: pointer;
    z-index: 20
    }
    #previousButton {
    position: absolute;
    font-size: 18px;
    left: 30px; /* same as padding on container */
    top: 12px;
    z-index: 20;
    color: #9e9e9e;
    float: right;
    cursor: pointer;
    }
    #previousButton:hover {color: #c49000}
    #forwardButton:hover {color: #c49000}
    .wrong #forwardButton {color: #ff2d26}
    .close #forwardButton, .close #previousButton {color: #fff}

    #inputContainer {
    position: relative;
    padding: 30px 20px 20px 20px;
    margin: 10px 60px 10px 10px;
    opacity: 0;
    transition: opacity .3s ease-in-out;
    }

    #inputContainer input {
    position: relative;
    width: 100%;
    border: none;
    font-size: 20px;
    outline: 0;
    background: transparent;
    box-shadow: none;
    }

    #inputLabel {
    position: absolute;
    pointer-events: none;
    top: 32px; /* same as container padding + margin */
    left: 20px; /* same as container padding */
    font-size: 20px;
    transition: .2s ease-in-out;
    }

    #inputContainer input:valid + #inputLabel {
    top: 6px;
    left: 42px; /* space for previous arrow */
    margin-left: 0!important;
    font-size: 11px;
    font-weight: normal;
    color: #9e9e9e;
    }

    #inputProgress {
    border-bottom: 3px solid #fbc02d;
    width: 0;
    transition: width .6s ease-in-out;
    }

    .wrong #inputProgress {
    border-color: #ff2d26;
    }

    @media (max-width: 420px) {
    #forwardButton {right: 10px}
    #previousButton {left: 10px}
    #inputLabel {left: 0}
    #inputContainer {padding-left: 0; margin-right:20px}
    }
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <div id="progress"></div>
    <div class="center">
    <div id="register">

    <i id="previousButton" class="ion-android-arrow-back"></i>
    <i id="forwardButton" class="ion-android-arrow-forward"></i>

    <div id="inputContainer">
    <input id="inputField" required multiple />
    <label id="inputLabel"></label>
    <div id="inputProgress"></div>
    </div>

    </div>
    </div>

    我知道我需要用有限的代码给出一个最小可重复的例子,但我认为创建一个工作片段可以很好地了解这个微型元素。任何帮助,将不胜感激。提前致谢 :)

    最佳答案

    我尽力按照您的要求做,您会看到我添加了 3 个 div 以包含您的不同请求
    我还修改了您的验证条件
    希望它可以帮助你

    var questions = [
    {
    question: "What's your full name?",
    type: "text"
    }, // TEXT INPUT FIELD
    {
    question: "What's your gender?",
    type: "radio",
    response: ['male','female','other']
    }, // RADIO BUTTONS {male, female, other}
    {
    question: "What's your date of birth?",
    type: "date"
    }, // TEXT INPUT FIELD WITH id="datepicker"
    {
    question: "What's your country?",
    type: "select",
    response: ['UK','FR','DE']
    }, // SELECT BOX WITH LIST OF COUNTRIES IN IT
    {
    question: "Interest in?",
    type: "checkbox",
    response: ['male','female','other']
    } // CHECKBOXES {male, female, other}
    ]

    //do something after the questions have been answered
    var onComplete = function() {
    var h1 = document.createElement('h1')
    h1.appendChild(document.createTextNode('Thanks ' + questions[0].answer + ' for checking this pen out!'))
    setTimeout(function() {
    register.parentElement.appendChild(h1)
    setTimeout(function() { h1.style.opacity = 1 }, 50)
    }, 1000)
    }

    ;(function(questions, onComplete) {
    var tTime = 100 // transition transform time from #register in ms
    var wTime = 200 // transition width time from #register in ms
    var eTime = 1000 // transition width time from inputLabel in ms

    // init
    if (questions.length == 0) return
    var position = 0
    putQuestion()

    forwardButton.addEventListener('click', validate)
    inputField.addEventListener('keyup', function(e) {
    transform(0, 0) // ie hack to redraw
    if (e.keyCode == 13) validate()
    })

    previousButton.addEventListener('click', function(e) {
    if (position === 0) return
    position -= 1
    hideCurrent(putQuestion)
    $('#gender').hide();
    $('#country').hide();
    $('#interest').hide();
    })

    // load the next question
    function putQuestion() {
    $('#gender').hide();
    $('#country').hide();
    $('#interest').hide();
    $(inputField).attr('readonly',false);
    $(inputField).attr('required',false);
    inputLabel.innerHTML = questions[position].question;
    inputField.type = 'text';
    switch(questions[position].type){
    case "text":
    $(inputField).attr('required',true)
    inputField.value = questions[position].answer || '';
    break;
    case "radio":
    $(inputField).attr('readonly',true)
    inputField.value = '';

    let nbrGender = questions[position].response;
    if( $('#gender').children().length > 0 ){
    $('#gender').children().remove()
    }
    $('#gender').show();
    for( var $i = 0; $i < nbrGender.length; ++$i ){
    let checkedGender = questions[position].answer == questions[position].response[$i] ? 'checked' : '';

    $('#gender').append(
    '<input type="radio" name="onlyone" value="'+questions[position].response[$i]+'" '+checkedGender+'>'+
    '<label id="text'+$i+'">'+questions[position].response[$i]+'</label>'
    );
    }
    break;
    case "date":
    inputField.type = 'date';
    inputField.value = questions[position].answer;
    break;
    case "select":
    $(inputField).attr('readonly',true)
    inputField.value = '';

    var nbrCountry = questions[position].response;
    if( $('#country').children().length > 0 ){
    $('#country').children().remove()
    }
    $('#country').show();
    var optionCountry;
    for( var $i = 0; $i < nbrCountry.length; ++$i ){
    let selectedCountry = questions[position].answer == questions[position].response[$i] ? 'selected' : '';
    optionCountry += '<option value="'+questions[position].response[$i]+'" '+selectedCountry+'>'+questions[position].response[$i]+'</option>'
    }
    $('#country').append(' <select name="gender" id="countryList">'+optionCountry+'</select>')
    break;
    case "checkbox":
    $(inputField).attr('readonly',true)
    inputField.value = '';

    let nbrInterest = questions[position].response;
    if( $('#interest').children().length > 0 ){
    $('#interest').children().remove()
    }
    $('#interest').show();

    for( var $i = 0; $i < nbrInterest.length; ++$i ){
    let checkedInterest = questions[position].answer == questions[position].response[$i] ? 'checked' : '';

    $('#interest').append(
    '<input type="checkbox" name="onlyone" value="'+questions[position].response[$i]+'" '+checkedInterest+'>'+
    '<label id="text'+$i+'">'+questions[position].response[$i]+'</label>'
    );
    }
    break;
    default:
    inputField.type = 'text';
    inputField.value = questions[position].answer || '';
    break;
    }
    inputField.focus()



    // set the progress of the background
    progress.style.width = position * 100 / questions.length + '%'
    previousButton.className = position ? 'ion-android-arrow-back' : 'ion-person'
    showCurrent()
    }

    // when submitting the current question
    function validate() {
    var validateCore = function() {
    if(inputField.type == "date" && inputField.value ){
    questions[position].answer =inputField.value;
    return true;
    }else if ( inputField.type != "date" ){

    if(inputField.value.match(questions[position].pattern || /.+/) ){
    questions[position].answer =inputField.value;
    return true;
    }
    else if( $('#countryList').is(':visible') && $('#countryList').find(':selected').length > 0 ){
    questions[position].answer = $('#country').find(':selected')[0].value
    return true;
    }
    else if( $('#gender').is(':visible') && $('#gender').find(':checked').length > 0 ){
    questions[position].answer = $('#gender').find(':checked')[0].value
    return true;
    }else if( $('#interest').is(':visible') && $('#interest').find(':checked').length > 0 ){
    let responseInterest = [];
    $('#interest').find(':checked').each(function(){
    responseInterest.push($(this).val());
    });
    questions[position].answer = responseInterest;
    return true;
    }
    else{
    return false;
    }
    }else{
    return false
    }

    }

    if (!questions[position].validate) questions[position].validate = validateCore
    // check if the pattern matches
    if (!questions[position].validate())
    wrong(inputField.focus.bind(inputField))
    else ok(function() {
    // execute the custom end function or the default value set
    if (questions[position].done) questions[position].done()

    ++position
    // if there is a new question, hide current and load next
    if (questions[position]) hideCurrent(putQuestion)
    else hideCurrent(function() {
    // remove the box if there is no next question

    register.className = 'close'
    progress.style.width = '100%'
    onComplete()
    })
    })
    }

    // helper
    function hideCurrent(callback) {
    inputContainer.style.opacity = 0
    inputLabel.style.marginLeft = 0
    inputProgress.style.width = 0
    inputProgress.style.transition = 'none'
    inputContainer.style.border = null
    setTimeout(callback, wTime)
    }

    function showCurrent(callback) {
    inputContainer.style.opacity = 1
    inputProgress.style.transition = ''
    inputProgress.style.width = '100%'
    setTimeout(callback, wTime)
    }

    function transform(x, y) {
    register.style.transform = 'translate(' + x + 'px , ' + y + 'px)'
    }

    function ok(callback) {
    register.className = ''
    setTimeout(transform, tTime * 0, 0, 10)
    setTimeout(transform, tTime * 1, 0, 0)
    setTimeout(callback, tTime * 2)
    }
    function wrong(callback) {
    register.className = 'wrong'
    for (var i = 0; i < 6; i++) // shaking motion
    setTimeout(transform, tTime * i, (i % 2 * 2 - 1) * 20, 0)
    setTimeout(transform, tTime * 6, 0, 0)
    setTimeout(callback, tTime * 7)
    }
    }(questions, onComplete))

    // load the next question
    function putQuestion() {
    inputLabel.innerHTML = questions[position].question
    inputField.type = questions[position].type || 'text'
    inputField.value = questions[position].answer || ''
    inputField.focus()

    // set the progress of the background
    progress.style.width = position * 100 / questions.length + '%'
    previousButton.className = position ? 'ion-android-arrow-back' : 'ion-person'
    showCurrent()
    }
    @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap');
    body {
    margin: 0;
    background: #fbc02d;
    font-family: 'Roboto', sans-serif;
    overflow-x: hidden;
    }

    h1 {
    position: relative;
    color: #fff;
    opacity: 0;
    transition: .8s ease-in-out;
    }

    #progress {
    position: absolute;
    background: #c49000;
    height: 100vh;
    width: 0;
    transition: width 0.2s ease-in-out;
    }

    .center {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    }


    #register {
    background: #fff;
    position: relative;
    width: 550px;
    box-shadow: 0 16px 24px 2px rgba(0,0,0,0.14), 0 6px 30px 5px rgba(0,0,0,0.12), 0 8px 10px -5px rgba(0,0,0,0.3);
    transition: transform .1s ease-in-out;
    }

    #register.close {
    width: 0;
    padding: 0;
    overflow: hidden;
    transition: .8s ease-in-out;
    box-shadow: 0 16px 24px 2px rgba(0,0,0,0);
    }

    #forwardButton {
    position: absolute;
    right: 20px;
    bottom: 5px;
    font-size: 40px;
    color: #fbc02d;
    float: right;
    cursor: pointer;
    z-index: 20
    }
    #previousButton {
    position: absolute;
    font-size: 18px;
    left: 30px; /* same as padding on container */
    top: 12px;
    z-index: 20;
    color: #9e9e9e;
    float: right;
    cursor: pointer;
    }
    #previousButton:hover {color: #c49000}
    #forwardButton:hover {color: #c49000}
    .wrong #forwardButton {color: #ff2d26}
    .close #forwardButton, .close #previousButton {color: #fff}

    #inputContainer {
    position: relative;
    padding: 30px 20px 20px 20px;
    margin: 10px 60px 10px 10px;
    opacity: 0;
    transition: opacity .3s ease-in-out;
    }

    #inputContainer input {
    position: relative;
    width: 100%;
    border: none;
    font-size: 20px;
    outline: 0;
    background: transparent;
    box-shadow: none;
    }

    #inputLabel {
    position: absolute;
    pointer-events: none;
    top: 32px; /* same as container padding + margin */
    left: 20px; /* same as container padding */
    font-size: 20px;
    transition: .2s ease-in-out;
    }

    #inputContainer input:valid + #inputLabel {
    top: 6px;
    left: 42px; /* space for previous arrow */
    margin-left: 0!important;
    font-size: 11px;
    font-weight: normal;
    color: #9e9e9e;
    }

    #inputProgress {
    border-bottom: 3px solid #fbc02d;
    width: 0;
    transition: width .6s ease-in-out;
    }

    .wrong #inputProgress {
    border-color: #ff2d26;
    }

    @media (max-width: 420px) {
    #forwardButton {right: 10px}
    #previousButton {left: 10px}
    #inputLabel {left: 0}
    #inputContainer {padding-left: 0; margin-right:20px}
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <div id="progress"></div>
    <div class="center">
    <div id="register">

    <i id="previousButton" class="ion-android-arrow-back"></i>
    <i id="forwardButton" class="ion-android-arrow-forward"></i>

    <div id="inputContainer">
    <input id="inputField" />
    <label id="inputLabel"></label>
    <div id="inputProgress"></div>
    <div id="gender"></div>
    <div id="country"></div>
    <div id="interest"></div>


    </div>

    </div>
    </div>

    关于javascript - 如何在多步 javascript 表单中添加单选按钮、复选框和选择字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68396680/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com