JavaScript dynamic card rendering in inner HTML - javascript

Spend much time but can't solve it. My CSS is OK. But why it is printing line by line in innerHTML? I am using an async function to get the data.
1st Function
const deploySnipCard = (getSnip) => {
for (x in getSnip) {
const tech = getSnip[x].tech;
const tags = getSnip[x].tags;
const tagsUrl = getSnip[x].tagsUrl;
const status = getSnip[x].status;
const imgSrc = getSnip[x].imgSrc;
const imgUrl = getSnip[x].imgUrl;
const caption = getSnip[x].caption;
appendCard(tech, tags, tagsUrl, status, imgSrc, imgUrl, caption);
}
};
2nd Function
const appendCard = (tech, tags, tagsUrl, status, imgSrc, imgUrl, caption) => {
const mainDiv = document.getElementById("root");
mainDiv.innerHTML += `
<div class="col-12 col-lg-4 col-md-6">
<div class="snip-card mt-5 p-2">
<div class="d-flex justify-content-between">
<div>
<span class="badge bg-primary mb-2">${tech}</span>
<a href="${tagsUrl}">
<span class="badge bg-danger mb-2 mx-1">${tags}</span></a>
</div>
<div>
<span class="badge bg-success mb-2">${status}</span>
</div>
</div>
<a href="${imgUrl}">
<div class="bg-dark">
<img class="card-img img-fluid" alt="click here" loading="lazy"
src="${imgSrc}">
</div>
</a>
<p class="snip-card-cap my-2">${caption}</p>
</div>
</div>`;
};
Output:
Expected Output:

Related

How to insert html element inside the index.html from javascript

