How to handle alternating rows dynamically? - javascript

Consider the following example: (live demo here)
HTML:
<div class="wrapper">
<div city_id="1" class="odd">Street Name #1 in city 1</div>
<div city_id="3" class="even">Street Name #2 in city 3</div>
<div city_id="2" class="odd">Street Name #3 in city 2</div>
<div city_id="1" class="even">Street Name #4 in city 1</div>
<div city_id="1" class="odd">Street Name #5 in city 1</div>
<div city_id="3" class="even">Street Name #6 in city 3</div>
<div city_id="2" class="odd">Street Name #7 in city 2</div>
<div city_id="3" class="even">Street Name #8 in city 3</div>
<div city_id="1" class="odd">Street Name #9 in city 1</div>
</div>
<select>
<option value="">Please select...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
CSS:
.odd {
background-color: #777;
}
.even {
background-color: #aaa;
}
JS:
$(function() {
$("select").change(function() {
var city_id = $("option:selected", this).val();
$("div[city_id]").each(function() {
$(this).toggle($(this).attr("city_id") == city_id);
});
});
});
I would like to keep the alternating coloring even when some rows are hidden.
Is that possible to achieve this with pure CSS ?
If no, how would you do this using Javascript/jQuery ?

Here's a simple solution . Dynamically change the row's class while the selected index changes
http://jsfiddle.net/4Bjbc/5/
$(function() {
$("select").change(function() {
var city_id = $("option:selected", this).val();
$("div[city_id]").each(function() {
$(this).toggle($(this).attr("city_id") == city_id);
}).filter(":visible") ///filter the visible ones
.attr("class",function(index,$class){
///if you don't want to miss out the other classes
return index%2 == 0 ? $class.replace("odd","even") : $class.replace("even","odd");
});
});
});

you need from javascript to set the class odd or even by walking through the items and if they are visible alternate the class

You can use CSS for it:
.wrapper div:nth-child(even) { background-color: #777; }
.wrapper div:nth-child(odd) { background-color: #aaa; }
However, it won't take hidden rows into account. To achieve this, you need to restrict the div selector even more:
.wrapper div.visible:nth-child(even) { background-color: #777; }
.wrapper div.visible:nth-child(odd) { background-color: #aaa; }
Then you just need to ensure that all visible elements have the visible class.

With jquery you could use in the change event:
$('.wrapper div:visible:even').css({
'background-color': '#777'
});
$('.wrapper div:visible:odd').css({
'background-color': '#aaa'
});
FULL CODE
$("select").change(function() {
var city_id = $("option:selected", this).val();
$("div[city_id]").each(function() {
$(this).toggle($(this).attr("city_id") == city_id);
});
$('.wrapper div:visible:even').css({
'background-color': '#777'
});
$('.wrapper div:visible:odd').css({
'background-color': '#aaa'
});
});
This way it sets the background color taking into account only visible rows
fiddle here: http://jsfiddle.net/4Bjbc/3/

Related

How to change the background color of div onclick?

I want to create a multiple choice test in HTML and I am using "div"s as answer options. When one option (div) is clicked, its background color should be changed. Here is my code:
<div id="option" onclick="select()">Option 1</div>
<div id="option" onclick="select()">Option 2</div>
<div id="option" onclick="select()">Option 3</div>
</div>
<script>
var div = document.getElementById("option");
function select() {
div.setAttribute("id", "optionSelected");
}
</script>
CSS code:
#option {
background-color: #ffffff;
}
#optionSelected {
background-color: #008080;
}
When I click any of the divs only the first div's background changes, because they all have the same id.
Rather than trying to assign the class based on ID (which as pointed out is not correct to have duplicates), you could instead just use the event target:
function select(e) {
// Unset selected class from other options
const selected = document.querySelectorAll('.option-list .option-selected');
selected.forEach(function(el) {
el.classList.remove('option-selected');
});
e.target.classList.add('option-selected');
}
.option {
background-color: #FFFFFF;
padding: 5px;
}
.option-selected {
background-color: #008080;
color: #FFFFFF;
}
<div class="option-list">
<div class="option option-selected" onclick="select(event)">Option 1</div>
<div class="option" onclick="select(event)">Option 2</div>
<div class="option" onclick="select(event)">Option 3</div>
</div>
This is my time posting an answer so sorry if it's not the best.
This is the simpliest way to do it I could think of right now.
You would have to change this
<div id="option" onclick="select()">Option 1</div>
<div id="option" onclick="select()">Option 2</div>
<div id="option" onclick="select()">Option 3</div>
to this
<div id="option1" class="option" onclick="select('option1')">Option 1</div>
<div id="option2" class="option" onclick="select('option2')">Option 1</div>
<div id="option3" class="option" onclick="select('option3')">Option 1</div>
So you have a way of distinguishing between the different divs. Also each element would call the function specifying which element should be changed.
Then add an parameter to the function so you can specify which element you want to change.
The other line of code replaces the current class "option" with "optionSelected".
<script>
function select(id) {
var div = document.getElementById(id);
div.classList.replace("option", "optionSelected");
}
</script>
Finally just change the CSS rules to classes.
.option {
background-color: #ffffff;
}
.optionSelected {
background-color: #008080;
}
You can't assign the same ID to all the divs. ID's must be unique. Use a class instead.
1) You should never assign multiple elements the same ID, they should always be different ID's.
2) You could instead use a class, and then call that within the JavaScript function.
var div = document.getElementsByClassName("option");
function select() {
div.setAttribute("class", "optionSelected")
}
Hope this helps!
You can simplify what you're trying to do by adding this as an argument to your function (added color toggle on each click):
<div class="option" onclick="select(this)">Option 1</div>
<div class="option" onclick="select(this)">Option 2</div>
<div class="option" onclick="select(this)">Option 3</div>
<script>
function select(el) {
el.classList.toggle("optionSelected");
}
</script>
<style>
.option {
background-color: #ffffff;
}
.optionSelected {
background-color: #008080;
}
</style>
so, this is what you've asked for but don't you want to use a drop down box instead?
function select(opt) {
var div = document.getElementById(opt);
div.setAttribute("class", "optionSelected");
}
#option {
background-color: #ffffff;
}
.optionSelected {
background-color: #008080;
}
<div id="option1" onclick="select('option1')">Option 1</div>
<div id="option2" onclick="select('option2')">Option 2</div>
<div id="option3" onclick="select('option3')">Option 3</div>
You should set your project up using classes, if you want to use Id's here is a way to do that.
<div id="option" onclick="select(this)">Option 1</div>
<div id="option" onclick="select(this)">Option 2</div>
<div id="option" onclick="select(this)">Option 3</div>
</div>
<script>
var div = document.getElementById("option");
function select(opt) {
opt.setAttribute("id", "optionSelected");
}
</script>
You can also do it without javascript, using just css.
.option {
background-color: #ffffff;
cursor: pointer; /* add if you want */
}
/*
When the div with the unique id gets focus
due to a click the background color is applied
*/
#option1:focus, #option2:focus, #option3:focus {
background-color: #008080;
}
<!--
Add a class for the background color that applies to the
three divs, and add unique id's to each div
-->
<div>
<div class="option" id="option1" tabindex="1">Option 1</div>
<div class="option" id="option2" tabindex="2">Option 2</div>
<div class="option" id="option3" tabindex="3">Option 3</div>
</div>

