jQuery remove class item keeps coming back - javascript

Here is the situation.
I'm trying to remove an div class item based when the user clicks on a rating.
The problem I have is that every time I click on the item it goes away, however when I move the mouse the item that I removed comes back.
Here is my current code:
<div class="star_'.($iPos+1).' ratings_stars ratings_vote" onmouseover="overRating(this);" onmouseout="outRating(this);" onClick="selectEmailRating(this);" ></div>
The above item is the div that is calling the JavaScript. When I click on the rating I run the code that is in the following function below:
function selectEmailRating(elem) {
var star = elem;
var rating = widget.data('fsr').rating;
if($(star).attr('class') === 'star_'+ rating + ' ratings_stars ratings_over ratings_vote'){
$(elem).andSelf().removeClass();
$(star).attr('class', 'star_'+ rating + ' ratings_stars');
$(star).attr('class').unbind('onmouseover').unbind('onmouseout');
}
function outRating(elem) {
$(elem).prevAll().andSelf().removeClass('ratings_over');
setRating($(elem).parent());
}
function overRating(elem) {
$(elem).prevAll().andSelf().addClass('ratings_over');
$(elem).nextAll().removeClass('ratings_vote');
}
function setRating(widget) {
var votes = $(widget).data('fsr').rating;
$(widget).find('.star_' + votes).prevAll().andSelf().addClass('ratings_vote');
$(widget).find('.star_' + votes).nextAll().removeClass('ratings_vote');
}
As you see in the code, it is removing the item, however, it is coming back when I move the mouse. Is there a way to make sure when I click on the item to remove it stays removed?

I may be wrong here, but you didn't "bind" the onmouse* events to the element, you added attributes.
You may overwrite the onmouse* attributes with $(elemment).attr('onmouseout', '') or something alike.
and you might want to have a look at https://api.jquery.com/hasclass/

Well I found a solution..
After trying to figure out why the rating keeps coming back, it was the due to the fact that the outRating function was causing the problem. Here is what I did...
The old outRating function:
function outRating(elem) {
$(elem).prevAll().andSelf().removeClass('ratings_over');
setRating($(elem).parent());
}
The new outRating function:
function outRating(elem) {
var star = elem;
var widget = $(elem).parent();
var rating = widget.data('fsr').rating;
$(elem).prevAll().andSelf().removeClass('ratings_over');
if($(star).attr('class') !== 'star_'+ rating + ' ratings_stars') {
setRating($(elem).parent());
}
}

Related

How to reveal dynamic data on click with jquery

EDIT: This is a more sound approach, since provided answer may have bugs when implementing a tags, or img tags.
================================================================
I am calling blog data from an API. (I've reformatted the data into an array by month).
So far, the blog titles print to the web page. I'd like a user to be able to click a title and have its description revealed.
Here is some of my code so far:
var blogPosts = $('#blog-posts');
$.each(byMonth, function(key, value) {
var outer = byMonth[key]
$.each(outer, function(k, v) {
var inner = outer[k]
var monthBlogPosts = $('<div class = "month"> </div>').appendTo(blogPosts);
$.each(inner, function(i, obj) {
title = inner[i].Title
description = inner[i].Description
date = inner[i].DatePublished
$('<div class = "title-list"><h3 class = "unique-title">' + title + '</h3></div>').appendTo(monthBlogPosts)
// if a title is clicked, show its Description
showDescription(description);
})
})
});
function showDescription(d){
$('.unique-title').on('click', function(){
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
}
When I click a title, all descriptions print instead of the matching description. I understand this is because I called the function in a nested loop, but I've also had trouble calling the description variable outside of it.
I have also tried
showDescription(title, description)
//...
function showDescription(t, d){
$(title).on('click', function(){
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
}
but then nothing is printed to the html page.
Essentially, I'd like to grab the title index, and print it's respective description when its clicked.
you should use event delegation to attach a click event to the document that will bubble up and trigger when .title-list is the event target.
$(document).on('click', '.title-list', function(event) {
showDescription(event.currentTarget) // pass the element being clicked (we will need it later)
})
you would also need to modify the way you get the description.
you could store you description in a data attribute of .title-list like so:
$('<div class = "title-list" data-description="'+ description +'"><h3 class = "unique-title">' + title + '</h3></div>').appendTo(monthBlogPosts)
so you can now modify showDescription() so it would get the data from the element we pass to the function
function showDescription(element){
var d = $(element).data('description')
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
So ok. From whatever I could understand (by looking at your code). You cannot register an event with simple on for dynamically added element. You have to use on delegate.
Try this
1) remove the function call (inside a loop)
2) delete the entire function showDescription and add event as below:
$('#blog-posts').on('click', '.unique-title',function(){
alert('title clicked').
});
3) As to display the description I think the best way will be to add the description in a div and hide it. Display it later once the title is clicked.
(inside the loop)
$('<div class = "desc" style="display:none">' + description + '</div>').appendTo(monthBlogPosts);
then on #2 above. Replace with this.
$('#blog-posts').on('click', '.unique-title',function(){
$(this).next('.desc').show(); //I am assuming desc will be next to the clicked title here. You can modify it as needed.
});
Finally, this is just an overview of a code so might not work as expected but I am pretty sure this should give you an idea and get you started

Adding and removing a class at the same time as updating a div

I am very new to JavaScript. I am trying to update a div, which works fine before the add and remove class pieces are added. The problem is when I add the class I can't seem to get it to be removed when the when the next image is clicked. I have used a remove class option, but it doesn't seem to want to work.
Any help is appreciated. Here is the code:
$('[class^="question"]').on('click', function(e) {
e.preventDefault();
var numb = this.className.replace('question', '');
$('[id^="answer"]').hide();
$('.question*').removeClass('question*selected');
$('#answer' + numb).show();
$('.question' + numb).addClass('question' + numb + 'selected');
});
Here is a link to the Fiddle I am Playing with.
Thanks.
You can keep track of your added class by defining a global variable. I created a working example in CODEPEN.
$(document).ready(function() {
var appliedClass = "container1";
var classNo = 1;
$(".buttonCon").click(function() {
if ($(".container").hasClass(appliedClass)) {
$(".container").removeClass(appliedClass);
classNo++;
if (classNo > 4) {classNo = 1;}
appliedClass = "container" + classNo;
$(".container").addClass(appliedClass);
}
});
});
I have appliedClass variable which keeps tracking of the latest added class. Every time you click on the button with .buttonCon class, this variable will be updated to the new added class. Next time, first we remove the former class. Then we added the new one. The second if statement might not be needed in your case, but in my example, I needed it to keep looping through container1 to container4 classes.
You've set yourself up with a really difficult-to-work-with class structure -- this can be a lot easier than you're making it. Give each of your "question" links the class 'question' and the unique id "question1", "question2", etc. Same for the answer nodes: class "answer" and id "answer1", "answer2" etc.
Now you can easily access all question links with $('.question') or all answers with $('.answer'), and can use the IDs to identify individual nodes as needed:
$('.question').on('click', function(e) {
e.preventDefault();
var numb = this.id.replace('question', '');
var answerNode = $('#answer'+numb);
if (answerNode.hasClass('hide')) {
// the Q they clicked on is not yet visible
$('.answer').addClass('hide'); // hide all answers
answerNode.removeClass('hide'); // show the desired one
} else {
// the Q they clicked on is already visible, so toggle it back off
answerNode.addClass('hide');
}
});
http://jsfiddle.net/647dadtj/

How do you create variables to open up the same type of div?

I am making a website that displays profiles of people. Each person is designated a svg button and when that button is clicked, a pop up displays that persons information.
I have this jquery function:
$('.button1').click(function() {
$('.person1-profile').fadeIn();
});
$('.button1-exit').click(function() {
$('.person1-profile').fadeOut();
});
$('.button2').click(function() {
$('.person2-profile').fadeIn();
});
$('.button2-exit').click(function() {
$('.person2-profile').fadeOut();
});
$('.button3').click(function() {
$('.person3-profile').fadeIn();
});
$('.button3-exit').click(function() {
$('.person3-profile').fadeOut();
});
I'm wondering if it is possible to do this with Javascript so that it significantly shortens the coding, and rather than copy & pasting that code every time for each person, if variables can be made for people/profile and so it would be something like:
$('var person + button').click(function() {
$('var person + profile').fadeIn();
});
$('var button + exit').click(function() {
$('var person + profile').fadeOut();
});
Thank you I really appreciate it! Sorry if it is unclear.
You could use data-attributes for this one:
Define your buttons like that:
<button class="openButton" data-person="3">Open</button>
<button class="closeButton" data-person="3">Close</button>
And your open/close-code like that:
$('.openButton').click(function() {
var personNumber = $(this).attr("data-person");
$('.person'+personNumber+"-profile").fadeIn();
});
$('.closeButton').click(function() {
var personNumber = $(this).attr("data-person");
$('.person'+personNumber+"-profile").fadeOut();
});
In action: http://jsfiddle.net/ndx4fn9n/
I can think of few ways of doing it.
You could read only 7th character of the class name. This limits you to having only 10 fields. Or you could put id on very end like this person-profile1 and read 16th and up character.
You could also set up additional tag to your container. But this will cause your web page to not HTML validate.
<div class="person" personid="1">// content</div>
You can do this in your selector:
var buttons = document.getElementsByTagName(svgButtonSelector);
for (i = 0; i > buttons.length; i++) {
$(".button" + index).click(function() {
$(".person" + index + "-profile").fadeIn();
});
}
This will attach the event to every svg button you've got on your page. You just gotta make sure the scope of selection for the buttons is declared right (I'm using document as an example).

Expand only one row in javascript code

hey guys having trouble figuring out how to make it so that i can make it only open one table at once, once you open another the other should close any help here?
function showRow(cctab){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = '';
}
}
function hideRow(row1){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = 'none';
}
}
function toggleRow(cctab){
if (document.getElementById(cctab)) {
if (document.getElementById(cctab).style.display == 'none') {
showRow(cctab)
} else {
hideRow(cctab)
}
}
}
Now I want to make it so that only one table "cctab" opens after I suggest the onClick="javascript:toggleRow(cctab);" anyhelp?
Well you could save a reference to the previously shown item and hide it when another is shown:
var currentTab;
function showRow(cctab){
if (document.getElementById(cctab))
document.getElementById(cctab).style.display = '';
if (currentTab && currentTab != cctab)
hideRow(currentTab);
currentTab = cctab;
}
Note that doing inline event handler attributes is so 1999, but assuming you're sticking with it for whatever reason you don't need the javascript: in onClick="javascript:toggleRow(cctab);". (Just say onClick="toggleRow(cctab);")
First you need to store the old row somewhere.
What you've got is a system where you're using <element onclick="..."> to pass the id of the current element into the controller that shows or hides the row.
But if you look at that, what you're missing is a way of telling what the last open row was.
So what your code will need is a central object, or variables which store the old element and the new element.
How you do this is up to you, but if you did something like this:
var table_rows = { current : null /* or set a default */, previous : null };
function rowController (cctab) {
var newRow = document.getElementById(cctab);
if (newRow === table_rows.current) { toggleRow(newRow); }
else {
table_rows.previous = table_rows.current;
table_rows.current = newRow;
showRow(table_rows.current);
hideRow(table_rows.previous);
}
}
Note:
This deals with elements directly, so you don't have to do getById in your functions;
that's handled one time, and then that element is passed around and saved and checked against.
It assumes that the click is happening on the row itself, and not on anything inside of the row;
that's a separate issue that your code has.
Unless it's obvious and easy to click on the row, and not the cells inside of the row, it's difficult to tell how you want users to be able to open and close rows.
What I mean is if only the table-row has an onclick, and somebody clicks on a table-column, then then onclick isn't going to fire.

Dynamically added input box problem?

I have dynamically added div.In which i have text box.While adding dynamic div i can put a value to the current div but not the previously open divs. I want to ask how to add Value to the previously open text boxes of Div.
Thank You
here is a solution that refresh ALL. (I don't understand the "previously open text box" part of your question. Well I understand it, but it doesn't show in your code. I assume the "rhythm" column of your table is an input/textarea html element (since you use it's value).
Please note I'm not sure what the vitalset function is supposed to accomplish, or what "vitals_form_readings_1_rhythm" is.
function queryDb(statement)
{
dbQuery = new air.SQLStatement();
dbQuery.sqlConnection = db;
dbQuery.text = statement //"SELECT * FROM rhythm";
//alert(dbQuery.text);
try {
dbQuery.execute();
} catch (error) {
air.trace("Error retrieving notes from DB:", error);
air.trace(error.message);
return;
}
return (dbQuery.getResult());
}
function crhythm()
{
var statement = "SELECT * FROM rhythm";
return queryDb(statement)
}
function reading_speedcode()
{
if (!cvitals) {
var crhythms = crhythm();
var i=0;
$(crhythms).each( function () {
crhythm = this.crhythm;
var pr = 'card_' + i;
$('#rhythm1').append('<br/><td class="content_big" id="'+pr+'" name="'+pr+'">' + crhythm + ' </td>');
i++
});
}
});
$(document).ready( function () {
reading_speedcode();
$('#rhythm1 .content_big').live('click', function(event) {
$('#rhythm1').empty()
reading_speedcode();
});
});
now, there are several things about your code.
variable naming. (for god sake use meaningful names!)
reading full table when you need one row
where is cvitals declared or assigned?
string parsing. Jquery is good at working with set of elements, there should be no need to parse "pr" to recover the row number.
if a value is inserted in rhythm table (or deleted) before your click, the vitalset logic fails. you might want to use the table id instead.
make sure "#vitals_form_readings_1_rhythm" is unique, not retrieved from the table.
if you can answer my question from the top of this post(vitalset function, vitals_form_readings_1_rhythm, cvitals) I will try improve the code.

Categories