As of December 1, 2020, Focal Point is retired and repurposed as a reference repository. We value the wealth of knowledge that's been shared here over the years. You'll continue to have access to this treasure trove of knowledge, for search purposes only.
Join the TIBCO Community TIBCO Community is a collaborative space for users to share knowledge and support one another in making the best use of TIBCO products and services. There are several TIBCO WebFOCUS resources in the community.
From the Home page, select Predict: WebFOCUS to view articles, questions, and trending articles.
Select Products from the top navigation bar, scroll, and then select the TIBCO WebFOCUS product page to view product overview, articles, and discussions.
Request access to the private WebFOCUS User Group (login required) to network with fellow members.
Former myibi community members should have received an email on 8/3/22 to activate their user accounts to join the community. Check your Spam folder for the email. Please get in touch with us at community@tibco.com for further assistance. Reference the community FAQ to learn more about the community.
Sometime, we see cool posts but not relevant at the time. When we really need them, they are hard to find. I am in a similar situation.
I want my fex to return a long string. Ex, 'abcxyzpqr'. I want to call this fex using Ajax and populate a dropdown. My intention is to load a dropdown fast. I trying to eliminate returning in xml format and avoid looping through the xml.
My question is how to return the value as string from a fex to Ajax.
I have tried 'ON TABLE PCHOLD FORMAT ALPHA'. Didn't work.
Does anyone have an example? Thanks in advance.This message has been edited. Last edited by: FP Mod Chuck,
As far as I know, using an Ajax call requires you to loop through the returned data. The simplest way to populate a list box is to keep it all within WebFOCUS, though this won't work using the GUI HTML Composer.
SET HOLDLIST=PRINTONLY
TABLE FILE CAR
SUM
COMPUTE OPTION_HTML/A100 =
'<option value="' | COUNTRY || '">' || COUNTRY || '</option>';
BY COUNTRY NOPRINT
ON TABLE HOLD AS HCOUNTRYOPT
END
-RUN
-HTMLFORM BEGIN
<html>
<head>
<title>test</title>
</head>
<body>
<select id='country' name='country'>
!IBI.FIL.HCOUNTRYOPT;
</select>
</body>
</html>
-HTMLFORM END
Francis
Give me code, or give me retirement. In FOCUS since 1991
Production: WF 7.7.05M, Dev Studio, BID, MRE, WebSphere, DB2 / Test: WF 8.1.05M, App Studio, BI Portal, Report Caster, jQuery, HighCharts, Apache Tomcat, MS SQL Server
I want to call this fex using Ajax and populate a dropdown. My intention is to load a dropdown fast. I trying to eliminate returning in xml format and avoid looping through the xml.
I've NEVER seen XML parsing be the bottleneck in loading drop downs unless there are thousands of options. Not to mentions that you are going to have to loop or split or whatever regardless of the response.
How many option values are you expecting?
"There is no limit to what you can achieve ... if you don’t care who gets the credit." Roger Abbott
The last level in the 3 chained controls can have lot of records based on the selection. It is taking lot of time. Hence, I am trying to improve the speed by sending all string with options lines instead of xml.
When I get to that point where a drop list have to many options and takes to long to load I get out of the "auto IBI chaining" feature and do it myself using js.
Let say I have 3 DL that needs to be chained together. 1- I create 3 fex on the RS that create each their own XML data for their own DL. But where the fex B have WHERE clause evaluating a param from fex A and fex C having WHERE clause with param from fex A and B. 2- In HTML I then add the js to populate each DL individually. The controls are not chained together !!!! 3- Add an onchange(event) to DL-1 where it will call the update of DL-2 based on selected values from DL-1. The update of DL-2 will then call the update of DL-3. 4- Add an onchange(event) to DL-2 where it will call the update of DL-3 based on selected values from DL-1 and DL-2.
Using that technique I often go from a DL loading that takes up to 30 second and more to less than few seconds.
And all that still using the XML file format.
I'll make it easy, here sample code for two chained DL
-* File: IBFS:/.../EDA/EDASERVE/APPPATH/sales/daily_sales_dl_site.fex
-DEFAULTH &IBIWF_language = 'en'
SET ASNAMES = ON
-SET &LANG = IF &IBIWF_language EQ 'en' THEN 'EN' ELSE 'FR';
-SET &ALL = IF &LANG EQ 'EN' THEN 'All' ELSE 'Tout';
DEFINE FILE DL_SITE_YARD
TRI /A4 = '1';
TRIA /A4 = '0';
CODE /A10V = SITECODE;
CODEA /A10V = 'FOC_NONE';
LST /A50V = BRANCHNAME_&LANG.EVAL;
LSTA /A50V = '&ALL.EVAL';
END
TABLE FILE DL_SITE_YARD
SUM LSTA AS 'LST'
BY TRIA AS 'TRI'
BY SITECODE
BY CODEA AS 'CODE'
WHERE READLIMIT EQ 1;
WHERE RECORDLIMIT EQ 1;
ON TABLE HOLD
END
-RUN
TABLE FILE DL_SITE_YARD
SUM LST AS 'LST'
BY TRI NOPRINT
BY LST NOPRINT
BY SITECODE NOPRINT
BY CODE AS 'CODE'
ON TABLE PCHOLD FORMAT XML
MORE
FILE HOLD
END
-RUN
-* File: IBFS:/.../EDA/EDASERVE/APPPATH/sales/daily_sales_dl_yard.fex
-DEFAULTH &IBIWF_language = 'en'
-DEFAULTH &SITECODE = '1110'
SET ASNAMES = ON
-SET &LANG = IF &IBIWF_language EQ 'en' THEN 'EN' ELSE 'FR';
-SET &ALL = IF &LANG EQ 'EN' THEN 'All' ELSE 'Tout';
DEFINE FILE DL_SITE_YARD
TRI /A4 = '1';
TRIA /A4 = '0';
CODE /A16V = YARDCODE;
CODEA /A16V = 'FOC_NONE';
LST /A100V = YARDNAME_&LANG.EVAL;
LSTA /A100V = '&ALL.EVAL';
END
TABLE FILE DL_SITE_YARD
SUM LSTA AS 'LST'
BY TRIA AS 'TRI'
BY YARDCODE
BY CODEA AS 'CODE'
WHERE READLIMIT EQ 1;
WHERE RECORDLIMIT EQ 1;
ON TABLE HOLD
END
-RUN
TABLE FILE DL_SITE_YARD
SUM LST AS 'LST'
BY TRI NOPRINT
BY LST NOPRINT
BY YARDCODE NOPRINT
BY CODE AS 'CODE'
WHERE SITECODE EQ '&SITECODE';
ON TABLE PCHOLD FORMAT XML
MORE
FILE HOLD
END
-RUN
-* Within the HTML Embedded JS
// For Site list
var xml20Http = false;
try {
xml20Http = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xml20Http = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e2) {
xml20Http = false;
}
}
if (!xml20Http && typeof XMLHttpRequest != 'undefined') {
xml20Http = new XMLHttpRequest();
}
// For Yard list
var xml25Http = false;
try {
xml25Http = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xml25Http = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e2) {
xml25Http = false;
}
}
if (!xml25Http && typeof XMLHttpRequest != 'undefined') {
xml25Http = new XMLHttpRequest();
}
function onInitialUpdate() {
callSite ("FOC_NONE");
}
function site_onchange(event) {
var eventObject = event ? event : window.event;
var ctrl = eventObject.target ? eventObject.target : eventObject.srcElement;
var siteCd = IbComposer_getCurrentSelection('site');
removeAllOptions(yard);
addOption(yard,"!IBI.AMP.#LOADING;", "FOC_NONE");
callYard (siteCd);
}
function callSite() {
var url = "/ibi_apps/WFServlet?IBIF_ex=daily_sales_dl_site.fex&IBIAPP_app=sales";
xml20Http.open("GET", url, true);
xml20Http.onreadystatechange = UpdateSite;
xml20Http.send(null);
}
function UpdateSite() {
if (xml20Http.readyState == 4)
{
if (xml20Http.status == 200 )
{
var responseXML = xml20Http.responseXML;
var trs = responseXML.getElementsByTagName("tr");
document.getElementById("site").options.length = 0;
for (r = 0; r < trs.length; r++) {
var tds = trs[r].getElementsByTagName("td");
document.getElementById("site").options[r] = new Option(tds[1].firstChild.nodeValue, tds[0].firstChild.nodeValue);
}
if (trs.length > 0)
{
document.getElementById("site").options[0].selected=true;
document.getElementById("site").style.color='black';
var siteCd = IbComposer_getCurrentSelection('site');
removeAllOptions(yard);
addOption(yard,"!IBI.AMP.#LOADING;", "FOC_NONE");
callYard (siteCd);
}
else
{
removeAllOptions(site);
addOption(site,"!IBI.AMP.#NOTFOUND;", "NODATA");
showAlertNoData("site");
}
}
}
}
function callYard(siteCd) {
var url = "/ibi_apps/WFServlet?IBIF_ex=daily_sales_dl_yard.fex&IBIAPP_app=sales&SITECODE=" + escape(siteCd);
xml25Http.open("GET", url, true);
xml25Http.onreadystatechange = UpdateYard;
xml25Http.send(null);
}
function UpdateYard() {
if (xml25Http.readyState == 4)
{
if (xml25Http.status == 200 )
{
var responseXML = xml25Http.responseXML;
var trs = responseXML.getElementsByTagName("tr");
document.getElementById("yard").options.length = 0;
for (r = 0; r < trs.length; r++) {
var tds = trs[r].getElementsByTagName("td");
document.getElementById("yard").options[r] = new Option(tds[1].firstChild.nodeValue, tds[0].firstChild.nodeValue);
}
if (trs.length > 0)
{
// check if only two options exist and if so, then remove the ALL option
if (trs.length == 2)
document.getElementById("yard").remove(0);
document.getElementById("yard").options[0].selected=true;
document.getElementById("yard").style.color='black';
}
else
{
removeAllOptions(yard);
addOption(yard,"!IBI.AMP.#NOTFOUND;", "NODATA");
showAlertNoData("yard");
}
}
}
}
function showAlertNoData(errctrl)
{
document.getElementById(errctrl).style.color='red';
alert("!IBI.AMP.#DLNODATA;");
return false;
}
// To add an option text and value to a dropdown list
function addOption(selectbox,text,value)
{
var optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;
selectbox.options.add(optn);
}
// To delete all options text and value from a dropdown list
function removeAllOptions(selectbox)
{
var i;
for(i=selectbox.options.length-1;i>=0;i--)
{
selectbox.remove(i);
}
}
This message has been edited. Last edited by: MartinY,
WF versions : Prod 8.2.04M gen 33, Dev 8.2.04M gen 33, OS : Windows, DB : MSSQL, Outputs : HTML, Excel, PDF In Focus since 2007
Posts: 2409 | Location: Montreal Area, Qc, CA | Registered: September 25, 2013
Originally posted by MartinY: When I get to that point where a drop list have to many options and takes to long to load I get out of the "auto IBI chaining" feature and do it myself using js.
@MartinY - Thank you for the example. I am doing more or less the same with JQuery. I was hoping not to loop through the returned data from fex. Instead, wanted to build the string consisting of option and the item data in the fex. If I return the same to the front end then I need not loop. This way I simple read the string to populate the dropdown control.
Originally posted by Francis Mariani: As far as I know, using an Ajax call requires you to loop through the returned data. The simplest way to populate a list box is to keep it all within WebFOCUS, though this won't work using the GUI HTML Composer.
@Francis Mariani - Thank you for the suggestion. Your example would work if the html is rendered via fex. However, in this case, we want to utilize the composer as html has many controls. We are loading all the controls using Ajax and custom fex. Not using GUI resource, chaining, etc.
Originally posted by WFConsultant: The last level in the 3 chained controls can have lot of records based on the selection. It is taking lot of time. Hence, I am trying to improve the speed by sending all string with options lines instead of xml.
What is "lot of records"?
Are the values static or dynamic? IOW's, do the values change based on the user or are they the same for all users? Does it take a long time for the screen to render when it is called, or does it take a long time for the chains to get refreshed one an upstream selection is made?
"There is no limit to what you can achieve ... if you don’t care who gets the credit." Roger Abbott
Originally posted by dhagen: What is "lot of records"?
The last level can have up to 6K items depending on the prior selection. It is taking about 4 to 5 seconds with Ajax load. Values can change based on the user. All of that is handled in the fex that is retrieving the data. Individually when run the fex it takes about 2 sec. Then, when it sent back as xml. Then, I loop through the xml to populate the dropdown.
Having more than 100 options in a select list is crazy enough, 6k is bonkers. Francis is correct in saying that will be slow in any circumstance. Pretty sure some platforms go as far as limiting the number of options in a list box for this very reason. I'd say the fact it even works is a plus and you might have to work around the speed issue.
JC WebFOCUS Dev Studio / App Studio 8.2.01 Windows 7