How to replace two class attribute in html content? - javascript

In my project, I fetch html content from DB with ajax, and these content will appear in web in div with id of timeTagDiv.
If My name is John, it should appears:
17:05:31 John translatetomaintanceGroup
letMnGrpmakeit
17:05:53 snow acceptSheet
17:06:04 snow translatetoleadGrp
leadercheckit
If my name is snow, it should appears:
17:05:31 John translatetomaintanceGroup
letMnGrpmakeit
17:05:53 snow acceptSheet
17:06:04 snow translatetoleadGrp
leadercheckit
Here is my ajax code:
var stChr="John";
var stTrnStr="translateto";
$.ajax({
......
success:function(data)
{
var $myHtml = $(data.stPrc);
$myHtml.find("label").filter(function(){
return $(this).text()===stChr;
}).parent().attr("class", "rightd");
//$myHtml.find('div:contains('+stChr+' '+stTrnStr+')').next().attr('class','rightd');
$('#timeTagDiv').html($myHtml);
}
});
Here is the content of data.stPrc from DB:
<div class="leftd">
<label>17:05:31</label>
<label>John</label>
<label> translateto</label>
<label>maintanceGroup</label>
</div>
<div class="leftd">
<div class="speech left" >letMnGrpmakeit</div>
</div>
<div class="leftd"><label>17:05:53</label>
<label>snow</label>
<label> acceptSheet</label>
</div>
<div class="leftd">
<label>17:06:04</label>
<label>snow</label>
<label> translateto</label>
<label>leadGrp</label>
</div>
<div class="leftd">
<div class="speech left" >leadercheckit</div>
</div>
When the context of label is John, the attribute class of parent div changed to rightd. Here is the code working successfully:
$myHtml.find("label").filter(function(){
return $(this).text()===stChr;
}).parent().attr("class", "rightd");
And then, the content of letMnGrpmakeit belongs to John should at the right side. So the next two divs class should be set class="rightd" and class="speech right".
In my example, before:
<div class="leftd">
<div class="speech left" >letMnGrpmakeit</div>
</div>
after replace:
<div class="rightd">
<div class="speech right" >letMnGrpmakeit</div>
</div>
I use :
$myHtml.find('div:contains('+stChr+' '+stTrnStr+')').next().attr('class','rightd');
$myHtml.find('div:contains('+stChr+' '+stTrnStr+')').next().next().attr('class','speech right');
But unfortunately, they both worked fail.
I have tried one condition:
$myHtml.find('label:contains('+stTrnStr+')').parent().next().attr('class','rightd');
It works, but it appears like:
17:05:31 John translatetomaintanceGroup
letMnGrpmakeit
17:05:53 snow acceptSheet
17:06:04 snow translatetoleadGrp
leadercheckit
"leadercheckit" should under "17:06:04 snow translatetoleadGrp", because it belongs to snow.
I have no idea about this. The key to change two div class are two conditions.
Who can help me?

I'm not sure I understand everything correctly because of wording and grammar, but I would suggest using addClass('className') and removeClass('className') instead. This way if your element has more than one class, it will only remove the desired class. By using .attr('class', 'className'), you're replacing everything. If you wish to add multiple classes, just use .addClass('class-1 class-2')

Use these:
$myHtml.find('label:contains('+stChr+')').next('label:contains('+stTrnStr+')').parent().next().attr('class','rightd');
$myHtml.find('label:contains('+stChr+')').next('label:contains('+stTrnStr+')').parent().next().children("div").eq(0).attr('class','speech right');

Related

Get first div after button is clicked

