I have a Vue app running a filter with Checkboxes and everything works fine for selecting multiple options. What I want to do is set it up to only allow one selection ie. Change input type to radio. The following function that worked with checkboxes throws this error in devtools console when changing the type to radio buttons...
categoryParams.map is not a function
Is this because it is now an Object and not an array? This is the function in question...
categories: []
let payload = {
categories : this.prepareQueryStringFromSelectedCategories(this.categoriesSelected),
};
prepareQueryStringFromSelectedCategories(categoryParams) {
return categoryParams.map(element => element.slug);
}
What would the solution be to convert the checkbox array to allowing a radio button to be selected to filter?
Thanks
Is this because it is now an Object and not an array? This is the function in question...
Yes. .map() is a function on native Javascript arrays, nothing specific to Vue. According to the Vue documentation, the bound variable in the view-model will contain the value of the selected item, so you should be able to access the property directly.
prepareQueryStringFromSelectedCategories(categoryParams) {
return categoryParams.slug;
}
Related
Per the docs you can add the attribute use-input to a QSelect component to introduce filtering and things of that nature: https://quasar.dev/vue-components/select#Native-attributes-with-use-input.
However, if you type something into one of these fields and click outside of it, the text gets removed.
Is there any way to grab that text in Vue before it gets removed and do something with it?
Since v1.9.9 there is also a #input-value event described in the q-select api.
As the api says it's emitted when the value in the text input changes. The new value is passed as parameter.
In the examples there's a filter function, so there you can save it in a data variable:
methods: {
filterFn (val, update, abort) {
update(() => {
this.myDataVariable = val;
})
}
}
When I have
data: {
pictures: [
'http://lorempixel.com/1920/1920?0',
'http://lorempixel.com/1920/1920?1',
'http://lorempixel.com/1920/1920?2',
'http://lorempixel.com/1920/1920?3',
'http://lorempixel.com/1920/1920?4',
'http://lorempixel.com/1920/1920?5',
'http://lorempixel.com/1920/1920?6',
'http://lorempixel.com/1920/1920?7',
'http://lorempixel.com/1920/1920?8',
'http://lorempixel.com/1920/1920?9',
]
}
it renders perfectly, but when I fetch the data and get it like this in the console and perfect data in the vue dev tools
["https://picsum.photos/id/1020/4288/2848",
"https://picsum.photos/id/1021/2048/1206",
"https://picsum.photos/id/1022/6000/3376",
"https://picsum.photos/id/1023/3955/2094",
"https://picsum.photos/id/1024/1920/1280",
__ob__: Observer]
it populates the dom but not rendered.
what am I missing??
If I face that situation then I check if I have created that property as reactive.
Means I have added v-model on it or not.
Other way is to add it in watch propery as shown below
watch:{
//just write name of the data propery and make it function
picutres(){}
//that's it
}
Now it will listen for the changes.
If you still somehow cannot fix that problem then other solution it to use custom events or a function
You will call function or trigger an event whenever you change your pictures array.
Then in function or event you can update your pictures array
I cannot for the life of me figure this out.
Fiddle at: https://jsfiddle.net/s8xvkt10/
I want
User clicks checkbox
Then based on separate conditions
Checkbox calculatedCheckedValue returns a data property /v-model of true/false
And the checked state reflects the calculatedCheckedValue
I can get:
The calculatedCheckedValue calculates and interpolates properly
But I fail at:
Having the :checked attribute render the calculatedCheckedValue properly in the DOM
e.g. If a false checkbox is clicked and the calculatedCheckedValue still returns false, the checkbox toggles onscreen between checked and unchecked
I’ve tried:
Using a v-model with a custom set that does the calculation and sets the local state which the custom get returns
Imitating a v-model using #change.prevent.stop="updateCalculatedValue" and :checked="calculatedValue"
Assuming the #change happens after the #click (which i think is wrong) and using #click.prevent.stop="updateCalculatedValue" and :checked="calculatedValue"
The model is working and rendering the calculated value as string in a DOM span,
but the checked value doesn't seem to respect the model value
Can someone please help me out?
I've solved the problem at: https://jsfiddle.net/pc7y2kwg/2/
As far as I can tell, the click event is triggered even by keyboard events (src)
And happens before the #change or #input events (src)
So you can click.prevent the event, but you need to either prevent it selectively or retrigger the event after the calculation.
//HTML Template
<input :checked="calculatedValue5" #click="correctAnswer" type="checkbox">
//VUE component
data() {
return {
calculatedValue5: false,
};
},
methods: {
correctAnswer(e){
const newDomValue = e.target.checked;
this.calculatedValue5 = this._calculateNewValue(newDomValue);
if(this.calculatedValue5 !== newDomValue){
e.preventDefault();
}
}
}
I think this is preventing checkbox value from updating before the data value, which seems to break the reactivity. I'm not sure the technical reason why, but the demo does work
I am working on a project in my organization where I have to implement ag-grid .I know ag-grid has a gridready event function which fires initially and sets the params with all grid api properties . My rowdata is constantly changing which is coming from some other component ,I have added a handler (function) where I want to call gridready event again which sets my rowdata with the latest values . The problem is gridapi properties will be initialized only at 1st time ,I want to access those (gridapi) properties in my handler as well which is becoming undefined now ,how to access gridapi properties even after grid initialization and scope is lost. I don't have the exact code ,I have added some code snapshots which will describe my situation exactly.
grid.component.ts
#Input() gridData
ngOnit() {
}
handler() {
want to call grid ready but params will be undefined ,how to set this gridapi properties.
gridready()
}
gridready(params) {
this.gridapi =params.api;
this.columnapi =params.clumnapi
this.gridapi.setRowData(this.gridData.rowData)
}
According to ag-Grid's documentation, the Grid API (both api and columnApi) will only be available after the gridReady event has been fired.
Here's an alternative way of achieving the same thing if I understood your problem correctly.
You can try adding a local variable, isGridAPIReady, in your own grid.component.ts to track that state.
Set isGridAPIReady to true when ag-grid GridReadyEvent fires.
And eventually set the new rowData using the grid api:
//grid.component.ts
#Input()
rowData: any[];
ngOnChanges(changes: SimpleChanges): void {
if (this.isGridAPIReady && changes['rowData']) {
this.gridOptions.api.setRowData(this.rowData);
}
}
Hope it helps!
I'm currently implementing a classical Minesweeper game in Vue.js which is working fine so far https://github.com/franktopel/defuse, Demo http://connexo.de/defuse/.
Now I would like to add touch support because as of now, to mark a field as "contains a mine" it is required that you right-click the field. Right-clicking is obviously not available on touch devices, so I would like to add longtap support. I'm using native events click and click.right from the parent component for each field, so the field does not handle the events, but the parent component that instantiates these fields does.
I've found this https://github.com/jerrybendy/vue-touch-events and added it to my project, yet it seems I cannot use this on the component tag (see https://github.com/franktopel/defuse/blob/master/src/components/Defuse.vue):
<m-field
v-for="field in row"
:field="field"
:key="`${field.x},${field.y}`"
#click.native="open(field)"
#click.right.native.prevent="toggleBombMarker(field)"
v-touch:longtap="toggleBombMarker(field)"
></m-field>
because that marks all fields without any user interaction and the console keeps producing
You may have an infinite update loop in a component render function.
This is how my field objects (which I'm passing to the field component) are created:
let Field = function (x, y) {
this.x = x
this.y = y
this.isOpen = false
this.hasBomb = false
this.isMarked = false
this.numNeighbourBombs = null
}
module.exports = Field
I have also tried emitting a custom event from inside my field component, yet I don't know how I can pass the triggering field to the event handler from there.
Can anyone push me in the right direction?
According to the vue-touch-events docs, the v-touch directive doesn't work in the same way as v-on; v-touch must be given a function to execute, whereas the toggleBombMarker(field) expression probably returns undefined.
If you want to pass extra parameters to the v-touch handler, your handler must return a function like this:
methods: {
toggleBombMarker(field) {
return () => {
// your handler code here
}
}
}