Passing dynamic styles to my element in VueJS - javascript

I am trying to make a type of progress bar to track a percentage of tasks completed. I want to v-bind:styles and pass it {width: dynamicWidth + '%'} in order to control the progression of this bar. So far I have created a computed variable that will return the percentage complete I want to bar to display, and I have set up my dynamic style in the data object
export default{
data: function () {
return {
numQuotes: dataBus.numQuotes,
numberA: 30,
barWidth: {
width: this.barWidthCalculated +'%'
}
}
},
computed: {
barWidthCalculated: function(){
return this.numQuotes * 10;
}
}
}
I also added an element to the DOM to see what was happening.
<div id="trackerBar">
<div id="trackerBarActual" v-bind:style="barWidth">
<h2>{{numQuotes}}/10</h2>
<p>{{barWidthCalculated}}</p>
</div>
</div>
My bar stays fixed at 100%, i dont see any interpolation on the DOM. I also established another NUMBER variable in my data section and attempted to pass that to my width property, but still no change, and no rendering on the DOM. However if I pass any other elements in my styles object such as
color: 'red'
Those changes take place. Also if I pass my styles object a number directly ie...
barWidth: {
width: 50 +'%'
}
It displays correctly on the DOM.
What am I missing/doing wrong?

why not just use :
<div id="trackerBarActual" v-bind:style="barWidthCalculated">
computed: {
barWidthCalculated: function(){
return {
width: (this.numQuotes * 10) + '%',
color: 'red'
};
}

Related

Tooltip component rendering but not visible, and it is not the z-index

import React, {useState, useEffect} from "react";
// The tooltip component is used for the Tooltip feature that is utilized
const Tooltip = (couponProps) => {
const { couponTheme, verticalMousePosition, data, showTooltip, isSwiper } = couponProps;
const { TooltipText } = data;
const [tooltipStyles, setTooltipStyles] = useState({display: 'none'});
const [tooltipArrowStyles, setTooltipArrowStyles] = useState({display: 'none'});
const { TooltipTextColor, TooltipBackgroundColor, TooltipFontSize } = couponTheme;
// The useEffect hook will first define all the tooltip styling as objects. If the showTooltip variable defined in the parent element is active, render the tooltip.
useEffect(() => {
const topTooltipStyles = {
bottom: '130%',
left: '20%',
right: '20%',
width: '60%'
}
const topTooltipArrowStyles = {
top: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: (TooltipBackgroundColor || 'black') + ' transparent transparent transparent',
marginTop: 'unset'
}
const bottomTooltipStyles = {
top: '125%',
left: '20%',
right: '20%',
width: '60%'
}
const bottomTooltipArrowStyles = {
bottom: '100%',
left: '50%',
marginLeft: '-5px',
borderColor: 'transparent transparent ' + (TooltipBackgroundColor || 'black') + ' transparent'
}
if (showTooltip) {
// The tooltip is configured to either render at the top of the interval bar or at the bottom of the interval bar. That is pased on where the mouse is located on the screen.
let tooltipPositionStyles = {};
let tooltipArrowPositionStyles = {};
// If the vertical mouse position is less than 250px to the top, render the tooltip at the bottom under the parent componet. This means the user is at the top of the screen, so use the bottom styling.
if (verticalMousePosition < 250 || isSwiper) {
// This way, the tooltip will not be cut of from the top of the screen.
tooltipPositionStyles = bottomTooltipStyles;
tooltipArrowPositionStyles = bottomTooltipArrowStyles;
// Else, that means the user is not at the top of the screen
} else {
tooltipPositionStyles = topTooltipStyles;
tooltipArrowPositionStyles = topTooltipArrowStyles;
}
const tooltipArrowStylesObj = {
content: ' ',
position: 'absolute',
borderWidth: '5px',
borderStyle: 'solid',
...tooltipArrowPositionStyles
}
const tooltipStylesObj = {
position: 'absolute',
color: TooltipTextColor || 'white',
background: TooltipBackgroundColor || 'black',
padding: '10px',
borderRadius: '10px',
zIndex: '5000',
textAlign: 'center',
...tooltipPositionStyles
}
// Set all of the arrow styles after determining if the tooltip is on top or on bottom.
setTooltipArrowStyles(tooltipArrowStylesObj);
setTooltipStyles(tooltipStylesObj);
} else {
// If the showTooltip variable is false, hide the tooltip.
setTooltipArrowStyles({});
setTooltipStyles({display: 'none'});
}
}, [showTooltip, verticalMousePosition, TooltipBackgroundColor, TooltipTextColor, isSwiper])
return (
<>{TooltipText !== undefined && TooltipText.trim() !== '' && TooltipText !== 'None' && TooltipText !== 'Inset Tooltip Text Here' && showTooltip ?
<div className='TooltipDiv' style={tooltipStyles}>
<span className="ToolTipText" style={{fontSize: TooltipFontSize || '12px'}}>{TooltipText}</span>
<span className="ToolTipArrow" style={tooltipArrowStyles}></span>
</div>
: null}</>
);
}
export default Tooltip;
So the code is passed the vertical mouse position as a prop and if the mouse is within 250 from the top of the page the tooltip is rendered below the component hovered. It all works fine if the component renders above and the mouse is lower down the page because there is nothing above to obstruct the tooltip, but when the component renders below, with bottomTooltipStyles, it is absolutely positioned but the issue is it is rendering behind another component. My gut said it was obviously the z-index, but this tooltip has a zIndex of 5000 which is significantly larger than the next largest z-index on the page at 60. Checking google chrome dev tools, the styles are all appropriate, the component renders, but it is still somehow behind/hidden behind another component no matter what I do. Any ideas would be greatly appreciated!! Thanks in advance!
So my question can also be asked like, "Is there a css property that would cause an element to render 'above' (over) another element that has an arbitrarily high z-index?"
Most of the gotchas with z-index have to do with "stacking context".
Elements are stacked on the z-axis within their stacking context.
Elements without position or explicit z-index values all share the same stacking context and are rendered in order of appearance in the rendered HTML.
Here are some specific z-index gotchas related to stacking context that may be affecting you:
1. z-index only applies to positioned elements
That is, position: absolute, position: relative, position: fixed, or position: sticky) and flex items. [1]
So first, make sure the elements you want to position on the z-axis are all explicitly positioned.
2. Some css properties can move an element into a new stacking context.
Some common ones are opacity and transform. Here is a list of CSS properties that can affect the stacking context.
And here is a detailed explanation on how opacity values affect stacking context:
Since an element with opacity less than 1 is composited from a single
offscreen image, content outside of it cannot be layered in z-order
between pieces of content inside of it. For the same reason,
implementations must create a new stacking context for any element
with opacity less than 1. If an element with opacity less than 1 is
not positioned, then it is painted on the same layer, within its
parent stacking context, as positioned elements with stack level 0. If
an element with opacity less than 1 is positioned, the ‘z-index’
property applies as described in [CSS21], except that if the used
value is ‘auto’ then the element behaves exactly as if it were ‘0’. [2]
To fix these, explicitly set the position and z-index so that they will be evaluated relative to the other positioned elements.
3. If an element's parent z-index (and position) is set, then that element's z-index will only apply within the parent.
In other words, the parent element is the stacking context.
To fix this, you can either modify the HTML hierarchy, or remove the position of the parent, or modify its z-index.
There are some good visuals and code examples for these situations here: https://www.freecodecamp.org/news/4-reasons-your-z-index-isnt-working-and-how-to-fix-it-coder-coder-6bc05f103e6c/
I had the same issue when rendering multiple components in one parent component. My popup div didn't appear on top of other components even though it had a higher z-index.
After a little bit of research, I found this answer helpful.
I had to move the popup component above everything else.
Also, please fix your code snippet so we can find out exactly what's wrong.

