0

I am building a quiz with two options for answering the questions, either swiping (right or left) or clicking (heart or crossed-out-heart) options.

I have the swipe functionality working and tabulating the score correctly but I am having trouble getting the click event to run the argument which calculates if the answer was correct or not.

My HTML looks like this:

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

  <title>Quiz</title>
    <link rel="stylesheet" href="css/style.css">
    <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
    <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
    <script src="http://code.ionicframework.com/collide/0.0.4/collide.js"></script>
    <script src="http://www.loringdodge.com/files/ionic.tdcards2.js"></script>
</head>

<body ng-app="starter" no-scroll>
    <ion-pane ng-controller="CardsCtrl" class="background-grey">
      <ion-header-bar class="bar-default">
        <h1 class="title">Quiz</h1>
      </ion-header-bar>

      <div class="td-title">
        <div class="row">
          <div class="col">Master: <span>{{ cards.master.length }}</span></div>
              <p style="color:blue;"><strong>Points</strong> : <span>{{points}}</span></p>
          <div class="col">Bands: <span>{{ cards.active.length }}</span></div>
          <div class="col">Discards: <span>{{ cards.discards.length }}</span></div>
        </div>
        <div class="row">
          <div class="col">Liked: <span>{{ cards.liked.length }}</span></div>
          <div class="col">Disliked: <span>{{ cards.disliked.length }}</span></div>
        </div>
      </div>

      <h2 id="family-zone">SWIPE RIGHT<br>FOR FAMILY</h2>
      <h2 id="not-family-zone">SWIPE LEFT<br>FOR NOT FAMILY</h2>


      <!-- *************************
        TD Cards
        - We start off with an ng-if so that the cards are not generated
          unless $scope.cards is not 'null'
      ************************* -->
      <div ng-if="cards.active">
        <td-cards>
          <td-card ng-repeat="card in cards.active" on-destroy="cardDestroyed($index)" on-swipe-left="cardSwipedLeft($index)" on-swipe-right="cardSwipedRight($index)">
            <div class="image" ng-controller="CardCtrl">
              <div class="no-text" ng-click="onClickTransitionOut(card)($index)" ng-click="onClickNotFamily(card)($index)"></div>
              <div class="yes-text" ng-click="onClickTransitionOut(card)($index)" ng-click="onClickFamily(card)($index)"></div>

              <!-- *************************
                Discard
                - The card is removed from the deck and a fly away animation is triggered.
                - onClickTransitionOut is found in ionic.tdcards.js
                - Animation can be customized by changing defaults
              ************************* -->

              <img ng-src="{{ card.image }}">
            </div>
          </td-card>
          <!-- *************************
            End Card
            - 'drag' is set to false. The user cannot drag it.
            - 'refreshCards()' reloads all cards that have NOT been discarded.
          ************************* -->
          <td-card id="end-card" drag="false">
          <h2 id="share">SHARE ON FACEBOOK</h2>
           <!--  <i class="icon ion-ios-refresh disable-user-behavior" ng-click="refreshCards()"></i> -->
          </td-card>
        </td-cards>
      </div>


    </ion-pane>
  </body>

And my Javascript currently looks like this:

 <script type="text/javascript">

        angular.module('starter', ['ionic', 'ionic.contrib.ui.tinderCards2'])


.config(function($stateProvider, $urlRouterProvider) {

})

.directive('noScroll', function($document) {

  return {
    restrict: 'A',
    link: function($scope, $element, $attr) {

      $document.on('touchmove', function(e) {
        e.preventDefault();
      });
    }
  }
})

