0

SOLUTION

https://github.com/Campos696/Attendance/commit/28177ff5cf285e9616faddae74fa6f0288a8667a

i have this javascript file:

https://github.com/Campos696/Attendance/blob/master/js/app.js

and am trying to make it so that the checkboxes created by the bodyView, have click listeners, however right now i can only create a listener for one checkbox at a time, is there any way to improve this?

And whether i check or uncheck it does the same thing(decreases daysMissed).

Here is the relevant part of the code:

var bodyView = {

  init: function() {
    this.render();
  },

  render: function() {
    var student, i, x;

    var schoolDays = octopus.getSchoolDays();
    var students = octopus.getStudents();


    for(i = 0;i < students.length; i++) {
      octopus.setCurrentStudent(students[i]);
      var daysMissed = octopus.getDaysMissed();
      $('#students').append('<tr class="'+i+'"><td class="name-col">' + students[i].name + '</td></tr>');
      for(x = 1;x < schoolDays; x++) {
        $('.'+i).append('<td id="check'+i+'" class="attend-col"><input type="checkbox"></td>');
      };
      $('.'+i).append('<td class="missed-col">'+ daysMissed + '</td>');
    };
    $(function(){
      $('#check0').click(function() {
        octopus.setCurrentStudent(students[0]);
        if($(this).is(':checked')){
          octopus.incrementDaysMissed();
        } else if(!$(this).is(':checked')){
          octopus.decreaseDaysMissed();
        }
      })
    })
  }
}

FUNCTION EDIT

$(function(){
         $('[id^=check] :checkbox').on('change', function(e) {                
            var daysMissed = $(this).closest('tr').find('td:last');

            if (this.checked) {
              octopus.decreaseDaysMissed();
              daysMissed.html(octopus.getDaysMissed());
            } else {
              octopus.incrementDaysMissed();
              daysMissed.html(octopus.getDaysMissed());
            }
        })
    })

2 Answers 2

1

IDs must be unique. That means you need to change the following line:

$('.'+i).append('<td id="check'+i+'" class="attend-col"><input type="checkbox"></td>');

with:

$('.'+i).append('<td id="check'+ i + x +'" class="attend-col"><input type="checkbox"></td>');
                               ^^^^^^^^

In this way each td has an id like: check01.....check46...

Second issue: change the click event with the change event and attach it to:

$('[id^=check] :checkbox').on('change', function(e) {

select each td having an id starting with check and for each td get the child checkbox.

var model = {

    currentStudent: null,
    schoolDays: 12,
    students: [
        {
            name: "Slappy the Frog",
            daysMissed: 12
        },
        {
            name: "Lilly the Lizard",
            daysMissed: 12
        },
        {
            name: "Paulrus the Walrus",
            daysMissed: 12
        },
        {
            name: "Gregory the Goat",
            daysMissed: 12
        },
        {
            name: "Adam the Anaconda",
            daysMissed: 12
        }
    ]
};

// Octopus

var octopus = {

    init: function () {
        model.currentStudent = model.students[0];
        headerView.init();
        bodyView.init();
    },

    getStudents: function () {
        return model.students;
    },

    setCurrentStudent: function (student) {
        model.currentStudent = student;
    },

    getSchoolDays: function () {
        return model.schoolDays + 1;
    },

    getDaysMissed: function () {
        return model.currentStudent.daysMissed;
    },

    incrementDaysMissed: function () {
        model.currentStudent.daysMissed++;
    },

    decreaseDaysMissed: function () {
        model.currentStudent.daysMissed--;
    }
};

// View

var headerView = {

    init: function () {
        this.render();
    },

    render: function () {
        var i;

        var schoolDays = octopus.getSchoolDays();

        $('#header').append('<th class="name-col">Student Name</th>');
        for (i = 1; i < schoolDays; i++) {
            $('#header').append('<th>' + i + '</th>');
        }
        ;
        $('#header').append('<th class="missed-col">Days Missed</th>');
    }
};

var bodyView = {

    init: function () {
        this.render();
    },

    render: function () {
        var student, i, x;

        var schoolDays = octopus.getSchoolDays();
        var students = octopus.getStudents();


        $('#students').empty();
        for (i = 0; i < students.length; i++) {
            octopus.setCurrentStudent(students[i]);
            var daysMissed = octopus.getDaysMissed();
            $('#students').append('<tr class="' + i + '"><td class="name-col">' + students[i].name + '</td></tr>');
            for (x = 1; x < schoolDays; x++) {
                $('.' + i).append('<td id="check' + i + x + '" class="attend-col"><input type="checkbox"></td>');
            }
            $('.' + i).append('<td class="missed-col">' + daysMissed + '</td>');
        }
        $(function(){
            $('[id^=check] :checkbox').on('change', function(e) {
                var colId = $(this).closest('td').index();
                var rowId = $(this).closest('tr').index();
                var studentName =
                        $(this).closest('tr').find('td:first').text();

                console.log('Student: <' + studentName +
                        '> on day: ' + colId + ' changed to: ' +
                        this.checked + ' Col: ' + colId + ' Row: ' + rowId);
            })
        })
    }
}
$(function () {
    octopus.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://rawgit.com/Campos696/Attendance/master/css/style.css">

<h1>Udacity Attendance</h1>

<table>
    <thead>
    <tr id="header"></tr>
    </thead>
    <tbody id="students"></tbody>
</table>

Sign up to request clarification or add additional context in comments.

4 Comments

Is there any way to separate the checkboxes by their first number, say i have the check0* boxes and the check1* boxes,i want an if statement that only happens when i click the check0* boxes but not the check1* boxes, because since i have multiple students and each checkbox row belongs to one of them, i tried putting the function inside the for loop for students length, and using $('[id^=check'+i+'] :checkbox') but it didnt work
It works mostly perfectly the only problem is that i set it so that when i click the checkbox it updates days missed and if i click checkboxes on two different rows it remembers the previous one, for instance i have 12 days missed in row 1 if i click any checkbox in row 1 it goes to 11 days missed, however if i then click a checkbox on another row the days missed in that row go down to 10 instead of 11. I have Updated the github repo if you need to see the changes
I use it to determine the daysMissed, however the bug still stands, i dont really understand why, i will edit my question with the function i created so as to have better formatting
Before decrease you need to set current student. I assume that is the direction to look for...
0

Use the input:checkbox selector to get all checkboxes:

$(function(){
  $("input:checkbox").click(function() {
    octopus.setCurrentStudent(students[0]);
    if($(this).prop("checked",true)){
      octopus.incrementDaysMissed();
    } else {
      octopus.decreaseDaysMissed();
    }
  });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.