Adding a reference point to a Jquery Slider

I have created a data entry web application using asp mvc where the user can submit a record of their wellbeing. The data is saved to a SQL database and everything is working fine however, I would like to add a fixed reference point on the jQuery slider itself to show the user their most recent score. Maybe in the form of an additional fixed handle at the corresponding value...however I'm very new to javascript and have tried and failed so far.
Here is a screen shot of my sliders
The numbers at the bottom show the values for the previous entry
I have posted my JS code for the sliders below. Any help would be much appreciated.
$(function() {
var handle = $("#pain-handle");
$("#painSlider").slider({
min: 0,
max: 10,
value: 0,
animate: "fast",
create: function() {
handle.text($(this).slider("value"));
}
}
);
$("#painSlider").slider().slider("pips", {
labels: {
first: "No Symptoms",
last: "Worst Symptoms"
}
}
).on("slidechange", function(e, ui) {
$("#pain-handle").text(ui.value);
}
);
}
);
so it seems like you need to make specific pips visible. Just for information; the slider always has values, but the css hides them. So we just need to make the correct pips visible.
The steps are;
figure out the correct values (suggest to put them as html-data)
add a cssClass to those values
use css to display the correct pips (style accordingly)
Firstly, I've amended your JS a little so that you're using the float plugin for the pips to display the values on the slider handles. It'll be a little more robust than your solution. $(".slider").slider("float"); You can read about it here; https://simeydotme.github.io/jQuery-ui-Slider-Pips/#options-float
the final js code is;
$(function() {
// here we assume 4 sliders all with the same css class
var $sliders = $(".painSlider");
$sliders.each( function(k, el) {
var $slider = $(el);
var previousValue = $slider.data( "previous" );
// handle different labels for best/worst
var firstLabel = $slider.hasClass( "bestWorst" ) ? "Best Imaginable" : "No Symptoms";
var lastLabel = $slider.hasClass( "bestWorst" ) ? "Worst Imaginable" : "Worst Symptoms";
$slider.slider({
min: 0,
max: 10,
value: 0,
animate: "fast"
})
.slider("pips", {
labels: {
first: firstLabel,
last: lastLabel
}
})
.slider("float")
// add a css class to the correct values
// so that we can style them to be shown
.find(".ui-slider-pip")
.eq( previousValue )
.find( ".ui-slider-label" )
.addClass( "previous-value" );
});
});
and then there's a little bit of css to apply;
/* this is the magic to show the value */
.ui-slider-label.previous-value {
display: block;
}
/* these two styles are to show the "float"
labels inside the handle, instead of using
your own custom handle-text. */
.ui-slider-tip {
visibility: visible!important;
opacity: 1!important;
transform: none!important;
position: static!important;
background: transparent!important;
border: none!important;
color: white!important;
margin: auto!important;
width: auto!important;
}
.ui-slider-tip::before,
.ui-slider-tip::after {
display: none!important;
}
the fully, working code, is viewable here; https://jsfiddle.net/vzw53dge/

