Creation of a timeline for all months per year - javascript

I have a problem. I have a timeline.
In this timeline I would like to indicate the whole events for each year. More precisely, I want to indicate all the months in the year that exist.
What is the best way to loop through all the months and years so that I don't have to repeat everything?
So I want to show all unique years on the one hand and then all unique months.
During the months I would then like to display the individual dates.
import React, { useState, useEffect } from "react";
import { useHistory } from "react-router-dom";
function Event() {
events = [
{
eventid: 6,
name: "Event 1",
description: "This is the first event.",
date: "10.10.2023",
status: "XO",
},
{
eventid: 8,
name: "Event 2",
description: "This is a another event",
date: "14.01.2023",
status: "XO",
},
{
eventid: 8,
name: "Event 3",
description: "This is the last event",
date: "14.03.2024",
status: "OS",
},
];
const result = {};
for (let e of res.data) {
const [_, m, y] = e.datum.split(".");
const yn = parseInt(y);
const mn = parseInt(m);
if (!result[yn]) result[yn] = [];
if (!result[yn].includes(mn)) result[yn].push(mn);
}
for (let y in result) {
result[y] = result[y]
.sort()
.map((m) =>
new Date(2020, m - 1, 1).toLocaleString("en-US", { month: "long" })
);
}
return (
<div>
<div className="timeline is-centered">
<header className="timeline-header">
<span className="tag is-medium is-primary">2023</span>
</header>
<div className="timeline-item is-primary">
<div className="is-primary"></div>
<div className="timeline-content"></div>
</div>
<header className="timeline-header ">
<span className="tag is-primary">January</span>
</header>
<div className="timeline-item is-primary">
<div className="timeline-marker is-primary is-danger is-icon">
<i className="fa fa-flag"></i>
</div>
<div className="timeline-content">
<p className="heading">14. January</p>
<p>Event 2</p>
<p>This is a another event.</p>
</div>
</div>
<header className="timeline-header ">
<span className="tag is-primary">October</span>
</header>
<div className="timeline-item is-primary">
<div className="timeline-marker is-primary is-danger is-icon">
<i className="fa fa-flag"></i>
</div>
<div className="timeline-content">
<p className="heading">10. Januar</p>
<p>Event 1</p>
<p>This is the first event.</p>
</div>
</div>
<header className="timeline-header">
<span className="tag is-medium is-primary">2024</span>
</header>
<div className="timeline-item is-primary">
<div className="is-primary"></div>
<div className="timeline-content"></div>
</div>
<header className="timeline-header ">
<span className="tag is-primary">March</span>
</header>
<div className="timeline-item is-primary">
<div className="timeline-marker is-primary is-danger is-icon">
<i className="fa fa-flag"></i>
</div>
<div className="timeline-content">
<p className="heading">14. Januar</p>
<p>Event 3</p>
<p>This is the last event</p>
</div>
</div>
<header className="timeline-header"></header>
</div>
</div>
);
}
export default Event;
What I want

Related

How to keep appending instead of replacing

const Sheet = [
{
"Code": "A-0-1",
"UPC": "Photos/4009803054728.jpg",
"Title": "U.S.S. Constitution",
"Price": "$34",
"InStock": "7"
},
]
const productsEl = document.querySelector(".Sheet");
function getProducts() {
Sheet.forEach((product) => {
productsEl.innerHTML += `<div class="productContainer">
<div class="img">
<img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
</div>
<div class="itemdesc">
<h2 class="itemName" id="itemName">${product.Title}</h2>
<h4 class="price"><span id="price">${product.Price}</span></h4>
<div class="desc">
<p id="desc">${product.Code}</p>
</div>
<div class="stock">
<p> ${product.InStock} Units</p>
</div>
<div class="addToCart" onclick="addToCart(this);">
<button id="addToCart" > Add to Cart</button>
</div>
</div>`;
})
}
getProducts();
let numUnit = document.getElementById("#Unit")
let itemTitle = document.getElementById("item")
let itemPrice = document.getElementById("$Price")
function addToCart(button) {
const parent = button.closest('.productContainer'),
Title = parent.querySelector('#itemName')
Price = parent.querySelector('#price')
Code = parent.querySelector('#desc')
itemTitle.textContent = Title.innerText + ' ' + Code.innerText
itemPrice.textContent = Price.innerText
//numUnit.textContent = '1'
}
<div class="Sheet">
</div>
<div class="cartContainer">
<div class="cart">
<h3>Cart: <span id="allNum"> 0</span></h3>
</div>
<div class="itemUl">
<ul>
<li id="Units">Units:<span id="#Unit"></span></li>
<li id="Items">Item:<span id="item"></span></li>
<li id="Price">Price:<span id="$Price"></span></li>
</ul>
</div>
</div>
Currently, when I press addToCart the title and price go to my cart but then when I press it again it replaces it. How can I add it below instead of replacing it? I know there is a way to create elements but I was wondering if there is another way since my elements are already created.

