首页 > 解决方案 > 如何根据多个单选按钮组更改表单操作

问题描述

所以我希望用户能够从三个组中的每一个中选择一个单选按钮,然后通过查看所有三个选择的值,我想更改提交按钮将用户引导到哪个页面。这是代码:

input[type=radio] {
  position: relative;
  visibility: hidden;
  display: none;
}

label {
  background-color: white;
  border: 1px solid black;
  color: black;
  display: inline-block;
  cursor: pointer;
  margin-left: -5px;
  margin-right: -5px;
  padding: 5px 20px;
}

input[type=radio]:checked+label {
  background-color: black;
  color: white;
}

label+input[type=radio]+label {
  border-left: solid 1px black;
}

.radio-group {
  border: 1px solid black;
  display: inline-block;
  margin: 2px;
  margin-top: 80px;
  border-radius: 10px;
  overflow: hidden;
}
<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<style>

</style>

<body>

  <form>

    <div class="radio-group">
      <input type="radio" id="career" name="time"><label for="career">Career</label>
      <input type="radio" id="season" name="time"><label for="season">Season</label>
    </div>
    <div class="radio-group">
      <input type="radio" onclick = "idForm" id="pts" name="stat"><label for="pts">PTS</label>
      <input type="radio" onclick = "idForm" id="reb" name="stat"><label for="reb">REB</label>
      <input type="radio" onclick = "idForm" id="ast" name="stat"><label for="ast">AST</label>
    </div>
    <div class="radio-group">
      <input type="radio" id="total" name="stattype"><label for="total">Total</label>
      <input type="radio" id="pergame" name="stattype"><label for="pergame">Per Game</label>
    </div>

    <input type="submit">
  </form>

</body>
<script>
 function idForm(){
 var selectvalue = $('input[name=stat]:checked', '#idForm').val();


if(selectvalue == "pts"){
window.open('/pts.html','_blank');
return true;
}
else if(selectvalue == "reb"){
window.open('/reb.html','_self');
return true;
}else if(selectvalue == 'ast'){
window.open('/ast.html','_self');
return true;
}
return false;
};
</script>

我假设为此我需要 Javascript。

编辑:

更清楚地说,我希望用户能够从 pts/reb/ast 和总/每场比赛中选择职业/赛季之一。一个例子是用户选择career-pts-total,然后我希望提交按钮将他们重定向到career-pts-total.html

这是我对一个组的尝试,它不会重定向到任何页面:

 function idForm(){
 var selectvalue = $('input[name=stat]:checked', '#idForm').val();


if(selectvalue == "pts"){
window.open('/pts.html','_blank');
return true;
}
else if(selectvalue == "reb"){
window.open('/reb.html','_self');
return true;
}else if(selectvalue == 'ast'){
window.open('/ast.html','_self');
return true;
}
return false;
};

标签: javascripthtml

解决方案


一种方法如下;我确实调整了 HTML,以便data-*在元素上设置自定义属性,<form>以构建最终创建的action属性;导致以下开始标签:

<form data-action-order="time-stat-stattype">

通过此更改,我使用以下 JavaScript:

