How to use $t from vue-i18n inside Vuex store to initialize static strings - vue.js

In my vuex store module I have provinceData to supply as datasource for Vuetify dropdown selection box.
provinceData: [
{value:"AB", text: "Alberta"},
{value:"BC", text: "British Columbia"},
...
],
I can import i18n from '../plugins/i18n' and confirm in console output that i18n.t('province.BC') return me proper text from resource files
i18n.t('province.BC') British Columbia
click onLanguageChange fr
i18n.t('province.BC') British Columbia (Fr)
But how I can insert these translations into datasource?
provinceData: [
{value:"AB", text: ???i18n.t('province.AB')??? },
{value:"BC", text: ???i18n.t('province.BC')??? },
...
]
Now I realized what mistake I did by wrapping i18n.t('province.AB') into back ticks. Here is corrected version which render english only messages:
provinceData: [
{value:"AB", text: i18n.t('province.AB') },
{value:"BC", text: i18n.t('province.BC') },
...
]
Moreover, will it be reinitialized if I switch the current locale?
PS. When getter for this datasource is hit I can see that message retrieved according to current locale. But dropdown box izn't reloaded. That's the problem
Following getter print correct translation every time it called:
provinceData: (state) => {
console.log("i18n.t('province.BC')",i18n.t('province.BC'));
return state.provinceData;
},

Because the provinceData inside the store it can't be modified by anything but mutators.
So I decided to create this array right in the getter and it turns out to be quite fast.
provinceData: ( state ) =>
{
const provinceData = [ "AB", "BC", "MB", "NB", "NF", "NT", "NS", "NU", "ON", "PE", "QC", "SK", "YT" ];
let provinces = [];
provinceData.forEach( (province) => {
provinces.push
({
value : province,
text : i18n.t( 'province.'+province )
})
})
return provinces;
}

Related

How to use two arrays in Vuetifyes v-autocomplete

