Change Div Class On Each Click - javascript

I am building Bootstrap HTML and PHP website. Basically I need a solution so that when a div is clicked on it changes color and adds some text.
I can do this however I need a solution so that it can be done 3 times, bronze, silver and gold in this instance.
Below is my JSFiddle which shows it working, it changes to bronze and inserts the text as it should however the second click will not work and the third click won't work.
https://jsfiddle.net/vvecu9qa/1/
Hope that makes sense,
Thanks in advance guys!
HTML
<table class="table table-bordered">
<tbody>
<tr>
<td>Name</td>
<td>Spin on a variety of body parts</td>
<td>Spin with control and body tension</td>
<td>Spin in a variety of shapes</td>
<td>Identify appropriate places to perform a spin</td>
</tr>
<tr>
<td>Jon Smith</td>
<td class="progress1"> </td>
<td class="progress2"> </td>
<td class="progress3"> </td>
<td class="progress4"> </td>
</tr>
</tbody>
CSS
.emerging {
background-color: #cd7f32;
color: #fff;
text-align: center;
}
.expected {
background-color: #c0c0c0;
color: #fff;
text-align: center;
}
.exceeding {
background-color: #ffd700;
color: #fff;
text-align: center;
}
JavaScript
$('.progress1').click(function(){
$(".progress1").removeClass("progress1");
$(this).addClass('emerging');
$(this).text('Emerging');
});
$('.emerging').click(function(){
$(".emerging").removeClass("emerging");
$(this).addClass('expected');
$(this).text('Expected');
});
$('.expected').click(function(){
$(".expected").removeClass("expected");
$(this).addClass('exceeding');
$(this).text('Exceeding');
});

change your script like this, it will work
$(document).on("click",'.progress1',function(){
$(".progress1").removeClass("progress1");
$(this).addClass('emerging');
$(this).text('Emerging');
});
$(document).on("click",'.emerging',function(){
$(".emerging").removeClass("emerging");
$(this).addClass('expected');
$(this).text('Expected');
});
$(document).on("click",'.expected',function(){
$(".expected").removeClass("expected");
$(this).addClass('exceeding');
$(this).text('Exceeding');
});
here is the updated fiddle link

Since you only have 3 scenarios, your approach is fine. However, a more intuitive approach would be to create an array and an index, then cycle through them. This way you would only need one click event instead of 1 per step.
Updated Fiddle Here
var classes = ['emerging', 'expected', 'exceeding'];
var index = 0;
$('.progress1').click(function(){
$(this).removeClass(); //Removes all classes
$(this).addClass(classes[index]);
$(this).text(classes[index]);
if(index == (classes.length - 1)) {
index = 0; //Reset index at end of array
} else {
index++; //Increment index if not at the end of array
}
});

Try this approach. I have used the data attribute to make it a bit cleaner.
https://jsfiddle.net/mvinayakam/m4q3rgrq/
<td class="progress" data-progress="base" ><span> <span></td>
The Javascript part
$('.progress').click(function(){
progressAttr=this.getAttribute('data-progress');
switch (progressAttr)
{
case "base":
this.setAttribute('data-progress',"emerging");
break;
case "emerging":
this.setAttribute('data-progress',"exceeding");
break;
}
});
The CSS
[data-progress="emerging"] {
/* Styles */
background-color: #cd7f32;
color: #fff;
text-align: center;
}
[data-progress="emerging"]:after {
content:"Emerging";
}

Related

How to send the element object as parameter to javascript function without ID

