首页 > 解决方案 > dataTables 表单无法在 Internet Explorer 中正确提交

问题描述

TL;DR - 除了让购物车 iframe 在最后刷新之外,一切都运行良好。Even window.location.reload(true);,我认为强制重新加载整个页面,它不起作用,但点击F5will。

我的问题最终源于这个问题中提出的相同问题。DataTables 需要有效的 HTML,因此<form>必须是<td>. 我正在尝试找到一个 javascript 解决方案,因此每行上的表单将在 IE 和较旧的 Edge 中工作,它们不支持标签form attribute外的 for 输入,<form>如 dataTables 的此代表性行所示(通常一次显示 25 ):

<table>
    <tr>
        <td></td>
        <td>
            <form id="101110" name="form" method="post" action="Cart.cfm" target="cart_frame">
                <input name="ItemID" type="hidden" id="ItemID" value="101110">
                <input title="Click to add to cart" name="Submit" type="submit" class="buttons" value="101110">
                <input name="Qty" type="hidden" value="">
                <input name="Brand" type="hidden" value="">
                <input name="Pack" type="hidden" value="113">
                <input name="UOM" type="hidden" value="CS">
            </form>
        </td>
        <td><input form="101110" title="Type number and ENTER to add to cart" name="Qty" type="text" id="Qty" value="" size="1" maxlength="4"></td>
        <td><input form="101110" name="Broken" type="checkbox" id="Broken"></td>
        <td>MY AWESOME WIDGET #115</td>
        <td></td>
        <td>115</td>
        <td>48.50</td>
        <td>&nbsp;</td>
        <td>0.52</td>
    </tr>
</table>

我想出了一个丑陋的 javascript 解决方案来拦截提交,找到其他 2 个输入并根据需要添加它们的数据,提交XMLHttpRequest并重新加载页面。但是,即使正确responseText返回并发送到cart_frame,框架仍显示为空白,直到我点击F5。这是我的来源:

    document.addEventListener('submit', function(e) {
        // disable the normal form submit handler
        e.preventDefault();
        // store reference to form
        const form = e.target;
        var XHR = new XMLHttpRequest();
        var urlEncodedData = "";
        var urlEncodedDataPairs = [];

        // convert form elements into an array of URL-encoded key/value pairs.
        for (var i = 0, element; element = form.elements[i++];) {
            urlEncodedDataPairs.push(encodeURIComponent(element.name) + '=' + encodeURIComponent(element.value));
        };
    /*
    *** FIND THE QTY AND BROKEN INPUTS AND ADD TO ABOVE ARRAY
    *** IF TABLE STRUCTURE CHANGES IT WILL BREAK THIS!!!
    */
        // get the NEXT td element of the form's parent node
        var tdSib1 = form.parentNode.nextElementSibling;
        // get child element (Qty)
        var input1 = tdSib1.firstElementChild;
        urlEncodedDataPairs.push(encodeURIComponent(input1.name) + '=' + encodeURIComponent(input1.value));
        // get the child of the NEXT td (Broken)
        var input2 = tdSib1.nextElementSibling.firstElementChild;
        //console.log(input2.name  + '=' + input2.checked);
        if (input2.checked) {
            urlEncodedDataPairs.push(encodeURIComponent(input2.name) + '=on');
        }
        // convert array into a single string and replace all %-encoded spaces to 
        // the '+' character; matches the behaviour of browser form submissions.
        urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
        console.log(urlEncodedData);

        XHR.addEventListener('load', function(event) {
            // success
            if (XHR.readyState === XHR.DONE) {
                if (XHR.status === 200) {
                    var destframe = parent.document.getElementsByName('cart_frame')[0];
                    destframe.src = XHR.responseText;
                    //console.log(XHR.responseText);
                    //destframe.contentWindow.location.reload(true); //did not work either
                    // what do I need to get cart to refresh properly???
                    window.location.reload(true);
                }
            }
        });

        XHR.addEventListener('error', function(event) {
            alert('Oops! Something went wrong.');
        });

        // Set up our request
        XHR.open('POST', form.action);

        // Add the required HTTP header for form data POST requests
        XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        XHR.send(urlEncodedData);
    });

如何强制真正刷新购物车 iframe 以显示更新后的内容responseText?如果由于某种原因它很重要,则该 iframe 在当时处于隐藏 <div>状态,因为购物车在后台更新,并且仅在主页上的按钮上显示更新后的项目数量,该按钮会更改div显示和隐藏以显示购物车准备结帐。

或者,是否有更好的方法来完成在 IE 中的单行数据表上提交表单?我知道我无法更改表格/表单 HTML 结构,它必须在 IE 11 中得到支持。我将把我的源代码移到它自己的函数中,这样它也可以在按 Qtyinput元素中的 Enter 时运行。

标签: javascriptjquerydatatables

解决方案


事实证明,我对 DOM 的了解还不够。改变

window.location.reload(true);

window.top.location.reload();

是重新加载整个页面所需的全部内容。:/

或者,这也可以工作,而无需重新加载所有内容,所以这是我选择做的。

destframe.src="cart.cfm";

推荐阅读