Application Packaging Standard

Last updated 18-Mar-2019

Offers List

The list of offers must display a table with all offers of the application and the buttons that the provider will use to operate the offers.

../../../../../_images/offer-step-model1.png ../../../../../_images/offer-step-meta1.png ../../../../../_images/offer-step-provision1.png ../../../../../_images/offer-step-presentation-b.png ../../../../../_images/offer-step-deploy1.png ../../../../../_images/offer-step-provisioning1.png

Overview

When managing a list of objects created from an APS type, you normally need a land page that presents this list and allows users to launch some management operations with the objects individually or in a bunch. In APS, for this purpose use the aps/Grid container consisting of toolbars and a table with specified columns.

Continue Your Demo Project

This section continues the demo project from the previous step.

The ui/offers.html file presents a list of offers and is also used for launching other views. When creating the file from scratch, keep in mind the Typical Structure of View File and follow these steps.

  1. Create a typical structure of an HTML file:

    <!DOCTYPE html>
    <html>
    <head>
       <script src="/aps/2/ui/runtime/client/aps/aps.js"></script>
       <script>
          /* You will place the main JavaScript code here
          ...
          */
       </script>
    </head>
    <body>
    </body>
    </html>
    
  2. Once the HTML skeleton is created, create the structure of the main script:

    require([
       "dojo/when",
       "dijit/registry",
    
       "aps/ResourceStore",
       "aps/load",
    
       "./displayError.js",
    
       "aps/ready!"
    ], function (when, registry, Store, load, displayError) {
       /* Define data source */
       var store = new Store({
          target:     "/aps/2/resources/" + aps.context.vars.cloud.aps.id + "/offers"
       });
    
       /* Define and load the widgets */
       load(["aps/PageContainer", { id: "page" }, [
           /* ...Define widgets here */
    
       ]]).then(function() {
          /* ...Define button processing here */
    
       });
    });
    
  3. Declare a grid containing a toolbar and a table presenting a list of offers.

    load(["aps/PageContainer", { id: "page" }, [
       ["aps/Grid", {
          id:                "offers_grid",
          selectionMode:     "multiple",
          apsResourceViewId: "offer-edit",
          columns:   [
             { field: "name",    name: "Name", type: "resourceName" },
             { field: "hardware.memory",       name: "RAM, MB" },
             { field: "hardware.diskspace",    name: "Diskspace, GB" },
             { field: "hardware.CPU.number",   name: "CPU cores" },
             { field: "platform.OS.name",      name: "OS" }
          ],
          store: store
       }, [
             ["aps/Toolbar", { id: "offers_toolbar" }, [
                ["aps/ToolbarButton", {
                   id: "offers_new",
                   iconClass: "sb-add-new",
                   label:  "New"
                }],
                ["aps/ToolbarButton", {
                   id: "offers_delete",
                   iconClass: "sb-delete",
                   label: "Delete",
                   requireItems: true
                }],
                ["aps/ToolbarButton", {
                   id: "offers_refresh",
                   iconClass: "sb-refresh",
                   label: "Refresh",
                   autoBusy: false
                }]
             ]]
       ]]
    ]])
    

    The type: "resourceName" attribute makes the offer name clickable. Once it is clicked, the offer-edit view is called as specified by the apsResourceViewId: "offer-edit" attribute.

  4. Define handlers for custom buttons in the toolbar.

    • New button:

      registry.byId("offers_new").on("click", function() {
          aps.apsc.gotoView("offer-new");
      });
      

      When the button is clicked, the offer-new view is called.

    • Refresh button:

      registry.byId("offers_refresh").on("click", function() {
          registry.byId("offers_grid").refresh();
      });
      

      The grid refresh method updates the grid store and subsequently the table contents.

    • Delete button:

      registry.byId("offers_delete").on("click", function() {
          var self = this;
          if (!confirm("Are you sure you want delete Offers?")) {
             self.cancel();
             return;
          }
          var grid    = registry.byId("offers_grid"),
              sel     = grid.get("selectionArray"),
              counter = sel.length;
      
          registry.byId("page").get("messageList").removeAll();
      
          sel.forEach(function(offerId){ /* Get a VPS from the selected list */
             console.log("I'm trying to delete Offer with id = [" + offerId + "]");
      
             /* Remove the VPS from the APS database */
             when(store.remove(offerId),
                 /* If success, process the next VPS until the list is empty */
                function(){
                   console.log("Offer with id = [" + offerId + "] removed");
                   sel.splice(sel.indexOf(offerId),1); /* Remove the VPS from the view */
                   grid.refresh();
                   if(--counter === 0) {
                      self.cancel(); /* Make the button available again */
                   }
                },
                 /* If failure, call the error handler */
                function(e){
                   displayError(e);
                   if(--counter === 0) {
                      self.cancel();
                   }
                }
             );
          });
      });
      

Conclusion

This completes the development of the view presenting a land page for managing VPS offers.

The project file you have created is similar to the respective file in the sample package.