Join the Stack Overflow Community
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I've a menu with about, news and contact buttons in addition to three buttons that allow to change the language of the label on the menu's buttons and the content of the text elements (variable contentText below).

I'm using Vue.js with custom components, as well as Vuex.js to store language states. I'm being able to select the language of the labels on the menu buttons. For instance, if I click on the button labeled fr, the labels on the meny bar change from about to à propos, news to nouvelles, etc., but for some reason that I cannot identify, when I click any one of the menu buttons, the click event doesn't trigger the visibility of the respective text elements. The code that deals with states is something along the following lines (Jsfiddle here):

Vue.use(Vuex)
var storelang = new Vuex.Store({
  state: {
    lang: {}
  },
  actions: {
    lang: 'code'
  },
  mutations: {
    code(state, ln) {
       var jsontext = '{"aboutMenu":"About", "aboutText":"This is just a small text in English.", "newsMenu":"News", "newsText":"News written in the English language.", "contactMenu":"Contact", "contactText":"Contact info written in English."}'
      if (ln === 'pt') {
        jsontext = '{"aboutMenu":"Sobre", "aboutText":"Isto é um pequeno texto em Português.", "newsMenu":"Novidades", "newsText":"Novidades escritas em Português.", "contactMenu":"Contactar", "contactText":"Informação de contacto escrita em Português."}'
      }
      if (ln === 'fr') {
        jsontext = '{"aboutMenu":"À propos", "aboutText":"Ceci est juste um petit texte en Français.", "newsMenu":"Nouvelles", "newsText":"Des nouvelles écrites en Français.", "contactMenu":"Contacter", "contactText":"Des informations dans la langue Française."}'
      }
      state.lang = JSON.parse(jsontext)
    }
  },
  strict: true
})

The components with their respective templates, created with Vue.extend:

var contentBtn = Vue.extend({
  template: '<button type="button" class="btn btn-default" @click="toggleAbout">{{lang.aboutMenu}}</button><button type="button" class="btn btn-default" @click="toggleNews">{{lang.newsMenu}}</button><button type="button" class="btn btn-default" @click="toggleContact">{{lang.contactMenu}}</button>'
})

var contentTxt = Vue.extend({
  template: '<div v-show="aboutIsVisible">{{lang.aboutText}}</div><div v-show="newsIsVisible">{{lang.newsText}}</div><div v-show="contactIsVisible">{{lang.contactText}}</div>'
})

var langBtn = Vue.extend({
  template: '<button type="button" class="btn btn-info" @click.prevent=activate("en")>en</button><button type="button" class="btn btn-info" @click.prevent=activate("pt")>pt</button><button  type="button" class="btn btn-info" @click.prevent=activate("fr")>fr</button>',
  methods: {
    activate: function(x) {
      storelang.actions.lang(x)
    }
  },
  ready: function() {
    return storelang.actions.lang('en') //default language
  }
})

And my Vue instance, where I store the values concerning the visiblity of the text elements, register the components and declare the methods for the click events:

new Vue({
  el: '#app',
  data: {
    aboutIsVisible: true,
    newsIsVisible: true,
    contactIsVisible: true
  },
  components: {
    'langbtn': langBtn,
    'contentbtn': contentBtn,
    'contenttxt': contentTxt
  },
  methods: {
    toggleAbout: function () {
      this.aboutIsVisible = !this.aboutIsVisible
    },
    toggleNews: function () {
      this.newsIsVisible = !this.newsIsVisible
    },
    toggleContact: function () {
      this.contactIsVisible = !this.contactIsVisible
    }
  }
})

What am I missing?

share|improve this question
up vote 1 down vote accepted

You're trying to call toggleNews on a child component that doesn't have a method called toggleNews. That method is on the parent component. You'll need to move the button into the parent element, or utilize events to broadcast clicks from the child elements up to the parent.

I moved the child templates up into the parent and your code is working as expected: https://jsfiddle.net/674z6w0h/13/

share|improve this answer
    
Of course that's it! Thank you so much (once again) :-) – pierrebonbon Mar 1 at 3:17
1  
no problem! Here is what it will look like if you want only one tab visible at a time: jsfiddle.net/674z6w0h/14 – Jeff Mar 1 at 3:19
    
that's absolutely awesome! I was gonna try to fix that just now, not as half as quick though eheheh – pierrebonbon Mar 1 at 3:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.