A function with changing variable, dependent on a class - javascript

So, first some background.
I have 9 types of rooms that are displayed as thumbnails with the name. What I want to do is that on click "Additional Information" - the rooms with disappear and the expanded version of a chosen room type will appear with the description and bigger picture. Also, there is an ability to go next and previous in the expanded view. I do not have a problem with this expansion and previous/next. BUT!
Here is what I am trying to achieve: if the code looks approximately like
<ul id="room_holder">
<li><div class="room 1">Additional Info</div></li>
<li><div class="room 2">Additional Info</div></li>
and so on...
And the expandable area will look something like:
<div id="expandable">
<div id="picture">Blah-blah-blah, some description, etc</div>
</div>
So, basically, what I can't figure out is how to get the needed slide to show when the correspondint thumbnail is pressed. I know I can do the .addClass method, and copy the code 9 times, for each of the numbers (1-9). But I believe it is 9 times more compact if I have some sort of function, that gets the second class name (the number) by using .split(' ')[1] and then using it as part of the variable in the part which opens the corresponding expandable view. So, my question is: how do I do this? I am a newbie with javascript, but try to learn on the go!
Oh, and the codepen that I've been trying to deal with is:
http://codepen.io/godban/pen/QbZmxz

Firstly, you should use data-* attribute instead of classes (new in HTML5) data attributes, w3school :
<ul id="room_holder">
<li><div class="room" data-room="1">Additional Info</div></li>
<li><div class="room" data-room="2">Additional Info</div></li>
Then, use the click function from jQuery .click( handler ), use it this way to know which one has been clicked :
$(".room").click(function(event){
var target = event.currentTarget;
var room = $(target).data("room");
alert(room);
});

Related

How to include a series of details in a div using jQuery only without using data-attributes?

Please bear with me because I don't know how to explain this in a shorter way. All the info I'm posting here is just an example, which is why they sound weird.
So, I wanted to have sort of a character select page and I wanted to display attributes of each character in a separate div when you click on the character's portrait. Certain data will be displayed on the character card div.
I basically have a list of character portraits, like this [html]:
<ul id="char-list">
<li id="greengirl">Green Girl</li>
<li id="maroonman">Maroon Man</li>
<li id="whitwoman">White Woman</li>
<li id="blackboy">Black Boy</li>
</ul>
<div id="char-card">
<div id="char-name"></div>
<div id="char-hair-color"></div>
<div id="char-eye-color"></div>
<div id="char-mag-power"></div>
</div>
All characters have for example, three attributes: hair-color, eye-color, and magical-power.
I want to display this within the #character-card div when the user clicks on each character.
Now, I know I can set a data-attribute to each character stat like this:
...
<li id="greengirl" data-eye-color="Green" data-hair-color="Green" data-mag-power="322">Green Girl</li>
...
And write my jQuery like this:
$('#char-list li').on('mouseup', function() {
var eyeColor = $(this).data('eye-color'),
hairColor = $(this).data('hair-color'),
magPower = $(this).data('mag-power'),
charName = $(this).text(),
nameDiv = $('#char-name'),
hairDiv = $('#char-hair-color'),
eyeDiv = $('#char-eye-color'),
magDiv = $('#char-mag-power');
nameDiv.text(charName);
hairDiv.text(hairColor);
eyeDiv.text(eyeColor);
magDiv.text(magPower);
});
This works with no issues, but I'm trying to do something that's rather complex and each character has a lot of data, including a quote for each character, 4 ability icons, health, mana, defense, etc. and I just don't think putting them all in data-attributes for each item would be efficient. If I follow that method, I'd have to edit the html itself and that would mean a very long and confusing html. I've already found one good way to make some attributes easy to apply via jQuery:
var greenHairList = '#greengirl, #blueboy'
...
$(greenHairList).attr('data-hair-color', 'Green')
This way, it will be applied via jQuery, leaving my html clean and uncluttered. However, this still uses data-attributes. I'd love it if there were any other ways to achieve what I want with minimal use of data-attributes, and addressing my issue with the character-card div. Thanks to anyone who can help!
Why you need to use data for your details?
The best solution is create an object list with all your characters deteails. And add just a data-id for get the good data.
You can:
var characters = [
{
id: 1,
firstname:"john",
lastname:"Doe",
mana:150,
power:2000
},
id: 2,
firstname:"Karl",
lastname:"Kanung",
mana:120,
power:300
}
];
When you create this list, you can add html element dynamicaly with data-id for your character:
This is just an example in loop:
id = 3;
characters.push({id: id, firstname: "Paul", lastname: "pool", mana: 500, power: 3000});
charlist = $("<li></li>").attr("data-id",id);
$("#char-list").append(charlist);
id++;
and know you need just to make a onclick function, get the data-id of element, check in object list the details to show and create the card.
The best is create just on card alredy in your html page and replace the value by your objects value.
This is one way.

