vuejs pass extra parameter to function - vue.js

Is it possible within Quasar Form rules to pass extra parameter?
This had to do with the following template code:
<q-field outlined v-else-if="prop.component === 'checkbox'"
class="q-gutter-sm"
v-model="dataRef[key]"
:label="prop.label"
:rules="[isCheckLimit]"
>
<q-option-group
style="margin-top:20px;"
:options="prop.options"
type="checkbox"
v-model="dataRef[key]"
/>
</q-field>
The function:
const isCheckLimit = (v) => {
return v.length > 2 || t('checked-to-much')
}
I want that number 2 to be dynamic instead of static, is it possible to pass for example a number to that function? I cant find any clear information about that?
Thank you in advance.

You have to define your rule as function in your rules array, first lets update your validation function to accept second argument, I will also set it to default value of 2:
const isCheckLimit = (v, minLength = 2) => {
return v.length > minLength || t('checked-to-much');
};
Now if you use this for your rules:
:rules="[(value) => isCheckLimit(value, 4)]"
Your validation function will use 4 for minLength instead of default 2.
Original way will also work:
:rules="[isCheckLimit]"
But will use the default value of 2 for minLength

Related

q-input has value then only Rules will apply

If q-input has value != '' then only i want to apply the Rules like required 8 number maximum. In the below code it gives me the required input error even it's null.
<q-input
filled
name="landline"
label="Landline Phone Number"
v-model="user.landline"
placeholder="Landline Phone Number"
ref="landlinePhoneNumber"
type="number"
:maxlength="8"
:rules="[val => val!='' && val.length > 7 || 'Landline Required 8 digit']"
/>
Try to add prop lazy-rules.
By default, it's set to 'ondemand', which means that validation will be triggered only when the component’s validate() method is manually called or when the wrapper QForm submits itself. More info
You have to return true when the field is null first, then validate only if it's not null. Also, add the prop lazy-rules so that it only validates when the form field loses focus.
Here is how I did it in Vue 3, using composable and TypeScript. The form field component:
<q-input
class="q-mt-md"
filled
v-model="id_number"
label="ID Number "
type="text"
hint="Optional/Leave blank if not available"
lazy-rules
:rules="[(val) => isNumberBlankOrValid(val) || 'Invalid ID Number']"
/>
The method isNumberBlankOrValid called from the field above:
const isNumberBlankOrValid = (val: string) => {
if (val.length === 0) {
return true
}
return isValidNumber(val)
}
The isValidNumber for other fields that must be filled:
const isValidNumber = (val: string) => val && isNumeric(val)
The isNumeric method is a simple regex for validating numbers:
const isNumeric = (value: string) => {
return /^\d+$/.test(value)
}

How can I pass a value from v-select to method - it always stays the same as the default

I have a function I want to pass a value to in my Vue app using v-select.
v-select is populated from a data array 'chapters'.
I then want to use the selected id to pass to a function.
I have an empty data variable 'chapterIdFilter' in my data return which is set to a value of 1 - this pre-filters my vuetify data table
How can I pass the value of the id - chapterIdFilter - from my v-select dropdown to a function in my methods so I can filter the table with it?
The chapterIdFilter is always '1'
<v-select
:model="chapterIdFilter"
:items="chapters"
item-text="locale.en.title"
item-value="id"
label="Filter by Chapter"
#change="currentDataItems(chapterIdFilter)"
/>
Method:
currentDataItems (chapterIdFilter) {
console.log(chapterIdFilter)
return this.portals.filter(val => val.chapterId === parseInt(chapterIdFilter)) // this.portals.filter(val => val.chapterId === '1')
}
UPDATE:
So the code below works as desired but I am not sure it should or know why
currentDataItems (chapterIdFilter) {
console.log(chapterIdFilter)
this.chapterIdFilter = chapterIdFilter
return this.portals.filter(val => val.chapterId === parseInt(this.chapterIdFilter))
},
You should bind v-model directive to the data property and use it with this in your method :
<v-select
v-model="chapterIdFilter"
:items="chapters"
item-text="locale.en.title"
item-value="id"
return-object
label="Filter by Chapter"
#change="currentDataItems"
/>
method:
currentDataItems () {
console.log(this.chapterIdFilter)
return this.portals.filter(val => val.chapterId === parseInt(this.chapterIdFilter))
}

