Countdown timer when link clicked - javascript

I'm trying to make a countdown timer.
I have a table with several rows and four columns. In column two, I need a timer that starts when you click on a link in column one. When the timer finishes, it will appear "available". Each row needs.
This is what I have.
<table width="798" border="1" cellspacing="15">
<tr>
<th width="302" scope="col">Website</th>
<th width="139" scope="col">Status</th>
<th width="118" scope="col">Time (Minutes)</th>
<th width="146" scope="col">WO</th>
</tr>
<tr>
<td>Don't click here</td>
<td> </td>
<td align="center">5</td>
<td align="center">0.5-1.0</td>
</tr>
<tr>
<td>Don't click me</td>
<td> </td>
<td align="center">720</td>
<td align="center">0.5-1.0</td>
</tr>
<tr>

The way to do this would be setTimeout
While I am not a fan of w3schools, but they do everything in easy to read, so here is the link https://www.w3schools.com/jsref/met_win_settimeout.asp
Also, I am not posting the exact code as you are new to programming, and the best way to learn is to do it yourself.

Steps overview:
In HTML, use onclick and pass this as a parameter to the function.
In JavaScript, define the function and get the element stored in the parameter.
Inside the function define the variable that will store the time remaining (in seconds). If you need many variables at once, store the values inside an object and use as key the id of your html row.
Use setInterval to start a loop that countdowns the variable that stores the time remaining.
Once the variable value reaches 0, display your "Available!" text and clear the interval.
This requires basic knowledge of:
JavaScript
DOM events
Arrays/Objects
Loops (look for window.setInterval() and window.clearInterval())
DOM modification
If you are new to programming it will take you some time to do this, but you will gain a valuable knowledge.
Btw if someone provides you the code working and ready to copy&paste, take your time in understand each line and even write your own implementation based on the provided one.
Good luck!

Related

JS Performance with lots of dynamic data. innerHTML, outerHTML, or textContent

