vue JS - Append data (strings) to a placeholder - vue.js

I am a absolut beginner with vue.js. So I did a little app for learning. But I stuck a little bit with append-Data to a placeholder, if that is the right term, for
{{ message1 }}
Here is my code:
<script>
Vue.createApp({
data() {
return {
bheight: '',
bwidth: '',
}
},
methods: {
domath(event) {
alert(`Hello!`)
}
}
}).mount('#app')
</script>
The "domath" method is triggred by a button. That work (the allert show up). I have this placeholder "message1. {{ message1 }}
What I want is this: If the button is clicked, I want the data from "bheight" and "bwidth" appends to the placeholder {{ message1 }}
Later I want to do a math with this both variables. And append the result in the placeholder.
Id do not figured out how I can to this. Can some help me please?

You need to have an additional variable:
data() {
return {
bheight: '',
bwidth: '',
message1: ''
}
And then:
domath(event) {
this.message1 += this.bwidth + ', ' + this.bheight;
}
Using this is crucial iin this context.

Try something like this:
Add computed Property
computed: {
placeholder() {
return this.errors.has('end_date') ? 'Your placeholder text' : ''
}
}
Next Steps:
Bind to your computed placeholder property with v-bind:placeholder="placeholder"

Related

Vue search while typing

I have search field and I wish to have the results in real-time,
I have no issue with returning data or showing data but I need a way to send input value to back-end while user is typing it.
Code
HTML
<el-input placeholder="Type something" v-model="search">
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
Script
data() {
return {
search: '' // getting data of input field
}
},
I've tried to compute it but it didn't return data
computed : {
searchSubmit: {
get: function () {
console.log(this.search);
}
}
},
Any idea?
For side effects as calling backend you can use Watchers.
watch: {
search(value) {
yourApiCall(value)
}
}

How do I properly display data from this Vue method?

I'm new to Vue and JS.
Could someone help me understand how can I:
display the data I get from the method shown below
and format the method itself and make it look like a proper Vue method in ES6
Code:
Right now it looks like this and just displays data to console.
[...]
<script>
var d = require('../util/diskinfo')
export default {
data () {
return {
}
},
methods: {
getDrivesList () {
d.getDrives(function(err, aDrives) {
for (var i = 0; i < aDrives.length; i++) {
console.log('Drive ' + aDrives[i].filesystem)
console.log('blocks ' + aDrives[i].blocks)
console.log('used ' + aDrives[i].used)
console.log('available ' + aDrives[i].available)
console.log('capacity ' + aDrives[i].capacity)
console.log('mounted ' + aDrives[i].mounted)
}
})
}
}
}
</script>
I want to display it on the page using a loop. Something like this:
<div v-for="i in aDrives" :key="i.id">
<p>Disk name: {{aDrives[i].mounted}}</p>
<p>Disk size: {{aDrives[i].blocks}}</p>
</div>
There's going to be 2 loops - one in the method and one in the template, which makes it confusing. Should I maybe save it to data () first? I'm not sure how to do it properly.
If I understand well, you will receive an array of data and you want to display it. In this case you don't need to loop in the model and in the template. You will just save array locally and then loop through it once in the template.
I will illustrate some ES6 syntax as well in my example:
<template>
<div v-for="driver in drivers">
<p> {{ driver.mounted }} </p>
... display all the data here
</div>
</template>
<script>
import d from '../util/diskinfo'
export default {
data () {
return {
drivers: []
}
},
methods: {
getDrivesList () {
d.getDrives((err, aDrives) => (this.drivers = aDrivers))
}
}
}
</script>

Vue.js 2: Highlight string occurrence

Is there a convenient way to highlight all string occurrences of a string in a text or an element?
Something like the filter method from vue.js 1?
The only problem with my solution is, that the whole v-html-text is now lowercase..
I defined the highlight-method in the methods-block:
methods: {
highlight(words, query) {
if(query === '') { return words }
if(typeof(words) === 'number') {
words = '' + words + ''
}
// when removing the .toLowerCase() your search becomes case-sensitive
return words.toLowerCase().replace(query, '<span style="background: yellow;">' + query + '</span>')
}
}
In my template it looks like this:
<span v-html="highlight('This is some sort of test', 'some')"> // should now highlight 'some'
There are filters in vuejs2 as well. You just create your own method to highlight.
<div>{{ 'some-text' | highlight }}
new Vue({
// ...
filters: {
highlight: function (value) {
// logic
}
}
})

Vue.js attach text after clicking. how?

I have this Vue Material (Vue.js) tag, with the function
<md-button id="" v-on:click.native="requestSelected(request)">
methods: {
requestSelected: function(request) {
request.accepted = true;
console.log(request);
var card = document.getElementById('text');
var accept = document.createTextNode("Job selected");
card.appendChild(accept);
}
I'm trying to add some text on the DOM after clicking, could someone recommend to me some Vue js documentacion to check info please
In your Vue component, create a data property for your display text:
data() {
return {
displayText: '',
}
}
Then, just put a reference to displayText in your template like so:
{{ displayText }}
Vue will initially display nothing, since displayText is empty, and the automatically update the DOM when displayText changes.
You would change the text in the requestSelected method like so:
requestSelected: function(request) {
request.accepted = true;
this.displayText = "Job selected";
}
Here's an example in codepen.

Only null or Array instances can be bound to a multi-select

I'm building a multi-step form in Aurelia where each page shows one question.
I use the same view for every question, with if statements determining what type of form field to show.
When I try to bind my question data to a multiple select element however, Aurelia throws errors and says "Only null or Array instances can be bound to a multi-select.".
What's really strange is that if the first question is a multiple select I don't get the error until I come to a non-multiselect question and then go back to the multiselect question.
I can solve this entire problem by setting activationStrategy: 'replace' for this route, but I really don't want that.
The important code follows:
import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
#inject(Router)
export class Form {
constructor (router) {
this.router = router;
this.active = 0;
this.field = null;
this.fields = [
{
type: 'text',
value: null
},
{
type: 'select',
value: [],
options: [
'foo',
'bar'
]
},
{
type: 'select',
value: [],
options: [
'foo',
'bar'
]
},
{
type: 'text',
value: null
},
];
}
activate (routeParams) {
this.active = routeParams.fieldIndex || 0;
this.active = parseInt(this.active);
this.field = this.fields[this.active];
}
prev () {
if (typeof this.fields[this.active - 1] !== 'undefined') {
this.router.navigateToRoute('form', {
fieldIndex: this.active - 1
});
return true;
}
else {
return false;
}
}
next () {
if (typeof this.fields[this.active + 1] !== 'undefined') {
this.router.navigateToRoute('form', {
fieldIndex: this.active + 1
});
return true;
}
else {
return false;
}
}
}
And the template:
<template>
<div class="select" if.bind="field.type == 'select'">
<select value.bind="field.value" multiple="multiple">
<option repeat.for="option of field.options" value.bind="option">${option}</option>
</select>
</div>
<div class="text" if.bind="field.type == 'text'">
<input type="text" value.bind="field.value">
</div>
<a click.delegate="prev()">Previous</a> | <a click.delegate="next()">Next</a>
</template>
But you'll probably want to check out the GistRun: https://gist.run/?id=4d7a0842929dc4086153e29e03afbb7a to get a better understanding.
Try setting the first question to a multiselect and you'll notice the error disappears (until you go back to it). You can also try activationStrategy in app.js like mentioned above.
Why is this happening and how can I solve it?
Also note that in my real app I'm actually using compose instead of ifs but have tried with both and both produce the same error. It almost seems as if the select values are bound before the if is evaluated, causing the error to show up because the text field type lacks the options array.
A little late but I wanted to give a suggestion -- for SELECT multi-selects, you should decouple the bound variable from the multi-selector to prevent those errors.
For example, if you in your custom elements that bind to 'selected', they should bind to:
<select multiple value.two-way="selectedDecoupled">
Then when the actual variable 'selected' changes, it only changes in the custom element if the bound value is an array:
selectedChanged( newV, oldV ){
if( typeof newV =='object' )
this.selectedDecoupled = newV;
else
this.selectedDecoupled = [];
$(this.SELECT).val(this.selectedDecoupled ).trigger('change');
}
Example of it in use with a custom select2 element:
https://github.com/codefreeze8/aurelia-select2
Ok so it turns out swapping the order of the HTML, and putting the select after the input solves this issue.
Jeremy Danyow explains it like this:
When Form.field changes, the bindings subscribing to that property's changes evaluate sequentially. Which means there's a period of time when the select AND the input are both on the page. The html input element coaleses null values to empty string which in turn causes field.value to be empty string, which makes the multi-select throw.
Very tricky to track down imo but I'm glad the Aurelia devs are so helpful over on Github.
Working Gist: https://gist.run/?id=3f88b2c31f27f0f435afe14e89b13d56