// using a named function to handle the behaviour,
// 'event' (the Event Object) is passed automatically
// from the later use of EventTarget.addEventListener():
let setFormAction = (event) => {

    // event.currentTarget is the element to which the
    // event-listener is bound (here, the <form> element):
    let self = event.currentTarget,

        // here we use Array.prototype.from() to convert
        // the iterable NodeList returned by
        // document.querySelectorAll() into an Array, in
        // order that we can use Array methods:
        inputs = Array.from(

          // using Element.querySelectorAll() to find all
          // <input> elements, within the <form>, whose
          // 'type' attribute is equal to 'radio':
          self.querySelectorAll('input[type=radio]')
        ),

        // here we filter the Array of <input> elements
        // to retain only those that are checked:
        checked = inputs.filter((input) => input.checked),

        // here we use the HTMLElement.dataset property
        // to retrieve the attribute-value from the
        // custom data-* attribute we defined earlier:
        actionOrder = self.dataset.actionOrder,

        // to find the group-names required to compose the
        // action property-value we split the actionOrder
        // on the '-' characters, resulting in an Array of
        // group-names:
        groups = actionOrder.split('-'),

        // we use this in two places, so caching the result;
        // with this we're simply checking that the number
        // of checked <input> elements is equal to the
        // number of required group-names (this is a naive
        // check and doesn't check that the <input> elements
        // are members of the required groups):
        check = checked.length === groups.length;

    if (check === true) {

      // we update the action property of the <form> element,
      // using String.prototype.replace():
      self.action = actionOrder
        .replace(
          // here we capture a group (wrapping it in parentheses)
          // comprised of a word-boundary (\b) followed by
          // one, or more (+), characters that are not ([^]) the
          // '-' character and followed in turn by another word-
          // boundary (\b). We use the global (g) flag to find all
          // matches in the String. Then we pass the matched group
          // ('match') to the anonymous function:
          /(\b[^-]+\b)/g, (match) => 

            // here we find the first (if any) <input> element
            // whose name is equal to the current matched string
            // and which also matches the :checked selector;
            // we're using template-literal syntax (a String
            // delimited by back-ticks ('`...`') which allows us
            // pass JavaScript variables into the String; here
            // ${match} is interpolated/resolved-to the value held
            // in the variable, and then retrieving the 'id' of that
            // resulting element (note this is naive, in that we
            // retrieve a property from a node without first checking
            // that the node exists; in production you should check
            // first):
            document.querySelector(`input[name=${match}]:checked`).id);
    }

    // here we enable/disable the <input type="submit"> element
    // according to whether the check is true or false, inverting
    // the result using the not ('!') operator:
    document.querySelector('input[type=submit]').disabled = !check;
  },

  // retrieving the <form> element:
  form = document.querySelector('form'),

  // creating a new Event in order that we can trigger
  // the function on page-load (in the event that you
  // have some <input> elements checked by default):
  changeEvent = new Event('change');

// we use EventTarget.addEventListener() to bind the setFormAction()
// function (note the deliberate lack of parentheses) as the
// event-handler for the 'change' event:
form.addEventListener('change', setFormAction);

// triggering the 'change' event in order to execute the function
// on page-load (as noted above):
form.dispatchEvent(changeEvent);

let setFormAction = (event) => {
    let self = event.currentTarget,
      inputs = Array.from(self.querySelectorAll('input[type=radio]')),
      checked = inputs.filter(input => input.checked),
      actionOrder = self.dataset.actionOrder,
      groups = actionOrder.split('-'),
      check = checked.length === groups.length;

    if (check === true) {
      self.action = actionOrder.replace(/(\b[^-]+\b)/g, (match) => document.querySelector(`input[name=${match}]:checked`).id);

      // purely to allow you visually see the updated/changing
      // 'action' attribute (updating the property doesn't
      // automatically update the attribute-value):
      self.setAttribute('action', self.action);
    }
    document.querySelector('input[type=submit]').disabled = !check;
  },
  form = document.querySelector('form'),
  changeEvent = new Event('change');

form.addEventListener('change', setFormAction);
form.dispatchEvent(changeEvent);
input[type=radio] {
  position: relative;
  visibility: hidden;
  display: none;
}

label {
  background-color: white;
  border: 1px solid black;
  color: black;
  display: inline-block;
  cursor: pointer;
  margin-left: -5px;
  margin-right: -5px;
  padding: 5px 20px;
}

input[type=radio]:checked+label {
  background-color: black;
  color: white;
}

label+input[type=radio]+label {
  border-left: solid 1px black;
}

.radio-group {
  border: 1px solid black;
  display: inline-block;
  margin: 2px;
  margin-top: 80px;
  border-radius: 10px;
  overflow: hidden;
}

form::before {
  content: 'Current action: \A' attr(action);
  display: block;
  min-height: 4em;
  font-size: 1.2em;
  white-space: pre-wrap;
}
<form data-action-order="time-stat-stattype">

  <div class="radio-group">
    <input type="radio" id="career" name="time"><label for="career">Career</label>
    <input type="radio" id="season" name="time"><label for="season">Season</label>
  </div>
  <div class="radio-group">
    <input type="radio" id="pts" name="stat"><label for="pts">PTS</label>
    <input type="radio" id="reb" name="stat"><label for="reb">REB</label>
    <input type="radio" id="ast" name="stat"><label for="ast">AST</label>
  </div>
  <div class="radio-group">
    <input type="radio" id="total" name="stattype"><label for="total">Total</label>
    <input type="radio" id="pergame" name="stattype"><label for="pergame">Per Game</label>
  </div>

  <input type="submit">
</form>

参考:


推荐阅读