Javascript - show a button inside of a DIV when clicked (and hide all others)

I have a list of DIVS that have buttons inside. By default, all buttons are hidden. When I click within a DIV area, the current button inside of this clicked DIV are should show (class='.db') AND all previously clicked/shown buttons should be hidden (class='.dn'). In other words, at any time there should be only one button (currently clicked) shown and all other should be hidden.
I want to use vanilla Javascript and tried this below, but it won't work. I feel there is some small error but don't know where.. Note - the DIVS and buttons don't have their own unique IDs (they only have the same CSS (.posted) classes.
PS - maybe it'd be better not to add this onClick="t();" to each DIV and use an 'addEventListener' function, but this is way too much for me ; )
CSS:
.dn {display:none}
.db {display:block}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
HTML:
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
JAVASCRIPT:
function t()
{
var x=document.getElementsByClassName("posted"),i,y=document.getElementsByTagName("button");
for(i=0;i<x.length;i++)
{
x[i].y[0].className="dn";
};
x.y[0].className='db';//make sure the currently clicked DIV shows this button (?)
}
You might want to read more about selector, how to select class, block level etc.
some link might be helpful:
CSS selector:
https://www.w3schools.com/cssref/css_selectors.asp
jQuery selector:
https://api.jquery.com/category/selectors/
Solution - Using jQuery:
$('.posted').on('click', function() {
//find all class called posted with child called dn, then hide them all
$('.posted .dn').hide();
//find this clicked div, find a child called dn and show it
$(this).find('.dn').show();
});
.dn {
display: none
}
.db {
display: block
}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="posted">
<button class="dn">Reply1</button>
</div>
<div class="posted">
<button class="dn">Reply2</button>
</div>
<div class="posted">
<button class="dn">Reply3</button>
</div>
Solution - Pure js version:
//get list of div block with class="posted"
var divlist = Array.prototype.slice.call(document.getElementsByClassName('posted'));
//for each div
divlist.forEach(function(item) {
//add click event for this div
item.addEventListener("click", function() {
//hide all button first
divlist.forEach(function(el) {
el.getElementsByTagName('button')[0].classList.add('dn');
});
//show button of the div clicked
this.getElementsByTagName('button')[0].classList.remove('dn');
}, false);
});
.dn {
display: none
}
.db {
display: block
}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="posted">
<button class="dn">Reply1</button>
</div>
<div class="posted">
<button class="dn">Reply2</button>
</div>
<div class="posted">
<button class="dn">Reply3</button>
</div>
You can do this with with plain JavaScript using Event Bubbling, querySelector and the element classList attribute like this.
Change your HTML to look like this:
<div class="posts">
<div class="posted">
<button class="dn">Reply</button>
</div>
<div class="posted" >
<button class="dn">Reply</button>
</div>
<div class="posted" >
<button class="dn">Reply</button>
</div>
</div>
Then use JavaScript like this:
var posts = document.querySelector('.posts');
var allPosted = document.querySelectorAll('.posted');
//clicks bubble up into the posts DIV
posts.addEventListener('click', function(evt){
var divClickedIn = evt.target;
//hide all the buttons
allPosted.forEach(function(posted){
var postedBtn = posted.querySelector('button');
postedBtn.classList.remove('db');
});
// show the button in the clicked DIV
divClickedIn.querySelector('button').classList.add('db')
});
You can find a working example here: http://output.jsbin.com/saroyit
Here is very simple example using jQuery .siblings method:
$(function () {
$('.posted').click(function () {
$('button', this).show();
$(this).siblings().find('button').hide();
});
});
https://jsfiddle.net/3tg6o1q7/

