jQuery: add multiple data attributes with each click function - javascript

I have a click function setup whereby when you click on the .click div, it takes the data-hook attribute, and add it as a data-filter attribute to the .button div, this works fine, but after each click it is replacing the data-filter attribute with the new one, ideally I want to add a new value to the attribute with each click, separating each value with a comma.
Here's a jsFiddle demo: http://jsfiddle.net/neal_fletcher/pSZ2G/
HTML
<div class="button">THIS</div>
<div class="click" data-hook="one">CLICK</div>
<div class="click" data-hook="two">CLICK</div>
<div class="click" data-hook="three">CLICK</div>
<div class="click" data-hook="four">CLICK</div>
<div class="click" data-hook="five">CLICK</div>
jQuery:
$(".click").click(function () {
var thing = $(this).attr("data-hook");
$('.button').attr('data-filter', thing);
});
If this is at all possible? Any suggestions would be greatly appreciated!

You can store the previous value and can concatinate with new clicked value, something like.
$(".click").click(function () {
var thing = $(this).attr("data-hook");
var earData = $('.button').attr('data-filter');
if(typeof earData != 'undefined'){
$('.button').attr('data-filter', earData + ","+thing);
}else{
$('.button').attr('data-filter', thing);
}
});
DEMO

$(".click").click(function () {
var thing = $(this).attr("data-hook");
var prevValue = $('.button').attr('data-filter');
if(prevValue){
$('.button').attr('data-filter', prevValue +','+thing)
}
else{
$('.button').attr('data-filter', thing)
}
});

$(".click").click(function () {
var thing = $(this).attr("data-hook")||'';
var df = $('.button').attr('data-filter')||'';
$('.button').attr('data-filter', df+','+thing)
});
on a side note.. I hope you don't have any other elements with a .button class in it.. if you're looking to update a single target, you should reference by an id attrib instead.

Related

How to call an div's attributes value using a function if there are many div's with the same function?

