BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.

Hi, I am a new SAS user. I was tasked to create a form to allow users to either submit their queries through text or filter data variables. The expected result will be for the form to display the 2 radio buttons first before either a text field comes out if the "Text" radio button is chosen, or a dropdown list comes out if the "Table" radio button is chosen. However, everything came out at once since the Javascript functions are not being displayed. This was not the case when I did the code for the form on Visual Studio as everything is being displayed.

 

My SAS code is as shown below:

proc sql;
	create table table_list as select * from dictionary.tables where 
		LIBNAME='PUBLIC';
quit;

data _null_;
	set table_list end=alldone;
	file _webout;

	if _n_=1 then
		do;
			thissrv="&_URL";
			thispgm="&_program";
			put '<html>';
			put '<head>';
			put '<meta name="viewport" content="width=device-width,initial-scale=1.0">';
			put '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">';
			put '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>';
			put '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>';
			put '</head>';
			put '<body onload="inputQuery()">';
			put '<h3>Query and Suppress Data</h3>';
			put '<FORM id="f1" ACTION="' thissrv +(-1) '" method=get  target="frame2">';
			put '<input type="hidden" name="_program" value="' thispgm +(-1) '">';
			put '<input type="hidden" name=reqtype value="create_input">';
			put '<input type="hidden" name=_ODSDEST value="html">';
			put '<div class="form-group row justify-content-center">';
			put '<div class="col-sm-6">';
			put '<div class="form-check form-check-inline">';
			put '<input type="radio" class="form-check-input" id="text" name="query" value="Text" onclick="showInput()" />';
			put '<label class="form-check-label" for="text">Text</label>';
			put '</div>';
			put '<div class="form-check form-check-inline">';
			put '<input type="radio" class="form-check-input" id="table" name="query" value="Table" onclick="showInput()" />';
			put '<label class="form-check-label" for="text">Table</label>';
			put '</div>';
			put '</div>';
			put '</div>';
			put '<script>
            			function inputQuery() {
                			document.getElementById("query_text").style.display = "none";
                			document.getElementById("subtext").style.display = "none";
                			document.getElementById("query_table").style.display = "none";
                			document.getElementById("subtable").style.display = "none";
                			document.getElementById("submit").style.display = "none";
                			document.getElementById("reset").style.display = "none";
                			document.getElementById("refresh").style.display = "none";
            			}

            			function showInput() {
                			var result = document.querySelector("input[name="query"]:checked").value;
                			if (result == "Text") {
                    				document.getElementById("query_text").style.display = "block";
                    				document.getElementById("subtext").style.display = "block";
                    				document.getElementById("query_table").style.display = "none";
                    				document.getElementById("subtable").style.display = "none";
                    				document.getElementById("submit").style.display = "block";
                    				document.getElementById("reset").style.display = "block";
                    				document.getElementById("refresh").style.display = "none";
                			}
                			else if (result == "Table") {
                    				document.getElementById("query_text").style.display = "none";
                    				document.getElementById("subtext").style.display = "none";
                    				document.getElementById("query_table").style.display = "block";
                    				document.getElementById("subtable").style.display = "block";
                  				document.getElementById("submit").style.display = "none";
                    				document.getElementById("reset").style.display = "none";
                    				document.getElementById("refresh").style.display = "block";
                			}
            			}
        			</script>';
				put '<div class="form-group row justify-content-center">';
				put '<label class="control-label col-sm-2" id="subtext">Submit Query:</label>';
				put '<div class="col-sm-6">';
				
				put '<textarea name="query_text" id="query_text" value="" cols="30" rows="5" placeholder="Enter Query" class="form-control"></textarea>';
				put '</div>';
				put '</div>';
				put '<div class="form-group row justify-content-center b4-form-inline">';
				put '<div class="text-left">';
				put '<button id="submit" formaction="' thissrv +(-1) 
					'" formtarget="frame3" type="submit">Submit Query</button>';
				put '</div>';
				put '<div class="text-right">';
				put '<input id="reset" type="reset" value="Reset">';
				put '</div>';
				put '</div>';
				put'<br>';

				put '<FORM id="f2" ACTION="' thissrv +(-1) '" method=get  target="frame2">';
				put '<input type="hidden" name="_program" value="' thispgm +(-1) '">';
				put '<input type="hidden" name=reqtype value="create_input">';

				put '<div class="form-group row justify-content-center">';
				put '<label class="control-label col-sm-2" id="subtable">Select a Table:</label>';
				put '<br>';
				put '<div class="col-sm-4">';
				put '<select class="form-control" id="query_table">';
				put '<OPTION VALUE="" selected></option>';
				put '<OPTION VALUE="SUPPRESSED_DATA">SUPPRESSED_DATA</option>';
				put '<OPTION VALUE="PREPARATION_DATA">PREPARATION_DATA</option>';
			end;
		if alldone then
			do;
				put '</select>';
				put '</div>';
				put '</div>';
				put '<div class="form-group row justify-content-center">';
				put '<div class="col-sm-4">';
				put '<input id="refresh" type="submit" value="Refresh Variable List">';
				put '</div>';
				put '</div>';
				put'<br>';
				put '</form>';
				put '</body>';
				put '</html>';
			end;
	run;

The output screen if running from SAS:

Actual output (1).pngActual output (2).png

If my Javascript codes are being run, it should look like this:

Expected output (1).pngExpected output (2).pngExpected output (3).png

