Oracle APEX Cookbook(Second Edition)
上QQ阅读APP看书,第一时间看更新

Creating a tag cloud with AJAX>

Asynchronous JavaScript and XML (AJAX) is a method of communication between a client and the server where the website resides. AJAX makes it possible to dynamically respond to actions on the client side. For example, it is possible to directly check an e-mail address while you are typing! Or set a color of an object when clicking on another object. Ajax is most used to dynamically fetch data from the server to use it on the web page.

Until APEX 4.0, using Ajax in your web page required advanced programming with JavaScript. But since APEX 4.0, it is a lot easier to use AJAX with the help of dynamic actions. We will make a page with a tag cloud and a region where you can see the news articles. When you click on a tag in the tag cloud, APEX will show the articles that are related to the selected tag. This information is an AJAX call and is implemented using a dynamic action.

Getting ready

We will create a new page. Make sure you have created, and have access to the tables APP_NEWS, APP_TAGS, and APP_TGS_NWS.

How to do it...

  1. Go to your application and click on the Create Page button.
  2. Select Blank page.
  3. Enter a page alias, for example tagnews, and click on Next.
  4. Enter a name for the page, for example, News articles by tags, and click on Next.
  5. Select No and click on Next.
  6. Click on Finish.
  7. Click on the Edit icon.
  8. In the Regions section, click on the Add icon.
  9. Select PL/SQL dynamic content.
  10. Enter a title for the region, in this case Tag cloud. Click on Next.
  11. In the PL/SQL Source textarea, enter the following code:
    declare
      --
      cursor c_tags is
        select tns.tgs_id
        ,      tgs.tag
        ,      count(tns.tgs_id) num_of_times
        from   app_tgs_nws tns
        ,      app_tags    tgs
        where  tgs.id = tns.tgs_id
        group by tns.tgs_id, tgs.tag
        order by 1;
      --
      l_min_num number(3);
      l_max_num number(3);
      l_size   number(2);
      l_multiplx number(2);
    begin
      select min(num_of_times) min_num
      ,      max(num_of_times) max_num
      into   l_min_num, l_max_num
      from   (select tns.tgs_id
             ,      tgs.tag
             ,      count(tns.tgs_id) num_of_times
             from   app_tgs_nws tns
             ,      app_tags    tgs
             where  tgs.id = tns.tgs_id
             group by tns.tgs_id, tgs.tag);
      --
      l_multiplx := round(72/l_max_num);
      --
      for r_tags in c_tags
      loop
        l_size := round(l_multiplx * r_tags.num_of_times);
        sys.htp.print (q'!<a onmouseover="this.style.cursor='pointer';" onclick=document.getElementById("PXX_TAG").value="!'||r_tags.tag||'"; 
    style="font-size:'||to_char(l_size)||'px; text-decoration:none;">'||r_tags.tag||'</a>');    
        sys.htp.print('  ');
      end loop;
    end;
    [9672_03_05.txt]

Replace XX in PXX_TAG by the page number. The onmouseover event is necessary to change the cursor as if it were pointing to a link. The onclick event copies the value of the tag that is clicked on to the hidden item PXX_TAG. This is needed to build the query. The item will be referenced in the dynamic action. But first we need to create the item through the following steps:

  1. Click on the Create Region button. The tag cloud region is now ready. Now we will create the hidden item.
  2. In the Items section, click on the Add icon.
  3. Select Hidden and click on next.
  4. In the Item Name text item, enter the name PXX_TAG where XX is the page number you are creating. You can see the page number on the first line of the Create Item section.
  5. In the Region listbox, select the tag cloud region you just selected. Click on Next two times.
  6. Click on the Create Item button. The hidden item is ready. Now we will create the region for the news articles.
  7. In the Regions section, click the Add icon.
  8. Select HTML.
  9. Again, select HTML and click on Next.
  10. Enter a title for the region, for example Related articles, and click on Next.
  11. Leave the Region Source empty and click on the Create Region button.

The last step is the creation of the dynamic action.

  1. In the Dynamic Actions sections, click on the Add icon.
  2. Select Advanced.
  3. Enter a name for this action, for example show_articles, and click on Next.
  4. In the Event listbox, select Click.
  5. In the Selection Type listbox, select Region.
  6. In the Region listbox, select the tag cloud region and click on Next.
  7. In the Action listbox, select Set Value. A Settings section appears.
  8. In the Set Type listbox, select PL/SQL function body.
  9. In the PL/SQL function body textarea, enter the following code:
    declare
    cursor c_nws is
       select title
       ,      text
       from   app_news
       where  upper(text) like '%'||upper(:PXX_TAG)||'%';
    --
    l_text varchar2(32000) := '';
    begin
    for r_nws in c_nws
    loop
       l_text := l_text || '<h1>' || r_nws.title || '</h1>';
       l_text := l_text || '<br>';
       l_text := l_text ||    replace(r_nws.text,:PXX_TAG,'<b>'||:PXX_TAG||'</b>');
       l_text := l_text || '<br>';
       l_text := l_text || '<br>';
    end loop;
    return l_text;
    end;
    [9672_03_06.txt]

Replace XX in PXX_TAG by the page number. This script loops through the records of a query. The query selects the records where the text contains the tag where the user clicked on. The results of the query are displayed using the htp.p function.

  1. In the Page Items to Submit text field, enter PXX_TAG where XX is the page number.
  2. In the Escape Special Characters listbox, select No and click on Next.

In the next step we must set the affected objects:

  1. In the Selection Type listbox, select Region. In the Region listbox, select HTML region (related articles). Click on the Create button.
  2. In the Processes section, click the Add icon.
  3. Select PL/SQL and click on Next.
  4. Enter a name for the PL/SQL process, for example populate_tags.
  5. In the Point listbox, select On Load – Before Header and click on Next.
  6. In the PL/SQL textarea, enter the following code:
    declare
      cursor c_app_tags
      is
        select id
        ,      tag
        from   app_tags
        order by id;
      --
      cursor c_instr(b_tag in varchar2)
      is
        select id
        ,      instr(upper(text),upper(b_tag)) tag_found
        from   app_news;
    begin
      delete from app_tgs_nws;
      --
      for r_app_tags in c_app_tags
      loop
        for r_instr in c_instr(r_app_tags.tag)
        loop
          if r_instr.tag_found > 0
          then
            insert into app_tgs_nws
            values (r_app_tags.id,r_instr.id);
          end if;
        end loop;
      end loop;
      --
      commit;
    end;
    [9672_03_25.txt]

    The preceding piece of code populates the intersection table between APP_NWS and APP_TAGS. First, the table is truncated, and then, the code loops through the text of the APP_NWS table to search for the tags from the APP_TAGS table. If it finds a match, a row is inserted into the APP_TGS_NWS table. This process is started each time the user enters this page. In this way, changes in the APP_NWS table are immediately visible. So, when a row is inserted into the APP_NWS table with a text that contains something like APEX, the tag cloud will show the APEX tag bigger.

  7. Click on the Create Process button.

The page is now ready. Run the page and see how the articles change when you click on a tag.

How it works...

We use the <a> tag where we put some extra JavaScript code. First, there is the onmouseover event which changes the cursor style to a pointer (the "hand"). Second, there is the onclick event which copies the tag to the hidden item.

In the dynamic action, a PL/SQL function is executed which loops through a cursor of a query that selects all records with articles related to the tag (the like operator is used). In the dynamic action, the set_value function is used to replace the content of the affected region by the content of the variable l_text.

Actually the affected region (Related articles) is a div, and the dynamic action is an AJAX process that retrieves the data from the server (the query) and puts them in the div. In JavaScript, you would use the following line of code for divs:

$('divid').html("some text or HTML code");

The following JavaScript code would be used for items:

$('#P_ITEM').val('some text');

The last case is similar to a dynamic action where the affected object is an item.

You can test all this yourself:

  1. Go to the page and click on the Edit icon in the Page section.
  2. In the HTML Header and Body Attribute section, enter the following in the HTML header textarea to create a JavaScript function:
    <script type="text/javascript">
    function set_div(){
    document.getElementById("dynamicdiv").innerHTML = "This is some text in a div";
    }
    </script>
    [9672_03_07.txt]
  3. Click on the Apply Changes button.
  4. To assign an ID for the Related articles div (region), click on the Related articles region. In the Attributes section, enter dynamicdiv in the Static ID text field and click on the Apply Changes button.
  5. To create a text item, in the Items section, click on the Add icon.
  6. Select Text field and click on Next. In the Item Name text field, enter a name and in the Region listbox, select the tag cloud region. Click three times on Next. Then click on the Create Item button.
  7. Click on the newly created item. In the Element section, enter the following in the HTML form element attributes:
    onblur=set_div();
    [9672_03_08.txt]

    The onblur event fires when the user navigates out of the item by using the Tab key, the Enter key, or by clicking the mouse pointer somewhere else.

  8. Click on the Apply Changes button.

Run the page. Click on the item you just created and navigate out of the item using the Tab or Enter key. The div should show the text This is some text in a div. This is just an example to show you what a dynamic action actually does. Don't mind the strange onblur event on the item used to trigger an event. An onclick event was not possible as the entire tag cloud had an onclick event triggering the dynamic action to set the Related articles region.

The static ID for the div is necessary, otherwise APEX generates its own ID which looks something like R431819100396833156 and then you have to find the div ID using the page source of the web page.