Monday, July 30, 2018

Integrando Oracle JET v5.1 en Oracle Apex + Jet TimeLine y PictoChart

En este corto tutorial vamos a ver la forma de integrar Oracle Jet v5.1 o cualquier version de JET dentro de APEX.
Cabe mencionar que puede ser cualquier version de apex, lo he probado en versiones de  Apex v5.1 y Apex 18.



Adionalmente en este tutorial he usado referencia a las librerias online de Oracle, en un siguiente tutorial describire como usar nuestro servidor Apache para usar nuestras propias librerias.

Video demostrativo:



Primero agregamos las referencias a las librerias de knockout y require.js:


https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/knockout/knockout-3.4.2.js
https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/require/require.js


Agregamos la referencia al CSS que utiliza oracle JET, esto lo pegamos en HTML Header


<link rel="stylesheet" id="css" href="https://static.oracle.com/cdn/jet/v5.1.0/default/css/alta/oj-alta-min.css">
<script>
       if (!document.createElement) {
         document.createElement = document.constructor.prototype.createElement;
         document.createElementNS = document.constructor.prototype.createElementNS;
         document.importNode = document.constructor.prototype.importNode;
       }

       // The "oj_whenReady" global variable enables a strategy that the busy context whenReady,
       // will implicitly add a busy state, until the application calls applicationBoostrapComplete
       // on the busy state context.
       window["oj_whenReady"] = true;
</script>


Luego creamos una acción dinamica, cuando carga la pagina para agregar las librerias de JET 5.1.
* Podemos aqui utilizar diferentes versiones de jet, en las referencias dejare los links de oracle donde tome el ejemplo.


define("knockout",[],function(){return ko;});


requirejs.config({
  // Path mappings for the logical module names
  paths: {
    'knockout': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/knockout/knockout-3.4.2',
    'jquery': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/jquery/jquery-3.3.1.min',
    'jqueryui-amd': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/jquery/jqueryui-amd-1.12.1.min',
    'ojs': 'https://static.oracle.com/cdn/jet/v5.1.0/default/js/min',
    'ojL10n': 'https://static.oracle.com/cdn/jet/v5.1.0/default/js/ojL10n',
    'ojtranslations': 'https://static.oracle.com/cdn/jet/v5.1.0/default/js/resources',
    'text': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/require/text',
    'promise': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/es6-promise/es6-promise.min',
    'hammerjs': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/hammer/hammer-2.0.8.min',
    'signals': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/js-signals/signals.min',
    'ojdnd': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/dnd-polyfill/dnd-polyfill-1.0.0.min',
    'css': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/require-css/css.min',
    'customElements': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/webcomponents/custom-elements.min',
    'proj4js': 'https://static.oracle.com/cdn/jet/v5.1.0/3rdparty/proj4js/dist/proj4'
  },
  // Shim configurations for modules that do not expose AMD
  shim: {
    'jquery': {
      exports: ['jQuery', '$']
    }
  }
});


Para probar usare el control de TimeLine , el cual saque del CookBook de oracle Jet
Creamos un region de tipo static content y en el text copiamos el codigo HTML del cookbook.


<div id='timeline-container'>
          <oj-timeline id='timeline' aria-label='Timeline Context Menu Demo' 
                     minor-axis='{
                       "scale": "weeks",
                       "zoomOrder": ["months", "weeks", "days"]
                     }'
                     major-axis.scale='quarters'
                     start='[[new Date("Jan 1, 2013").toISOString()]]'
                     end='[[new Date("Dec 31, 2013").toISOString()]]'
                     selection-mode='single'
                     selection='["e4"]'
                     series='[[timelineSeries]]'
                     style='width:100%;height:350px'>
            <oj-menu slot='contextMenu' style='display:none' aria-label='Match Edit' 
                   on-oj-action='[[menuItemAction]]' 
                   on-oj-before-open='[[beforeOpenFunction]]'>
              <oj-option value='action1'>Action 1</oj-option>
              <oj-option value='action2'>Action 2</oj-option>
              <oj-option value='action3'>Action 3</oj-option>
            </oj-menu>
          </oj-timeline>
        
          <p>Last selected menu item:
            <span id='results' class='italic' style='font-weight:bold' data-bind='text: selectedMenuItem'></span>
          </p>
        </div>



