Why are muiltiple users not showing in WebRTC - javascript

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);
}
};
})();

Related

What am I doing wrong here? The count is being stored and transferred to the other group of buttons

I have been struggling with this, please can you help? Here is the code. I want the group buttons to work independently from each other. F.example, if I press the Home buttons, the count should not transfer to the Guest button. It should begin from zero when clicked, but it counts what has been stored in the variable prior to it being clicked.
const homeScreen = document.getElementById("home-screen");
const guestScreen = document.getElementById("guest-screen");
let count = 0;
homeScreen.textContent = 0;
guestScreen.textContent = 0;
const plusOne = () => {
count += 1;
guestScreen.textContent = count;
}
const plusTwo = () => {
count += 2;
guestScreen.textContent = count;
}
const plusThree = () => {
count += 3;
let result = guestScreen.textContent = count;
if (result.length !== 0) {
return result;
}
}
const reset = () => {
guestScreen.textContent = 0;
}
const homeOne = () => {
count += 1;
homeScreen.textContent = count;
console.log("Clicked Home");
}
<div class="container">
<div class="d-flex justify-content-between bd-highlight mb-2">
<div id="left">
<h3 class="home">HOME</h3>
<span id="home-screen" class="float-start rounded"></span>
<div>
<button onclick="homeOne()" class="btn btn-info">+1</button>
<button onclick="homeTwo()" class="btn btn-info">+1</button>
<button onclick="homeThree()" class="btn btn-info">+1</button>
</div>
</div>
<div><Button onclick="reset()" class="btn reset">Reset</Button> </div>
<div id="left">
<h3 class="text">GUEST</h3>
<span id="guest-screen" class="float-end rounded"></span>
<div>
<button onclick="plusOne()" class="btn ">+1</button>
<button onclick="plusTwo()" class="btn ">+1</button>
<button onclick="plusThree()" class="btn ">+1</button>
</div>
</div>
</div>
<div class="row">
<div class="row">
<div class="row">
<div class="col-sm-4">
</div>
<div class="row">
<div class="col-sm-5">
</div>
</div>
</div>
</div>
</div>
</div>
Then use two different variable: homeCount and guestCount .
const homeScreen = document.getElementById("home-screen");
const guestScreen = document.getElementById("guest-screen");
let homeCount = 0;
let guestCount = 0;
homeScreen.textContent = 0;
guestScreen.textContent = 0;
const plusOne = () => {
guestCount += 1;
guestScreen.textContent = guestCount;
}
const plusTwo = () => {
guestCount += 2;
guestScreen.textContent = guestCount;
}
const plusThree = () => {
guestCount += 3;
guestScreen.textContent = guestCount;
// Unclear what was attempted here...
// let result = guestScreen.textContent = guestCount;
// if (result.length !== 0) {
// return result;
// }
}
const reset = () => {
guestScreen.textContent = 0;
}
const homeOne = () => {
homeCount += 1;
homeScreen.textContent = homeCount;
}
const homeTwo = () => {
homeCount += 2;
homeScreen.textContent = homeCount;
}
const homeThree = () => {
homeCount += 3;
homeScreen.textContent = homeCount;
}
<div class="container">
<div class="d-flex justify-content-between bd-highlight mb-2">
<div id="left">
<h3 class="home">HOME</h3>
<span id="home-screen" class="float-start rounded"></span>
<div>
<button onclick="homeOne()" class="btn btn-info">+1</button>
<button onclick="homeTwo()" class="btn btn-info">+2</button>
<button onclick="homeThree()" class="btn btn-info">+3</button>
</div>
</div>
<div><Button onclick="reset()" class="btn reset">Reset</Button> </div>
<div id="left">
<h3 class="text">GUEST</h3>
<span id="guest-screen" class="float-end rounded"></span>
<div>
<button onclick="plusOne()" class="btn ">+1</button>
<button onclick="plusTwo()" class="btn ">+2</button>
<button onclick="plusThree()" class="btn ">+3</button>
</div>
</div>
</div>
<div class="row">
<div class="row">
<div class="row">
<div class="col-sm-4">
</div>
<div class="row">
<div class="col-sm-5">
</div>
</div>
</div>
</div>
</div>
</div>

JavaScript dynamic card rendering in inner HTML

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:

How do I add new text after all functions are executed?

