How to get href from this response? - javascript

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

Related

how to place age and gender value in canvas in face-api.js

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 ?

how to exchange 2 href with respect to the presence of a text?

I need to exchange two href if a "text" is exact.
I tried lots of solutions and I thought I finally found one with a clean way but there is no change and no error. Do you have an explanation ?
let link_1 = document.getElementById('rempl_1').href;
let link_2 = document.getElementById('rempl_2').href;
$(document).ready(function() {
if (
document.getElementById('custom_field').innerHTML.indexOf('remplacement') != -1) {
let tmp = link_1;
link_1 = link_2;
link_2 = tmp;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="row">
<span class="custom_field" id="custom_field">remplacement</span>
<a class="rempl" href="my_first_url" title="original" id="rempl_1">First</a>
<a class="rempl" href="my_second_url" title="remplacement" id="rempl_2">Second</a>
</div>
You mean this?
Note I removed the need for jQuery since you were not using it anyway
window.addEventListener("load", function() {
const custom = document.getElementById('custom_field');
if (custom.innerHTML.includes('remplacement')) {
const links = document.querySelectorAll(".rempl");
const href0 = links[0].href;
const href1 = links[1].href;
links[0].href = href1;
links[1].href = href0;
}
});
<div class="row">
<span class="custom_field" id="custom_field">remplacement</span>
<a class="rempl" href="my_first_url" title="original" id="rempl_1">First</a>
<a class="rempl" href="my_second_url" title="remplacement" id="rempl_2">Second</a>
</div>
string is copied as value when assigned to new variable, so assign a new string to variable will not change href original value.
if change anchor href is what you want, you should add
document.getElementById('rempl_1').href = link_1;
document.getElementById('rempl_2').href = link_2;
for this scenario, i prefer store element as variable:
let a1 = document.getElementById('rempl_1');
let a2 = document.getElementById('rempl_2');
$(document).ready(function () {
if (
document.getElementById('custom_field').innerHTML.includes('remplacement')
) {
[a1.href, a2.href] = [a2.href, a1.href];
}
});
PS: maybe you want write replacement instead of remplacement

Loop through object of objects

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

Javascript split the HTML attributes and value

I have a list of javascript string with HTML tags and want to split the tags.
<img class="logo" src="http://i.imgur.com/z38lrml.png" height="60px" />
<section id = "test">
I tried to split by double quotes (") but getting only
class=", logo"
I want to split in the following array
[class="logo"], [src="http://i.imgur.com/z38lrml.png"],[height="60px"]
and so on for the next line.
Is there anyway to separate?
Thank you
It seems your HTML tag is actually just a string?
In that case, you can use regex:
let html = '<img class="logo" src="http://i.imgur.com/z38lrml.png" height="60px" />';
let attributes = html.match(/[\w-]+="[^"]*"/g);
console.log(attributes);
const attributes = document.querySelector('img').getAttributeNames();
const img = document.querySelector('img');
const output = [...attributes].map((attr) => {
const val = img.getAttribute(attr);
return `${attr}" = "${val}`;
});
console.log(output);
<img class="logo" src="http://i.imgur.com/z38lrml.png" height="60px" />
Edit --
If your html is a string, use DOMParser to convert it into html.
const str = `<img class="logo" src="http://i.imgur.com/z38lrml.png" height="60px" />
<section id = "test">`;
const dom = new DOMParser().parseFromString(str, 'text/html');
let output = [];
[...dom.body.children].forEach((node) => {
const attributes = node.getAttributeNames();
output.push([...attributes].map((attr) => {
const val = node.getAttribute(attr);
return `${attr}" = "${val}`;
}));
})
console.log(output);

How to replace two similar HTML elements with vanilla javascript?

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.

Categories