javascript doesn´t work in joomla 3.0

I have a javascript code that shows a div content depending on the select-box option value.
The code works fine in html, but in the Joomla 3.0 he doesn't.
inside the php of Joomla i have this script:
<?php
//jQuery Framework in noConflict mode
JHtml::_('jquery.framework', false);
$document = JFactory::getDocument();
$document->addScriptDeclaration('
jQuery(document).ready(function(){
jQuery("select").change(function(){
jQuery( "select option:selected").each(function(){
if($(this).attr("value")=="3"){
$(".box").hide();
$(".choose").show();
}
if($(this).attr("value")=="5"){
$(".box").hide();
$(".green").show();
}
if($(this).attr("value")=="6"){
$(".box").hide();
$(".blue").show();
}
if($(this).attr("value")=="7"){
$(".box").hide();
$(".red").show();
}
});
}).change();
});
');
// Disallow direct access to this file
defined ( '_JEXEC' ) or die ( 'Restricted access' );
?>
And this is the drop-down form:
<select id="profiletypes" name="profiletypes" class="select required pt-font-color">
<option value="3">option3</option>
<option value="5">option5</option>
<option value="6">option6</option>
<option value="7">option7</option>
</select>
<div class="choose box">You have to select <strong>any one option</strong> so i am here</div>
<div class="red box">You have selected <strong>red option</strong> so i am here</div>
<div class="green box">You have selected <strong>green option</strong> so i am here</div>
<div class="blue box">You have selected <strong>blue option</strong> so i am here</div>
Along with the CSS:
//select::-ms-expand { /* for IE 11 */
display: none; }
div.registerProfileType .pt-font-color{ background:
url(/images/sports-5.png) 96% / 15% no-repeat #6d9dc0;
color:#fff; }
.box{
padding: 20px;
display: none;
margin-top: 20px;
border: 1px solid #000;
}
.red{ background: #ff0000;
}
.green{ background: #00ff00;
}
.blue{ background: #0000ff;
}
.choose{background: #ffffff;
}
</style>
I know that in joomla 3.0 we need to use Jquery instead of $, if we call JQuery normally, i have tryed that, but it doesn´t work.
What am I can possibly doing wrong? I shall be grateful for any help.
You are still using $ within the .each loop which is causing the issue. Another issue is the loop causes multiple redirects. If you use the below block of code in your PHP script, it should work as intended (option 3 selected by default but picking another option changes the colour of the div etc).
// jQuery Framework in noConflict mode
JHtml::_('jquery.framework', false);
$document = JFactory::getDocument();
$js =<<<JS
jQuery(document).ready(function(){
jQuery("#profiletypes").change(function(){
if(jQuery(this).attr("value")=="3"){
jQuery(".box").hide();
jQuery(".choose").show();
}
if(jQuery(this).attr("value")=="5"){
jQuery(".box").hide();
jQuery(".green").show();
}
if(jQuery(this).attr("value")=="6"){
jQuery(".box").hide();
jQuery(".blue").show();
}
if(jQuery(this).attr("value")=="7"){
jQuery(".box").hide();
jQuery(".red").show();
}
}).change();
});
JS;
// The above 'JS' must be at the start of the line, not tabbed in
// Add the JS
$document->addScriptDeclaration($js);

Click and change THIS div

I have 3 divs with the same class (i can't use IDs on them). I find all of them by targeting their class and then - on click - i want to apply some stuff (e.g. change background-color). i only managed to change all of them, but not only the one i'm actually clicking. what am i missing?
var thisDiv = $('.thisDiv');
thisDiv.click(function() {
var i = thisDiv.index(this);
console.log(i);
console.log(thisDiv.css('background-color'));
// this changes all of the div, not only the clicked one
thisDiv.css('background-color', 'red');
// console msg for the code below: Uncaught TypeError: thisDiv[i].css is not a function
// thisDiv[i].css('background-color', 'red');
// i also tried these, which didn't work...
//console.log(thisDiv[i].css('background-color'));
//console.log(thisDiv.eq[i].css('background-color'));
});
.thisDiv{width:50px;height:50px;background-color:lightgrey;float:left;margin:15px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="thisDiv">div 0</div>
<div class="thisDiv">div 1</div>
<div class="thisDiv">div 2</div>
use $(this) will give you the div which you have clicked
$(this).css('background-color', 'red');
use .eq():
thisDiv.eq(i)
as thisDiv is a collection of objects, you can get the specific ones with $(this) or .eq(i).
var thisDiv = $('.thisDiv');
thisDiv.click(function() {
var i = thisDiv.index(this);
thisDiv.eq(i).css('background-color', 'red');
});
.thisDiv {
width: 50px;
height: 50px;
background-color: lightgrey;
float: left;
margin: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="thisDiv">div 0</div>
<div class="thisDiv">div 1</div>
<div class="thisDiv">div 2</div>

Changing multiple textareas css values with javascript and dropdown?

http://jsfiddle.net/g3u7hxr6/4/
I have this following code, currently it changes all textareas css values with the dropdown boxes.
I want it so that when 1 textarea is selected and glowing green, the dropdown boxes will only change the css for the selected textarea rather than all of them.
Basically I want to be able to change each text area font individually.
I considered using another dropdown box to select which textarea to change. but there must be a way for the javascript to detect the selected textarea and make changes to it only. I would need to add a unique id field to each textarea but i'm completely lost with the javascript. please help!!!
Answered thanks to Binvention:
http://jsfiddle.net/g3u7hxr6/19/
JS:
$(function () {
$("[id^=font]").on('change', function () {
$('.address').css(this.id, /\d/.test(this.value) ? this.value + "px" : this.value);
});
});
$('.address').focus(
function(){
$(this).parent('div').css('box-shadow','0px 0px 10px green');
}).blur(
function(){
$(this).parent('div').css('box-shadow','0px 0px 0px');
});
HTML:
<div class="options">
<div class="left">Font:
<br>Size:
<br>Weight:</div>
<div class="right">
<select name="fontFamily" id="fontFamily">
<option selected value="Verdana">Verdana</option>
<option value="Arial">Arial</option>
</select>
<br>
<select name="fontSize" id="fontSize">
<option value="8">8</option>
<option selected value="16">16</option>
<option value="24">24</option>
</select>
<br>
<select name="fontWeight" id="fontWeight">
<option selected value="Bold">Bold</option>
<option value="Normal">Normal</option>
</select>
<br /> <br />
</div>
<div class="page">
<div class="left border">
<textarea class="address" tabindex="1">text area 1</textarea>
</div>
<div class="right border">
<textarea class="address" tabindex="4">text area 4</textarea>
</div>
<div class="left border">
<textarea class="address" tabindex="2">text area 2</textarea>
</div>
<div class="right border">
<textarea class="address" tabindex="5">text area 5</textarea>
</div>
<div class="left border">
<textarea class="address" tabindex="3">text area 3</textarea>
</div>
<div class="right border">
<textarea class="address" tabindex="6">text area 6</textarea>
</div>
</div>
CSS:
.left {
float: left;
}
.right {
float: right;
}
.options {
width: 200px;
}
.page {
width: 440px;
}
.border {
border:1px solid #888;
border-radius: 5px;
padding: 5px;
margin: 0 0px 0px 0;
}
textarea {
resize:none;
height: 100px;
width: 200px;
overflow: auto;
font-family: Verdana;
font-size: 16px;
}
You need to create a unique class that marks one as selected like this
$('textarea').click(function(){
$(this).toggleClass('textselected');
});
That will allow you to dynamically pick which text boxes your editing just click to edit click to deselect from editing. You'll need some css to distinguish selected from not selected though.
Then when you edit the font and text properties you use that special class not the text areas to select the property like this
$("[id^=font]").on('change', function () {
$('.textselected').css(this.id, /\d/.test(this.value) ? this.value + "px" : this.value);
});
});
I have edited your fiddle with the necessary changes here
You need to add $(this).addClass('selected'); within your focus event and change the selector to $('.address.selected') within your change event.

Categories

Resources