Y luego creamos un boton que llame una accion dinamica para crear el ViewModel (JS) del control.


require(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojknockout', 'ojs/ojmenu', 'ojs/ojtimeline'],
  function (oj, ko, $)
  {
    function ViewModel()
    {
      var self = this;
      
      self.seriesData = [{
          id: 'e1',
          title: 'ATP VTR Open',
          start: new Date('Feb 4, 2013').toISOString(),
          end: new Date('Feb 10, 2013').toISOString(),
          description: 'Finalist: 3-1'
        }, {
          id: 'e2',
          title: 'ATP Brasil Open',
          start: new Date('Feb 11, 2013').toISOString(),
          end: new Date('Feb 17, 2013').toISOString(),
          description: 'Champion: 4-0'
        }, {
          id: 'e3',
          title: 'ATP Abierto Mexicano Telcel',
          start: new Date('Feb 25, 2013').toISOString(),
          end: new Date('Mar 2, 2013').toISOString(),
          description: 'Champion: 5-0'
        }, {
          id: 'e4',
          title: 'ATP BNP Paribas Open',
          start: new Date('Mar 7, 2013').toISOString(),
          end: new Date('Mar 17, 2013').toISOString(),
          description: 'Champion: 6-0'
        }
      ];
      var items = ko.observableArray(self.seriesData)();
      self.timelineSeries = [{id: 's1', emptyText: 'No Data.', label:'Oracle Events', items: items}];

      self.selectedMenuItem = ko.observable('(None selected yet)');
      var itemTitle;
      self.beforeOpenFunction = function (event)
      {
        var target = event.detail.originalEvent.target;
        var context = document.getElementById('timeline').getContextByNode(target);
        if (context != null && context.subId == 'oj-timeline-item')
        {
          var itemIndex = context['itemIndex'];
          itemTitle = self.seriesData[itemIndex]['title'];
        }
      };
      self.menuItemAction = function (event)
      {
        var text = event.target.textContent;
        if (itemTitle)
        {
          self.selectedMenuItem(text + ' from ' + itemTitle);
          itemTitle = null;
        }
        else
          self.selectedMenuItem(text + ' from timeline background');
      };
    };

    $(
        function()
        {
            ko.applyBindings(new ViewModel(), document.getElementById('timeline-container'));
        }
    );
  }
);


Finalmente tenemos nuestro TimeLine en Apex Oracle



Aplicación demo:




Referencias:




















Share:

Thursday, July 5, 2018

APEX_ITEM Parte 3 Guardando automáticamente los valores de un apex_item con Ajax + Oracle Apex + Jquery

Continuando con los apex_item, en esta oportunidad vamos a ver como usar datepicker, lista de valores y campos de input, haciendo que se guarden automaticamente, cada vez que modifiquemos algun valor.




apex_item parte 1
apex_item parte 2
como integrar alertify / plugin

Link demo: user: demo/ pass: demo

Video explicacion:



Lo primero es crear un interactive report con la siguiente consulta, donde ya he creado mis apex_item de datepicker, lista de valores y entrada de texto.

select e.empno
     , e.ename
   --, e.deptno
   --, e.sal
   --, e.hiredate
    -- apex items
     , apex_item.hidden( p_idx    => 1
                       , p_value  => e.empno)  ||
       apex_item.date_popup2(p_idx           => 2
                            , p_value        => e.hiredate
                            , p_date_format  => :APP_DATE_TIME_FORMAT
                            , p_size         => 20) hiredate
     , apex_item.select_list_from_lov(p_idx        => 3
                                    , p_value      => e.deptno
                                    , p_lov        => 'DEPARTAMENTOS'
                                    , p_attributes => 'style="width: 200px;"'
                                    , p_show_null  => 'NO') deptno
     , apex_item.text(p_idx   => 4
                    , p_value => e.sal
                    , p_size  => 5) sal
  from emp e