Passing a axios request to a child component in vue.js

I am breaking my head in this. I am new to a fullstack project involving fullstack with vue.js and node.js.
My problem is: My get request is functioning and fetching data from database, but, I can't pass these data's via props on a component. It keeps telling that "paciente" is not defined.
Here's the code:
<div><div v-for="(paciente, index) in pacientes" :key="index">
<div class="blocoDeInformacao">
<h2 class="nomePessoa">{{paciente.nome}}</h2>
<h4 class="cpfPessoa">{{paciente.cpf}}</h4>
<div class="bordinha"></div>
<span class="botoes">
<button class="botao " #click="s1 = 1, bExcluir = false"><img class="icone" src="#/assets/paper.png" alt="editarPaciente"></button>
<button class="botao" #click="bExcluir = true, bCerto = paciente.id"><img class="icone" src="#/assets/trash.png" alt="excluirPaciente"></button>
</span>
<div class="excluir" v-show="bExcluir == true && bCerto == informacaoPessoa.id">
<img class="alertIcon" src="#/assets/alert.png" alt="iconeAlerta">
<h2 class="confirmacaoExclusao">Quer realmente excluir esse paciente?</h2>
<div>
<button class="botaoEscolha" #click="confirmacaoExcluir(paciente.idpaciente)">Sim</button>
<button class="botaoEscolha" #click="bExcluir = false">Não</button>
</div>
</div>
</div>
</div></div>
</div>
</div>
</div>
<div v-else-if="s1 == 1">
<editarPaciente :nomePessoa="paciente.nome"
:cpfPessoa="paciente.cpf" :senhaPessoa="paciente.senha" :id="paciente.idpaciente" :key="paciente.idpaciente"/>
</div>
and the props from components:
export default {
name: 'editarPaciente',
components: {
},
props: {
nomePessoa: String,
cpfPessoa: String,
senhaPessoa: String,
id: String
},
}
</script>

How to add a 'Sort By' dropdown to sort a list in Vuejs?

I've got a pretty straight forward setup.
Trying to display a list of users with a search box at the top (for actively filtering the search results).
If I use just that the page works and displays fine.
I'm trying to add in an additional dropdown to pick an attribute to sort by (and hopefully add in another dropdown to indicate ascending/descending once I get the first dropdown working).
My current code (with a non-working version of the sort) looks like this:
<div id="app">
<section class="mb-3">
<div class="container">
<h2>Person Search</h2>
<h3>
<small class="text-muted">Filter people based on the name, location or job</small>
</h3>
<h3>
<small class="text-muted">
Examples: “Jane Doe”, “ABC Building”, or “Math”
</small>
</h3>
<input type="text" class="form-control" v-model="search_term" placeholder="Begin typing to filter by name, location or job...">
<!-- THIS WOULD CAUSE THE LIST TO FILTER ALPHABETICALLY BY SELECTED ATTRIBUTE -->
<select id="sortFilterSelect" name="sort_filter" v-model="sort_filter">
<option value="">Sort By...</option>
<option value="first_name">First Name</option>
<option value="last_name">Last Name</option>
</select>
</div>
</section>
<section>
<div class="container">
<h3>People List : ([[ people_count ]] People)</h3>
<!-- I ADDED 'sortedPeople' HERE - WHICH BROKE IT -->
<div v-for="person in filteredPeople | sortedPeople">
<div class="card mb-4" :class="person.has_summative_past_due ? 'alert-warning' : ''">
<div class="card-body row" >
<div class="col">
<h4 class="card-title" v-bind:person='person.full_name'><a v-bind:href="'{% url 'commonground:index' %}' + 'users/' + person.id">[[ person.full_name ]]</a></h4>
<p v-if="person.active_summative" class="card-text">
Active Summative Due Date: [[ person.active_summative.due_date ]]
<span v-show="!person.active_summative.past_due" v-bind:past_due='person.active_summative.past_due' class="badge badge-success">[[ person.active_summative.due_date_status ]]</span>
<span v-show="person.active_summative.past_due" class="badge badge-danger">[[ person.active_summative.due_date_status ]]</span>
<ul class="list-group list-group-flush">
<li class="list-group-item justify-content-between align-items-center" v-for="summary in person.summative_evaluations_summary">
<span class="badge badge-secondary badge-pill">[[summary.evaluation_type__count]]</span> [[ summary.evaluation_type__name ]]
</li>
</ul>
</p>
<p v-if="!person.active_summative" class="card-text">
No Active Unlocked Summatives
</p>
<a v-if="person.active_summative" :href="person.active_summative.absolute_url" class="btn btn-primary"><i class="far fa-edit"></i> View / Edit Active Summative</a>
</div>
<div class="col-auto float-right text-right">
<p class="h5">
[[ person.base_location ]]
<div v-if="person.multiple_locations" class="small text-muted"><i class="fal fa-info-circle"></i> User has multiple locations</div>
</p>
<p class="h5">
[[ person.assignment_job ]]
<div v-if="person.multiple_jobs" class="small text-muted"> <i class="fal fa-info-circle"></i> User has multiple jobs</div>
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- END OF VUE -->
</div>
The actual Vue code looks like this:
<script>
const app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
data: {
people: [],
people_count: 0,
search_term: "",
sort_filter: "",
},
computed: {
filteredPeople:function()
{
var search = this.search_term.toLowerCase();
return this.people.filter(function(person){
return Object.values(person).some( val => String(val).toLowerCase().includes(search))
})
},
sortedPeople:function()
{
var sort_filter = this.sort_filter.toLowerCase();
console.log('triggered')
return this.people.filter(function(person){
return Object.values(person).some( val => String(val).toLowerCase().includes(sort_filter))
})
},
},
async created () {
var response = await fetch("{% url 'user-list' %}");
this.people = await response.json();
this.people_count = await this.people.length
}
})
</script>
Fairly new to Vue, but I am building this to learn. All help is appreciated!
Check out the simple sample I made: Link
filteredPeople() {
return this.people.filter(
(person) =>
person.firstname
.toLowerCase()
.includes(this.search.toLowerCase().trim()) ||
person.lastname
.toLowerCase()
.includes(this.search.toLowerCase().trim())
);
},
sortedPeople() {
return this.filteredPeople.sort((a, b) =>
a[this.sortby].localeCompare(b[this.sortby])
);
},
Added asc/dec order: Link
sortedPeople() {
return this.filteredPeople.sort((a, b) =>
(this.sort == 'asc') ? a[this.sortby].localeCompare(b[this.sortby]) : b[this.sortby].localeCompare(a[this.sortby])
);
},

