BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
AhmedAl_Attar
Ammonite | Level 13

@Babloo 

As a SAS skilled person working with SAS Viya 3.5, My preference would be

  1. Use the Task Prompts
  2. Optimize my SAS data sets for querying. 

The Task Prompts are more mature and provides lots of functionality out of the box (Stored Process Prompting Framework). It's shortens the development time.

 

But if you are a Web Stack Developer (Web, CSS, JS, Ajax) you may find the developing the HTML page more appealing, but you'll still need to interact with SAS skilled person, and someone who is familiar with how SAS Stored Processes used to work, as they are fundamentally provide the origin of the Task prompts.

 

Just my 2 cents

Babloo
Rhodochrosite | Level 12

@AhmedAl_Attar I agree with you. Even I find easy to work with SAS Viya Task prompts but struggling fetch value from the SAS datasets to show in the prompts.

AhmedAl_Attar
Ammonite | Level 13
"struggling fetch value from the SAS datasets to show in the prompts"
I'm guessing this is due to not having the Library defined when the job executes!?

As I had mentioned before, ask your SAS Viya Administrator to add this library assignment at the Compute Server startup/initialization step.

Typically, the custom library assignment would be placed in this file
/opt/sas/viya/config/etc/workspaceserver/default/autoexec_usermods.sas

Hope this helps
Babloo
Rhodochrosite | Level 12
I'm bit confused now. May I request you to clarify which method or the
document to follow? As few suggested solutions were not working as I
mentioned in the previous posts.

Thanks again for staying with me.
AhmedAl_Attar
Ammonite | Level 13

@Babloo 

Sorry! I feel your pain, so let us reset and start fresh.

Here are what I would like to recommend you do.

  1. Ask your SAS Viya Administrator to add your custom library assignment(s) to the
    /opt/sas/viya/config/etc/workspaceserver/default/autoexec_usermods.sas file, and make sure all your required data sets are stored in the location where the custom library(is) would be pointing to, and everyone has the ability to read these tables/data sets (File permissions set as 644 (rw-r--r--), Directory permissions set as 755 (rwxr-xr-x))
  2. Follow the steps outlined in the Create a SAS Viya Job with a prompt using Task Prompts article, and for clarifications read the online docs SAS Help Center: Overview of the Task Prompting Interface
  3. Test and measure response times, then refine/tune your data if needs be.

Good luck

Babloo
Rhodochrosite | Level 12

@AhmedAl_Attar  I connected with my manager and understood that we need solution using HTML, CSS and JavaScript  with SAS Viya. I'm not sure how to move forward now as we identified the SAS Viya version issue earlier which prevented me to load values in the drop when I followed the reference article which you shared earlier

AhmedAl_Attar
Ammonite | Level 13

@Babloo 

You said "we need solution using HTML, CSS and JavaScript with SAS Viya."

 

In this case for Vanilla HTML/JS you are probably will need to

  1. Read and follow this article Series "Data Entry in SAS Visual Analytics 8.3: Part 1, The basics"
  2. Get familiar with HTML control tags HTML Tutorial (w3schools.com) and JavaScript Ajax AJAX Introduction (w3schools.com)

With this approach, you are writing/composing the HTML output using the SAS language.

Alternatively

  1. Teach yourself React JS React Tutorial (w3schools.com) 
  2. Pick your choice out of these links and follow it as needed
    1. Develop web applications series: Options for extracting data
    2. Rapid SAS App Deployment
    3. Building and Deploying Web Apps With SASjs CLI

If you want my opinion, this could be a lengthy process and involves steep learning curve!

You probably would be better served seeking React JS versed developer(s) to assist you.

 

Good luck

Babloo
Rhodochrosite | Level 12

@AhmedAl_Attar Article which you shared is really helpful. However I'd like to give the little backgroud where I need the help. We already have prompts in SAS Viya Job execution. In order to improve the performance and for better UI I was asked to create the standalone webpage using HTML and CSS.

 

I wrote the HTML code for the prompts where the drop down values are not dependent on the SAS datasets. For few prompts we have numerous values and it is fetching values from SAS datasets. Now I need some help to tackle this scenario? 

Kurt_Bremser
Super User

Write the HTML code manually first, then look how you can populate it from the dataset. To get help, show the manually written HTML, and post the dataset as a data step with datalines, both in code boxes.

Babloo
Rhodochrosite | Level 12

@Kurt_Bremser I don't know how to populate the SAS datsaet values in HTML code, hence this post. Hopefully someone of you can help me to move forward. Here is the code snippet of my HTML code which I wrote manually. Please ignore the silly errors as this is only a snippet for you to undertand.

 

<!DOCTYPE html>
<script type="text/javascript">
  function show_div() {
    document.getElementById('_division_lbl').hidden = false;
    document.getElementById('_division_sel').hidden = false;
  }
  function show_tts() {
    document.getElementById('_dentype_lbl').hidden = false;
    document.getElementById('_dentype_sel').hidden = false;
  }