I want to insert the card into container using javascript. How do I do it. or make those card display in flex. So it's not like shown in below pic. I have used insertAdjancentHTML to insert the data in note class using javascript. However i'm unable to put them in container.
const addBtn = document.getElementById("add");
const addNewNote = (text = "") => {
const note = document.createElement("div");
note.classList.add("note");
const htmlData = `<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-primary">
<i class="bi bi-trash"></i>
</button>
</span>
</div>
<hr />
<p class="card-text">
Some quick example text to build on the card title and make up the
bulk of the card's content.
</p>
</div>
</div>`;
note.insertAdjacentHTML("afterbegin", htmlData);
console.log(note);
document.body.appendChild(note);
};
addBtn.addEventListener("click", () => {
addNewNote();
});
Firstly, just use innerHTML - it's an empty element:
note.innerHTML = htmlData;
Secondly, you need to select the element to append this note to. Add an ID:
<div class="container d-flex" id="noteContainer">
And append it like so:
document.getElementById("noteContainer").appendChild(note);
You can add an identifier to the div an use the appendChild to this div instead of the body of the document
<div id="myDiv" class="container d-flex"></div>
And at the end of your function
document.getElementById("myDiv").appendChild(note);
Working example
const button = document.getElementById("addButton")
const addNote = () => {
const myElement = document.createElement('p')
myElement.innerHTML = "Hello world !"
const div = document.getElementById("myDiv")
div.appendChild(myElement)
}
button.addEventListener("click", addNote)
<button id="addButton">Add element</button>
<div id="myDiv"></div>
Cache the container element.
Return the note HTML from the function (no need to specifically create an element - just wrap the note HTML in a .note container), and then add that HTML to the container.
(In this example I've used unicode for the icons, and a randomiser to provide some text to the note.)
const container = document.querySelector('.container');
const addBtn = document.querySelector('.add');
function createNote(text = '') {
return`
<div class="note">
<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">🖉</button>
<button class="btn btn-primary">🗑</button>
</span>
</div>
<hr />
<p class="card-text">${text}</p>
</div>
</div>
</div>
`;
};
function rndText() {
const text = ['Hallo world', 'Hovercraft full of eels', 'Two enthusiastic thumbs up', 'Don\'t let yourself get attached to anything you are not willing to walk out on in 30 seconds flat if you feel the heat around the corner'];
const rnd = Math.round(Math.random() * ((text.length - 1) - 0) + 0);
return text[rnd];
}
addBtn.addEventListener('click', () => {
const note = createNote(rndText());
container.insertAdjacentHTML('afterbegin', note);
});
<div>
<button type="button" class="add">Add note</button>
<div class="container"></div>
</div>

Why are muiltiple users not showing in WebRTC

The code only shows yourself and no one else
Using Express, Socket.io, WebRTC, Nodejs, Jquery, And Nodemon
I am following a tutorial
on WebRTC, The goal is to make a google-meet clone
I tested the source code from my tutorial
it worked!
but my code isn't working
I don't know why tho'
Using NPM 8.1.x
Using Node 14.18.x
Using Express 4.17.x
Using Socket.io 4.4.x
Using Nodemon 2.0.x
Using JQuery 3.4.x
Index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WittyChat</title>
<link rel="stylesheet" href="public/Assets/css/bootstrap.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="public/Assets/css/style.css">
<script src="https://cdn.socket.io/4.4.0/socket.io.min.js" integrity="sha384-1fOn6VtTq3PWwfsOrk45LnYcGosJwzMHv+Xh/Jx5303FVOXzEnw0EpLv30mtjmlj" crossorigin="anonymous"></script>
<script>
const socket = io("http://localhost:3000");
</script>
<script src="public/Assets/js/jquery-3.4.1.min.js"></script>
<script src="public/Assets/js/app.js"></script>
<script>
$(function(){
const urlParams = new URLSearchParams(window.location.search);
var meeting_id = urlParams.get('meetingID');
user_id = window.prompt('Enter Your Username/UserID');
if(!user_id || !meeting_id) {
alert('ERROR WC0139 | Invalid/Missing Username/UserID or MeetingID');
window.location.href="/action.html";
return;
}
$("#meetingContainer").show();
MyApp._init(user_id, meeting_id);
})
</script>
</head>
<body>
<main class=" d-flex flex-column home-wrap">
<div class="g-top text-light">
<div class="top-remote-video-show-wrap d-flex">
<div id="meetingContainer" style="flex-basis: 75%;">
<div class="call-wrap" style="background-color: black;">
<div class="video-wrap" id="divUsers" style="display:flex; flex-wrap:wrap">
<div id="me" class="userbox display-center flex-column">
<h2 class="display-center" style="font-size: 14px;"></h2>
<div class="display-center">
<video autoplay muted id="locaVideoPlayer"></video>
</div>
</div>
<div id="otherTemplate" class="userbox display-center flex-column" style="display:none">
<h2 class="display-center" style="font-size: 14px;"></h2>
<div class="display-center">
<video autoplay muted></video>
<audio autoplay controls style="display:none"></audio>
</div>
</div>
</div>
</div>
</div>
<div class="g-right-details-wrap bg-light text-secondary h-100" style="flex-basis: 25%; z-index: 1; display: none;">
<div class="meeting-heading-wrap d-flex justify-content-between align-items-center pr-3 pl-3" style="height: 10vh;">
<div class="meeting-heading font-weight-bold ">Meeing Details</div>
<div class="meeting-heading-cross display-center cursor-pointer">
<span class="material-icons">clear</span>
</div>
</div>
<div class="people-chat-wrap d-flex justify-content-between align-items-center ml-3 mr-3 pr-3 pl-3" style="height: 10vh;font-size: 14px;">
<div class="people-heading display-center cursor-pointer">
<div class="people-headin-icon display-center mr-1">
<span class="material-icons">people</span>
</div>
<div class="people-headin-text display-center">
Participant (<span class="participant-count">1</span>)
</div>
</div>
<div class="chat-heading d-flex just-content-round align-items-center cursor-pointer">
<div class="chat-heading-icon display-center mr-1">
<span class="material-icons">
message
</span>
</div>
<div class="chat-heading-text">
Chat
</div>
</div>
</div>
<div class="in-call-chat-wrap mr-3 ml-3 pl-3 pr-3" style="font-size: 14px; height: 69vh; overflow-y: scroll;">
<div class="in-call-wrap-up" style="display: none !important;">
<div class="in-call-wrap d-flex justify-content-between align-items-center mb-3">
<div class="participant-img-name-wrap display-center cursor-pointer">
<div class="participant-img">
<img src="public/Assets/images/other.jpg" alt="" class="border border-secondary" style="height: 40px;width: 40px;border-radius: 50%;">
</div>
<div class="participant-name ml-2">You</div>
</div>
<div class="participant-action-wrap display-center">
<div class="participant-action-dot display-center mr-2 cursor-pointer">
<span class="material-icons">
more_vert
</span>
</div>
<div class="participant-action-pin display-center mr-2 cursor-pointer">
<span class="material-icons">
push_pin
</span>
</div>
</div>
</div>
</div>
<div class="chat-show-wrap text-secondary flex-column justify-content-between h-100" style="font-size: 14px; display: flex;">
<div class="chat-message-show" id="messages"></div>
<div class="chat-message-sent d-flex justify-content-between align-items-center" style="margin-bottom:35px">
<div class="chat-message-sent-input" style="width: 85%;">
<input type="text" name="" class="chat-message-sent-input-field w-100" id="msgbox" placeholder="Send a message to everyone" style="border-bottom: 1px solid teal; border: none;">
</div>
<div class="chat-message-sent-action display-center" id="btnsend" style="color: teal; cursor:pointer;">
<span class="material-icons">send</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="g-top-left bg-light text-secondary w-25 d-flex align-items-center justify-content-between pl-2 pr-2">
<div class="top-left-participant-wrap pt-2 cursor-pointer">
<div class="top-left-participant-icon">
<span class="material-icons">people</span>
</div>
<div class="top-left-participant-count participant-count">1</div>
</div>
<div class="top-left-chat-wrap pt-2 cursor-pointer">
<span class="material-icons">message</span>
</div>
<div class="top-left-time-wrap"></div>
</div>
</div>
<div class="g-bottom bg-light m-0 d-flex justify-content-between align-items-center">
<div class="bottom-left d-flex" style="height:10vh">
<div class="g-details border border-success mb-2" style="display: none;min-height: 19.5vh;">
<div class="g-details-heading d-flex justify-content-between align-items-center border-bottom pb-1">
<div class="g-details-heading-detail d-flex align-items-center cursor-pointer">
<span class="material-icons">error</span style="margin-top:-5px">Details<span></span>
</div>
<div class="g-details-heading-attachment d-flex align-items-center cursor-pointer">
<span class="material-icons">attachment</span style="margin-top:-5px">Attachment<span></span>
</div>
</div>
<div class="g-details-heading-show-wrap">
<div class="g-details-heading-show">
<div style="font-weight: 600;color:gray">Joining Info</div>
<div class="meeting_url" style="padding: 5px 0;" data-toggle="tooltip" data-placement="top"></div>
<div style="cursor: pointer;">
<span class="material-icons" style="font-size: 14px;">content_copy</span>
<span class="copy_info font-weight-bold">Copy Joining Info <span style="display: none;background-color: aquamarine; border-radius: 5px;" class="link-conf font-weight-bold p-1">Link Copied</span></span>
</div>
</div>
<div class="g-details-heading-show-attachment" style="display: none;position: relative;">
<div class="show-attach-file"></div>
<div class="upload-attach-file">
<form enctype="multipart/form-data" ref="uploadForm" class="display-center" id="uploadForm" style="justify-content: space-between;">
<div class="custom-file" style="flex-basis:79%">
<input type="file" class="custom-file-input" id="customFile" name="imagefile">
<label for="customFile" class="custom-file-label">Choose File</label>
</div>
<div class="share-button-wrap">
<button class="btn btn-primary btn-sm share-attach" style="flex-basis:19%;padding: 6px 20px;">Share</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="display-center cursor-pointer meeting-details-button">
Meeting Details<span class="material-icons">keyboard_arrow_down</span>
</div>
</div>
<div class="bottom-middle d-flex just-content-center align-items-center" style="height: 10vh;">
<div class="mic-toggle-wrap action-icon-style display-center mr-2 cursor-pointer" id="miceMuteUnmute">
<span class="material-icons" style="width: 100%;">mic_off</span>
</div>
<div class="end-call-wrap action-icon-style display-center mr-2 cursor-pointer">
<span class="material-icons text-danger">call</span>
</div>
<div class="video-toggle-wrap action-icon-style display-center cursor-pointer" id="videoCamOnOff"><span class="material-icons" style="width: 100%;">videocam_off</span></div>
</div>
<div class="bottom-right d-flex just-content-center align-items-center mr-3" id="screenShare-wrap" style="height: 10vh;">
<div class="present-now-wrap d-flex just-content-center flex-column align-items-center mr-5 cursor-pointer" id="ScreenShareOnOf">
<span class="material-icons">present_to_all</span>
<div>Present Now</div>
</div>
<div class="option-wrap cursor-pointer display-center" style="height: 10vh; position:relative;">
<div class="recording-show">
<button class="btn btn-dark text-danger start-record">Start Recording</button>
</div>
<div class="option-icon">
<span class="material-icons">more_vert</span>
</div>
</div>
</div>
</div>
<div class="top-box-show" style="display: none;">
</div>
</main>
</body>
</html>
Server.js
const path = require("path");
var app = express();
var server = app.listen(3000, function () {
console.log("Listening on port 3000");
});
const fs = require("fs");
const io = require("socket.io")(server, {
allowEIO3: true, // false by default
});
app.use(express.static(path.join(__dirname, "")));
app.use(express.static(path.join(__dirname, "")));
var userConnections = [];
io.on("connection", (socket) => {
console.log("socket id is ", socket.id);
socket.on("userconnect", (data) => {
console.log("userconnent", data.displayName, data.meetingid);
var other_users = userConnections.filter(
(p) => p.meeting_id == data.meetingid
);
userConnections.push({
connectionId: socket.id,
user_id: data.displayName,
meeting_id: data.meetingid,
});
other_users.forEach((v) => {
socket.to(v.conncetionId).emit("imform_others_about_me", {
other_users: data.displayName,
connId: socket.id
})
});
socket.on("SDPProcess", (data) => {
socket.to(data.to_connid).emit("SDPProcess", {
message: data.message,
from_connid: socket.id,
})
});
});
socket.emit("infrom_me_about_other_user",);
}
)
App.js
var peers_connection_ids = [];
var peers_connection = [];
var remote_vid_stream = [];
var remote_aud_stream = [];
var local_div;
var serverProcess;
var audio;
var isAudioMute = true;
var rtp_aud_senders = [];
var video_states = {
None: 0,
Camera: 1,
ScreenShare: 2
// This code is here because in order to turn on and off the video you need to declare a var containing the states of the video e.g Off:0 On:1
}
var video_st = video_states.None;
var videoCamTrack;
var rtp_vid_senders = [];
async function _init(SDP_function, my_connid) {
serverProcess = SDP_function;
my_connection_id = my_connid;
eventProcess();
local_div = document.getElementById("locaVideoPlayer");
}
function eventProcess() {
$("#miceMuteUnmute").on("click", async function () {
if (!audio) {
await loadAudio();
}
if (!audio) {
alert("Audio Permission has been denied!");
return;
}
if (isAudioMute) {
audio.enabled = true;
$(this).html("<span class='material-icons>mic</span>");
updateMediaSenders(audio, rtp_aud_senders);
} else {
audio.enabled = false;
$(this).html("<span class='material-icons>mic-off</span>");
removeMediaSenders(rtp_aud_senders);
}
isAudioMute = !isAudioMute;
});
$("#videoCamOnOff").on("click", async function () {
if (video_st == video_states.Camera) {
await videoProcess(video_states.None);
} else {
await videoProcess(video_states.Camera);
}
});
$("#ScreenShareOnOf").on("click", async function () {
if (video_st == video_states.ScreenShare) {
await videoProcess(video_states.None);
} else {
await videoProcess(video_states.ScreenShare);
}
});
}
async function updateMediaSenders(track, rtp_senders) {
for (var con_id in peers_connection_ids) {
if (connection_status(peers_connection[con_id])) {
if (rtp_senders[con_id] && rtp_senders[con_id].track) {
rtp_senders[con_id].replaceTrack(track);
} else {
rtp_senders[con_id] = peers_connection[con_id].addTrack(track);
}
}
}
}
function removeMediaSenders(rtp_senders) {
for (var con_id in peers_connection_ids) {
if (rtp_senders[con_id] && connection_status(peers_connection[con_id])) {
peers_connection[con_id].removeTrack(rtp_senders[con_id]);
rtp_senders[con_id] = null;
}
}
}
function removeVideoStream(rtp_vid_senders) {
if (videoCamTrack) {
videoCamTrack.stop();
videoCamTrack = null;
local_div.srcObject = null;
removeMediaSenders(rtp_vid_senders);
}
}
async function videoProcess(newVideoState) {
if (newVideoState == video_states.None) {
$("#videoCamOnOff").html(
"<span class='material-icons' style='width:100%;'>videocam_off</span>"
);
$("#ScreenShareOnOf").html(
'<span class="material-icons">present_to_all</span><div>Present Now</div>'
);
video_st = newVideoState;
removeVideoStream(rtp_vid_senders);
return;
}
if (newVideoState == video_states.Camera) {
$("#videoCamOnOff").html(
"<span class='material-icons' style='width:100%;'>videocam_on</span>"
);
}
try {
var vstream = null;
if (newVideoState == video_states.Camera) {
vstream = await navigator.mediaDevices.getUserMedia({
video: {
width: 1920,
height: 1080,
},
audio: false,
});
} else if (newVideoState == video_states.ScreenShare) {
vstream = await navigator.mediaDevices.getDisplayMedia({
video: {
width: 1920,
height: 1080,
},
audio: false,
});
vstream.oninactive = (e) => {
removeVideoStream(rtp_vid_senders);
$("#ScreenShareOnOf").html(
'<span class="material-icons ">present_to_all</span><div >Present Now</div>'
);
};
}
if (vstream && vstream.getVideoTracks().length > 0) {
videoCamTrack = vstream.getVideoTracks()[0];
if (videoCamTrack) {
local_div.srcObject = new MediaStream([videoCamTrack]);
alert("Video Cam found")
updateMediaSenders(videoCamTrack, rtp_vid_senders);
}
}
} catch (e) {
console.log(e);
return;
}
video_st = newVideoState;
if (newVideoState == video_states.Camera) {
$("#videoCamOnOff").html(
'<span class="material-icons" style="width: 100%;">videocam</span>'
);
$("#ScreenShareOnOf").html(
'<span class="material-icons ">present_to_all</span><div >Present Now</div>'
);
} else if (newVideoState == video_states.ScreenShare) {
$("#videoCamOnOff").html(
'<span class="material-icons" style="width: 100%;">videocam_off</span>'
);
$("#ScreenShareOnOf").html(
'<span class="material-icons text-success">present_to_all</span><div class="text-success">Stop Present Now</div>'
);
}
}
var iceConfiguration = {
iceServers: [
{
urls: "stun:stun.l.google.com:19302",
},
{
urls: "stun:stun1.l.google.com:19302",
},
],
};
async function setConnection(connid) {
var connection = new RTCPeerConnection(iceConfiguration);
connection.onnegotiationneeded = async function (event) {
await setOffer(connid);
};
connection.onicecandidate = function (event) {
if (event.candidate) {
serverProcess(
JSON.stringify({ icecandidate: event.candidate }),
connid
);
}
};
connection.ontrack = function (event) {
if (!remote_vid_stream[connid]) {
remote_vid_stream[connid] = new MediaStream();
}
if (!remote_aud_stream[connid]) {
remote_aud_stream[connid] = new MediaStream();
}
if (event.track.kind == "video") {
remote_vid_stream[connid]
.getVideoTracks()
.forEach((t) => remote_vid_stream[connid].removeTrack(t));
remote_vid_stream[connid].addTrack(event.track);
var remoteVideoPlayer = document.getElementById("v_" + connid);
remoteVideoPlayer.srcObject = null;
remoteVideoPlayer.srcObject = remote_vid_stream[connid];
remoteVideoPlayer.load();
} else if (event.track.kind == "audio") {
remote_aud_stream[connid]
.getAudioTracks()
.forEach((t) => remote_aud_stream[connid].removeTrack(t));
remote_aud_stream[connid].addTrack(event.track);
var remoteAudioPlayer = document.getElementById("a_" + connid);
remoteAudioPlayer.srcObject = null;
remoteAudioPlayer.srcObject = remote_aud_stream[connid];
remoteAudioPlayer.load();
}
};
peers_connection_ids[connid] = connid;
peers_connection[connid] = connection;
if (
video_st == video_states.Camera ||
video_st == video_states.ScreenShare
) {
if (videoCamTrack) {
updateMediaSenders(videoCamTrack, rtp_vid_senders);
}
}
return connection;
}
async function setOffer(connid) {
var connection = peers_connection[connid];
var offer = await connection.createOffer();
await connection.setLocalDescription(offer);
serverProcess(JSON.stringify({
offer: connection.localDescription,
}), connid);
}
async function SDPProcess(message, from_connid) {
message = JSON.parse(message);
if (message.answer) {
await peers_connection[from_connid].setRemoteDescription(
new RTCSessionDescription(message.answer)
);
} else if (message.offer) {
if (!peers_connection[from_connid]) {
await setConnection(from_connid);
}
await peers_connection[from_connid].setRemoteDescription(
new RTCSessionDescription(message.offer)
);
var answer = await peers_connection[from_connid].createAnswer();
await peers_connection[from_connid].setLocalDescription(answer);
serverProcess(
JSON.stringify({
answer: answer,
}),
from_connid
);
} else if (message.icecandidate) {
if (!peers_connection[from_connid]) {
await setConnection(from_connid);
}
try {
await peers_connection[from_connid].addIceCandidate(
message.icecandidate
);
} catch (e) {
console.log(e);
}
}
}
return {
setNewConnection: async function (connid) {
await setConnection(connid);
},
init: async function (SDP_function, my_connid) {
await _init(SDP_function, my_connid);
},
processClientFunc: async function (data, from_connid) {
await SDPProcess(data, from_connid);
},
closeConnectionCall: async function (connid) {
await closeConnection(connid);
},
};
})();
var MyApp = (function () {
var socket = null;
var user_id = "";
var meeting_id = "";
function init(uid, mid) {
user_id = uid;
meeting_id = mid;
$("#meetingContainer").show();
$("#me h2").text(user_id + "(Me)");
document.title = user_id;
event_process_for_signalling_server();
}
function event_process_for_signalling_server() {
socket = io();
var SDP_function = function (data, to_connid) {
socket.emit("SDPProcess", {
message: data,
to_connid: to_connid,
});
};
socket.on("connect", () => {
if (socket.connected) {
AppProcess.init(SDP_function, socket.id);
if (user_id != "" && meeting_id != "") {
socket.emit("userconnect", {
displayName: user_id,
meetingid: meeting_id,
});
}
}
});
socket.on("inform_others_about_me", function (data) {
addUser(data.other_user_id, data.connId, data.userNumber);
AppProcess.setNewConnection(data.connId);
});
socket.on("inform_me_about_other_user", function (other_users) {
var userNumber = other_users.length;
var userNumb = userNumber + 1;
if (other_users) {
for (var i = 0; i < other_users.length; i++) {
addUser(
other_users[i].user_id,
other_users[i].connectionId,
userNumb
);
AppProcess.setNewConnection(other_users[i].connectionId);
}
}
});
socket.on("SDPProcess", async function (data) {
await AppProcess.processClientFunc(data.message, data.from_connid);
})
}
function addUser(other_user_id, connId, userNum) {
var newDivId = $("#otherTemplate").clone();
newDivId = newDivId.attr("id", connId).addClass("other");
newDivId.find("h2").text(other_user_id);
newDivId.find("video").attr("id", "v_" + connId);
newDivId.find("audio").attr("id", "a_" + connId);
newDivId.show();
$("#divUsers").append(newDivId);
$(".in-call-wrap-up").append(
'<div class="in-call-wrap d-flex justify-content-between align-items-center mb-3" id="participant_' +
connId +
'"> <div class="participant-img-name-wrap display-center cursor-pointer"> <div class="participant-img"> <img src="public/Assets/images/other.jpg" alt="" class="border border-secondary" style="height: 40px;width: 40px;border-radius: 50%;"> </div> <div class="participant-name ml-2"> ' +
other_user_id +
'</div> </div> <div class="participant-action-wrap display-center"> <div class="participant-action-dot display-center mr-2 cursor-pointer"> <span class="material-icons"> more_vert </span> </div> <div class="participant-action-pin display-center mr-2 cursor-pointer"> <span class="material-icons"> push_pin </span> </div> </div> </div>'
);
$(".participant-count").text(userNum);
}
return {
_init: function (uid, mid) {
init(uid, mid);
}
};
})();

