Reputation: 504
So I'm building a form and a field within the form needs to be capped at a certain length.
I then need a simple progress bar which displays how close the user is to exceeding the maximum length on the input field. So let's say the input is capped at 50 characters. When the user hits 25 characters in the input, the progress bar should be at 50%.
I've given this a go with the below code, but I'm not sure on how to do it based on keypress or the max characters.
Something similar to what I'm after:
Vue Code:
Vue.component('count-fieldtype', {
mixins: [Fieldtype],
template: `
<div>
<input type="text" class="form-control type-text mb-2" placeholder="" :maxlength="max" v-model="text" />
<small class="help-block">You have: <strong><span v-text="(max - text.length)"></span></strong> characters left.</small>
<progress max="100" :value="calculatePercentage(value)" id="progress"></progress>
</div>
`,
methods: {
calculatePercentage(value) {
let contentLentg = handleKeyUp();
return 50;
}
},
data: function() {
return {
max: 50,
text: ''
};
},
});
Any help would be appreciated!
Upvotes: 1
Views: 976
Reputation: 2070
You should use computed property to calculate progress https://v2.vuejs.org/v2/guide/computed.html
new Vue({
el: "#app",
data() {
return {
text: '',
max: 150
}
},
computed: {
progress() {
return this.text.length / this.max * 100
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<div id="app">
<div>
<input type="text" class="form-control type-text mb-2" placeholder="" :maxlength="max" v-model="text" />
<small class="help-block">You have: <strong><span v-text="(max - text.length)"></span></strong> characters left.</small>
<progress max="100" :value="progress" id="progress"></progress>
</div>
</div>
Upvotes: 2
Reputation: 1730
Here is a version with some styling, if it can help. It uses too a computed property for calculating the progress bar value. (the snippet need to be run expanded).
new Vue({
el: "#app",
data: function() {
return {
max: 50,
text: ''
};
},
computed: {
calculatePercentage() {
let contentLength = this.text.length;
return (contentLength / this.max) * 100;
}
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.container {
width: 30%;
}
progress, input {
width: 100%;
box-sizing: border-box;
}
progress {
height: 8px;
background-color: white;
appearance: none;
}
progress[value]::-webkit-progress-bar {
background-color: lightgrey;
border-radius: 2px;
}
progress[value]::-webkit-progress-value {
background-color: orange;
border-radius: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="container">
<div >
<input type="text" class="form-control type-text mb-2" placeholder="" :maxlength="max" v-model="text" />
</div>
<progress max="100" :value="calculatePercentage" id="progress"></progress>
<small class="help-block">You have: <strong><span v-text="(max - text.length)"></span></strong> characters left.</small>
</div>
</div>
Upvotes: 2
Reputation: 3994
You might not need to check for keypress events. A computed property on the text length can be used to map the progress bar.
template: `
<div>
<input type="text" class="form-control type-text mb-2" placeholder="" :maxlength="max" v-model="text" />
<small class="help-block">You have: <strong><span v-text="(max - text.length)"></span></strong> characters left.</small>
<progress max="100" :value="progress" id="progress"></progress>
</div>
`,
computed: {
progress: function(){
return Math.floor((this.text.length/this.max)*100)
}
}
Upvotes: 2