I want to have a line of text "oh no you are staving" to show up only after all items are removed. So in this case it means all the function are executed. Do I have to create a if statement?
Sorry I am really new to programming so I know my code is very wonky. Thanks for helping still!
function ateKroket() {
var delFood = document.getElementById("kroket");
delFood.remove();
}
function ateCake() {
var delFood = document.getElementById("cake");
delFood.remove();
}
function atePizza() {
var delFood = document.getElementById("pizza");
delFood.remove();
}
function ateSushi() {
var delFood = document.getElementById("sushi");
delFood.remove();
}
<div id="foodStorage">
<div id="kroket">
<img class="foodImg" src= "images/kroket.jpg">
<div><h5 id="foodName">Kroket</h5>
<button class="ateBtn" onclick="ateKroket()">Ate</button>
</div>
</div>
<div id="cake">
<img class="foodImg" src= "images/cake.jpg">
<div><h5 id="foodName">Cake</h5>
<button class="ateBtn" onclick="ateCake()">Ate</button>
</div>
</div>
<div id="pizza">
<img class="foodImg" src= "images/pizza.jpg">
<div><h5 id="foodName">Pizza</h5>
<button class="ateBtn" onclick="atePizza()">Ate</button>
</div>
</div>
<div id="sushi">
<img class="foodImg" src= "images/sushi.jpg">
<div><h5 id="foodName">Sushi</h5>
<button class="ateBtn" onclick="ateSushi()">Ate</button>
</div>
</div>
Add the following:
(To HTML):
<div id="foodEaten" style="display:none;">4</div>
(Then to your Javascript):
function ateKroket() {
var delFood = document.getElementById("kroket");
delFood.remove();
checkFood()
}
function ateCake() {
var delFood = document.getElementById("cake");
delFood.remove();
checkFood()
}
function atePizza() {
var delFood = document.getElementById("pizza");
delFood.remove();
checkFood()
}
function ateSushi() {
var delFood = document.getElementById("sushi");
delFood.remove();
checkFood()
}
function checkFood(){
var foodLeft = parseInt(document.getElementById('foodEaten').innerHTML);
foodLeft = foodLeft-1;
document.getElementById('foodEaten').innerHTML = foodLeft;
if(foodLeft<1){
console.log("starving");
//DO WHATEVER YOU WANT WHEN NO FOOD LEFT
}
}
What this will do is edit an invisible counter of food left each time a button is clicked, and then action something if that counter is a certain value
You should make use of classes to make your code more maintainable/reusable wihout repetition. Here is an example where I added a food class to each food div:
var foodStorage = document.getElementById('foodStorage'),
ateBtns = document.querySelectorAll('.ateBtn');
ateBtns.forEach(function(btn) {
btn.addEventListener('click', function() {
foodStorage.removeChild(this.closest('.food'));
if (foodStorage.children.length === 0) {
alert('Oh no, you are starving!');
}
});
});
<div id="foodStorage">
<div class="food">
<div><h5>Kroket</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
<div class="food">
<div><h5 id="foodName">Cake</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
<div class="food">
<div><h5>Pizza</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
<div class="food">
<div><h5>Sushi</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
</div>
You could declare a variable counter:
var food = 4;
function ateKroket() {
var delFood = document.getElementById("kroket");
delFood.remove();
checkfood()
}
function ateCake() {
var delFood = document.getElementById("cake");
delFood.remove();
checkfood()
}
function atePizza() {
var delFood = document.getElementById("pizza");
delFood.remove();
checkfood()
}
function ateSushi() {
var delFood = document.getElementById("sushi");
delFood.remove();
checkfood()
}
function checkfood() {
food--;
if (food === 0) {
document.getElementById("starving").style.display = "block";
}
}
#starving {
display: none;
}
<div id="foodStorage">
<div id="kroket">
<img class="foodImg" src="images/kroket.jpg">
<div>
<h5 id="foodName">Kroket</h5>
<button class="ateBtn" onclick="ateKroket()">Ate</button>
</div>
</div>
<div id="cake">
<img class="foodImg" src="images/cake.jpg">
<div>
<h5 id="foodName">Cake</h5>
<button class="ateBtn" onclick="ateCake()">Ate</button>
</div>
</div>
<div id="pizza">
<img class="foodImg" src="images/pizza.jpg">
<div>
<h5 id="foodName">Pizza</h5>
<button class="ateBtn" onclick="atePizza()">Ate</button>
</div>
</div>
<div id="sushi">
<img class="foodImg" src="images/sushi.jpg">
<div>
<h5 id="foodName">Sushi</h5>
<button class="ateBtn" onclick="ateSushi()">Ate</button>
</div>
</div>
<div id="starving">
oh no you are starving
</div>
</div>
Or something much more optimized:
document.getElementById("foodStorage").addEventListener("click", function(e) {
if (e.target.classList.contains("ateBtn")) {
e.target.parentElement.parentElement.remove();
if (this.childElementCount === 1) {
document.getElementById("starving").style.display = "block";
}
}
});
#starving {
display: none;
}
<div id="foodStorage">
<div id="kroket">
<img class="foodImg" src="images/kroket.jpg">
<div>
<h5 id="foodName">Kroket</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
<div id="cake">
<img class="foodImg" src="images/cake.jpg">
<div>
<h5 id="foodName">Cake</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
<div id="pizza">
<img class="foodImg" src="images/pizza.jpg">
<div>
<h5 id="foodName">Pizza</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
<div id="sushi">
<img class="foodImg" src="images/sushi.jpg">
<div>
<h5 id="foodName">Sushi</h5>
<button class="ateBtn">Ate</button>
</div>
</div>
<div id="starving">
oh no you are starving
</div>
</div>

