How do you use vue-select reduce prop to reduce a value to an object - vue-select

Can you use vue-select to reduce a value to an object with specific properties?
I am trying to do something like this:
<v-select
multiple
:options="locations_ordered"
v-model="state.modal.data.locations"
label="name"
:reduce="loc => {id: loc.id, name: loc.name}"
>
But it's throwing an error at the first colon. What's the right syntax here?

According to Vue docs transforming selections, you use reduce to select to a single key.
In your example, you'd be able to reduce to just returning the id(or name). See below:
<v-select multiple
:options="locations_ordered"
v-model="state.modal.data.locations"
label="name"
:reduce="loc => loc.id">
</v-select>
If you want to reduce to a smaller class perhaps it would be better to run a .map() on the list before handing it to the vue-select control.

Related

VUEJS: Is it possible to process/modify data retrieved through v-for before displaying?

Hello I am extremely new to web application development / javascript in general. Only gave myself crash courses from udemy videos for the past 4 months.
For my web application, I am retrieving data from a database through my server-side backend with axios. I have a logRepository Array where the retrieved data is pushed.
data() {
return {
logRepository: [],
}
},
created() {
axios.get('/myrestapiroute', {
headers: {
'Authorization': `Bearer ${this.$store.state.token}`
},
params: {
userId: this.userId
}
})
.then(res => {
const data = res.data.logs
this.dataCheck = data
for(let key in data) {
const log = data[key]
log.id = key
this.logRepository.push(log)
}
})
On my template, I used v-for to loop through all the retrieved data elements:
<div ..... v-for="(log,index) in logRepository" :key="index">
With the v-for in place, one example of how I display my data as such in a paragraph tag. The format is due to how the data was structured.
<p style="text-align: justify;">
{{ log.logId.jobPerformed }}
</p>
The problem arises when I try to apply styling to the text. As you can see above, I would like to use text-align: justify. I also wanted to keep the whitespace as how it was input by the user through the use of white-space: pre-wrap.
(https://i.imgur.com/dwaJHT9.png)
But the problem is these two styles do not work together well. As can be seen below in the picture, if I use justify on its own, it behaves normally (Except that whitespace is lost). However, if I combine both text-align:justify and white-space: pre-wrap, the text end up justified with spacing, but aligned in a weird way.
(https://i.imgur.com/DQSfOya.png)
For short entries, they begin with weird indentation when the starting side should be aligned to the left of the column. The issue appears to be more than simply whitespaces at the start as I have tried .trim() as suggested by a contributor.
(https://i.imgur.com/uwysk9X.png)
I tried to tweak the CSS around, with text-align-last, text-align-start, direction: ltr, pre-tags etc. But it just does not work properly. Suggestions from other SO pages recommended that the data be processed by performing a string replace of all \n to br before displaying.
Is it possible to perform processing for individual data obtained from v-for before displaying or it has to be done to the array using computed property?
Since my data is to be fetched from a database, I am confused on how to achieve the pre-processing of data, since my array size will dynamic and differ for each user.
What would be the most optimal way to achieve pre-processing of data before displaying for such case?
This image below is how my Array of Object (logRepository) looks like. The format is largely due to mongoDB schema.
(https://i.imgur.com/7SilcF7.png)
======= Solution =======
I modified the object variables in my .then block and performed string replace for all \n characters to tags.
https://i.imgur.com/EtLX2tg.png
With that my display no longer requires the "white-space: pre-wrap" styling. However, since I was previously using string interpolation to display my data the tags were treated as plain text.
https://i.imgur.com/zUbNZbI.png
I had to modify the tags to use v-html binding to display the data as htmltext so that would work. The difference can be seen in the last picture.
https://i.imgur.com/sCTsCV4.png
Thanks for helping me on this since I am very new to javascript.
There are a number of patterns you could use here to pre-process your data.
Process your data in the then function you have created
Wrap the data in functions within the {{ ... }} blocks in the template
Create a component that is used as the element that the v-for loop iterates over which displays a computed value
Use a computed value as the source array of the v-for directive in the main template. This is often done using a processing function mapped to the source data, as in log.map( data => data.logId.jobPerformed.trim()

How to give preference to a particular dictionary in sightly?

I have multiple dictionaries under "/etc/project_name/i18n" (e.g "/etc/project_name/i18n/default" and "/etc/project_name/i18n/overlay").
My requirement is picking up the values first from overlay path and if the overlay dictionary is empty, select the default path.
With the usage of internationalization in sightly, I am always getting the key values from "default" dictionary first. Is there a way to change this order of preference?
Thank you.
Assuming both 'default' and 'overlay' are jcr:language, you can provide explicit preference as such:
${'key' # i18n, locale='overlay'}
For recurring implementation:
<sly data-sly-call="${i18nOverlay # key='key'}"></sly>
<template data-sly-template.i18nOverlay="${# key}">
${key # i18n, locale='overlay'}
</template>
Ref: HTL Expression Language

How to sort the columns in the tool panel. Ag-Grid

Edit: Found out move column doesn't work in v6.4.0
Example Link:
https://www.ag-grid.com/javascript-grid-tool-panel/toolPanelExample.html
The order of columns visible in the tool panel are always in the same order that they are defined in the column definition. Check the image below.
Is it possible to sort them in the tool panel in an order(say alphabetically) but without changing the order they are shown in the grid.
What I tried:
I tried defining them in alphabetical order in the columnDefination and tried to move them to there position using the columnApi.moveColumn(). That doesn't seems to work either also that increases the complexity when I have to move all the columns and position them.
Questions:
Is this even possible/feasible?
The moveColumn() function is not working. Can you tell in which version it was introduced not able to find it in changeLog.
Additional Details:
Using ag-grid enterprise version v6.4.0
Please refer to this plnkr. I used the same basic idea that you had, creating the colDefs in alphabetical order then in the onGridReady function moved the columns to their respective placements. There are two functions that are useful in doing this, the second is much preferable in my opinion:
moveColumn(colKey, toIndex)
//colKey refers to the id of the column which defaults to the specified field
//toIndex is simply a number that is within the range of columns.
moveColumns(colKeys[], toIndex)
//colKeys[] is an array in the order that you want them to be
displayed starting at the toIndex
Here is how I implemented it in the plnkr:
private onReady() {
// this.gridOptions.columnApi.moveColumn('name',1)
// this.gridOptions.columnApi.moveColumn('country',2)
// this.gridOptions.columnApi.moveColumn('dob',3)
// this.gridOptions.columnApi.moveColumn('skills',4)
// this.gridOptions.columnApi.moveColumn('proficiency',5)
// this.gridOptions.columnApi.moveColumn('mobile',6)
// this.gridOptions.columnApi.moveColumn('landline',7)
// this.gridOptions.columnApi.moveColumn('address',8),
this.gridOptions.columnApi.moveColumns(['name', 'country', 'dob', 'skills', 'proficiency', 'mobile', 'landline', 'address'],1)
}
There is one more function that is available to you if you would like to use it:
moveColumnByIndex(fromIndex, toIndex)
//This uses just indexes and not the colid/colkey idea if you prefer
to keep it more anonymous

Adding fields dynamically to Share form

I want to add a text field for each file that is added to the attached package items in alfresco to write notes regarding each file, is it possible to do?
I have implemented something that could be reused for your use case.
You can define a property with multiple values that will contain the list of notes associated with each attachment.
There is a simple trick to post a property with multiple values: add "[]" to the name of the property. For example:
<input id="template_x002e_edit-metadata_x002e_edit-metadata_x0023_default_prop_someco_notes_0"
name="prop_someco_notes[]"
tabindex="0"
type="text"
value="Meeting minutes"
title="Notes"
noderef="workflow://...."
>
<input id="template_x002e_edit-metadata_x002e_edit-metadata_x0023_default_prop_someco_notes_1"
name="prop_someco_notes[]"
tabindex="1"
type="text"
value="Meeting minutes"
title="Notes"
noderef="workflow://...."
>
As you can see, the name of the input ends with []. Both input textfields have the same name.
The Alfresco Form Engine will consider these two inputs as the value for the property with multiple values: "someco:notes".
The bigger problem is that you need to generate this html with some smart javascript and free marker template.
You can write a custom free marker template to render the initial html: if a user opens a task on which documents have been already attached, you will need to generate the list of inputs using a custom control (you can of course start from textfield.ftl).
It won't be easy to generate the initial list because unfortunately Alfresco returns the list of values as a single comma separated value.
You can customise the webscript that injects the model in the free marker template "org.alfresco.web.scripts.forms.FormUIGet" to pass an array instead of a csv.
A quicker and dirtier solution is to split the csv value. In share-config-custom.xml, you can specify what textfield.ftl show use as a separator instead of the comma.
When a user adds/remove elements from the package, you can intercept the update and add/remove the correspondent note. Notice that I have added the filed "noderef" to each input so it is possible to know the relation between the notes and the nodes in the package.
UPDATE:
For the associations (used for example to define the package in a workflow task), Share uses a javascript library called "object finder" (or "object picker"). This library fires an event called "formValueChanged" that you can intercept:
YAHOO.Bubbling.fire("formValueChanged",
{
eventGroup: this,
addedItems: addedItems,
removedItems: removedItems,
selectedItems: selectedItems,
selectedItemsMetaData: Alfresco.util.deepCopy(this.selectedItems)
});

Sort form field choices by translated labels

I have an array:
[
0 => 'translate.label1',
1 => 'translate.label2',
2 => 'translate.label1'
]
which I specify as a choices param for field creation.
Now, is it possible to sort these options by translated labels? For example, label1 translated value is zero, label2 - something, label3 - abracadabra. Of course, I expect select options to be:
abracadabra
something
zero
I thought to use this approach: https://stackoverflow.com/a/21586886/2324004
But doesn't it involve second translator digest inside view? Any ideas? I'd rather to use something more flexible because my form is based on non-fixed selects count and it would have executed something recursive...
You have to do it in js after data will be uploaded.
Check this topic:
Javascript to sort contents of select element
Due to fact the translation occurs inside Twig view, the only solution (right now I'm aware) is to prepare translated and sorted list during form build process by injecting manually TranslatorInterface service.
Unfortunately, without overriding widget's template, translation occurs second time, against already translated labels.

Resources