Why this odd warning from Vue / Vuetify / Vite? - vue.js

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"

Related

How can I debug why my array of objects have inconsistent values?

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?

[Vue warn]: Invalid prop: custom validator check failed for prop "colspan" in bootstrapvue

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>

Can't print value from array of objects

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}}

Foundation 6 slider: range stating from negative values

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.

How to create SwapView dynamically using Dojo

I am using Dojo v1.8 with Worklight; I would like create a SwapView dynamically in View, but I'm encountering problems...
HTML code:
<div data-dojo-type="dojox.mobile.View" id="listeInscriptionView"
data-dojo-props="selected:false,scrollDir:'vh'"
style="background-image: url('images/bg-texture.jpg');"
data-dojo-id="id">
</div>
JavaScript code:
var view = registry.byId(listeInscriptionView);
alert(view);
for(var i = 1; i < 3; i++ ){
var swap = new dojox.mobile.SwapView({
id: i,
selected:false
});
var head = new dojox.mobile.Heading({
label:'Swap' + i,
});
swap.addChield(head);
view.addChield(swap);
alert("test" + i);
}
The above does not work. How I can create the widget SwapView dynamically?
Is that a copy of your actual code? I have not actually tested it but there are syntax errors and typos:
registry.byId(listeInscriptionView);
should be
registry.byId("listeInscriptionView");
(missing quotes), and
swap.addChield(head);
view.addChield(swap);
should be
swap.addChild(head);
view.addChild(swap);
Maybe it works better with these errors fixed?