1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Hide Element Function

Discussion in 'JavaScript' started by Web_Dev_Chris, Jun 3, 2019.

  1. #1
    Hi,

    I want to write a function to execute on page load to hide the calendar if it's an old calendar.

    So I thought I when I upload the calendar I can have a hidden element with text content of the month and write a function to get the current month and check against the element text content and if it matches display block, if it's doesn't display none which will basically hide the calendar if it's not up to date.

    This is what i have so far. I'm stuck as my if statement is not working. Any suggestions. What is the best way of doing this? Thanks.

    https://jsfiddle.net/64uhpenw/1/
     
    Solved! View solution.
    Web_Dev_Chris, Jun 3, 2019 IP
  2. #2
    You need to learn basic javascript debugging skills and how to proof read your code
    //Hide Calendar if calendar is not up tp date with current month
    console.log(pOutput.innerHTML);
    console.log(theDate.getMonth());
    console.log(theMonths[theDate.getMonth()]);
    if (pOutput.innerHTML === theMonths[theDate.getMonth()]) {
      divDate.style.display = "block";
    } else {
      divDate.style.display = "none";
    };
    Code (javascript):
    The first thing I got when I ran your code was an error on innerText
    Then an error getMonths() which you had right in your commented out code but not in the live stuff
    These are easy errors to identify and fix
    Your final problem is going to be because you've got
    
    <p id="output">
        may
      </p>
    Code (markup):
    when your variable theMonths looks like this
    let theMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    Code (javascript):
     
    sarahk, Jun 3, 2019 IP
  3. Web_Dev_Chris

    Web_Dev_Chris Well-Known Member

    Messages:
    222
    Likes Received:
    12
    Best Answers:
    1
    Trophy Points:
    105
    #3
    Thanks very helpful. Maybe I need to convert the array result to lowercase and convert the output to lower case and use a == exact match compression.

    I’ll look into this some more.

    Thanks for your helpful feedback about debugging.
     
    Web_Dev_Chris, Jun 3, 2019 IP
  4. Web_Dev_Chris

    Web_Dev_Chris Well-Known Member

    Messages:
    222
    Likes Received:
    12
    Best Answers:
    1
    Trophy Points:
    105
    #4
    Wow I have found exactly how to do this even easier than what I was trying.

    Convert my array to lowercase using .map and passing in an arrow function.

    I’m very new to JavaScript but didn’t realise you could do a comparison variable with name = ()?result1:result2; Which can also be really handy with Booleans.

    Learning lots

    Thanks again.
     
    Web_Dev_Chris, Jun 3, 2019 IP
  5. Web_Dev_Chris

    Web_Dev_Chris Well-Known Member

    Messages:
    222
    Likes Received:
    12
    Best Answers:
    1
    Trophy Points:
    105
    #5
    I was able to achieve what I wanted, code below:
    Basically should I wrap this in a function to be called on page load or just leave it as is at it will execute fine as is on page load.


    <div id="date">
    
    <h1>
      JUNE CALENDAR
    </h1>
    
    <p id="calendar-label">
    June
    </p>
    
    </div>
    HTML:
    //Select DOM HTML Elements
    let divDate = document.querySelector('#date');
    let calLabel = document.querySelector('#calendar-label');
    
    //Date Variable
    let theDate = new Date();
    
    //Array of Months
    let theMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"].map(function(v){
    return v.replace(/\s/g,'').toLowerCase();
    });
    
    //Current Month Variable
    let currentMonth = theMonths[theDate.getMonth()];
    
    //Calendar Label Variable
    let calendarLabel = calLabel.innerHTML.replace(/\s/g,'').toLowerCase();
    
    //Check if calendar Label matches the current month.
    let checkMonth = (calendarLabel == currentMonth)?true:false;
    
    //If statement to disable out-dated calendar.
    if(checkMonth == true){
    divDate.style.display = "block";
    } else {
    divDate.style.display = "none";
    };
    
    
    //console.log(currentMonth);
    //console.log(calendarLabel);
    //console.log(checkMonth);
    
    
    
    
    Code (JavaScript):
    #date{
      position:relative;
      width:500px;
      height: 300px;
      border: 1px solid black;
      margin:auto;
      margin-top: 50px;
      background: silver;
    
    }
    
    #date h1{
    position:absolute;
    top:40%;
    left:55%;
    transform:translate(-50%, -50%);
     
    }
    
    #calendar-label{
      display:none;
    }
    Code (CSS):
     
    Web_Dev_Chris, Jun 4, 2019 IP
  6. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #6
    Yes, they're called "ternary operators" and are VERY useful for keeping the code under control. In general your code has a lot of "variables for nothing" and functions for nothing. Unless you plan on re-using your values later in the scripting, I suggest NOT spending time on so much variable creation.

    I'd also suggest:

    1) skip the mostly pointless "let" and instead be sure your entire scope is isolated with a SIF / IIFE (self instancing function / Immediately Invoked Function Expression.) I learned it under the former name long before it became hot and trendy and got the latter/longer name slapped on it, but same thing.

    2) If we have a SIF / IIFE, we can pass document to it. This saves some typing long-run, and actually executes faster as it moves document up the variable search list for the interpreter.

    3) I would suggest using a regex for the search instead of playing with map/replace and all that. Regex is capable of case insensitive searches in JavaScript, you just add "i" to the end. As a String.search can check for the word anywhere in the string, it takes a lot of the matching stuff out of the way. So long as the result != -1 we're good to go.

    4) If you have a bunch of var/let/const in a row, put the command on its own line, then comma delimit them instead of saying it each and every time.

    5) I suggest you avoid innerHTML. 99.99% of the code you see using it is incompetent trash that runs the risk of opening security holes, even when using it to read. The correct property you're looking for is 'Node.textContent'. The only issue is that textContent doesn't exist in older browsers. Most consider this a non-issue in 2019, but if you REALLY care the IE8/earlier equivalent is "innerText". (though they're not QUITE the same they'd work well enough here).

    
    (function(d) {
    
    	var
    		now = new Date(),
    		months = [
    			'January', 'February', 'March', 'April', 'May', 'June', 'July',
    			'August', 'September', 'October', 'November', 'December'
    		];
    			
    	d.getElementById('date').style.display =
    		d.getElementById('calendar-label').textContent.search(
    			new RegExp('/(' + months[now.getMonth()] + ')/i')
    		) == -1 ? 'none' : 'block';
    
    })(document);
    
    Code (JavaScript):
    All that said, if the calendar is being built wrong, you probably shouldn't be having the server send it in the first place. In that way, this may not even be JavaScript's job to fix.

    finally if this is indeed a calendar, those tend to be tabular data, meaning whilst the TABLE tag should have an ID there is little reason for the child elements to have classes or ID's apart from code bloat... as such grabbing the table with getElementsById then using querySelector('#date caption') might be the more appropriate approach, (since caption is usually where the month would belong on a calendar) but I'd have to see the markup...

    But remember, proper markup for a calendar is:
    
    <table>
    	<caption>June 2019</caption>
    	<thead>
    		<tr>
    			<th scope="col">Sun</th>
    			<th scope="col">Mon</th>
    			<th scope="col">Tue</th>
    			<th scope="col">Wed</th>
    			<th scope="col">Thu</th>
    			<th scope="col">Fri</th>
    			<th scope="col">Sat</th>
    		</tr>
    	</thead><tbody>
    		<tr>
    			<td colspan="6"></td><td>1</td>
    		</tr><tr>
    			<td> 2</td><td> 3</td><td> 4</td><td> 5</td><td> 6</td><td> 7</td><td> 8</td>
    		</tr><tr>
    			<td> 9</td><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td>
    		</tr><tr>
    			<td>16</td><td>17</td><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td>
    		</tr><tr>
    			<td>23</td><td>24</td><td>25</td><td>26</td><td>28</td><td>28</td><td>29</td>
    		</tr><tr>
    			<td>30</td><td colspan="6"></td>
    		</tr>
    	</tbody>
    </table>
    
    Code (markup):
    If the markup varies significantly from this, you might have bigger fish to fry.
     
    Last edited: Jun 7, 2019
    deathshadow, Jun 7, 2019 IP
  7. Web_Dev_Chris

    Web_Dev_Chris Well-Known Member

    Messages:
    222
    Likes Received:
    12
    Best Answers:
    1
    Trophy Points:
    105
    #7
    Thanks. That’s a very informative reply. The issue is the calendar is a jpeg. I realised I could probably get a name value on the HTML element and match that instead of trying to add it into the webpage.

    Basically I have to upload the calendar but I’m not responsible for creating it. The person that creates it doesn’t always send it on time so if the calendar that is being displayed is still from the previous month I would like it automatically disabled.


    hank
     
    Web_Dev_Chris, Jun 10, 2019 IP