leelou
leelou

Reputation: 43

Show div only if specific other divs have been clicked

I am new to jQuery (this is my second attempt). I looked for answers via Google and StackOverflow and I have tried quite a few but have yet to figure out the last part of my problem. Any help or guidance is most appreciated.

What I want to do is have a bunch of images(apple, pumpkin, candle, etc) that when clicked, fade the image out and then cross off the image's name in a text list. Then, if you click on specific sets of those images they will show a div containing a deal.

An example: If you click on the images of apple, pear and pumpkin (in any order) a deal will show. Another example: You click on the images of candle, apple, pumpkin and key(in any order) a deal will show. Another example: You click on all image items(in any order) a deal shows.

I have the first part working (click on an image, it fades out and crosses its name off the list).

What I need help with is checking to see if certain combinations of images have been clicked and if so show the deal div.

I was thinking I could use index for this but I haven't been able to make it work. Maybe there is a better way? Thanks for any guidance.

Here is my test code so far (JSFIDDLE):

HTML

    <div class="pic1">
    <img width="50" height="50" src="http://us.123rf.com/400wm/400/400/chudtsankov/chudtsankov1208/chudtsankov120800002/14670247-cartoon-red-apple.jpg" />
    </div>
    </div>
    <div class="pic2">
    <img width="50" height="50" src="http://www.in.gov/visitindiana/blog/wp-content/uploads/2009/09/pumpkin.gif" />
    </div>
    <div class="pic3">
    <img width="50" height="50" src="http://upload.wikimedia.org/wikipedia/commons/f/fc/Candle_icon.png" />
    </div>
    <div class="pic4">
    <img width="50" height="50" src="http://tasty-dishes.com/data_images/encyclopedia/pear/pear-06.jpg" />
    </div>
    <div class="pic5">
    <img width="50" height="50" src="http://free.clipartof.com/57-Free-Cartoon-Gray-Field-Mouse-Clipart-Illustration.jpg" />
    </div>
    <div class="pic6">
    <img width="50" height="50" src="http://images.wisegeek.com/brass-key.jpg" />
    </div>
    <div id="items">
    <p class="apple">Apple</p>
    <p class="pumpkin">Pumpkin</p>
    <p class="candle">Candle</p>
    <p class="pear">Pear</p>
    <p class="mouse">Mouse</p>
    <p class="key">Key</p>
    </div>
    <div class="someText">Reveal Deal #1 after finding apple, candle and mouse</div>
    <div class="deal1">This is deal box #1! You must have found apple, candle and mouse! WIN</div>
    <div class="someText">Reveal Deal #2 after finding key, pumpkin, pear and mouse!</div>
    <div class="deal2">This is deal box #2! You must have found key, pumpkin, pear and mouse!</div>
    <div class="someText">Reveal Deal #3 after finding ALL objects!</div>
    <div class="deal3">This is deal box #3! You must have ALL the items!</div>
    <div id="output"></div>`

CSS

.intro, .someText {
        color:#333;
        font-size:16px;
        font-weight: bold;
    }
    .deal1, .deal2, .deal3 {
        font-size: 18px;
        color: red;
    }

Javascript: jQuery

$(document).ready(function () {

    $('.deal1, .deal2, .deal3').hide();

    $('.pic1').click(function () {
        $(this).data('clicked');
        $('#items p.apple').wrap('<strike>');
        $(".pic1").fadeOut("slow");
    });

    $('.pic2').click(function () {
        $(this).data('clicked');
        $("#items p.pumpkin").wrap("<strike>");
        $(".pic2").fadeOut("slow");
    });

    $('.pic3').click(function () {
        $(this).data('clicked');
        $("#items p.candle").wrap("<strike>");
        $(".pic3").fadeOut("slow");
    });

    $('.pic4').click(function () {
        $(this).data('clicked');
        $("#items p.pear").wrap("<strike>");
        $(".pic4").fadeOut("slow");
    });

    $('.pic5').click(function () {
        $(this).data('clicked');
        $("#items p.mouse").wrap("<strike>");
        $(".pic5").fadeOut("slow");
    });

    $('.pic6').click(function () {
        $(this).data('clicked');
        $("#items p.key").wrap("<strike>");
        $(".pic6").fadeOut("slow");
});

$(document).on('click', '*', function (e) {
        e.stopPropagation();
        var tag = this.tagName;
        var index = $(tag).index(this); // doesn't work, as it gives the total no. elements

        $('#output').html(index);
    });

});

Upvotes: 4

Views: 1927

Answers (2)

binboavetonik
binboavetonik

Reputation: 192

first of all you can give your divs a corresponding data value to their p items for instance if you implement your div ( and all the other divs)

<div class="pic" data="pumpkin">

instead of

<div class="pic2"> 

You can write an almost oneliner with jquery

$('.pic').click(function () {
    $("#items p."+$(this).attr("data")).wrap("<strike>");
    $(this).fadeOut("slow");
});

you can define your sets: set1 = ["apple","pumpkin"] and after every click you can check clicked paragraphes with

$(document).ready(function () {
var set1 = ["apple", "candle", "mouse"]


$('.deal1, .deal2, .deal3').hide();

$('.pic').click(function () {

    $("#items p." + $(this).attr("data")).wrap("<strike>").addClass("strike");
    $(this).fadeOut("slow");
    //test for set1
    set1Completed = true;
    for (i = 0; i < set1.length; i++) {
        if ($("p.strike." + set1[i]).length==0) {
            set1Completed = false;
            break;
        }
    }
    if (set1Completed) {
        $('div.deal1').fadeIn(); // or fadeIn whatever u want
    }
});

Upvotes: 3

PlantTheIdea
PlantTheIdea

Reputation: 16359

Create a custom event:

$('.HiddenItem').css({display:'none'}).on('somethingElseClicked',function(){
    $(this).show();
});

And then trigger it with the other click:

$('.ItemToTrigger').on('click',function(e){
    $('.HiddenItem').trigger('somethingElseClicked');
});

This is obviously supergeneralized, but it gives the framework necessary to trigger the event you want.

EDIT

Alright, so you will need to store each value for the clicks needed, as well as the total needed. I always prefer to use object-based variables rather than globals, so:

var click = {
    deal1:[0,2],
    deal2:[0,3],
    deal3:[0,5]
}

This creates arrays for each deal, the first being the number of clicks that have happened and the second being the total needed minus 1. You will then increment the "clicks that have happened" value, as well as prevent it from allowing double-clicks, by the JS described later. First, I recommend adding a generic class to all clickable items, as well as the deal items they are associated with, and verifying that way. The HTML:

<div class="picItem d1" data-fruit="apple">
<div class="picItem d2" data-fruit="pumpkin">
<div class="picItem d1" data-fruit="candle">
<div class="picItem d2" data-fruit="pear">
<div class="picItem d1 d2" data-fruit="mouse">
<div class="picItem d2" data-fruit="key">

And the JS I described:

$('.picItem').on('click',function(){
    var $this = $(this),
        $fruit = $this.data('fruit');

    $this.fadeOut('slow');

    if($this.hasClass('d1') && !$this.hasClass('clicked1')){
        if(click.deal1[0] < click.deal1[1]){
            click.deal1[0]++;
            $this.addClass('clicked1');
        } else {
            $('.deal1').trigger('showDeal');
        }
    }

    if($this.hasClass('d2') && !$this.hasClass('clicked2')){
        if(click.deal2[0] < click.deal2[1]){
            click.deal2[0]++;
            $this.addClass('clicked2');
        } else {
            $('.deal2').trigger('showDeal');
        }
    }

    if(!$this.hasClass('clicked3')){
        if(click.deal3[0] < click.deal3[1]){
            click.deal3[0]++;
            $this.addClass('clicked3');
        } else {
            $('.deal3').trigger('showDeal');
        }
    }

    $('.'+$fruit).wrap("<strike>");
});

The last if is for all elements clicked, hence not the need for adding a class and checking. The final piece grabs the associated data attribute and strikes it out.

Now you just trigger the event:

$('.deal1,.deal2,.deal3').on('showDeal',function(){
    $(this).show();
});

This event will only be triggered when the appropriate number of clicks has been reached. Here is the jsFiddle you gave me updated to show it is working as requested.

If you want to only allow one deal, you would just turn off the event after being triggered:

var $allDeals = $('.deal1,.deal2,.deal3');

$allDeals.on('showDeal',function(){
    $(this).show();

    if($(this).hasClass('deal3')){
        // this is to prevent deal 1 and deal 2 showing, since the criteria for them is also met
        $allDeals.not('.deal3').hide();
    }

    // this turns off all other deals
    $allDeals.off('showDeal');
    $('.picItem').off('click');
});

Not sure if you would need it or not, figured I would include it just in case. Here is an updated jsFiddle to show that case working.

Upvotes: 1

Related Questions