Custom spinners that use step for increment, but enforce multipleOf
This commit is contained in:
parent
e66fe5a35a
commit
ec9fbd6245
1 changed files with 97 additions and 22 deletions
|
|
@ -5,7 +5,7 @@
|
|||
<div class="input-and-buttons-container">
|
||||
<select
|
||||
v-model="internalValue"
|
||||
class="uk-form-small numeric-setting-line-input dropdown"
|
||||
class="uk-form-small property-input dropdown"
|
||||
@change="sendValue"
|
||||
>
|
||||
<option v-for="(value, display) in options" :key="value" :value="value">
|
||||
|
|
@ -18,26 +18,32 @@
|
|||
<label v-if="!useDropdown && dataType == 'number'" class="uk-form-label"
|
||||
>{{ label }}
|
||||
<div class="input-and-buttons-container">
|
||||
<div class="uk-inline number-wrapper">
|
||||
<input
|
||||
ref="numericalInput"
|
||||
v-model="internalValue"
|
||||
class="uk-form-small numeric-setting-line-input"
|
||||
class="uk-form-small property-input numeric-property"
|
||||
:class="{ edited: isEdited, flash: animateUpdate }"
|
||||
:disabled="isDisabled"
|
||||
type="number"
|
||||
:min="minimum"
|
||||
:max="maximum"
|
||||
:step="spinner_step"
|
||||
@wheel="handleSpiner"
|
||||
@input="grabFocus"
|
||||
@focusout="focusOut"
|
||||
@keydown="keyDown"
|
||||
@animationend="animationEnd"
|
||||
/>
|
||||
<div class="spinner-buttons">
|
||||
<button type="button" @click="increment(1)" @mousedown="spinnerClick">▲</button>
|
||||
<button type="button" @click="increment(-1)" @mousedown="spinnerClick">▼</button>
|
||||
</div>
|
||||
</div>
|
||||
<sync-property-button @click="requestUpdate" />
|
||||
</div>
|
||||
</label>
|
||||
<div v-if="!useDropdown && dataType == 'boolean'" class="input-and-buttons-container">
|
||||
<label class="uk-form-label numeric-setting-line-input">
|
||||
<label class="uk-form-label property-input">
|
||||
<input
|
||||
ref="checkbox"
|
||||
v-model="internalValue"
|
||||
|
|
@ -57,7 +63,7 @@
|
|||
v-for="i in valueLength"
|
||||
:key="i"
|
||||
v-model="internalValue[i - 1]"
|
||||
class="uk-form-small numeric-setting-line-input"
|
||||
class="uk-form-small property-input"
|
||||
:class="{ edited: isEdited, flash: animateUpdate }"
|
||||
:disabled="isDisabled"
|
||||
type="number"
|
||||
|
|
@ -76,7 +82,7 @@
|
|||
<div class="input-and-buttons-container">
|
||||
<input
|
||||
v-model="internalValue[key]"
|
||||
class="uk-form-small numeric-setting-line-input"
|
||||
class="uk-form-small property-input"
|
||||
:class="{ edited: isEdited, flash: animateUpdate }"
|
||||
:disabled="isDisabled"
|
||||
type="number"
|
||||
|
|
@ -94,7 +100,7 @@
|
|||
<div class="input-and-buttons-container">
|
||||
<input
|
||||
v-model="internalValue"
|
||||
class="uk-form-small numeric-setting-line-input"
|
||||
class="uk-form-small property-input"
|
||||
:class="{ edited: isEdited, flash: animateUpdate }"
|
||||
:disabled="isDisabled"
|
||||
type="text"
|
||||
|
|
@ -110,7 +116,7 @@
|
|||
<div class="input-and-buttons-container">
|
||||
<input
|
||||
v-model="internalValue"
|
||||
class="uk-form-small numeric-setting-line-input"
|
||||
class="uk-form-small property-input"
|
||||
type="text"
|
||||
disabled="true"
|
||||
/>
|
||||
|
|
@ -321,6 +327,37 @@ export default {
|
|||
this.sendValue();
|
||||
}
|
||||
},
|
||||
increment(sign) {
|
||||
const step = this.spinner_step || 1;
|
||||
const multipleOf = this.dataSchema.multipleOf;
|
||||
let newValue = Number(this.internalValue) || 0;
|
||||
newValue += sign * step;
|
||||
// Apply minimum if defined
|
||||
if (this.minimum !== undefined && this.minimum !== null) {
|
||||
newValue = Math.max(newValue, this.minimum);
|
||||
}
|
||||
// Apply maximum if defined
|
||||
if (this.maximum !== undefined && this.maximum !== null) {
|
||||
newValue = Math.min(newValue, this.maximum);
|
||||
}
|
||||
|
||||
// If mulipleOf is validated on server then enforce it.
|
||||
if (multipleOf) {
|
||||
newValue = Math.round(newValue / multipleOf) * multipleOf;
|
||||
}
|
||||
|
||||
// Rounding to about 5 sig figs to stop weird javascript rounding.
|
||||
const magnitude = Math.floor(Math.log10(Math.abs(newValue)));
|
||||
const factor = 10 ** -(Math.floor(magnitude) - 4);
|
||||
this.internalValue = Math.round(newValue * factor) / factor;
|
||||
},
|
||||
/**
|
||||
* Grab focus for the numerical input when a spinner is clicked.
|
||||
*/
|
||||
spinnerClick(event) {
|
||||
event.preventDefault();
|
||||
this.$refs.numericalInput.focus();
|
||||
},
|
||||
/** Grab the browser focus.
|
||||
*
|
||||
* This is needed for numerical elements to be in focus when a spinner
|
||||
|
|
@ -378,12 +415,50 @@ export default {
|
|||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
.numeric-setting-line-input {
|
||||
.property-input {
|
||||
flex-grow: 1;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
width: 6em;
|
||||
}
|
||||
/*Hide standard spinners as it isn't possible to customise the browser ones.*/
|
||||
.numeric-property {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
.numeric-property::-webkit-outer-spin-button,
|
||||
.numeric-property::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.number-wrapper {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: flex-start;
|
||||
align-content: stretch;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.spinner-buttons {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 1px;
|
||||
bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.spinner-buttons button {
|
||||
height: 45%;
|
||||
padding: 0 6px;
|
||||
line-height: 1;
|
||||
font-size: 10px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: #888;
|
||||
}
|
||||
.dropdown {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue