如何使用ColdFusion/jQuery发布表单、更新查询并在同一页面上显示结果?

如何使用ColdFusion/jQuery发布表单、更新查询并在同一页面上显示结果?,jquery,sql,ajax,forms,coldfusion,Jquery,Sql,Ajax,Forms,Coldfusion,目标: 我有一个动态创建的大表单(它是一个产品订单表单,输入type=“number”)。填写表单后,用户单击“下订单”按钮,我想在灯箱中显示摘要订单(在同一页上),以便他们确认 当前使用的方法: 1) 我将表单发布到页面上一个不可见的iframe <cfform id="refSubmit" action="/createTable.cfm" method="post" target="hiddenFrame"> 问题: 尽管从createTable.cfm创建的表在100%的时

目标:

我有一个动态创建的大表单(它是一个产品订单表单,输入type=“number”)。填写表单后,用户单击“下订单”按钮,我想在灯箱中显示摘要订单(在同一页上),以便他们确认

当前使用的方法:

1) 我将表单发布到页面上一个不可见的iframe

<cfform id="refSubmit" action="/createTable.cfm" method="post" target="hiddenFrame">
问题:

尽管从createTable.cfm创建的表在100%的时间内都是正确构建的,但当在orderConfirmation.cfm中调用查询时,它会在完成构建之前调用该查询。所以输出的不是等待表创建完成

我知道我的ajax帖子做的正是它应该做的。它会触发成功行,因为尽管表单数据已成功发送,但cfm文件尚未完成处理

问题:

所以,我来这里的原因。如何确保.load()行等待执行,直到createTable.cfm完成其服务器端处理?如您所见,我确实尝试使用.delay()。当然,我可以输入一个数字,让用户等待这个过程,但这意味着订购1件物品的人将与订购2000件独特物品的人等待的时间相同

因为有人问这个问题,下面是我用来创建唯一表的代码

<!--- Create Unique ID for Table --->
  <cfset SESSION.tempOrder = Replace(CreateUUID(),"-","","All")>

  <!--- Create Temp Order Table --->
  <cfquery name="qCreateTempOrder" datasource="#REQUEST.dsn#" username="#REQUEST.dsu#" password="#REQUEST.dsp#">
    CREATE TABLE order_temp_#SESSION.tempOrder#
    ( id INTEGER IDENTITY(1,1) PRIMARY KEY,
    productId INTEGER NOT null,
    quantity INTEGER NOT null
    );
  </cfquery> 

创建表order_temp_35; SESSION.tempOrder#
(id)整数标识(1,1)主键,
productId整数不为空,
数量整数不为空
);

我将发布在其他人访问此页面时的结果,并显示我的问题已得到解决

根据Miguel-F的建议,我去掉了表单上的cf

<form id="refSubmit">

我的jQuery现在看起来像这样

$("#refSubmit").submit(sendForm);
  var confirmLightbox = $("#confirmationLightbox");
  var placeOrder = $("input[name*='submit']");

  function sendForm(event) {
    if (confirmLightbox.is(":visible")){
      confirmLightbox.toggle().children().remove();
      placeOrder.val("Place Order");
      event.preventDefault();
    } else {
      $('<input name="processing" style="margin: 5px 10px; float: right;" type="button" class="processingButton" value="Processing..." disabled>').insertBefore(placeOrder.hide());
      $.post('process/createTable.cfm',$("#refSubmit").serialize(),function(){
        confirmLightbox.toggle().delay(0).queue(function(){
        $(this).load('/includes/inc_lightboxes/jcorderconfirmation.cfm', function(){
          var confirmOrder = $("button[name*='confirm']");
          placeOrder.show().val("Edit Order");
          $("input.processingButton").remove();
          $("input[name*='confirmOrder']").on("click", function(){
            if($(this).is(':checked')){
              confirmOrder.removeAttr("disabled");
            } else {
              confirmOrder.prop("disabled", true);
            }
          });
          $("button[name*='cancel']").on("click", function(){
            confirmLightbox.toggle().children().remove();
            placeOrder.val("Place Order");
          });
          confirmOrder.on("click", function(){
          alert("Products successfully added to inventory.");
        });
      });
    });
  });
}
return false;
}
$(“#refSubmit”).submit(sendForm);
var确认灯箱=$(“#确认灯箱”);
变量placeOrder=$(“输入[name*='submit']”);
函数sendForm(事件){
如果(confirmLightbox.is(“:可见”)){
confirmLightbox.toggle().children().remove();
placeOrder.val(“placeOrder”);
event.preventDefault();
}否则{
$('').insertBefore(placeOrder.hide());
$.post('process/createTable.cfm',$(“#refSubmit”).serialize(),function(){
confirmLightbox.toggle().delay(0).队列(函数(){
$(this).load('/includes/inc_lightbox/jcorderconfirmation.cfm',function(){
变量确认器=$(“按钮[名称*='确认']”);
placeOrder.show().val(“编辑订单”);
$(“input.processingButton”).remove();
$(“输入[name*='confirmOrder']”)。在(“单击”,函数()上){
如果($(this).is(':checked')){
确认人。删除请求(“禁用”);
}否则{
确认人道具(“禁用”,真实);
}
});
$(“按钮[名称*='cancel'])。在(“单击”,函数()上){
confirmLightbox.toggle().children().remove();
placeOrder.val(“placeOrder”);
});
confirmOrder.on(“单击”,函数(){
警报(“产品已成功添加到库存”);
});
});
});
});
}
返回false;
}