Issue with tree traversal, finding div ID to be used variably - jquery

so I've been trying to figure this out but I'm coming up short. Have really tried searching the best I could to come up with the answer, including jQuery API documentation and other SO posts. I feel like I'm almost there but I'm either misunderstanding something or I'm approaching this goal incorrectly.
For multiple different sections, I have 2 clickable icons in separate div's, 1 (lets say iconA) shown on load and 1 hidden (iconB) on load. When (iconA) is clicked, it hides the [sectionA] where (iconA) is located then shows the [sectionB] where (iconB) is located. I then want (iconB) to hide [sectionB] and show [sectionA].
Clearly I can't use toggle because one of the sections is always hidden at any given point. And since I'm trying to write a script that I can use for multiple sections and multiple icons, with different names, I can't just set 1-1 class names for ALL icons and sections.
I've created a jsfiddle to illustrate. Below I'll write a quick example.
HTML:
<div class="sectionAparent>
<div class="sectionA" id="example>
<i class="fa fa-code contbtn">iconA (shown on load)</i>
</div>
</div
<div class="sectionB" id="exampleSHOW">
<i class="fa fa-minus minushide">iconB (hidden on load)</i>
</div>
jQuery:
$('.contbtn').click(function(){
var contid = $(this).attr('id');
$('#'+contid+'show').slideToggle(1000);
$(this).hide(1000);
});
-this first one is to hide sectionA and show sectionB, which works fine.
$('.minushide').click(function(){
var cbtn = $(this).closest('.sectionB').siblings('.sectionAparent').find('div[id]');
var cid = $(cbtn).attr('id')
$('#'+cid+'show').slideUp(1000);
$(cid).slideDown(1000);
});
-So my thoughts were to jump up to the closest ancestor that is a sibling to the section containing the ID that I need. Then find the div with that ID, retrieve that ID, and use it show the section containing the ID and hiding the section with the ID+more. The goal is for this to be variable for multiple different sections with similar naming conventions without having to hard-code the section names in a list inside my script.
Hope this makes sense and I apologize for the wall of text, just wanted to make sure I conveyed what I'm trying to do and where I'm at. If my logic is incorrect or there is an easier way to do this, then I'm all ears! Thanks.
https://jsfiddle.net/dankbawls/wnjxwyfy/
You forgot to append the '#' character to sid in the second last line of the js
Updated fiddle
$('#'+sid).slideDown(2000);
Since you are using class (sectionhide) to toggle visibility, you can look into .toggleClass method.
It has an overriden constructor to accept 2 arguments, className and state (a boolean value)
Based on this state, it will add/remove class. True means add and false means remove
$('.minushide, .contbtn').on("click", function() {
var container = $(this).closest('.container');
var nextContainer = container.next('.container').length > 0 ? container.next('.container') : container.prev('.container');
container.toggleClass('sectionhide', true)
nextContainer.toggleClass('sectionhide', false)
})
Sample Fiddle
Note: I have added a common class container to both divs to have a common pattern
For a carousel kind of behaviour, you can use index to find index of element to be shown and hide all.
Sample Fiddle

How to create a see-more/Read-more feature requiring only anchors in the html?