</script>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SAS Job</title>
    <link rel="stylesheet" href="css/library.css">
  </head>
  <body role="main" class="jobexec_body">
    <script src="index.js"></script>
    <div class="jobexec_header">Management System</div>
    <form class="jobexec_form" action="/SASJobExecution/" target="_tab">
      <input type="hidden" name="_program" value="$PROGRAM$"/>
      <input type="hidden" name="_action" value="execute"/>
      <input type="hidden" name="_output_type" value="ods_html5"/>
      <div class="jobexec_header_2">SAS<sup>®</sup> Job Execution</div>
      <br />
        <div class="divTableHeading">
          <div class="divTableBody">
            <div class="divTableRow">
              <div class="divTableCell"><label for="_rawdata">Raw Data Required:<span class="required-field"></span></label></div>
              <div class="divTableCell"><label for="_demgroup">Group:</label></div>
              <div class="divTableCell"><label for="_division_sel" id="_division_lbl" hidden>Division:<span class="required-field"></span></label></div>
              <div class="divTableCell"><label for="_dentype_sel" id="_dentype_lbl" hidden>Type:<span class="required-field"></span></label></div>
            </div>
          </div>
          <div class="divTableBody">
            <div class="divTableRow">
              <div class="divTableCell">
                <select name="_rawdata" id="_rawdata" class="jobexec_select">
                  <option value="yes" selected>Yes</option>
                  <option value="no">No</option>
                </select>
              </div>
              <div class="divTableCell">
                <select name="_demgroup" id="_demgroup" class="jobexec_select" onchange="show_div()">
                  <option value="crm" selected>CRM</option>
                  <option value="tts">Sales</option>
                </select>
              </div> 
              <div class="divTableCell">
                <select name="_division" id="_division_sel" class="jobexec_select" onchange="show_tts()" multiple hidden>
                  <option value="ep">sample1</option>
                  <option value="es">sample2</option>
                  <option value="ic">sample3</option>                  
                </select>
              </div>
              <div class="divTableCell">
                <select name="_dentype_sel" id="_dentype_sel" class="jobexec_select" hidden>
                  <option value="tts" selected>Sales</option>
                </select>
              </div>
            </div>
          </div>
        </div>
        <br />	  
    <label for="_odsstyle" >ODS style:</label>
    <select name="_odsstyle" id="_odsstyle" class="jobexec_select">
      [More values here]
      <option value="HTMLBlue" selected>HTMLBlue</option>
      [More values here]
    </select>
  
  <!--<input type="checkbox" name="blanks" id="blanks" value="ExcludeBlanks"
    class="jobexec_input_checkbox"/>
  <label for="blanks">Exclude blank macro variables from the report.</label>-->  
      <br/>
      <hr size="1"/>
      <input type="submit" value="Run Job" class="jobexec_input_submit"/>
      <input type="checkbox" name="_debug" id="_debug" value="log" 
        class="jobexec_input_checkbox"/>
      <label for="_debug">Show SAS Log</label>
    </form>
  </body>
</html>

Now assume I want to introduce some prompts (e.g. product, model) in this HTML code which takes values from SAS dataset, then how to do this?  My dataset looks like this.

 

If I choose one product from the 'product' prompt, then corresponding model number should display in next prompt, 'model'. 

 

Product Model
Electronics 1
Electronics 2
Electronics 3
Electrical 7
Electrical 9
Medical 6
Medical 10

 

P.S. I'm sorry for not sending the datastep with datalines and it is due to weekend SAS outage for license renewal.

Babloo
Rhodochrosite | Level 12

@Kurt_Bremser It will look like this if I write manually. Actual SAS dataset set has over 10K rows and it will be refreshed often by other SAS programs. Hence I want to fetch the prompt values from SAS dataset.

 

<div class="divTableCell"></div>
    <div class="divTableHeading">
      <div class="divTableBody">
        <div class="divTableRow">
          <div class="divTableCell"><label for="cer_ttf_casnomap">Product</label></div>
          <div class="divTableCell"><label for="ctr_ttf_casnomap">Model</label></div>
          <div class="divTableCell"><label for="act_ttf_casnomap">Account(TTS Cascading/No Mapping)</label></div>          		  
        </div>
      </div>
      <div class="divTableBody">
        <div class="divTableRow">
          <div class="divTableCell">
            <select name="cer_ttf_casnomap" id="cer_ttf_casnomap" class="jobexec_select" multiple>
              <option value="selection1">Electronics</option>
              <option value="selection2">Electrical</option> 
              <option value="selection2">Medical</option>   			  
            </select>
          </div>
          <div class="divTableCell">
            <select name="ctr_ttf_casnomap" id="ctr_ttf_casnomap" class="jobexec_select" multiple>
              <option value="selection1">1</option>
              <option value="selection2">2</option>
              <option value="selection2">3</option>
              <option value="selection2">7</option>
              <option value="selection2">9</option>
              <option value="selection2">6</option>
              <option value="selection2">10</option>			  
            </select>
          </div> 