how to get the array from the javascript function to the html form as input field value by body onload() function?

I am having 6 bootstrap cards where the card details are id,content. Onclick of every card I am getting the ids of clicked card into the array from the local storage now I want to send that ids to the html form as value for input field
My html code is:
<body onload = "sample(),issample()">
<div class="form-group" >
<input type="text" name="goal" id="goal" value=" ">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="text" name="email" class="form-control" required>
</div>
<div class="form-group">
<label for="password2">Password</label>
<input type="password" name="password" class="form-control" required>
</div>
<input type="submit" value="Register" class="btn btn-secondary btn-block">
My JS code is :
var goal = []
function getGoal(id, content) {
if (goal.length > 0) {
var data = { id: id, content: $("#cont_" + id).text() }
var x = JSON.stringify(data)
var index = goal.indexOf(x)
if (index == -1) {
goal.push(x)
}
else {
goal.splice(index, 1)
}
}
else {
var data = { id: id, content: $("#cont_" + id).text() }
var x = JSON.stringify(data)
goal.push(x)
}
localStorage.setItem("goal", JSON.stringify(goal))
// To get all ids
var storedNames = JSON.parse(localStorage.getItem("goal"))
var goalIds = []
if (storedNames)
storedNames.forEach(element => {
element = JSON.parse(element)
goalIds.push(element.id)
});
console.log(goalIds)
}
function issample(){
$("#goal").val(goalIds);
}
I am getting error as goalIds not defined but the goalIds array is getting the ids but that ids are not getting in the form as a value how can I access the goalids in the other function
My cards code is
<div class="col-4" onclick="getGoal(1)">
<div class="card4 mt-3" id="room_1" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_1"><b>I am redecorating</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(2)">
<div class="card4 mt-3" id="room_2" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_2"><b>I am moving</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(3)">
<div class="card4 mt-3" id="room_3" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_3"><b>I need help with a layout</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(4)">
<div class="card4 mt-3" id="room_4" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_4"><b>I am looking for species</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(5)">
<div class="card4 mt-3" id="room_5" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_5"><b>I am moving in someone</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(6)">
<div class="card4 mt-3" id="room_6" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_6"><b>other</b></p>
</div>
</center>
</div>
</div>
My styles code is:
var styles = []
var styleIds = []
function getStyle(id) {
if (styles.length > 0) {
var data = { id: id, image: $("#img_"+id).attr('src'),content: $("#cont_" + id).text() }
var x = JSON.stringify(data)
var index = styles.indexOf(x)
if (index == -1) {
styles.push(x)
}
else {
styles.splice(index, 1)
}
}
else {
var data = { id: id, image: $("#img_"+id).attr('src'),content: $("#cont_" + id).text() }
var x = JSON.stringify(data)
styles.push(x)
}
localStorage.setItem("styles", JSON.stringify(styles))
styleIds = styles.map(element => JSON.parse(element).id);
console.log(styleIds)
assample();
}
function assample() {
$("#style").val(styleIds);
console.log(styleIds)
}
function initStyles() {
var storedNames = JSON.parse(localStorage.getItem("styles") || '[]');
styleIds = storedNames.map(element => JSON.parse(element).id);
}
You need to make goalIds a global variable so it can be used in both functions.
Use storedNames.map() when assigning it, so it will be reset each time.
getGoal() doesn't use the content parameter, you can just remove that.
You should call issample() at the end of getGoal() to update the input field.
var goal = []
var goalIds = [];
function getGoal(id) {
if (goal.length > 0) {
var data = {
id: id,
content: $("#cont_" + id).text()
}
var x = JSON.stringify(data)
var index = goal.indexOf(x)
if (index == -1) {
goal.push(x)
} else {
goal.splice(index, 1)
}
} else {
var data = {
id: id,
content: $("#cont_" + id).text()
}
var x = JSON.stringify(data)
goal.push(x)
}
localStorage.setItem("goal", JSON.stringify(goal))
goalIds = goal.map(element => JSON.parse(element).id);
console.log(goalIds)
issample();
}
function issample() {
$("#goal").val(goalIds);
}
To initialize goalIds when the page is loaded, add another function:
function initGoals() {
var storedNames = JSON.parse(localStorage.getItem("goal") || '[]');
goalIds = storedNames.map(element => JSON.parse(element).id);
}
And call initGoals() in your onload:
<body onload="sample(); initGoals(); issample();">