为什么要发布到隐藏的iframe并通过AJAX调用发布(到同一页面)?以这种方式,很难让每个单独的请求相互依赖。您是否可以取消iframe,而只在AJAX中收集和发布参数,这样
success
实际上只在处理完成后才被调用?这就是我的出发点。我意识到我的ajax调用可能不正确。但最初我拥有的是创建表的cfm文件,也是我执行.load()的文件。我遇到的问题是,我无法阻止表单帖子将我从该页面带走并发送信息。iframe确实感觉像是macgyver类型的解决方案。如果有一种方法可以实现您的建议,那肯定是更理想的方法。您使用cfquery创建和填充临时表的方法是有风险的。除了您遇到的问题之外,您还可能遇到用户B干扰用户A的风险。我建议将所有代码转移到存储过程中。用户A和B的冲突已经在ColdFusion端得到解决。使用唯一名称创建会话变量,并使用该变量命名临时表。话虽如此,一旦我知道ajax正在工作,它最终将在一个存储过程中完成。你不应该需要这个。事实上,这可能会造成干扰。当您使用这些
cf..
标记时,javascript会嵌入到响应中,这可能会干扰您的jQuery/javascript。感谢您回来发布您的解决方案。如果你能提供一些关于是什么使这项工作成功的细节,那将是很有帮助的。您是否必须修改您的ColdFusion模板(除了删除cfform之外),还是全部都是JavaScript代码?很高兴你成功了。它由两部分组成。首先,在cfform上执行一个操作当然是试图重定向页面,这就是我最终使用iframe的原因。所以我尝试发送表单两次,一次在标记中,另一次在jquery中。相反,删除操作并让jquery发送信息完全符合我的需要。您还将看到我修改了jquery并在$.post行中使用了回调。这允许处理完成。自从这篇文章发表后,我将createTable.cfm修改为一个cfc文件,它在SQL中调用一个存储过程。希望有帮助
$("#refSubmit").submit(sendForm);
  var confirmLightbox = $("#confirmationLightbox");
  var placeOrder = $("input[name*='submit']");

  function sendForm(event) {
    if (confirmLightbox.is(":visible")){
      confirmLightbox.toggle().children().remove();
      placeOrder.val("Place Order");
      event.preventDefault();
    } else {
      $('<input name="processing" style="margin: 5px 10px; float: right;" type="button" class="processingButton" value="Processing..." disabled>').insertBefore(placeOrder.hide());
      $.post('process/createTable.cfm',$("#refSubmit").serialize(),function(){
        confirmLightbox.toggle().delay(0).queue(function(){
        $(this).load('/includes/inc_lightboxes/jcorderconfirmation.cfm', function(){
          var confirmOrder = $("button[name*='confirm']");
          placeOrder.show().val("Edit Order");
          $("input.processingButton").remove();
          $("input[name*='confirmOrder']").on("click", function(){
            if($(this).is(':checked')){
              confirmOrder.removeAttr("disabled");
            } else {
              confirmOrder.prop("disabled", true);
            }
          });
          $("button[name*='cancel']").on("click", function(){
            confirmLightbox.toggle().children().remove();
            placeOrder.val("Place Order");
          });
          confirmOrder.on("click", function(){
          alert("Products successfully added to inventory.");
        });
      });
    });
  });
}
return false;
}