Merge pull request #742 from dod-ccpo/disable-save-buttons

Disable save buttons
This commit is contained in:
leigh-mil 2019-04-08 11:15:19 -04:00 committed by GitHub
commit cf2273d47c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 268 additions and 192 deletions

View File

@ -1,3 +1,5 @@
import { emitFieldChange } from '../lib/emitters'
export default { export default {
name: 'checkboxinput', name: 'checkboxinput',
@ -7,10 +9,7 @@ export default {
methods: { methods: {
onInput: function(e) { onInput: function(e) {
this.$root.$emit('field-change', { emitFieldChange(this, { value: e.target.checked, name: this.name })
value: e.target.checked,
name: this.name,
})
}, },
}, },
} }

View File

@ -1,5 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import { getDaysInMonth } from 'date-fns' import { getDaysInMonth } from 'date-fns'
import { emitFieldChange } from '../lib/emitters'
var paddedNumber = function(number) { var paddedNumber = function(number) {
if ((number + '').length === 1) { if ((number + '').length === 1) {
@ -62,18 +63,23 @@ export default {
isMonthValid: function() { isMonthValid: function() {
var _month = parseInt(this.month) var _month = parseInt(this.month)
var valid = _month >= 0 && _month <= 12
return _month >= 0 && _month <= 12 this._emitChange('month', this.month, valid)
return valid
}, },
isDayValid: function() { isDayValid: function() {
var _day = parseInt(this.day) var _day = parseInt(this.day)
var valid = _day >= 0 && _day <= this.daysMaxCalculation
return _day >= 0 && _day <= this.daysMaxCalculation this._emitChange('day', this.day, valid)
return valid
}, },
isYearValid: function() { isYearValid: function() {
return parseInt(this.year) >= 1 // Emit a change event
var valid = parseInt(this.year) >= 1
this._emitChange('year', this.year, valid)
return valid
}, },
isWithinDateRange: function() { isWithinDateRange: function() {
@ -128,6 +134,12 @@ export default {
}, },
}, },
methods: {
_emitChange: function(name, value, valid) {
emitFieldChange(this, { value, name })
},
},
render: function(createElement) { render: function(createElement) {
return createElement('p', 'Please implement inline-template') return createElement('p', 'Please implement inline-template')
}, },

View File

@ -0,0 +1,26 @@
import ally from 'ally.js'
import FormMixin from '../../mixins/form'
import textinput from '../text_input'
import optionsinput from '../options_input'
import DateSelector from '../date_selector'
import MultiStepModalForm from './multi_step_modal_form'
import multicheckboxinput from '../multi_checkbox_input'
import checkboxinput from '../checkbox_input'
import levelofwarrant from '../levelofwarrant'
import Modal from '../../mixins/modal'
export default {
name: 'base-form',
components: {
textinput,
optionsinput,
DateSelector,
MultiStepModalForm,
multicheckboxinput,
checkboxinput,
levelofwarrant,
Modal,
},
mixins: [FormMixin, Modal],
}

View File

@ -118,7 +118,6 @@ export default {
return newVal.showValid && previous return newVal.showValid && previous
}, true) }, true)
this.validate() this.validate()
isValid = this.errors.length == 0 && isValid isValid = this.errors.length == 0 && isValid

View File

@ -1,5 +1,6 @@
import optionsinput from '../components/options_input' import optionsinput from '../components/options_input'
import textinput from '../components/text_input' import textinput from '../components/text_input'
import { emitFieldChange } from '../lib/emitters'
export default { export default {
name: 'multicheckboxinput', name: 'multicheckboxinput',
@ -40,10 +41,7 @@ export default {
methods: { methods: {
onInput: function(e) { onInput: function(e) {
this.$root.$emit('field-change', { emitFieldChange(this, { value: e.target.value, name: this.name })
value: e.target.value,
name: this.name,
})
this.showError = false this.showError = false
this.showValid = true this.showValid = true
}, },

View File

@ -1,3 +1,5 @@
import { emitFieldChange } from '../lib/emitters'
export default { export default {
name: 'optionsinput', name: 'optionsinput',
@ -21,10 +23,7 @@ export default {
methods: { methods: {
onInput: function(e) { onInput: function(e) {
this.$root.$emit('field-change', { emitFieldChange(this, { value: e.target.value, name: this.name })
value: e.target.value,
name: this.name,
})
this.showError = false this.showError = false
this.showValid = true this.showValid = true
}, },

View File

@ -1,6 +1,7 @@
import MaskedInput, { conformToMask } from 'vue-text-mask' import MaskedInput, { conformToMask } from 'vue-text-mask'
import inputValidations from '../lib/input_validations' import inputValidations from '../lib/input_validations'
import { formatDollars } from '../lib/dollars' import { formatDollars } from '../lib/dollars'
import { emitFieldChange } from '../lib/emitters'
export default { export default {
name: 'textinput', name: 'textinput',
@ -124,7 +125,7 @@ export default {
this.showValid = this.value != '' && valid this.showValid = this.value != '' && valid
// Emit a change event // Emit a change event
this.$root.$emit('field-change', { emitFieldChange(this, {
value: this._rawValue(value), value: this._rawValue(value),
valid, valid,
name: this.name, name: this.name,

View File

@ -33,6 +33,7 @@ import { isNotInVerticalViewport } from './lib/viewport'
import DateSelector from './components/date_selector' import DateSelector from './components/date_selector'
import SidenavToggler from './components/sidenav_toggler' import SidenavToggler from './components/sidenav_toggler'
import KoReview from './components/forms/ko_review' import KoReview from './components/forms/ko_review'
import BaseForm from './components/forms/base_form'
Vue.config.productionTip = false Vue.config.productionTip = false
@ -68,12 +69,14 @@ const app = new Vue({
EditOfficerForm, EditOfficerForm,
SidenavToggler, SidenavToggler,
KoReview, KoReview,
BaseForm,
}, },
mounted: function() { mounted: function() {
this.$on('modalOpen', isOpen => { this.$on('modalOpen', data => {
if (isOpen) { if (data['isOpen']) {
document.body.className += ' modal-open' document.body.className += ' modal-open'
this.activeModal = data['name']
} else { } else {
document.body.className = document.body.className.replace( document.body.className = document.body.className.replace(
' modal-open', ' modal-open',

6
js/lib/emitters.js Normal file
View File

@ -0,0 +1,6 @@
export const emitFieldChange = (el, data) => {
el.$root.$emit('field-change', {
...data,
parent_uid: el.$parent && el.$parent._uid,
})
}

View File

@ -8,7 +8,23 @@ export default {
const { value, name } = event const { value, name } = event
if (typeof this[name] !== undefined) { if (typeof this[name] !== undefined) {
this[name] = value this[name] = value
if (event['parent_uid'] === this._uid) {
this.changed = true
}
} }
}, },
}, },
data: function() {
return {
changed: this.hasChanges,
}
},
props: {
hasChanges: {
type: Boolean,
default: false,
},
},
} }

View File

@ -10,7 +10,7 @@ export default {
openModal: function(name) { openModal: function(name) {
this.activeModal = name this.activeModal = name
this.$emit('modalOpen', true) this.$root.$emit('modalOpen', { isOpen: true, name: name })
const idSelector = `#${this.modalId}` const idSelector = `#${this.modalId}`
this.allyHandler = ally.maintain.disabled({ this.allyHandler = ally.maintain.disabled({

View File

@ -297,7 +297,11 @@
.members-table-footer { .members-table-footer {
float: right; float: right;
padding: 3 * $gap; padding: 3 * $gap 0;
.action-group.save {
padding-right: 3 * $gap;
}
} }
a.modal-link.icon-link { a.modal-link.icon-link {

View File

@ -493,12 +493,10 @@
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
.usa-button { button.usa-button {
margin-left: 4 * $gap; margin-left: 4 * $gap;
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
} }
} }
} }

View File

@ -0,0 +1,10 @@
{% macro SaveButton(text, element="button", additional_classes="", form=None) -%}
{% set class = "usa-button usa-button-primary" + additional_classes %}
{% if element == "button" %}
<button type="submit" class="{{ class }}" tabindex="0" v-bind:disabled="!changed" {{ form_attr }} >
{{ text }}
</button>
{% elif element == 'input' %}
<input type="submit" class="{{ class }}" tabindex="0" v-bind:disabled="!changed" value="{{ text }}" {% if form %}form="{{ form }}"{% endif %} />
{% endif %}
{%- endmacro %}

View File

@ -1,5 +1,6 @@
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
{% from "components/options_input.html" import OptionsInput %} {% from "components/options_input.html" import OptionsInput %}
{% from 'components/save_button.html' import SaveButton %}
{% from "components/modal.html" import Modal %} {% from "components/modal.html" import Modal %}
{% from "components/alert.html" import Alert %} {% from "components/alert.html" import Alert %}
@ -9,6 +10,7 @@
{% if g.matchesPath("portfolio-members") %} {% if g.matchesPath("portfolio-members") %}
{% include "fragments/flash.html" %} {% include "fragments/flash.html" %}
{% endif %} {% endif %}
<base-form inline-template>
<form method='POST' id="member-perms" action='{{ url_for("portfolios.edit_portfolio_members", portfolio_id=portfolio.id) }}' autocomplete="off" enctype="multipart/form-data"> <form method='POST' id="member-perms" action='{{ url_for("portfolios.edit_portfolio_members", portfolio_id=portfolio.id) }}' autocomplete="off" enctype="multipart/form-data">
{{ member_perms_form.csrf_token }} {{ member_perms_form.csrf_token }}
@ -50,10 +52,17 @@
</tbody> </tbody>
</table> </table>
<div class="members-table-footer">
<div class="action-group save">
{% if user_can(permissions.EDIT_PORTFOLIO_USERS) %}
{{ SaveButton(text=('common.save' | translate), element="input", form="member-perms") }}
{% endif %}
</div>
</div>
{% endif %} {% endif %}
</form> </form>
</base-form>
{% if user_can(permissions.EDIT_PORTFOLIO_USERS) %} {% if user_can(permissions.EDIT_PORTFOLIO_USERS) %}
{% for member in portfolio.members %} {% for member in portfolio.members %}
@ -84,19 +93,11 @@
<div class="members-table-footer"> <div class="members-table-footer">
<div class="action-group"> <div class="action-group">
{% if user_can(permissions.EDIT_PORTFOLIO_USERS) %}
<input
type='submit'
form="member-perms"
class='usa-button usa-button-primary'
value={{ "common.save" | translate }} />
{% endif %}
{% if user_can(permissions.CREATE_PORTFOLIO_USERS) %} {% if user_can(permissions.CREATE_PORTFOLIO_USERS) %}
{% include "fragments/admin/add_new_portfolio_member.html" %} {% include "fragments/admin/add_new_portfolio_member.html" %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div> </div>
</section> </section>

View File

@ -3,7 +3,9 @@
{% from "components/date_input.html" import DateInput %} {% from "components/date_input.html" import DateInput %}
{% from "components/phone_input.html" import PhoneInput %} {% from "components/phone_input.html" import PhoneInput %}
{% from "components/date_picker.html" import DatePicker %} {% from "components/date_picker.html" import DatePicker %}
{% from 'components/save_button.html' import SaveButton %}
<base-form inline-template>
<form method="POST" action='{{ form_action }}'> <form method="POST" action='{{ form_action }}'>
{{ form.csrf_token }} {{ form.csrf_token }}
<div class='panel'> <div class='panel'>
@ -33,8 +35,7 @@
</div> </div>
<div class='action-group'> <div class='action-group'>
<button class='usa-button usa-button-big' type='submit'> {{ SaveButton(text=("fragments.edit_user_form.save_details_button" | translate), additional_classes="usa-button-big" )}}
{{ "fragments.edit_user_form.save_details_button" | translate }}
</button>
</div> </div>
</form> </form>
</base-form>

View File

@ -4,6 +4,7 @@
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
{% from "components/text_input.html" import TextInput %} {% from "components/text_input.html" import TextInput %}
{% from "components/multi_step_modal_form.html" import MultiStepModalForm %} {% from "components/multi_step_modal_form.html" import MultiStepModalForm %}
{% from 'components/save_button.html' import SaveButton %}
{% set secondary_breadcrumb = "navigation.portfolio_navigation.portfolio_admin" | translate %} {% set secondary_breadcrumb = "navigation.portfolio_navigation.portfolio_admin" | translate %}
@ -15,6 +16,7 @@
<div class="panel__content"> <div class="panel__content">
{% if user_can(permissions.VIEW_PORTFOLIO_NAME) %} {% if user_can(permissions.VIEW_PORTFOLIO_NAME) %}
<base-form inline-template>
<form method="POST" action="{{ url_for('portfolios.edit_portfolio', portfolio_id=portfolio.id) }}" autocomplete="false"> <form method="POST" action="{{ url_for('portfolios.edit_portfolio', portfolio_id=portfolio.id) }}" autocomplete="false">
{{ portfolio_form.csrf_token }} {{ portfolio_form.csrf_token }}
<div class='form-row'> <div class='form-row'>
@ -23,7 +25,7 @@
</div> </div>
<div class='edit-portfolio-name action-group'> <div class='edit-portfolio-name action-group'>
<button type="submit" class="usa-button usa-button-big usa-button-primary" tabindex="0">Save</button> {{ SaveButton(text='Save', additional_classes='usa-button-big') }}
</div> </div>
</div> </div>
<div class='defense-row'> <div class='defense-row'>
@ -37,6 +39,7 @@
</div> </div>
</div> </div>
</form> </form>
</base-form>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -4,6 +4,7 @@
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
{% from "components/modal.html" import Modal %} {% from "components/modal.html" import Modal %}
{% from "components/text_input.html" import TextInput %} {% from "components/text_input.html" import TextInput %}
{% from 'components/save_button.html' import SaveButton %}
{% set secondary_breadcrumb = 'portfolios.applications.new_application_title' | translate %} {% set secondary_breadcrumb = 'portfolios.applications.new_application_title' | translate %}
@ -76,7 +77,7 @@
</div> </div>
<div class="action-group"> <div class="action-group">
<button class="usa-button usa-button-primary" tabindex="0" type="submit">{{ 'portfolios.applications.create_button_text' | translate }}</button> {{ SaveButton(text=('portfolios.applications.create_button_text' | translate)) }}
</div> </div>
</form> </form>
</new-application> </new-application>

View File

@ -6,6 +6,7 @@
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
{% from "components/text_input.html" import TextInput %} {% from "components/text_input.html" import TextInput %}
{% from "components/confirmation_button.html" import ConfirmationButton %} {% from "components/confirmation_button.html" import ConfirmationButton %}
{% from 'components/save_button.html' import SaveButton %}
{% macro Link(text, icon_name, onClick=None, url='#', classes='') %} {% macro Link(text, icon_name, onClick=None, url='#', classes='') %}
@ -59,7 +60,7 @@
{{ Icon("x") }} {{ Icon("x") }}
<span>Cancel</span> <span>Cancel</span>
</a> </a>
<input type='submit' class='usa-button usa-button-primary' value='Save Changes' /> {{ SaveButton(text='Save Changes', element="input") }}
</div> </div>
</div> </div>
</template> </template>

View File

@ -10,7 +10,7 @@
{% from "components/alert.html" import Alert %} {% from "components/alert.html" import Alert %}
{% from "components/review_field.html" import ReviewField %} {% from "components/review_field.html" import ReviewField %}
{% from "components/upload_input.html" import UploadInput %} {% from "components/upload_input.html" import UploadInput %}
{% from 'components/save_button.html' import SaveButton %}
{% block content %} {% block content %}
<ko-review inline-template v-bind:initial-data='{{ form.data|tojson }}'> <ko-review inline-template v-bind:initial-data='{{ form.data|tojson }}'>
@ -103,7 +103,7 @@
{% endblock %} {% endblock %}
<div class='action-group'> <div class='action-group'>
<input type='submit' class='usa-button usa-button-primary' value='Continue' /> {{ SaveButton(text="Continue", element="input") }}
</div> </div>
</form> </form>

View File

@ -2,11 +2,12 @@
{% from "components/text_input.html" import TextInput %} {% from "components/text_input.html" import TextInput %}
{% from "components/multi_checkbox_input.html" import MultiCheckboxInput %} {% from "components/multi_checkbox_input.html" import MultiCheckboxInput %}
{% from 'components/save_button.html' import SaveButton %}
{% block content %} {% block content %}
{% include "fragments/flash.html" %} {% include "fragments/flash.html" %}
<base-form inline-template>
<div class="col"> <div class="col">
<div class="panel"> <div class="panel">
@ -31,13 +32,11 @@
{{ MultiCheckboxInput(form.required_distribution) }} {{ MultiCheckboxInput(form.required_distribution) }}
<div class="action-group"> <div class="action-group">
<button class="usa-button usa-button-big usa-button-primary"> {{ SaveButton(text='Continue', additional_classes="usa-button-big") }}
Continue
</button>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</base-form>
{% endblock %} {% endblock %}

View File

@ -3,8 +3,10 @@
{% from "components/text_input.html" import TextInput %} {% from "components/text_input.html" import TextInput %}
{% from "components/checkbox_input.html" import CheckboxInput %} {% from "components/checkbox_input.html" import CheckboxInput %}
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
{% from 'components/save_button.html' import SaveButton %}
{% block content %} {% block content %}
<base-form inline-template>
<form method="POST" action='{{ url_for("task_orders.record_signature", task_order_id=task_order_id) }}'> <form method="POST" action='{{ url_for("task_orders.record_signature", task_order_id=task_order_id) }}'>
{{ form.csrf_token }} {{ form.csrf_token }}
<div class="row row--pad"> <div class="row row--pad">
@ -37,10 +39,7 @@
</div> </div>
</div> </div>
<div class="action-group"> <div class="action-group">
<button class="usa-button usa-button-big usa-button-primary"> {{ SaveButton(text=('common.sign' | translate), additional_classes="usa-button-big") }}
{{ "common.sign" | translate }}
</button>
<a <a
href="{{ url_for("portfolios.ko_review", portfolio_id=portfolio_id, task_order_id=task_order_id) }}" href="{{ url_for("portfolios.ko_review", portfolio_id=portfolio_id, task_order_id=task_order_id) }}"
class="action-group__action icon-link"> class="action-group__action icon-link">
@ -52,5 +51,5 @@
</div> </div>
</div> </div>
</form> </form>
</base-form>
{% endblock %} {% endblock %}