First of all, i'm a newb to HTML and JS and my english is not the best so sorry about that.
I have an id on a HTML element. I want to add content to this element with a function and create another element (inside the first one), with a new ID and then modify this last ID with a function that runs after the first one.
The id i have defined in HTML is "product-container"
With the function "show product()" i want to create its content and to create a div for its images (id=images-div), which i will add with the function "appendImages()".
I honestly don't know how to do this with only 1 function becouse the item has multiple images and i dont know how to iterate them in a for inside the innerHTML. But i think i should be able to do it this way.
I'm not sure if the problem is that i'm defining the variable (let imagesDiv = document.getElementById("images-div")) before the element is created...
HTML Code:
<div class="list-group" id="product-container"> </div>
JS Code:
const URL = PRODUCT_INFO_URL + localStorage.getItem("productID") + EXT_TYPE
let productContainer = document.getElementById("product-container")
let imagesDiv = document.getElementById("images-div")
let relatedProducts =document.getElementById("related-products")
let currentProduct = [];
function appendImages(){
let HTMLContentToAppend = "";
for (let productImage of product.images){
HTMLContentToAppend +=`
<div class="col-3">
<img src="${productImage}" alt="${product.name}" class="img-thumbnail">
</div>`
}
imagesDiv.innerHTML = HTMLContentToAppend
}
function showProduct(){
let product = currentProduct
productContainer.innerHTML = `
<div class="list-group-item">
<h1> ${product.name} </h1>
<hr>
<div class="col">
<div class="justify-content-between">
<h4 class="mb-1"> Precio </h4>
<p> ${product.currency} ${product.cost}
</div>
<div class="justify-content-between">
<h4 class="mb-1"> Descripción </h4>
<p> ${product.description}
</div>
<div class="justify-content-between">
<h4 class="mb-1"> Categoría </h4>
<p> ${product.category}
</div>
<div class="justify-content-between">
<h4 class="mb-1"> Cantidad de Vendidos </h4>
<p> ${product.soldCount}
</div>
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3" id="images-div">
</div>
</div>
</div>`;
appendImages()
};
Thanks in advance for the help and sorry for the newby question :/
What you assumed to be the problem is actually the problem. Move let imagesDiv = document.getElementById("images-div") inside the appendImages function.
Related
I am new on laravel framework.
I have created an component (lecture-content) having some files input options, and there is an button onclick which should add one more (lecture-content) component. On DOM.
function addContent()
{
let newDoc = "#include('inc.lecture-content')";
let extendContent = document.getElementById('addNew').innerHtml;
console.log(extendContent);
console.log(newDoc);
extendContent+=newDoc;
document.getElementById('addNew').innerHtml= extendContent;
}
<div class="cariculum-heading my-2">
<h5 class="my-auto py-auto font-weight-normal ">Curriculum </h5>
<button class="px-2 btn my-auto py-auto add-content-btn" onclick="addContent()" id="add-content">+ content</button>
</div>
<div class="content-section" id="addNew">
#include('inc.lecture-content')
</div>
but this is not working at this position let newDoc = "#include('inc.lecture-content')"; it shows syntax error. can anyone help me to resolve it. What I am doing wrong here
Use clone()
Below jQuery code will fulfill your purpose.
function addContent()
{
var clone = $('#addNew').clone().css('display','block');
$('#newEle').append(clone);
}
Add one more div to your blade file.
<div id="newEle">
</div>
This newly created div will be used to append cloned div.
function addContent()
{
var clone = $('#addNew').clone().css('display','block');
$('#newEle').append(clone);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cariculum-heading my-2">
<h5 class="my-auto py-auto font-weight-normal ">Curriculum </h5>
<button class="px-2 btn my-auto py-auto add-content-btn" onclick="addContent()" id="add-content">+ content</button>
</div>
<div id="newEle">
</div>
<div class="content-section" id="addNew" style="display: none;">
#include('inc.lecture-content')
</div>
So, recently I made a project where the Javascript just create an element and getting the data from Firebase Firestore database then append it to the body of HTML. This consist of a div which act as the box container with object.className, h4 act as title, some p as texts. But, all of those elements I've added isn't visible on the webpage. But surprisingly, if I open the Inspect element, and call console.log(object) of one of the object, they will show up HTML tag element that exactly what I want and when I hover it, it will show up a highlighted area in the webpage that sized exactly what I want. But, still not visually visible. Actually, in the HTML document, I've added some boxes and element before the element from Javascript, and if I add some new element from the HTML, the element from Javascript is pushed after the newly added element from HTML. So, can someone help me? I'm a newbie in this field. Thank you.
1.) Part of the HTML Element (The Firebase is well set-up here)
<body>
<div class="big-container">
<div class="title">
<span class="title-text">Kompor</span>
</div>
<nav id="wrapper">
<!-- ONE DIV CALLED "IMPORTANT" is necessary for the last box visible -->
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box 2">
<h4 class="title-box">Rinnai 522-A</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div onclick="" class="box">
<h4 class="title-box">Rinnai 522-E</h4>
<p class="tc-1">HB</p>
<p class="tc-2">313.000</p>
<p class="tc-3">HJ</p>
<p class="tc-4">345.000</p>
</div>
<div class="box"></div>
<div class="box"></div>
<div class="important"></div>
</nav>
</div>
2.) JS
//DOMstart
const docTarget = document.querySelector('#wrapper');
function insertDoc(doc){
//creation
let box = document.createElement('div');
let header = document.createElement('h4');
let hargaBeli = document.createElement('p');
let p2 = document.createElement('p');
let hargaJual = document.createElement('p');
let p4 = document.createElement('p');
//insertion
header.textContent = doc.data().name;
hargaBeli.innerHTML = "HB";
p2.textContent = doc.data().HB;
hargaJual.innerHTML = "HJ";
p4.textContent = doc.data().HJ;
console.log(box);
console.log(header);
console.log(hargaBeli);
console.log(p2);
console.log(hargaJual);
console.log(p4);
//naming
box.classname = "box";
header.className = "title-box";
hargaBeli.className = "tc-1";
p2.className = "tc-2";
hargaJual.className = "tc-3";
p4.className = "tc-4";
//box-naming plus deletion ops
var hitung = 1;
hitung++;
console.log(hitung);
box.className = "box " + hitung;
box.onclick = function(){
if (confirm('Apa kamu yakin mau menghapus produk ini?')) {
this.parentElement.removeChild(this);
} else {
console.log('Tidak jadi menghapus produk.');
}
}
//appending...
box.appendChild(header);
box.appendChild(hargaJual);
box.appendChild(p2);
box.appendChild(hargaBeli);
box.appendChild(p4);
docTarget.appendChild(box);
console.log(box.className + "Creation Tracker"); //detection
}
//get doc
var doc;
db.collection('Product').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
insertDoc(doc);
})
})
The CSS is connected well and as you can see working well with those elements from HTML document.
As I tried your HTML and javascript code on jsbin, I see that it worked well. The problem is your variable doc, you might add console.log to get the variable again to see why, or you can paste your data structure for further debug.
https://jsbin.com/jeyamoqabu/edit?html,js,output
I'm trying to filter data gotten from database with the class="data-groups".
Here is the code:
this.shuffle.filter(function(element, shuffle) {
// If there is a current filter applied, ignore elements that don't match it.
if (shuffle.group !== Shuffle.ALL_ITEMS) {
// Get the item's groups.
var groups = JSON.parse(element.getAttribute('data-groups'));
var isElementInCurrentGroup = groups.indexOf(shuffle.group) !== -1;
// Only search elements in the current group
if (!isElementInCurrentGroup) {
return false;
}
}
var titleElement = element.querySelector('.book-item_title');
var titleText = titleElement.textContent.toLowerCase().trim();
return titleText.indexOf(searchText) !== -1;
});
};
<!-- begin snippet: js hide: false console: true babel: false -->
<div class="grid-shuffle">
<ul id="grid" class="row">
#foreach($libraries as $library)
<li class="book-item small-12 medium-6 columns" data-groups='["{{$library->genre}}"]' data-date-created='{{$library->published}}' data-title='{{ $library->title }}' data-color='{{$library->color}}'>
<div class="bk-img">
<div class="bk-wrapper">
<div class="bk-book bk-bookdefault">
<div class="bk-front">
<div class="bk-cover" style="background-image: url('img/001-small.png')"></div>
</div>
<div class="bk-back"></div>
<div class="bk-left"></div>
</div>
</div>
</div>
<div class="item-details">
<h3 class="book-item_title">{{$library->title}}</h3>
<p class="author">{{$library->author}} • {{$library->published}}</p>
<p>{{$library->synopsis}}</p>
Details
</div>
<div class="overlay-details">
Close
<div class="overlay-image">
<img src="img/001.jpg" alt="Book Cover">
<div class="back-color"></div>
</div>
<div class="overlay-desc activated">
<h2 class="overlay_title">{{$library->title}}</h2>
<p class="author">by {{$library->author}}</p>
<p class="published">{{$library->published}}</p>
<p class="synopsis">{{ $library->synopsis }}</p>
Preview
</div>
<div class="overlay-preview">
Back
<h4 class="preview-title">Preview</h4>
<div class="preview-content">
<h5>Chapter 1</h5>
<p>{{$library->details}}</p>
</div>
</div>
</div>
</li>
#endforeach
</ul>
</div>
The problem is it doesn't work unless I hard code the genre like this
data-groups='["fiction"]'
Now since I'm retrieving data from a database using the foreach loop it means any book out the database is automatically given the "fiction" attribute regardless of its db assigned genre.
Any help on how to solve this will be appreciated.
Found the problem
I was Filtering with this lines of code
All Categories
Fantasy
Sci-Fi
Classics
Fairy Tale
The problem was that the data-group items are case sensitive. So for example I was filtering with "classic" while my database was providing "Classic" therefore making the filter function seem faulty.
I am trying to refactor and make a performance wise code.
The idea of the code is to update the id or value of all element with id or value that needs to be updated that happens when an element has been removed / deleted
So what I am trying to do is get all element with Id or value inside a container element (which is possible to be nested in 2 to 4).
At the moment, I am using jQuery to this task. I added a class on every element that has Id and use jQuery .find() to get all of this element using the class I've assign to them .. which is I really hate about my code and wanted to change as well if there's another best way to do it.
So is there a fastest way and performance wise at the same time to do this task?
$("button").on("click", function(){
$($(this).val()).remove();
updateParagraph();
});
function updateParagraph() {
$(".paragraphs").each(function(index, data){
var dataId = data.id.split("-");
var idIndex = dataId[dataId.length-1];
var index = index + 1;
if (index != idIndex) {
dataId.splice(-1, 1);
dataId.push(index);
dataId = dataId.join("-");
$(this).attr("id", dataId);
setChildElementsId($(this), index)
}
});
}
function setChildElementsId(parent, inx) {
$(parent).find(".id-holder").each(function(index, data){
if (data.id) {
var dataId = data.id.split("-");
dataId.splice(-1, 1);
dataId.push(inx);
dataId = dataId.join("-");
$(this).attr("id", dataId);
if(isParagraph(data.tagName)) {
$(this).text(inx);
}
}
else if (data.value) {
var dataValue = data.value.split("-");
dataValue.splice(-1, 1);
dataValue.push(inx);
dataValue = dataValue.join("-");
$(this).val(dataValue);
}
});
}
function isParagraph(tagName){
return tagName == "P";
};
<div id="container-1" class="paragraphs">
<div id="header-container-id-1" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-1" class="id-holder">
<p id="id-1" class="id-holder">1</p>
</div>
<button value="#container-1" class="id-holder">delete</button>
</div>
<div id="container-2" class="paragraphs">
<div id="header-container-id-2" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-2" class="id-holder">
<p id="id-2" class="id-holder">2</p>
</div>
<button value="#container-2" class="id-holder">delete</button>
</div>
<div id="container-3" class="paragraphs">
<div id="header-container-id-3" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-3" class="id-holder">
<p id="id-3" class="id-holder">3</p>
</div>
<button value="#container-3" class="id-holder">delete</button>
</div>
<div id="container-4" class="paragraphs">
<div id="header-container-id-4" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-4" class="id-holder">
<p id="id-4" class="id-holder">4</p>
</div>
<button value="#container-4" class="id-holder">delete</button>
</div>
<div id="container-5" class="paragraphs">
<div id="header-container-id-5" class="id-holder">
<h4>Header</h4>
</div>
<div id="paragraph-container-id-5" class="id-holder">
<p id="id-5" class="id-holder">5</p>
</div>
<button value="#container-5" class="id-holder">delete</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If I understand your question correctly, you're looking to more elegantly identify which elements have an id of the form "__-id-#" or simply "id-#".
If this is the case, take a look at some more advanced jQuery selectors. One in particular which might meet your needs is the Attribute Contains Selector.
For instance, I think $(parent).find("[id*='id-']") might do what you're looking to do.
While I understand what you're attempting to do, I don't quite understand why you're doing this in the first place.
Unless there are restrictions that force you to structure your HTML like you did, well, don't. Aim for the simplest structure:
<div id="container-123" class="paragraphs">
<h4>Header</h4>
<p>1</p>
<button type="button">delete</button>
</div>
Remove the <div>s around the <h4> and the <p> unless you need them for some styling reason. The <button> doesn't need to know its ID, because it's a child element of the container, so you're delete handler could make use of that fact:
$(document.body).on("click", "button", function() {
$(this).closest('.paragraphs').remove();
});
If there are outside forces that require a specific ID (e.g. for linking to an anchor), keep that on the top container element. If your CSS targets elements by ID, refactor the CSS.
I would like to answer your question using javascript. In fact you don't need any of those id-s
I hope I'm not too late.
let buttons = Array.from(document.querySelectorAll(".id-holder"));
buttons.forEach(b => {
//for each button add an event listener
b.addEventListener("click", () => {
b.parentElement.parentElement.removeChild(b.parentElement);
resetNums();
});
});
function resetNums(){
// reseting the text inside the p
let btns = Array.from(document.querySelectorAll(".id-holder"));
btns.forEach((bt,i)=>{
let theP = bt.parentElement.querySelector("p");
theP.innerHTML = i+1;
})
}
<div>
<div>
<h4>Header1</h4>
</div>
<div>
<p>1</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header2</h4>
</div>
<div>
<p>2</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header3</h4>
</div>
<div>
<p>3</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header4</h4>
</div>
<div>
<p>4</p>
</div>
<button class="id-holder">delete</button>
</div>
<div>
<div>
<h4>Header5</h4>
</div>
<div>
<p>5</p>
</div>
<button class="id-holder">delete</button>
</div>
I am trying to use jQuery to get the value of the divs with the classes of more_details_con, more_details_desc and more_details_res and when edit_entry is clicked but I don't think I am traversing the DOM correctly because the alert just says undefined.
The HTML
<div class="details">
<span class="id">1234</span>
<span class="contact">account name</span>
</div>
<div class = "more_details">
<div class = "more_details_btns">
<div class="go_account">Go to Account</div>
<div class="edit_entry">Edit</div>
<div class="delete_entry">Delete</div>
</div>
<div class="container">
<div class="more_details_title">Contact:</div>
<div class="more_details_con">Contact name</div>
<p class="clear"></p>
</div>
<div class="container">
<div class="more_details_title">Description:</div>
<div class="more_details_desc">Actual Description</div>
<p class="clear">
</div>
<div class="container">
<div class="more_details_title">Resolution:</div>
<div class="more_details_res">Actual Resolution</div>
<p class="clear">
</div>
</div>
The jQuery I've tried
$("#results").on("click", ".edit_entry", function() {
var contact = $(this).next(".more_details_con").html();
var desc = $(this).next(".more_details_desc").html();
var res = $(this).next(".more_details_res").html();
alert(contact+desc+res);
});
The issue is because the elements you're looking for are not siblings of the one which raised the event. You instead could use closest() to find the nearest common parent element, .more_details, and then find() to get the element you want. Try this:
$("#results").on("click", ".edit_entry", function() {
var $parent = $(this).closest('.more_details');
var contact = $parent.find(".more_details_con").text();
var desc = $parent.find(".more_details_desc").text();
var res = $parent.find(".more_details_res").text();
console.log(contact, desc, res);
});