after reading a lot of posts here, I've come to the conclusion that textContent is faster than innerHTML and outerHTML; but what happens when I have a lot of data that needs to be replaced?
I have a table with dynamic second columns such as follows. Keep in mind a JS function will show/hide metric or imperial <span> when clicked.
When a new variant is selected, data in the second cells will change.
<div class="spec-table" id="SpecTable">
<table class="table">
<tr>
<td>dimension_1_title</td>
<td><span class="spec-table_metric">dimension_1_metric</span><span class="spec-table_imperial">dimension_1_imperial</span></td>
</tr>
<tr>
<td>dimension_2_title</td>
<td><span class="spec-table_metric">dimension_2_metric</span><span class="spec-table_imperial">dimension_2_imperial</span></td>
</tr>
<tr>
<td>Other information</td>
<td><span class="spec-table_metric">Other information metric</span><span class="spec-table_imperial">Other information imperial</span></td>
</tr>
</table>
</div>
Would it make sense if I put the entirety of my HTML table into JS variables for each variant and use getElementById(#SpecTable).innerHTML to replace it or use 6 functions to change each <span> individually by using getElementById(#IDs for Spans).textContent?
I'm confused as I may have 5 variants, which means 30 JS variables to collect and match when needed, whereas only 5 JS variables that contain the whole table.
In addition, is it better or worst if I get rid of the <div> and use outerHTML to change the table?
I'm a beginner at JS, and if you have other recommendations, I appreciate your input.

Can't select element on a webpage even though it is present

I am trying to select an element on a table which is on a webpage. The inner text which is on the table is a name of a professor. I am using this line of code to grab the elements.
var tableElementNode = document.querySelectorAll(".section-detail-grid.table-bordered-wrap>tbody>tr>td>div");
And yes it works with the tables on the main webpage and grabs the elements I need. However when i try going on a different course page to grab the elements of another table it does not work even though all the tables have the same format. Its as if the tables are invisible to the code and only grabs the ones on the main webpage.
However every so know and then it grabs all the elements I need on a different course page but on very rare occasions.
The last line on the code below is the element I am trying to grab.
<table class="section-detail-grid table-bordered-wrap">
<thead>
</thead>
<tbody>
<tr data-id="80886" data-index="0" class="section-item section
first linked-section">
<td class="persist row-label">
COP
</td>
<td class=" row-label">
3514
</td>
<td class="persist row-label">
001
</td>
<td class="persist row-label">
Class Lecture
</td>
<td class=" row-label">
<div>Wang, Jing</div>
Someone mentioned that it may be an ajax driven site and thats why its not grabbing all the elements all the time. Ive even tried getting the xpath of that element but it is still not being found. Why is this element invisible to my code?

How would I write a regular expression that captures an HTML Table with a particular class?

I'm trying to write a regular express that will capture an HTML table (and all it table data) that has a particular class.
For example, the table has a recapLinks class, its comprised of numerous table rows and table data and then terminated with . See below:
<table width="100%" class="recapLinks" cellspacing="0">
[numerous table rows and data in the table.]
</td></tr></tbody></table>
I'm using javascript.
The regex to capture this is pretty simple, if you can guarantee that there are never nested tables. Nested tabled become much trickier to deal with.
/<table[^>]*class=("|')?.*?\bCLASSNAMEHERE\b.*?\1[^>]*>([\s\S]*?)</table>/im
For instance, if an attribute before class had a closing > in it, which isn't likely, but possible, the regex would fall flat on it's face. Complex reges can try to prepare for that, but it's really not worth the effort.
However, jQuery all by itself can make this a breeze, if these elements are within the DOM. Regex can be easily fooled or tripped, deliberately or accidentally but that's why we have parsers. JQuery doesn't care what's nested or not within the element. It doesn't care about quote style, multiline, any of that.
$(document).ready(function () {
console.log($("table.myClassHere").prop("outerHTML"))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table class="myClassHere">
<tr>
<td>Book Series</td>
</tr>
<tr>
<td>Pern</td>
</tr>
<tr>
<td>Hobbit</td>
</tr>
</table>
<table class="otherClassHere">
<tr>
<td>Movies</td>
</tr>
<tr>
<td>Avengers</td>
</tr>
<tr>
<td>Matrix</td>
</tr>
</table>

Altering value in one row dependant on another row's value

How do you alter a value in row to update on load dependant on another row's value?
For example in my table I have a column called Room Allocation and another called Action. If a row value Room Allocation column is set to Pending then I want the buttons for that particular row under Action to be Edit and Cancel but if it is anything else (i.e. not Pending) then the buttons should be Edit and Decline.
How can I go about doing this using jQuery? Here is my code below and I've included a fiddle here:
<table id="home_tbl">
<thead>
<tr>
<th>Module Code</th>
<th>Day</th>
<th>Start Period</th>
<th>Length</th>
<th>Room Preference</th>
<th>Room Allocation</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- dummy data starts here -->
<tr>
<td>COA101</td>
<td>Tuesday</td>
<td>11:00</td>
<td>2 hours</td>
<td>B.1.11</td>
<td>Pending</td>
<td><button class="cupid-green">Edit</button>
<button class="cupid-green">Cancel</button></td>
</tr>
<tr>
<td>COA201</td>
<td>Monday</td>
<td>10:00</td>
<td>1 hours</td>
<td>J001</td>
<td>J001</td>
<td><button class="cupid-green">Edit</button>
<button class="cupid-green">Cancel</button></td>
</tr>
<!-- dummy data ends here -->
</tbody>
</table>
How I would approach it depends on a couple of things: 1) what the difference between 'edit' and decline' is, and 2) who the audience is.
First, I assume that 'edit' and 'decline' are separate actions/URL endpoints? That is - the difference is what the button does, not just what the label is?
Next, if your audience is trusted (say, staff using an internal tool), you could include all three buttons in the markup, and show or hide them based on the 'pending' status. This is the easier option, but it won't work if you don't trust your audience.
If you don't trust them, you should never show the buttons to do the incorrect action - if the user has javascript disabled (or purposely disables it), they will be able to send a 'decline' request for rooms/bookings that they shouldn't be able to. In this case, you should create the table on the server, not using javascript/jQuery.
If you let me know that info, I can give you some examples of how to do either option!
Answer for a trusted audience:
OK - here's how to show/hide various buttons based on the status column. We'll use CSS and descendent selectors to do the showing/hiding, which makes the javascript very simple:
Here's the HTML you'll need for each row:
<tr class="booking">
<td>COA101</td>
<td>Tuesday</td>
<td>11:00</td>
<td>2 hours</td>
<td>B.1.11</td>
<td class="status">Pending</td>
<td class="action">
<button class="edit cupid-green">Edit</button>
<button class="decline cupid-green">Decline</button>
<button class="cancel cupid-green">Cancel</button>
</td>
</tr>
And the CSS:
/* Don't show the cancel button for normal rows, or the decline button for pending rows */
tr.booking button.cancel,
td.booking.pending button.decline {
display: none;
}
/* When the row is pending, show the cancel button */
tr.booking.pending button.cancel{
display: inline-block;
}
And finally, the jQuery/JS:
$(function(){
var bookingRows = $('table tr.booking'); //Find all the booking rows
bookingRows.each(function(){
var row = $(this); //Stash a reference to the row
//If you can add a class of 'pending' to the status <td>, this becomes even cleaner and nicer...
if (row.find('td.status').text().toLowerCase() == 'pending') { //Check the contents of the status column
row.addClass('pending'); //Add a class to the row so the CSS can do its thing...
}
});
});
To be honest, if you can make any changes on the server-side (which I hope you can, to make the JS easier as per my example), you can also just have the server create the rows with the correct buttons in the first place. Is there a reason this needs to be done on the client with JS?
Let me know if you need more detail or get stuck - I haven't tested this code, but it should work no problems.

XForms repeat - JavaScript error

I am using XForms to build a web application with XML-DB eXist-db as backend.
eXist transforms the XForms code into HTML and JavaScript.
First of all I got two instances:
<xf:instance xmlns="" id="results">
<result>
<ServiceDefinition>
<InventoryLabel LastChange="2012-01-24">SVC380712435</InventoryLabel>
<SystemName IPaddress="111.222.333.123">XXX</SystemName>
<Service ServiceCategory="Internetservice">Web-Server</Service>
<OSClass OperatingSystem="CentOS">UNIX</OSClass>
<SystemType Manufacturer="VMware">VM</SystemType>
<Backup/>
<Location SystemContact="Max Power" AdminGroup="power">N22</Location>
</ServiceDefinition>
....
</result>
</xf:instance>
<xf:instance xmlns="" id="domain">
<system name="XXX">
<NIC MAC="00-50-56-ae-00-3c"
time="1329167846" missed="1323350247" state="inactive"
IP="111.222.333.123" LAN="Test"/>
</system>
...
</xf:instance>
I want to build a table using xf:repeat to iterate through all the <ServiceDefinition> Elements in the 'results' instance. Every row contains a 'Status' column where I want to put the related 'state' information from the 'domain' instance.
This is the XForms code for the table:
<div class="table">
<table border="0">
<thead>
<tr>
<th class="sysName">Hostname</th>
<th class="services">Service</th>
<th class="os">OS Class</th>
<th class="location">Location</th>
<th class="link">Details</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<xf:repeat nodeset="instance('results')/result/ServiceDefinition" id="link-repeat">
<tr>
<td class="sysName"><xf:output ref="SystemName" /></td>
<td>
<xf:repeat nodeset="Service" class="row">
<div>
<xf:output ref="."/>
</div>
</xf:repeat>
</td>
<td class="os"><xf:output ref="OSClass"/> </td>
<td class="location"><xf:output ref="Location" /></td>
<td class="link">
<xf:trigger submission="view-entry" appearance="minimal" class="url">
<xf:label>View</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('URL-container')"
value="concat('serviceDetails.xql?svc=', instance('results')/result/ServiceDefinition[index('link-repeat')]/InventoryLabel)"/>
<xf:load ref="instance('URL-container')" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:output ref="instance('domain')/system[#name = instance('results')/result/ServiceDefinition[index('link-repeat')]/SystemName]/NIC/#state" />
</td>
</tr>
</xf:repeat>
</tbody>
</table>
</div>
The problem seems to be this part:
<td>
<xf:output ref="instance('domain')/system[#name = instance('results')/result/ServiceDefinition[index('link-repeat')]/SystemName]/NIC/#state" />
</td>
Is there something wrong with this expression? I want to get the state attribute of the system that matches the current node in the repeat statement.
However when I load the page and the 'results'-instance consist of many items I get a Javascript error:
A script on this page may be busy, or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete.
Script: http://test:8080/exist/xforms/xsltforms/xsltforms.js:771*
The line (in this case 771) always differs.
When the result instance is very small (up to about 20 Elements) it works as expected.
Any help or suggestion appreciated, I am new to all this, so please be patient.
Because XSLTForms has its own XPath engine written in JavaScript, browsers might be slow to evaluate expressions requiring to navigate through a lot of nodes, especially old versions of Internet Explorer.
Performance has been improved recently and you should try with latest build in SVN repository of XSLTForms at sourceforge.net.
Using the id() function is a possibility to heavily reduce evaluation time.
There is also an XSLTForms specific extension to indicate whether an instance contains only readonly data.
Did you try the Profiler (press F1 first) to have time measures?

Categories

Resources