I would like to find if my duration is > 0. I use MomentJs and Vue to get my duration using this code :
moment3: function (date) {
var now = moment();
var day = moment(date);
var duration = day.diff(now);
return parseInt(duration);
},
I get the duration correctly (2987546325 in example). But still this code not working.
<a v-if="event.time | moment3 > 0"> Do somethingHere </a>
Thank you for help.
I assume that you're trying to use moment3 as a Vue filter function.
There are two problems here:
You can't use a filter function in a v-if expression. They're only available inside a {{ ... }} or a v-bind expression.
You can't put anything after a filter function, other than the function's arguments or another filter function. So the > 0 isn't allowed even if you were in a {{ ... }} or v-bind.
See https://v2.vuejs.org/v2/guide/filters.html
The | character will just be interpreted as JavaScript's bitwise OR operator in this case.
You'd probably be better off just using a method instead. So define moment3 inside your component's methods and then call it using v-if="moment3(event.time) > 0".
Related
When I have a textarea like
<textarea v-model="foo.abc.text"></textarea>
and either foo or foo.abc does not exist yet then
vue removes either parts of the DOM or is giving me a blank page.
It does never recover.
That alone is annoying, regardless of if I am using a debug version of vue or not.
If I try to use an approach that I have been advised to use earlier like
<textarea v-model="foo?.abc?.text"></textarea>
then I am still out of luck, I presume that I get a "rvalue" using those question marks and what I need rather is a variable location.
How do I, with as little trickery as possible, allow v-model to exist later on even if it doesnt exist now (late binding)?
Just shape your data accordingly and initialize it with empty values:
data(){
return {
foo: {
abc: {
text: ''
}
}
}
}
You can later populate it e.g. with the result of api call, but it's still better to initialize data properly
I would suggest going the :value + #input way. It allow more control over the input model, and does not require hiding it.
<textarea :value="!!foo && foo.abc.text" #input="(val) => !!foo && (foo.abc.text = val)" />
You can even hook in a validator:
<textarea
:value="!!foo && foo.abc.text"
#input="(val) => !!foo && (foo.abc.text = val)"
:rules="v => !v && 'The object has not been initialised'"
/>
I found a solution I can live with and then I got a comment in the same direction:
Conditionally showing the textarea.
v-if seems to do it but it falls under the "trickery" category, I think (angularjs would be more relaxed).
<textarea v-if="foo!=null" v-model="foo.abc"></textarea>
The symptom to hiding components if something is not all correct is not the best part of vue.js. Better show them and color them red.
How can you calculate something inside a html template of go?
For example:
{{ $length := len . }}
<p>The last index of this map is: {{ $length -1 }} </p>
Were the . is a map.
The code {{ $length -1 }} is not working, is there a way to achieve this?
You can't. Templates are not a scripting language. By design philosophy, complex logic should be outside of templates.
Either pass the calculated result as a parameter (preferred / easiest), or register custom functions which you can call during template execution, pass values to them and which may perform calculations and return any values (e.g. return param - 1).
For examples of registering and using custom functions, see:
Golang templates (and passing funcs to template)
How do I access object field by variable in template?
Iterate Go map get index.
The other answers are correct, you can't do it in the template themselves. However, here's a working example of how to use Funcs:
package main
import (
"fmt"
"html/template"
"os"
)
type MyMap map[string]string
func LastMapIndex(args ...interface{}) string {
if m, ok := args[0].(MyMap); ok && len(args) == 1 {
return fmt.Sprintf("%d", len(m) - 1)
}
return ""
}
func main() {
myMap := MyMap{}
myMap["foo"] = "bar"
t := template.New("template test")
t = t.Funcs(template.FuncMap{"LastMapIndex": LastMapIndex})
t = template.Must(t.Parse("Last map index: {{.|LastMapIndex}}\n"))
t.Execute(os.Stdout, myMap)
}
Playground: https://play.golang.org/p/YNchaHc5Spz
You can use a FuncMap like this. Once you define a function within a funcmap, you can use it in the HTML. In your case you could define a MapLength function or something similar that calculates the length of a given map and returns it for you. You can then call it in the template a bit like this:
<p>The last index of this map is: {{ .MapLength . }} </p>
validate, and Im trying to create multiple rules for my textfield for example: required, minlength, maxLength and chain them together, and based on whic h parameter is passed to preform validation
So I tried using example from the docs:
http://vee-validate.logaretm.com/v2/guide/custom-rules.html#args-and-rule-configuration
const isBetween = (value, { min, max } = {}) => {
return Number(min) <= value && Number(max) >= value;
};
// The first param is called 'min', and the second is called 'max'.
const paramNames = ['min', 'max'];
Validator.extend('between', isBetween, {
paramNames // pass it in the extend options.
});
And my Vue model looks like this:
<ValidationProvider
v-if="item && item.type === 'TEXT_AREA'"
:rules="`isBetween:true, 10`"
v-slot="{ errors, valid, validate }"
>
<b-form-textarea
size="sm"
:id="`attribute`"
:value="attributeValue"
#input="addAttributeValue($event, uid, validate)"
/>
<span>{{ displayError(errors) }}</span>
</ValidationProvider>
Here I try to pass in IsBeterrn params like: required, length and based on that to preform validation but I always get min & max value as null, and arguments is array instead of object
Also my second question is how would I use required from vee-validate in my custom rule
You have two ways of specifying parameters, with strings or with objects. I suggest you use the object method like this:
<ValidationProvider
:rules="{between:[0, 10]}"
>
You had a couple mistakes - the rule is called between because that's what you called it when you did this:
Validator.extend('between', isBetween, {
paramNames // pass it in the extend options.
});
Also, you can't use a boolean and a number as the parameter as you did here:
:rules="`isBetween:true, 10`"
The way I specified it, with :rules="{between:[0, 10]}" also lets you make the min and max variable if you wanted, i.e. if you had a component data item called minValue you could use that in the rule like this :rules="{between:[minValue, 10]}" and your rules would react to changes to minValue.
Lets say I have a custom filter cf.js that needs to return multiple values in an array like this:
export default (value) => {
var a = 5
var b = 3
return [a, b]
}
In my vue file, how can I display only the first element? I thought something like below would work but they do not
{{ myvar | cf[0] }} or {{ (myvar | cf)[0] }}
You're limited by the filter syntax in the Vue template, so what you tried won't work.
A filter doesn't make sense in the example you've given since it doesn't make use of the argument.
But anyway, to answer your question, two options come to mind:
1. Define another filter to get the first element
{{ myvar | cf | first }}
export default function first(value) {
return value[0]
}
2. Call the filter function manually
This will allow you to do what you want with the filter result since you're just calling it as if it were any other function.
{{ $options.filters.cf(myvar)[0] }}
I want to create a complex condition to pass to the v-if directive.
I have tried the following.
<div v-if="(order.order_products[key].statuses[0].id) != 3 || order.status != 3" >
Can I add a complex condition in Vue's v-if? This is not working.
I also tried with && but that wasn't working, either. I haven't found anything in the documentation about this.
Firstly, to answer your question.
Can I add a complex condition in Vue's v-if?
You can pass an arbitrary JavaScript expression to the v-if directive in Vue, including a complex boolean expression which contains operators || or &&.
You can test this on your own. For example, try having the following template.
<div v-if="true && false">I am not visible!</div>
Of course, you might try out something less trivial, too:
<div v-if="1 == 2 || (1 + 2 == 3 && 4 == 4)">I am visible!</div>
Your expression looks good, but based on the provided information it's impossible to deduce what exactly is wrong.
Your problem is something else: maybe the data is not in the format you thought it would be, or maybe your logic has a flaw in it.
Yes, you can set complex condition. I suggest you to use Vue computed fields, so you will have better highlight (through Vue Devtools) of variables which use in v-if expression. I suppose that order is data field, so you can set computed fields like this:
computed: {
orderStatusId: function () {
// Write some checks is variable defined/undefined
return this.order.order_products[key].statuses[0].id
},
orderStatus: function () {
return this.order.status
}
}
and v-if expression should look like this:
<div v-if="orderStatusId !== 3 || orderStatus !== 3" >
In this approach you can review values of variables in your v-if expression.
Yes, you can use any JavaScript expresion inside v-if quotes.
But I recommend you to create a function or computed function and to call it inside your if statement, for better readability.
ex:
computed: {
shouldDisplay: function () {
return this.order.order_products[key].statuses[0].id) !== 3 || this.order.status !== 3;
}
...
}
<div v-if="shouldDisplay"> ... </div>
v-if="(segmento != 4) && (segmento != 2) && (segmento != 8)"
Works like a breeze for me!