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?
Related
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?
I am putting together an email template for electronic deposits. All the email will do is let students and customers know that an electronic payment has been made out to them and display the items. The information should look like this:
Date | Invoice# | Description | Amount
12/20/2019 | 01 | Refund | $33
| 02 | Refund | $44
(Since the Date is the Date of Deposit, it will be the same for all the listed invoices.)
There can be up to 30 potential rows like this, one for each invoice number. The trouble is, though, that not all of those rows will have values.
So, for a student or customer that is receiving payment for nine invoices (nine rows), we wouldn't want to show the remaining twenty-one empty rows.
The question, then, is how might we hide these remaining empty rows? Since this will be an email template, I don't know if JavaScript or jQuery would work, since from what I've read, they get blocked by the email system for security reasons.
I thought I might also try converting it from HTML to .NET, and seeing if I could use a Repeater, but I don't know if that would work either.
If the information can be of any use, this email is getting it's information using a T-SQL query. I imagine I can modify it to just not return NULL results, but that still leaves the issue of the empty rows on the front-end side...
Any assistance or insight would be appreciated. I'll post URLs for resources I've read so far below. :)
Thanks!
Resources:
hide table rows if empty
Generating row dynamically in javascript?
Is JavaScript supported in an email message?
https://kb.mailchimp.com/campaigns/design/limitations-of-html-email
Updated - 3/19/2018
Below is the function I am using:
<script>
$(function(){
$('.row').each(function(){
if($(this).val().trim()=='')
$(this).hide();
})
});
</script>
Since the HTML file is quite long, I don't know that I should post the whole thing inline. Below is the HTML for the first three rows in the table:
<table class="w580" border="0" cellpadding="0" cellspacing="0" width="580">
<tbody><tr>
<td class="w580" width="580">
<div class="article-content" align="left">
<multiline label="Description">
<p style="text-align: center; color: #e54a3d; font-size: larger;">
<strong>
Accounts Receivable Hold Notice
</strong></p>
<hr style="margin: 0 0 1.625em;"/>
<p>Dear firstname,</p>
<p></p>
<p>If you have any questions, you may call the Office of Student Financial Services at 573.592.1793</p>
<p>Have a great day!</p>
<p><strong>Check Date:</strong> checkdate</p>
<table width="580" border="1">
<thead>
<tr>
<th width="145" >Invoice</th>
<th width="145" >Description</th>
<th width="145" >Amount</th>
</tr>
</thead>
<tbody>
<tr class="row">
<td>
##invoicenum1##
</td>
<td>
##desc1##
</td>
<td>
##amount1##
</td>
</tr>
<tr class="row">
<td>
##invoicenum2##
</td>
<td>
##desc2##
</td>
<td>
##amount2##
</td>
</tr>
<tr class="row">
<td>
##invoicenum3##
</td>
<td>
##desc3##
</td>
<td>
##amount3##
</td>
</tr>
All of the items surrounded with ##s (for example, ##invoicenum1## ) are the "potential values" that get populated by the results from the database.
So, theoretically, if a field is NULL in the database, it won't put anything there. Then, the jQuery in the head will see that nothing is there and simply hide the row.
My concern, though, is that, if JavaScript and jQuery are blocked by the email clients, that this functionality won't perform.
Updated - 3/21/2018
I've confirmed that the jQuery won't work. I've got the desired visual effect through inline styles - just setting "border: none;" on the individual rows and cells. That way, if it's empty, it just doesn't show...
This works for us, since we have a set maximum number of potential rows (30).
If we wanted to set up a system, though, where the number of rows was determined by the actual number of results returned, any idea how we might do that?
Or do the big companies like Amazon also have a set number of items they'll show when they email you your order details? Maybe they just show you five or six items and tell you "To view your complete order, visit the Orders Page", or something...
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!
I am running into an interesting issue where my Dust.js template is not honoring an exists conditional.
My data looks like this:
{"guaranteedHistory": [
{
"depositDate": "2017-08-31T00:00:00.000-0500",
"interestRate": 515.5,
"maturityDate": "2017-08-31T00:00:00.000-0500",
"beginningBalance": 874757257.4,
"deposits": 4.25,
"transferIn": 75.7,
"investmentReturn": 52.71,
"amtReinvested": 5.5,
"maturityWithdrawal": 6.66,
"surrenderCharge": 7.77,
"endingBalance": 8.88,
"surrenderValue": 5735.56
}
],
}
Template (Doesn't work):
{?guaranteedHistory}
<table id="a">
<thead>
<tr>
<th> </th>
<th>What happened this period</th>
<th></th>
</tr>
</thead>
</table>
{:else}
<table id="b">
<thead>
<tr>
<th>Deposits</th>
<th>Dividends</th>
<th>Investment return</th>
</tr>
</thead>
</table>
{/guaranteedHistory}
The issue is that no matter what happens, the template will only display everything in the else conditional UNLESS inside the exists I output a value inside guaranteedHistory...
Template (This works):
{?guaranteedHistory}
{guaranteedHistory[0].depositDate}
<table id="a">
<thead>
<tr>
<th> </th>
<th>What happened this period</th>
<th></th>
</tr>
</thead>
</table>
{:else}
<table id="b">
<thead>
<tr>
<th>Deposits</th>
<th>Dividends</th>
<th>Investment return</th>
</tr>
</thead>
</table>
{/guaranteedHistory}
I was not able to find any way to get around this. I also could not duplicate this issue within a dev mode on dustjs.com, it works correctly there. Could anyone please help or tell me what could possibly be going wrong based on the provided information?
There is no reason that this shouldn't work correctly as you've described it. In addition, the compiled body_0 you provided is definitely correct.
So, if this really is happening, the only possible reasons are:
You aren't rendering the template you think you are. This seems unlikely if you're compiling and rendering yourself.
The value of guaranteedHistory isn't what you think it is. Because you are testing your template on http://www.dustjs.com/test/test.html and it works properly there, this is my guess.
So, this suggests to me that you have a race condition, and that you're trying to render with guaranteedHistory before it has been set (via some callback, Promise, etc).
Dust 2.7.2 doesn't resolve Promises in exists blocks so this may be what you're hitting. You can use the trunk tip if you need to until 2.8 is released.
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>