I'm working on a site which will be maintained by not so tech savvy people, and I need to be able to give them the ability to add "see-more" anchors which use Jquery slide up/down to reveal their content.
My code works well for a single instance of the read more, but when there are multiple instances of this, it gets fairly screwed up.
javascript/jquery
$(".see-more").nextUntil(".see-less").wrapAll("<div class='see-more-content'></div>");
$(".see-less").hide();
var count= 1
/*
$(".see-more-content").each(function(){
var count= count+1;
$(this).data("count",count);
console.log(count);
});
*/
$(".see-more-content").slideUp(0);
$(".see-more").click(function(){
$(".see-more-content").slideToggle();
$(".see-more").hide();
$(".see-less").show();
});
$(".see-less").click(function(){
$(".see-more-content").slideToggle();
$(".see-less").hide();
$(".see-more").show();
});
HTML
<a class="see-more">See More...</a>
<ul>
<li>Advanced Elastic search Technology </li>
<li>Document Text Search</li>
<li>Embed Code Web Publishing for Images, Video & PDFs</li>
<li>Video Management with HTML5 Full</li>
<li>Previews On the Fly Conversions and Transcoding</li>
<li>Print on Demand</li>
<li>Stylized Collections (Lightboxes/Galleries)</li>
<li>Alerts and Notifications</li>
<li>Comments, Ratings and Favorites</li>
<li>WordPress and Drupal CMS Integrations</li>
<li>Dropbox Integration</li>
<li>Asset Level Performance Analytics • Site Activity Analytics Dashboard</li>
<li>Unlimited Custom User Access Levels</li>
<li>Integrated Content Contribution and Workflow</li>
<li>Personal Profile Management</li>
<li>Mobile App and Site </li>
<li>Watermarking</li>
<li>Rights Management</li>
<li>All New Feature Releases3</li>
</ul>
<a class="see-less">See Less...</a></div>
What I want to happen:
I want everything between the anchor with class see-more and anchor with class see-less, to get wrapped in a div, which when the anchor for see-more is clicked that div jquery slides down, when see-more is clicked, and slides up when see-less is clicked.
What is happening:
It works perfect when there is only one instance of see-more and see-less in a page. https://jsfiddle.net/TheWebTech/by3LsLuu/
When there are multiple instances of see-more and see-less in the html, the contents of all see-more+see-less blocks after the first instance are all moved/wrapped into the first block instances of the see-more see-less blocks get added.
https://jsfiddle.net/TheWebTech/by3LsLuu/4/
How do I prevent everything from being wrapped into the first instance of the see-more see-less block and instead have each one get wrapped separately?
Bonus but not really required: how can I make each see-more section slide up/down separately from eachother?
If you're going to keep the layout the same, you can use .prev() and .next() jQuery methods to determine which selector group you're referring too. Here's an updated fiddle with two instances:
https://jsfiddle.net/szva79d6/1/
First, I've made it so that your wrapping function applies to each selector individually, like so:
$(".see-more").each(function() {
$(this).nextUntil(".see-less")
.wrapAll("<div class='see-more-content'></div>");
});
What I've done in the two event methods is to make each event only act on the previous or next siblings, so that your events are properly delegated to each dynamically wrapped element.
$(".see-more").click(function() {
var $more = $(this),
$content = $more.next(".see-more-content"),
$less = $content.next(".see-less");
$content.slideToggle();
$more.hide();
$less.show();
});
$(".see-less").click(function() {
var $less = $(this),
$content = $less.prev(".see-more-content"),
$more = $content.prev(".see-more");
$content.slideToggle();
$less.hide();
$more.show();
});
You need to target specific to itself, try this:
$(".see-more").click(function(){
$(this).next(".see-more-content").slideToggle(); // find next content and show
$(this).hide(); // hide the see more button
$(this).nextAll('.see-less').first().show(); // show the next see less button
});
$(".see-less").click(function(){
$(this).prev(".see-more-content").slideToggle();
$(this).hide();
$(this).prevAll(".see-more").first().show();
});
Here's an updated fiddle

(jQuery) Find and Replace specific text