Vue.js - on click collapse the nearest div

Below are some snippets of my code. Basically I have a few sections in my code to show some data and all these sections are collapsible. First load all sections expanded. On click on the chevron arrow, div -'ibox-content' will be collapsed.
How do I target only the nearest ibox to collapse? At moment when one arrow is clicked all sections are collapsed.
var vue = new Vue({
el: '#vue-systemActivity',
data: {
loading: false,
collapsed: false,
dateStart: '',
dateEnd: '',
status: 'fail',
msg: '',
meta: '',
data: ''
},
created: function() {
this.fetchData();
},
ready: function() {
this.fetchData();
},
methods: {
fetchData: function() {
var self = this;
if (self.dateStart != '' && self.dateEnd != '') {
this.loading = true;
$.get(baseUrl + '/backend/getSystemActFeed?dateStart=' + self.dateStart + '&dateEnd=' + self.dateEnd, function(json) {
self.data = json.data;
self.status = json.status;
self.meta = json.meta;
self.msg = json.msg;
}).always(function() {
self.loading = false;
});
}
}
}
});
");
<div v-if="data.events">
<div class="ibox float-e-margins" :class="[collapsed ? 'border-bottom' : '']">
<div class="ibox-title">
<h5>Events</h5>
<div class="ibox-tools">
<a v-on:click=" collapsed = !collapsed" class="collapse-link">
<i :class="[collapsed ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>
</a>
</div>
</div>
<div v-for="event in data.events" class="ibox-content inspinia-timeline" v-bind:class="{'is-collapsed' : collapsed }">
<div class="timeline-item">
<div class="row">
<div class="col-xs-3 date">
<i class="fa fa-calendar"></i> {{event.fDateStarted}}
<br/>
</div>
<div class="col-xs-7 content no-top-border">
<!-- <p class="m-b-xs"><strong>Meeting</strong></p> -->
<b>{{event.title}}</b> started on {{event.fDateStarted}} at {{event.at}}
</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="data.mentorBookings">
<div class="ibox float-e-margins" :class="[collapsed ? 'border-bottom' : '']">
<div class="ibox-title">
<h5>Mentorship</h5>
<div class="ibox-tools">
<a v-on:click=" collapsed = !collapsed" class="collapse-link">
<i :class="[collapsed ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>
</a>
</div>
</div>
<div v-for="mentorProgram in data.mentorBookings" class="ibox-content inspinia-timeline">
<div class="timeline-item">
<p class="m-b-xs"><strong>{{mentorProgram.programName}}</strong></p>
<div v-for="upcomingBooking in mentorProgram.upcomingBookings">
<div class="row">
<div class="col-xs-3 date">
<i class="fa fa-users"></i> {{upcomingBooking.fBookingTime}}
<br/>
</div>
<div class="col-xs-7 content no-top-border">
#{{upcomingBooking.id}} {{upcomingBooking.mentor.firstname}} {{upcomingBooking.mentor.lastname}} ({{upcomingBooking.mentor.email}}) mentoring {{upcomingBooking.mentee.firstname}} {{upcomingBooking.mentee.lastname}} ({{upcomingBooking.mentee.email}}) on
{{upcomingBooking.fBookingTime}} thru {{upcomingBooking.sessionMethod}}
<!--
<p><span data-diameter="40" class="updating-chart">5,3,9,6,5,9,7,3,5,2,5,3,9,6,5,9,4,7,3,2,9,8,7,4,5,1,2,9,5,4,7,2,7,7,3,5,2</span></p> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Each div should have each own collapsed state for control. You can turn collapsed into an array/object to control them.
simple example: https://codepen.io/jacobgoh101/pen/QQYaZv?editors=1010
<div id="app">
<div v-for="(data,i) in dataArr">
{{data}}<button #click="toggleCollapsed(i)">toggle me</button>
<span v-if="collapsed[i]">this row is collapsed</span>
<br/>
<br/>
</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
dataArr: ["data0", "data1", "data2"],
collapsed: [false, false, false]
},
methods: {
toggleCollapsed: function(i) {
this.$set(this.collapsed, i, !this.collapsed[i]);
}
}
});
</script>