UI not being updated by the result of fetch

I am trying to load search results based on what the user typed (responsive search), I thought it was my event as I wanted it more responsive e.g keyup but it didn't work. Here is working codepen
and following in my code. I had been struggling for hours now. What am I doing wrong?
function generateHTML(el,toggleClass){
const div = document.createElement("div");
const card = div.classList.add("card","col-sm-6", "col-md-6", "col-lg-3", "m-2",toggleClass);
div.innerHTML = `
<a href='#' class="products">
<img src="${el.image}" class="card-img-top rounded" alt="${el.title}">
<div class="card-body">
<h5 class="card-title">${(slicer(el.title))}</h5>
</div>
</a>
`
grid.appendChild(div);
}
This should do what you actually want
//getting the reference to elements
const row = document.querySelector("#search");
const grid = document.querySelector("#grid");
document.addEventListener("DOMContentLoaded", function () {
const div = document.createElement("div");
const formGroup = div.classList.add("form-group");
div.innerHTML = `
<div class="alert alert-primary">
<label for="searchField">Search</label>
<input type="text" class="form-control" id="searchField" placeholder="Type in what your looking for">
</div>
`;
row.appendChild(div);
//fetchData()
//get the reference to form
var input = '';
const myInput = document.getElementById("searchField");
myInput.addEventListener("keyup", function (e) {
input = myInput.value;
console.log(input);
fetch('https://fakestoreapi.com/products/')
//convert the response to JSON
.then(res => res.json())
//use the data to filter if it matches or display all
.then(data => {
grid.innerHTML = '';
data.forEach(el => {
if (el.title.toLowerCase().includes(input.toLowerCase())) {
console.log('h')
generateHTML(el, "block")
}
})
})
});
//get the reference to input
//const input = form.searchField.value.trim();
//add a event to listen on key up
})
function generateHTML(el, toggleClass) {
const div = document.createElement("div");
const card = div.classList.add("card", "col-sm-6", "col-md-6", "col-lg-3", "m-2", toggleClass);
div.innerHTML = `
<a href='#' class="products">
<img src="${el.image}" class="card-img-top rounded" alt="${el.title}" width="100" height="auto">
<div class="card-body">
<h5 class="card-title">${(slicer(el.title))}</h5>
</div>
</a>
`;
grid.appendChild(div);
}
function slicer(str) {
return str.slice(0, 10);
}
<div class="container">
<div class="" id="search">
</div>
<div class="row" id="grid">
</div>
</div>

