Data Property to Hold Index of Array Object during Mouse Over Vuejs - html

I've used list rendering to create a menu with items from an array. I'm now trying to create a new data property which holds the index of the array item when the item of the menu is mouse-overed but I'm not sure of how to do it. Here's what I've tried:
HTML:
<header>
<nav class="pure-menu pure-menu-horizontal">
<ul id="topmenu" class="pure-menu-list">
<li v-for="item in topmenu" class="pure-menu-item">
<a v-bind:href="item.url" v-on:mouseover="mouseOver" class="pure-menu-link">{{ item.title }}</a></li>
<li v-for="item in topmenu.submenus" class="pure-menu-item">
<a v-bind:href="item.url" class="pure-menu-link">{{ item.title }}</a></li>
</ul>
<div class="pure-menu">
<ul id="submenu" class="pure-menu-list">
</ul>
</div>
</nav>
</header>
JS:
var vueinst = new Vue({
el: '#vuemain',
data: {
topmenuitem : 0,
topmenuhover : false,
topmenu: [
{ title:'Home', url:'/', submenus: [] },
{ title:'About', url:'/about',
submenus: [
{ title:'Who we are', url:'/about#us' },
{ title:'What we do', url:'/about#store' },
{ title:'Our range', url:'/about#range' }
]
},
{ title:'Contact Us', url:'/contact',
submenus: [
{ title:'Information', url:'/contact#info' },
{ title:'Returns', url:'/contact#return' },
{ title:'Locate Us', url:'/contact#locate' }
]
}
]
},
methods: {
mouseOver: function(){
this.topmenuitem = this.topmenu.index;
}
}
});
I'm pretty new to web developing, please help me with this. Thank you!

In your html pass the index of the current item to the mouseOver function like the following:
<header>
<nav class="pure-menu pure-menu-horizontal">
<ul id="topmenu" class="pure-menu-list">
<li v-for="item in topmenu" :key="item.index" class="pure-menu-item">
<a v-bind:href="item.url" v-on:mouseover="mouseOver(item.index)" class="pure-menu-link">{{ item.title }}</a></li>
<li v-for="item in topmenu.submenus" class="pure-menu-item">
<a v-bind:href="item.url" class="pure-menu-link">{{ item.title }}</a></li>
</ul>
<div class="pure-menu">
<ul id="submenu" class="pure-menu-list">
</ul>
</div>
</nav>
</header>
And you should bind key in the v-for like :key="item.index". And then in your mouseOver function accept the index of the item as a parameter and push the element on that index into your new array ass follows.
mouseOver: function(index){
this.topmenuitem.push(index);
}
This way you could get the index of all items hovered on.

Related

How can I solve this using Knockout JS?

