Space disabled on concatenation - vue.js

I have an array which looks like this
skills: [
"HTML5",
"CSS3",
"SCSS",
"Bootstrap",
"JavaScript",
"Vue.js",
"PHP",
"MySQL",
"Symfony"
]
And in my template I'm doing something like
<ul>
<li v-for="(skill,index) of skills" :key="index">{{ skill + ', '}}</li>
</ul>
But what I get is
HTML5,CSS3,SCSS,Bootstrap,JavaScript,Vue.js,PHP,MySQL,Symfony,
How do I able the spaces?
Btw is there a better way to concatenate the elements of my array? I first used join() like that
<ul>
<li v-for="(skill,index) of skills.join(', ')" :key="index">{{ skill }}</li>
</ul>
But not only the spaces are still disabled but it returns every character of my elements, I don't know why
Like
<ul data-v-c226fde6="">
<li data-v-c226fde6="">H</li>
<li data-v-c226fde6="">T</li>
<li data-v-c226fde6="">M</li>
<li data-v-c226fde6="">L</li>
<li data-v-c226fde6="">5</li>
<li data-v-c226fde6="">,</li>
<li data-v-c226fde6=""> </li>
<li data-v-c226fde6="">C</li>
<li data-v-c226fde6="">S</li>
<li data-v-c226fde6="">S</li>
<li data-v-c226fde6="">3</li>
...
EDIT: otherwise what I could just do is
<ul>
<li v-for="(skill,index) of skills" :key="index">{{ skill + ','}}</li>
</ul>
And then adding some padding-right to the li but I don't know if it's good practice + I don't know how I would remove the comma after the last element

Inside html template such as li you have to specify space characters using ;
<ul>
<li v-for="(skill,index) of skills" :key="index">{{ skill + ','}} </li>
</ul>
also checkout https://www.w3schools.com/html/html_entities.asp
to learn more about HTML entities

With that code you will get a list of <li></li> elements with each skill looking like this:
<li>HTML5,</li><li>CSS3,</li><li>...
just add a class or even a style with a margin to the right to add a little space between the elements either:
<ul>
<li v-for="(skill,index) of skills" style="margin-right: 5px" :key="index">{{ skill }}</li>
</ul>
better:
<ul>
<li v-for="(skill,index) of skills" class="class-with-some-margin-right" :key="index">{{ skill }}</li>
</ul>

You can add the ', ' after each item using CSS like so:
var example1 = new Vue({
el: '#example-1',
data: {
skills: ["HTML5", "CSS3", "SCSS", "Bootstrap", "JavaScript",
"Vue.js", "PHP", "MySQL", "Symfony", ]
}
})
/* styling help:
Q: https://stackoverflow.com/questions/1517220/
A: https://stackoverflow.com/a/1517228/7505395 */
#example-1 {
display: inline;
list-style: none;
}
#example-1 li {
display: inline;
}
#example-1 li:after {
content: ", ";
}
#example-1 li:last-child:after {
content: "";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<ul id="example-1">
<li v-for="(sk, idx) in skills" :key="idx">{{ sk }}</li>
</ul>
This answer incorporates it into Vue, for the pure css answer, go here.
As always you can also combine normal text inside Vues {{}} like so : {{ skill + ', ' }} - not sure if thats helpfull though as it applies to all replacement and you end up having a trailing ,

Related

Display nested loop in Vue from a GraphQL query

I'm using OneGraph to pull data from Spotify. I can't figure how to render out the 3rd nested loop though even looking at other Vue code samples. I'm trying to return the artist name for each playlist as shown below.
<template>
<ul>
<li v-for="(item, index) in $page.oneGraph.spotify.me.playlists" :key="index">
<ol>
<li v-for="track in item.tracks" :key="track.playlists">
{{track.name}} -
<span v-for="artist in item.tracks.artists" :key="artist.tracks">
{{artist.name}}
</span>
</li>
</ol>
</li>
</ul>
</template>
The query:
{
spotify {
me {
id
playlists(limit: 1) {
name
tracks {
name
artists {
name
}
}
}
}
}
}
Nested loop:
<li v-for="track in item.tracks" :key="track.playlists">{{track.name}}</li>
Child nested loop:
<span v-for="artist in track.artists" :key="artist.tracks" {{artist.name}}</span>

Getting nested <li> tags also.....just need the direct <li> item

