0

So i have been working on this for a while now. in my html/php i have two dropdowns that become dates. That is working fine in my php when i POST. but that looks like this:

<?php for($x=1; $x<=20; $x++){ ?>
              <div class="form-group">
                <label><?php echo "$x"; ?>.</label>
                <select class="form-control" name="month<?php echo $x ;?>">
                  <option selected disabled>- Month -</option>
                  <option value="06">June</option>
                  <option value="07">July</option>
                  <option value="08">August</option>
                </select>
                <select class="form-control" name="day<?php echo $x ;?>">
                  <option selected disabled>- Day -</option>
                  <option value="01">1</option>
                  <option value="02">2</option>
                  <option value="03">3</option>
                  <option value="04">4</option>
                  <option value="05">5</option>
                  <option value="06">6</option>
                  <option value="07">7</option>
                  <option value="08">8</option>
                  <option value="09">9</option>
                  <option value="10">10</option>
                  <option value="11">11</option>
                  <option value="12">12</option>
                  <option value="13">13</option>
                  <option value="14">14</option>
                  <option value="15">15</option>
                  <option value="16">16</option>
                  <option value="17">17</option>
                  <option value="18">18</option>
                  <option value="19">19</option>
                  <option value="20">20</option>
                  <option value="21">21</option>
                  <option value="22">22</option>
                  <option value="23">23</option>
                  <option value="24">24</option>
                  <option value="25">25</option>
                  <option value="26">26</option>
                  <option value="27">27</option>
                  <option value="28">28</option>
                  <option value="29">29</option>
                  <option value="30">30</option>
                  <option value="31">31</option>
                </select>
              </div> <?php } ?>

So with that i want to have certain days from the drop down disabled when a certain month is picked from the other. To do this i figured javascript would be the easiest way. The available dates are listed above the drop down to the user so i was just going to validate the day and use an alert if they were wrong. js code is as follows:

function validate(){
  for(i=1;i<=20;i++){
    var month = document.getElementByName("month"+i);
    var day   = document.getElementByName("day"+i);

    if(month == "06"){//alert user if selecting a disabled date for june
      if(day == "01" || day == "02" || day == "03" || day == "04" || day == "05" || day == "06" || day == "07" || day == "08" || day == "09" || day == "10" || day == "11" || day == "17"){
        if(day == "18" || day =="24" || day == "25"){
          alert("Please choose a daily dropin date that corresponds to a date available during a session!");
        }
      }
    }//end if for june

    if(month == "07"){//alert user if selecting a disabled date for july
      if(day == "01" || day == "02" || day == "03" || day == "04" || day == "08" || day == "09" || day == "15" || day == "16" || day == "22" || day == "23" || day == "29" || day == "30"){
          alert("Please choose a daily dropin date that corresponds to a date available during a session!");
      }
    }//end if for july

    if(month == "08"){//alert user if selecting a disabled date for august
      if(day == "05" || day == "06" || day == "12" || day == "13" || day == "19" || day == "20" || day == "26" || day == "27"){
          alert("Please choose a daily dropin date that corresponds to a date available during a session!");
      }
    }//end if for august
  }
}

the button im using to run the onlcick function is the same one used to POST the form. i dont know if that matters but i am kinda lost right now with what is wrong in my javascript

1 Answers1

0

This is an interesting and common task. As a programmer you should strive not to create control structures that require you to excessively nest or multiply your code base.