Why does binding not work in JS code (QML)?

There's a kind of reusable element that have the property of Rectangle type:
property Item middleRegion: Rectangle {
color: "grey";
border.width: 1;
height: line.height;
parent: line
}
Then, if an user defines own middleRegion, onMiddleRegionChanged() is called:
onMiddleRegionChanged: {
middleRegion.parent = line
middleRegion.height = line.height
}
But, despite of the fact that line.height is changed, middleRegion.height isn't changed after it. Why does binding not work in this code?
The important thing that if user doesn't defined middleRegion, everything's going well.
I've found the answer by myself.
According to the example from Qt documentation the problem is solved by using Qt.binding():
import QtQuick 2.0
Rectangle {
width: 100
height: width * 2
focus: true
Keys.onSpacePressed: {
height = Qt.binding(function() { return width * 3 })
}
}

How to use Ember Liquid-Fire to transition between two elements with different font sizes

I'm using Ember and Liquid Fire to create some interesting material-design-inspired animated transitions between routes.
I've created two transitions. The first occurs during the transition from the index route to the about route and uses the explode, flyTo, and toLeft transitions successfully. Here I match by a data-nav attribute on both routes to create a smooth, seamless transition that makes the matched element appear to move across the screen to the next page as it flies left. Thumbs up!
The second occurs during the transition from the about route back to the index route. Here I match a different element than above by a data-text attribute on both routes, however unlike the example above, the elements are not identical. Specifically, the font-size is different. Unfortunately this has an undesired effect of immediately displaying the larger font-size text and then having it fly across the page.
What I'd like to do is add an additional transition that animates the font-size. Sounds simple enough.
Below is my initial transitions.js file with the two transitions described above.
export default function() {
var duration = 1000;
this.transition(
// --------------------- INDEX to ABOUT ----------------------------------- //
this.fromRoute('index'),
this.toRoute('about'),
this.use('explode', {
matchBy: 'data-nav',
use: [ 'flyTo', { duration } ]
}, {
use: [ 'toLeft', { duration } ]
}),
// --------------------- ABOUT to INDEX ----------------------------------- //
this.reverse('explode', {
matchBy: 'data-text',
use: [ 'flyTo', { duration } ]
}, {
use: [ 'toRight', { duration } ]
})
);
}
I believe the answer is to create my own custom transition, however it is turning out to be rather challenging. I created a custom transition called scale-font.js and added it to my transitions.js file for this transition.
import { animate, Promise } from "liquid-fire";
export default function scaleFont(opts={}) {
// returns a Promise that resolves when the transition is done
if (!this.newElement) {
return Promise.resolve();
} else if (!this.oldElement) {
this.newElement.css({visibility: ''});
return Promise.resolve();
}
var oldFontSize = this.oldElement.css('font-size');
var newFontSize = (opts.selector ? this.newElement.find(opts.selector) : this.newElement).css('font-size');
this.newElement.css({ visibility: 'hidden' });
return animate(
this.oldElement,
{ fontSize: oldFontSize },
{ duration: 1000 }
).then(() => {
return animate(
this.newElement,
{ fontSize: newFontSize },
{ duration: 1000, visibility: 'visible' }
);
});
}
Unfortunately this doesn't quite work. The first problem is that the oldFontSize is not correct. It ends up grabbing the new font size. The second problem is no font scaling occurs.
I've researched animating fonts, so I am fairly certain it can be done. Suggestions?