I have the following bit about shop info:
<h3 class="-center"><shop>Shop name</shop></h3>
<button type="button" id="banff" onclick="showShop(this.id)"><shop-title><b>Bakery Shop</b></shop-title></button>
<p class="move-right"><shop-info>Shop Address · Shop number</shop-info></p>
<div id="shop" class="hidden">
<p><shop-info>Opening soon</shop-info></p>
</div>
What I'm trying to do is that once the button is clicked, it will get the first div after the button and toggle the hidden class without referencing the id, there will be multiple shops so I am trying to create one function which will work for all of them rather than create an individual function for each.
I thought I could do something like:
function showShop(id) {
const elem = document.getElementById(id);
alert(id);
const div = elem.closest('div');
div.classList.toggle('hidden');
}
But it's referencing the first div on the page rather than the first one after the button, where have I gone wrong here? Or do I need to go about this a different way?
Thanks in advance for any advice
What about connecting the button id with the div id?
something like:
<h3 class="-center"><shop>Shop name</shop></h3>
<button type="button" id="button-1" onclick="showShop(this.id)">
<shop-title><b>Bakery Shop</b></shop-title>
</button>
<p class="move-right"><shop-info>Shop Address · Shop number</shop-info></p>
<div id="shop-button-1" class="hidden">
<p><shop-info>Opening soon</shop-info></p>
</div>
and in the javascript code would be possible to simplify to:
function showShop(id) {
const elem = document.getElementById(id);
const div = document.getElementById('shop-' + id);
div.classList.toggle('hidden');
}
You should try and avoid using ids as they are difficult to keep track of. Instead you should navigate relative to the clicked button. Below is a script that can easily take care of multiple shop sections without using any ids:
document.querySelectorAll("button").forEach(btn=>{
for(var div=btn;div=div.nextElementSibling;)
if(div.tagName==="DIV") break;
if(div) btn.onclick=()=>div.classList.toggle("hidden")
})
.hidden {display:none}
<h3 class="-center"><shop>Shop name</shop></h3>
<button><shop-title><b>Bakery Shop</b></shop-title></button>
<p class="move-right"><shop-info>Shop Address · Shop number</shop-info></p>
<div class="hidden">Info on bakery shop:
<p><shop-info>Opening soon</shop-info></p>
</div>
<button><shop-title><b>Iron Monger</b></shop-title></button>
<p class="move-right"><shop-info>Shop Address · Shop number</shop-info></p>
<div class="hidden">Info on iron monger's:
<p><shop-info>already open!</shop-info></p>
</div>
<button><shop-title><b>Fish Monger</b></shop-title></button>
<p class="move-right"><shop-info>Shop Address · Shop number</shop-info></p>
<div class="hidden">Info on fish monger's:
<p><shop-info>will never open!</shop-info></p>
</div>
In my latest update I tweaked the snippet again so that now I do the "relative navigation to the associated <div>" only once: at the time when I define and add the onclick eventlistener.

Show/hide multiple children classes for an individual parent click (Jquery)

I'm fairly new to Javascript/Jquery and I'm trying to hide multiple children/adjacent classes when a specific parent class is clicked.
Here's my HTML
<div class="container">
<div class="row">
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small">
<i class="fa fa-clock-o"></i>
</div>
<div class="pov_title_small">
MEASURE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_large">
<i class="fa fa-map-marker"></i>
</div>
<div class="pov_title_large">
MEASURE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small">
<i class="fa fa-commenting"></i>
</div>
<div class="pov_title_small">
MEASURE
</div>
</div>
</div>
</div>
What I'm aiming to do is: When a user clicks one of the two smaller icons shown (pov_icon_small), for that individual icon: the classes pov_icon_small and pov_title_small will change to pov_icon_large and pov_title_large respectively. In the same time, I want the other 'large' icon and 'title' to revert back to the 'small' state
I've started calling some Javascript but I don't think I'm headed the right way:
$('.pov_icon_small').on('click', function (e) {
$(this).toggleClass("pov_icon_large");
});
Would anyone be willing to point me to the right direction?
To use individual click
$('.pov_icon_small , .pov_icon_large').on('click', function (e) {
$('.pov_icon_large').not($(this)).removeClass('pov_icon_large').addClass('pov_icon_small');
$(this).toggleClass("pov_icon_small").toggleClass("pov_icon_large");
});
and for title the same way
$('.pov_title_small , .pov_title_large').on('click', function (e) {
$('.pov_title_large').not($(this)).removeClass('pov_title_large').addClass('pov_title_small');
$(this).toggleClass("pov_title_small").toggleClass("pov_title_large");
});
Working Demo
To run both action on icon click use this
$('.pov_icon_small , .pov_icon_large').on('click', function () {
$('.pov_icon_large').not($(this)).removeClass('pov_icon_large').addClass('pov_icon_small');
$('.pov_title_large').not($(this).next('div[class^="pov_title_"]')).removeClass('pov_title_large').addClass('pov_title_small');
$(this).toggleClass("pov_icon_small").toggleClass("pov_icon_large");
$(this).next('div[class^="pov_title_"]').toggleClass("pov_title_small").toggleClass("pov_title_large");
});
Working Demo
Note: be sure to include Jquery
You can add a common class icon for the icon div and title for the title div and following code will work,
$(".pov_icon_small").on('click',function(){
$(this).parent().siblings().children('div').each(function(value){
if($(this).hasClass('icon'))
$(this).addClass('pov_icon_small').removeClass('pov_icon_large');
else if($(this).hasClass('title'))
$(this).addClass('pov_title_small').removeClass('pov_title_large');
});
$(this).addClass('pov_icon_large').removeClass('pov_icon_small');
$(this).siblings('.title').addClass('pov_title_large').removeClass('pov_title_small');
});
Here as you can see, I am first getting parent of the icon clicked i.e. Your pav_icon div now I am changing for all the siblings now each div in the sibling. If it is Iicon changing icon classes as required if title changing title classes.