I have the following code:
function openCanviewer() {
var cid = $(this).data('cid');
alert(cid);
}
And the HTML:
<div onclick="openCanviewer();" data-cid="ID OF CAN FROM DATABASE"></div>
My problem is that when I click the element with the onclick function, which I have many of because they get inserted from the database, the alert is just showing "undefined" instead of the contents of the data-cid attribute. Does someone have any idea what I have done wrong, or what I am missing here?
To capture the exact element, pass this from the element's click event handler
function openCanviewer(element) {
var cid = $(element).data('cid');
alert(cid);
}
<div onclick="openCanviewer(this);" data-cid="ID OF CAN FROM DATABASE"></div>
^^^ you have a typo here
Snippet
function openCanviewer(element) {
var cid = $(element).data('cid');
alert(cid);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div onclick="openCanviewer(this);" data-cid="ID OF CAN FROM DATABASE">Click</div>
$('#mi').click(function() {
var cid = $(this).data('cid');
alert(cid);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mi" data-cid="ID OF CAN FROM DATABASE">hello</div>
In general you shouldn't use inline events like onclick="openCanviewer();", you should always keep js, css and html separate.
For your problem you could use delegate event listening:
function openCanviewer() {
var cid = $(this).data('cid');
alert(cid);
}
$(document).on('click', '[data-cid]', openCanviewer)

How do I get the id of parent div, then take out the first 3 letters of the name and store the last digit of the name into a variable?

I have an HTML structure like this:
<div id="tip1">
<div class="tip-icon"></div>
</div>
<div id="tip2">
<div class="tip-icon"></div>
</div>
<div id="tip3">
<div class="tip-icon"></div>
</div>
<div class="1 content"></div>
<div class="2 content"></div>
<div class="3 content"></div>
And I have a jQuery function like this:
$('.tip-icon').mouseenter(function() {
$('.1').addClass('tip-show'); //Change .1 to a variable
});
$('.tip-icon').mouseleave(function() {
$('.1').removeClass('tip-show2'); //Change .1 to a variable
});
But instead of having $('.1'), I want it to be the class numbers 1-3 depending on which "tip-icon" was hovered. I need to make is so that on "tip-icon" mouseenter it will take the parent div's id and delete the first 3 letters so that it is just the number left and store it into a variable. I then want to take this variable and use it in $('???').addClass('tip-show'); so that the ??? are replaced by the variable to make it so that one of divs with the classes 1-3 will get the 'tip-show' class added depending on which 'tip-icon' was hovered.
https://jsfiddle.net/oak4L9ga/
Dont do all that string mashing just to get the id out of the class. Instead tie your elements/functionality together using data-* attributes
<div id="tip1" data-tipid="1">
<div class="tip-icon"></div>
</div>
Then you can use that within your code to get the right id (actually, in your case class name)
$('.tip-icon').mouseenter(function () {
var tipId = $(this).parent().data('tipid');
$('.' + tipId).addClass('tip-show'); //Change .1 to a variable
});
Live example: https://jsfiddle.net/oak4L9ga/6/
You don't need to hack around the string of the class attribute as you can simply use index() to retrieve a numerical value representing the position of an element within a selector. Try this:
$('.tip-icon').on({
mouseenter: function () {
$('.' + ($(this).index('.tip-icon') + 1)).addClass('tip-show');
},
mouseleave: function () {
$('.' + ($(this).index('.tip-icon') + 1)).removeClass('tip-show');
}
});
Example fiddle
This can then be made shorter by using hover and toggleClass:
$('.tip-icon').hover(function () {
$('.' + ($(this).index('.tip-icon') + 1)).toggleClass('tip-show');
});
Example fiddle
Just make use of html5 data attribute:
Fiddle here: https://jsfiddle.net/oak4L9ga/8/
you can use hover for this as combination of mouseenter and mouseleave. Use regex to get the number in the id of parent.
$('.tip-icon').hover(function () {
var id = $(this).parent().attr('id').replace(/[a-z]/ig, '');
// Get the number from the id
$('.' + id).addClass('tip-show').show();
}, function () {
$('.content').removeClass('tip-show').hide();
});
Demo: https://jsfiddle.net/tusharj/oak4L9ga/9/
try
$(".tip-icon").hover(
function () {
$('.' + $(this).parent().attr("id").replace('tip', '')).addClass('tip-show');
}, function () {
$('.' + $(this).parent().attr("id").replace("tip", "")).removeClass('tip-show');
});
Updated Fiddle
Like this you mean?
$('.tip-icon').mouseenter(function() {
var id = $(this).parent().attr('id').substring(3, 1);
$('#'+id).addClass('tip-show');
});
Using JQuery chaining concept.
Check JQuery:
$('.tip-icon').mouseenter(function () {
var idValue = $(this).parent('div').attr('id').substr(3, 4);
$('.'+idValue).addClass('tip-show');
});
$('.tip-icon').mouseleave(function () {
var id_Value = $(this).parent('div').attr('id').substr(3, 4);
$('.'+id_Value).removeClass('tip-show');
});
Demo:
https://jsfiddle.net/oak4L9ga/11/

How can I add my own <divs> to a container dynamically?

I found a lot of info about this, but I haven't foundanything that could help me yet.
My problem is that I have got a div with its id and it supposes to be a container (#cont_seguim).
I have a menu on the right side which contains circles (made by css and filled with text), like following:
<div class="circle_menu b">
<div class="text_menu n">ECO</div>
</div>
where b and n are the format for background and text.
When I click a circle, this one must be added to the container (notice that each circle has got its own text), but I can't get that.
I made and array and used alert() to test that click works, and it does, but append() doesn't even work to print text, and I don't know why.
<script type="text/javascript">
var arrayS = new Array();
$(document).ready(function() {
$(".circulo_menu").click(function() {
var text = $(this).text();
alert("calling " + text);
$("#cont_seguim").append(text);
});
return text;
});
</script>
Thank you for your responses!
Your code seems to work fine (if you fix the different class name used in html vs script circulo_menu vs circle_menu)
Demo at http://jsfiddle.net/7jbUj/
To add the whole circle append the whole element and not its text by using .append(this)
$(".circle_menu").click(function() {
$("#cont_seguim").append(this);
});
Demo at http://jsfiddle.net/7jbUj/1/
To add a copy of the circle, so you can add multiple of them use the .clone() first..
$(".circle_menu").click(function() {
var clone = $(this).clone(false);
$("#cont_seguim").append(clone);
});
Demo at http://jsfiddle.net/7jbUj/3/
Inside the click handler, this refers to the clicked element. And since you bind the click handler on the circle_menu element, this refers to that. You can use it directly for the appending or clone it to make a copy first..
unable to understand properly, hope below one can help you.
<script type="text/javascript">
$(document).ready(function() {
$(".circulo_menu").click(function() {
var myText = $(this).html();
alert("calling " + myText);
$("#cont_seguim").html(myText);
});
});
</script>
make sure classname and id name will remain same as html
Try using html() instead of text().
Try this: Demo
HTML:
<div class="circle_menu b">
<div class="text_menu n">ECO</div>
</div>
<div id="cont_seguim"></div>
Javascript:
$(document).ready(function() {
$(".circle_menu").click(function() {
var text = $(this).html();
console.log("calling " + text);
$("#cont_seguim").append(text);
});
});
Try this:
$( ".container" ).append( $( "<div>" ) );
source
use
$("#container").append($("<div/>", {id:"newID",text:"sometext"}));
You could try
<script type="text/javascript">
var arrayS = new Array();
$(document).ready(function() {
$(".circulo_menu").click(function() {
var text = $(this).text();
alert("calling " + text);
$("#cont_seguim").append($(this).html());
});
return text;
});
</script>
By this way the clicked circle element get added to div

Attaching data to DOM elements

I m new to jquey.I m facing a problem to attach data to particular inner div's. I am writing a demo code for the problem that i faced which did the same behaviour as original one. I have to small div inside a big div and i want to store (for some further processing) and show some data to small div's based on user input.
[html code]
<div id="ctrl-1001" class="big">
<div id="m1" class="small"></div>
<div id="m2" class="small"></div>
</div>
<div id="input" class="control-group module">
<label class="control-label">Module Name</label>
<div class="controls">
<select id="ModuleName" name="DSname" class="input-large">
<option>TitleImage</option>
<option>SearchBox</option>
<option>CategoryLinks</option>
<option selected>BannerSlides</option>
</select>
</div>
<button id="sa">save</button>
</div>
[jquery code]
$('.small').click(function(){
$('#input').show();
var myId = $(this).attr("id");
var myParentId = $(this).parents('.big').attr('id');
var uniqueId = '#'+myParentId+' #'+myId;
create(uniqueId);
});
function create(uniqueId){
$('#input').show();
$('#ModuleName').change(function(){
var name = this.value;
$('#sa').click(function(){
save_name(name,uniqueId);
});
});
}
function save_name(name,uniqueId){
var div = $(uniqueId)[0];
jQuery.data(div,'store',name);
//alert(uniqueId);
//var val = jQuery.data(div,'store');
$(uniqueId).text(name);
$('#input').hide();
}
But the problem is when I click on second div to store some data the first div also changes the value which second one contains. demo on Jsfiddle
It is because when you click the first time one change handler is added to the select with targeting #m1 element, then again when you click on #m2 a new change handler is added without removing the first one, so when you click the button both these code gets executed.
So try
$('.small').click(function () {
var uniqueId = '#' + this.id;
create(uniqueId);
});
function create(uniqueId) {
$('#input').show();
//remove previously added handlers
//take a look at namespaced event handlers
//also there is no need to have a change handler for the select element
$('#sa').off('click.create').on('click.create', function () {
var name = $('#ModuleName').val();
save_name(name, uniqueId);
});
}
function save_name(name, uniqueId) {
var div = $(uniqueId);
//you can use the .data() method instead of the static jQuery.data() method
div.data('store', name);
//alert(uniqueId);
var val = div.data('store');
$(uniqueId).text(name);
$('#input').hide();
}
Demo: Fiddle
But a more jQueryish solution might look like
var $smalls = $('.small').click(function () {
var uniqueId = '#' + this.id;
$smalls.filter('.active').removeClass('active');
$(this).addClass('active');
$('#input').show();
});
$('#sa').on('click', function () {
var name = $('#ModuleName').val();
save_name(name, '.small.active');
});
function save_name(name, target) {
var div = $(target);
//you can use the .data() method instead of the static jQuery.data() method
div.data('store', name);
//alert(uniqueId);
var val = div.data('store');
div.text(name);
$('#input').hide();
}
Demo: Fiddle

Selecting a single class from a multi class element

I'm trying to select a specific class (in this case page1, page2, page3 etc.)
I've written this code that works fine for a single class, i've tried using .match() to exclude the .plink class picked up in dis but can't get it working.
$(function(){
$("a.plink").click(function() {
var dis = $(this).attr("class"); // This is the problem line, I need it to contain 'page1' ONLY. Not 'page1 plink'.
$("#page1,#page2,#page3").hide();
$("#" + dis).show();
return false;
});
});
The HTML that is associated with this is:
<div id="page-links">
<a class="page1 plink" href="#">About</a>
<a class="page2 plink" href="#">History</a>
<a class="page3 plink" href="#">Backstage</a>
</div>
EDIT:
These are the DIV's being shown and hidden:
<div id="page1">
<?php include_once("page1.php");?>
</div>
<div id="page2">
<?php include_once("page2.php");?>
</div>
<div id="page3">
<?php include_once("page3.php");?>
</div>
Is there a simple way to achieve this without regular expression matching?
$(function(){
var pages = $('div[id^=page]');
$("a.plink").click(function() {
var dis = $(this).attr("class").replace(' plink', '');
pages.hide().filter('#' + dis).show();
return false;
});
});
This should be
$("." + dis).show();
for class and in your example there are all classes.
As you mentioned simple way so it could be
$("a.plink").click(function() {
$(".plink").hide();
$(this).show();
return false;
});
According to your question after edit
$("a.plink").click(function() {
$('div[id^="page"]').not('#page-links').hide();
pid=$(this).attr('class').split(' ')[0];
$('#'+pid).show();
return false;
});
Here is a fiddle.
The JavaScript code is not correct. With the "#" you select ids from the html-element.
As you have only classes, the right way is to do it with "."
So this would be correct:
$(function(){
$("a.plink").click(function() {
var dis = $(this).attr("class");
$(".page1,.page2,.page3").hide();
$("." + dis).show();
return false;
});
});
I didn't test it, but I think you have to change something with the var dis.
If you click on .page1, the variable dis would contain "page1 plink".
$("." + dis).show();
would be
$(".page1 plink").show();
So I recommend to split the two classes, as it should be like
$(".page1 .plink").show();
You are trying to associate functionality of a click by appending classes. It would make more sense to put id of the div you want to show in the href
html:
<div id="page-links">
<a class="plink" href="#page1">About</a>
<a class="plink" href="#page2">History</a>
<a class=" plink" href="#page3">Backstage</a>
</div>
<div id="page1">
Content 1
</div>
<div id="page2">
Content 2
</div>
<div id="page3">
Content 3
</div>
​javascript:
jQuery(function ($) {
var pages = [];
function showPage(page) {
var i;
for(i = 0; i < pages.length; i++)
{
if(page === pages[i]) {
$(pages[i]).show();
} else {
$(pages[i]).hide();
}
}
}
// Store each href in a pages array and add handlers
$('.plink').each( function() {
var page = $(this).attr('href');
pages.push(page);
$(this).attr('href', '#');
$(this).click(function () {
showPage(page);
});
});
// show the first page
if(pages.length > 0) {
showPage(pages[0]);
}
});​
Example:
http://jsfiddle.net/38qLB/
And just so I don't avoid the actual question, which is how do you select a class from a multi class element, you should follow this example of splitting up the class name Get class list for element with jQuery if you truly insist on using classes to make your link/div association
You don't really want to exclude the plink class, because that will bring you confusion and trouble when you need to add another class. Instead you want to extract just the pageX class:
// Regex for extracting pageXX
var reg = /^(.*\s)?(page\d+)([^\d].*)?$/;
dis = reg.exec(dis)[2];
I haven't testet this 100%, but put these two lines in right after var dis = $(this).attr("class"); and you should hopefully be good to go.
i down't know if i get your question right
to get all classes with class plink u can use
var klasses $("a.plink");
now u can loop true the items
var yourClasses = Array();
for(var klass in klasses)
{
var word = klass.attr('class').replace(" plink", "");
yourClasses.push(word);
}
now you have all the classes wich have the class plink
hope this was where u where looking for
If I was just doing a minor tweak to fix your existing structure I would do something like this:
$(document).ready(function() {
$('a.plink').click(function() {
var id = $.trim(this.className.replace('plink', ''));
/*adding a "page" class to each of the page divs makes hiding the visible one a bit easier*/
$('div.page').hide();
/*otherwise use the version from sheikh*/
//$('div[id^="page"]').not('#page-links').hide();
$('div#' + id).show();
});
});
The main change I would recommend to your existing markup would be to add a common "page" class to each of the page divs. Here is a fiddle
If I was starting on this from scratch I would probably take a slightly different approach in which I define an "active" class and toggle which elements have it rather than using show/hide on the divs. And that would end up looking something like this:
Markup:
<div id="page-links">
<a class="plink active" href="#page1">About</a>
<a class="plink" href="#page2">History</a>
<a class="plink" href="#page3">Backstage</a>
</div>
<div id="page1" class='page active'> </div>
<div id="page2" class='page'> </div>
<div id="page3" class='page'> </div>
CSS:
div.page
{
height: 300px;
display:none;
}
div.page.active
{
display:block;
}
a.plink
{
padding-left:5px;
padding-right:5px;
}
a.plink.active
{
background-color:#ddd;
}
div#page1
{
background-color:blue;
}
div#page2
{
background-color:green;
}
div#page3
{
background-color:red;
}
Script:
$(document).ready(function() {
$('a.plink').click(function() {
var id = $(this).attr('href');
$('.active').removeClass('active');
$(this).addClass('active');
$('div' + id).addClass('active');
});
});
Or the fiddle here.
Oh and to answer the title question rather than just the end behavior described...
var classes = this.className.split(' ');
var id;
for (var i = 0; i < classes.length; i++) {
if(classes[i].substring(4) === classes[i].replace('page', '')) {
id = classes[i];
break;
}
}
should end up with id containing the "page#" value associated with the link that was clicked regardless of its position in the list of classes.

Categories