Renaming flot pie chart ID

I'm trying to create a pie chart through the use of flot charts. I have successfully managed to create one with the following code:
HTML:
<div class="row">
<div class="col-md-6">
<div id="pie-chart"></div>
</div>
</div>
Javascript:
var data = [];
data[0] = { label: "Vertification successful", data: 9 };
data[1] = { label: "Vertification failed", data: 2 };
var series = Math.floor(Math.random() * 10) + 1;
$.plot($("#pie-chart"), data,
{
series: {
pie: {
show: true,
}
},
grid: { hoverable: true },
});
And it displays just fine.
The thing is, if I change the ID of the div element to "pie-chart1" (rather than "pie-chart")
and update the javascript accordingly:
$.plot($("#pie-chart1"), data,
I get the following error:
Uncaught Invalid dimensions for plot, width = 501, height = 0
What on earth could be causing this? I simply wanna rename the ID which apparently for some reason is impossible.
It's very likely that there is some CSS or possibly JS elsewhere on your site that expects the div to be called pie-chart. You need to ensure that it still applies to the new div. For example, if you had:
#pie-chart {
width: 400px;
height: 300px;
}
When you change the ID of the div, you need to update that reference too, or else the placeholder's height and width become undefined, which Flot cannot handle.
If your goal in adding that number is to create several charts, then you should use a class to apply the styles rather than an ID.

Categories