将50字段表单提交给多个表格; 常规POST,AJAX POST或其他?

sck*_*ckd 5 mysql coldfusion performance jquery

Stackoverflow的长期读者; 第一次海报,所以希望你会温柔:)

我在页面上有一个表单,包含大约50个不同类型的字段(复选框/文本/小数/日期等).通过一个查询从大约8个表中提取值大致如下:

SELECT * FROM p
LEFT JOIN pd on p.id=pd.id
LEFT JOIN pc on p.id=pc.id
LEFT JOIN pie on p.id=pie.id
etc.
WHERE p.id = xxx
Run Code Online (Sandbox Code Playgroud)

我开始认为我只是在表单上使用一个简单的POST,写了一堆验证和更新查询(用表格中的任何内容覆盖每一个现有的值)并完成它,但我在质疑我的判断这里.

具体来说,如果现有值没有改变,覆盖现有值感觉是错误的,我有点担心如果db更新失败一半(考虑使用Transactions处理)会发生什么.我对较小的表格感到很满意,但如果工作人员只改变了1或2个字段,这就像是写了很多东西.我接下来的想法是根据每个字段级别制作AJAX.更改任何字段会提交更改并保存.感觉它可能更有意义,即使我愿意尽可能避免使用js.第三种选择当然是将其转换为具有多个提交按钮的多个表单,例如每个选项卡一个(表单已经被分成选项卡),然后是因为需要更多提交而更频繁地重新加载页面(尽管这里当然也可以使用AJAX).

我是否应该把这么多的想法投入其中(到目前为止,花了很多时间阅读旧线程......)?!这里涉及一些财务数据,所以我主要关心的是可靠性和性能,但我也很好奇是否有其他人遵循的最佳实践?

---实施CHOSEN ANSWER后的更新---

作为SO的长期读者,我总是很欣赏后来提出问题的人所提出的问题,所以我想我自己也会这样做.不确定正确的协议或格式.

如上所述,我最终选择了barnyr的解决方案,它主要使用javascript将提交时的表单与原始值进行比较,然后将更改发布到mysql(使用jquery post).如果您正在考虑类似的情况,请考虑以下事项:

  1. 如果没有选择,jquery的序列化不会发送复选框/无线电值.我看到他们的逻辑,但对我来说这没有意义.我使用http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/上的插件解决了这个问题.

  2. 如果你在页面上编辑一个值,然后保存它然后再次编辑它,回到原始值,与页面加载时设置的初始值相比,你将得到一个"没有改变"的消息,没有任何改变.这是合乎逻辑的,但在我完成所有测试之后,我才考虑这个问题.我真的没有看到任何方法可以保证这个解决方案带来的复杂性超过简单的"覆盖表单提交上的所有内容",所以如果你构建一个关心用户的公共应用程序,我不会建议您使用此方法.

  3. 在规范化方面,这个解决方案很漂亮,因为我可以保持行不被添加到链接到包含userid的主表的表中,除非将内容添加到这些特定字段.但是,如果第2点对我来说是一个大问题,它会从代码中减少很多复杂性,只是将显示在一个大表格中的所有这些值存储在一个大表中.我几乎是一个新手的标准化(所以在干草叉上很容易),这当然主要是所有数据只以一种形式显示的结果.如果您使用多个表单,则不再适用.

  4. 系统的一部分涉及很多数字,总结在表单的其他部分,并通过AJAX完成所有这些操作意味着您必须非常小心并清楚当用户点击保存时究竟发生了什么变化.例如,他们可以更改程序价格,总价格也应该更新,但是当您通过AJAX提交并且没有正确的重新加载时,您必须将所有这些代码重新编码到系统中.

在这种情况下,点2,3和4可以解决,但是在开始时我已经知道我现在知道的东西,我可能会选择一个包含所有数据的大表,并在表单提交上简单编辑整行.然后,我会学到更多,所以没有遗憾:)希望这对那些在后期发现这个线程的人有所帮助.

bar*_*nyr 1

更新 - 最初的方法不能很好地处理其他输入类型。我更改了代码来处理常见的输入类型,并使用 DOM 属性作为初始值,这避免了在加载页面时运行任何代码:

这是链接: http: //jsfiddle.net/rLwca/5/这是更新的函数:

    //Initial setup no longer needed. the DOM has the default states anyway...

//heres where we filter the elements for ones which have changed
$("#My50PageForm").submit(function(){        
    var elems = $("#My50PageForm :input").filter(function(value){
        var elem=$(this),
            type=this.tagName +"_"+(elem.attr("type")||""); // uniquely name the element tag and type

        switch (type){
            case "INPUT_radio": case "INPUT_checkbox":                    
                return elem.prop("checked")!=elem.prop("defaultChecked");
            case "INPUT_text": case "INPUT_textarea": case "INPUT_":                 
                return elem.val()!=elem.prop("defaultValue");
            case "SELECT_":
                var options=$(this).find('option'),
                    defaultValue=options.first().val(); //use the first element's value as default in case no defaults are set
                options.each(function (i,o) {
                    defaultValue=this.defaultSelected?this.value:defaultValue;
                });
                return $(this).val()!=defaultValue;

            default:
                console.log("type "+type+" not handled");
                return false;
        }
     });

    if(elems.length){
        console.log(elems.serialize());
        return false;
        $.post("http://jsfiddle.net/example.cfm",
               elems.serialize());
    }else{
       alert("nothing changed");   
    }         

    return false;
});
Run Code Online (Sandbox Code Playgroud)

原始代码如下:

以下是发送更改内容的最小示例的链接:

http://jsfiddle.net/UhGQX/

$(document).ready(function(){
//Copy all form valued into a data attribute called 'original' when the page loads
$("#My50PageForm :input").each(function(elem){
    $(this).data("original",$(this).val());
});

//here's where you check what has changed
$("#My50PageForm").submit(function(){        

    var elems = $("#My50PageForm :input").filter(function(value){
        var elem=$(this),
        original=elem.data("original");
        console.log(original);
        //check that original isn't 'undefined' and that it's been changed
        return original && elem.val()!==original
    });
    if(elems.length){
        //post the data back to your server for processing
        $.post("http://jsfiddle.net/example.cfm",
               elems.serialize());
    }else{
     alert("nothing changed");   
    }         

    return false;
});
});
Run Code Online (Sandbox Code Playgroud)

关键位是:

  • 页面加载时,使用 jQuery 复制每个表单字段的初始值
  • 当提交被触发时,将每个字段的当前值与页面加载时保存的值进行比较。
  • 如果有变化,将数据发送回服务器。

其他方法可能是允许发布整个表格:

  • 将数据存储在服务器上的session中
  • 重新运行用于填充页面的选择,然后将其与表单发布的内容进行比较