how to create a gallery of 3 X 3 (Col X Row) using bootstrap on Api call

using Bootstrap for UI and call a api for images to diplay in 3X3 [Col X Row]
using javascript Async-Await.
But getting 3 image in colums and not 3 X 3 Grid layout
It can be using Grid Columns or using Flex In bootstrap 4
I am use Prototyping using Dog Api for Demo purpose.
On click of Button it will display top 15 images on Grid layout in bootstrap
Not getting correct result image1 below is output I got.
Image1
But it should display as Image2 with different Image in grid
Image2
const API_URL = 'https://dog.ceo/api/breeds/image/random/20';
const randomImgDogs = document.querySelector('.random-dogs');
const loadingImg = document.querySelector('.loading');
const getButton = document.querySelector('.getRandomDog');
loadingImg.style.display = 'none';
async function getRandomDogs() {
randomImgDogs.innerHTML = '';
loadingImg.style.display = '';
const response = await fetch(API_URL);
const json = await response.json();
console.log(json.message);
json.message.forEach(dogImage => {
randomImgDogs.innerHTML += `
<div class="container-fluid">
<div class="d-flex flex-row flex-wrap justify-content-center">
<div class="d-flex flex-column">
<img src="${dogImage}" class="img-fluid">
</div>
</div>
</div>`;
});
loadingImg.style.display = 'none';
}
getButton.addEventListener('click', getRandomDogs);
img {
margin: 5px;
}
.flex-column {
max-width: 260px;
}
a svg {
font-size: 30px;
text-align: center;
align-items: center;
justify-content: center;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css">
<div class="jumbotron text-center">
<h1 class="display-4 font-weight-bold text-center">Random Dogs</h1>
<p class="lead">Click on Get to see some random dogs Images!</p>
<a class="btn btn-primary btn-lg getRandomDog " href="#" role="button">Get Random Dogs Images
<svg class="bi bi-chevron-right" width="32" height="32" viewBox="0 0 20 20" fill="currentColor"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M6.646 3.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L12.293 10 6.646 4.354a.5.5 0 010-.708z"
clip-rule="evenodd" /></svg>
</a>
</div>
<!-- -->
<!-- loading -->
<div class="loading text-center">
<div class="spinner-border text-dark" style="width: 3rem; height: 3rem;" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<!-- loading ends -->
<!-- main start -->
<div class="random-dogs">
</div>
<!-- main ends -->
You're looping the entire container instead of the item itself.
The entire container you're looping:
<div class="container-fluid">
<div class="d-flex flex-row flex-wrap justify-content-center">
<div class="d-flex flex-column"> <!-- what you should loop. i.e duplicate -->
<img src="${dogImage}" class="img-fluid">
</div>
</div>
</div>
what you should be looping(the item):
<div class="d-flex flex-column">
<img src="${dogImage}" class="img-fluid">
</div>
You can refactor your code to below code:
async function getRandomDogs() {
const createParentContainer = children => (
`<div class="container-fluid">
<div class="d-flex flex-row flex-wrap justify-content-center">
${children}
</div>
</div>`
);
randomImgDogs.innerHTML = '';
loadingImg.style.display = '';
const response = await fetch(API_URL);
const json = await response.json();
console.log(json.message);
const children = '';
json.message.forEach((dogImage) => {
children += `<div class="d-flex flex-column">
<img src="${dogImage}" class="img-fluid">
</div>`;
});
randomImgDogs.innerHTML += createParentContainer(children);
loadingImg.style.display = 'none';
}

Why are all of my file paths broken with innerHTML?

I'm starting to use innerHTML quite a lot with Javascript.
I've also just started using Parcel Bundler.
My problem is that all of my href links and img src file paths don't seem to be working while using innerHTML.
I should also mention that the img links already in the html file are working fine. and I'm using ./ for the innerHTML assigned to the same html file so I can't see any file path issues. Furthermore, if I copy and paste the innerHTML from the JS file into the HTML file the images work fine so it absolutely can't be a file path issue.
There is a lot of code so I'd rather not flood this questions with lines upon lines however this is what I believe to be the relevant code:
I'm using grid-template-areas and flexbox. 'main' being one of my template-area's.
HTML:
<main>
<div class="list-box">
<div class="nav-panel">
<a class="nav-div-l nav-pic-bg hover"><img class="nav-pic-l nav-img" src="./img/arrow-left.png" alt="Logout Arrow">
<h2 id="logout-btn">Logout</h2></a>
<a id="user-btn" class="nav-div-c hover"><img class="nav-pic-c nav-img" src="./img/user.jpg" alt="User Picture">
<h2>Username</h2></a>
<a id="settings-btn" class="nav-div-r hover hide-mobile"><h2>Settings</h2>
<img class="nav-pic-r nav-img settings-img" src="./img/white-cog-hi.png" alt="Settings Cog"></a>
<a class="settings-btn hide-desktop"><img class="nav-img" src="./img/white-cog-hi.png" alt="Settings Cog"></a>
</div>
<div id="settings"></div>
<div id="user"></div>
<div id="lists"></div>
</div>
</main>
At the top of this JS file you'll notice a module import. This is simply JS data for the website.
JS:
import data from './data.js';
const settingsBtn = document.getElementById('settings-btn'); // nav links
const logoutBtn = document.getElementById('logout-btn');
const userBtn = document.getElementById('user-btn');
const lists = document.getElementById('lists');
const settings = document.getElementById('settings');
const user = document.getElementById('user');
logoutBtn.addEventListener('click', () => { // change to lists page
displayLists();
settingsBtn.style.display = 'flex';
logoutBtn.innerHTML = 'Logout';
userBtn.style.display = 'flex';
settings.innerHTML = '';
user.innerHTML = '';
});
userBtn.addEventListener('click', () => { // change to user page
displayUser();
settingsBtn.style.display = 'flex';
logoutBtn.innerHTML = 'Back';
userBtn.style.display = 'none';
lists.innerHTML = '';
settings.innerHTML = '';
});
settingsBtn.addEventListener('click', () => { // change to settings page
displaySettings();
settingsBtn.style.display = 'none';
logoutBtn.innerHTML = 'Back';
userBtn.style.display = 'flex';
lists.innerHTML = '';
user.innerHTML = '';
});
const displayLists = () => { // lists
lists.innerHTML += `
<div class="category-panel hide-mobile">
<h3>Name:</h3>
<div class="category-sections">
<div class="category-l"><h3>Items:</h3></div>
<div class="category-c"><h3>Reminders:</h3></div>
<div class="category-r"><h3>Created:</h3></div>
</div>
</div>
`;
for (let i = 0; i < data.lists.length; i++) {
let obj = eval(data.lists[i]);
let totalReminders = getTotalReminders(obj);
lists.innerHTML += `
<a href="./list.html">
<div class="list-item">
<p>${obj.name}</p>
<div class="category-sections">
<p class="category-circle-border">${obj.items.length}</p>
<p class="category-circle-border">${totalReminders}</p>
<p class="date-width">${obj.created}</p>
</div>
</div>
</a>
`;
}
};
const getTotalReminders = passed => {
let total = 0;
for (let i = 0; i < passed.items.length; i++) {
total += passed.items[i].reminders;
}
return total;
};
displayLists();
const displaySettings = () => {
settings.innerHTML = `
<div class="row-auto">
<div class="flex-column hover">
<img class="api-img" src="./img/apple.png" alt="Apple Logo">
<div class="flex">
<h3>Connected</h3>
<div class="circle api-colour-online"></div>
</div>
</div>
<div class="flex-column hover">
<img class="api-img" src="./img/windows.png" alt="Windows Logo">
<div class="flex">
<h3>Connected</h3>
<div class="circle api-colour-online"></div>
</div>
</div>
<div class="flex-column hover">
<img class="api-img" src="./img/android.png" alt="Android Logo">
<div class="flex">
<h3>Not Connected</h3>
<div class="circle api-colour-offline"></div>
</div>
</div>
<div class="flex-column hover">
<img class="api-img" src="./img/google.png" alt="Google Logo">
<div class="flex">
<h3>Connected</h3>
<div class="circle api-colour-online"></div>
</div>
</div>
</div>
<div class="row-auto-c">
<h3>Background:</h3>
</div>
<div class="flex settings-bg-contain-padding">
<img class="settings-bg-pic hover" src="./img/background-0.jpg" alt="Background 1">
<img class="settings-bg-pic hover" src="./img/background-1.jpg" alt="Background 2">
<img class="settings-bg-pic hover" src="./img/background-2.jpg" alt="Background 3">
<img class="settings-bg-pic hover" src="./img/background-3.jpg" alt="Background 4">
<img class="settings-bg-pic hover" src="./img/background-4.jpg" alt="Background 5">
<img class="settings-bg-pic hover" src="./img/background-5.jpg" alt="Background 6">
<div class="hover">
<img class="settings-bg-pic-upload" src="./img/background-0.jpg" alt="Arrow Up">
<p class="black-text">Upload</p>
</div>
</div>
<div class="row-auto">
<div class="flex-column">
<h3>Background On</h3>
<div class="slider">
<div class="slider-back"></div>
<div class="slider-circle"></div>
</div>
</div>
<div class="flex-column">
<h3>Random Slider</h3>
<div class="slider">
<div class="slider-back"></div>
<div class="slider-circle"></div>
</div>
</div>
<div class="flex-column">
<h3>24h Time</h3>
<div class="slider">
<div class="slider-back"></div>
<div class="slider-circle"></div>
</div>
</div>
</div>
`;
const getBG = document.getElementsByClassName('settings-bg-pic');
const changeBG = BG => { // settings background change
for (let i = 0; i < BG.length; i++) {
BG[i].addEventListener('click', () => {
document.body.style.backgroundImage = `url(./img/background-${[i]}.jpg)`;
});
}
};
changeBG(getBG);
const slide = document.querySelectorAll('.slider');
const sliders = (slide) => { // sliders
slide.forEach(slider => slider.addEventListener('click', (i) => {
i.currentTarget.querySelector('.slider-circle').classList.toggle('slider-checked');
}));
};
sliders(slide);
}
const displayUser = () => {
user.innerHTML = ``;
}
While running Parcel Bundler if I click on my links it simply reloads the page and all of my img's are broken with the alt showing.
Ok I found the solution. The problem was with Parcel Bundler and how it bundles the img files to the dist folder. It doesn't like simply putting img src file paths in the innerHTML. It wants you to import the img's into the JS its self. Here is my solution:
import arrowUp from '../img/arrow-up.png';
import arrowDown from '../img/arrow-down.png';
import arrowLeft from '../img/arrow-left.png';
import arrowRight from '../img/arrow-right.png';
import user from '../img/user.jpg';
import apiApple from '../img/apple.png';
import apiWindows from '../img/windows.png';
import apiAndroid from '../img/android.png';
import apiGoogle from '../img/google.png';
import plus from '../img/add.png';
import tick from '../img/tick-green.png';
import cog from '../img/cog.png';
import bin from '../img/bin.png';
import doc from '../img/document.png';
import lock from '../img/lock.png';
import png from '../img/save.png';
import BG0 from '../img/background-0.jpg';
import BG1 from '../img/background-1.jpg';
import BG2 from '../img/background-2.jpg';
import BG3 from '../img/background-3.jpg';
import BG4 from '../img/background-4.jpg';
import BG5 from '../img/background-5.jpg';
import fb from '../img/facebook.png';
import insta from '../img/insta.png';
import twitter from '../img/twitter.png';
module.exports = {
arrows: [
arrowUp, arrowDown, arrowLeft, arrowRight,
],
symbols: [
plus, tick, cog, bin, doc, lock, png,
],
user: [
user,
],
bgImg: [
BG0, BG1, BG2, BG3, BG4, BG5,
],
apiImg: [
apiApple, apiWindows, apiAndroid, apiGoogle,
],
footer: [
fb, insta, twitter,
],
}
Main JS:
import img from './images.js';
<div class="flex settings-bg-contain-padding">
<img class="settings-bg-pic hover" src="${img.bgImgs[0]}" alt="Background 1">
<img class="settings-bg-pic hover" src="${img.bgImgs[1]}" alt="Background 2">
<img class="settings-bg-pic hover" src="${img.bgImgs[2]}" alt="Background 3">
<img class="settings-bg-pic hover" src="${img.bgImgs[3]}" alt="Background 4">
<img class="settings-bg-pic hover" src="${img.bgImgs[4]}" alt="Background 5">
<img class="settings-bg-pic hover" src="${img.bgImgs[5]}" alt="Background 6">
<div class="hover">
<img class="settings-bg-pic-upload" src="${img.bgImgs[0]}" alt="Arrow Up">
<p class="black-text">Upload</p>
</div>
</div>

Categories

Resources