Using Ajax to populate Apex items on the fly

Published in APEX by Sam Khalaf Monday July 21, 2008

 Overview

In this example, we will demonstrate how Ajax can be use to efficiently populate a select list item in an Apex page on the fly “at run time”. Of course, this can be also done by using some simple JavaScript code BUT Ajax will be more efficient because it does not require reloading the whole Apex page every time the JavaScript event is fired. On the other hand, using just JavaScript will require the entire Apex page to reload, which is not a good practice in today’s dynamic world.

Imagine an Apex form that contains 100 items (Text fields, Select lists, Radio buttons, Check boxes), and that there is a JavaScript event defined for one item. The event dynamically sets the value of another item in that form. Every time this event is fired, Apex will need to reload the entire form and re-populate all fields with their old values (if any); this can be time consuming and may also cause some issues “side effects”.

 Example:

Consider the following sample table that basically contains data about movies, and categorize movies into different Genres.

 

MOVIE_ID   

  GENRE_ID  

  GENRE    

MOVIE_NAME

 

1

1

Action

 Romeo Must Die

 

2

2

Comedy

 Meet Dave

 

3

2

Comedy

 Kit Kittredge an American Girl

 

4

1

Action

 Wanted

 

5

3

Drama

 Hancock

 

6

1

Action

 Dark Knight

     row(s) 1 - 6 of 6

 Requirements:

 We need to create a simple Apex page with the following items:
- A select list that contains all the movies (Movie_name)
- A select list that contains the movies’ genres (Genre)
- A text field that represents the genre ID ( example: 1,2 or 3) .

The behavior of these items should be as follows:
- When the value of the Genre select list is changed, the Movies’ select list is auto populated with the corresponding movie(s) that belong to the selected genre.
-When the value of the Genre ID Text field is changed (1,2 or 3), the Movies’ select list is auto populated with the corresponding movie(s) that belong to the selected genre ID.

Implementation: 

1) Create the Genre ID text field (P1_GENRE_ID) and add the following code to the HTML Form Element
    Attributes
:

    
onKeyUp=get_List_XML (this,’ P1_MOVIE_LIST ‘)”  

2) Create the Genre select list (P1_GENRE_LIST)  and add the following code to the HTML Form Element   
       Attributes:
    
    
    
onchange=get_List_XML (this,’P1_MOVIE_LIST‘)”   

    And this code to the list of values definition:

    select distinct  genre display_val,genre_id return_val
    from movies

 3) Create the Movies select list (P1_MOVIE_LIST) and add the following code to the list
    of values definition:

    select movie_name, movie_id
   from movies
   where genre_id= :P1_GENRE_ID

4) Create an On Demand Process (POPULATE_LIST_XML) as follows:

declare 
l_counter number;  
l_o_name  varchar2(2000);  
begin  
    owa_util.mime_header(’text/xml’, FALSE );   
    htp.p(’Cache-Control: no-cache’);   
    htp.p(’Pragma: no-cache’);   
    owa_util.http_header_close;  
    htp.prn(’<select>’);  
     for rec in (select “MOVIES”.”GENRE” as “GENRE”,   
      “MOVIES”.”MOVIE_NAME” as “MOVIE_NAME”,   
      “MOVIES”.”MOVIE_ID” as “MOVIE_ID”   
       from “MOVIES” “MOVIES” 
       where “MOVIES”.”GENRE_ID” = :TEMP_ITEM)  
      loop  
       htp.prn(’<option value=”‘ || rec.movie_id || ‘”>’ || rec.movie_name || ‘</option>’);  
     end loop;   
      htp.prn(’</select>’);  
end;

5) Add the following JavaScript code to the source of any exiting HTML region in the page:

 <center><b>This example demonstrates the use of Ajax to dynamically populate a select list on the fly.</center><br>

Type in the Genre ID in the Genre ID text field or select a Genre from the Genre select list <br> to automatically populate the Movies list (( without re-loading this page! ))

<br><br>
<script language=”JavaScript1.1″ type=”text/javascript”>   
 function get_List_XML (source_item,target_item){    
    var v_Target = html_GetElement(target_item);
    var v_Source = html_GetElement(source_item);
    var ajaxResult = new htmldb_Get
    (null,&APP_ID.,’APPLICATION_PROCESS=POPULATE_LIST_XML’,0);  
   
ajaxResult.add(’TEMP_ITEM’,source_item.value);  

    var v_result_xml = ajaxResult.get(’XML’);  
   
if(v_Source == document.getElementById(’P1_GENRE_ID’) )
   
document.getElementById(’P1_GENRE_LIST’).selectedIndex=0;
   
else
   
document.getElementById(’P1_GENRE_ID’).value=”;

    if(v_result_xml && v_Target){
    
var options_Contents = v_result_xml.getElementsByTagName(”option”);
    v_Count = options_Contents.length;
    v_Target.length = 0;     for(var i=0;i<v_Count;i++) {
      var v_opt_xml = v_result_xml.getElementsByTagName(”option”)[i];   
      writeToSelectList (v_Target, v_opt_xml.getAttribute
      (’value’),v_opt_xml.firstChild.nodeValue)  
}   
    }   
 }  

   function writeToSelectList(target_item, option_val, option_content) {   
    var v_Opt = document.createElement(”option”);   
    v_Opt.option_value = option_val;  

    if(document.all){ 
        target_item.options.add(v_Opt);   
        v_Opt.innerText = option_content;   
     } else {   
       v_Opt.appendChild(document.createTextNode(option_content));   
       target_item.appendChild(v_Opt);   
    }   
  }  
</script>

You can run the Apex page for this example by visiting my online Apex account

28 queries. 0.517 seconds.
Powered by Wordpress
theme by cmoanz