【问题标题】:Multi-Page Form Submit多页表单提交
【发布时间】:2013-10-22 08:24:44
【问题描述】:

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

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

背景:我们有一个应用程序,它使用呈现给最终用户的多页表单。该表单分 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观看,看到显示:无;与该字段集交互时循环并更改为“阻止”。

问题:我们没有以任何方式为用户构建以保存进度并在以后完成。我现在正在尝试这样做。我已经成功创建了“保存”按钮,它触发了一个 javascript 来更改表单的操作,它将数据发布到一个新的 php 文件,该文件处理和处理 POST 数据到 MySQL。这可行,但是,POST 仅传递当前查看的字段集中的数据,而不是 POST 所有数据。而且我无法弄清楚如何确保所有表单数据都已发布。任何指导或建议都会有所帮助。谢谢。

编辑:

我能够使用以下内容加载正确的页面:

$(function(){ $('#appForm').formwizard('show','" . $row["current_step"] . "'); }); 

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

【问题讨论】:

  • 可以把表单的js代码贴出来吗?
  • 您需要从您的代码中向我们展示更多内容。尝试查找从哪里获取数据形式,可能是通过$('#formId').serialize() 以及通过ajax 将数据发送到处理数据的php 文件的位置。

标签: javascript php jquery html forms


【解决方案1】:

&lt;input&gt; 属性为 '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");

从页面上的所有内容然后提交帖子/获取。

看起来之前的编码器通过检查页面上的所有数据并使其未在此处禁用来完成此操作。

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
    });
}

因此,您可以在发布退货时调用该代码,也可以执行类似的操作来启用页面上的输入。

编辑:

根据您的 cmets,我建议您使用它来解决您的问题,以便您始终使用相同的实用程序和库来操作页面上的对象。加上 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 内容,并在具有类 input 的对象中抓取每个 &lt;input&gt; 并将其添加到容器中。

注意:JQuery 的$(TEXT) 使用与 CSS 相同的对象定义语法,并添加了一些特别易用的插件,例如 ':input'。对于 CSS 参考和 JQuery 特殊选择器语法的检查 here,有一个很好的参考。这就是我知道如何用一个非常紧凑的语句编写的东西来抓住你感兴趣的一切。

【讨论】:

  • 是的!这完美无缺。它说在我的声望达到 15 之前我不能投票。但是谢谢你!
  • var 输入 = document.getElementsByClassName('ui-wizard-content'); for(var i = 0; i
  • @BrianRandolph 你写的是完全有效的Javascript,但考虑到你的前任使用的是JQuery,我建议像$('ui-wizard-content').each(function() {$( this ).removeAttr("disabled");}); 这样的东西,因为你使用的是与他相同的库和函数,因为我真的很喜欢 JQuery。再加上看看 1 行就可以了。 :)
  • 嗨,丹。我提出了你的建议,效果很好。更好的是,我想我明白了。谢谢你。这可能需要进入一个单独的问题,但现在我需要能够在我的用户重新加载表单以完成时显示正确的页面。我似乎无法弄清楚如何加载“第 4 页”。我将步骤保存在 mysql 中,并在 if 语句中正确检索它,但我不知道如何设置 jquery 来加载我需要的页面。
  • 试一试。保存用户当前所在的 id,即“page_4”,当从保存加载页面时,使用这些 JQuery 行运行一个函数。 $(":input.step").attr("disabled","disabled"); $(":input#"+SAVEDSTEPIDVALUE).removeAttr("disabled"); 我个人会选择$(".step").css("display","none"); $("#"+STEPIDVALUE.step).css("display","inline");,但我认为他以某种方式隐藏了禁用的输入。顺便说一句,通常这应该是一个新问题,但这真的很具体,你永远不会得到答案,他们可能会删除你的问题。希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多