The way that you should try to organize your code is with the DRY(don't repeat yourself) principle. This includes using loops to complete otherwise lengthy tasks and control structures. Otherwise you'll get what you have in your validation code if this or this or this or this or this or this or this... etc and that's not maintainable as well as being rather unsightly.

To give a more clear example of this, if you were to build a tic-tac-toe game, would you painstakingly write in every scenario of a win by saying "if top-left is x and top-mid is x and top-right is x OR top-left is x mid-left is x and bottom-left is x OR if top-left is x and middle is x and bottom-right is x..." for both team "X" and "O" respectively, or would you simply ask the browser "Is there a row of three boxes that all contain the same value?"

It's not something that you'll understand immediately, but it's important to realize that you will have to think a bit differently about your programs, but not to worry because if you keep at it I guarantee it will happen!

To answer your question:

https://jsfiddle.net/ygpqqmL9/3/

//create our data
data = {
  disabled_days: {
    "June": [3, 5, 7, 9],
    "July": [10, 20, 30],
    "August": [1, 2, 3, 4]
  }
}

//get the select month box
let select_month = document.querySelector('select[name="month"]');

//when a month is selected...
select_month.addEventListener('change', function(e) {

//get the name of the month
  let month = select_month[select_month.selectedIndex].textContent;

// get all the days in the day select box
// enable all of them
  let day_arr = [].slice.call(document.querySelectorAll('select[name="day"] option'))
  for (let day of day_arr) day.disabled = false;

// loop over all the days to be disabled
// find them in the data object based on the month name
// disable those days
 for (let disabled_day of data.disabled_days[month]) {
    for (let day of day_arr) {
      if (day.textContent == disabled_day) day.disabled = true;
    }
  }
})
zfrisch
  • 8,474
  • 1
  • 22
  • 34
  • Just came in this morning and read all of this. Thanks for the tips. As i was writing what i did i was thinking the whole time that there had to be a more simplified way. – somebodystopme Apr 24 '17 at 13:49
  • Im curious as to why you used let instead of var though – somebodystopme Apr 24 '17 at 13:50
  • @somebodystopme in this example, with the exception of the for loop, it wouldn't matter if you used var instead of let. The keyword let assigns a variable with lesser scope than var. Anything declared with let is only available within that block of code and any of its children(code blocks typically begin and end with braces, such as if statements and functions) var will set a variable globally or to the entirety of a code block, regardless of where it is declared within it. more here: http://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable – zfrisch Apr 24 '17 at 14:44
  • okay thank you. I have one last question. my html is looped through 20 times using php. So my month and day name attributes are then numbered day1, day2, day3... and same with month. it creates 20 of these dropdowns. continue in next comment – somebodystopme Apr 24 '17 at 15:45
  • So to get the month and name correct in your example would i loop the code and concatenate the for loop variable to to day and month like this: `for(x=1;x<=20;x++){` `let select_month = document.querySelector('select[name="month"+x]');` `let day_arr = [].slice.call(document.querySelectorAll('select[name="day"+x] option'))` – somebodystopme Apr 24 '17 at 15:50
  • @somebodystopme yep, you got it! That looks like it should work! – zfrisch Apr 24 '17 at 15:51
  • hmm i just implemented that and its not working. is the x var from the for loop not being interpreted as its value like that? – somebodystopme Apr 24 '17 at 15:58
  • I can't say for certain. What kind of error message are you receiving? – zfrisch Apr 24 '17 at 16:06
  • Uncaught DOMException: Failed to execute 'querySelector' on 'Document': 'select[name="month"+x]' is not a valid selector. – somebodystopme Apr 24 '17 at 16:34
  • @somebodystopme Sorry, the string concatenation was off. Try this: `let select_month = document.querySelector('select[name="month'+x + "']'); let day_arr = [].slice.call(document.querySelectorAll('select[name="day'+x‌+'"​] option'))` – zfrisch Apr 24 '17 at 16:46
  • So i fixed the concatenation which after seeing it completely makes sense. I get no errors, my js linter finds nothing either. Still not working but I have a feeling I am a lot closer than I was. – somebodystopme Apr 24 '17 at 17:01
  • @somebodystopme typically if there are no errors either a function is not being invoked or the element names are incorrect. That might be grounds to open a new question. If this answer helped you out though, please accept it(there should be a checkmark next to my answer that can be selected) to help out others! – zfrisch Apr 25 '17 at 15:16