Am I overwriting computed property filter in Vue?

I am trying to create a reactive filter for an array in Vue. My starting array comes from an API call which returns this.features (geojson features). I am filtering on a nested array. This works -- but when I enter a search term and then backspace back out to an empty string, and enter another string, I am not filtering the original array but appear to be filtering the already-filtered array. How could I filter again on the original array from the API call?
computed property:
filteredFeatures() {
if (this.searchTerm == '') {
return this.features
}
// filter on nested array
let filtered = this.features.filter(feature => {
feature.properties.site_observations = feature.properties.site_observations.filter(
el => JSON.stringify(el).match(this.searchTerm, 'i')
)
return feature.properties.site_observations.length > 0
})
return filtered
}
I have looked at Vue filtering objects property but I cannot make that code work (it uses Object.assign()). Thanks for any ideas.
Your computed property is mutating feature.properties.site_observations, that's a nono. Computed properties should be read only.
filteredFeatures() {
if (this.searchTerm == '') {
return this.features
}
// filter on nested array
let filtered = this.features.filter(feature => {
const site_observations = feature.properties.site_observations.filter(
el => JSON.stringify(el).match(this.searchTerm, 'i')
)
return site_observations.length > 0
})
return filtered
}
It seems here is your problem:
feature.properties.site_observations = feature.properties.site_observations.filter(
el => JSON.stringify(el).match(this.searchTerm, 'i')
)
Because this code filter feature and alter the proprieties of feature.properties.site_observations. Then, in the next read the value is alter. We say that your function it is not pure, because it alter the state of feature.
So, what you should do is:
let anotherVariable = feature.properties.site_observations.filter(
el => JSON.stringify(el).match(this.searchTerm, 'i')
)
Therefore, on a function, avoid alter state of objects, this lead to bugs.
On further checking, the above answer returns all site_observations, not just the ones that match the search. A much better solution is the following, using map to avoid overwriting the data, and the object spread operator to perform an object assign, and drilling down through the nested objects as follows:
filteredFeatures() {
return this.features
.map(feature => ({
...feature,
properties: {
site_observations: feature.properties.site_observations.filter(
element => {
return JSON.stringify(element).match(new RegExp(this.search, 'i'))
}
)
}
}))
.filter(feature => feature.properties.site_observations.length)
}

Kendo-vue-ui wrapper kendo-grid-column format phone number in grid

I have been trying to use vuejs filter in kendo-grid-column
<kendo-grid-column field="phone" title="Phone" :template="`kendo.toString(phone) | phoneformat`" width="10%"></kendo-grid-column>
Rather being displayed as formatted string the result is displayed as
Filter I am using as:
const filters = [
{
name: "phoneformat",
execute: value => {
debugger
var piece1 = phoneNumber.substring(0, 3); //123
var piece2 = phoneNumber.substring(3, 6); //456
var piece3 = phoneNumber.substring(6); //7890
//should return (123)456-7890
return kendo.format("({0})-{1}-{2}", piece1, piece2, piece3);
}
}
];
export default filters;
I have been registering the filter globally as:
import filters from './shared/extension'
filters.forEach(f => {
Vue.filter(f.name, f.execute)
})
Help me what i am missing here.
:template="`kendo.toString(phone) | phoneformat`"
You have backticks around the :template attribute value, meaning you're binding the template prop to a JavaScript template literal which evaluates to the literal string
"kendo.toString(phone) | phoneformat"
The solution is to simply bind an expression instead
<kendo-grid-column :template="phone | phoneformat" ...
See
https://v2.vuejs.org/v2/guide/filters.html
https://v2.vuejs.org/v2/guide/components-props.html#Passing-Static-or-Dynamic-Props

Angular Translate default translate value while using filter

Is there any way to provide the translate-default value while using the filter instead of directive?
e.g:
How to achieve the same results as this
<h3 translate="TEST" translate-default="Not present"></h3>
with filter format
{{ 'TEST' | translate }}
How do i put the "translate-default" attribute when using the translate filter?
What i need to do is show the original text if the key is not present.
I have created a wrapping filter for that purpose:
.filter('txf', ['$translate', ($translate: angular.translate.ITranslateService) => {
return (input: string, stringIfNotAvailable: string = '') => {
const translation = $translate.instant(input);
return translation === input ? stringIfNotAvailable : translation;
};
}]);