I'm new to Vue.js v2. This is my first project. I have no idea what caused this issue, but I can't explain why my values changed when they're 6 lines apart. Hint 966 & 972
If line 966 returns null, why 972 returns 25 ??
I only post this image for the line numbers references
storeRule() {
this.$refs.form.validate()
if (this.$refs.form.validate()) {
let conditions = []
for (var i = 0; i < this.ruleDetails.length; i++) {
let c = this.ruleDetails[i]
// NEVER REMOVE THIS DEBUG STATEMENT
console.log('%c ', 'background: linear-gradient(45deg, red, yellow, orange)')
console.log('this.ruleDetails[i] >>', this.ruleDetails[i])
console.log('%c ________________________________________________________________', 'background: linear-gradient(45deg, red, pink, white, pink, red)')
// NEVER REMOVE THIS DEBUG STATEMENT
if (c.attribute_id != '' && c.attribute_id != null) {
console.log('..........................NEW..........................')
console.log('c.attribute_id', c.attribute_id) //will run ...
let condition = this.mapCondition(c)
if (c.attribute_id == 22 && c.operator_id == 21) {
var submitValue = []
c.value.sort()
if (c.value.length > 1) {
for (var j = 0; j < c.value.length; j++) {
submitValue.push(c.value[j])
}
}
condition.value = submitValue.join(', ')
}
conditions.push(condition)
}
}
let currentPriority = this.rules.length + 1
var rule = {}
rule.name = this.ruleName
rule.priority = currentPriority
if (this.urlType == 'Multi') {
rule.group_id = this.userGroup.id
rule.group_name = this.userGroup.name
} else {
rule.url = this.url
}
rule.details = conditions
this.rules.push(rule)
if (this.rules.length > 0) {
this.submit = true
}
this.showAddRule = false
this.alert = true
this.alertColor = 'green'
this.alertMessage = this.ruleName + ' - created !'
this.$refs.form3.reset()
}
},
HTML
<v-row v-for="(rule, index) in ruleDetails" :key="`ruleDetails-${index}`">
<v-col md="4">
<v-select dense outlined item-text="name" item-value="id" label="Attribute" :items="attributes" v-model="rule.attribute_id" #change="changeAttribute(index, rule.attribute_id)"></v-select>
</v-col>
<v-col md="3">
<v-select outlined dense item-text="name" item-value="id" label="Operator" v-model="rule.operator_id" :items="rule.operators" #change="changeOperator(index, rule.attribute_id, rule.operator_id)"></v-select>
</v-col>
<v-col md="4">
<!-- ---------
/// ruleDetails
--------- -->
{{ rule.attribute_id }}
<v-row v-if="locationIds.includes(rule.attribute_id)">
<v-col md="4" v-if="rule.attribute_id == 34">
<v-combobox :items="radiuses" v-model="rule.value[index].value_param" label="Radius" dense outlined></v-combobox>
</v-col>
<v-col md="8">
<v-combobox :items="locations" item-text="value_alias" item-value="value" return-object v-model="rule.value[index].value" :label="`Name (${locations.length})`" dense outlined append-outer-icon="delete" #click:append-outer="removeRuleDetail(index)" #change="getLocations(index, rule, rule.attribute_id)"></v-combobox>
</v-col>
</v-row>
</v-row>
Updated
I thought I got hit by one of this 🐞
I even tried
this.$forceUpdate()
Same result... I see attribute_id = null, but in the next 6 lines, it's 25 🤯
It makes no sense to me...
Try to use this instead
JSON.parse(JSON.stringify(var))
Full disclosure... I've never used vue.js in my life. But I believe this is just how Javascript objects work. Just because attribute_id shows as null inside the object doesn't mean it was null when the code was running. It doesn't mean it was changed within those 6 lines either.
Simplified example. But you can see the value in console reflects the change that was made after console.log.
Might be a bug in chrome?
Related
I am constructing an array of Vuetify 'chips' that can have data dragged from one to the other:
<v-container id="endgrid" style="max-width: 300px; position: relative;">
<v-row v-for="(row,r) in endGrid">
<v-chip size="x-large"
v-for="(chip,c) in row"
:key="chip.name"
draggable="true"
#drop="drop($event)"
#dragover="allowDrop($event)"
#dragstart="drag($event)"
:id=idString(1,r,c)
> {{ chip.name }} </v-chip>
</v-row>
</v-container>
and it works as expected. But during the document creation I am getting this warning (in the debug console) for every one (of 25) chip creations:
[Vue warn]: Invalid prop: type check failed for prop "draggable". Expected Boolean, got String with value "true".
at <VChip size="x-large" key=43 draggable="true" ... >
I'm sure the correct syntax for draggable is with a string, not a Boolean. Although if I remove the quotes, the warnings still appear - but the code still works.
I'm concerned that
this may be hiding something else wrong in my code
even if not, those warnings appearing in a browser's debug console don't look good!
Since it may be relevant, the data used to construct the grid looks like this:
onBeforeMount(() => {
var index = 1;
for (var i = 0; i < 5; i++)
{
endGrid[i] = [];
for (var j = 0; j < 5; j++)
{
endGrid[i][j] = {
"name" : i*10+j,
"id" : index,
"row" : i,
"col" : j,
"list": 'end'
};
++index;
}
}
});
You need to bind draggable first in order to pass boolean:
:draggable="true"
Currently developing an appointment-making application using a C# API in Vue.js with Vuetify, I encounter a behaviour with the component V-Calendar I can't comprehend. When originally feeding events to the calendar (appointments retrieved from a database by contacting the API), those events are correctly displayed as followed :
Original calendar loading
The query originally ignores cancelled appointments. However, I give the option to include them with a checkbox in the calendar header. Checking the box automatically refreshes the list of events through a watcher. When doing so, the calendar has a strange behaviour and does no longer display the events. This only occurs in the "Month" view, the "Day" and "Week" ones correctly display the data.
Result of refreshing the calendar
Here is the definition of my calendar (programming in french, translated in english the variables/methods for your easier understanding)
<v-calendar ref="calendar"
v-model="focus"
:event-color="getEventColor"
:events="events"
:first-interval="13"
:interval-count="22"
:interval-format="intervalFormat"
:interval-minutes="30"
:type="type"
:weekdays="weekDays"
color="primary"
event-more-text="Show more"
event-overlap-mode="column"
locale="fr"
#change="updateRange"
#click:event="showEvent"
#click:more="viewDay"
#click:date="viewDay">
<template #event="event">
<div v-if="event.eventParsed.input.idEtat === etats.annule"><s><i>{{
event.eventParsed.input.name
}}</i></s></div>
<div>{{ event.eventParsed.input.name }}</div>
</template>
</v-calendar>
The definition of the updateRange method (called once when the page is loaded in the created() hook)
async updateRange({start, end}) {
this.currentDateDebut = start.date;
this.currentDateFin = end.date;
await this.refreshCalendarData();
}
The definition of the refreshCalendar method
async refreshCalendarData() {
this.loading = true;
const events = []
//Récupération des rendez-vous
await this.getRendezVous(this.currentDateDebut, this.currentDateFin);
this.rendezVous = await this.$store.getters["rendezVous/getRendezVousData"];
for (let i = 0; i < this.rendezVous.length; i++) {
const calculImcPossible = (this.rendezVous[i].taille != null && this.rendezVous[i].taille > 0) &&
(this.rendezVous[i].poids != null && this.rendezVous[i].poids > 0);
const calculImc = calculImcPossible
? (Math.round(this.rendezVous[i].poids / ((this.rendezVous[i].taille / 100) * (this.rendezVous[i].taille / 100)) * 100) / 100).toFixed(2)
: null;
const libelleImc = this.getLibelleImc(calculImc);
events.push({
id: this.rendezVous[i].id,
idInstitution: this.rendezVous[i].idInstitution,
name: this.heureCourte(this.rendezVous[i].date) + " | Appointment",
start: new Date(this.rendezVous[i].date),
end: new Date(new Date(this.rendezVous[i].date).getTime() + 15 * 60000),
color: this.rendezVous[i].institution.color,
timed: true,
taille: this.rendezVous[i].taille != null && this.rendezVous[i].taille > 0
? this.rendezVous[i].taille + "cm"
: "indéfinie",
poids: this.rendezVous[i].poids != null && this.rendezVous[i].poids > 0
? this.rendezVous[i].poids + "kg"
: "indéfini",
sexe: this.rendezVous[i].patient.sexe,
imc: calculImc != null ? (calculImc + " (" + libelleImc + ")") : "non-déterminé",
nom: this.rendezVous[i].patient.nom + " " + this.rendezVous[i].patient.prenom,
telephone: this.rendezVous[i].patient.telephone != null ? this.rendezVous[i].patient.telephone : "-",
email: this.rendezVous[i].patient.email != null ? this.rendezVous[i].patient.email : "-",
commentaire: this.rendezVous[i].commentaire,
regime: this.rendezVous[i].regime,
hospitalisation: this.rendezVous[i].hospitalisation,
contagieux: this.rendezVous[i].contagieux,
incontinent: this.rendezVous[i].incontinent,
naissance: this.dateCourte(this.rendezVous[i].patient.naissance),
diabete: this.rendezVous[i].diabete.type,
examen: this.rendezVous[i].examen.nom,
idEtat: this.rendezVous[i].idEtat,
idPatient: this.rendezVous[i].idPatient,
typeEvent: "rendez-vous",
editable: this.rendezVous[i].editable
});
}
}
And finally, the definition of the watcher showCancalledAppointments
async showCancelledAppointments() {
await this.refreshCalendarData();
}
Do you have any idea why this behaviour is displayed by the calendar ? Thank you for your time and help.
Updating the solution with the command 'npm update' fixed the problem. The latest version of Vuetify seems to solve the issue
I am using BootstrapVue in my Vuejs project, I face a weired issue "Invalid prop" with b-table-simple componentinb-thead table helper I bind colspan with array length which always gives a number, and it works fine but it generates console warning message:
[Vue warn]: Invalid prop: custom validator check failed for prop "colspan".
found in
---> <BTh>
<BTr>
<BThead>
<BTableSimple>
<NationalTrends> at resources/js/components/trends/NationalTrends.vue
<Trends> at resources/js/components/trends/Trends.vue
<Root>
When I put number (4 or any other number) it works fine without generating the warning in the console.
Below is my code:
<template>
<div>
<b-table-simple hover small caption-top responsive striped>
<caption>Commodity Trends</caption>
<b-thead head-variant="light">
<b-tr>
<b-th>Commodity</b-th>
<b-th>Current Month</b-th>
<b-th :colspan="selected_periods.length">Previous Period</b-th>
<b-th :colspan="selected_periods.length">% Change From the Previous Period</b-th>
<b-th :colspan="selected_periods.length" class="text-center">Direction of Change</b-th>
</b-tr>
</div>
</template>
Please help, I spent one hour trying to figure out whats the problem but no luck......
Try to use like this:
:colspan="selected_periods.length > 0 ? selected_periods.length : 1"
Please check selected_periods.length against that custom validator (see bootstrap-vue source)
const digitsRx = /^\d+$/
// Parse a rowspan or colspan into a digit (or null if < 1 or NaN)
const parseSpan = val => {
val = parseInt(val, 10)
return digitsRx.test(String(val)) && val > 0 ? val : null
}
/* istanbul ignore next */
const spanValidator = val => isUndefinedOrNull(val) || parseSpan(val) > 0
export const isUndefined = val => val === undefined
export const isNull = val => val === null
export const isUndefinedOrNull = val => isUndefined(val) || isNull(val)
I managed to remove the warning by adding a default value if null (which will not happen in my code) as below:
<b-th :colspan="selected_periods.length || 4">Previous Period</b-th>
<b-th :colspan="selected_periods.length || 4">% Change From the Previous Period</b-th>
<b-th :colspan="selected_periods.length || 4" class="text-center">Direction of Change</b-th>
Here I am filling the localStorage:
let storageObj = {};
storageObj.date = (new Date().toLocaleString().replace(", ","T"));
storageObj.url = this.responseURL;
localStorage.setItem(storageObj.date, storageObj.url);
In mounted() I am iterate all data from localStorage like:
for(let obj of Object.entries(localStorage))
{
this.lastpasts.push(obj);
}
And placing every Object to lastpasts (located in data() {lastpasts : []}).
In template I want to print only url:
<div class="ui divided items" v-for="el in lastpasts">
<div class="item">
{{el.url}}
</div>
</div>
But this code do not print nothing. Work only {{el}}. It's print in HTML block:
[ "24.06.2017T11:55:10", "362e9cc5-e7e6" ]
[ "24.06.2017T12:26:47", "b0f9f20d-7851" ]
Browser console do not have any errors.
In the chat session we managed to solve his issue.
It was caused by the fact, that he was using Array of Arrays instead of Array of Objects. Because Array can be used only with index, not field name, {{el.url}} was not working.
The code to get values from LocalStorage had to be changed to:
mounted() {
for(let obj of Object.entries(localStorage)) {
var x = {};
x.url = obj[0];
x.date = obj[1];
this.lastpasts.push(x);
}
}
Now, it is possible to use {{el.url}}
I wander if in foundation 6 sliders, it is possible to allow negative values e.g. swinging from -50 to 50.
Currently I have a slider in [0 100]:
<div class="row">
<div class="small-4 large-4 columns">
<label>Audio Volume</label>
</div>
<div class="small-6 large-6 columns">
<div class="slider" id="slidervol" data-slider data-end="100" display_selector: "#slidervol">
<span class="slider-handle" data-slider-handle role="slider" tabindex="1" aria-controls="sliderVolOutput"></span>
<span class="slider-fill" data-slider-fill></span>
</div>
</div>
<div class="small-2 large-2 columns">
<input name="AudioVolTxtbox" type="number" style="width: 4em;" tabindex="2" id="sliderVolOutput">
</div>
</div>
You can set a negative start value, but the behaviour is unpredictable when you do so. If you want to make use of negative values, you'll need logic to update the value in #sliderVolOutput after the handle has been moved.
The moved.zf.slider event is triggered every time the handle is moved and you can use that fact to update the textbox value. This event is fired quite a few times, so you'll need to add additional code to get rid of the flickering (if it's bothersome).
I've provided some basic code that should get you started. If you have any questions, please let me know.
var target = document.getElementById("slidervol");
var options = {
"start": 0,
"end": 100,
"decimal": 0
};
var elem = new Foundation.Slider($(target), options);
var offset = 50;
$(target).on('moved.zf.slider', function() {
$('#sliderVolOutput').val(Number($('.slider-handle').attr('aria-valuenow')) - offset);
});
Another approach would be to use the mousemove.zf.slider event. This gets rid of the flicker, but the textbox value is only updated once you've stopped manipulating the slider:
$(target).on('mousemove.zf.slider', function() {
$('#sliderVolOutput').val(Number($('.slider-handle').attr('aria-valuenow')) - offset);
});
UPDATE:
In response to your additional query, I've had time to implement the required functionality (editing the value in the text box causing the slider to update) using a hidden control.
The slider-handle now targets the hidden control (aria-controls), which will always contain a positive value. The text box will contain the negative (computed) value. This is what the updated html looks like for the slider-handle:
<span class="slider-handle" data-slider-handle role="slider" tabindex="1" aria-controls="sliderVolOutputHidden"></span>
And this is the additional hidden input I've used:
<input type="hidden" id="sliderVolOutputHidden" value="0">
I've also added an input event for #sliderVolOutput that updates the value of the hidden input and triggers the change event. The change event is important, as without it, the handle will not update:
$('#sliderVolOutput').on('input', function() {
$('#sliderVolOutputHidden').val(Number($('#sliderVolOutput').val()) + offset);
$('#sliderVolOutputHidden').trigger('change');
});
Fiddle Demo
I get quite a result patching as follows foundation.js.
I can change values smoothly with the slider (with no flickering) but I can not decrement the textbox (aria-controls) below 0 since he event handler does not fire.
## -6953,13 +6953,14 ##
'id': id,
'max': this.options.end,
'min': this.options.start,
+ 'offset': this.options.offset,
'step': this.options.step
});
this.handles.eq(idx).attr({
'role': 'slider',
'aria-controls': id,
- 'aria-valuemax': this.options.end,
- 'aria-valuemin': this.options.start,
+ 'aria-valuemax': this.options.end + this.options.offset,
+ 'aria-valuemin': this.options.start + this.options.offset,
'aria-valuenow': idx === 0 ? this.options.initialStart : this.options.initialEnd,
'aria-orientation': this.options.vertical ? 'vertical' : 'horizontal',
'tabindex': 0
## -6978,8 +6979,8 ##
key: '_setValues',
value: function _setValues($handle, val) {
var idx = this.options.doubleSided ? this.handles.index($handle) : 0;
- this.inputs.eq(idx).val(val);
- $handle.attr('aria-valuenow', val);
+ this.inputs.eq(idx).val(val+this.options.offset);
+ $handle.attr('aria-valuenow', val+this.options.offset);
}
/**
## -7033,7 +7034,8 ##
} else {
//change event on input
value = this._adjustValue(null, val);
- hasVal = true;
+ value = value - this.options.offset;
+ hasVal = true;
}
this._setHandlePos($handle, value, hasVal);
## -7286,7 +7288,13 ##
* #option
* #example false
*/
- invertVertical: false
+ invertVertical: false,
+ /**
+ *
+ * #option
+ * #example 0
+ */
+ offset: 0
};
function percent(frac, num) {
Then, for instance I want to change my parameter "Audio Volume" from -24 to 24 so in js:
// Audio Volume
vartxt = GetParameter("AudioVolume") // get the value in some way
tval = parseFloat(vartxt);
document.DeviceConfig.AudioVolTxtbox.value = tval - 24; //change the textbox
var target = document.getElementById("slidervol");
var options = {
"start": 0,
"end": 48,
"decimal": 0,
"step": 1,
"offset": -24,
"initialStart": tval
};
var elem = new Foundation.Slider($(target), options);
At the moment the only problem I get is that I have to configure the input box as 'text', since if I set it as 'number' the spinner does not allow to go below the 0.