Different if on each item in a vue list - javascript

I'm making a list with 'v-for' where each item has to have an if with a different value corresponding the array, but the Vue not allows to create a 'v-if' expression starting from {{ i.some_data_to_evaluate }} .
Have a way to solve this?
Here is my code:
HTML
<div id='test' v-for="i in items">
<p v-if={{i.value}}>{{i.some_text}}</p>
<p v-else>{{i.other_text}}</p>
</div>
JS
let test = new Vue({
el: '#test',
data: [
{some_text: 'jhon', other_text: 'jonas', value:false},
{some_text: 'joao', other_text: 'maria', value:true}
]
})
I'm just trying to change the version that is in the Vue guide.
Here's the link: http://vuejs.org/guide/list.html

You should replace the brackets with quotes on the v-if directive:
<div id="test" v-for="i in items">
<p v-if="i.value">{{i.some_text}}</p>
<p v-else>{{i.other_text}}</p>
</div>

Related

Why can't I get a basic example of working v-for in Vue JS?

I'm trying to get just a simple hello world for v-for. I've googled this for an hour and found various other posts, such as this one to no use.
My HTML:
<ul>
<li v-for="item in history">
{{ item }}
</li>
</ul>
My JS:
new Vue({
el: '#app',
data: {
history: [
'red','green','blue'
],
},
});
My Output:
{{ item }}
Someone please tell me what I'm doing wrong and why I can't get this bare-bones example working. I've tried using arrays and objects, looping using the key attribute, and several other things.
Docs: https://v2.vuejs.org/v2/guide/list.html
EDIT: apologise for the awful title; I had to change it 13 times before SO stopped yelling at me...
EDIT 2: I have the app defined containing the entire body of HTML: <div id="app">, thank you for the answers though : )
EDIT 3: Resolved, I must've had a div tag closed prematurely; commenting it out fixed the code. Thanks for the answers.
Probably you don't define the id app in the HTML section. Here is the working code.
new Vue({
el: '#app',
data: {
history: [
'red', 'green', 'blue'
],
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<ul id='app'>
<li v-for="item in history">
{{ item }}
</li>
</ul>
You need to have "#app" id in your code like this
<ul id="app">
<li v-for="item in history">
{{ item }}
</li>
</ul>

VueJS: Fixing component order in Bootstrap

I've been having some trouble recently with the order of Vue components in Bootstrap. I'm trying to generate some Bootstrap collapsible content in Vue here's the code so far:
HTML
<div class="col-sm main-content" id="main-content">
<p>
<main-section-button v-for="item in sections"
v-bind:section="item"
v-bind:data-target="'#section-' + item.text"
v-bind:aria-controls="'section-' + item.text">
</main-section-button>
</p>
<main-section v-for="item in sections"
v-bind:id="'section-' + item.text">
</main-section>
</div>
VueJS
Vue.component("main-section-button", {
props: ["section"],
template: String.raw`<button class="btn btn-block btn-dark" type="button" data-toggle="collapse" aria-expanded="false">{{ section.text }}</button>`
});
Vue.component("main-section", {
props: ["section"],
template: String.raw`<div class="collapse"><div class="card card-body"><p>Hello, World!</p></div></div></div>`
});
let app = new Vue({
el: '#main-content',
data: {
sections: [
{ id: 0, text: "example1"},
{ id: 0, text: "example2"}
]
}
});
I have tried to make just one component for main-section and main-section-button, but that did not work because of the requirement to pass an id to the card (collapsible content), and a data-target to the button that collapses and expands the content.
Current Result
Required Result
Is it possible to create a component so that the section content is always below the section button.
Thank you in advance.
I guess you have two options to achieve this:
Create a new component that takes the items and displays both components as you wish.
Do not iterate over the components, instead use a <div> around both components or a non-rendered <template> like this:
<div class="col-sm main-content" id="main-content">
<template v-for="item in sections">
<p>
<main-section-button
v-bind:section="item"
v-bind:data-target="'#section-' + item.text"
v-bind:aria-controls="'section-' + item.text">
</main-section-button>
</p>
<main-section
v-bind:id="'section-' + item.text">
</main-section>
</template>
</div>

How to use javascript method in Vue template

I am trying to split the last end of the URL to get numeric value. It is throwing an error. I haven't used vue in a while but I know we can use methods/function to get desired results? Where am I doing it wrong?
<ul>
<li v-for="(character, index) in characters" :key="index">
<router-link :to="'/characters'+ character.url.split("/").pop()">
{{character.name}}
</router-link>
</li>
</ul>
Here is an example, hope this helps:
new Vue({
el: '#app',
data: {
character: {
url: 'https://jsonplaceholder.typicode.com/todos/101'
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-html="`/characters/${character.url.split('/').pop()}`"></div>
<div> {{ `/characters/${character.url.split('/').pop()}` }}</div>
</div>
I am using string literals (Template literals or Template strings) to keep the code clean by eliminating some double/single quotes and + used for concatenation.

Setting a dynamic initial index for template variable using Vue JS

I'm using a CMS to create a front-end form where customers (theatre directors) can define several showtimes. I have a button they click to "add another" input field as needed (sidenote: I don't know how to enable a 'remove last' button using Vue, but that's another topic for another day).
I've gotten that working. But now, once a director has created their showtimes and they come back to edit them, I need the starting index of the Vue counter to be the number of fields that already exist. So if they've defined 3 showtimes already (0,1,2), the first field dynamically placed with Vue should start with 3.
Alternatively, I wonder if it'd be easier to generate an array of the existing data in Vue when the page loads, but I don't know where I'd start with that method.
Here's my HTML and Vue JS:
new Vue({
el: '#app',
data: {
timeslots: [
{
count: 0
}
],
count: 0
},
methods: {
addAnother: function(){
this.timeslots.push({
count: ++this.count
});
}
}
});
<div id="app">
{{ performances }}
<input name="performances[{{ zero_index }}][showtime]" value="{{ showtime }}">
{{ /performances }}
<template v-for="slot in timeslots">
<input name="performances[#{{ slot.count }}][showtime]" value="{{ now }}">
</template>
<div>
<button #click.prevent="addAnother">Add another</button>
</div>
</div>
Any help to move forward is appreciated!
I solved it myself in shorter time than expected using the 2nd method I speculated about in my OP, and using $index instead of an arbitrary integer like count. This method requires the JS to be put directly in my template though, not in a separate file. But that's fine by me.
<div id="oven">
<template v-for="biscuit in oven">
<div>
<input type="text" name="performances[#{{ $index }}][showtime]" value="#{{ biscuit.showtime }}">
</div>
</template>
<span class="add small black btn" #click="addAnother"><i class="fa fa-plus-circle"></i> Add another</span>
</div>
<script>
new Vue({
el: '#oven',
data: {
oven: [
{{ performances }}
{
showtime: "{{ showtime }}"
},
{{ /performances }}
]
},
methods: {
addAnother: function(){
this.oven.push({
showtime: '{{ now modify_date="+2 months" format="Y-m-d" }} 7:30 PM'
});
}
}
});
</script>

angular ng-repeat and html

So I have the next div in index.html:
...
<div ng-include src="'templates/blocks.html'" ng-controller='Foo'></div>
...
The Foo controller holds an array of html snippets under the "bars" property.
The blocks.html looks like:
<div class="block" ng-repeat="bar in bars">
<div ng-bind-html-unsafe="{{bar}}"></div>
</div>
and what I'm getting is the html as text in the div with class "block", meaning it is not evaluated as html.
thanks.
ng-bind-html-unsafe is removed in 1.2. Use ng-bing-html instead and remove the curly braces just like Sebastian said.
Include ngSanitize module as a dependancy to your app and dont forget to include its JS
//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-sanitize.js.
Remove the curly braces in ng-bind-html-unsafe and it should work:
<div class="block" ng-repeat="bar in bars">
<div ng-bind-html-unsafe="bar"></div>
</div>
Just for completeness - here is a sample jsfiddle.
<div ng-repeat="item in tree" ng-include="'a.html'" class="node"></div>
a.html
<p> {{item.name}}</p>
controller.js
$scope.tree = [
{name: 'Узел', nodes: [] },
{name: 'Морской', nodes: []},
{name: 'Устричный', nodes: []}
];

Categories

Resources