In function ClickedRow, i want to use the "a" which is being clicked. So i want to receive it as a parameter.
<td ...... >
<span class="......>
<span onmousedown="event.cancelBubble = true">
<a class="GridLinkRenderer" href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" urlText="XXXX">
<td ......
<span class="......>
<span onmousedown="event.cancelBubble = true">
<a class="GridLinkRenderer" href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" urlText="XXXXX">
Based on clicked <a ....> I would like to hide/show it (or to show/hide next <a class= "GridLinkRenderer" in other <td ...>) by function ClickedRow(this).
How can I do it ?
I've tried to send the clicked $(row).next().eq(0).tagName and row.style.display = 'none' , it says that it is "undefined".
function ClickedRow(row){
$(row).next().eq(0).hide();
$(row).hide();
}
Instead of this, remove href and use
$('#TheidOfTheA').on('click'function(){
let myAElement = $(this);
}
have you looked at closest(),find() and next() ?
https://api.jquery.com/closest/
https://api.jquery.com/next/
https://api.jquery.com/find/
$(row).closest('td').next('td').find('.GridLinkRenderer')
haven't tested this.. but if I'm thinking right this should be at least the point to right direction.
I can't tell by OP if the td are being used in a tr and the tr in a table as it should so I'll just mention real quick that it's invalid HTML should there be any td without a tr as a parent and it's invalid HTML having a tr without a table as its ancestor.
If starting at a tag nested within a td you'll need to climb out:
$(this).closest('td')...
Once at the cell level look around for the cells to the left: ....prev('td'), or to the right: ....next('td') or both: ....siblings('td'). Then go down each td and find the link nested within and turn it off/on: ....find('.gLR').fadeToggle();
$(this).closest('td').siblings('td').find('.gLR').fadeToggle();
$('.gLR').not('.g5').hide();
$('.gLR').on('click', function(e) {
if ($(this).hasClass('g5')) {
$('.gDir').fadeToggle();
} else if ($(this).hasClass('g1') || $(this).hasClass('g9')) {
const cell = $(this).closest('td');
cell.siblings('td').find('.gLR').fadeToggle();
} else if ($(this).hasClass('g4')) {
$(this).closest('td').prev('td').find('.gLR').fadeToggle();
} else if ($(this).hasClass('g6')) {
$(this).closest('td').next('td').find('.gLR').fadeToggle();
} else {
return false;
}
});
:root {
font: 700 5vw/1.5 Consolas
}
table {
table-layout: fixed;
border-collapse: collapse;
}
td {
width: 20%;
text-align: center
}
a {
display: block;
height: 10vh;
text-decoration: none;
color: cyan;
}
a:hover {
color: tomato;
}
a.g5:hover {
font-size: 0;
}
a.g5:hover::after {
content: '\1f536';
font-size: 5vw;
}
td b {
display: block;
height: 10vh;
}
<table>
<tr class='gRA'>
<td colspan='2'>
<b>🌈</b>
</td>
<td><b>⮝</b></td>
<td colspan='2'>
<b>🦄</b>
</td>
</tr>
<tr class='gRB'>
<td><b>🏰</b></td>
<td><b>⮜</b></td>
<td><b>🔷</b></td>
<td><b>⮞</b></td>
<td><b>🏯</b></td>
</tr>
<tr class='gRC'>
<td colspan='2'>
<b>🔥</b>
</td>
<td><b>⮟</b></td>
<td colspan='2'>
<b>💀</b>
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I tried both recommendations(thx for it) - no success.
It looks that the "this" argument is not passed like clicked element(object) reference.
The parameter "row" seems to be like parent of all object, so like new Object and not the clicked object.
I am not sure if href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" is correct syntax though.
so copied Your sample and came up with this. ;) try this out.. and
make sure You understand what's happening here.
$(() => {
$("body").on("click",".GridLinkRenderer", (e) => {
e.preventDefault();
//works on the first link.. stil misses a few check..
//for example do we have the next td.. at all..
console.log($(e.currentTarget).closest('td').next('td').find('.GridLinkRenderer'));
})
});

Jquery Next() not highlighting next element correctly when using a table