Luego crearemos una accion dinamica para capturar el cambio de algun apex item en la region del reporte.





#empleados_ir tr:gt(1)

actualizarEmpleado(this.triggeringElement);


Creamos la funcion en la definicion de la pagina y hacemos el llamado al proceso ajax.


var empno, hiredate, deptno, sal;


function actualizarEmpleado(elem){

  empno    = $(elem).find("input[name='f01']").val();
  hiredate = $(elem).find("input[name='f02']").val();
  deptno   =  $(elem).find("select[name='f03']").val();
  sal      = $(elem).find("input[name='f04']").val(); 
 console.log(empno + ' / ' +  hiredate + ' / ' +  deptno + ' / ' + sal);
 ajax_process_actualizar(empno,hiredate,deptno,sal);

}


function ajax_process_actualizar(empno,hiredate,deptno,sal){

  apex.server.process("ActualizarEmpleado",
       {  x01: empno
        , x02: hiredate
        , x03: deptno
        , x04: sal 
       }
     , {success: function(pData){ 
       
           if (pData.ind_error == 1){

             alertify.error(pData.mensaje);
             apex.event.trigger( "#empleados_ir", "apexrefresh" );
           } else {
             alertify.success(pData.mensaje);
           }

          }
       }
     //, {dataType: "text"}
   ); 
}



Creamos el proceso ajax callback, que retorna el mensaje de actualizacion correcta o de error.




begin

  update emp
     set hiredate = to_date(apex_application.g_x02,:APP_DATE_TIME_FORMAT)
       , deptno   = apex_application.g_x03
       , sal      = apex_application.g_x04
  where empno = apex_application.g_x01;

  apex_json.open_object;
  apex_json.write(p_name => 'mensaje', p_value=> 'Actualizado correctamente');
  apex_json.write(p_name => 'ind_error', p_value=> 0);
  apex_json.close_object;
exception
  when others then
  apex_json.open_object;
  apex_json.write(p_name => 'mensaje', p_value=> 'Error al actualizar');
  apex_json.write(p_name => 'ind_error', p_value=> 1);
  apex_json.close_object;

end;















Share:

Monday, July 2, 2018

Como integrar y usar plug-in en Apex / Alertify + Oracle Apex + JavaScript (notificaciones/alertas)

En esta oportunidad veremos como integrar el plugin alertify en Apex. y veremos dos formas de poderlo usar. Con una accion dinamica custom o con javaScript.



Este plugin da al usuario una mejor experiencia de uso al tener notificaciones con un buen diseño.
Cabe mencionar que este plug-in fue construido en base a esta libreria de JS

Link de descarga Alertify como plugin
Link demo propia del autor.

Link mi aplicacion demo 

Video demo




Lo primero que use es crear una accion dinamica CUSTOM


y seleccionamos una accion de tipo alertify



En mi boton de comprobar, llamare un javascript que compruebe si mi item tiene o no valor.


if ($("#P26_TIENE_VALOR").val())
{
  $.event.trigger("mostrar_mensaje_correcto");
}
else{
   $.event.trigger("mostrar_mensaje_error"); 
}



Resultado:




Y la otra forma de usar este plug in es llamarlo, directamente en un javaScript:
* nota podemos usar la documentacion oficial para su uso. aqui


// alert dialog
alertify.alert("Message");

// success notification
// shorthand for alertify.log("Notification", "success");
alertify.success("Success notification");







Share:

Subscribe to my Newsletter

Acerca de mi:

img

Ing. Angel O. Flores Torres, soy Ingeniero de Sistemas e Ingeniero de Aplicaciones Oracle Apex, he trabajado con Oracle Apex 5 y 5.1 desde el 2017, En los ultimos años he desarrollado habilidades en CSS, JavaScript, Jquery y PlSql , I specialize in Oracle APEX (Oracle Application Express )

Followers

Popular Posts