Changing content in a div when a link is clicked

I am trying to change a div content box when a link above that box is clicked. I added a click function to the individual buttons then the corresponding dive containing the content for that particular box should be displayed.
When I apply the jQuery to the page, the content does not change according to the link that is clicked and the page displays awkwardly.
This is the jsfiddle I'm working with.
The webpage I'm working with is here.
Place where am i making the mistake.
The jQuery I'm working with so far looks like this
$(document).ready(function() {
$('.question1').click(function(){
$('.new_member_box_display').load('#answer1');
})
$('.question2').click(function(){
$('.new_member_box_display').load('#answer2');
})
$('.question3').click(function(){
$('.new_member_box_display').load('#answer3');
})
$('.question4').click(function(){
$('.new_member_box_display').load('#answer4');
})
});//end of ready
The HTML I'm working with looks like this :
<div class="new_member_box">
<h4>Vision</h4>
</div>
<div class="new_member_box">
<h4>Church History</h4>
</div>
<div class="new_member_box">
<h4>Becoming a Member</h4>
</div>
<div class="new_member_box">
<h4>Pastor-in-Training</h4>
</div>
</div>
<div class="clear" class="question"></div>
<div id="answer1">
1
</div>
<div id="answer2">
2
</div>
<div id="answer3">
3
</div>
<div id="answer4">
4
</div>
<div class="new_member_box_display" id="question">
Text will appear here when one of the tabs above is clicked
</div>
load() loads an external file with ajax, not elements on your page. You're probably just trying to hide and show elements :
$('[class^="question"]').on('click', function(e){
e.preventDefault();
var numb = this.className.replace('question', '');
$('[id^="answer"]').hide();
$('#answer' + numb).show();
});
FIDDLE
Here's a fiddle that does what I think you're looking to do. There are cleaner ways to do it, but this should work.
http://jsfiddle.net/PZnSb/6/
Basically you want to set the inner html of one element to the inner html of another, like this:
$('.question1').click(function(){
$('.new_member_box_display').html($('#answer1').html());
})
instead of this:
$('.question1').click(function(){
$('.new_member_box_display').load('#answer1');
})
It seems you just want the text to change when you click, try this.
$(document).ready(function() {
$('.question1').click(function(){
$('.new_member_box_display').text($('.answer1 ').text());
});
$('.question2').click(function(){
$('.new_member_box_display').text($('.answer2').text());
});
$('.question3').click(function(){
$('.new_member_box_display').text($('.answer3').text());
});
$('.question4').click(function(){
$('.new_member_box_display').text($('.answer4').text());
});
});
http://jsfiddle.net/cornelas/PZnSb/7/embedded/result/

filtering and sorting divs