I have a table with each row representing a song.
When a song is clicked, the parent td should be highlighted a light blue color with the .active class and if any song was highlighted previously the parent td's .active class should be removed.
This part works fine and is represented with this jquery:
$(".songs").click(function(){
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
I also want to have a next button and a previous button. This where I am having issues. When the next button is clicked, the next song on the list should be highlighted and the previously highlighted song should be unhighlighted (I am using the class .active to do the highlighting and unhighlighting). This part is not working:
$('#next_button').click(function(){
var current = $('td.active');
$('.songs').parents('td').removeClass('active');
current.nextAll('td:first').addClass('active');
});
Here is the jsfiddle link:
jsfiddle Link
Here is my html code:
<table id="song_table">
<thead id="song_thead">
<tr>
<th id="table_head">Songs</th>
</tr>
</thead>
<tbody id="song_tbody">
<tr>
<td class="td_songs">
<a class="songs">
1
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
2
</a>
</td>
</tr>
</tbody>
</table>
<div id="next_button">
<p id="next_text">Next Button</p>
</div>
Here is my css:
.active{
background-color: #D9FAFA;
}
table{
text-align: center;
height: 100px;
width: 200px;
}
#table_head{
text-align: center;
}
#next_button{
height: 100px;
width: 200px;
background-color: lightgreen;
}
Here is my jquery
$(document).ready(function() {
$(".songs").click(function(){
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
$('#next_button').click(function(){
var current = $('td.active');
$('.songs').parents('td').removeClass('active');
current.nextAll('td:first').addClass('active');
});
});
If you could help me solve this issue, I would greatly appreciate it. I feel like this should be so easy but I just can't seem to make it work.
Thanks!
The trick is to get the row index of the current song, add 1, and then do a modulo with number of rows that way if the current row+1 overflows the number of rows, it will start from the beginning:
$().ready(function() {
$(".songs").click(function(){
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
$('#next_button').click(function(){
//here .parent() will get the current <tr>
//.parent().index() will get the index of the current <tr>
var currentID = $('td.active').parent().index();
//here .parent() will get the <tr>
//.parent().parent() will get the <tbody>
//.parent().parent().children() will get all the rows
//.parent().parent().children().length will get the row count
var nextID=(currentID+1)%($('td.active').parent().parent().children().length)
$('.songs').parents('td').removeClass('active');
$('td').eq(nextID).addClass('active');
});
});
.active{
background-color: #D9FAFA;
}
table{
text-align: center;
height: 100px;
width: 200px;
}
#table_head{
text-align: center;
}
#next_button{
height: 100px;
width: 2d00px;
background-color: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="song_table">
<thead id="song_thead">
<tr>
<th id="table_head">Songs</th>
</tr>
</thead>
<tbody id="song_tbody">
<tr>
<td class="td_songs">
<a class="songs">
1
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
2
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
3
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
4
</a>
</td>
</tr>
</tbody>
</table>
<div id="next_button">
<p id="next_text">Next Button</p>
</div>
Something like this? http://jsfiddle.net/y5ntap04/3/
You needed to go up the DOM and then where all the siblings are, you can go to the next() one.
Plus added a previous button for you.
$().ready(function () {
$(".songs").click(function () {
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
$('#next_button').click(function () {
$('.songs').parents('td.active').removeClass('active').closest('tr').next().find('td').addClass('active');
});
$('#previous_button').click(function () {
$('.songs').parents('td.active').removeClass('active').closest('tr').prev().find('td').addClass('active');
});
});
in your code you have each td in its own tr meaning there is no next td to go to.
you should adjust your jquery to focus on the rows, as in this fiddle (shown below)
$().ready(function() {
$(".songs").click(function(){
$('.songs').parents('tr').removeClass('active');
$(this).parents('tr').addClass('active');
});
$('#next_button').click(function(){
var current = $('tr.active');
$('.songs').parents('tr').removeClass('active');
current.next('tr').addClass('active');
});
});
You'll also notice I'm using .next() which will just grab the next element or the next element which matches the argument (in this case tr) - no need to get all then restrict to just the first.
All this will make your fiddle behave as expected, however, if you want to target the td's within each of the tr's you'll have to add .find('td') to get the td out of the retrieved tr, like this. Here the only line that is changed is the one that adds the class on click of next, which is now: current.parent().next('tr').find('td').addClass('active');
Refactoring out $('.songs').parents('tr').removeClass('active'); into it's own function would also clear your code a bit and make it easier to follow, a good habit! (also +1 for using a variable to store a returned JQuery DOM object - var current = $('tr.active'); - another good habit for code clarity and efficiency, especially when you are deraling with more complicated DOM structures and functions)

Replace HTML content and revert on hover

I have a HTML table filled with short sentences in two colors.
I want to cover the text with bars of corresponding colors and, when each block is hovered, the content has to revert to its original HTML state.
I would like to do the following either with JS or CSS:
leave the default HTML table as-is
switch the original content via javascript to a sequence of ASCII 219 / &block / █
make it switch to "original" content when each block (e.g. "last week tonight with J.Oliver) is hovered.
Any help with this method, or a more efficient method, is appreciated. Thanks!
EDIT / a similar code might do it for me, the only thing i miss is the "original content" word:
div:hover span {display:**ORIGINAL CONTENT**}
div:hover:before {content:"&block;&block;&block;&block;&block;"}
You can get a similar effect with just CSS - set the same color and background on the cells, then switch to something readable on hover:
.red {
color: red;
background-color: red;
}
.blue {
color: blue;
background-color: blue;
}
.revealer:hover td {
color: black;
background-color: white;
}
<div class="revealer">
<table>
<tr>
<td class="red">One</td>
<td class="blue">Two</td>
</tr>
<tr>
<td class="red">Three</td>
<td class="blue">Four</td>
</tr>
</table>
</div>
If you include jQuery, this will do what you originally requested:
$(function(){
$('td').each(function(idx){
$(this).data().originaltext = $(this).text();
$(this).html(fill_with_blocks($(this).data().originaltext));
})
$('td').hover(function(){
$(this).html($(this).data().originaltext);
},
function(){
$(this).html(fill_with_blocks($(this).data().originaltext));
});
});
function fill_with_blocks(str) {
var blocks = '';
for(var i = 0;i<str.length;i++){
blocks += '█';
}
return blocks;
}

Making a table dynamic

Made a table for a product listings page that has a row of 3 images, then a row of text below each image, then repeat. Rather than have the page scroll down indefinitely, I figure it would be better to use some JS/jQuery to change the values in each < td > (img & matching text) than to create a new page for every 6 products. However, my kindergarten-level JS is failing me miserably.
While I think the question I'm asking above is pretty obvious, I'm also wondering if this never should have been set up as a table in the first place. It seemed like the easiest way to keep it organized, but the few examples I've seen seem to do this with < div >'s rather than tables.
Here's a JSFiddle I was messing around with: http://jsfiddle.net/jshweky/FgVY2/
HTML:
<table id="saladGrid">
<tr class="saladPics">
<td class="s1"></td>
<td class="s2"></td>
<td class="s3"></td>
</tr>
<tr class="saladTxt">
<td class="txt">
<p>acorn squash, golden beets, pistachios</p>
</td>
<td class="txt">
<p>roasted eggplant, herbed ricotta, sumac</p>
</td>
<td class="txt">
<p>arugula, fennel, blackberries, quinoa, pickled shallots</p>
</td>
</tr>
<tr class="saladPics">
<td class="s4"></td>
<td class="s5"></td>
<td class="s6"></td>
</tr>
<tr class="saladText">
<td class="text">
<p>arugula, orange, golden beets, golden tomatoes, pistachios</p>
</td>
<td class="text">
<p>caesar</p>
</td>
<td class="text">
<p>butternut squash, lime, feta, chili</p>
</td>
</tr>
</table>
<button id="prev">Prev</button>
<button id="next">Next</button>
CSS (paraphrased):
table {
width: 100%;
height: 100%;
margin-top: 0;
padding: 0;
border: 0;
border-spacing: 0;
}
td {
margin: 0;
padding: 0;
border: 0;
text-align: center;
vertical-align: middle;
}
#saladGrid table {
margin: 0 auto;
border-spacing: 30px;
}
.saladPics td {
height: 350px;
width: 350px;
background-position: center;
background-size: 415px 400px;
background-repeat: no-repeat;
border-radius: 250px;
border: 1px black solid;
}
.saladText {
position: relative;
margin-bottom: -20px;
}
.saladPics td.s1 {
background-image: url("http://i1281.photobucket.com/albums/a514/jshweky/Gourmade%20to%20Order/IMG_1989_zps38d802a7.jpg");
}
I figure it's a matter of creating new var's and writing a function to add 6 to the existing img class (e.g. s1 becomes s7, etc.) but that's just a guess and as I said, even if that's right I'm still in the embryonic stages of JS coding.
Your JavaScript to Swap the image works fine, the issue is the first part of your script. I commented it out in the fiddle and it worked fine. There are definitely better ways to do this (sliding DIVs inside a container, build elements in javascript and append them to the frames on the page - this would give you almost a pinterest style effect of loading new elements at the bottom) - it all depends on how you want to handle it but my suggestion would be to look into using jQuery to add or remove elements to the DOM.
//var s7= new image();
//img.src=url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRHC9Vk1U5yC5RWMhUK9Ai2RGIDCSh-wxPt-aleQm9onxi9xbN9dA');
$(document).ready(function () {
$('#prev').click(function () {
$('.s1').css('background-image', 'url("http://i1281.photobucket.com/albums/a514/jshweky/Gourmade%20to%20Order/IMG_1483_zpsc4ca87cf.jpg")');
});
});
Also, here is an alternate syntax for the .css() that will let you change more than one property of an elements at a time (you will need to use the .html() function to change the text in the following element too):
$('.s1').css({backgroundImage : 'url("http://i1281.photobucket.com/albums/a514/jshweky/Gourmade%20to%20Order/IMG_1483_zpsc4ca87cf.jpg")', backgroundSize : "cover"}); });

Disabled inputs in bootstrap. How to apply it to a different TAG?

By using disabled attribute on an input is possible to prevent user input and trigger a slightly different look.
Here is the demo http://jsfiddle.net/D2RLR/3023/
Let's suppose I want to apply the same style to a different TAG like a table.
In fact, I am using handsontable to generate an Excel-like data grid editor.
How can I apply disabled attribute in the following context (TAG like a table)?
Here is the demo using handsontable and bootstrap http://jsfiddle.net/D2RLR/3025/
You can't apply Bootstrap's existing input[disabled] styling, but you can add new CSS that mimics the styles exactly.
For example:
#exampleGrid td {
cursor: not-allowed;
background-color: #EEE;
color: #9E9999;
}
Obviously this doesn't include your readonly logic, and looks a little weird with your fiddle (because the column and row headers are the same color), but that's the gist of it.
Check here:
http://handsontable.com/demo/conditional.html
There is .readOnly cell property - use it!
HTML inputs also have readonly property, not only disabled property, an there are some considerable differences between their behaviour.
Boostrap is only styling the inputs based on their disabled attribute like:
input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] {
background-color: #EEEEEE;
cursor: not-allowed;
}
So you won't be able to use bootstrap to do that, because tables don't have such attribute.
You should use a plugin of sorts or roll your own.
Maybe this can help... changes the look of the cell and you can edit on it.
HTML
<table class="editableTable">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>E-mail</th>
<th>Telephone</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>João Carlos</td>
<td>joca#email.com</td>
<td>(21) 9999-8888</td>
</tr>
<tr>
<td>002</td>
<td>Maria Silva</td>
<td>mariasilva#mail.com</td>
<td>(81) 8787-8686</td>
</tr>
<tr>
<td>003</td>
<td>José Pedro</td>
<td>zepedro#meuemail.com</td>
<td>(84) 3232-3232</td>
</tr>
</tbody>
</table>
CSS
* {
font-family: Consolas;
}
.editableTable {
border: solid 1px;
width: 100%
}
.editableTable td {
border: solid 1px;
}
.editableTable .editingCell {
padding: 0;
}
.editableTable .editingCell input[type=text] {
width: 100%;
border: 0;
background-color: rgb(255,253,210);
}
JS
$(function () {
$("td").dblclick(function () {
var originalContent = $(this).text();
$(this).addClass("editingCell");
$(this).html("<input type='text' value='" + originalContent + "' />");
$(this).children().first().focus();
$(this).children().first().keypress(function (e) {
if (e.which == 13) {
var newContent = $(this).val();
$(this).parent().text(newContent);
$(this).parent().removeClass("editingCell");
}
});
$(this).children().first().blur(function(){
$(this).parent().text(originalContent);
$(this).parent().removeClass("editingCell");
});
});
});

Categories