I want to replace the class in the div from
this
<div class="producttitle"></div>
to this
<div class="producttitle h3"></div>
The above class is under the main div it has around 5 other classes to it
<div class="col-md-3 col-xs-6 cegg-gridbox">
<div class="cegg-thumb"></div>
<div class="producttitle"><div class="cegg-mb10"></div></div>
<div class="cegg-btn-grid cegg-hidden hidden-xs"></div>
</div>
const div = document.querySelector('producttitle');
div.classList.replace('producttitle','producttitle h3');
console.log(document.querySelector('producttitle').classList.value);
// Expected output: multi-class header first title
document.querySelector('producttitle').classList.replace('producttitle', 'producttitle h3')
console.log(document.querySelector('producttitle').classList.value);
// Expected output: multi-class header first bundle
I tried both the aboves ones but it's not working, correct me what I'm doing wrong here.
The snippet below is a proof-of-concept, basically I added two buttons to test adding or removing the class. For the sake of simplicity I assumed that you want to apply this for a single element, hence the use of .querySelector.
function add(selector, cl) {
let element = document.querySelector(selector);
if (element.classList.contains(cl)) {
alert('Class was already added');
} else {
element.classList.add('h3');
}
}
function remove(selector, cl) {
let element = document.querySelector(selector);
if (!element.classList.contains(cl)) {
alert('Class was already removed');
} else {
element.classList.remove('h3');
}
}
.h3 {
background-color: green;
}
<div class="col-md-3 col-xs-6 cegg-gridbox">
<div class="cegg-thumb"></div>
<div class="producttitle">The title<div class="cegg-mb10"></div></div>
<div class="cegg-btn-grid cegg-hidden hidden-xs"></div>
</div>
<input type="button" onclick="add('.producttitle', 'h3')" value="Add h3">
<input type="button" onclick="remove('.producttitle', 'h3')" value="Remove h3">
Let's see how we can support plural class additions/removals:
function add(selector, cl) {
let elements = document.querySelectorAll(selector);
for (let element of elements) {
if (!element.classList.contains(cl)) {
element.classList.add(cl);
}
}
}
function remove(selector, cl) {
let elements = document.querySelectorAll(selector);
for (let element of elements) {
if (element.classList.contains(cl)) {
element.classList.remove('h3');
}
}
}
.h3 {
background-color: green;
}
<div class="col-md-3 col-xs-6 cegg-gridbox">
<div class="cegg-thumb"></div>
<div class="producttitle">The title<div class="cegg-mb10"></div></div>
<div class="cegg-btn-grid cegg-hidden hidden-xs"></div>
</div>
<div class="col-md-3 col-xs-6 cegg-gridbox">
<div class="cegg-thumb"></div>
<div class="producttitle">The second title<div class="cegg-mb10"></div></div>
<div class="cegg-btn-grid cegg-hidden hidden-xs"></div>
</div>
<input type="button" onclick="add('.producttitle', 'h3')" value="Add h3">
<input type="button" onclick="remove('.producttitle', 'h3')" value="Remove h3">
Here I'm not alerting when the addition/removal did not succeed because it does not make sense to alert partial failures in the context of this test.
So, I found the solution
<h3 class="producttitle">
<?php if ($merchant = TemplateHelper::getMerhantName($item)): ?>
<div class="cegg-mb10">
<small class="text-muted title-case"><?php echo \esc_html($merchant); ?></small>
</div>
<?php endif; ?>
<?php if ($item['rating']): ?>
<div class="cegg-title-rating">
<?php TemplateHelper::printRating($item, 'small'); ?>
</div>
<?php endif; ?>
<?php echo \esc_html(TemplateHelper::truncate($item['title'], 80)); ?>
</h3>
From basic paragraph to a wrapped heading h3
Related
through Bootstrap Studio and a few lines of PHP, I dynamically generate a series of Cards.
I can filter the cards via an input box, but the filtered cards, don't reposition....they do if i change the width of the browser window....is there a way to make them reposition?
I'm posting my code
<div style="padding: 20px;border-radius: 20px;" id="card-list">
<div class="row" id="myItems" data-masonry="{"percentPosition": true }" >
<?php
//creo l'elenco dei campionati che si disputeranno fra oggi e domani
foreach ($arr_fed_NS as $key => $value) {
$text_camp=str_replace(']','',str_replace('[','',$value));
// echo '<br>ecco: '.$text_camp.'<BR>';
echo'
<div class="col-sm-6 col-lg-4 mb-4">
<div class="card">
<picture type="" srcset=""><img class="card-img-top p-3" src="'.$arr_camp[$text_camp].'" style="border-radius: 24px; object-fit: cover"></picture>
<div class="card-body">
<h3 class="fw-bolder card-title" style="text-align: center;--bs-body-font-weight: bold;">'.$text_camp.'</h3>
</div>
</div>
</div>';
}
?>
</div><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.2/masonry.pkgd.min.js" integrity="sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D" crossorigin="anonymous"></script>
</div>
function prova(){
const input = document.getElementById('filter').value.toUpperCase();
const card = document.getElementsByClassName('card');
for (let i = 0; i < card.length; i++) {
let title = card[i].querySelector(".card-body h3.card-title");
if (title.innerText.toUpperCase().indexOf(input) > -1){
card[i].style.display="";
}else {
card[i].style.display="none";
}
}
}
I have some HTML - pretty nasty, but not mine and so I don't have control over it. I need to extract some data from the form, the First name value (ABDIGANI) and the Surname value (AHMED). What is the best way to do this with javascript?
<div class="voffset3"></div>
<div class="container well panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-3">
<span class="ax_paragraph">
First name
</span>
<div class="form-group">
<div class="ax_h5">
ABDIGANI
</div>
</div>
</div>
<div class="col-md-3">
<span class="ax_paragraph">
Surname
</span>
<div class="form-group">
<div class="ax_h5">
AHMED
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You could consider HTML in most cases well structured. Try this the following snippet.
Edit: did a change due to the first comment.
Edit: if you have more than one rows, you should use
document.querySelectorAll('.container > .panel-body > .row');
and fetch the pairs for each found element as below.
const markers = ['First name', 'Surname'];
const mRx = [new RegExp(markers[0]), new RegExp(markers[1])];
function findMarker(element) {
for(let i = 0; i < mRx.length; i++) {
if(element.innerHTML.match(mRx[i])) {
return markers[i];
}
}
return null;
}
function findValue(el) {
return el.parentElement.querySelector('.form-group > div').innerHTML.trim();
}
const pairs = [... document.querySelectorAll('.ax_paragraph')]
.map(el => {
return {el: el, mk: findMarker(el)};
})
.filter(n => n.mk !== null)
.map(o => {
return {key: o.mk, value: findValue(o.el)};
});
console.log(pairs);
var x = document.querySelectorAll(".panel-body > div >.col-md-3 > div > div");
x.forEach(myFunction);
function myFunction(item, index) {
//console.log(item.innerHTML.trim());
if (index===0){
console.log("First name : "+item.innerHTML.trim());
}
if (index===1){
console.log("Surname : "+item.innerHTML.trim());
}
}
<div class="voffset3"></div>
<div class="container well panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-3">
<span class="ax_paragraph">
First name
</span>
<div class="form-group">
<div class="ax_h5">
ABDIGANI
</div>
</div>
</div>
<div class="col-md-3">
<span class="ax_paragraph">
Surname
</span>
<div class="form-group">
<div class="ax_h5">
AHMED
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Check this
const firstName = document.querySelector('.row .form-group div').textContent.trim();
const surname = document.querySelector('.row > div:last-child .form-group div').textContent.trim();
note: Its better to change html according to functionality needs, like if you need firstname then you must keep an id attribute to div which is having first name, same goes to surname. then select those fields using id selector, because even if you change html page structure in future, functionality will not get effected.
Check below for reference on how the html should actually be(just to make sure you know it, but the solution you are seeking is above in first two lines)
eg:
<div class="voffset3"></div>
<div class="container well panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-3">
<span class="ax_paragraph">
First name
</span>
<div class="form-group">
<div class="ax_h5" id="firstNameField">
ABDIGANI
</div>
</div>
</div>
<div class="col-md-3">
<span class="ax_paragraph">
Surname
</span>
<div class="form-group">
<div class="ax_h5" id="surnameField">
AHMED
</div>
</div>
</div>
</div>
</div>
</div>
</div>
document.querySelector('.form-group > div').textContent but without modifying the html there is no way to distinguish first name and surname.
If you can't edit the HTML, you can use the XPATH for Example.
I would like the .box elements to show/hide based on the words the user searches for, so for example if a user types in 'Title2 Title1' because those words exists inside box one and two they will remain visible with the renaming .box elements hiding. All the text within the .box elements needs to be searchable not just that in the .title element.
Below is how far I've got. It's almost there but it's not quite working as hoped.
Any help would be great.
Many thanks.
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">
Box title one content
</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">
Box title two content
</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">
Box title three content
</div>
</div>
<script>
$("#search").on("input", function () {
var search = $(this).val();
if (search !== "") {
var searchArray = search.split(" ");
searchArray.forEach(function(searchWord) {
$(".box").each(function () {
if($(this).is(':contains('+ searchWord +')')) {
$(this).show();
} else {
$(this).hide();
}
});
});
} else {
$(".box").show();
}
});
</script>
You need to use a different search method. :contains does not work as you expect. Consider the following example.
$(function() {
function filter(e) {
var term = $(e.target).val();
if (term.length < 3) {
$(".box").show();
return;
}
$(".box").each(function(i, el) {
if ($(".content", el).text().indexOf(term) >= 0) {
$(el).show();
} else {
$(el).hide();
}
});
}
$("#search").keyup(filter);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">Box title one content</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">Box title two content</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">Box title three content</div>
</div>
So for example if on is entered, no filtering is performed. If one is entered, the script will look inside the content class of each box and if one is found in the text, it will be shown otherwise, it is hidden. If the User clears their search out, all items are shown.
Hide all box before iterate, then only show when match any words:
$("#search").on("input", function () {
var search = $(this).val();
if (search !== "") {
var searchArray = search.split(" ");
// Hide all .box
$(".box").each(function () {
$(this).hide();
})
searchArray.forEach(function(searchWord) {
$(".box").each(function () {
if($(this).is(':contains('+ searchWord +')') ) {
$(this).show();
}
});
});
} else {
$(".box").show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">
Box title one content
</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">
Box title two content
</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">
Box title three content
</div>
</div>
Loop through all .boxs and using regex pattern matching, check either the title or content matches the search query. Show all matched boxes and hide all others
I have also fiddled it here
$("#search").on("input", function () {
var searchables=$('.box');
console.log(searchables)
var query=$(this).val();
searchables.each(function(i,item){
var title=$(item).find('.title').text();
var content=$(item).find('.content').text();
var rgx=new RegExp(query,'gi');
if(rgx.test(title) || rgx.test(content))
{
$(item).show();
}
else
{
$(item).hide();
}
})
})
I have some javascript function - shows me a popup with some texts. I try to rotate two "section" elements, but if I add to HTML one more section with class custom, the page shows only first element. Please, help me to add 1-2 more elements and to rotate it. The idea is to have 2 or more elements with class custom and to show it in random order, after last to stop. Thanks.
setInterval(function () {
$(".custom").stop().slideToggle('slow');
}, 2000);
$(".custom-close").click(function () {
$(".custom-social-proof").stop().slideToggle('slow');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="custom">
<div class="custom-notification">
<div class="custom-notification-container">
<div class="custom-notification-image-wrapper">
<img src="checkbox.png">
</div>
<div class="custom-notification-content-wrapper">
<p class="custom-notification-content">
Some Text
</p>
</div>
</div>
<div class="custom-close"></div>
</div>
</section>
Set section display none of page load instead of first section. Check below code of second section:
<section class="custom" style=" display:none">
<div class="custom-notification">
<div class="custom-notification-container">
<div class="custom-notification-image-wrapper">
<img src="checkbox.png">
</div>
<div class="custom-notification-content-wrapper">
<p class="custom-notification-content">
Mario<br>si kupi <b>2</b> matraka
<small>predi 1 chas</small>
</p>
</div>
</div>
<div class="custom-close"></div>
</div>
</section>
And you need to make modification in your jQuery code as below:
setInterval(function () {
var sectionShown = 0;
var sectionNotShown = 0;
$(".custom").each(function(i){
if ($(this).css("display") == "block") {
sectionShown = 1;
$(this).slideToggle('slow');
} else {
if (sectionShown == 1) {
$(this).slideToggle('slow');
sectionShown = 0;
sectionNotShown = 1;
}
}
});
if (sectionNotShown == 0) {
$(".custom:first").slideToggle('slow');
}
}, 2000);
Hope it helps you.
I have a hover effect (with 'div' slide up on a hover), but it works not properly - for some reason it opens on every element in the grid, but I need it to be only on mouseover element
$(document).ready(function() {
if($(document).width() > 992) {
$('.one').hover(function() {
var color = $(this).css('background-color'),
hint = $(this).parent().find('.morehover');
if (($(hint).text()).trim() == "") return 0;
$(hint).css('border-top-color', color).clearQueue().delay(500).slideDown();
}, function() {
var hint = $(this).parent().find('.morehover').first();
$(hint).clearQueue().delay(500).slideUp();
});
}});
and
<div class="one">
<?= $f_AdminButtons ?>
<div class="img-logo-cat"> <img src="<?= $f_imagelogocatalogue ?>" alt="">
<div class="link-not-link">
<?= $f_linkShow ?>
</div>
</div>
<div class="image"><img src="<?= $f_phoneImage ?>" alt=""></div>
<div class="line"></div>
<div class="more">
<div class="morehover">
<?= nc_edit_inline('morehover', $f_RowID, $cc)?>
<div class="ssilka-podrob"><a class="ssilka-podrob-link" href="<?= $f_linkMore ?>">Подробнее </a><i class="fas fa-angle-right"></i></div>
</div><span><?= nc_edit_inline('Price', $f_RowID, $cc)?></span>
<a href="<?= $f_buttonLink ?>" class="button" target="_blank">
<?= $f_buttonText ?>
</a>
</div>
</div>
Where is my mistake?
look at this line:
hint = $(this).parent().find('.morehover');
You are on the element <div class="one"> and you are selecting the parent element of it than looking for morehover. You want the morehover inside of the element you are on, so you should NOT be looking at the parent.
hint = $(this).find('.morehover');