I use nuxt-i18n nuxt-i18n documentation link to get different locales on my website like that :
<nuxt-link v-for="locale in $i18n.locales"
v-if="locale.code !== $i18n.locale"
:key="locale.code"
:to="switchLocalePath(locale.code)"
class="locales white--text"
>{{ locale.code }}
</nuxt-link>
And it works perfectly fine but i want to transform this code to render in a select element:
<select v-model="selected" class="locales white--text" #change=" ??? ">
<option disabled value="">{{ $i18n.locale }}</option>
<option v-for="locale in $i18n.locales" :key="locale.code">{{ locale.code }}</option>
</select>
Locales strings appears well but i don't dind a solution to launch the switchLocalePath function on change. Is there a proper way to do that with nuxt (vue.js) ?
Here you are, the dropdown list and the onChange method:
<select v-model="selectedValue" #change="onChange(selectedValue)">
<option disabled value>Please select one</option>
<option
v-for="(locale, index) in $i18n.locales"
:key="index"
:value="locale.code"
>{{locale.name}}</option>
</select>
methods: {
onChange(event) {
this.$router.replace(this.switchLocalePath(event));
}
}
If you want to check working I have build a CodeSandox Nuxt working here:
https://codesandbox.io/embed/codesandbox-nuxt-1bhug?fontsize=14&hidenavigation=1&theme=dark
Also there is no need to use the router to change the locale, the API can be used too using this.$i18n.setLocale(locale)
<select v-model="activeLang" #change="changeLang" name="lang" id="">
<option
:selected="locale === activeLang"
v-for="locale in locales"
:key="locale"
:value="locale"
>
{{ locale }}
</option>
</select>
changeLang(event) {
this.$i18n.setLocale(event.target.value);
}
CodeSandbox here
In the first step, do the following first
// nuxt.config.js, inside nuxt-i18n module
locales: [
{ code: 'ar', iso: 'ar', file: 'ar/app.js', dir: 'rtl' },
{ code: 'en', iso: 'en-US', file: 'en/app.js', dir: 'ltr' },
{ code: 'fr', iso: 'fr-FR', file: 'fr/app.js', dir: 'ltr' },
],
Then create a plugin in the code and enter the following code
// plugins/ltr-rtl.js
export default function({ app }, inject) {
const dir = () => app.i18n.locales.find((x) => x.code === app.i18n.locale)?.dir;
inject( 'dir', dir);
}
And in the last step
<!-- layouts/default.vue -->
<div id="app" :dir="$dir()">
My app here...
</div>
Related
I have to use i18n variables for a select dropdown in the form.
I can access i18n data in main.js like this :
// Load locales
axios
.get("http://localhost:3000/data")
.then(({data}) => {
console.log(data);
appOptions.i18n.setLocaleMessage("fr", basil.get(data, "fr", {}));
appOptions.i18n.setLocaleMessage("en", basil.get(data, "en", {}));
appOptions.i18n.setLocaleMessage("nl", basil.get(data, "nl", {}));
})
.catch((error) => {
console.error(error);
});
In my form component I can use these date for example for simple field like this :
<div class="success" v-if="success">
{{ $t("contact.success_message") }}
</div>
I would like to use v-for for select options with "$t" variable . Something like this don't work :
<option
v-for="item in $t("register")"
:key="item"
:value="item"
>
{{ item }}
Can you please tell me how can I achieve this if I have to follow the structure of the json file with i18n variable :
{
es: {
contact: {
contact_demo: "Contáctenos para una demostración",
contact_sales: "Comuníquese con ventas",
...
},
register: {
option_Germany: "Alemania",
option_Morocco: "Marruecos",
option_Belgium: "Bélgica",
option_Cook Islands: "Islas Cook",
...
found the solution :
<select id="countries">
<option
v-for="value in $t('register',)"
:key="value"
>
{{ value }}
</option>
</select>
I am creating a custom select component in VueJS 2. The component is to be used as below by the end-user.
<custom-select>
<option value="value 1">Option 1</option>
<option value="value 2">Option 2</option>
<option value="value 3">Option 3</option>
...
<custom-select>
I know the Vue <slot> tag and usage. But how do I get the user provided <option> tags as an array/list so I can get its value and text separately for custom rendering inside the component?
Those <option>s would be found in the default slot array (this.$slots.default), and you could get to the inner text and value of the <option>s like this:
export default {
mounted() {
const options = this.$slots.default.filter(node => node.tag === 'option')
for (const opt of options) {
const innerText = opt.children.map(c => c.text).join()
const value = opt.data.attrs.value
console.log({ innerText, value })
}
}
}
demo
You can achieve it, using v-bind and computed property
new Vue({
el: '#vue',
data: {
selected: '',
values: [
{
code: '1',
name: 'one'
},
{
code: '2',
name: 'two'
}
]
},
computed: {
selectedValue() {
var self = this;
var name = "";
this.values.filter(function(value) {
if(value.code == self.selected) {
name = value.name
return;
}
})
return name;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vue">
<div>
<select v-model="selected">
<option v-for="value in values" v-bind:value="value.code">
{{ value.name }}
</option>
</select>
</div>
<strong>{{ selected }} {{ selectedValue }}</strong>
</div>
I am using vuelidate (https://vuelidate.js.org/) on select option to require and it works when the v-model has a single name $v.selectedWorkflow.$model
<div class="form-group" :class="{ 'form-group--error': $v.selectedWorkflow.$error }">
<select v-model.trim="$v.selectedWorkflow.$model">
<option :value="undefined" selected disabled>Select a Workflow</option>
<option v-for="workflow in workflows"
:key="workflow.id" :value="workflow">
{{workflow.name}}
</option>
</select>
</div>
However, when doing v-model with array, I got an error that $error is undefined or sometimes $model is undefined when using $v.usersForRole[role.name].$model I am not sure if I'm doing the right syntax
<div class="form-group" :class="{ 'form-group--error': $v.usersForRole[role.name].$error }">
<select v-model.trim="$v.usersForRole[role.name].$model">
<option :value="undefined" selected disabled>Select a User</option>
<option v-for="user in role.users" :key="user.id" :value="user.id">
{{user.display_name}}
</option>
</select>
</div>
<div class="error" v-if="!$v.usersForRole[role.name].required"></div>
here's my validations
validations: {
title: {
required,
minLength: minLength(4)
},
slug: {
required
},
selectedWorkflow: {
required
},
usersForRole: {
required
}
},
Use $each for this requirement.
Ref link: https://vuelidate.js.org/#sub-collections-validation
validations: {
title: {
required,
minLength: minLength(4)
},
slug: {
required
},
selectedWorkflow: {
required
},
usersForRole: {
$each: {
required
}
}
},
I'm creating this post because I'm trying to add and remove option in an HTML select from a function.
I've searched everywhere but unfortunately I didn't find anything.
thank you in advance for your help!
methods: {
addElement() {
// function add option in actions select
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div class="col-md-10 col-md-offset-1">
<select name="actions" v-model="model.actions" class="form-control">
</select>
</div>
</template>
Example from the vue docs https://v2.vuejs.org/v2/guide/forms.html#Select (find using v-for with select at that page):
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
If you want to add option to select just create some method addOption(option):
methods:{
addOption(option){
this.options.push(option);
}
}
I am currently developing frontend with Argon for vue.js.
Free Argon template doesn't support type select for base-input so I decided to make it myself.
Here is my code:
<template>
// ...
<base-input alternative
type="select"
:options="genders"
addon-left-icon="ni ni-circle-08">
</base-input>
// ...
</template>
<script>
export default {
name: 'app-footer',
data() {
return {
genders: [
{ value: 0, text: 'Select Gender' },
{ value: 1, text: 'Male' },
{ value: 2, text: 'Female' }
]
}
}
}
</script>
BaseInput.vue:
<template>
// ...
<slot v-bind="slotData">
<select v-if="$attrs.type==='select'"
:value="value"
v-on="listeners"
v-bind="$attrs"
class="form-control"
:class="[{'is-valid': valid === true}, {'is-invalid': valid === false}, inputClasses]"
aria-describedby="addon-right addon-left">
<option v-for="(option, index) in $attrs.options"
:key="index"
v-bind:value="option.value">
{{$t(option.text)}}
</option>
</select>
<input
v-else
:value="value"
v-on="listeners"
v-bind="$attrs"
class="form-control"
:class="[{'is-valid': valid === true}, {'is-invalid': valid === false}, inputClasses]"
aria-describedby="addon-right addon-left">
</slot>
// ...
</template>
However, it only renders following html:
<select aria-describedby="addon-right addon-left" type="select" class="form-control"></select>
What is the problem here?
I found a solution. I used options for props. In vue.js options is a reserved keyword. I replaced it with optionlist and it works perfectly.