So I have created this website which lets users search for the weather in different cities. These searches then get saved in an object which looks like this through the localstorage.
To display this on the website I've tried to make the following
<div class="jumbotron bg-white">
<div class="container">
<h1>Latest requests</h1>
<h5 id="get-weather">We remember your five last requests for you :)</h5>
<div class="last-requests">
<img src="" class="imgs">
<p class="cityname" class="mr-3"></p>
<p class="cityweather"></p>
<p class="citytemp"></p>
<p class="citywind"></p>
</div>
</div>
</div>
And the following JS
// Displays last 5 requests/searches
function displayLastRequests() {
const lastReq = JSON.parse(localStorage.getItem('last-requests'))
console.log(lastReq)
if (displayLastRequests > 0) {
// for loop request
for (req in lastReq) {
$(".imgs").attr('src', req.imgurl);
$(".cityname").text(req.city_name);
$(".cityweather").text(req.city_weather);
$(".citytemp").text(req.city_temp + " °C");
$(".citywind").text(req.city_wind + " m/s");
}
}
};
displayLastRequests()
Not quite sure where I'm doing something wrong, any help would be much appreciated.
Your existing code will only show the last search as there's only one "cityname" to output to.
You can use HTML5 <template> to provide a ...well... template which you can copy and add as required.
Your for loop may also need to be for (.. of ..) rather than .. in .. which will give indexes rather than entries.
Updated code:
function displayLastRequests() {
//const lastReq = JSON.parse(localStorage.getItem('last-requests'))
// Sample data
const lastReq = [
{city_name:"Istanbul", weather:"Cloudy"},
{city_name:"Madrid", weather:"Stormy"},
{city_name:"London", weather:"Sunny"}
];
console.log(lastReq)
for (req of lastReq) {
var clone = $($("#last-request-template").html());
clone.appendTo(".last-requests");
clone.find(".cityname").text(req.city_name);
clone.find(".cityweather").text(req.weather);
//clone.find(".imgs").attr('src', req.imgurl);
//clone.find(".citytemp").text(req.city_temp + " °C");
//clone.find(".citywind").text(req.city_wind + " m/s");
}
};
displayLastRequests()
.last-requests { border: 1px solid #CCC; }
.last-request+.last-request { border-top: 1px solid #CCC; }
p { padding:5px; margin: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="jumbotron bg-white">
<div class="container">
<h1>Latest requests</h1>
<h5 id="get-weather">We remember your five last requests for you </h5>
<template id='last-request-template'>
<div class='last-request'>
<!--<img src="" class="imgs">-->
<p class="cityname"></p>
<p class="cityweather"></p>
<!--<p class="citytemp"></p>-->
<!--<p class="citywind"></p>-->
</div>
</template>
<div class="last-requests"> </div>
</div>
</div>
Related
Using this example:
$('[data-switch]').on('click', function(e)
{
var
$page = $('#page-2')
, blockToShow = e.currentTarget.getAttribute('data-switch')
;
// Hide all children.
$page.children().hide();
// And show the requested component.
$page.children(blockToShow).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-switch="#about_me">Click to read about me</button>
<button data-switch="#education">Click to show my education</button>
<button data-switch="#about_name_bravitus">Click to read about the name Bravitus</button>
<div id="page-2">
<div id="about_me" class="container">
<h1>This is about me section</h1>
<div>about me about me about me</div>
</div>
<!-- Hidden blocks that you show when requested. -->
<div id="education" class="container" style="display: none;">
<h1>This is about my education</h1>
<div>education education education</div>
</div>
<div id="about_name_bravitus" class="container" style="display: none;">
<h1>This is about the name bravitus</h1>
<div>bravitus bravitus bravitus</div>
</div>
</div>
How would one go about changing the font color and weight of the button text when the content is being displayed (not based on when the button is clicked)?
I have tried to find posts with a similar request, but I am greatly struggling. Any direction would be appreciated.
There is many ways to do that, like this one :
const
btns_Switch = document.querySelectorAll('[data-switch]')
, page2_parent = document.querySelector('#page-2')
;
btns_Switch.forEach( btn =>
{
btn.onclick = e =>
{
page2_parent.dataset.switch = btn.dataset.switch;
setButtonActive();
}
})
setButtonActive(); // init on page load...
function setButtonActive()
{
let activBtn = page2_parent.dataset.switch;
btns_Switch.forEach( btn =>
btn.classList.toggle('active', activBtn === btn.dataset.switch ))
}
#page-2[data-switch="about_me"] > div:not(#about_me) ,
#page-2[data-switch="education"] > div:not(#education) ,
#page-2[data-switch="about_name_bravitus"] > div:not(#about_name_bravitus)
{
display : none;
}
button.active
{
background : yellow;
font-weight : bold;
}
<button data-switch="about_me">Click to read about me</button>
<button data-switch="education">Click to show my education</button>
<button data-switch="about_name_bravitus">Click to read about the name Bravitus</button>
<div id="page-2" data-switch="education" > <!-- set initial ID value -->
<div id="about_me" class="container">
<h1>This is about me section</h1>
<div>about me about me about me</div>
</div>
<div id="education" class="container" >
<h1>This is about my education</h1>
<div>education education education</div>
</div>
<div id="about_name_bravitus" class="container" >
<h1>This is about the name bravitus</h1>
<div>bravitus bravitus bravitus</div>
</div>
</div>
Sorry I don't code much and have adapted this code, so help would be greatly appreciated.
I'm trying to emulate a shopping page where you can 'like' a product and shows number of 'likes' for each product.
What is happening:
When I click on different instances of the 'like' button they get saved as one instance on firebase and all the 'like' counters show the same number of 'likes'
What I want:
Every time I click a different instance of the 'like' button I want it saved as a different instance on firebase so the counts are different for each 'like' button.
var dCounters = document.querySelectorAll('.CountLike');
[].forEach.call(dCounters, function(dCounter) {
var el = dCounter.querySelector('button');
var cId = dCounter.id;
var dDatabase = firebase.database().ref('Like Number Counter').child(cId);
// get firebase data
dDatabase.on('value', function(snap) {
var data = snap.val() || 0;
dCounter.querySelector('span').innerHTML = data;
});
// set firebase data
el.addEventListener('click', function() {
dDatabase.transaction(function(dCount) {
return (dCount || 0) + 1;
});
});
});
.CountLike div {
display: inline-flex;
}
.item-like {
font-size: 18px;
display: inline-block;
margin-top: 10px;
}
.counterStat {
margin-right: 15px;
margin-top: 5px;
}
.heart {
width: 32px;
height: 32px;
}
.btn {
background: none;
border: none;
cursor: pointer;
}
<div>
<div class="store-action">
<div class="CountLike" id="Like Count">
<div class="likes">
<span class="counterStat">0</span>
<button class="btn"><img src="https://www.svgrepo.com/show/164008/heart.svg" class="heart" alt="the heart-like button"></button>
</div>
</div>
</div>
</div>
<div>
<div class="store-action">
<div class="CountLike" id="Like Count">
<div class="likes">
<span class="counterStat">0</span>
<button class="btn"><img src="https://www.svgrepo.com/show/164008/heart.svg" class="heart" alt="the heart-like button"></button>
</div>
</div>
</div>
</div>
Below snippet should do it for now. Both of your elements have the same id value set which is set as id="Like Count"
So right now you just end up writing and reading from the same field for every cell you have.
As it is also stated on this link you should always make sure the id values you assign are unique.
<div>
<div class="store-action">
<div class="CountLike" id="xyz">
<div class="likes">
<span class="counterStat">0</span>
<button class="btn"><img src="https://www.svgrepo.com/show/164008/heart.svg" class="heart" alt="the heart-like button"></button>
</div>
</div>
</div>
</div>
<div>
<div class="store-action">
<div class="CountLike" id="xyzt">
<div class="likes">
<span class="counterStat">0</span>
<button class="btn"><img src="https://www.svgrepo.com/show/164008/heart.svg" class="heart" alt="the heart-like button"></button>
</div>
</div>
</div>
</div>
I am trying to multiply and append one div element by changing its values inside it with loop in Javascript. I receive json array. After that, I parse json array in loop and place in div elements by id. My purpose is I want to make a div for each user and place all of them under each other. In the end by pressing Download pdf I will download div element using html2pdf library. How Can I do this task using javascript.
Now result is like below:
I want the same div for each json object inside json array. All of the divs are appended like below.
The result page should like this:
index.html
<div class="container d-flex justify-content-center mt-50 mb-50">
<div class="row">
<div class="col-md-12 text-right mb-3">
<button class="btn btn-primary" id="download"> download pdf</button>
</div>
<div class="col-md-12">
<div class="card" id="invoice">
<div class="card-body ml-3 mr-2 pt-0">
<div class="row justify-content-center">
<h6 style="margin-bottom: 2px;"><strong>Contract <span>№ </span><u id="user_dogovor"></u> </strong> </h6>
</div>
<div class="row my-row0 nopadding">
<div class="col-md-6" >
<p style="float: left; margin-bottom: 5px;">London st</p>
</div>
<div class="col-md-6">
<p style="float: right; margin-bottom: 5px;">«____» ________________2021 year.</p>
</div>
</div>
<div class="row row-beginning" >
<div class="col-sm" >
<div class="text-sm-left">
<p>If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators <b><u id="user_name"></u></b>, passport: <b><u id="user_passport"></u></b> given <b><u id="user_vidan_date"></u></b> year given <b><u id="user_kem_vidan"></u></b>, address: <b><u id="user_address"></u></b>, It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable:
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm mydiv-menu">
<div class="text-sm-left">
<p>1.1. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable
</p>
<p>1.2 If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
style.css
*{
font-family: "Times New Roman", Times, serif;
line-height: 16px;
}
div.mydiv-menu{
text-indent: 40px;
}
.row-beginning p{
text-indent: 40px;
margin-bottom: 2px;
}
.my-below p{
text-indent: 40px;
margin-bottom: 3px;
}
.my-row3 p{
text-indent: 40px;
}
.mydiv-menu p{
margin:0;
}
.my-row p{
margin:0;
}
.my-row5 {
margin-top:5px;
}
.my-row-mid {
margin-top:5px;
}
.table-condensed{
font-size: 10px;
}
.my-row4 p{
margin-bottom: 0px;
}
h6{
font-size:13px;
}
p{
font-size: 14px;
}
th {
font-size: 14px;
}
td {
font-size: 14px;
}
My js code
for (var i = 0; i < rowObject.length; i++) {
var counter = rowObject[i];
var name = counter["dogovor_id"];
var passport = counter["passport"];
var kogda_vidan = '16.02.2021';
var vidan_date = '«' + kogda_vidan.substring(0,2) + '»' + ' ' + kogda_vidan.substring(3,5) + ' ' + kogda_vidan.substring(6,10);
var kem_vidan =counter["kem_vidan"];
var address_dostavki = counter["address"];
var dogovor_id = 153;
document.getElementById('user_name').innerHTML = name;
document.getElementById('user_passport').innerHTML = passport;
document.getElementById('user_vidan_date').innerHTML = vidan_date;
document.getElementById('user_kem_vidan').innerHTML = kem_vidan;
document.getElementById('user_address').innerHTML = address_dostavki;
document.getElementById('user_dogovor').innerHTML = dogovor_id;
}
The issue you are experiencing is because you are not creating another div element, all you are actually doing is replacing the content of the same elements over and over. What you will need to do is append a new element and then from there update the content of that element with the relevant data.
The most readable way would be to generate the html on the server and then return that to the JS via a XHR call.
If that is not possible you can build the HTML using JS and then append that all as a single string to an element.
Something like:
HTML
<div class="container d-flex justify-content-center mt-50 mb-50">
<div class="row">
<div class="col-md-12 text-right mb-3">
<button class="btn btn-primary" id="download"> download pdf</button>
</div>
<div class="col-md-12" id="elementsToPdf">
</div>
</div>
</div>
JS
for (var i = 0; i < rowObject.length; i++) {
var counter = rowObject[i];
var name = counter["dogovor_id"];
var passport = counter["passport"];
var kogda_vidan = '16.02.2021';
var vidan_date = '«' + kogda_vidan.substring(0,2) + '»' + ' ' + kogda_vidan.substring(3,5) + ' ' + kogda_vidan.substring(6,10);
var kem_vidan =counter["kem_vidan"];
var address_dostavki = counter["address"];
var dogovor_id = 153;
var htmlString = '<div class="card" id="invoice">';
htmlString += '<div class="card-body ml-3 mr-2 pt-0">';
htmlString += '<div class="row justify-content-center">';
htmlString += '<h6 style="margin-bottom: 2px;"><strong>Contract <span>№ </span><u id="user_dogovor"> ' + name + ' </u> </strong> </h6> '
htmlString += '</div>'
htmlString += '<div class="row my-row0 nopadding"> <div class="col-md-6" > <p style="float: left; margin-bottom: 5px;">London st</p></div><div class="col-md-6"><p style="float: right; margin-bottom: 5px;">«____» ________________2021 year.</p></div></div>'
htmlString += '</div>'
//etc.
document.getElementById('elementsToPdf').append(htmlString);
}
You will just need to complete the above code with the rest of your html and replace code where required as per the one example I gave here.
See https://developer.mozilla.org/en-US/docs/Web/API/Element/append for more information about the append and how it is used to solve your problem
A better solution would be if your server could return the complete HTML that you want to append to the element, this would make your code more readable. Since we don't know more about your setup and solution this is the best I could do with your given example.
Here is another way of doing what you asked, much less elegant and prone to XSS attacks, choice is yours:
<body>
<div class="container d-flex justify-content-center mt-50 mb-50">
<div class="row">
<div class="col-md-12 text-right mb-3">
<button class="btn btn-primary" id="download"> download pdf</button>
</div>
<div class="col-md-12 target-div">
</div>
</div>
</div>
</body>
function generateCard(name, passport, kogdaVidan, vidanDate, kemVidan, addressDostavki, dogovorId) {
const targetDiv = document.querySelector('.target-div');
const card = document.createElement('div');
card.classList.add('card');
card.id = 'invoice';
card.innerHTML = `
<div class="card-body ml-3 mr-2 pt-0">
<div class="row justify-content-center">
<h6 style="margin-bottom: 2px;"><strong>Contract <span>№ </span><u id="${dogovorId}"></u> </strong> </h6>
</div>
<div class="row my-row0 nopadding">
<div class="col-md-6" >
<p style="float: left; margin-bottom: 5px;">London st</p>
</div>
<div class="col-md-6">
<p style="float: right; margin-bottom: 5px;">${vidanDate}</p>
</div>
</div>
<div class="row row-beginning" >
<div class="col-sm" >
<div class="text-sm-left">
<p>If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators <b><u id="user_name"></u></b>, passport: <b><u id="user_passport"></u></b> given <b><u id="user_vidan_date"></u></b> year given <b><u id="user_kem_vidan"></u></b>, address: <b><u id="user_address"></u></b>, It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable:
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm mydiv-menu">
<div class="text-sm-left">
<p>1.1. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable
</p>
<p>1.2 If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text</p>
</div>
</div>
</div>
</div>
`;
targetDiv.appendChild(card);
}
for (let i = 0; i < rowObject.length; i++) {
const counter = rowObject[i];
const name = counter["dogovor_id"];
const passport = counter["passport"];
const kogda_vidan = '16.02.2021';
const vidan_date = '«' + kogda_vidan.substring(0,2) + '»' + ' ' + kogda_vidan.substring(3,5) + ' ' + kogda_vidan.substring(6,10);
const kem_vidan =counter["kem_vidan"];
const address_dostavki = counter["address"];
const dogovor_id = 153;
generateCard(name, passport, kogda_vidan, vidan_date, kem_vidan, address_dostavki, dogovor_id);
};
By the way, you need to pass the other parameters where needed.
I have a code block here that is 90% working. The idea is that I have an autocomplete (searches via axios with a LIKE condition on the database but I simplified the result set here). When you type in the input, it searches and returns matching results in a dropdown. If you select an option, it replaces the search text in the input with the actual selected value. Then if you click to add another zone it clones the divs with the input.
The issue is that when I create another div and start searching in the input it glitches and then it also triggers the dropdown on both divs (or more if you add more than two). But it doesn't actually allow text to be entered in the newly added zones.
How can I fix this so that each zone actually has it's own input and results dropdown so that I can send something on save that has distinct values for each div?
new Vue({
components: {},
el: "#commonNameDiv",
data() {
return {
searchString: [],
results: [],
savedAttributes: [],
cards: []
}
},
methods: {
autoComplete() {
this.results = [];
console.log(this.searchString);
if (this.searchString.length > 2) {
this.results = [
{attribute_value:"apple"},
{attribute_value:"banane"}
]
}
},
saveAttribute(result) {
this.savedAttributes = [];
console.log('cool');
this.savedAttributes.push(result.attribute_value);
console.log('here is the attribute');
console.log(this.savedAttributes);
this.searchString = result.attribute_value;
this.results = [];
},
addCard: function() {
this.cards.push({
index: ''
})
}
}
})
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="commonNameDiv">
<div class="uk-grid">
<div class="uk-width-2-10" >
<input size="4" type="text" name="mapNumber">
</div>
<div class="uk-width-6-10">
<input style="width:100%" type="text" placeholder="what are you looking for?" v-model="searchString" v-on:keyup="autoComplete" class="form-control">
<div class="panel-footer componentList" v-if="results.length">
<ul class="list-group">
<li class="list-group-item" v-for="result in results">
<a v-on:click="saveAttribute(result)">{{ result.attribute_value }}</a>
</li>
</ul>
</div>
</div>
<div class="uk-width-2-10" style="border: 1px solid black; height:50px; width: 50px; margin: 0 auto;" >
</div>
</div>
<div v-for="(card,index) in cards" class="uk-grid">
<div class="uk-width-2-10">
<input size="4" type="text" name="mapNumber">
</div>
<div class="uk-width-6-10">
<input style="width:100%" type="text" placeholder="what are you looking for?" v-model="searchString[index]" v-on:keyup="autoComplete" class="form-control">
<div class="panel-footer componentList" v-if="results.length">
<ul class="list-group">
<li class="list-group-item" v-for="result in results">
<a v-on:click="saveAttribute(result)">#{{ result.attribute_value }}</a>
</li>
</ul>
</div>
</div>
<div class="uk-width-2-10" style="border: 1px solid black; height:50px; width: 50px; margin: 0 auto;">
</div>
</div>
<div style="height: 35px;">
</div>
<div>
<a v-on:click="addCard">Add another zone</a>
</div>
</div>
All your variables and/or properties need to be unique, currently they are not. The easiest way would be in my mind to just store all that you need inside the card object you are using. When you are done, you can just extract the data you need from your array.
Template where we have removed the first div you have, let's just push an empty card object to the array. Our card object will look like this:
{
index: "",
value: "" // the end value
results: [] // the search results will be stored here
}
So in template we use value as v-model for the input and display results for the user to pick their value. Also I suggest you use in all v-for iterations a key. Here I use the index, but that is really not that efficient! But anyway, so the stripped down version of template would look like:
<div v-for="(card, i) in cards" :key="i">
<div>
<input
placeholder="what are you looking for?"
v-model="card.value"
v-on:keyup="autoComplete($event, card)"
>
<div v-if="card.results.length">
<ul>
<li v-for="(result, i) in card.results" :key="i">
<a v-on:click="saveAttribute(result, card)">#{{ result.attribute_value }}</a>
</li>
</ul>
</div>
</div>
</div>
<div>
<a v-on:click="addCard">Add another zone</a>
</div>
The methods would be:
methods: {
autoComplete(ev, card) {
if (ev.target.value.length > 2) {
// here would be actual results...
card.results = [
{ attribute_value: "apple" },
{ attribute_value: "banane" }
];
}
},
saveAttribute(result, card) {
card.value = result.attribute_value;
},
addCard() {
this.cards.push({
index: "",
value: "",
results: []
});
}
}
and lastly, like mentioned, call addCard in a life cycle hook. Here I use created:
created() {
this.addCard();
}
I've got an issue where I want to select (and replace) a string of text with no tags with jQuery. I need to retrieve the "us-east1-mp2 lobby", but it only selects the text with a span.
My code:
function fixServerLocation() {
setTimeout(function() {
if ($(".admin.chatLog").find(".section").length > 0) {
var section = ($(".admin.chatLog").find(".section"));
if (typeof section !== 'undefined') {
var chatMessages = document.querySelectorAll("[id^='chatMessage']");
if (typeof chatMessages !== 'undefined') {
$('.section [id^="chatMessage"]').children('div.details').children().css({
"color": "red",
"border": "2px solid red"
});;
//The code that I currently have to select the tag-less text. The styling is only to highlight it.
}
}
}
fixServerLocation();
}, 70);
}
fixServerLocation();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chatMessage listItem first" id="chatMessage-us-east1-mp2-6668675">
<button class="expand small" type="button" tabindex="-1">+</button>
<div class="options right"></div>
<div class="details"><span class="time">2020-04-04 11:07</span>us-east1-mp2 lobby
<span><span class="username adminLookup">CommanderAnime</span></span>:
<span class="message ">Test</span></div>
</div>
How it currently looks when running the code:
I want to replace the "us-east1-mp2 lobby" with "Newark lobby". Thanks for any help
This is quite dangerous if your text is part of text attributes
NOTE: because I remove the event handler when I rewrite the HTML, you will need to delegate the button:
$("#someStaticContainerForTheChatMessages").on("click","button.expand",function() { whatever the button does })
$(function() {
const $chatMessages = $("[id^='chatMessage']");
if ($chatMessages.length > 0) {
$chatMessages.each(function(i, message) {
$('div.details', message).children().addClass("highlight")
message.innerHTML = message.innerHTML.replace("us-east1-mp2 lobby", "Newark lobby")
})
}
})
.highlight {
color: red;
border: 2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chatMessage listItem first" id="chatMessage-us-east1-mp2-6668675">
<button class="expand small" type="button" tabindex="-1">+</button>
<div class="options right"></div>
<div class="details"><span class="time">2020-04-04 11:07</span>us-east1-mp2 lobby<span><span class="username adminLookup">CommanderAnime</span></span>:
<span class="message ">Test</span></div>
</div>
If using jquery, you can easily achieve this by using javascript String.replace method:
const detailsHtml = $('.details').html()
const replacedContent = detailsHtml.replace('us-east1-mp2 lobby', 'Newark lobby')
$('.details').html(replacedContent)
Whats the idea: As this text isn't inside a tag, you need to get the whole div html as a string, and perform a replace. The first line returns the html content of .details as a string.
Then we perform the replace and use the same .html(value) method to set the new content.
Check the fiddle: https://jsfiddle.net/diogocosta/7wrmLog5/5/
const detailsHtml = $('.details').html()
const replacedContent = detailsHtml.replace('us-east1-mp2 lobby', 'Newark lobby')
$('.details').html(replacedContent)
//console.log(replacedContent)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chatMessage listItem first" id="chatMessage-us-east1-mp2-6668675">
<button class="expand small" type="button" tabindex="-1">+</button>
<div class="options right"></div>
<div class="details"><span class="time">2020-04-04 11:07</span>us-east1-mp2 lobby
<span><span class="username adminLookup">CommanderAnime</span></span>:
<span class="message ">Test</span></div>
</div>