I have been looking for a robust and simple way to sort my casestudies but after a couple of hours and a search of stack overflow i could not find a way to filter casestudies the way I want.
Basically I will give each casestudy three categories (year produced, type of project and name) using css classes, for example the markup would look something like this
<div class="name1 home 2013"></div>
<div class="name2 work 2012"></div>
<div class="name3 home 2012"></div>
<div class="name4 charity 2012"></div>
<div class="name5 home 2010"></div>
<div class="name6 work 2007"></div>
Then I want to have buttons so you can choose which category you want to sort the casestudies by. So something like.
<div class="button" id="year">Sort by Year</div>
<div class="button" id="alpha">sort Alphabetically</div>
<div class="button" id="type">sort by type</div>
This is where I am getting stuck. What javascript function can i create so that if you click the button "sort by year" it will create a mark up that looks like this. eg sorting all the casestudies in to divs with casestudies of the same year.
<div>
<div class="name1 home 2013"></div>
</div>
<div>
<div class="name2 work 2012"></div>
<div class="name3 home 2012"></div>
<div class="name4 charity 2012"></div>
</div>
<div>
<div class="name5 home 2010"></div>
</div>
<div>
<div class="name6 work 2007"></div>
</div>
I would use data attributes to make the filtering easier.
<div class="name1 home" data-year="2013">2013</div>
<div class="name2 work" data-year="2012">2012</div>
<div class="name3 home" data-year="2012">2012</div>
<div class="name4 charity" data-year="2012">2012</div>
<div class="name5 home" data-year="2010">2010</div>
<div class="name6 work" data-year="2007">2007</div>
The using JQuery and array.map (could be replaced with a foreach if you want older browser support)
var studies = $('[data-year]')
studies.map(function(index, el) {
var $el = $(el)
year = $el.attr('data-year')
if($('#' + year).length == 0){
$(document.body).append(
$('<div>').attr('id', year)
.css('margin-bottom', '20px')
)
}
$('#' + year).append(el)
})
what this does is take all the elements with a data-year attribute, foreach element check to see if a div with the id of that elements year exists. If it doesn't create one and append it to the body. Then it appends the element into the year container.
see this jsfiddle

animate show/hide from css class