AhmedAl_Attar
Ammonite | Level 13

Hi @Babloo 

Not sure if you looked into the GitHup link that was embedded in the last article link I sent you "Create a SAS Viya Job with a prompt using HTML Prompts"

, but this is what you could have found there

https://github.com/xavierBizoux/SAS/blob/master/jobPrompt/index.html

 

 

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Job with Dynamic prompts</title>
</head>
<script src="/SASJobExecution/resources/sap/ui/thirdparty/jquery.js"></script>
<script src="/SASJobExecution/resources/dynamic.min.js"></script>

1. These two <script src...></script> tags will load custom built JavaScripts that contain all the needed components to populate Html widgets from a SAS data set.

 

2. Here is a sample how SAS data set's values loaded into the HTML Widget, and honors Selection dependency across widgets (Cascading Prompts)

 

        <details>
            <summary>Geography</summary>
            <div>
                <label for="var_origin">Choose a geographic location:</label>
                <select name="var_origin" id="var_origin" data-colname="origin" data-library="SASHELP" data-table="CARS"></select>
            </div>
        </details>
        <details>
            <summary>Car's characteristics</summary>
            <div>
                <label for="var_type">Choose one or multiple car types:</label>
                <select name="var_type" id="var_type" data-colname="type" multiple size="10" data-library="SASHELP" data-table="CARS" data-uses="var_origin"></select>
            </div>
            <div>
                <label for="var_driveTrain">Which kind of drive train do you want:</label>
                <select name="var_driveTrain" id="var_driveTrain" data-colname="drivetrain" data-library="SASHELP" data-table="CARS" data-uses="var_origin, var_type"></select>
            </div>
        </details>

Let me explain

  • Geographic Location: SASHELP.CARS.Origin (id=var_origin)
  • Car Type: SASHELP.CARS.Type (id=var_type) (data-uses="var_origin" ----> Data Filter) Only display types related to selected origin
  • Drive train: SASHELP.CARS.Drivetrain (id=driveTrain) (data-uses="var_origin, var_type" ----> Data Filter) Only display drivetrain related to selected Origin and type(s)

 

With that said, based on your data size, I would highly recommend considering splitting your data based on your desired Selection Navigation Path, in OLAP term, "Drill Hierarchy".

i.e. Rather than keeping one single data set with multiple columns, that you have to keep filtering as you select more and more values for the various columns in the data. Split the data set into multiples of 2-3 columns as you fit, based on how you want your users to navigate the selections.

 

Hint: You can use Proc Summary/Means with the TYPES statement to generate the various aggregations/columns-combination in a single Proc step, then you can use a data step to split it into multiple smaller data sets with Indexes applied to filtering variables where needed.

 

You could ask, "Why should I split the data"?

Well, you don't have to, but here is why you should it consider it:

1. BASE SAS data set can only use single index in its where clause. That index can be simple (single column) / Complex (multiple columns). So as the Filtering/Selection conditions starts to build-up, the underlying query will start to take longer time to get back with the results to populate the HTML widget. This is bad in a Web App!!

2. The only other BASE data set format that can use multiple Indexes in a where clause would be SPDE. You could experiment with copying your data into an SPDE format, and create index on every filtering column. But then you'll have to deal with changing your Back-End ETL/DataPrep routines that manages updates to the data.

 

I recently applied this splitting technique on a Viya Job prompts against a data set that had 6+ millions records, and was 12 GB in size. The Prompts where unusable and users kept complaining on how slow the app was. After re-working the prompts to use multiple split data sets, the prompts started to get populated much faster, and it started to feel more fluid 😊

 

 

AhmedAl_Attar
Ammonite | Level 13

@Babloo 

Sorry, just for clarification. What did you mean by "In order to improve the performance and for better UI I was asked to create the standalone webpage using HTML and CSS."

What does "Standalone Webpage" mean?

  1. Is it external App or still part of SAS Viya & the Job Execution?
    1. If external
      1. Where you hosting & running this HTML Page?
      2. How you planning to interact with the SAS Viya Server?
        1. How you plan to authenticate to the SAS Viya Server
        2. Using Rest API?
        3. Using Job execution to query data?
    2. If part of Viya and Job Execution, then you'll probably can use the article I sent you as kick start for what you want to do

These are just some of the questions an considerations that has to be looked into.

If you are building external Single Page Web App, then I would recommend looking into these links

Hope this helps

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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
  • 66 replies
  • 5360 views
  • 32 likes
  • 5 in conversation