I have the following code, I am trying to get an id in the SPAN and it is not accepting values in any type of tag that is located inside ....
<div class="col-lg-12 col-md-12" id="contenedorListaTarea">
<ul class="nav nav-tabs align-items-lg-start mb-1" data-bind="foreach: loterias">
<li class="nav-item" name="loteria" data-bind="click:namerjarClickLoteria">
<a class="nav-link fontSizeTab" data-bind="text: nombre,style: { backgroundColor: color},attr:{id:id+nombreCorto}">
<span data-bind="attr:{id:nombreCorto}" >0.00</span>
</a>
</li>
</ul>
</div>
If I understand you correctly your problem is that any tag placed in <a> tag is to being rendered. The reason for that to happen is that your <a> tag is using text: nombre binding which is replacing anything you have put inside it.
I removed that binding and <span> started to appear in it with working attr binding.
var viewModel = function() {
this.loterias = ko.observableArray([
{
nombre: 'test',
color: 'red',
id: 'test-id',
nombreCorto: 1,
namerjarClickLoteria: function(){
}
},
{
nombre: 'test',
color: 'green',
id: 'test-id',
nombreCorto: 2,
namerjarClickLoteria: function(){
}
}
]);
return this;
}
ko.applyBindings(viewModel(), $('#contenedorListaTarea')[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="col-lg-12 col-md-12" id="contenedorListaTarea">
<ul class="nav nav-tabs align-items-lg-start mb-1" data-bind="foreach: loterias">
<li class="nav-item" name="loteria" data-bind="click:namerjarClickLoteria">
<a class="nav-link fontSizeTab" data-bind="style: { backgroundColor: color},attr:{id:id+nombreCorto}">
<span data-bind="attr:{id:nombreCorto}" >0.00</span>
</a>
</li>
</ul>
</div>

VUE: How to multiple component partials in one file?

home.vue
<template>
<app-navbar>
<logo title="navbar"></logo>
<div class="navbar-collapse">
<link href="#first" title="first link"></link>
<link href="#second" title="second link"></link>
<link href="#third" title="third link"></link>
</div>
</app-navbar>
</template>
<script>
export default {
name: "Home",
components: {
AppNavbar: () => import('#/components/navbar.vue')
}
}
</script>
navbar.vue
<script>
export default {
name: "AppNavbar",
props: {
title: {
type: String,
default: "navbarDemo"
},
href: {
type: String,
default: "#"
}
},
template: `
<div class="navbar-container">
<component :is="logo">
<div class="navbar-brand">{{ title }}</div>
</component>
<ul>
<component :is="link">
<li class="item">
<a :href="href" class="link">{{ title }}</a>
</li>
</component
</ul>
</div>
</div>
`
};
</script>
I WANT THIS
<div class="navbar-container">
<div class="navbar-brand">navbar</div>
<div class="navbar-collapse">
<ul>
<li class="item">
first link
</li>
<li class="item">
second link
</li>
<li class="item">
third link
</li>
</ul>
</div>
</div>
What am I doing wrong? Is component used differently? I want to use a component and have another component in it in one file (I don't want to have 20 files here just for navbar). Then compose the structure in this way. Possible?
I'm trying a similar HTML structure as here: link
Here is what you need:
home.vue
<app-navbar :links="links">
<template #logo>
<img src=""/>
</template>
</app-navbar>
data() {
return {
links: [
{ href: '#first", title: 'first link' },
{ href: '#second", title: 'secondlink' },
{ href: '#third", title: 'thirdlink' },
]
}
}
navbar.vue
<template>
<div class="navbar-container">
<div class="navbar-brand">
<slot name="logo" />
</div>
<div class="navbar-collapse">
<ul>
<li v-for="link in links" :key="link.href">
<a :href="link.href">{{ link.title }}</a>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: {
links: Array
}
}
</script>
The logo element is passed through a slot (https://fr.vuejs.org/v2/guide/components-slots.html).
You understood <component> wrongly :p <component> do not declare a component, it's only a way to use a component when its name might change.
Instead of writing
<comp1 v-if="test" /> <comp2 v-else /> you could write <component :is="test ? 'comp1" : 'comp2' />. But comp1 and comp2 components still need to be declared somewhere and imported.
Did you check https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components ?
EDIT: If you want to customize links with scoped-slots:
home.vue
<app-navbar :links="links">
<template #logo>
<img src=""/>
</template>
<template #link="{ href, title }">
<a :href="href">{{ title }}</a>
</template>
</app-navbar>
data() {
return {
links: [
{ href: '#first", title: 'first link' },
{ href: '#second", title: 'secondlink' },
{ href: '#third", title: 'thirdlink' },
]
}
}
navbar.vue
<template>
<div class="navbar-container">
<div class="navbar-brand">
<slot name="logo" />
</div>
<div class="navbar-collapse">
<ul>
<li v-for="link in links" :key="link.href">
<slot name="link" :href="link.href" :title="link.title" />
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: {
links: Array
}
}
</script>
So the looped links are passed through the slot so the parent is handling the rendering

Show Submenu On Mouse Enter Vuejs

Sorry I'm really new to all this.
I'm trying display a submenu during a menu item mouse-over. I've been given hints on recording the index of menu items, and recording the boolean value of whether the user currently has their mouse over the top menu's nav container. However I do not know how to proceed on using these to create conditional renderings for the submenu. Here's what I've tried:
HTML:
<div id="vuemain">
<nav v-on:mouseover="mouseOverNav" v-on:mouseleave="mouseLeaveNav" class="pure-menu pure-menu-horizontal">
<ul id="topmenu" class="pure-menu-list">
<li v-for="(item, index) in topmenu" v-on:mouseover="mouseOver(index)" class="pure-menu-item">
<a v-bind:href="item.url" class="pure-menu-link">{{ item.title }}</a>
</li>
</ul>
<div class="pure-menu">
<ul id="submenu" class="pure-menu-list">
<li v-if= "topmenuhover == true" class="pure-menu-item">
<a v-bind:href="topmenu[topmenuitem].submenus.url" class="pure-menu-link">{{ topmenu[topmenuitem].submenus.title }}</a></li>
</ul>
</div>
</nav>
</div>
JS:
var vueinst = new Vue({
el: '#vuemain',
data: {
topmenuitem : -1,
topmenuhover : false,
topmenu: [
{ title:'Home', url:'/', submenus: [] },
{ title:'About', url:'/about',
submenus: [
{ title:'Who we are', url:'/about#us' },
{ title:'What we do', url:'/about#store' },
{ title:'Our range', url:'/about#range' }
]
},
{ title:'Contact Us', url:'/contact',
submenus: [
{ title:'Information', url:'/contact#info' },
{ title:'Returns', url:'/contact#return' },
{ title:'Locate Us', url:'/contact#locate' }
]
}
]
},
methods: {
mouseOver: function(index){
this.topmenuitem=index;
},
mouseOverNav: function(){
this.topmenuhover = true;
},
mouseLeaveNav: function(){
this.topmenuhover = false;
}
}
});
Can anyone help me with this? Thank you!
The Javascript part should do the trick, you just need to tweak the template a bit to actually render the submenu. Here's how you could do it:
var vueinst = new Vue({
el: "#vuemain",
data: {
topmenuitem: -1,
topmenuhover: false,
topmenu: [
{ title: "Home", url: "/", submenus: [] },
{
title: "About",
url: "/about",
submenus: [
{ title: "Who we are", url: "/about#us" },
{ title: "What we do", url: "/about#store" },
{ title: "Our range", url: "/about#range" },
],
},
{
title: "Contact Us",
url: "/contact",
submenus: [
{ title: "Information", url: "/contact#info" },
{ title: "Returns", url: "/contact#return" },
{ title: "Locate Us", url: "/contact#locate" },
],
},
],
},
methods: {
mouseOver: function (index) {
this.topmenuitem = index;
},
mouseOverNav: function () {
this.topmenuhover = true;
},
mouseLeaveNav: function () {
this.topmenuhover = false;
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vuemain">
<nav v-on:mouseover="mouseOverNav" v-on:mouseleave="mouseLeaveNav" class="pure-menu pure-menu-horizontal">
<ul id="topmenu" class="pure-menu-list">
<li v-for="(item, index) in topmenu" v-on:mouseover="mouseOver(index)" class="pure-menu-item">
<a v-bind:href="item.url" class="pure-menu-link">{{ item.title }}</a>
</li>
</ul>
<div class="pure-menu">
<ul v-if="topmenuhover" id="submenu" class="pure-menu-list">
<li v-for="subitem in topmenu[topmenuitem].submenus" class="pure-menu-item">
<a v-bind:href="subitem.url" class="pure-menu-link">{{ subitem.title }}</a></li>
</ul>
</div>
</nav>
</div>

href scroll anchor angularjs

Im having a problem using href/anchor scrolling with angularjs. Once I click the h ref link it always links to the index page sample like this http://xxxxxx/#!/index#sec-menu not sure what I'm doing wrong.
Thanks for the assistance.
HTML
<div class="nav-holder main-menu">
<nav>
<ul>
<li>
Menu
</li>
</ul>
</nav>
</div>
<span class="fw-separator" id="sec-menu"></span>
not sure if this is the cause but I have something like this in my app.js
.otherwise({
redirectTo: '/index'
});
<div class="nav-holder main-menu">
<nav>
<ul>
<li>
<a ng-href="#/?scroll=sec-menu">My element</a>
</li>
</ul>
</nav>
</div>
<span class="fw-separator" id="sec-menu"></span>
change the run code in the module declaration in app.js like so:
app.run(function($location, $rootScope) {
$rootScope.$watch(function() { return $location.search() }, function(search) {
var po= 0;
if (search.hasOwnProperty('scroll')) {
var $target = $('#' + search.scroll);
po= $target.offset().top;
}
$("body,html").animate({scrollTop: po}, "slow");
});
})

value part of key value pair not accesible in ng-repeat

I have the below HTML code with AngularJS
<div class="col-xs-1" style="width:130pt;background-color:#474747;border:2px ridge;">
<div class="container-fluid">
<ul class="nav">
<li class="dropdown" style="width:140px;" ng-repeat = "page in homeCategoryList">
<a class= "dropdown-toggle dropdown-menu-hover-color menu-left-color" data-toggle="dropdown" href="#" ng-repeat ="(key, value) in page">{{key}}</a>
<ul class="dropdown-menu" style="position:absolute;float:right;top: 0; left: 140px;">
<li ng-repeat = "subcat in value">
<a class="dropdown-level1-color " href= "#" ng-repeat="(key,value) in subcat">{{key}}</a>
<ul type="none">
<li ng-repeat="childcat in value">{{childcat}}}</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
I want to represent the below JSON in the above html using angularjs. The problem is that I am able to access "electronics" but not its value which is an array."li ng-repeat="subcat in {{value}}" gives error Error: [$parse:syntax] Syntax Error: Token 'value' is unexpected, expecting [:] at column 3 of the expression [{{value}}] starting at [value}}].
[
{
"electronics": [
{
"cameras": [
"sony",
"panasonic",
"nikon",
"canon"
]
},
{
"TV": "none"
},
{
"laptop": [
"toshiba",
"hp",
"apple",
"samsung",
"sony",
"acer",
"lenovo"
]
}
]
},
{
"home": [
{
"furniture": [
"cupboard",
"table",
"chair"
]
},
{
"couch": "none"
},
{
"utensils": "none"
}
]
}
]
Could anyone kindly tell me how to access the value variable in the ng-repeat.
You will have to re-do your HTML/classes but take a look here: http://jsfiddle.net/Fs8eH/
You might want to consider using a tree directive if the layers get any deeper.
<ul ng-app ng-controller="MyCtrl">
<li style="width:140px;" ng-repeat="page in homeCategoryList">
<div ng-repeat="(key, value) in page"> <span>{{key}}</span>
<ul>
<li ng-repeat="item in value">
<div ng-repeat="(key, value) in item"> <span>{{key}}</span>
<ul>
<li ng-repeat="brand in value"> <span>{{brand}}
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>