【问题标题】:FormData doesn't include the button JavascriptFormData 不包含按钮 Javascript
【发布时间】:2016-10-23 11:02:43
【问题描述】:

我遇到了FormData 的问题,几天前它还在工作,但现在不行了,它会提交除提交按钮之外的所有输入。这是我的登录表单。

<form action="" method="post" name="login_user">
    <label for="username">Username/e-mail <span class="error" id="user-error"></span></label>
    <input type="text" name="username" id="username" required>
    <br>
    <label for="passwd">Password <span class="error" id="passwd-error"></span></label>
    <input type="password" name="passwd" id="passwd" required>
    <br>
    <p><input type="checkbox" checked name="remember"> Remember me <span class="forgot"><a href="<?php echo SITE_URL; ?>/reset">Forgotten password</a></span> </p>
    <input type="submit" id="login" value="Login" name="login">
    <p>Don't have an account? <a href="<?php echo SITE_URL; ?>/register/">Sign up</a></p>
</form>

JS 登录,使用 MVC。

//ajax login
var login = document.forms.namedItem('login_user');
if (login) {
    login.addEventListener('submit', function (e) {
        if (validatePassword('passwd', 'passwd-error')) {
            var data = new FormData(login);
            var userlogin = new XMLHttpRequest();
            var btn = document.getElementById('login');
            btn.value = 'Login, Please wait...';

            userlogin.open('POST', url + 'login/login_user_ajax', true);
            userlogin.onload = function (event) {
                if (userlogin.status == 200) {
                    var result = JSON.parse(userlogin.responseText);
                    if (result.results == 'success.') {
                        alert('logged in'); //change this later
                    } else {
                        document.getElementById('cred-error').innerHTML = result.results;
                    }
                    btn.value = 'Login';
                }
            };
            userlogin.send(data);
        }
        e.preventDefault();
    }, false);

我的控制器中的登录方法,未检测到按钮。

public function login_user_ajax() {
    $this->login_user(1);
}

private function login_user($ajax  = '')
{
    if (filter_has_var(INPUT_POST, 'login')) {
        $new_user = $this->model('User');
        $new_user->setDb(Controller::getDb());
        $new_user->set_site(SITE_URL);
        $user = trim(filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING));
        $passwd = trim(filter_input(INPUT_POST, 'passwd', FILTER_SANITIZE_STRING));
        if ($new_user->login($user, $passwd)) {
            if ($ajax) {
                $site_data['results'] = 'success.';
                echo json_encode($site_data);
                return true;
            }else {
                $this->redirect(SITE_URL . '/edit');
            }
        } else {
            if (!$ajax){
            return 'The username or password is incorrect.';
            }else {
                $site_data['results'] = 'The username or password is incorrect.';
                echo json_encode($site_data);
                return false;
            }
        }
    }else {
        print_r($_POST);
    }
}

我在print_r $_POST 时得到这个,没有按钮。

【问题讨论】:

  • 应该是这样,提交按钮没有提交?
  • @adeneo 但它工作正常。
  • @adeneo:对于正常的表单提交,如果该按钮用于导致提交,则提交按钮的名称和值将与表单一起发送。例如,如果您有一个包含四个不同提交按钮的表单,所有按钮的名称都为btn,并且每个按钮都有不同的值,如果您使用一个按钮提交表单,则数据中将包含btn=the-value-of-the-clicked-button
  • @T.J.Crowder - 好点,我可能应该注意到使用formData时,它没有提交

标签: javascript php


【解决方案1】:

因为您实际上并没有使用默认提交(而是使用 ajax),所以您需要自己添加点击按钮。一种简单的方法是在表单中添加一个隐藏的输入,并使用您希望按钮具有的名称,然后让表单中的所有按钮都使用此单击处理程序:

function clickHandler() {
    this.form.theHiddenInput.value = this.value;
}

这样,如果使用了一个按钮来提交表单,该按钮的处理程序会在 submit 之前设置隐藏输入的值。

【讨论】:

    【解决方案2】:

    我使用&lt;button&gt; 元素构建的 SwitchToggle 组件也有类似的问题。即使元素有name,在提交表单时它也不会包含在我的FormData 中。

    我最终在标记中添加了一个视觉隐藏的&lt;input type="checkbox"&gt;,其namevalue 属性与SwitchToggle 组件相同。除了显示在FormData 之外,此输入没有任何作用(它不可点击且不可见)。此示例在 React 中,但该方法适用于所有框架或原生 JavaScript。

    const SwitchToggle = (props) => {
      const { id, name, className } = props;
      const [enabled, setIsEnabled] = React.useState(props.enabled);
    
      return (
        <>
          <input
            style={{opacity: 0.05}}
            name={name}
            checked={enabled}
            type={"checkbox"}
          />
          <button
            className={`switch-toggle ${enabled ? 'on' : 'off'}`}
            onClick={(e) => {
              e.preventDefault();
              setIsEnabled(!enabled);
            }}
          />
        </>
      );
    };
    

    Full example on Codepen.

    由于我的组件是开/关,我使用了复选框输入,但您也可以使用带有字符串值的文本输入。

    【讨论】:

      猜你喜欢
      • 2018-06-27
      • 1970-01-01
      • 2021-08-19
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多