I have two arrays, one with 7 boolean values representing the weekdays, and the other with the weekdays names and the value of which day of the week it represents, kind of index of weekdays (0 beeing sunday, and 6 beeing saturday)
This sample is from the ts file belonging to the vue file where the autocomplete is.
export const scheduleDays: TextValueViewModel[] = [
{ Text: "Mon", Value: 1},
{ Text: "Tue", Value: 2 },
{ Text: "Wed", Value: 3 },
{ Text: "Thu", Value: 4 },
{ Text: "Fri", Value: 5 },
{ Text: "Sat", Value: 6 },
{ Text: "Sun", Value: 0 }
];
This is from a view model I have containing this array with booleans representing the weekdays.
public readonly SelectedDays: boolean[] = [false,false,false,false,false,false,false];
I then have a autocomplete where I want to save the clicked checkboxes and that would be saved into the boolean array
<v-autocomplete
v-model="editedReleaseSchedule.ScheduleInterval.SelectedDays"
:items="scheduleDays"
:item-text="item => `${item.Text}`"
:item-value="item => `${item.Value}`"
:label="'ADMINISTRATION_RELEASE_SCHEDULE_DETAILS_SCHEDULED_DAYS' | translate('Selected days')"
:disabled="formDisabled"
:rules="[rules.required]"
outlined
hide-details
multiple
dense
/>
How can I make the clicked value of the weekday array beeing saved into the boolean array in the right index spot? And at the same time I want the correct checkboxes be checked in the autocomplete field.
The implemented auto complete in the interface
Using Vue 2 at my workplace, so no solution for vue 3 would work out for me.
I've tried to google if I can get the index of the v-autocomplete row and use that in item-value like:
editedReleaseSchedule.ScheduleInterval.SelectedDays[index]
but that does not seem possible. I've also tried different ways of filtering before using v-autocomplete, but I still want the whole list, not only the clicked (marked) once.
Use an intermediate model for the selectedValues, watch it, and map the selected values ([1,2,3...,0]) into the real model.
data: () => ({
selectedValues: [],
// ...
<v-autocomplete
v-model="selectedValues"
<!-- etc -->
watch: {
selectedValues(newValues) {
const allFalse = [false,false,false,false,false,false,false];
this.editedReleaseSchedule.ScheduleInterval.SelectedDays = allFalse;
newValues.forEach(value => {
// presumes sunday is the last index, the others are offset by +1
let j = value === 0 ? 6 : value-1;
this.editedReleaseSchedule.ScheduleInterval.SelectedDays[j] = true;
})
},

How can I retrieve nested values in Keystone 5 for my list

I'm adding a list called 'tourlocation' to my Keystone 5 project. In my mongo database my tourlocations collection has an object called 'coordinates', with two values: 'lat' and 'long'. Example:
"coordinates" : {
"lat" : 53.343761,
"long" : -6.24953
},
In the previous version of keystone, I could define my tourlocation list coordinates object like this:
coordinates: {
lat: {
type: Number,
noedit: true
},
long: {
type: Number,
noedit: true
}
Now unfortunately, when I try to define the list this way it gives the error: The 'tourlocation.coordinates' field doesn't specify a valid type. (tourlocation.coordinates.type is undefined)'
Is there any way to represent objects in keystone 5?
#Alex Hughes I believe your error says "type" which you may need to add it like this
keystone.createList('User', {
fields: {
name: { type: Text }, // Look at the type "Text" even in the MongoDB you can choose the type but it will be better to choose it here from the beginning.
email: { type: Text },
},
});
Note that noedit: true is not supported in version 5 of KeystoneJS.
For more info look at this page https://www.keystonejs.com/blog/field-types#core-field-types

Filter Vue list based on select option value

I try to filter my list with 2 select lists based on the selected value. It seems like my computed filter is not working?
You should be able to filter the list on 'Price from' and 'Price to'
List.vue
My computed filter property:
filteredData() {
const LowerCaseSearch = this.search.toLowerCase();
return this.products.filter(
product =>
(product.name.toLowerCase().includes(LowerCaseSearch) ||
product.category.toLowerCase().includes(LowerCaseSearch)) &&
(!this.checked.length || this.checked.includes(product.category)) &&
(!this.selectedFrom.length || this.selectedFrom.includes(product.price)) &&
(!this.selectedTo.length || this.selectedTo.includes(product.price))
);
},
In my registered component I use v-model to bind to the computed property selectedFrom
<Price v-model="selectedFrom" />
How do I bind to the other property selectedTo in one v-model and what's wrong with my filter?
I also use a prefix 'From' and 'To' to put in front of the options.
data: () => {
return {
selectedFrom: '0,00',
priceFrom: [
{ prefix: 'From', text: '0,00', value: '0,00' },
{ prefix: 'From', text: '200,00', value: '200,00' },
{ prefix: 'From', text: '400,00', value: '400,00' }
],
selectedTo: 'No max',
priceTo: [
{ prefix: 'To', text: '400,00', value: '400,00' },
{ prefix: 'To', text: '600,00', value: '600,00' },
{ prefix: 'To', text: '800,00', value: '800,00' },
{ text: 'No max', value: 'No max' }
]
}
},
Is there a more elegant and D.R.Y way to do this?
Here is a sandbox what I have so far.
You should bind an object to your v-model on the <price> component.
This way you can pass multiple values to and from your component, without having to use multiple props.
I would also suggest you convert your value in your selects to numbers, so it's easier to use them to compare to your prices.
You've also defined data properties and computed properties in the sandbox (<price> component) with the same name, this is not possible. So you should remove the data properties and stick to the computed ones to handle your data.
Fork of your sandbox with my suggested changes.

ReferenceArrayInput usage with relationships on React Admin

I have followed the doc for the ReferenceArrayInput (https://marmelab.com/react-admin/Inputs.html#common-input-props) but it does not seem to be working with relationship fields.
For example, I have this many-to-many relation for my Users (serialized version) :
Coming from (raw response from my API):
I have setup the ReferenceArrayInput as followed :
<ReferenceArrayInput source="profiles" reference="profiles" >
<SelectArrayInput optionText="label" />
</ReferenceArrayInput>
I think it's making the appropriate calls :
But here is my result :
Any idea what I'm doing wrong ?
Thanks in advance for your help !
On docs, ReferenceArrayInput is said to expect a source prop pointing to an array os ids, array of primitive types, and not array of objects with id. Looks like you are already transforming your raw response from api, so if you could transform a bit more, mapping [{id}] to [id], it could work.
If other parts of your app expects profiles to be an array of objects, just create a new object entry like profilesIds or _profiles.
As gstvg said, ReferenceArrayInput expects an array of primitive type, not array of objects.
If your current record is like below:
{
"id": 1,
"tags": [
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' }
]
}
And you have a resource /tags, which returns all tags like:
[
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' },
{ id: 'photography', name: 'Photography' }
]
Then you can do something like this (it will select the tags of current record)
<ReferenceArrayInput
reference="tags"
source="tags"
parse={(value) => value && value.map((v) => ({ id: v }))}
format={(value) => value && value.map((v) => v.id)}
>
<AutocompleteArrayInput />
</ReferenceArrayInput>

How to localize the alloyui scheduler component?

I am trying to fully localize the alloyui scheduler in French.
Following this article: How can I get a localized version of a YUI 3 or AlloyUI component? the job is almost done.
However I am still missing tips for two things:
- I need the time format in the left column to be changed from 1-12am/pm to 1-24
- I don't succeed to localize the "All day" term in the left top corner (or at least a way to hide it).
Any help will be welcome
To change to a 24 hour clock, you need to set the isoTime attribute to true for each SchedulerView subclass that you are using.
To internationalize the strings, you need to set the strings attribute of Scheduler, SchedulerDayView SchedulerWeekView, SchedulerMonthView, SchedulerAgendaView, and SchedulerEventRecorder as well as setting YUI's lang attribute to the locale of your choice. For example, I've used Google Translate* to internationalize the Scheduler below for Spanish users:
YUI({lang: 'es-ES'}).use('aui-scheduler', function (Y) {
var es_ES_strings_allDay = { allDay: 'todo el dia' };
new Y.Scheduler({
render: true,
// https://alloyui.com/api/classes/A.Scheduler.html#attr_strings
// https://github.com/liferay/alloy-ui/blob/3.0.3-deprecated.65/src/aui-scheduler/js/aui-scheduler-base.js#L606-L622
strings: {
agenda: 'agenda',
day: 'día',
month: 'mes',
today: 'hoy',
week: 'semana',
year: 'año'
},
views: [
// https://alloyui.com/api/classes/A.SchedulerDayView.html#attr_strings
// https://github.com/liferay/alloy-ui/blob/3.0.3-deprecated.65/src/aui-scheduler/js/aui-scheduler-view-day.js#L363-L373
new Y.SchedulerDayView({
isoTime: true,
strings: es_ES_strings_allDay
}),
// https://alloyui.com/api/classes/A.SchedulerWeekView.html#attr_strings
// SchedulerWeekView extends SchedulerDayView: https://github.com/liferay/alloy-ui/blob/3.0.3-deprecated.65/src/aui-scheduler/js/aui-scheduler-view-week.js#L19
new Y.SchedulerWeekView({
isoTime: true,
strings: es_ES_strings_allDay
}),
// https://alloyui.com/api/classes/A.SchedulerMonthView.html#attr_strings
// https://github.com/liferay/alloy-ui/blob/3.0.3-deprecated.65/src/aui-scheduler/js/aui-scheduler-view-week.js#L19
new Y.SchedulerMonthView({
isoTime: true,
strings: {
showMore: 'mostrar {0} más',
close: 'cerrar'
}
}),
// https://alloyui.com/api/classes/A.SchedulerAgendaView.html#attr_strings
// https://github.com/liferay/alloy-ui/blob/3.0.3-deprecated.65/src/aui-scheduler/js/aui-scheduler-view-week.js#L19
new Y.SchedulerAgendaView({
isoTime: true,
strings: {
noEvents: 'No hay eventos futuros'
}
})
],
// https://alloyui.com/api/classes/A.SchedulerEventRecorder.html#attr_strings
// https://github.com/liferay/alloy-ui/blob/3.0.3-deprecated.65/src/aui-scheduler/js/aui-scheduler-view-week.js#L19
eventRecorder: new Y.SchedulerEventRecorder({
strings: {
'delete': 'borrar',
'description-hint': 'descripción insinuación',
cancel: 'cancelar',
description: 'descripción',
edit: 'editar',
save: 'salvar',
when: 'cuando'
}
})
});
});
* I don't recommend using Google Translate to internationalize a production application since there are many nuances to internationalization that a machine translation will miss.