I have a page structure where it includes hyperlinks with different levels of nested list items. I am writing the xpath for just the second nested list items(level 2) but it is also giving me all the list items below level 2(level 3 or below), which i don't need. It's getting really frustrating now because I have tried different xpaths and cssSelectors, everytime it is taking the level 3 list items along with level 2.
The page structure is exactly like following:
<div>
<ul class="menuBar_menu_lvl_0">
<li class="item_lvl_1">
<li class="item_lvl_1">
<ul class="menu_lvl_1">
<li class="item_lvl_2"></li>
<li class="item_lvl_2"></li>
<li class="item_lvl_2">
<ul class="menu_lvl_2">
<li class="item_lvl_3"></li>
<li class="item_lvl_3"></li>
<li class="item_lvl_3"></li>
</ul>
</li>
</ul>
<li class="item_lvl_1">
<li class="item_lvl_1">
xpath = //ul[#class="menuBar_menu_lvl_0"]//li[#class="item_lvl_1"]//ul[#class="menu_lvl_1"]//li[#class="item_lvl_2"]
This is also giving me item number 3 elements along with item level 2. I want to get each level item correctly and separately. Anybody's help would be highly appreciated
Welcome to SO.
Here is the sample that used.
<html>
<body>
<div>
<ul class="menuBar_menu_lvl_0">
<li class="item_lvl_1">
<li class="item_lvl_1">
<ul class="menu_lvl_1">
<li class="item_lvl_2">Level1-li1</li>
<li class="item_lvl_2">Level1-li2</li>
<li class="item_lvl_2">
<ul class="menu_lvl_2">
<li class="item_lvl_3">Level2-li1</li>
<li class="item_lvl_3">Level2-li2</li>
<li class="item_lvl_3">Level2-li1</li>
</ul>
Level1-li3
</li>
</ul>
<li class="item_lvl_1">
<li class="item_lvl_1">
</ul>
</div>
</body>
</html>
And below is the xpath
//ul[#class='menu_lvl_1']//li[not(parent::ul[#class='menu_lvl_2'])]
Here is the output:
Here is the method to get the text from parent element only.
def get_text_exclude_children(element):
return driver.execute_script(
"""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element).strip()

For loop of objects

I'm trying to do a for loop of a set of objects but since they all aren't named the same, I'm stuck.
<div id="components-demo">
<div>Travel Information</div>
<ul>
<li
v-for="(todo, index) in todos"
v-bind:id="index"
v-bind:title="todo"
>{{todo}}</li>
</ul>
</div>
var newData = #Html.Raw(Json.Encode(Model));
// Object returns like { Passenger: "Tom Jones", Airline: "United Airways", Destination: "Atlanta, GA", etc. }
var vm = new Vue({
el: '#components-demo',
data: {
todos: [
{ newData }
]
}
})
In the developer tools in Vue, it lists out the object fine like:
todos: Array [1]
0: Object
Passenger: "Tom Jones"
Airline: "United Airways"
Destination: "Atlanta, GA"
etc.
At the end I'm looking to list out li's containing these items but can't seem to loop through unless I specify exactly each one.
According to the object you say is constructed.
<div id="components-demo">
<div>Travel Information</div>
<ul>
<li v-for="(item, index) in todos" :key="index">{{ item.Passenger }}</li>
</ul>
</div>
To list out dynamic objects using nested loop:
<div id="components-demo">
<div>Travel Information</div>
<ul>
<li v-for="(item, index) in todos" :key="index">
<ul>
<li v-for="(value, key) in item" :key="key">{{ key }} : {{ value }}</li>
</ul>
</li>
</ul>
</div>
You are assigning the object to an array, you can just loop through the object directly https://jsfiddle.net/cckLd9te/4656/
data: {
todos: newData
},

How can I switch the `selected` style easily in Vue?

How can I switch the selected style easily?
In the template I have a nav:
<ul class="nav">
<li class="nav-item selected" #click="clickLi(0)"><router-link to="/">首页</router-link></li>
<li class="nav-item" #click="clickLi(1)"><router-link to="/data-center">数据中心</router-link></li>
</ul>
in the methods:
clickLi(page_num){
// there I have to clear all the li `selected` style, then add the style to the page_num.
}
in Vue whether there is a better way to realize this effect?
Take a look at Cass and Style Binding Docs
pseudo example below, also added some shorcuts to vue-router to avoid the router-link component, you just can bind the :to to the <li>
<li
v-for="(item, $index) in routes"
#click="selectedIndex = $index"
:class="{'item-selected': $index == selectedIndex}"
:to="item.path">{{ item.name }}</li>
// on component
data() {
return {
selectedIndex: null,
routes: [{path:'/', name: 'home'},{path:'/data-center', name:'data center'}]
}
}
in the data you return a selected_num param:
data() {
return {
selected_num: 0
}
}
in your template:
<ul class="nav">
<li class="nav-item" :class="selected_num===0 ? 'selected' : ''" #click="selected_num=0"><router-link to="/">首页</router-link></li>
<li class="nav-item" :class="selected_num===1 ? 'selected' : ''" #click="selected_num=1"><router-link to="/data-center">数据中心</router-link></li>
</ul>
you even do not need the method.

index of matching items in parent element even if they're in other child containers

I need to get the index of the li.play relevant to the ul.showreel_thumbnails. Is this even possible? All i seem to get is the li index inside ul.row
<ul class="showreel_thumbnails">
<li>
<ul class="row">
<li class="play_video">item</li>
<li class="play_video">item</li>
<li class="play_video">item</li>
</ul>
</li>
<li>
<ul class="row">
<li class="play_video">item 4</li>
<li class="play_video">item</li>
</ul>
</li>
</ul>
so if item 4 is clicked it should give me the index of 4 etc...
best, Dan.
It may not be valid HTML but here's how it would work (with JQuery):
function FindMyCount()
{
var item_count = 0;
$("#showreel_thumbnails li").each(function() {
++item_count;
if($(this).hasClass("igotclicked"))
return false;
});
return item_count;
}
$("#showreel_thumbnails li").click(function() {
$(this).addClass("igotclicked");
var myCount = FindMyCount(); // 1 - the # of li's under the showreel piece
$(this).removeClass("igotclicked");
// Do what you want here.
});