Javascript onclick does not work, multiple images to click in a row

I've tried to combine code I found (I don't know JS too well), and I click on the image in the DOM (mockup2.png), but nothing happens. It is supposed to go to mockup3.png, and then another click takes it to mockup4.png etc. For context, some of the other code is using Bootstrap and Razor. Any idea why the clicking does nothing?
#{
ViewBag.Title = "Marketplace";
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="~/Content/Login.css" />
<link rel="stylesheet" type="text/css" href="~/Content/Site.css" />
<script>
$(document).ready(
function () {
$('#studentnavicons a').hover(
function () {
$("#studentnaviconstext p").text($(this).attr("title"));
}
});
</script>
<script type="text/javascript">
var checkbox = document.getElementById('wireframe-student');
var img = <img src="~/Content/img/Student Market/market_mockup2.png" />;
var img1 = <img src="~/Content/img/Student Market/market_mockup3.png" />;
var img2 = <img src="~/Content/img/Student Market/market_mockup4.png" />;
var img3 = <img src="~/Content/img/Student Market/market_mockup5.png" />;
checkbox.onclick = function () {
if (checkbox.src == img) {
checkbox.src = img1;
} else if (checkbox.src == img1) {
checkbox.src = img2;
} else if (checkbox.src == img2) {
checkbox.src = img3;
} else {
checkbox.src = img3;
}
}
</script>
<div class="background">
<div class="row text-center">
<h1 class="student-header" align="center">Marketplace</h1>
<div id="studentnavicons">
<i class="fas fa-store-alt" style="color:#7a553b"></i>
<i class="fas fa-map-signs" style="color:#7a553b"></i>
<i class="fas fa-shopping-cart" style="color:#7a553b"></i>
<i class="fas fa-trophy" style="color:#7a553b"></i>
<i class="fas fa-user" style="color:#7a553b"></i>
<i class="fas fa-sign-out-alt" style="color:#7a553b"></i>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="boxed" align="center">
<font size="10">Points: 150</font>
</div>
<img id="wireframe-student" src="~/Content/img/Student Market/market_mockup2.png" width="1000" class="img-responsive" />
<div class="col-md-4">
<div style="float: right; margin-top:-70px;" align="center">
#Html.ActionLink("Sell", "MarketAfter", "Student", null, new { #class = "btn btn-primary" })
</div>
</div>
<div class="col-md-4">
<div style="float:right; margin-top:-70px;" align="center">
#Html.ActionLink("Buy", "MarketAfter", "Student", null, new { #class = "btn btn-primary" })
</div>
</div>
</div>
</div>
</div>
Trying the JQuery, but still nothing:
#{
ViewBag.Title = "Marketplace";
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="~/Content/Login.css" />
<link rel="stylesheet" type="text/css" href="~/Content/Site.css" />
<script>
$(document).ready(
function () {
$('#studentnavicons a').hover(
function () {
$("#studentnaviconstext p").text($(this).attr("title"));
}
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
$('#wireframe-student').on('click', function () {
var img_src = $(this).attr('alt');
if (img_src == 'image1') {
$(this).attr({ src: '/Content/img/Student Market/Market_demo3.png', alt: 'image2' });
} else if (img_src == 'image2') {
$(this).attr({ src: '/Content/img/Student Market/Market_demo4.png', alt: 'image3' });
} else if (img_src == 'image3') {
$(this).attr({ src: '/Content/img/Student Market/Market_demo5.png', alt: 'image4' });
} else {
/* carry on..... */
}
});
</script>
<div class="background">
<div class="row text-center">
<h1 class="student-header" align="center">Marketplace</h1>
<div id="studentnavicons">
<i class="fas fa-store-alt" style="color:#7a553b"></i>
<i class="fas fa-map-signs" style="color:#7a553b"></i>
<i class="fas fa-shopping-cart" style="color:#7a553b"></i>
<i class="fas fa-trophy" style="color:#7a553b"></i>
<i class="fas fa-user" style="color:#7a553b"></i>
<i class="fas fa-sign-out-alt" style="color:#7a553b"></i>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="boxed" align="center">
<font size="10">Points: 150</font>
</div>
<div class="row">
<div class="col-md-12">
<img id="wireframe-student" src="/Content/img/Student Market/Market_demo2.png" width="1000" class="img-responsive" alt="image1" />
</div>
</div>
<div class="col-md-4">
<div style="float: right; margin-top:-70px;" align="center">
#Html.ActionLink("Sell", "MarketAfter", "Student", null, new { #class = "btn btn-primary" })
</div>
</div>
<div class="col-md-4">
<div style="float:right; margin-top:-70px;" align="center">
#Html.ActionLink("Buy", "MarketAfter", "Student", null, new { #class = "btn btn-primary" })
</div>
</div>
</div>
</div>
</div>
try changing this
var checkbox = document.getElementById('wireframe-student');
var img = <img src="~/Content/img/Student Market/market_mockup2.png" />;
var img1 = <img src="~/Content/img/Student Market/market_mockup3.png" />;
var img2 = <img src="~/Content/img/Student Market/market_mockup4.png" />;
var img3 = <img src="~/Content/img/Student Market/market_mockup5.png" />;
to
var checkbox = document.getElementById('wireframe-student');
var img = "~/Content/img/Student Market/market_mockup2.png";
var img1 = "~/Content/img/Student Market/market_mockup3.png";
var img2 = "~/Content/img/Student Market/market_mockup4.png";
var img3 = "~/Content/img/Student Market/market_mockup5.png";
i changed the code in the second block you can refer it here
https://jsfiddle.net/3pan85xv/
just the after click part more readable then if else loop
<script>
$(function() {
// Handler for .ready() called.
$('#wireframe-student').on('click', function () {
var img_src = $(this).attr('alt');
switch(img_src){
default :
case 'image1': $(this).attr({ src: '/Content/img/Student Market/Market_demo3.png', alt: 'image2' });
break;
case 'image2': $(this).attr({ src: '/Content/img/Student Market/Market_demo4.png', alt: 'image3' });
break;
case 'image3': $(this).attr({ src: '/Content/img/Student Market/Market_demo5.png', alt: 'image4' });
break;
}
});
});
</script>
new fiddle with the changes i just did https://jsfiddle.net/shyamjoshi/qoa3jfq1/1/
I think you should try this jQuery code.
For easy understanding keep short image name in img's alt tag
to differentiate on each click and change image name on each click for next image.
I hope this will help..!
$('#wireframe-student').on('click', function(){
var img_src = $(this).attr('alt');
if(img_src == 'image1') {
$(this).attr({src:'http://via.placeholder.com/150x160',alt:'image2'});
} else if(img_src == 'image2') {
$(this).attr({src:'http://via.placeholder.com/150x170',alt:'image3'});
} else if(img_src == 'image3') {
$(this).attr({src:'http://via.placeholder.com/150x180',alt:'image4'});
} else {
/* carry onn..... */
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-md-12">
<img id="wireframe-student" src="http://via.placeholder.com/150x150" width="" class="img-responsive" alt="image1" />
</div>
</div>

Categories

Resources