Is it better if I use SAS programming language to solve this problem? Or if there is any other way to import my Javascript code? I cannot link this to a new embedded form because my full SAS code requires 2 HTML codes to run properly.

 

Can anyone tell me a way to solve this? Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
AllanBowe
Barite | Level 11

Hi - I had to rush to a meeting and hadn't updated the gist.

 

Here you go:  https://gist.github.com/allanbowe/1dbb3cc64e430d2f385bb26d27773019

 

There was another issue with apostrophes here:  `querySelector("input[name="query"]:checked").value;`

This is also fixed.

Screenshot 2020-03-18 at 10.50.44.png

 

These things are MUCH easier to spot in a web IDE.  If you send me a PM, I'd be happy to jump on a video call and give you a 20 minute 'quick start' into building web apps on SAS.

 

/Allan

/Allan
SAS Challenges - SASensei
MacroCore library for app developers
SAS networking events (BeLux, Germany, UK&I)

Data Workflows, Data Contracts, Data Lineage, Drag & drop excel EUCs to SAS 9 & Viya - Data Controller
DevOps and AppDev on SAS 9 / Viya / Base SAS - SASjs

View solution in original post

3 REPLIES 3
AllanBowe
Barite | Level 11

Welcome to the world of building web apps on SAS - probably the best way to use SAS (imho)!

 

I reproduced your code as a stored process using the MacroCore library here: 

https://gist.github.com/allanbowe/4e2bb87250450381389e74f8e45a3a02.js

 

I then opened Developer tools (F11) and saw the following errors:

 

Screenshot 2020-03-18 at 08.18.17.png

After a trying a few things, I realised you were hit with probably one of the hardest-to-detect errors in SAS.

 

The line length limit!   Your program editor has a limit to the number of characters in a line of code.  Anything longer than approx 1000, and your code is just truncated, without a message.

 

I split your code into several put statements and it worked:

 

Screenshot 2020-03-18 at 08.46.54.png

 

 

The final code is here:  https://gist.github.com/allanbowe/1dbb3cc64e430d2f385bb26d27773019

 

For the future, you will find it much easier to build web apps on SAS using the Web Server.  Simply put your html / css/ js files in the static content folder, and call SAS using an adapter (such as SASjs).  An example (minimal) seed app for doing this is provided here:  https://github.com/macropeople/minimal-seed-app

 

A full React example is here:  https://github.com/macropeople/react-seed-app

 

And here's a video of putting it together in 5 mins:  https://www.youtube.com/watch?v=vSNBea_M8yU

 

An end to end guide for building web apps on SAS is available here:  https://sasjs.io

 

Now, in case you are saying - "I don't have access to the SAS Web Server and my admin will never leave his cave to even respond to that request" - there is another solution, that doesn't involve hours of copy pasting put statements and apostrophes.

 

That is - sasjs-cli

 

This is a client tool that handles the compilation of SAS (backend) data services, and also FRONTEND files such as HTML / CSS / Javascript.  It will wrap your frontend files in put statements, and automatically 'split' them to prevent lines over 120 characters.  You can work locally in your favourite editor, with all your SAS / frontend files tidily arranged in your GIT repo, and simply build / deploy when ready.  The pre-requisite - NodeJS (version 12+).

 

The workflow:

 

# install the tool globally (one time)

npm install -g sasjs-cli

# create a new project

sasjs create myapp

cd myapp

# all your SAS files are under sas/services/(subfolder)
# your frontend goes in a folder in the root
# update sas/config.json to set streamweb:true and websourcepath:yourwebfolder

sasjs build

that's it - you now have a deploy script under the `sasbuild` folder that will stream your frontend, and connect it to your backend services.

 

Enjoy.

/Allan
SAS Challenges - SASensei
MacroCore library for app developers
SAS networking events (BeLux, Germany, UK&I)

Data Workflows, Data Contracts, Data Lineage, Drag & drop excel EUCs to SAS 9 & Viya - Data Controller
DevOps and AppDev on SAS 9 / Viya / Base SAS - SASjs
Ezer_Tien
SAS Employee

Hi Allan,

 

Your code is still not working on my server. I still got the same output as the first output that I pasted.

I compared the final code with my code, but I didn't see any new put statements.

The output that you pasted isn't my expected output. There should only be radio buttons on the webpage if neither radio button has been selected, as seen in the output that is produced from my Visual Studio code (the second one).

Thanks for your help and advice. I will try this on my existing project and see how it goes.

AllanBowe
Barite | Level 11

Hi - I had to rush to a meeting and hadn't updated the gist.

 

Here you go:  https://gist.github.com/allanbowe/1dbb3cc64e430d2f385bb26d27773019

 

There was another issue with apostrophes here:  `querySelector("input[name="query"]:checked").value;`

This is also fixed.

Screenshot 2020-03-18 at 10.50.44.png

 

These things are MUCH easier to spot in a web IDE.  If you send me a PM, I'd be happy to jump on a video call and give you a 20 minute 'quick start' into building web apps on SAS.

 

/Allan

/Allan
SAS Challenges - SASensei
MacroCore library for app developers
SAS networking events (BeLux, Germany, UK&I)

Data Workflows, Data Contracts, Data Lineage, Drag & drop excel EUCs to SAS 9 & Viya - Data Controller
DevOps and AppDev on SAS 9 / Viya / Base SAS - SASjs

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 1825 views
  • 1 like
  • 2 in conversation