I'm new to JavaScript and jQuery so please be gentle with me. I'm trying to animate a show/hide of several divs based on if it has a certain class or not.
Basically, I'm creating a site for a photographer and have a portfolio section with a list of filters along the top, each div has a class of "portfolio-items" as well as additional classes for all the categories it's in, so family / wedding / kids / couples. any image can have multiple classes on it.
What I want to do is click on the family link and it hides anything that doesn't have the family class on it. If I then click on wedding it closes anything that's currently open that doesn't have the wedding class on it and opens anything thats currently closed that does have the wedding class on it.
I currently have it working with the code below but this simply closes everything and then opens the ones that have the class required. Plus I don't know how to add an animate to it.
function portfolioItems(filter) {
$(".portfolio-items").hide();
$("."+filter).show(); }
function initEventHandlers () {
$(".port-all").click(function () {
$(".portfolio-items").show();
return false;
})
$(".port-wedding").click(function () {
portfolioItems("wedding");
return false;
})
$(".port-family").click(function () {
portfolioItems("family");
return false;
})
$(".port-kids").click(function () {
portfolioItems("kids");
return false;
})
$(".port-couples").click(function () {
portfolioItems("couples");
return false;
}) }
The HTML is...
<div class="portfolio-container">
<div class="portfolio-links">
<img alt="All" class="port-all" src="images/port-all.png" />
<img alt="family" class="port-family" src="images/port-family.png" />
<img alt="wedding" class="port-wedding" src="images/port-wedding.png" />
<img alt="couples" class="port-couples" src="images/port-couples.png" />
<img alt="kids" class="port-kids" src="images/port-kids.png" />
</div>
<div class="portfolio">
<div class="portfolio-items wedding couples family"></div>
<div class="portfolio-items kids"></div>
<div class="portfolio-items wedding kids family"></div>
<div class="portfolio-items couples"></div>
<div class="portfolio-items couples kids family"></div>
<div class="portfolio-items wedding"></div>
</div>
</div>
First of all you may use not selectors(look here!) to avoid hiding all your photos. Just assign two classes to your blocks with photos. Something like this
<div class="portfolio-items wedding"></div>
<div class="portfolio-items family"></div>
<div class="portfolio-items kids"></div>
And then you can rewrite your portfolioItems function in this way
function portfolioItems(filter) {
$(".portfolio-items:not(."+filter+")").hide();
}
Secondly you may create one generic function for hiding some category, but not duplicating the same code by several times.
You can try this:
function portfolioItems(filter) {
$(".portfolio-items.not("+filter+")").fadeOut();
$("."+filter).fadeIn();
}
Here's an approach I've found useful for filtering via CSS. I like to use the data attribute on links to specify a filter. To start, set up a navigation with some links and a portfolio with some images or divs:
<!-- set up some navigation -->
<nav>
All Photos
Family Photos
Art Photos
Wombat Photos
</nav>
<!-- set up a portfolio -->
<div class="portfolio">
<div class="family item">Some family image or something</div>
<div class="art item"> Some art image or something</div>
<div class="wombats item">Some wombat image or something</div>
<div class="wombats item">Some wombat image or something</div>
<div class="art item"> Some art image or something</div>
</div>
Notice how each of the a tags has the class name you'd want to use as a filter as a data-filter attribute. You can specify multiple classes in here and it'll work just the same. For instance ".wombat.family" would let you use a DOUBLE filter in your portfolio.
Here's a script that will help you get set up to filter:
//on document ready
$(document).ready(function(){
//when you click <a> tag in the <nav>
$("nav a").click(function(e){
//if the <a> has a data-filter attribute
if($(this).attr("data-filter")){
//show all the .items with the class in the data-filter attribute
$(".portfolio .item"+$(this).attr("data-filter")).show(300);
//hide all the .items that do not have that class
$(".portfolio .item:not("+$(this).attr("data-filter")+")").hide(300);
}else{
//if there's no data-filter attribute, show all the images
$(".portfolio .item").show(300);
}
});
});
For this one, I'm simply using a time in the show() and hide() functions, but fadeIn() fadeOut() might work for you as well.
To enable the "all" filter, I simply didn't write a data-filter attribute for that particular a tag and made sure JS knew what to do (check the if/else).
The important thing to remember is the link between the class used on the portfolio item and the data-filter attribute. Pretty simple to get started, though I'm sure it'll get a little more complicated before you get finished :)
Here's a jsfiddle to play around: http://jsfiddle.net/w4VWm/
Good luck!
Hide all, add the new classname to a filter string then show by the filter string
http://jsfiddle.net/uhCY5/3/
var filters = "";
function portfolioItems(filter) {
filters += '.' + filter
$(".portfolio-items").hide();
$(filters).show();
$("#filter").text(filters)
}
function initEventHandlers() {
$(".port-all").click(function () {
filters = "";
$(".portfolio-items").show();
return false;
})
// the rest is the same
}
Not sure exactly what kind of transition you want, but this will do a fade in/out with very little jquery:
please note, you may be able to remove some of the stuff in the divs, but i didn't know what you needed for other things on the page
the fiddle: http://jsfiddle.net/Z5uXP/
<div class="portfolio-container">
<div class="portfolio-links">
<img alt="All" class="port-all" src="images/port-all.png" />
<img alt="family" class="port-family" src="images/port-family.png" />
<img alt="wedding" class="port-wedding" src="images/port-wedding.png" />
<img alt="couples" class="port-couples" src="images/port-couples.png" />
<img alt="kids" class="port-kids" src="images/port-kids.png" />
</div>
<div class="portfolio">
<div class="portfolio-items wedding couples family"></div>
<div class="portfolio-items kids"></div>
<div class="portfolio-items wedding kids family"></div>
<div class="portfolio-items couples"></div>
<div class="portfolio-items couples kids family"></div>
<div class="portfolio-items wedding"></div>
</div>
</div>
<script>
$(document).ready(function(){
var $container = $("div.portfolio-container"),
$portfolio = $container.find("div.portfolio");
$container
.on("click", ".portfolio-links a", function(event){
var $obj = $(this);
event.preventDefault();
$portfolio
.fadeOut()
.queue(function(next){
$($(this)[0]).css("color", "red")
.removeClass("family wedding couples kids")
.addClass($($obj[0]).data("type"));
next();
})
.fadeIn();
});
});
</script>
<style>
.portfolio .portfolio-items{
display: none;
}
.portfolio.all .portfolio-items,
.portfolio.family .portfolio-items.family,
.portfolio.wedding .portfolio-items.wedding,
.portfolio.couples .portfolio-items.couples,
.portfolio.kids .portfolio-items.kids{
display: block;
}
</style>

Categories