Howe to add opacity when change object property - javascript

i have next example https://codepen.io/mihail-kuznecow/pen/mjoYzz
It's animejs library, https://github.com/juliangarnier/anime.
Codesnippet example:
const members = [{
name: "Вася Пупки"
}, {
name: "Дмитрий Васильев"
}, {
name: "Анатолий Вассерман"
}, {
name: "Петросян Вазгенович"
}, {
name: "Гоша Вазгенович"
}, {
name: "Миша Вазгенович"
}, {
name: "Саша Вазгенович"
}, {
name: "Анатолий Вазгенович"
}, {
name: "Энакентий Вазгенович"
}, {
name: "Динис Вазгенович"
}, {
name: "Иван Вазгенович"
}, {
name: "Руслан Вазгенович"
}, {
name: "Богдан Вазгенович"
}, {
name: "Костян Вазгенович"
}];
window.onload = function() {
const button = document.getElementById('start');
if(button){
button.addEventListener('click', () => rollNames(document.querySelector('.name'), members));
}
function rollNames(domNode, names) {
const animatedName = {value: 0};
let name;
if (domNode) {
anime({
targets: [animatedName, domNode],
value: names.length - 1,
round: 1,
easing: 'easeInOutCirc',
duration: 5000,
update: function(a) {
if(name != names[animatedName.value].name) {
a.animatables[1].target.style.opacity = 0;
}else{
a.animatables[1].target.style.opacity = 1;
}
domNode.innerText = names[animatedName.value].name;
name = names[animatedName.value].name;
}
});
//return anime.finished;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="test">
<div class="name">
Hello!
</div>
</div>
<button id="start">Start roll</button>
You can see, name change with flash, i would like to this flash was changed smoothly for each name.
Maybe I should take callbacks or timeline, but all my attempts are not successful.
How i can do it?

This took me a while, but I think I finally have something that you were looking for. You will have to mess around with it a little bit more to get it perfect but I think it's pretty close to what you were asking. The few things I changed was the easing to linear and the duration to 14000 (14 names, 1 name per second). I then used jquery's animate to have a sort of fade in/fade out for each name. You will have to tweak the timing a little but I think basically it is a good example of what you were asking (I hope). Also, here is the modified codepen: https://codepen.io/anon/pen/ZjZYWM
const members = [{
name: "Вася Пупки"
}, {
name: "Дмитрий Васильев"
}, {
name: "Анатолий Вассерман"
}, {
name: "Петросян Вазгенович"
}, {
name: "Гоша Вазгенович"
}, {
name: "Миша Вазгенович"
}, {
name: "Саша Вазгенович"
}, {
name: "Анатолий Вазгенович"
}, {
name: "Энакентий Вазгенович"
}, {
name: "Динис Вазгенович"
}, {
name: "Иван Вазгенович"
}, {
name: "Руслан Вазгенович"
}, {
name: "Богдан Вазгенович"
}, {
name: "Костян Вазгенович"
}];
window.onload = function() {
const button = document.getElementById('start');
if(button){
button.addEventListener('click', () => rollNames(document.querySelector('.name'), members));
}
function rollNames(domNode, names) {
const animatedName = {value: 0};
let name;
if (domNode) {
anime({
targets: [animatedName, domNode],
value: names.length - 1,
round: 1,
easing: 'linear',
duration: 14000,
update: function(a) {
if(name != names[animatedName.value].name) {
$(a.animatables[1].target).animate({opacity:'+=1'}, 500)
if(a.animatables[1].target.style.opacity > 0 ){
$(a.animatables[1].target).animate({opacity:'-=1'}, 500) //fades out
}
else{
$(a.animatables[1].target).animate({opacity:'+=1'}, 500)//fades in
$(a.animatables[1].target).animate({opacity:'-=1'}, 500)//fades out
}
}
else{
}
domNode.innerText = names[animatedName.value].name;
name = names[animatedName.value].name;
}
});
//return anime.finished;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">
<div class="name">
</div>
</div>
<button id="start">Start roll</button>

Related

How to calculate Total Amount by Change Status Debit or Credit from array in components in Vue3 JS

I have one Amount column in my table and I want to calculate total debit, total credit, total remaining amount by chnage in status of dropdown debit and credit.
if dropdown selection is debit then "Remaining=Amount-current Amount" and
if dropdown selection is credit then add amount in remaining balance, This Is My Code. Please help I'm new in Vuejs
<script>
import Breadcrumb from "primevue/breadcrumb";
import Button from "primevue/button";
import InputText from "primevue/inputtext";
import Calendar from "primevue/calendar";
import Dropdown from "primevue/dropdown";
import InputNumber from "primevue/inputnumber";
import { ref, reactive } from "vue";
import { computed } from "#vue/reactivity";
export default {
name: "CashPayementVoucher",
components: {
Button,
InputText,
Calendar,
Dropdown,
InputNumber,
Breadcrumb,
},
setup() {
const home = ref({ icon: "pi pi-home", to: "/" });
const items = ref([
{ label: "Vouchers" },
{ label: "Cash Payement Voucher" },
]);
const accountsData = ref([
{ name: "0987-12345678-1", value: "0987-12345678-1" },
{ name: "0987-12345678-2", value: "0987-12345678-2" },
{ name: "0987-12345678-3", value: "0987-12345678-3" },
{ name: "0987-12345678-4", value: "0987-12345678-4" },
{ name: "0987-12345678-5", value: "0987-12345678-5" },
]);
const projectsData = ref([
{ name: "Blue World City", value: "Blue World City" },
{ name: "Estate 92", value: "Estate 92" },
{ name: "Atlantics City", value: "Atlantics City" },
{ name: "Park View City", value: "Park View City" },
{ name: "Bahria Town", value: "Bahria Town" },
]);
const usersData = ref([
{ name: "Ali Suleman", value: "Ali Suleman" },
{ name: "Muhammad Khan", value: "Muhammad Khan" },
{ name: "Sheraz Ahemad", value: "Sheraz Ahemad" },
{ name: "Mehbob Sultan", value: "Mehboob Sultan" },
{ name: "Usama Javeed", value: "Usama javeed" },
{ name: "Shoaib Khan", value: "Shoaib Khang" },
]);
const payementType = ref([
{ name: "Debit", value: 1 },
{ name: "Credit", value: 0 },
]);
const invoice = reactive({
account: "",
date: "",
projects: "",
payeeName: "",
amount: 0,
details: [
{
account: "",
name: "",
description: "",
debit_credit: 1,
amount: 0,
},
],
totalCredit: 0,
totalDebit: 0,
difference: 0,
});
const addnewRow = () => {
invoice.details.push({
account: "",
name: "",
description: "",
debit_credit: "",
amount: 0,
});
};
const removeRow = (index) => {
invoice.details.splice(index, 1);
};
const postData = () => {
console.log("Hello I'm Here 'Cash Payement Voucher'", invoice);
};
const remaining =computed(() => {
return (
invoice.amount +
invoice.details.reduce(function (prevTotal, detail) {
let temp = detail.debit_credit > 0 ? detail.amount * -1 : detail.amount * 1;
return +prevTotal + temp;
}, 0)
);
});
return {
home,
items,
accountsData,
projectsData,
usersData,
payementType,
invoice,
addnewRow,
removeRow,
postData,
remaining
};
},
};
</script>
Image Link
https://i.stack.imgur.com/zkdOZ.png
Please on the next question insert only important code for your problem it's easier to analyze code. To solve your problem create computed property which will return data depending on dropdown choose.
computed() {
calculateValue() {
if (this.details[0].debit_credit === 'Debit') {
return //enter your equation for debit option i can't find currentAmount data
else if (this.details[0].debit_credit === 'Credit') {
return //enter your equation for credit option
}
return null
}
}
}
Then you can display calculateValue anywhere in HTML code:
<template>
<div> Balance: {{calculateValue}} </div>
</template>

run function with uniquie value using javascript / node js

let object=
[
{
id:`01`,
name:`fish`,
type:null,
care:'owner',
},
{
id:`02`,
name:`fish`,
type:'fresh',
care:'peter',
},
{
id:`03`,
name:`fish`,
type:`fresh`,
care:'amy',
},
{
id:`04`,
name:`fish`,
type:`tank`,
care:'abc',
},
{
id:`05`,
name:`animal`,
type:`pet`,
care:'teen',
},,
{
id:`06`,
name:`animal`,
type:`pet`,
care:'ran',
},
{
id:`07`,
name:`animal`,
type:null,
care:'roh',
},
{
id:`08`,
name:`food`,
type:`veg`,
care:'test',
},
{
id:`09`,
name:`food`,
type:null,
care:'dop',
}
]
object.map((value)=>{
console.log(value.name)
// i am calling function here by passing value.name as a parameter
let gotValue = functionName(value.name);
// using type also
if(typeof value.type!=="string"){
// Do some task here with gotValue
}
})
I have this object and i am getting some value from it for ex getting name from it as i want to pass this name to function but the problem is due to repeat of data the function calling again and again is there any possibility i can run function inside map but with unique value any help ?
as my output is getting like this
fish
fish
fish
animal
animal
animal
and this value.name is passing inside my function so its repeating like this
functionName(fish);
functionName(fish);
functionName(fish);
functionName(animal);
functionName(animal);
functionName(animal);
multiple time function is running with same name and getting duplicate values
just need my function run with unique name
functionName(fish)
functionName(animal);
functionName(food);
as i want to stay inside map function because i am performing some task which can only be possible inside map that's why i need unique value
You can use Set which can be used to test if the object with value already exists or not. It will only call the function only once.
let object = [
{
id: `01`,
name: `fish`,
type: null,
},
{
id: `02`,
name: `fish`,
type: `fresh`,
},
{
id: `03`,
name: `fish`,
type: `tank`,
},
{
id: `04`,
name: `animal`,
type: `pet`,
},
{
id: `05`,
name: `animal`,
type: `wild`,
},
{
id: `06`,
name: `animal`,
type: null,
},
{
id: `07`,
name: `food`,
type: `veg`,
},
{
id: `08`,
name: `food`,
type: null,
},
];
const dict = new Set();
object.map((value) => {
if (!dict.has(value.name)) { // Run only if objet with name is not already existed in dict
dict.add(value.name);
console.log(value.name); // For testing
// functionName(value.name);
}
});
If you want to call the function with two filters then you can use some to find the elements in an array. See I've now declared dict as an array
let object = [{
id: `01`,
name: `fish`,
type: null,
},
{
id: `02`,
name: `fish`,
type: `fresh`,
},
{
id: `03`,
name: `fish`,
type: `tank`,
},
{
id: `04`,
name: `animal`,
type: `pet`,
},
{
id: `05`,
name: `animal`,
type: `wild`,
},
{
id: `06`,
name: `animal`,
type: null,
},
{
id: `07`,
name: `food`,
type: `veg`,
},
{
id: `08`,
name: `food`,
type: null,
},
{
id: `09`,
name: `food`,
type: null,
},
{
id: `10`,
name: `fish`,
type: `tank`,
},
];
const dict = [];
object.map((value) => {
const { name, type } = value;
if (!dict.some((obj) => obj.name === name && obj.type === type)) {
// Run only if objet with name is not already existed in dict
dict.push({ name, type });
console.log(name, type); // For testing
// functionName(value.name);
}
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

Add tasks for todo list

I am trying to add tasks for each todo list that has a specific title.
Can I get a specific todo list by its id and add some tasks to it?
I am new to javascript, so I searched google about adding lists for a specific list with no results :(
class Model {
constructor() {}
this.todos = [
{
id: 1,
title: 'Outside',
text: 'Running',
complete: false,
tasks: [
{ id: 1, text: 'Run a marathon', complete: false},
{ id: 2, text: 'Run with freinds', complete: false}
]
},
{
id: 2,
title: 'Garden',
text: 'Plant',
complete: false,
tasks: [
{ id: 1, text: 'Plant a garden', complete: false},
{ id: 2, text: 'Water the garden', complete: false}
]
}];
addTodo(todoText) {
const todo = {
id: this.todos.length > 0 ? this.todos[this.todos.length - 1].id + 1 : 1,
text: todoText,
complete: false,
tasks: []
}
this.todos.push(todo)
}
}
Is it true to do like addTodo function for adding a tasks for a specific todo list like this?
addTodoTask(todoTaskText) {
const todoTask = {
id: this.todos.tasks.length > 0 ? this.todos[this.todos.tasks.length - 1].id + 1 : 1,
text: todoText,
complete: false,
}
this.todos.tasks.push(todoTask)
}
and how to add a list of a list in javascript like:
<ul>
<li>Running
<ul>
<li>Run a marathon</li>
<li>Run with freind</li>
</ul>
</li>
</ul>
You could make each class handle rendering its own content and just map the list items consecutively while rendering from the top-down.
Edit: The render() methods make use of ES6 template literals. These are special strings that allow you embed variabes and expressions without the use of string concatenation.
const main = () => {
let todoList = new TodoList({ todos : getData() })
document.body.innerHTML = todoList.render()
}
class TodoTask {
constructor(options) {
this.id = options.id
this.text = options.text
this.complete = options.complete
}
render() {
return `<li>[${this.id}] ${this.text} (${this.complete})</li>`
}
}
class TodoEntry {
constructor(options) {
this.id = options.id
this.title = options.title
this.text = options.text
this.complete = options.complete
this.tasks = []
if (options.tasks) {
options.tasks.forEach(task => this.addTask(task))
}
}
addTask(task) {
this.tasks.push(new TodoTask(Object.assign({
id : (this.tasks.length || 0) + 1
}, task)))
}
render() {
return `<li>
[${this.id}] ${this.title} (${this.complete})
<ul>${this.tasks.map(task => task.render()).join('')}</ul>
</li>`
}
}
class TodoList {
constructor(options) {
this.todos = []
if (options.todos) {
options.todos.forEach(todo => this.addTodo(todo))
}
}
addTodo(todo) {
this.todos.push(new TodoEntry(Object.assign({
id : (this.todos.length || 0) + 1
}, todo)))
}
render() {
return `<ul>${this.todos.map(todo => todo.render()).join('')}</ul>`
}
}
function getData() {
return [{
id: 1,
title: 'Outside',
text: 'Running',
complete: false,
tasks: [{
id: 1,
text: 'Run a marathon',
complete: false
}, {
id: 2,
text: 'Run with freinds',
complete: false
}]
}, {
id: 2,
title: 'Garden',
text: 'Plant',
complete: false,
tasks: [{
id: 1,
text: 'Plant a garden',
complete: false
}, {
id: 2,
text: 'Water the garden',
complete: false
}]
}]
}
main() // entry
To add a task your todo, you should have a way of knowing which todo list you're updating. Like using the todo's id.
For example your addTaskToTodo will looks like so.
addTask(todoId, taskObject) {
// find that todos index
const todoIndex = this.todos.findIndex(todo => todo.id ===todoId);
// using that index update the tasks
this.todos[todoIndex].tasks.push(taskObject)
}
This assumes your taskObject already has all the properties. If you need to manually update its id, you can also do that before pushing by checking the length of the tasks and incrementing by 1.
I made an example of how to use dictionaries instead of arrays, and also a random ID. I think you will find it much cleaner and simpler:
class Model {
constructor() { }
todos = {
1: {
id: 1,
title: 'Outside',
text: 'Running',
complete: false,
tasks: {
1: { id: 1, text: 'Run a marathon', complete: false },
2: { id: 2, text: 'Run with freinds', complete: false }
}
},
2: {
id: 2,
title: 'Garden',
text: 'Plant',
complete: false,
tasks: {
1: { id: 1, text: 'Plant a garden', complete: false },
2: { id: 2, text: 'Water the garden', complete: false }
}
}
}
getRandomId = () => {
return '_' + Math.random().toString(36).substr(2, 9);
}
addTodo(todoText) {
const id = this.getRandomId();
const todo = {
id,
text: todoText,
complete: false,
tasks:{}
}
this.todos[id] = todo;
}
addTodoTask(todoTaskText,todoId) {//Pass also the id of the todo, to know where this task belongs to.
const id = this.getRandomId();
const todoTask = {
id,
text: todoTaskText,
complete: false,
}
this.todos[todoId].tasks[id] = todoTask
}
}
This way you could easily edit/remove both todos and tasks, just by their id, without using any messy Array.filter and such

Vue.js - Only display false array elements

If I have code like the code below in my vue.js, upon clicking a button, how can I only display the array item I clicked ( for e.g, Donnie) and hide all of the rest? (Joanne, Peter e.t.c), then when you click the only displayed element again, make all of the other array elements display again?
const app = new Vue({
el: '#app',
data: {
keyword: '',
friends: [
{
name: "Donnie",
age: "20"
},
{
name: "Joanne",
age:"19",
},
{
name: "David",
age: "26"
},
{
name: "Peter",
age: "23"
},
{
name: "John",
age: "29"
},
{
name: "Jason",
age: "19"
},
],
},
computed: {
filteredList() {
return this.friends.filter((friend) => {
return friend.name.toLowerCase().includes(this.keyword) + friend.age.includes(this.keyword) + friend.name.includes(this.keyword);
});
}
},
methods:{
exclude(friend) {
console.log(!friend.name);
},
}
})
HTML
<div v-for="friend in filteredList" class="card" #click="exclude(friend)">
{{friend.name}} - {{friend.age}}
</div>
You should be able to add an identity check to your filter expression if an item has been clicked.
Start by adding a property to store the clicked friend. I'll call mine selected
data {
selected: null,
keyword: '',
//etc
}
Then in your exclude method
exclude (friend) {
this.selected = this.selected ? null : friend
}
now your computed property can filter the list based on the selected friend first, then fall back to the keyword match
filteredList () {
return this.selected ? [this.selected] : this.friends.filter(friend => {
let search = this.keyword.trim().toLowerCase()
return friend.name.toLowerCase().includes(search) || friend.age.includes(search)
})
}
I think that's what you're looking for:
const app = new Vue({
el: '#app',
data: {
keyword: '',
friends: [
{
name: "Donnie",
age: "20"
},
{
name: "Joanne",
age:"19",
},
{
name: "David",
age: "26"
},
{
name: "Peter",
age: "23"
},
{
name: "John",
age: "29"
},
{
name: "Jason",
age: "19"
},
],
selected: null
},
computed: {
filteredList() {
if (!this.selected) {
return this.friends.filter((friend) => {
return friend.name.toLowerCase().includes(this.keyword) + friend.age.includes(this.keyword) + friend.name.includes(this.keyword);
});
} else {
return [this.selected];
}
},
},
methods:{
exclude(friend) {
if(!this.selected) {
this.selected = friend;
} else {
this.selected = null;
}
},
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<div v-for="friend in filteredList" class="card" #click="exclude(friend)">
{{friend.name}} - {{friend.age}}
</div>
</div>
The trick here is that the selected data property store the friend and also doubles as a checker if there's a friend, so if not, show all, if is, show only that one.

How to disable focus for an option in `dijit/form/Select`?

I need to change behavior for a widget dijit/form/Select.
Widget should not allow focus (from mouse or using the keyboard) for options which have property disabled: true.
I would like to know if you can point me out how to achieve this result.
require([
'dijit/form/Select',
'dojo/_base/window',
'dojo/domReady!'
], function(Select, win) {
var select = new Select({
name: 'select2',
options: [{
label: '<i>Swedish Cars</i>',
value: '',
disabled: true
},
{
label: 'Volvo',
value: 'volvo'
},
{
label: 'Saab',
value: 'saab',
selected: true
},
{
label: '<i>German Cars</i>',
value: '',
disabled: true
},
{
label: 'Mercedes',
value: 'mercedes'
},
{
label: 'Audi',
value: 'audi'
}
]
}, 'select');
select.on('change', function(evt) {
console.log('myselect_event');
});
});
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dijit/themes/claro/claro.css" />
<script>
window.dojoConfig = {
parseOnLoad: false,
async: true
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dojo/dojo.js"></script>
<body class="claro">
<div id="select"></div>
</body>
I was able to solve this issue using a monkey patch.
The solution consist into:
Adding markup in label so we can customize the look.
Adding property disabled:true in item options, so item won't fire onChange.
Disabling focus on group item when mouse and keyboard are used.
I still very interesting to know if another better/cleaner solutions exists.
require([
'dijit/form/Select',
'dojo/_base/window',
'dojo/domReady!'
], function(Select, win) {
var select = new Select({
name: 'select2',
options: [{
label: '<i>Swedish Cars</i>',
value: '',
group: true,
disabled: true
}, {
label: 'Volvo',
value: 'volvo'
}, {
label: 'Saab',
value: 'saab',
selected: true
}, {
label: '<i>German Cars</i>',
value: '',
group: true,
disabled: true
}, {
label: 'Mercedes',
value: 'mercedes'
}, {
label: 'Audi',
value: 'audi'
}]
}, 'select');
select.on('change', function(value) {
alert(value);
});
select.dropDown._onUpArrow = function() {
this.dropDown.focusPrev()
}.bind(select);
select.dropDown._onDownArrow = function() {
this.dropDown.focusNext()
}.bind(select);
select.dropDown.focusNext = function() {
var next = this.dropDown._getNextFocusableChild(this.dropDown.focusedChild, 1);
var nextSuccessive;
var nextFinal;
if (next.option.group) {
var next = this.dropDown._getNextFocusableChild(this.dropDown.focusedChild, 1);
this.dropDown.focusChild(next);
nextSuccessive = this.dropDown._getNextFocusableChild(this.dropDown.focusedChild, 1);
nextFinal = nextSuccessive;
} else {
nextFinal = next;
}
this.dropDown.focusChild(nextFinal);
}.bind(select);
select.dropDown.focusPrev = function() {
var prev = this.dropDown._getNextFocusableChild(this.dropDown.focusedChild, -1);
var prevSuccessive;
var prevFinal;
if (prev.option.group) {
var prev = this.dropDown._getNextFocusableChild(this.dropDown.focusedChild, -1);
this.dropDown.focusChild(prev);
prevSuccessive = this.dropDown._getNextFocusableChild(this.dropDown.focusedChild, -1);
prevFinal = prevSuccessive;
} else {
prevFinal = prev;
}
this.dropDown.focusChild(prevFinal, true);
}.bind(select);
select.dropDown.onItemHover = function( /*MenuItem*/ item) {
if (item.option.group) {
item._set("hovering", false);
console.log('skip hover');
return;
}
if (this.activated) {
this.set("selected", item);
if (item.popup && !item.disabled && !this.hover_timer) {
this.hover_timer = this.defer(function() {
this._openItemPopup(item);
}, this.popupDelay);
}
} else if (this.passivePopupDelay < Infinity) {
if (this.passive_hover_timer) {
this.passive_hover_timer.remove();
}
this.passive_hover_timer = this.defer(function() {
this.onItemClick(item, {
type: "click"
});
}, this.passivePopupDelay);
}
this._hoveredChild = item;
item._set("hovering", true);
}.bind(select.dropDown);
select.dropDown._onItemFocus = function( /*MenuItem*/ item) {
if (item.option.group) {
return;
}
if (this._hoveredChild && this._hoveredChild != item) {
this.onItemUnhover(this._hoveredChild);
}
this.set("selected", item);
}.bind(select.dropDown);
});
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dijit/themes/claro/claro.css" />
<script>
window.dojoConfig = {
parseOnLoad: false,
async: true
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dojo/dojo.js"></script>
<body class="claro">
<div id="select"></div>
</body>

Categories