0

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?

David Barker
  • 14,484
  • 3
  • 48
  • 77

7 Answers7

2
$(function(){
    var pages = $('div[id^=page]');
    $("a.plink").click(function() {
        var dis = $(this).attr("class").replace(' plink', '');
        pages.hide().filter('#' + dis).show();
        return false;
    });
});
silly
  • 7,789
  • 2
  • 24
  • 37
  • @ManseUK thank you, an i have to replace ' plink' from classes string! – silly Mar 09 '12 at 12:42
  • Sorry I wasn't clear in my initial question. This answer is definitely on the right lines (I think)... still quite nooby with Jquery :( my JQuery works fine as long as I dont have `.plink` as a class for the links. I can't use the container div as a selector either as there are other links on the page that will use this function. Thanks for your answer :) – David Barker Mar 09 '12 at 12:54
  • @DavidBarker ok i correct it... first i select all pages with a id = page*... than i hide all and show just the '#' + dis page – silly Mar 09 '12 at 12:57
  • Thank you! That's working... though I have a load of DIV's that start with 'page'... that are now hidden :) I'll go through and change them unless there's another way of populating `var pages`? – David Barker Mar 09 '12 at 13:02
1

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 Alpha
  • 143,660
  • 29
  • 287
  • 307
  • No this is not correct but not your fault as I didnt word the question properly. I have now included the DIV's I am showing and hiding that have ID's. – David Barker Mar 09 '12 at 12:48
  • Thank you Sheikh Heera, using `div[id^="page"]` was new to me as is `split()` I now understand them after reading the documentation on them. Really helpful. – David Barker Mar 09 '12 at 13:53
1

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

Community
  • 1
  • 1
Matt Esch
  • 22,661
  • 8
  • 53
  • 51
  • Thanks for your answer m232, im unclear on the JQuery though +1 for the link. I will certainly be using `href` values in the future to clear up my code. – David Barker Mar 09 '12 at 13:54
1

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();
Daniel Blaichinger
  • 348
  • 1
  • 2
  • 13
1

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.

Supr
  • 18,572
  • 3
  • 31
  • 36
  • Thanks supr, I've always been wary of using regex in JS (not sure why, but I don't particularly like using them in PHP either) thanks for showing me how it would be achieved. – David Barker Mar 09 '12 at 13:56
  • My pleasure. Noticed a mistake so I had to update it. I used to avoid regex as well, because they were foreign and tricky to me. Now that I understand them though I love them, but it is essential to have a tool for testing/debugging it. A nice online tool (one of many) I just found is this: http://gskinner.com/RegExr/ – Supr Mar 09 '12 at 14:48
0

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

thanksalot
  • 115
  • 2
  • 16
0

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.

Rozwel
  • 1,990
  • 2
  • 20
  • 30