多页表单提交

5

我有一个问题,我似乎无法解决。

首先,我有一个由专业人员构建的网站,但我们不再与该公司保持工作关系。现在我正在自己管理网站。我有能力,但我绝不是一名经验丰富的Web开发人员。

背景:我们有一个申请程序,使用向最终用户呈现的多页表单。表单分为7个步骤,但所有步骤都是从一个php文件中完成的,使用(我想)jquery / javascript循环遍历这些步骤,并验证一些字段。在最后一步中,会向用户呈现摘要以供提交。这非常有效。

以下是我认为处理页面循环的相关javascript:

<script>
$(function () {

    window.confirmLeave = true;

    $('.datefield').datepicker();

    var cache = {};                                                                                             // caching inputs for the visited steps

    $("#appForm").bind("step_shown", function(event,data){  

         if(data.isLastStep){                                                                                      // if this is the last step...then
                $("#summaryContainer").empty();                                                                     // empty the container holding the 
                $.each(data.activatedSteps, function(i, id){                                                        // for each of the activated steps...do
                    if(id === "summary") return;                                                                    // if it is the summary page then just return
                    cache[id] = $("#" + id).find(".input");                                                         // else, find the div:s with class="input" and cache them with a key equal to the current step id
                    cache[id].detach().appendTo('#summaryContainer').show().find(":input").removeAttr("disabled");  // detach the cached inputs and append them to the summary container, also show and enable them
                });
            }else if(data.previousStep === "summary"){                                                              // if we are movin back from the summary page
                $.each(cache, function(id, inputs){                                                                 // for each of the keys in the cache...do
                    var i = inputs.detach().appendTo("#" + id).find(":input");                                      // put the input divs back into their normal step
                    if(id === data.currentStep){                                                                    // (we are moving back from the summary page so...) if enable inputs on the current step
                         i.removeAttr("disabled");
                    }else{                                                                                          // disable the inputs on the rest of the steps
                        i.attr("disabled","disabled");
                    }
                });
                cache = {};                                                                                         // empty the cache again
            }
        });

</script>

我也在下面包含了表单的HTML代码:
<form name="appForm" id="appForm" action="submit-app-exec.php" method="post" 
enctype="multipart/form-data" autocomplete="off" onSubmit="showProgressBar()">

<fieldset class="step" id="page_1">
<div class="input">
<?php include("add-company/step1.html"); ?>
</div>
</fieldset>

<fieldset class="step" id="page_2">
<div class="input">
<?php include("add-company/step2.html"); ?>
</div>
</fieldset>

<fieldset class="step" id="page_3">
<div class="input">
<?php include("add-company/step3.html"); ?>
</div>
</fieldset>

<fieldset class="step" id="page_4">
<div class="input">
<?php include("add-company/step4.html"); ?>
</div>
</fieldset>    

<fieldset class="step" id="page_5">
<div class="input">
<?php include("add-company/step5.html"); ?>
</div>
</fieldset>

<fieldset class="step" id="page_6">
<div class="input">
<?php include("add-company/step6.html"); ?>
</div>
</fieldset>

<fieldset class="step" id="page_7">
<div class="input">
<?php include("add-company/step7.html"); ?>
</div>
</fieldset>

<fieldset class="step" id="summary" >
    <span class="font_normal_07em_black">Summary page</span><br />
    <p>Please verify your information below.</p>
    <div id="summaryContainer"></div>
</fieldset>

<div id="wizardNavigation">

    <button class="navigation_button" onclick="javascript:saveApp()">Save</button>
    <input class="navigation_button" id="back" value="Back" type="reset" />
    <input class="navigation_button" id="next" value="Next" type="submit" onclick="javascript:noSaveApp()" />

    <div class="clearFix"></div>
</div>

当页面加载时,每个字段集都有额外的类和样式属性:
class="step ui-formwizard-content ui-helper-reset ui-corner-all" style="display: none;"

在这个过程中,我可以使用firebug观察,看到当与该fieldset交互时,display:none;会循环并更改为“block”。
问题是:我们没有以任何方式建立用户保存进度并稍后完成的方法。我现在正在尝试做到这一点。我已经成功创建了“保存”按钮,它触发一个javascript来更改表单的操作,将数据POST到一个新的php文件中,处理并将POST数据转换为MySQL。这部分工作正常。但是,POST只传递当前查看的fieldset的数据,而不是POST所有数据。我无法弄清楚如何确保POST所有表单数据。任何指导或建议都会有所帮助。谢谢。
编辑:
我能够用以下方法加载正确的页面:
$(function(){ $('#appForm').formwizard('show','" . $row["current_step"] . "'); }); 

这将加载正确的页面。现在的问题是,最后一步是显示所有输入元素以进行最终提交的摘要页面。但是,它似乎只显示从已查看的页面中获取的元素,我非常确定是数组“data.activatedSteps”决定了元素是否在最终摘要中显示。您的代码是否比我的更好地解决了这个问题?再次感谢您的帮助。–


你能发布一下表单的js代码吗? - mayabelle
1
你需要展示更多的代码。尝试找到从表单中获取数据的位置,可能是通过 $('#formId').serialize() 获取数据,并且找到将数据通过ajax发送到处理数据的php文件的位置。 - Cristian Bitoi
1个回答

6

<input>标签如果设置了'disable'属性,将不会在post/get请求中返回。

下面这段JavaScript是需要注意的:

if(id === data.currentStep){                                                                    // (we are moving back from the summary page so...) if enable inputs on the current step
    i.removeAttr("disabled");
}else{                                                                                          // disable the inputs on the rest of the steps
    i.attr("disabled","disabled");
}

这是先前的程序员控制用户可编辑的方式。如果您想在用户点击保存按钮时发送回所有值,请执行以下操作:
removeAttr("disabled");

从页面上的所有内容中提取数据,然后提交post/get请求。看起来前一个开发人员通过浏览页面上的所有数据并在此处取消禁用来实现此目标。
if(data.isLastStep){                                                                                    // if this is the last step...then
    $("#summaryContainer").empty();                                                                     // empty the container holding the 
    $.each(data.activatedSteps, function(i, id){                                                        // for each of the activated steps...do
        if(id === "summary") return;                                                                    // if it is the summary page then just return
        cache[id] = $("#" + id).find(".input");                                                         // else, find the div:s with class="input" and cache them with a key equal to the current step id
        cache[id].detach().appendTo('#summaryContainer').show().find(":input").removeAttr("disabled");  // detach the cached inputs and append them to the summary container, also show and enable them
    });
}

因此,您可以在提交返回时调用该代码,或者做类似的事情来启用页面上的输入。

编辑:

根据您的评论,我建议使用这个来解决您的问题,以便您可以使用相同的工具和库来一致地操作页面上的对象。此外,JQuery非常方便。

$(':input.ui-wizard-content').each(function() {$( this ).removeAttr("disabled");});

:input 获取页面上的所有输入。 .ui-wizard-content 告诉JQuery只查找具有该类的输入,然后.each循环遍历每个对象,在找到的对象上运行lambda函数(function() {$( this ).removeAttr("disabled");})。

编辑2:

很难确定你代码中的 $row[] 是什么。显然它是一个容器,但你提供的代码有点缺乏上下文,所以我不能确定它是什么。

话虽如此,如果我只能使用DOM(Java脚本表示的页面内容)并且我了解您之前发布的函数,我会这样做:

替换

if(data.isLastStep){                                                                                    // if this is the last step...then
    $("#summaryContainer").empty();                                                                     // empty the container holding the 
    $.each(data.activatedSteps, function(i, id){                                                        // for each of the activated steps...do
        if(id === "summary") return;                                                                    // if it is the summary page then just return
        cache[id] = $("#" + id).find(".input");                                                         // else, find the div:s with class="input" and cache them with a key equal to the current step id
        cache[id].detach().appendTo('#summaryContainer').show().find(":input").removeAttr("disabled");  // detach the cached inputs and append them to the summary container, also show and enable them
    });
}

使用

if(data.isLastStep){ 
    $("#summaryContainer").empty();
    $('.input :input').detach().appendTo('#summaryContainer').show().find(":input").removeAttr("disabled");
}

大部分代码是从先前的程序员那里借来的。他假设表单中的所有内容都在"data.activatedSteps"中,因为他所创建的工作流程,但现在不再是这样了。因此,您需要查看他在何处将数据添加到"data.activatedSteps"中,并在重新加载时以相同的方式将保存的内容放入其中。或者只需使用我的代码行,它会忽略所有"data"内容并且只会抓取带有"class=input"的对象内的每个"",并将其添加到容器中。
注意:JQuery的 "$(TEXT)" 使用与CSS相同的对象定义语法,并添加了一些特殊的易用性附加功能,如':input'。关于我所说的内容,这里提供了一个很棒的CSS参考here,而对于JQuery特殊的选择器语法,请检查here。这就是我知道如何使用非常简洁的语句抓取您感兴趣的所有内容的方法。

是的!那完美地运作了。它说在我的声望达到15之前,我不能给它点赞。但是非常感谢你! - Brian Randolph
2
@BrianRandolph,你写的 JavaScript 完全没有问题,但考虑到你的前任使用了 JQuery,我建议你使用类似这样的语句 $('ui-wizard-content').each(function() {$( this ).removeAttr("disabled");});,因为这样你就可以使用与他相同的库和函数,而且我真的很喜欢 JQuery。再加上一行代码就能解决所有问题。 :) - Dan
嗨,丹。我采纳了你的建议,它运行得很好。更好的是,我认为我理解了它。谢谢。这可能需要成为一个单独的问题,但现在我需要能够在用户重新加载表单以完成时显示正确的页面。我似乎无法弄清楚如何加载“第4页”。我已经将步骤保存在mysql中,并在if语句中正确检索它,但我不知道如何设置jquery来加载我需要的页面。 - Brian Randolph
1
这是一个尝试。保存用户当前所在的id,即“page_4”,并在从保存中加载页面时运行带有以下JQuery代码的函数。$(":input.step").attr("disabled","disabled"); $(":input#"+SAVEDSTEPIDVALUE).removeAttr("disabled"); 我个人会选择 $(".step").css("display","none"); $("#"+STEPIDVALUE.step).css("display","inline"); 但我认为他以某种方式隐藏了禁用的输入。顺便说一句,通常这应该是一个新问题,但这非常具体,你永远不会得到答案,他们可能会删除你的问题。希望能帮到你。 - Dan
@BrianRandolph 之前评论中忘记@你了。如果这样还不行,编辑这个问题,并补充类似于“我还需要在同一页重新加载保存的内容”的需求,我会再试一次。 - Dan
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接