.controller('CardsCtrl', function($scope, TDCardDelegate, $timeout) {

  var cardTypes = [

  { 
    "image": 'http://classicsdujour.com/wp2015/wp-content/uploads/2015/01/Van-Halen-Deluxe-Cover.jpg',
    "question" : "Q: This question is true",
    "valid"    : 1, // indicates the correct array number, use 0, 1...
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is True"]  
  },
  {
    "image": 'https://www.dustygroove.com/images/products/j/jackson5~~~_abc180gra_101b.jpg',
    "question" : "Q: This answer to this question is true",
    "valid"    : 1,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is True"] 
  },
  {
    "image": 'https://fanart.tv/fanart/music/9beb62b2-88db-4cea-801e-162cd344ee53/albumcover/solid-gold-hits-504adea20593c.jpg',
    "question" : "Q: This question is false",
    "valid"    : 0, 
    "buttons"  : ["False", "True"],
   "answers"  : [ "The correct answer is False"] 
  },
    {
    "image": 'http://cdn.therockcorner.com/artists/k/kings-of-leon/albums/youth-and-young-manhood-5.jpg',
    "question" : "Q: The answer to this question is truuueee",
    "valid"    : 1,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is True"] 
  },
    {
    "image": 'https://analogkidblog.files.wordpress.com/2015/06/the-family-320-kbps.png',
    "question" : "Q: False is the answer here",
    "valid"    : 0,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is false"] 
  },
    {
    "image": 'https://upload.wikimedia.org/wikipedia/en/1/1c/SoundsSilence.jpg',
    "question" : "Q: This questions is false",
    "valid"    : 0,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is False"] 
  },
    {
    "image": 'http://static1.squarespace.com/static/5073209bc4aa6253939f5db3/t/5715299c40261d3e0a616695/1461004706936/?format=500w',
    "question" : "Q: True True Truueee",
    "valid"    : 1,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is True"] 
  },
    {
    "image": 'https://upload.wikimedia.org/wikipedia/en/a/ae/Daft_Punk_-_Discovery.jpg',
    "question" : "Q: This one is indeed false",
    "valid"    : 0,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is False"] 
  },
      {
    "image": 'http://66.media.tumblr.com/tumblr_lidp3btJqJ1qzk6vno1_1280.jpg',
    "question" : "Q:  Ahaaaa a true question",
    "valid"    : 1,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is True"] 
  },
    {
    "image": 'https://upload.wikimedia.org/wikipedia/en/2/20/Arcticmonkeys-humbug.jpg',
    "question" : "Q: Another false statement",
    "valid"    : 0,
    "buttons"  : ["False", "True"],
    "answers"  : [ "The correct answer is False"] 
  },
      //{
    //"question" : "Game over, check your score below.",

  //}

];

var qc        = 0, // Current Question counter
    points    = 0, // Current points
    validIdx = cardTypes.valid,
    $points   = ("p>span");


  $scope.cards = {
    master: Array.prototype.slice.call(cardTypes, 0),
    active: Array.prototype.slice.call(cardTypes, 0),
    discards: [],
    liked: [],
    disliked: []

  }

  $scope.points = 0;

  $scope.cardDestroyed = function(index) {
    $scope.cards.active.splice(index, 1);
  };

  $scope.addCard = function() {
    var newCard = cardTypes[0];
    $scope.cards.active.push(angular.extend({}, newCard));
  }

  $scope.refreshCards = function() {
    // Set $scope.cards to null so that directive reloads
    $scope.cards.active = null;
    $timeout(function() {
      $scope.cards.active = Array.prototype.slice.call($scope.cards.master, 0);
    });
    $scope.points = 0;
  }

  $scope.$on('removeCard', function(event, element, card) {
    var discarded = $scope.cards.master.splice($scope.cards.master.indexOf(card), 1);
    $scope.cards.discards.push(discarded);
  });

  $scope.cardSwipedLeft = function(index) {
    console.log('LEFT SWIPE');
    var card = $scope.cards.active[index];
    $scope.cards.disliked.push(card);

    var givenAnswer = 0,
    correctAnswer = card.valid;  
  if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');            
  } else {
    console.log('incorrect!!!!');                       
  }
//increment the points variable if the answer is correct:

if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');
    $scope.points++;             
} 
  };

  $scope.cardSwipedRight = function(index) {
    console.log('RIGHT SWIPE');
    var card = $scope.cards.active[index];
    $scope.cards.liked.push(card);

   var givenAnswer = 1,
    correctAnswer = card.valid;  
  if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');            
  } else {
    console.log('incorrect!!!!');                       
  }
//increment the points variable if the answer is correct:
if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');
    $scope.points++;             
} 

  };

  $scope.onClickNotFamily = function(index) {
    console.log('LEFT CLICK');

    var givenAnswer = 0,
    correctAnswer = card.valid;  
    if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');            
    } else {
    console.log('incorrect!!!!');                       
    }
    //increment the points variable if the answer is correct:

    if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');
    $scope.points++;             
    } 

  };

  $scope.onClickFamily = function(index) {
    console.log('RIGHT CLICK');
    var card = $scope.cards.active[index];
    $scope.cards.liked.push(card);

   var givenAnswer = 1,
    correctAnswer = card.valid;  
  if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');            
  } else {
    console.log('incorrect!!!!');                       
  }
//increment the points variable if the answer is correct:
if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');
    $scope.points++;             
} 

  };


})




.controller('CardCtrl', function($scope, TDCardDelegate) {

});





        </script>

I just want the click event to run the argument to determine if the answer was correct or not.

The current piece of script running this argument when the user swipes right looks like this for example:

$scope.cardSwipedRight = function(index) {
    console.log('RIGHT SWIPE');
    var card = $scope.cards.active[index];
    $scope.cards.liked.push(card);

   var givenAnswer = 1,
    correctAnswer = card.valid;  
  if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');            
  } else {
    console.log('incorrect!!!!');                       
  }
//increment the points variable if the answer is correct:
if (givenAnswer === correctAnswer) {
    console.log('correct!!!!');
    $scope.points++;             
} 

  };

1 Answers1

0

From the HTML spec:

When the user agent leaves the attribute name state (and before emitting the tag token, if appropriate), the complete attribute's name must be compared to the other attributes on the same token; if there is already an attribute on the token with the exact same name, then this is a parse error and the new attribute must be removed from the token.

Meaning, when you write:

<div class="no-text" ng-click="onClickTransitionOut(card)($index)" ng-click="onClickNotFamily(card)($index)"></div>

The first ng-click attribute (onClickTransitionOut...) is assigned, and the second one (onClickNotFamily) is discarded, because there is already a value for ng-click. So only the first function will get run when you click.

Here are two options to resolve this so that both functions are run:

  • Restructure your code so that there is a single function which you can bind to ng-click. I would recommend this, since your JS appears to have some of copy/pasted code between the click and swipe handlers.

  • Combine the ng-click attributes to be ng-click="function1(); function2()" (as in this post).

I hope that helps! I am not an Angular expert so there may be other issues which I have not noticed.

Community
  • 1
  • 1
Ollin Boer Bohan
  • 2,296
  • 1
  • 8
  • 12