AngularJS - passing a value to a function for the second time returns undefined

I'm new to Angular and on my way to learn while bulding a website I've stopped with a really stupid moment.
I have a function inside a controller that is supposed to be called on ng-click event, I'm passing an 'id' value to it and using that 'id' it's supposed to search an array of presenters(objects) returning and assigning to $scope.presenter the one that I'm looking for. The thing is that the functions works ok for the the first time, but when I'm trying to call it again using a next/previous button the console log returns that the 'id' is undefined. Here is the controller code:
angular.module('fpl15App').controller('PresentersCtrl', function ($scope, $filter) {
$('body').css({'overflow':'hidden'});
$scope.showDetails = false;
$scope.currentPresenter = {};
$scope.getPresenterDetails = function( presenterId ) {
var id = presenterId - 1;
console.log(id);
$scope.showDetails = true;
var i=0, len=$scope.presenters.length;
for (; i<len; i++) {
if (+$scope.presenters[i].id === +id) {
return $scope.currentPresenter = $scope.presenters[i];
}
}
return null;
};
$scope.hideOverlay = function(){
$scope.showDetails = false;
};
$scope.presenters = [
{
id: 1,
name: 'adam_wolf',
thumb: 'images/presenters/adam_wolf.jpg',
bio: 'lorem ipsum'
}.
...
{
id: 15,
name: 'aimee_nicotera',
thumb: 'images/presenters/aimee_nicotera.jpg',
bio: 'lorem ipsum'
}
];
});
end here is the view code:
<div class="row" id="presenters">
<div class="col-md-12 above-element" id="presenter-overlay" ng-show="showDetails">
<div class="col-md-12 col-md-offset-6 motion-container animated" ng-class="{fadeInRight : showDetails}">
<div class="col-md-12 skew-container bg-yellow no-pad">
<div class="skew-content col-md-6 no-pad">
<div class="row presenter-image-container">
<div class="col-md-6 flex-container name-holder">
<h2>{{currentPresenter.name}}</h2>
</div>
<div class="col-md-6 no-pad image-holder">
<figure><img src="{{currentPresenter.image}}" alt=""></figure>
</div>
</div>
<div class="row bg-white presenter-bio-container">
<div class="col-md-6 col-md-offset-6">
<p>{{currentPresenter.bio}}</p>
</div>
</div>
<div class="row bg-white presenter-navigation">
<div class="col-md-10 col-md-offset-2">
<div class="row">
<div class="col-md-6 no-pad"> <span class="presenter-nav" ng-click="getPresenterDetails({{currentPresenter.id - 1}})"> <i class="glyphicon glyphicon-menu-left"></i> Prev </span> </div>
<div class="col-md-6 no-pad"> <span class="presenter-nav" ng-click="getPresenterDetails({{currentPresenter.id + 1}})"> Next <i class="glyphicon glyphicon-menu-right"></i> </span> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12 under-element">
<ul id="presenters-list">
<li class="presenter animation" ng-repeat="presenter in presenters"> <a ng-href="" ng-click="getPresenterDetails({{presenter.id}})"><img ng-src="{{presenter.thumb}}" alt="{{presenter.name}}"></a> </li>
</ul>
</div>
</div>

Categories