问题
What's the best way to enforce require
check on paper-radio-group
? I saw another question and answer that uses fallback-selection
, here, but I want to force the user to choose "yes" or "no".
<paper-radio-group selected="" attr-for-selected="value" data-required="{{question.required}}">
<paper-radio-button name="{{question.id}}" value="yes">Yes</paper-radio-button>
<paper-radio-button name="{{question.id}}" value="no">No</paper-radio-button>
</paper-radio-group>
The only way I can think of, is to run a checker function at the end to check for it specifically.
checkAnswers: function() {
var currentGroup = document.querySelector('.question-group.iron-selected'),
answers = Array.prototype.slice.call(currentGroup.querySelectorAll('paper-input, paper-radio-group'));
return answers.every(function(a) {
return a.validate && a.validate() || a.nodeName === 'PAPER-RADIO-GROUP' && a.dataRequired && a.selected;
});;
},
The above works, but I still need to figure out a way to display the error to the user. Is there a better way to validate required paper-radio-group
?
回答1:
I'm assuming you call checkAnswers()
in your submit
handler. Note that <iron-form>.validate() performs similar logic except it only calls validate()
on children that have the IronFormElementBehavior
and the required
attribute. If you apply required
to the appropriate input elements, you could replace checkAnswers()
with this.$.form.validate()
.
submit: function() {
//var isValid = checkAnswers();
var isValid = this.$.form.validate();
}
<paper-radio-group>
actually does not have the IronFormElementBehavior
, so its required
attribute has no effect. You could workaround this by wrapping <paper-radio-group>
with your own custom element that properly adds the behavior:
<dom-module id="radio-group">
<template>
<paper-radio-group id="group"
attr-for-selected="{{attrForSelected}}"
selected="{{selected}}">
<content></content>
</paper-radio-group>
</template>
<script>
Polymer({
is: 'radio-group',
behaviors: [
Polymer.IronFormElementBehavior
],
get selectedItem() {
return this.$.group.selectedItem;
},
validate: function() {
return this.selectedItem != null;
}
});
</script>
</dom-module>
Then, just replace <paper-radio-group>
with <radio-group>
:
<radio-group attr-for-selected="value" required>
<paper-radio-button value="yes">Yes</paper-radio-button>
<paper-radio-button value="no">No</paper-radio-button>
</radio-group>
<head>
<base href="https://polygit.org/polymer+1.11.0/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="iron-form/iron-form.html">
<link rel="import" href="iron-label/iron-label.html">
<link rel="import" href="paper-radio-group/paper-radio-group.html">
<link rel="import" href="paper-radio-button/paper-radio-button.html">
<link rel="import" href="paper-button/paper-button.html">
</head>
<body>
<x-form></x-form>
<dom-module id="x-form">
<template>
<iron-form id="form">
<form action="">
<iron-label>Do you agree?
<radio-group name="answers" id="answer" attr-for-selected="value" required>
<paper-radio-button name="answerY" value="yes">Yes</paper-radio-button>
<paper-radio-button name="answerN" value="no">No</paper-radio-button>
</radio-group>
</iron-label>
<div>
<paper-button on-click="submit">Submit</paper-button>
</div>
</form>
</iron-form>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-form',
submit: function() {
console.log('valid', this.$.form.validate(),
'answer', this.$.answer.selectedItem && this.$.answer.selectedItem.value);
}
});
});
</script>
</dom-module>
<dom-module id="radio-group">
<template>
<paper-radio-group id="group" attr-for-selected="{{attrForSelected}}" selected="{{selected}}">
<content></content>
</paper-radio-group>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'radio-group',
behaviors: [
Polymer.IronFormElementBehavior
],
get selectedItem() {
return this.$.group.selectedItem;
},
validate: function() {
return this.selectedItem != null;
}
});
});
</script>
</dom-module>
</body>
codepen
For binary input like these Yes/No answers, it might be appropriate to use <paper-checkbox>
instead, as it requires less code and simplifies the form for that input.
<head>
<base href="https://polygit.org/polymer+1.11.0/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="iron-form/iron-form.html">
<link rel="import" href="paper-checkbox/paper-checkbox.html">
<link rel="import" href="paper-button/paper-button.html">
</head>
<body>
<x-form></x-form>
<dom-module id="x-form">
<template>
<iron-form id="form">
<form action="">
<paper-checkbox id="answer" required>I agree</paper-checkbox>
<div>
<paper-button on-click="submit">Submit</paper-button>
</div>
</form>
</iron-form>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-form',
submit: function() {
console.log('valid', this.$.form.validate(),
'answer', this.$.answer.checked);
}
});
});
</script>
</dom-module>
</body>
codepen
来源:https://stackoverflow.com/questions/38003624/how-to-enforce-required-paper-radio-group-in-polymer