So I have the following function vanilla JS code:
function get_menu(menu_id) {
wp.api.loadPromise.done(function() {
const menus = wp.api.collections.Posts.extend({
url: wpApiSettings.root + 'menus/v1/menus/' + menu_id,
});
const Menus = new menus();
Menus.fetch().then(
posts => {
let post_list = posts.items;
console.log(post_list);
});
});
}
get_menu(4);
This gives me a object of objects as shown below:
What is the best way to loop through these objects and render HTML within? So let's say I want to loop through each object and grab the post_title and output HTML <div> + post_title + </div>.
All help would be appreciated!
Update:
Need to render this in a loop:
<div class="column is-one-third is-flex py-0">
<a href=" ***url*** " class="dropdown-item px-2 is-flex is-align-items-center">
<figure class="image is-32x32 is-flex">
<img src=" ***image*** + ***post_title*** '.svg'; ?>">
</figure>
<span class="pl-2"><?= ***post_title*** ?></span>
</a>
</div>
You can iterate through the array and create a dom tree
function get_menu(menu_id) {
wp.api.loadPromise.done(function () {
const menus = wp.api.collections.Posts.extend({
url: wpApiSettings.root + 'menus/v1/menus/' + menu_id,
});
const Menus = new menus();
Menus
.fetch()
.then(posts => {
let post_list = posts.items;
// Map through response data and turn objects into elements
const postElements = post_list.map(createDomTree)
// spread all elements from array into arguments for the append method
document.body.append(...postElements)
});
});
}
function createDomTree(post) {
// I'm not sure if these values are available in the response data, but can be replaced
const { post_url, post_title, post_image } = post
const container = document.createElement('div')
container.className = 'column is-one-third is-flex py-0'
const anchor = document.createElement('a')
anchor.href = post_url
anchor.className = 'dropdown-item px-2 is-flex is-align-items-center'
const figure = document.createElement('figure')
figure.className = 'image is-32x32 is-flex'
const img = document.createElement('img')
img.src = `${post_image}${post_title}.svg`
const span = document.createElement('span')
span.className = 'pl-2'
span.textContent = post_title
figure.appendChild(img)
anchor.append(figure, span)
container.appendChild(anchor)
return container
}
get_menu(4);
Related
Sir i'm creating a javascript application with face-api.js
Face-api.js working fine , but i don't know to place or add text filed which have written age and gender value,
here is my javascript code:
Promise.all([
faceapi.nets.faceRecognitionNet.loadFromUri('weights'),
faceapi.nets.faceLandmark68Net.loadFromUri('weights'),
faceapi.nets.ageGenderNet.loadFromUri('weights'),
faceapi.nets.ssdMobilenetv1.loadFromUri('weights')
])
.then(uploadImage)
// upload image
function uploadImage() {
console.log("Modals Loaded")
const con = document.querySelector('.container');
const input = document.querySelector('#myImg')
const imgFile = document.querySelector('#myFile')
var can;
var img;
imgFile.addEventListener("change", async ()=>{
if(can) {can.remove();}
if(img) {img.remove();}
// creating a html Element from Blob data
img = await faceapi.bufferToImage(imgFile.files[0])
input.src = img.src;
const result = await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceDescriptors().withAgeAndGender();
console.log(result)
const faceMatcher = new faceapi.FaceMatcher(result);
result.forEach(fd=>{
const { age, gender, genderProbability } = fd
const bestMatch= faceMatcher.findBestMatch(fd.descriptor)
console.log(bestMatch)
console.log(age, "age")
console.log(gender,"gender")
})
// canvas created
can = faceapi.createCanvasFromMedia(input);
con.append(can);
faceapi.matchDimensions(can,{width: input.width,height: input.height})
// resizing box
const detectionsForSize = faceapi.resizeResults(result,{width: input.width,height: input.height})
const box = result[0].detection.box;
console.log("detectionsForSize",detectionsForSize)
const facebox =new faceapi.draw.DrawBox(box);
faceapi.draw.drawDetections(can,detectionsForSize,Math.round(detectionsForSize[0].age));
})
}
And Here is Html Code
<div class="container">
<div id="im">
<img src="" alt="photo" id="myImg">
</div>
</div>
<input type="file" id="myFile" onchange="uploadImage()" accept=".jpg,.jpeg,.png">
I have tried but i can't achive that ?
I have some code where I'm getting the response of the first child of div's class and I want to get 993307 from my first variable. How can I do it?
<a href="https://osu.ppy.sh/beatmapsets/993307/discussion#/1050967" title="MIIRO (TV Size) - AKINO from bless4 (mapped by Sotarks)">
const cheerio = require('cheerio');
const rp = require('request-promise');
var array = [];
rp(`https://osu.ppy.sh/beatmapsets/events?user=&types%5B%5D=disqualify&min_date=&max_date=`)
.then((html) => {
let $ = cheerio.load(html);
$('div#events.beatmapset-events').each(function(i, element) {
var first = $(this).children().eq(1);
console.log(first.html())
})
})
.catch(console.error.bind(console));
here's response from first variable
<div class="beatmapset-event">
<a href="https://osu.ppy.sh/beatmapsets/993307/discussion#/1050967" title="
MIIRO (TV Size) - AKINO from bless4
(mapped by Sotarks)
">
<img class="beatmapset-activities__beatmapset-cover" src="https://assets.ppy.sh/beatmaps/993307/covers/list.jpg?1562167122" srcset="https://assets.ppy.sh/beatmaps/993307/covers/list.jpg?156216712
2 1x, https://assets.ppy.sh/beatmaps/993307/covers/list#2x.jpg?1562167122 2x">
</a>
<div class="beatmapset-event__icon beatmapset-event__icon--disqualify beatmapset-activities__event-icon-spacer"></div>
<div>
<div class="beatmapset-event__content">
Disqualified by <a class="user-name js-usercard" data-user-id="3388410" href="https://osu.ppy.sh/users/3388410" style="color: #6B3FA0">eiri-</a>. Reason: <a href="https://osu.ppy.sh/beatmapsets/9
93307/discussion#/1050967">#1050967</a> ([no preview]).
</div>
<div><time class="timeago" datetime="2019-07-03T15:17:20+00:00">July 3, 2019 at 3:17:20 PM UTC</time></div>
</div>
</div>
Asuming that your response is a string. Use DomParser()
let response = '<div class="beatmapset-event"> <img class="beatmapset-activities__beatmapset-cover" src="https://assets.ppy.sh/beatmaps/993307/covers/list.jpg?1562167122" srcset="https://assets.ppy.sh/beatmaps/993307/covers/list.jpg?156216712 2 1x, https://assets.ppy.sh/beatmaps/993307/covers/list#2x.jpg?1562167122 2x"> <div class="beatmapset-event__icon beatmapset-event__icon--disqualify beatmapset-activities__event-icon-spacer"></div><div><div class="beatmapset-event__content"> Disqualified by <a class="user-name js-usercard" data-user-id="3388410" href="https://osu.ppy.sh/users/3388410" style="color: #6B3FA0">eiri-</a>. Reason: #1050967 ([no preview]).</div><div><time class="timeago" datetime="2019-07-03T15:17:20+00:00">July 3, 2019 at 3:17:20 PM UTC</time></div></div></div>'
var parser = new DOMParser(); // initiate DomParser()
var data = parser.parseFromString(response, 'text/html');
let atagLink = data.querySelector("a").getAttribute("href") // get the a tag's href attribute
console.log(atagLink.match(/(\d+)/)[0]) // match with regex
Regex details: (\d+) Matches the first number occurance.
That makes your code
rp(`https://osu.ppy.sh/beatmapsets/events?user=&types%5B%5D=disqualify&min_date=&max_date=`)
.then((html) => {
let $ = cheerio.load(html);
var parser = new DOMParser(); // initiate DomParser()
var data = parser.parseFromString(html, 'text/html');
let atagLink = data.querySelector("a").getAttribute("href") // get the a tag's href attribute
let number = atagLink.match(/(\d+)/)[0]
$('div#events.beatmapset-events').each(function(i, element) {
var first = $(this).children().eq(1);
console.log(first.html())
})
})
Is this what you are looking for?
var href = $(first).find('a').first().attr('href');
var matches = href.match(/\/(\d+)\//);
if (matches[1]) {
console.log(matches[1]);
}
I want to build a website which returns products from a database and when click on See More, should return product details from server in another html page. The problem is that when I click See More, productID%20=%20null :(.
productDetails = second html page.
productDetails = div - in index.html where products are returned from server
<script>
var productsUrlList = 'https://finalonlineshop.firebaseio.com/.json';
async function getProductsFromServer() {
var productsResponse = await fetch(productsUrlList)
var products = await productsResponse.json();
return products;
}
async function showProducts(productsPromise) {
var products = await productsPromise;
var generatedHTML = '';
var productsIDs = Object.keys(products);
productsIDs.forEach(productID => {
var product = products[productID];
generatedHTML += getGeneratedHTMLForProduct(productID, product);
});
document.getElementById('categories').innerHTML = generatedHTML;
}
function getGeneratedHTMLForProduct(productID, product) {
var generatedHTML = `
<div id = categoriesDiv>
<img class = "categoryImage" src = ${product.Image} />
<div class = "categoryName">${product.Name}</div>
<div class = "categoryPrice">$ ${product.Price}</div>
<br>
<button id = "seeMore" onclick = "seeMore('${productID}')">See
more</button>
</div>
`;
return generatedHTML;
}
function seeMore (productID) {
window.location = `./productDetails.html?productID = ${productID}`;//issue
}
function getProductIDFromUrl () {
var params = new URLSearchParams(window.location.search);
var productID = params.get('productID');
return productID;
}
async function getDetailsFromServer(productID) {
var detailsResponse = await fetch(`https://finalonlineshop.firebaseio.com/Products/details/${productID}.json`);
var details = await detailsResponse.json();
return details;
}
async function seeDetails(detailsPromise) {
var details = await detailsPromise;
var generatedHTML = `
<div id = "detailsAboutProduct">
<img src = "${details.Image}" /> //Cannot read property "Image" of null
<div>${details.Name}</div>
<div>${details.Details}</div>
<div>$ ${details.Price}</div>
<div>${details.Qty}</div>
<button id = "addToCart" onclick = "addToCart();">Add to
cart</button>
</div>
`;
document.getElementById('details').innerHTML = generatedHTML;
}
</script>
get rid of the spaces around the = in the URL, that gets encoded as %20. You should also use encodeURIComponent() to escape any special characters in the product ID.
function seeMore (productID) {
window.location = `./productDetails.html?productID=${encodeURIComponent(productID)}`;
}
Your query to your firebase app seems to be wrong.
you are fetching : https://finalonlineshop.firebaseio.com/Products/details/${productID}.json
which return null
but you have to fetch: https://finalonlineshop.firebaseio.com/${productID}.json
instead and it will return the right object
I have two similar elements to replace:
Replace:
<div class="radio__label content-box__emphasis ">
<label class="radio__label__primary" for="checkout_payment_gateway_1">
Payment 1
</label>
</div>
with:
<div class="radio__label content-box__emphasis payment-method-wrapper">
<label class="radio__label__primary" for="checkout_payment_gateway_1">
<img alt="Payment 1" class="offsite-payment-gateway-logo" src="payment-1.png">
<span class="visually-hidden">
Payment 1
</span>
</label>
</div>
And analogously for a Payment 2.
I want to do this without jQuery.
I don't want to add payment-method-wrapper to all <div class="radio__label content-box__emphasis "> on the site, but only for Payment 1 and Payment 2.
What would be the best approach to do this?
Moti Korets beat me to it, but here's a more complete solution:
function transformLabelContainer(id, imgSrc) {
const label = document.querySelector(`label[for$=_gateway_${id}]`);
const labelDiv = label.parentElement;
labelDiv.className += 'payment-method-wrapper';
const originalText = label.innerText;
const span = document.createElement('span');
span.className = 'visually-hidden';
span.innerText = originalText;
const img = document.createElement('img');
img.alt = originalText;
img.className = 'offsite-payment-gateway-logo';
img.src = imgSrc;
label.replaceChild(img, label.firstChild);
label.appendChild(span);
}
const labelsToTransform = [
{
id: '1',
imgSrc: 'payment-1.png'
},
{
id: '2',
imgSrc: 'payment-2.png'
}
];
labelsToTransform.forEach(label => transformLabelContainer(label.id, label.imgSrc));
To query for the label object you can run
let label_payment1 = document.querySelector('.payment-method-wrapper>label[for$=_gateway_1]')
Then create the inner node with
let img = document.createElement("img")
img.src = "payment-1.jpg"
// .. set other image attributes
let span = document.createElement("span")
span.class = "visually-hidden"
let textContent = document.createTextNode("Payment 1");
span.appendChild(textContent)
And lastly add created nodes to label
label_payment1.replaceChild(img,label_payment1.firstChild)
label_payment1.appendChild(span)
Edit: This is just a sketch. See #Kevin Huang answer for complete solution.
I'm trying to learn HTML and Javascript/jQuery. If I have a container which holds a title, an image, a description and a number, then I want to create a new container with the exact same format (except the values will be different), how is this commonly done?
This is an example of the format I'm looking for in each item.
<li>
<div>
<div>
Image Name
</div>
<div>
<a href=URL>
<img src='image_url'>
</a>
</div>
<div>
Description
</div>
<div>
num_comment Comments
</div>
</div>
</li>
Do I just create a string and concatenate with the actual values for the image, then add that string to some variable I've saved called html_content, and then set the html value to html_content? Is that the common way of doing this or is there a better way?
EDIT
To give a better idea of what I'm currently doing, here's the javascript:
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
};
$('pics').html(html);
}
In jQuery you just have to use the append() function to add on to something.
You could do something like...
$('select element').append('<li><div>....etc.');
and where you want a different value you can use a variable.
You can use .clone() and create a copy of this, then iterate through the cloned object and change what you need:
var $objClone = $("li").clone(true);
$objClone.find("*").each(function() {
//iterates over every element. customize this to find elements you need.
});
To change the image source you can do:
$objClone.find("img").attr("src", "new/img/here.jpg");
Fiddle demoing the concept: http://jsfiddle.net/H9DnA/1/
You may find it useful to explore some of the JavaScript templating libraries. The essential idea is that you create a template of your markup:
<li>
<div>
<div>
{{name}}
</div>
<div>
<a href="{{url}}">
<img src="{{imageUrl}}">
</a>
</div>
<div>
{{description}}
</div>
<div>
{{comments}}
</div>
</div>
</li>
Then you merge it against some associated matching object and insert it into your document:
{ name: 'Image Name',
url: 'http://example.com',
imageUrl: 'http://example.com/image.jpg',
description: 'Description',
comments [ { text: 'Comment' } ]
}
function render(pics)
{
var theList = document.getElementByid("LIST ID");
for (var i in pics){
var listItem = document.createElement('li'); // Create new list item
var nameDiv = document.createElement('div'); // Create name DIV element
nameDiv.innerHTML = pics[i].name; // Insert the name in the div
var img = document.createElement('img'); // Create Img element
img.setAttribute('src',pics[i].src); // Assign the src attribute of your img
var imgDiv = document.createElement('div'); // Create Img Div that contains your img
imgDiv.appendChild(img); // Puts img inside the img DIV container
var descDiv = document.createElement('div'); // Create Description DIV
descDiv.innerHTML = pics[i].description; // Insert your description
listItem.appendChild(nameDiv); // Insert all of you DIVs
listItem.appendChild(imgDiv); // inside your list item
listItem.appendChild(descDiv); // with appropriate order.
theList.appendChild(listItem); // Insert the list item inside your list.
}
}
I think this will work just fine:
$('#button').click(function () {
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
$("ul").append(html);
}
}
// call render
});
I didn't do a test run on your code so there might be an error somewhere. My tweak adds this line $("ul").append(html); inside your loop