Change div order based on operating system - javascript

I would like to change div order based on operating system.
For example on windows
<div class="first"> </div>
<div class="second"> </div>
<div class="third"> </div>
on Mac
<div class="third"> </div>
<div class="first"> </div>
<div class="second"> </div>
I have some this js to show and hide a div which is okay if I use a parent div but I would rather reorder.
if (navigator.appVersion.indexOf("Mac") > -1) {
$('#windows').hide();
$('#mac').show();
}

Here is one way:
if (navigator.appVersion.indexOf("Mac") > -1) {
$('.third').insertBefore('.first');
}
There is also .insertAfter() that you can use. I would use these methods for basic reordering like that seen in your example. If there is a lot of re-ordering required, I think a different approach may be better, like #Daniel's example

For a more general solution, you could store the order for each platform in an array and then go through the array and re-add the element to the container using $.appendTo().
Demo
HTML
<div id="container">
<div class="first">1</div>
<div class="second">2</div>
<div class="third">3</div>
</div>
JS
var macOrder = [".third", ".first", ".second"];
$(function () {
var container = $('#container');
for (var i = 0; i < macOrder.length; i++) {
$(macOrder[i]).appendTo(container);
}
});

Related

Link simillary name classes so that when one is clicked the other is given a class

Basically, I'm asking for a way to optimize this code. I'd like to cut it down to a few lines because it does the same thing for every click bind.
$("#arch-of-triumph-button").click(function(){
$("#arch-of-triumph-info").addClass("active-info")
});
$("#romanian-athenaeum-button").click(function(){
$("#romanian-athenaeum-info").addClass("active-info")
});
$("#palace-of-parliament-button").click(function(){
$("#palace-of-parliament-info").addClass("active-info")
});
Is there a way to maybe store "arch-of-triumph", "romanian-athenaeum", "palace-of-parliament" into an array and pull them out into a click bind? I'm thinking some concatenation maybe?
$("+landmarkName+-button").click(function(){
$("+landmarkName+-info").addClass("active-info")
});
Is something like this even possible?
Thanks in advance for all your answers.
EDIT: Here's the full HTML.
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button"></div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button"></div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Assuming you're not able to modify your HTML markup (in which case with use of CSS classes would be cleaner), a solution to your question would be as shown below:
// Assign same click handler to all buttons
$("#arch-of-triumph-button, #romanian-athenaeum-button, #palace-of-parliament-button")
.click(function() {
// Extract id of clicked button
const id = $(this).attr("id");
// Obtain corresponding info selector from clicked button id by replacing
// last occurrence of "button" pattern with info.
const infoSelector = "#" + id.replace(/button$/gi, "info");
// Add active-info class to selected info element
$(infoSelector).addClass("active-info");
});
Because each .landmark-button looks to be in the same order as its related .landmark-info, you can put both collections into an array, and then when one is clicked, just find the element with the same index in the other array:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
This does not rely on IDs at all - feel free to completely remove those from your HTML to declutter, because they don't serve any purpose now that they aren't being used as selectors.
Live snippet:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
.active-info {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button">click</div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button">click</div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Older answer, without knowing the HTML: You can extract the ID of the clicked button, slice off the button part of it, and then select it concatenated with -info:
$(".landmark-button").click(function() {
const infoSel = this.id.slice(0, this.id.length - 6) + 'info';
$(infoSel).addClass('active-info');
});
A much more elegant solution would probably be possible given the HTML, though.

How to show element only if other element contains something using jQuery?

My guess is what I want to achieve should be easy, but due to my lack of knowledge of front-end development, I cannot manage to solve issue. Have a page that works with AJAX-filters that users can select. Filters that are currently applied show up within <div> with id=current-filters.
HTML looks like this:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Need to hide the the entire DIV current-filters-box in case no filter is applied.
The page uses a Javascript file, bundle.js which is massive, but contains the following line:
s=document.getElementById("current-filters")
Therefore tried the following if-statement to hide the DIV:
if(s.length<1)$('#current-filters-box').hide()
and
if(s=0)$('#current-filters-box').hide()
But this does not seem to have any effect. Can someone tell, what I did wrong?
Demo of page can be found here
EDIT: this is what the HTML looks like when filters are applied:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Both of your conditions are incorrect or I would say they are not doing what you think they do.
s.length will always prints undefined so instead of s.length<1 you could use s.children.length
and the second one is not a condition rather it is an assignment
s==0 // condition
s=0 //assignment
the correct condition for your requirement would be
if(s.children.length<1){
I have assigned snippets for illustration.
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="current-filters-box">
filter box
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Try this .
if( $('#current-filters').is(':empty') ) {
$('#current-filters-box').hide()// or $('#current-filters-box').css("display","none")
}
You are performing an assignment, try..
if (s.children.length)
Using vanilla JavaScript, you can check if the current-filters div is empty or not and toggle the parent div current-filters-box like this:
s= document.getElementById("current-filters");
t= document.getElementById("current-filters-box");
if(s.children.length<1) {
t.style.display = 'none';
// t.style.visibility= 'hidden'; <<-- use this if you want the div to be hidden but maintain space
}
else {
t.style.display = 'block';
// t.style.visibility= 'visible'; <<-- use this if you used visibility in the if statement above
}
You can achieve this by adding your own variable which counts or maintains your applied filters, e.g.
var applied_filter_count = 0;
at every time filter is applied
applied_filter_count++;
if(applied_filter_count) {
$('#current-filters-box').show()
}
and at every time filter is removed
applied_filter_count--;
if(!applied_filter_count) {
$('#current-filters-box').hide()
}
and by default current-filters-box should be display:none

$().next() returning the same element multiple times

I tried to name the title as best I could. A little difficult for me to explain.
I'm having an issue with some code I'm writing (which runs in a widget on my wordpress site.) What I've written here emulates this issue. Just fyi I'm very new to jquery, JS, etc.
What I'm trying to do is set the variable "thumb" to the element after "widget-code". It works, however it's only finding that element ("thumb-class") in "wordpress-post1"
The console output is:
wordpress-post1
wordpress-post1
wordpress-post1
But it should be:
wordpress-post1
wordpress-post2
wordpress-post3
This is the actual code
<div class="wordpress-post1">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("#widget-code").next();
console.log(thumb[0].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post2">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("#widget-code").next();
console.log(thumb[0].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post3">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("#widget-code").next();
console.log(thumb[0].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
I'm going to try and clarify a little more:
This code is placed in an html widget which the wordpress theme I'm using provides. It hooks into each post. This is the only place I can put code, and this is the only code I've written. (I haven't altered the theme's files in any way.)
I have no control over the name of the classes or IDs. And they're dynamic. An unlimited number of posts could exist. Therefore I can't hardcode anything.
In order for this code to work correctly it'll need to find the sibling of the "widget-code" element in only the post it's running from.
This is the link to the code on JSFiddle: http://jsfiddle.net/pattnvy3/
Would appreciate any help on the matter.
If you want a nasty hack, try
<div class="wordpress-post1">
<div id="widget-code">
<script>
$(document).ready(function(){
var c = window['widget-code-counter'] || 0;
window['widget-code-counter'] = ++c;
var className = 'wordpress-post' + c;
console.log(className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
Demo: Fiddle
It will give the container class wordpress-post1, then you can use it to find any of the descendant element.
As per the immediate comments, it is invalid markup to use an id for multiple elements. That said, changing your id to a class such that:
<div class="wordpress-post[some-number-here]">
<div class="widget-code">
</div>
<div class="thumb-class">
</div>
</div>
would allow you to to a jQuery selector like so:
$('.widget-code').each(function (){
var thumb = $(this).next();
console.log(thumb[0].parentElement.className);
});
However, if I may make a recommendation, I would say that you tag each of your wordpress-post divs with the class "wordpress-post" and then have a more specific id which is the value you want to print.
Then it would look like this:
<div id="wordpress-post[some-number-here]" class="wordpress-post">
<div class="widget-code">
</div>
<div class="thumb-class">
</div>
</div>
and your javascript like this (with jQuery):
$('.widget-code').each(function (){
var post = $(this).closest('.wordpress-post');
console.log(post.attr('id'));
});
or even simpler:
$('.wordpress-post').each(function (){
console.log($(this).attr('id'));
});
depending on the needs you have. If you have any questions as to what you need, feel free to comment and I will get back to you as soon as I can.
A pure javascript method:
This is just a workaround since you have no control over ids or classes, this will target all div elements on the page, loop through them and search for any that contains wordpress-post in the class name.
window.onload=function(){
var posts=document.getElementsByTagName('div');
for(var i=0; i<posts.length; i++){
if(posts[i].className.indexOf("wordpress-post")> -1){
console.log(posts[i].className);
//Snippet Use
alert(posts[i].className);
}
}}
<div class="wordpress-post1">
<div id="widget-code"></div>
<div class="thumb-class"></div>
</div>
<div class="wordpress-post2">
<div id="widget-code"></div>
<div class="thumb-class"></div>
</div>
<div class="wordpress-post3">
<div id="widget-code"></div>
<div class="thumb-class"></div>
</div>
If you have any questions, please leave a comment below and I will get back to you as soon as possible.
I hope this helps. Happy coding!
This can help if you want to have multiple IDs:
$(document).ready(function(){
$("[id^=widget-code]").each(function(){
console.log(this.parentElement.className);
});
});
But, still multiple same Ids are not recommended.
FIDDLE
Update: Declare a global variable var i=0; and keep increment it like :
<div class="wordpress-post1">
<div id="widget-code">
<script>
var i=0;
$(document).ready(function(){
var thumb = $("[id^=widget-code]").next();
console.log(thumb[i++].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post2">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("[id^=widget-code]").next();
console.log(thumb[i++].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post3">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("[id^=widget-code]").next();
console.log(thumb[i++].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
DEMO

Hide parent div if child div is missing

Is it possible at all to hide a parent div if there is a child div missing?
In the example below I would like to hide the parent div of "#live-sessions" if some of the divs are missing such as .views-content and .views-row.
This is what it looks like when the divs are there:
<div id="live-sessions">
<div class="container">
<div class="row">
<div class="col-sm-3">
<h3 class="session-title">Sessions Live Now</h3>
<div class="col-sm-9">
<div class-"view-display-id-live_sessions">
<div class="views-content">
<div class="views-row">
</div>
<div class="views-row">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This is what it looks like when the divs are missing:
<div id="live-sessions">
<div class="container">
<div class="row">
<div class="col-sm-3">
<h3 class="session-title">Sessions Live Now</h3>
<div class="col-sm-9">
<div class-"view-display-id-live_sessions">
</div>
</div>
</div>
</div>
</div>
I tried using the :empty selector with the parent method, but my child div contains some blank lines so it doesn't think it's empty. Also I would like to hide the parent of the parent of the empty div.
$(".view-display-id-live_sessions:empty").parent().hide();
You have a typo in your html:
class-"view-display-id-live_sessions"
should be
class="view-display-id-live_sessions"
you can try the following jQuery code:
if ($(".view-display-id-live_sessions").html().trim() == '') {
$(".view-display-id-live_sessions").parent().parent().hide();
}
jqVersion demo
Use jQuery has() in a negative if test - http://api.jquery.com/has/
if(!$('#parent').has('.child')){
$('#parent').hide();
}
There isn't a one-line-query for this. Following code would do the trick:
$('#live-sessions .row').each(function(idx, row) {
if ($(row).find('.views-content').length == 0) {
$(row).hide();
}
});
If you want to keep using jQuery, you could instead do:
if ( ! $(".view-display-id-live_sessions").children().length ) { /* your logic */ }
Note that there's a syntax error in your code:
<div class-"view-display-id-live_sessions">
Should be
<div class="view-display-id-live_sessions">
If you understand your question:
First you need to check the number of .views-row divs. If the length is zero hide the parent div.
Ex:
if ($('.views-row').length < 1)
$('#live-sessions').hide();
Good Luck.
You need to trim the blank spaces, correct a typo and test for the text within the div -
class="view-display-id-live_sessions" // note the equals sign after class
The code to do the hiding (EDIT re-read problem again):
var liveSessionsText = $.trim( $('.view-display-id-live_sessions').text() );
if(0 == liveSessionsText.length) {
$('.view-display-id-live_sessions').closest('.row').hide();
}
The div with class="row" is the parent of the parent of view-display-id-live_sessions.

How should I edit strings across many instances of the same html?

I've got this code below, with different data, repeated over 10 times on the page I am working on:
HTML:
<div class="kpaGraph">
<p>Target: 43%</p>
<div class="progress">
<div class="bar"></div>
</div>
</div>
<div class="kpaBottom">
<div class="strong">
<p>311</p>
</div>
<div class="weak">
<p>number of teachers trained</p>
</div>
</div>
I want to alter the number in div.strong p (311) based on the number in div.kpaGraph p (43%) in the same manner across all instances of this code with Javascript/ jQuery. What is the cleanest way to do this? Should I select all $('div.kpaGraph p') and then use each() Or should I create a function and run it on all of them?
Thanks!
You can use the following to find the proper element in conjuntion with an .each() on $('div.kpaGraph p'):
$(this).parent().next('div.kpaBottom').find('div.strong p')
For example, using the following will take the value in the kpaGraph p node and append it to the p node in the following kpaBottom node:
$('div.kpaGraph p').each(function () {
$(this).parent().next('div.kpaBottom').find('div.strong p').html('foo');
});
jsFiddle example
There are a few ways.
You can use "next".
$('.kpaGraph').each(function(){
var $kpaStrong = $(this).next('.kpaBottom .strong p');//this is the elm that has 311
});
Or you have to somehow create a relation between them so you know they go together, like a common parent.
<div class="kpaWr">
<div class="kpaGraph">
<p>Target: 43%</p>
<div class="progress">
<div class="bar"></div>
</div>
</div>
<div class="kpaBottom">
<div class="strong">
<p>311</p>
</div>
<div class="weak">
<p>number of teachers trained</p>
</div>
</div>
</div>
Then with jQuery you can select it like so:
$('.kpaGraph').each(function(){
var $kpaStrong = $(this).closest('.kpaWr').find('.kpaBottom .strong p');//this is the elm that has 311
});
Something like this might be pretty clean too:
$("div.strong p").text(function(index, text){
return $(this).closest("div.kpaBottom").prev("div.kpaGraph").find("p").text();
});
That would change the text to Target: 43% in your example.

Categories

Resources