User specific infoProfile pic displayI fixed a ton of bugs I had before.
Goal: Dynamically display all signed up users with their names displayed under their profile pic.
What it does now: Dynamically displays all users(when you click it shows specific user info) and profile pics in seperate divs.
Image:Dynamic images displayed
Snippet:
const dbRef = firebase.database().ref();
const usersRef = dbRef.child('userInfo');
const userListUI = document.getElementById("userList");
usersRef.on("child_added", snap => {
let user = snap.val();
let $h3 = document.createElement("h3");
$h3.innerHTML = user.name;
$h3.setAttribute("child-key", snap.key);
$h3.addEventListener("click", userClicked)
userListUI.append($h3);
});
function userClicked(e) {
var userID = e.target.getAttribute("child-key");
const userRef = dbRef.child('userInfo/' + userID);
const userDetailUI = document.getElementById("userDetail");
userDetailUI.innerHTML = ""
userRef.on("child_added", snap => {
var $p = document.createElement("p");
$p.innerHTML = snap.key + " - " + snap.val()
userDetailUI.append($p);
});
}
var storage = firebase.storage();
var storageRef = storage.ref();
$('#List').find('tbody').html('');
var i = 0;
storageRef.child('users').listAll().then(function(result) {
result.items.forEach(function(imageRef) {
i++;
displayImage(i, imageRef);
});
});
function displayImage(row, images) {
images.getDownloadURL().then(function(url) {
// console.log(url);
let new_html = '';
// new_html += '<tr>';
new_html += '<td>';
// new_html += '</td>';
// new_html += '<td>';
new_html += '<img src= "' + url + '">';
new_html += '</td>';
// new_html += '</tr>';
new_html += row;
$('#List').find('tbody').append(new_html);
});
}
<table id="List">
<tbody>
</tbody>
</table>
<br><br>
<ul id="userList"></ul>
<div id="userDetail">
<p>
<strong class="detailName"></strong>
</p>
</div>
What I've done to try to fix:Googling, playing around with the display image function (tried moving the $('#List').find('tbody').append(new_html); below the 2nd to last });) add something to the new_html to display names but the images.getDownloadURL messes the other stuff I tried because if I add another function after or before it, I'll get an error because the images are stored in storage and the user info is in realtime database. Any pointers?
var userData = docRef.collection("userInfo");
usersRef.on("child_added", snap => {
let user = snap.val();
let $ul = document.createElement("ul");
$ul.innerHTML = user.name;
$ul.setAttribute("child-key", snap.key);
$ul.addEventListener("click", userClicked)
userListUI.append($ul);
});
function userClicked(e) {
var userID = e.target.getAttribute("child-key");
const imageRef = storageRef.child('users/' + userID);
const userRef = dbRef.child('userInfo/' + userID);
// window.location = 'profileview.html';
const userDetailUI = document.getElementById("userDetail");
userDetailUI.innerHTML = "";
userRef.on("child_added", snap => {
var $ul = document.createElement("ul");
$ul.innerHTML = snap.key + " - " + snap.val()
userDetailUI.append($ul);
});
}
Related
I apologize if this is a bit confusing to read, this is my first post.
Please consider the following code:
HTML:
...
<form>
<input type="text" id="to-do-input" placeholder="Add new task..">
<button id="add-to-do" type="button">Add ToDo</button>
</form>
<div id="to-do-container">
</div>
...
JAVASCRIPT:
var addButton = document.getElementById("add-to-do");
toDoArray = [];
addButton.addEventListener("click", function() {
let nHTML = '';
let todoValue = document.getElementById("to-do-input").value;
toDoArray.push(todoValue);
toDoArray.forEach( function(item) {
//READ BELOW
//<!--set each array item's id to it's own string value minus white spaces
var itemId = item.replace(' ','');
item.setAttribute("id", itemId); //console: "item.setAttribute is not a function"
//-->
nHTML += '<li>' + item + ' <button id="delete">Remove</button> </li>';
});
document.getElementById("to-do-container").innerHTML = '<ul>' + nHTML + '</ul>';
document.getElementById("to-do-input").value = '';
});
PROBLEM:
The plan is to set each array item's id value to its own string value minus all spaces via .replace(), but the console is saying:
app.js:17 Uncaught TypeError: item.setAttribute is not a function
at app.js:17:26
at Array.forEach (<anonymous>)
at HTMLButtonElement.<anonymous> (app.js:14:27
I tried to also type item.setAttribute("id", ${itemId}), but that hasn't worked either.
Javascript code:
var addButton = document.getElementById("add-to-do");
toDoArray = [];
addButton.addEventListener("click", function () {
let nHTML = '';
let todoValue = document.getElementById("to-do-input").value;
toDoArray.push(todoValue);
toDoArray.forEach(function (item, index) {
//READ BELOW
//<!--set each array item's id to it's own string value minus white spaces
var itemId = item.replace(' ', '');
// item.setAttribute("id", itemId); //console: "item.setAttribute is not a function"
//--> //This line has been replaced
nHTML += `<li id='${itemId}'>` + item + ` <button id="delete" onclick="dltFun(${index},${itemId})">Remove</button> </li>`; //This line has been replaced
});
document.getElementById("to-do-container").innerHTML = '<ul>' + nHTML + '</ul>';
document.getElementById("to-do-input").value = '';
});
function dltFun(index, itemId) {
let element = document.getElementById(itemId)
element.remove()
toDoArray.splice(index, 1)
}
Fixed JavaScript code:
const addButton = document.getElementById('add-to-do');
const input = document.getElementById('to-do-input');
const toDoContainer = document.getElementById('to-do-container');
const toDoArray = [];
addButton.addEventListener('click', () => {
toDoArray.push(input.value);
toDoContainer.innerHTML = `<ul>${toDoArray
.map(
(todo) =>
`<li id='${todo.replace(
' ',
'',
)}'>${todo}<button id="delete">Remove</button> </li>`,
)
.join('')}</ul>`;
input.value = '';
});
Hope this helps.
I am trying to get a value from a dropdown list. I have the dropdown list and I have the value that I want but I don't know how to link them to each other. So the value of the category should go in the dropdown list and then the image value from that string should be the outcome.
This is the JSON file array called ill.json
...
[{"id":"7","category":"Lente collectie 2021","image":"Teddy_bears_10.png"},{"id":"11","category":"Lente collectie 2021","image":"Individual_floral_elements_01.png"}
...
The category value goes into the dropdown list and then the outcome should be the image value:
This is my dropdown
...
const req = new XMLHttpRequest();
req.open('GET', 'ill.json', true);
req.send();
req.onload = function() {
const json = JSON.parse(req.responseText);
let dropdown = "";
let html = "";
//FILLING DROPDOWN WITH CATEGORYs
var result = json.reduce(function (r, a) {
r[a.category] = r[a.category] || [];
r[a.category].push(a);
return r;
}, Object.create(null));
let keys = Object.keys(result)
keys.forEach((key) => {
dropdown += "<select id='select'>"
dropdown += "<option value='" + key + "'>"
dropdown += key
dropdown += "</option>"
dropdown += "</select"
})
document.getElementsByClassName('dropdown')[0].innerHTML = dropdown;
...
And this is how I got the images
...
//get all images
json.forEach(function(val) {
html += "<div class='illustratie-item'>";
html += "<img class='dt-filelist-image' src='" + val.image + "'/>"
html += "</div><br>";
});
document.getElementsByClassName('illustratie-wrapper')[0].innerHTML = html;
...
If I get that right, it should be as easy as this:
var categorySelect = document.querySelector('.dropdown');
categorySelect.addEventListener('change', function(evt) {
var item = json.find(function(item) {
return item.id === evt.target.value;
});
console.log(item.image); // there's your image
});
Check the below snippet.
var images = [{"id":"7","category":"Lente collectie 2020","image":"Teddy_bears_10.png"},{"id":"11","category":"Lente collectie 2021","image":"Individual_floral_elements_01.png"}];
var dropdown = '';
dropdown += '<select id="select">';
Object.keys(images).forEach(function(key) {
dropdown += '<option value="' + images[key].id + '">';
dropdown += images[key].category;
dropdown += '</option>';
});
dropdown += '</select>';
document.getElementsByClassName('dropdown')[0].innerHTML = dropdown;
var categorySelect = document.querySelector('#select');
categorySelect.addEventListener('change', function(evt) {
var item = images.find(function(item) {
return item.id === evt.target.value;
});
console.log( item.image );
});
<div class="dropdown"></div>
here I'm working with localstorage in javascript
here is my code for enter productDetails in the table using a form. when i'm enter productDetails in the table and refresh the page the entered data is in the table because of localStorage. but my problem is that when I refresh the page and again add new data so that newly added data is replaced with data which is added before refresh the page. and I want all my data instead of replacing
let productDetails = {
};
/**
* this function is for get the value from form
*/
function getValue() {
let id = document.getElementById('productId').value;
let partNo = document.getElementById('productNo').value;
let productName = document.getElementById('productName').value;
let size = getRadioValue();
let color = getCheckBoxValue();
let description = document.getElementById('description').value;
let date = document.getElementById('date').value;
let address = document.getElementById('address').value;
let companyName = document.getElementById('companyName').value;
return {
id, partNo, productName, size, color, description, date, address, companyName
};
}
/**
* function to insert data into table
*/
function insertion() {
let value = getValue();
let letter = value.productName[0];
if (!productDetails.hasOwnProperty(letter)) {
productDetails[letter] = [];
}
let object = {
weight: value.weight, id: value.id, partNo: value.partNo, productName: value.productName, size: value.size, color: value.color, description: value.description,
companyDetails: {
date: value.date,
address: value.address,
companyName: value.companyName
}
};
JSON.parse(window.localStorage.getItem('productDetails'));
productDetails[letter].push(object);
localStorage.setItem("productDetails", JSON.stringify(productDetails));
displayData();
message("");
}
/**
* this function display the data in table
*/
function displayData() {
objectArray = Object.values(productDetails);
display(objectArray);
}
/**
* function to display table
*/
function display() {
var result = JSON.parse(window.localStorage.getItem("productDetails"));
console.log(result)
messageTable(" ");
let table = "<table border = 1 cellpadding = 10 ><th colspan=7 >Product Details</th><th colspan=7 >company Details</th><tr><th>weight</th><th>Product Id</th><th>Part No</th><th>Name</th><th>Size</th><th>Color</th><th>Description</th><th>Date</th><th>Address</th><th>Company name</th></tr>";
for (var key in result) {
for (var weight in result[key]) {
//let companyDetails = result[key][weight].companyDetails ? result[key][weight].companyDetails : { date: "", address: "", companyName: "" };
table += "<tr><td>" + key + "</td>";
table += "<td>" + result[key][weight].id + "</td>";
table += "<td>" + result[key][weight].partNo + "</td>";
table += "<td>" + result[key][weight].productName + "</td>";
table += "<td>" + result[key][weight].size + "</td>";
table += "<td>" + result[key][weight].color + "</td>";
table += "<td>" + result[key][weight].description + "</td>";
table += "<td>" + result[key][weight].companyDetails.date + "</td>";
table += "<td>" + result[key][weight].companyDetails.address + "</td>";
table += "<td>" + result[key][weight].companyDetails.companyName + "</td>";
}
} messageTable(table);
console.log(result)
}
What you need to do is add a check looking for the localstorage key for your data when the page loads, if the check is true then add the previous localstorage data to your productDetails object. This is the Example =>
window.onload = init;
var arr = [];
function init() {
if(localStorage.getItem("productDetails")) {
arr.push(JSON.parse(localStorage.getItem("productDetails")));
getValue(); /*Then Continue eg.Refer to a function*/
}
else {
getValue(); /*Do something eg.Refer to a function*/
}
}
The concept is when the page loads add a window.onload function to check whether the localStorage key "productDetails" exists. If the key exist then add/push the value stored by the key to the array arr in this example. If it does not exist then eg. Do something like => Refer to a function.
I got the data stored on my localStorage and display them in table format with each row having a button. What I want to do now is, when the button is clicked I want it to change the background color to another color and when the page refreshes the button persists its color state.
Here is my code
// here i will be the data in form of table
// my algorithm comes here
// this function will get data from the localstorage
const get_todos = ()=>{
let todos = new Array();
let todos_str = localStorage.getItem("todo");
if(todos_str !== null){
todos = JSON.parse(todos_str);
}
return todos;
}
//this function will show the data in the localstorage in table format
const show = ()=>{
let todos = get_todos();
let text = "";
for(let i = 0; i < todos.length; i++){
let allData = todos[i];
let eventName = allData.Eventname;
let location = allData.Location;
let date = allData.Date;
text += "<tr>";
text += "<td>" + eventName + "</td>";
text += "<td>" + location + "</td>";
text += "<td>" + date + "</td>";
text += "<td>" + "<button class='buttons' type='button'>Pending</button>" + "</td>";
text += "<td>" + "<i id='remove' class='fas fa-trash-alt btndelete'></i>" + "</td></tr>";
}
//the data gotten from the localstorage will be here
let table = document.querySelector("#table > tbody");
table.innerHTML = text;
//this is where the button background color will change
window.addEventListener("load", ()=>{
let thead = document.querySelector("#thead");
let buttons = Array.from(document.querySelectorAll(".buttons"));
thead.addEventListener("click", (e)=>{
if(e.target.className === "buttons"){
let index = buttons.indexOf(e.target);
changeBackground(e, index);
}
});
buttons.forEach(btn, index =>{
btn.className = sessionStorage.getItem('background${index}') || 'buttons';
});
});
const changeBackground = (e, index)=>{
e.target.className += "change";
sessionStorage.setItem(background${index}, e.target.className);
}
}
window.addEventListener("DOMContentLoaded", ()=>{
show();
});
There is few errors in your code:
First:
btn.className = sessionStorage.getItem('background${index}') || 'buttons';
Should be:
btn.className = sessionStorage.getItem(`background${index}`) || 'buttons';
because you are create a string using Template literals (Template strings)
Second:
e.target.className += "change";
Should be:
e.target.className += " change";
You have to add space when concatenate strings, or else in your case it will not provide the intended behavior, since your code will add change class name to the previous class as one word.
Third:
sessionStorage.setItem(background${index}, e.target.className);
Should be:
sessionStorage.setItem(`background${index}`, e.target.className);
In your question you are talking about localStorage but you are
using sessionStorage, Still not sure if this what you want, so if you want it to be localStorage just replace sessionStorage with localStorage
// here i will be the data in form of table
// my algorithm comes here
// this function will get data from the localstorage
const get_todos = ()=>{
let todos = new Array();
let todos_str = localStorage.getItem("todo");
if(todos_str !== null){
todos = JSON.parse(todos_str);
}
return todos;
}
//this function will show the data in the localstorage in table format
const show = ()=>{
let todos = get_todos();
let text = "";
for(let i = 0; i < todos.length; i++){
let allData = todos[i];
let eventName = allData.Eventname;
let location = allData.Location;
let date = allData.Date;
text += "<tr>";
text += "<td>" + eventName + "</td>";
text += "<td>" + location + "</td>";
text += "<td>" + date + "</td>";
text += "<td>" + "<button class='buttons' type='button'>Pending</button>" + "</td>";
text += "<td>" + "<i id='remove' class='fas fa-trash-alt btndelete'></i>" + "</td></tr>";
}
//the data gotten from the localstorage will be here
let table = document.querySelector("#table > tbody");
table.innerHTML = text;
//this is where the button background color will change
window.addEventListener("load", ()=>{
let thead = document.querySelector("#thead");
let buttons = Array.from(document.querySelectorAll(".buttons"));
thead.addEventListener("click", (e)=>{
if(e.target.className === "buttons"){
let index = buttons.indexOf(e.target);
changeBackground(e, index);
}
});
buttons.forEach(btn, index =>{
btn.className = localStorage.getItem(`background${index}`) || 'buttons';
});
});
const changeBackground = (e, index)=>{
e.target.className += " change";
localStorage.setItem(`background${index}`, e.target.className);
}
}
window.addEventListener("DOMContentLoaded", ()=>{
show();
});
I am trying to get images from a Firebase Storage into a table, and the links to each image are given as a Child in a Firebase Database. By following many of the SE recommendations, I finally got a code that can convert images from from gs:// to http://. By using alert(url), I can see the image link that can potentially be inserted in a <img>, but I can't manage to make it show as an image object. What am I doing wrong in the code? Can anyone help me to elucidate this?
In the code below, imageUrl contains the gs:// code
< script >
var events = firebase.database();
var storage = firebase.storage();
events.ref("-Events").orderByKey().limitToLast(10).once('value', function(snapshot) {
if (snapshot.exists()) {
var content = '';
snapshot.forEach(function(data) {
var val = data.val();
var link = val.imageUrl;
var storageRef = storage.refFromURL(link).getDownloadURL().then(function(url) {
var test = url;
alert(url);
document.querySelector('img').src = test;
alert(test);
}).catch(function(error) {});
content += '<tr>';
content += '<td>' + val.imageUrl + '</td>';
content += '<td>' + '<img src="storageRef.url" alt='
' border=3 height=100 width=100>' + '</td>';
content += '</tr>';
});
$('#ex-table').append(content);
var tbody = $('table tbody');
tbody.html($('tr', tbody).get().reverse());
}
});
<
/script>