I am trying to build a website and have this carousel, that was made with Alpine JS and Tailwind CSS. I took the Alpine Javascript from a template and it works according to specifications. But I would want to make it mouse draggable as well.
Here is the carousel slider
<div class="mt-24">
<script>
window.carousel = function () {
return {
container: null,
prev: null,
next: null,
init() {
this.container = this.$refs.container
this.update();
this.container.addEventListener('scroll', this.update.bind(this), {passive: true});
},
update() {
const rect = this.container.getBoundingClientRect();
const visibleElements = Array.from(this.container.children).filter((child) => {
const childRect = child.getBoundingClientRect()
return childRect.left >= rect.left && childRect.right <= rect.right;
});
if (visibleElements.length > 0) {
this.prev = this.getPrevElement(visibleElements);
this.next = this.getNextElement(visibleElements);
}
},
getPrevElement(list) {
const sibling = list[0].previousElementSibling;
if (sibling instanceof HTMLElement) {
return sibling;
}
return null;
},
getNextElement(list) {
const sibling = list[list.length - 1].nextElementSibling;
if (sibling instanceof HTMLElement) {
return sibling;
}
return null;
},
scrollTo(element) {
const current = this.container;
if (!current || !element) return;
const nextScrollPosition =
element.offsetLeft +
element.getBoundingClientRect().width / 2 -
current.getBoundingClientRect().width / 2;
current.scroll({
left: nextScrollPosition,
behavior: 'smooth',
});
}
};
}
</script>
<style>
.scroll-snap-x {
scroll-snap-type: x mandatory;
}
.snap-center {
scroll-snap-align: center;
}
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
</style>
<div class="flex mx-auto items-center">
<div x-data="carousel()" x-init="init()" class="relative overflow-hidden group">
<div x-ref="container"
class="ml-4 flex overflow-x-scroll scroll-snap-x space-x-4 no-scrollbar touch-pan-x cursor-pointer">
{% for origin in origins %}
<div class="group/item relative ml-4 flex-auto flex-grow-0 flex-shrink-0 w-4/5 sm:w-4/5 xl:w-2/5 rounded-lg bg-gray-100 items-center justify-center snap-center overflow-hidden shadow-md"><!-- items container -->
<div class="min-w-full h-full rounded-lg bg-gray-100 overflow-hidden shadow-md">
<div><img src="{{ origin.imgurl }}" alt="{{ origin.alt }}" class="object-cover h-96" /></div>
<div class="absolute bg-gray-800 bg-opacity-0 group-hover/item:bg-opacity-50 top-2/3 inset-x-0 text-center px-2 py-3">
<div class="text-2xl text-transparent group-hover/item:text-emerald-500 font-extrabold uppercase">{{ origin.name }}</div>
<div class="text-xl text-transparent group-hover/item:text-white font-bold">{{ origin.country }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div #click="scrollTo(prev)" x-show="prev !== null"
class="block absolute top-1/2 left-0 bg-white text-3xl p-2 rounded-full transition-transform ease-in-out transform -translate-x-full -translate-y-1/2 group-hover:translate-x-0 cursor-pointer">
<div><ion-icon name="chevron-back-outline"></ion-icon></div>
</div>
<div #click="scrollTo(next)" x-show="next !== null"
class="block absolute top-1/2 right-0 bg-white p-2 text-3xl rounded-full transition-transform ease-in-out transform translate-x-full -translate-y-1/2 group-hover:translate-x-0 cursor-pointer">
<div><ion-icon name="chevron-forward-outline"></ion-icon></div>
</div>
</div>
</div>
</div>
</div>
I tried adding Alpine script from a different carousel that has this function, but it does not do anything. My understanding of Javascript is rudimentary.
I recently learned about web development, and I want to build my own portfolio website using Github Pages. For the 'Portfolio' section, I want to use a slider using Javascript. Then, when I copy paste the code and change the title to 'Blog' section, this new section didn't apply the slider that seen in Portfolio.
I already seen multiple online sources to see where is my problem, and it shows that the getElementById only can be used one time. I try to modify the code to use querySelectorAll but it's still doesn't work.
This is the JS code that I used:
const sliderContainer = document.getElementById('sliderContainer');
const slider = document.getElementById('slider');
const cards = slider.getElementsByTagName('li');
var elementsToShow = 3;
if (document.body.clientWidth < 1000) {
elementsToShow = 1;
} else if (document.body.clientWidth < 1500) {
elementsToShow = 2;
}
var sliderContainerWidth = sliderContainer.clientWidth;
var cardWidth = sliderContainerWidth / elementsToShow;
slider.style.width = cards.length * cardWidth + 'px';
slider.style.transition = 'margin';
slider.style.transitionDuration = '1s';
for (var index = 0; index < cards.length; index++) {
const element = cards[index];
element.style.width = cardWidth + 'px';
}
function next() {
if (+slider.style.marginLeft.slice(0, -2) != -cardWidth * (cards.length - elementsToShow)) slider.style.marginLeft = +slider.style.marginLeft.slice(0, -2) - cardWidth + 'px';
}
function prev() {
if (+slider.style.marginLeft.slice(0, -2) != 0) slider.style.marginLeft = +slider.style.marginLeft.slice(0, -2) + cardWidth + 'px';
}
function autoPlay() {
prev();
if (+slider.style.marginLeft.slice(0, -2) === -cardWidth * (cards.length - elementsToShow)) {
slider.style.marginLeft = '0px';
}
setTimeout(() => {
autoPlay();
}, 3000);
}
and this is my HTML code. I use TailwindCSS for the CSS framework.
<div class="flex">
<div class="flex items-center">
<div class="w-full text-right">
<button class="bi bi-arrow-left-circle-fill mb-2 ml-2 flex h-9 w-9 items-center justify-center rounded-full border border-slate-300 text-slate-300 hover:border-primary hover:bg-primary hover:text-white"
onclick="prev()"
></button>
</div>
</div>
<div id="sliderContainer" class="overflow-hidden">
<ul id="slider" class="flex w-full">
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
</ul>
</div>
<div class="flex items-center">
<div class="w-full">
<button
onclick="next()"
class="bi bi-arrow-right-circle-fill mr-2 mb-2 ml-2 flex h-9 w-9 items-center justify-center rounded-full border border-slate-300 text-slate-300 hover:border-primary hover:bg-primary hover:text-white slider__btn--right"
></button>
</div>
</div>
</div>
Please help me modify the JS code so it can be use multiple times. thanks in advance!
I am looping through an array of objects (rendering data coming from an API) via Vanilla JavaScript (DOM). And I want to pass more than one value (Product ID, Product Name .. etc) to a function triggered in the event of a click button. saveProduct(${proInfo}) as it shown below (proInfo is an object).
The problem is I have been able to pass ONLY ONE value to this function. I tried to pass the variable as an object but it didn't work and got the error (index):1 Uncaught SyntaxError: Unexpected end of input
var shopNcounter = 0;
const baseURL = "***";
const idsArray = [];
const divRow = document.querySelector(".row");
const buttonContainer = document.querySelector("#button-container")
//create column div
function createDiv() {
const div = document.createElement("div");
div.classList.add("col-xl-3");
div.classList.add("col-md-6");
div.classList.add("col-sm-12");
return div;
}
async function getData(id) {
shopNcounter ++;
console.log(shopNcounter);
if(shopNcounter > 5) {
getProInfo(id);
return;
} else if (shopNcounter > 4) {
getProducts(id);
return;
}
idsArray.push(id);
console.log(id);
console.log(idsArray);
if(idsArray.length > 10) {
idsArray.splice(0,6);
}
const api = `**shop=${shopNcounter}&id=${id}`;
try {
const response = await fetch(api);
const data = await response.json();
divRow.innerHTML = "";
if (shopNcounter > 1) {
buttonContainer.innerHTML = `
<button class="btn btn-lg btn-warning px-5" onclick="moveBack(${idsArray[idsArray.length-2]})">رجوع</button>
`
} else {
buttonContainer.innerHTML = "";
}
//mapping through data
data.map(item => {
const div = createDiv();
divRow.appendChild(div);
div.innerHTML+=`
<div class="card text-center h-100 mx-auto border-white shadow" style="width: 16rem;">
<img src="${baseURL + item.image}" class="card-img-top mx-auto" alt="...">
<div class="card-body">
<a onclick=handleClick(${item.id}) class="btn btn-outline-dark px-5 mt-4" id="goToItemButton">${item.name}</a>
</div>
</div>
`;
});
} catch(error) {console.log(error);}
}
getData(0);
async function getProducts(id) {
//shop > 4 = 5
console.log("Get Product is being executing");
const apiProducts = `**product?id=${id}`;
try {
const response = await fetch(apiProducts);
const data = await response.json();
console.log(data);
divRow.innerHTML = "";
//mapping through data
data.map((item, index) => {
var proInfo = {
pid: item.PID,
pname: item.PName
}
const div = createDiv();
divRow.appendChild(div);
div.innerHTML+=`
<div class="card text-center h-100 mx-auto border-white shadow" style="width: 16rem;">
<img src="${baseURL + item.image}" class="card-img-top mx-auto" alt="...">
<div class="card-body">
<h5>${item.PName}</h5>
<p class="product-price">Price: ${item.PSelPrice}</p>
<a onclick=saveProduct(${item.PID}) class="btn btn-danger px-5 mt-4"> Add to Card </a>
</div>
</div>
`;
});
} catch(error) {
console.log(error);
}
}
function moveBack(id) {
shopNcounter = shopNcounter -2;
getData(id);
}
function handleClick(id) {
let clickedButton = document.querySelector("#goToItemButton");
clickedButton.onclick = "";
getData(id);
}
function saveProduct(g) {
console.log(g);
}
your code should not result in the error you see
However you can make your life easier using delegation
do this
document.getElementById("container").innerHTML = data.map((item,i) => `<div class="card text-center h-100 mx-auto border-white shadow" style="width: 16rem;">
<img src="${baseURL + item.image}" class="card-img-top mx-auto" alt="...">
<div class="card-body">
<h5>${item.PName}</h5>
<p class="product-price">Price: ${item.PSelPrice}</p>
<a data-id="${i}" class="add btn btn-danger px-5 mt-4"> Add to Card </a>
</div>
</div>`).join("");
Have this
document.getElementById("container").addEventListener("click",function(e) {
const tgt = e.target.closest("a");
if (tgt && tgt.className.contains("add")) {
const item = data[tgt.dataset.id]
// here you can add the item
saveProduct({pid: item.PID,pname: item.PName })
}
})
I saw this code in an article about discord Oauth2. As I have two HTML files so how do I connect both of them in this line: res.sendFile('index.html', { root: '.' });
And my both HTML files are not in a specific folder it's in the main file.
When I open my code with VS code live server it looks like this:
But when I open it with localhost:53134 it looks like this:
This is my index.html code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Montserrat Google Font -->
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#900&display=swap" rel="stylesheet">
<!-- Changes this to your bot's name -->
<title>Discord Bot Website Template</title>
<!-- Change the content attribute's value to your bot's description -->
<meta name="description" content="An opensource discord bot website template that you can use to make your bot seem more professional!">
<!-- Change the content attribute's value to your name -->
<meta name="author" content="TrustedMercury">
<link rel="stylesheet" href="styles/theTrendingStyle.css">
<link rel="stylesheet" href="styles/index.css">
<link rel="stylesheet" href="styles/css/all.css" />
</head>
<body class="bg-shinyGray overflow-x-hidden">
<nav id="navigationBar" class="flex flex-row items-center justify-between p-6 bg-sweetBlack">
<div class="left flex flex-row items-center ml-10 md:ml-20 text-white">
<img src="images/botLogo.png" width="48px" height="48px" class="mr-2 hidden md:inline pointer-events-none noselect" />
Home
Pricing
</div>
<div class="right mr-10 md:mr-20">
<i class="fab fa-discord mr-1"></i> Invite
<div id="info">
Hoi!
</div>
</div>
</nav>
<div id="container" class="flex flex-col items-center justify-center">
<div class="flex flex-col items-center justify-center pt-40 text-center">
<span class="text-2xl md:text-5xl font-semibold text-white">Changing the way servers work</span>
<span class="text-gray-400 text-lg md:text-xl max-w-xl font-light">Helping servers grow exponentially with a simple solution. Make your server active and entertain your community with a simple solution - <b>a single discord bot</b>!</span>
<div class="flex flex-col md:flex-row mt-8">
Invite the bot now!
Join the Support Server
</div>
</div>
<svg class="bg-blurple" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#1D1E23" fill-opacity="1" d="M0,160L48,138.7C96,117,192,75,288,74.7C384,75,480,117,576,160C672,203,768,245,864,261.3C960,277,1056,267,1152,240C1248,213,1344,171,1392,149.3L1440,128L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"></path></svg>
<div class="flex flex-col md:flex-row items-center justify-center w-full bg-blurple">
<img src="images/discordUI.png" class="max-w-xs md:max-w-5xl noselect pointer-events-none" />
<div class="flex flex-col items-center justify-center noselect">
<div class="flex flex-col items-center text-4xl mb-4">
<span class="font-montserrat font-black">200+</span>
<span class="font-montserrat font-black">SERVERS</span>
</div>
<div class="flex flex-col items-center text-4xl my-4">
<span class="font-montserrat font-black">14500+</span>
<span class="font-montserrat font-black">USERS</span>
</div>
<div class="flex flex-col items-center text-4xl mt-4">
<span class="font-montserrat font-black">2300+</span>
<span class="font-montserrat font-black">CHANNELS</span>
</div>
</div>
</div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#7289DA" fill-opacity="1" d="M0,224L48,240C96,256,192,288,288,304C384,320,480,320,576,288C672,256,768,192,864,138.7C960,85,1056,43,1152,48C1248,53,1344,107,1392,133.3L1440,160L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"></path></svg>
<div class="flex flex-row items-center justify-center mb-10">
<span class="text-lg text-gray-400 font-semibold">Copyright © Kevin Thomas 2020</span>
</div>
</div>
<a id="login" style="display: none;" href="Oauth link here">Identify Yourself</a>
<script>
function generateRandomString() {
const rand = Math.floor(Math.random() * 10);
let randStr = '';
for (let i = 0; i < 20 + rand; i++) {
randStr += String.fromCharCode(33 + Math.floor(Math.random() * 94));
}
return randStr;
}
window.onload = function () {
const fragment = parseQuery(window.location.href);
if (fragment.access_token) {
const urlState = fragment.state;
const stateParameter = localStorage.getItem('stateParameter');
if (stateParameter !== atob(decodeURIComponent(urlState))) {
return console.log('You may have been clickjacked!');
}
const accessToken = fragment.access_token;
const tokenType = fragment.token_type;
fetch('https://discordapp.com/api/users/#me', {
headers: {
authorization: `${tokenType} ${accessToken}`
}
})
.then(res => res.json())
.then( (response) => {
console.log(response);
const { username, discriminator, avatar } = response;
document.getElementById('info').innerHTML = ` ${username}#${discriminator}`;
let user = provider.getResourceOwner(`${accessToken}`);
let avatar1 = 'https://cdn.discordapp.com/avatars/' + user.id + '/' + user.avatar + '.png ?size=225';
document.getElementsByClassName("avatar-img").src = avatar1;
})
.catch(console.error);
} else {
const randStr = generateRandomString();
localStorage.setItem('stateParameter', randStr);
document.getElementById('login').href += `&state=${encodeURIComponent(btoa(randStr))}`;
document.getElementById('login').style.display = 'block';
}
}
function parseQuery(queryString) {
var query = {};
var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
}
return query;
}
</script>
<script src="main.js"></script>
</body>
</html>
This is my javascript code:
const app = require('express')();
const fetch = require('node-fetch');
app.get('/', async (req, res) => {
let access_token;
let token_type;
if (req.query.code) {
const accessCode = req.query.code;
const data = {
client_id : 'client id here',
client_secret : 'client secret here',
grant_type : 'authorization_code',
redirect_uri : 'http://localhost:3000',
code : accessCode,
scope : 'identify'
};
const res = await fetch('https://discordapp.com/api/oauth2/token', {
method : 'POST',
body : new URLSearchParams(data),
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
}
});
const info = await res.json();
token_type = info.token_type;
access_token = info.access_token;
const post = await fetch('https://discordapp.com/api/users/#me', {
headers : {
authorization : `${token_type} ${access_token}`
}
});
const user = await post.json();
}
if (token_type && access_token && req.query.state) {
res
.status(200)
.redirect(
`http://localhost:3000/?code=${req.query.code}&state=${req.query
.state}&access_token=${access_token}&token_type=${token_type}`
);
} else {
res.sendFile('index.html', { root: '.' });
}
});
app.listen(3000);
sorry I am new in angular and StackOverflow
I have 3 divs and I want to add background-color: red to all divs which status is requesting payment. It should make background color to the second and the third div but it makes to only the third
html
<div class="col-md-4 mb-4" *ngFor="let invoice of Invoices let i=index">
<div id="{{'activeInvoice'+i}}" class=" d-flex justify-content-between align-items-center w-100 card-header ">
<strong class="text-gray-dark">{{langVar.Invoice}} {{invoice.invoiceNumber}}</strong>
<i class="fa fa-info-circle" title="show Details" aria-hidden="true" (click)="showInvoiceDetailsModal(invoice.id)"></i>
</div>
</div>
for (var i = 0; i <= this.Invoices.length-1; i++) {
console.log("invoice num", this.Invoices[i].invoiceNumber);
console.log("order", this.Invoices[i].order.length);
for (var j = 0; j <= this.Invoices[i].order.length - 1; j++) {
console.log("STATUS", this.Invoices[i].order[j].status);
if (this.Invoices[i].order[j].status == 'requestingPayment') {
var elementValue = 'activeInvoice'+i;
setTimeout(() => {
document.getElementById(elementValue).classList.add("cardBackGround");
}, 1000);
}
else {}
}
}
you can conditionally add CSS classes in angular using ngClass
<div [ngClass]={'cardBackGround': true }> </div>
// apply your condition instead of true