I've got the following HTML code, which essentially pertains to a post where I announce something in just a few lines, end it with "[...]", and add a "Read more" link-button at the bottom. When this button is clicked, additional content that's hidden will fadeIn as the button disappears, leaving visible the introductory text and the one that was hidden -- simple enough. Now, I've already written the code for this, but the complication comes when I try to also remove that "[...]" (from the post where the click button happened) that I included in the sneak peek. Here's the HTML:
<div class="entry">
<p>Welcome. Talk about something briefly and click below for more. [...]</p>
<div class="slide-content">
<p>Hidden content.</p>
</div>
<span id="revealer" class="button">Read more</span>
</div>
Classes "entry" and "button" belong to my CSS file, while "slide-content" belongs to my .js file to control the fadeIn effect. The ID "revealer" also belongs to the .js file for the same purpose. This HTML is wrapped in a div tag with a class of "box". This is the format that each post follows, exactly the same format with the same HTML elements -- every time an announcement needs to be made, it's just a matter of putting the content between the paragraph tags and publish. Here is where my problem comes in, since I can't find a way to remove the "[...]" only in the post where the button has been clicked. I tried doing the following but it resulted in the deletion of all "[...]" throughout multiple posts:
$('.entry p').each(function() {
var textReplace = $(this).text();
$(this).text(textReplace.replace('[...]', ''));
});
Summary:
I need to remove the "[...]" text only from the post where the user has clicked on (the "Read more" button). The idea is to have this removed while at the same time the hidden content fades in.
I've been able to accomplish the above but for all instances of "[...]". I need to sophisticate my selection by modifying my jQuery code or the HTML.
Option 3 is to get rid of this "[...]", but I would like to leave it there to let the user know she has more content to read, and I would like to have that "Read more" button in all posts for consistency.
~Thanks in advance!
First, you mention you have multiple of these. In that case, this:
<span id="revealer" class="button">Read more</span>
will not work. id attribute has to be unique per document, i.e. you can have at most one element with the specific id value.
If you make your HTML (for each of the blocks) like this:
<div class="entry">
<p>Welcome. Talk about something briefly and click below for more. [...]</p>
<div class="slide-content">
<p>Hidden content.</p>
</div>
<span class="revealer button">Read more</span>
</div>
and your JS like this:
function replace(fromp) {
var textReplace = fromp.text();
fromp.text(textReplace.replace('[...]', ''));
}
$('.revealer').click(function() {
var fromp = $(this).siblings().eq(0);
replace(fromp);
});
it will work properly. Working example:
http://jsfiddle.net/G4t7Q/
Hope this helps.
When you run your page initialization script, you could use jquery to select all of the posts and all of the remove buttons and link them up via their click event. I've created a JSFiddle example, but here's the jist of it:
var removers = $(".remover")
var posts = $(".post")
for (var i = 0; i < removers.length; i++) {
$(removers[i]).click( { post: posts[i] },
function(event) {
var textReplace = $(event.data.post).text()
$(event.data.post).text(textReplace.replace('[...]', ''))
}
)
}​
This is a simplified example; it assumes the posts and buttons are sorted in the markup.

JavaScript incrementing a variable

I'm trying to increment a variable in JavaScript by clicking on a link, it works the first time but then every other time if I click on it once it will show up 3 times, then 4, 5 and so on.
A screenshot of the console:
The numbers in the blue (right) are as expected, there is nothing wrong with this but as you can see on the left, each line is one click. the first log is fine but then it logs 1 three times, then 10 four times.
Here is the code thats doing the work.
$('.here').live('click', function(eve) {
eve.preventDefault();
var curpop = $(this).attr('rel')
++curpop
$('.pop').html(curpop);
console.log(curpop)
})
$(this).attr('rel') is just a number (in the blue, right, in the picture) once you click the link it is meant to increment the number.
Thanks for you help.
EDIT: I have set up the same thing in jsfiddle but it seems to work there, and all the suggestions still dont work on my project even though they should.
<h4 class='left'>Click
<a class="here" href="#" rel="1">here</a></h4>
<h4 class='right'>
<span class='pop'>
1
</span>
</h4>
This is the html, now there are multiple of these but are loaded via ajax, I am guessing that it would have something to do with the multiple instances of the class with no identifier to separate them?
More EDIT
As I suspected the problem was with the "multiple instances of the class with no identifier to separate them" so I just made each one like this:
<span id="<?php echo $thereID; ?>_span" class='pop'>
1
</span>
then
$('#' + thereID + '_span').html(curpop);
Thanks for all the help
Need to see more code, but typically I see JS beginners adding the event inside of the event. In other words, every time the link is clicked, another event handler is added.
At any rate, here's an example of incrementing a counter in a click handler: http://jsfiddle.net/GSuSk/
GO UP
<p>0</p>
<script>
$('#link').click(function(){
var v=$('p').text();
$('p').text(+(v)+1);
});
</script>
Why dont you try this kind of method? Look here for demo
Not sure with this limited amount of code, but if I'm not mistaken, I think one problem is that the variable is being created within live and really should initialize outside so that it only needs grab it once, then increment from there on without having to grab the new value each time. Here is how I re-arranged it.
http://jsfiddle.net/robx/nDbb8/1/
<script type="text/javascript">
$(function(){
$('.here li a').click(function(){
var current = parseInt($(this).attr('rel'));
var inc = current + 1;
console.log(inc);
$(this).attr('rel',inc);
});
});
</script>
<div >
<ul class='here'>
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
</div>
I don't think you need the live function here ... the key is to use parseInt to cast the current value of the rel attribute as it's being evaluated as a string ... :-)

Categories

Resources