formatting json file with vue.js - javascript

How can I show the output from json file with vue.js
this is my example:
access_type: {
"id": 1210765901,
"version": "17",
"creation_time": "2015-04-02 15:09:02",
"change_time": "2017-01-06 02:51:01",
"fixnet_id": "BN00002969937",
"status": "ACTIVE",
"xipsib_lan_ip": null
}
I wanna make the output like this:
id: 1210765901
version: 17
...
this is my script:
<div class="card-content">
<pre v-for="(info, index) in activeInfos" :key="index">
<li>{{ type }}: {{ info}}</li>
</pre>
</div>

thanks for your help
i have found the solution:
<vue-tabs class="row" direction="vertical" value="Description">
<div v-for="(siteParts, index) in sitePartLine">
<v-tab :title="sitePartLine[index].serial_no" v-if="sitePartLine[index]">
<div class="description text-left" v-for="siteParts in sitePartLine">
{{ siteParts.fixnet_id }}
<div class="description text-left" v-for="item in siteParts.part_attributes">
<small><strong>{{item.x_name}}</strong> {{item.x_value}}</small>
</div>
</div>
</v-tab>
</div>
</vue-tabs>

Related

Vue CLI: Project list with component

I'm completely new to VueJS and am trying to create a project tile list with different data values per tile. I use Vue CLI. I created a component which is my template for one project tile.
component TheProjectTile.vue :
<template>
<router-link to="{{ project.url }}">
<div
class="row project-container"
style="background-color: {{ project.backgroundcolor }};"
v-scrollanimation
>
<div class="column column-60">
<h2>{{ project.title }}</h2>
<div class="button">view</div>
</div>
<div class="column">
<img src="#/assets/img/{{ project.image }}" alt="{{ project.title }}" />
</div>
</div>
</router-link>
</template>
<script type="text/javascript">
export default {
props: { project: Object },
data() {
return {}
}
}
</script>
Then I have my View on my Vue CLI application where I want to render the project tiles and where I want to give the data to the tiles:
View where the projects should be shown
<template>
<div id="projekte">
<section class="container">
<div id="projects">
<projectlist v-for="project in projects" :project="project" />
</div>
</section>
</div>
</template>
<script>
import TheProjectTile from './components/TheProjectTile'
export default {
components: {
projectlist: TheProjectTile
},
data() {
return {
projects: [
{
url: '/projekte/client1',
backgroundcolor: '#005ca9',
title: 'Website client 1',
img: 'client1.png'
},
{
url: '/projekte/client2',
backgroundcolor: '#c10b25',
title: 'Website client 2',
img: 'client2.png'
}
]
}
}
}
</script>
What do I need to change that it works? :/
Please take a look at following snippet:
You need to bind data with v-bind or :,
in v-for loop you need key
Vue.component('projectList', {
template: `
<a :to="project.url">
<div
class="row project-container"
:style="{'background-color': project.backgroundcolor}"
>
<div class="column column-60">
<h2>{{ project.title }}</h2>
<div class="button">view</div>
</div>
<div class="column">
<img :src="'#/assets/img/'+project.image" :alt="project.title" />
</div>
</div>
</a>
`,
props: { project: Object },
})
new Vue({
el: '#demo',
data() {
return {
projects: [{url: '/projekte/client1', backgroundcolor: '#005ca9', title: 'Website client 1', img: 'client1.png'}, {url: '/projekte/client2', backgroundcolor: '#c10b25', title: 'Website client 2', img: 'client2.png'}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div id="projekte">
<section class="container">
<div id="projects">
<!-- 👇 key -->
<project-list v-for="(project, index) in projects" :key="index" :project="project" />
</div>
</section>
</div>
</div>

Passing context to tooltip of ngx bootstrap

I'm working with tooltip in ngx-bootstrap, and want to pass data to the ng-template being to the tooltip. The documentation provides [tooltipContext], but it didn't seem to be working. I have provided a code snippet.
HTML:
<ng-template #tooltipTmpl let-view="view">
<div class="tooltip-section">
<div class="section-title">
{{ view.dateRangeText }}
</div>
<div class="section-text">
{{ view.data }}
</div>
</div>
</ng-template>
<div
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl"
[tooltipContext]="{view: view}"
containerClass="white-tool-tip"
placement="top"
>
<div class="sub-title">
{{ view.title }}
</div>
</div>
REF: https://valor-software.com/ngx-bootstrap/#/tooltip
I have used bootstrap popover in my projects, so would recommend using popover.
Also, there was an issue created on GitHub but the user ended up using popover -
https://github.com/valor-software/ngx-bootstrap/issues/4775
#Yiu Pang Chan - you can have views array with following approach.
In app.component.html file
<div *ngFor="let view of views; let i = index">
<button type="button" class="btn btn-success"
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl" on-mouseover="setTooltipData(view)" >
Show me tooltip with html {{ view.title }}
</button>
</div>
<ng-template #tooltipTmpl>
<h4>
{{ viewDateRangeText }}
</h4>
<div>
<i>
{{ viewData }}
</i>
</div>
</ng-template>
In app.component.ts file
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public viewDateRangeText: string;
public viewData: any;
setTooltipData(view: any){
viewDateRangeText = view.dateRangeText;
viewData = view.data;
}
}
I have face the same problem , so far I have check the source code the tooltipContext mark as deprecated you can do a work a round thi like this
you can still access to the view property inside the ng-template
<button type="button" class="btn btn-success"
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl">
Show me tooltip with html {{ view.title }}
</button>
<ng-template #tooltipTmpl>
<h4>
{{ view.dateRangeText }}
</h4>
<div>
<i>
{{ view.data }}
</i>
</div>
</ng-template>
demo 🔥🔥
Updated 🚀🚀
incase you want to use my solation with array of views , you juest need to move ng-template to the body of the ngFor.
template
<ng-container *ngFor=" let view of views">
<button type="button" class="btn btn-success"
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl">
Show me tooltip with html {{ view.title }}
</button>
<ng-template #tooltipTmpl>
<h4>
{{ view.dateRangeText }}
</h4>
<div>
<i>
{{ view.data }}
</i>
</div>
</ng-template>
<br>
<br>
</ng-container>
demo 🚀🚀
#rkp9 Thanks for the codes. It does solve the issue, but it added viewDateRangeText, viewData, and setTooltipData in the TS codes.
I went with the approach #MuhammedAlbarmavi suggested, since it is without extra variables and functions. The comment on Github didn't have the configuration that we need for popover to act like a tooltip. I have it in the following.
<ng-template #tooltipTmpl let-view="view">
<div class="tooltip-section">
<div class="section-title">
{{ view.dateRangeText }}
</div>
<div class="section-text">
{{ view.data }}
</div>
</div>
</ng-template>
<div
[popoverContext]="{ view: view }"
[popover]="tooltipTmpl"
triggers="mouseenter:mouseleave"
placement="top"
>
<div class="sub-title">
{{ view.title }}
</div>
</div>

v-bind in b-list-group-item not working in vue CLI-app with boootstrap-vue

i have an app made with vue-CLI including bootstrap-vue. In my App.vue i'am using axios to fetch some sample JSON-data. I generate a list with the b-list-group-item (bootstrap-tag) and want to bind a key in each element (v-bind:key="result.ItemId"). This is not working. In html no "key" is rendered.
This is the code snippet:
<b-list-group >
<b-list-group-item
href="#"
class="flex-column align-items-start"
v-for="result in post"
v-bind:key="result.ItemId"
>
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">{{ result.ItemHeading }}</h6>
<small>{{ result.ItemSubHeading }}</small>
</div>
<p class="mb-1">{{ result.ItemDetails }}</p>
</b-list-group-item>
</b-list-group>
This is the rendered html with no key-binding:
This is the JSON-result:
0: {ItemId: "10075328", ItemHeading: "news im November", ItemSubHeading: "unter news",…}
Date4Itemnew: "24.11.2019"
ItemDetails: "lorem ipsum"
ItemHeading: "news im November"
ItemId: "10075328"
ItemSubHeading: "unter news"
u_date: "1574550000"
I tried all possibilities to bind it. Please help.
First you have to loop inside the json file by value of key [ result.ItemHeading ] , After you have to bind this value inside props by same name of value props: ["ItemHeading", "ItemSubHeading", "ItemDetails"]
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<b-list-group>
<b-list-group-item
href="#"
class="flex-column align-items-start"
v-for="result in post"
v-bind:key="result.ItemId"
v-bind:ItemHeading="result.ItemHeading"
v-bind:ItemSubHeading="result.ItemSubHeading"
v-bind:ItemDetails="result.ItemDetails"
>
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">{{ result.ItemHeading }}</h6>
<small>{{ result.ItemSubHeading }}</small>
</div>
<p class="mb-1">{{ result.ItemDetails }}</p>
</b-list-group-item>
</b-list-group>
</template>
<script>
export default {
props: ["ItemHeading", "ItemSubHeading", "ItemDetails"]
};
</script>

Filter ul list by input text Vue.js 2

I want to filter one ul list when a user types rather the name or the initials on an input filed. I am working with vue.js 2. The list is being rendered calling a store variable, a JSON file.
STORE VARIABLE
$store.coin.coin
JSON example
{
"coin": [
{
"initials": "DLR",
"price": "0.727282",
"volume": "1212",
"change": "+1.22",
"name": "dollar"
}, ...
]
}
HTML
<li>
<div class="input-group search-box">
<input id="filter-coins" v-model="search" placeholder="Filter" class="input-group-field" type="text">
</div>
</li>
<li class="tabs-title" v-for="item in filteredItems" :key="item.initials" >
<a href="#coinList" aria-selected="true">
<div class="grid-x">
<div class="auto cell">{{ item.initials }}</div>
<div class="auto cell">{{ item.price }}</div>
<div class="auto cell">{{ item.volume }}</div>
<div class="auto cell">{{ item.change }}</div>
<div class="auto cell">{{ item.name }}</div>
</div>
</a>
</li>
METHOD
export default {
name: 'coins',
search: '',
computed: {
filteredItems() {
return this.$store.coin.coin.filter(item =>
(item.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1));
},
},
};
store.js
import Vue from 'vue';
import Vuex from 'vuex';
import coin from '../data/coins-btc.json';
Vue.use(Vuex);
export default {
state: {
coin,
},
getters: {
coin: state => state.coin,
},
};
Here is an example filter that works with either the initials or the name.
computed:{
filteredItems(){
let coins = this.$store.getters.coin.coin
// if there is no filter, return everything
if (!this.search) return coins
// setup the filter function
let searchValue = this.search.toLowerCase()
let filter = coin => coin.initials.toLowerCase().includes(searchValue) ||
coin.name.toLowerCase().includes(searchValue)
return coins.filter(filter)
}
}
And here is an example of it in action.
console.clear()
const store = new Vuex.Store({
state: {
coin: {
"coin": [
{
"initials": "DLR",
"price": "0.727282",
"volume": "1212",
"change": "+1.22",
"name": "dollar"
},
{
"initials": "EUR",
"price": "0.727282",
"volume": "1212",
"change": "+1.22",
"name": "euro"
},
{
"initials": "AUS",
"price": "0.727282",
"volume": "1212",
"change": "+1.22",
"name": "australian"
}
]
}
},
getters:{
coin: state => state.coin
}
})
new Vue({
el: "#app",
store,
data:{
search: null
},
computed:{
filteredItems(){
let coins = this.$store.getters.coin.coin
// if there is no filter, return everything
if (!this.search) return coins
// setup the filter function
let searchValue = this.search.toLowerCase()
let filter = coin => coin.initials.toLowerCase().includes(searchValue) ||
coin.name.toLowerCase().includes(searchValue)
return coins.filter(filter)
}
}
})
<script src="https://unpkg.com/vue#2.4.2"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.4.0/vuex.js"></script>
<div id="app">
<ul>
<li>
<div class="input-group search-box">
<input id="filter-coins" v-model="search" placeholder="Filter" class="input-group-field" type="text">
</div>
</li>
<li class="tabs-title" v-for="item in filteredItems" :key="item.initials" >
<a href="#coinList" aria-selected="true">
<div class="grid-x">
<div class="auto cell">{{ item.initials }}</div>
<div class="auto cell">{{ item.price }}</div>
<div class="auto cell">{{ item.volume }}</div>
<div class="auto cell">{{ item.change }}</div>
<div class="auto cell">{{ item.name }}</div>
</div>
</a>
</li>
</ul>
</div>

Mustache Conditions and Loops

Here are the resources:
JSON
{
"badges":{
"unlocked": [
{"name": "Win 1"},
{"name": "Win 2"},
{"name": "Win 3"}
],
"locked":[
{"name": "Lose 1"},
{"name": "Lose 2"},
{"name": "Lose 3"}
]
}
}
Algorithm
{{ if_has_badges }}
<div class="badges">
<h1>Badges</h1>
{{ if_has_badges_unlocked }}
<div class="badges-unlocked">
<h2>Unlocked!</h2>
{{ loop_badges_unlocked }}
<a href="#" class="badge">
<strong>{{ name }}</strong>
</a>
{{ end_loop_badges_unlocked }}
</div>
{{ end_if_has_badges_unlocked }}
{{ if_has_badges_locked }}
<div class="badges-locked">
<h2>Locked!</h2>
{{ loop_badges_locked }}
<a href="#" class="badge">
<strong>{{ name }}</strong>
</a>
{{ end_loop_badges_locked }}
</div>
{{ end_if_has_badges_locked }}
</div>
{{ end_if_has_badges }}
How I can write this algorithm to work with Mustache compiler?
I need to do this to work with two sides, first is the RubyOnRails application and the second is the client-side (JavaScript).
There are two solutions to your problem.
Using selections and inverted selections
Here is an example from the mustache documentation:
{
"repos": []
}
Template:
{{#repos}}<b>{{name}}</b>{{/repos}}
{{^repos}}No repos :({{/repos}}
Output:
No repos :(
As you see the inverted selections let me do conditional logic. In your case it would look something like:
Json:
var viewModel = {
badges:[]//badges here
}
viewModel.anyBadges = badges.length >0;
Mustache:
<div class="badges-unlocked">
{{#anyBadges}}
<h2>Unlocked!</h2>
{{/anyBadges}}
{{#badges_unlocked}}
<a href="#" class="badge">
<strong>{{ name }}</strong>
</a>
{{/badges_unlocked}}
Don't do logic in logic-less templating
This is what I would do. If you have conditional logic in your Mustache templates I think you're doing it wrong. You can either use Handlebars instead which is much more advanced in this regard or move your logic someplace else (to your javascript).
Please see the Mustache readme
The best answer (for both Ruby and JavaScript) is to encapsulate your logic (the if_has_badges type questions) into a View class.
You can actually fake it for the little bit of logic you need in both Ruby and JavaScript by using the array length property:
{{# badges.length }}
<div class="badges">
<h1>Badges</h1>
{{# badges.unlocked.length }}
<div class="badges-unlocked">
<h2>Unlocked!</h2>
{{# badges.unlocked }}
<a href="#" class="badge">
<strong>{{ name }}</strong>
</a>
{{/ badges.unlocked }}
</div>
{{/ badges.unlocked.length }}
{{# badges.locked.length }}
<div class="badges-locked">
<h2>Locked!</h2>
{{# badges.locked }}
<a href="#" class="badge">
<strong>{{ name }}</strong>
</a>
{{/ badges.locked }}
</div>
{{# badges.locked.length }}
</div>
{{/ badges.length }}
But that's a bit of a dirty way of doing it...

Categories

Resources