Monday, August 26, 2019

Manejo de Calendario/Calendar Oracle APEX parte 2

Seguiendo con el manejo de calendarios, aqui veremos algunas funciones avanzadas usando JavaScript. Fuente FullCalendar Doc





Cambiar la relación de aspecto:


apex.region("calendar_demo1").widget().fullCalendar("option",{'aspectRatio': 0.5})


Formato de titulo/fecha:


apex.region("calendar_demo1").widget().fullCalendar("option",{'titleFormat': 'MMMM D YYYY'})

apex.region("calendar_demo1").widget().fullCalendar("option",{'titleFormat': 'MMM YYYY'})


Idioma de los labels:


apex.region("calendar_demo1").widget().fullCalendar("option",
                                                    {'buttonText': 
                                                         {
                                                          today:    'Hoy',
                                                          month:    'Mes',
                                                          week:     'Semana',
                                                          day:      'Dia',
                                                          list:     'Lista'
                                                         }
                                                    });

apex.region("calendar_demo1").widget().fullCalendar("option",
                                                    {'buttonText': 
                                                         {
                                                            today:    'today',
                                                            month:    'month',
                                                            week:     'week',
                                                            day:      'day',
                                                            list:     'list'
                                                         }
                                                    });

Posición de la cabecera:


apex.region("calendar_demo1").widget().fullCalendar("option",{'header': {
  left:   'title',
  center: '',
  right:  'today prev,next'
}});


apex.region("calendar_demo1").widget().fullCalendar("option",{'header': {
  left:   'today prev,next',
  center: 'title',
  right:  'today prev,next'
}});

Ver fines de semana:


apex.region("calendar_demo1").widget().fullCalendar("option",{'weekends': true});


Minutos entre slots, ver vista semana o día:


apex.region("calendar_demo1").widget().fullCalendar("option",{'slotDuration': '00:30:00'})


Posición del Scroll, cuando te muevas de una pestaña de semana o día, el scroll estará predefinido en la hora indicada.


apex.region("calendar_demo1").widget().fullCalendar("option",{'scrollTime':'10:00:00'})


Hora mínima y máxima en la lista.



apex.region("calendar_demo1").widget().fullCalendar("option",{'minTime':'10:00:00'});



apex.region("calendar_demo1").widget().fullCalendar("option",{'maxTime':'16:00:00'});


Share:

Manejo de Calendarios/Calendar Oracle APEX parte 1

Crear un calendario en Oracle APEX es de lo mas sencillo. Además que nos permite una alta personalización, al utilizar librerías JS de fullcalendar.


En un query definimos parametros importantes:
Nombre
Fecha de Inicio
Fecha Fin
Y como alternativa:
ID : En caso de usar la funcionalidad de editar/eliminar
Css_Class: Para agregar colores


 select id 
      , project
      , task_name
      , start_date
      , end_date  
      , case status
           when 'Open'    then 'apex-cal-green'
           when 'Pending' then 'apex-cal-yellow'
           when 'Closed'  then 'apex-cal-red'
           when 'On-Hold' then 'apex-cal-black'
        end as css_class
from eba_demo_cal_projects

Opciones:

  • Uso de ToolTip




  • Colores
    • apex-cal-red
    • apex-cal-cyan
    • apex-cal-blue
    • apex-cal-bluesky
    • apex-cal-darkblue
    • apex-cal-green
    • apex-cal-yellow
    • apex-cal-silver
    • apex-cal-brown
    • apex-cal-lime
    • apex-cal-white
    • apex-cal-gray
    • apex-cal-black
    • apex-cal-orange

  • A partir de APEX 18 podemos usar Hints en el query
  • Mostrar en formato, mes , semana, día, lista





  • Hora formato 12 y 24
  • Exportar CSV, iCal, xml

  • APEX 18: Rest WebService Json
  • Opciones avanzadas en JavaScript


function ( pOptions) {
    pOptions.titleFormat      = "[Conference Schedule]";                  // custom title
    pOptions.minTime          = "07:00:00";                               // hide slots before minTime
    pOptions.maxTime          = "18:00:00";                               // hide slots after maxTime
    pOptions.columnFormat     = {month: '', week: 'dddd', day: 'dddd'};   // week view column headings
    pOptions.slotDuration     = "00:15:00";                               // custom slot duration
    pOptions.weekNumbers      = true;                                     // show week numbers
    pOptions.weekNumberTitle  = "CW";                                    
    return pOptions;
}
Share:

Monday, August 5, 2019

Integrando Oracle Jet 7.1 Gantt + Data dinámica + Oracle APEX 19.1 + AJAX

En este post integraremos la actual versión de Oracle JET 7.1 en Oracle APEX y usaremos AJAX para cargar la información de forma dinámica.



Demo

Descarga App: GDrive


Para este ejemplo usaremos el control Gantt del CookBook de JET

En la hoja creamos una variable que será nuestro enlace de la data.

Agregamos la referencia de CSS

#JET_CSS_DIRECTORY#/alta/oj-alta-notag-min.css


Agregamos la librería de requireJS

APEX_JAVASCRIPT.add_requirejs();


En el page load creamos dos acciones dinámicas, en una cargamos las librerías de JET 7.1



requirejs.config({

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

Y en otra acción dinámica el código del ViewModel, el código fue extraído de la guía del cookbook de Oracle JET.

Aquí se han modificado los siguientes puntos:

-- La función recibe un parámetro que es la data para usar en el Gantt
function ViewModel(dataArray) 
-- El construcctor recibe el parametro de la data.
this.dataProvider = new ArrayDataProvider(dataArray, {keyAttributes: 'id'});

-- Para los path de las images se estan usando link de images online
 this.rowLabelImagePath = { 'Flag1' ....
-- dataArray se inicializa como:
dataArray = ko.observableArray([]); 

Código ViewModel

  require(['knockout', 'ojs/ojbootstrap', 'ojs/ojarraydataprovider', 'ojs/ojknockout', 'ojs/ojgantt'],  
    function(ko, Bootstrap, ArrayDataProvider)
    {
      function ViewModel(dataArray) 
      {
        this.dataProvider = new ArrayDataProvider(dataArray, {keyAttributes: 'id'});
        this.projectStartDate = new Date("Jan 1, 2019");
        this.projectEndDate = new Date("Dec 31, 2019");
  
        this.currentDateString = "Apr 15, 2019";
        this.currentDate = new Date(this.currentDateString);
  
        // set viewport to center around the reference object
        var month = 1000 * 60 * 60 * 24 * 30;
        this.viewportStart = new Date(Math.max(this.projectStartDate.getTime(), this.currentDate.getTime() - 3*month));
        this.viewportEnd = new Date(Math.min(this.projectEndDate.getTime(), this.currentDate.getTime() + 3*month));
  
        // Helper function to get appropriate row label image x position depending on document reading direction
        this.getRowImageX = function() {
          var dir = document.documentElement.getAttribute("dir");
          return dir === 'ltr' ? '0' : '0';
        };
  
        // Helper function to get appropriate row label text x position depending on document reading direction
        this.getRowTextX = function() {
          var dir = document.documentElement.getAttribute("dir");
          return dir === 'ltr' ? '30' : '25';
        };
  
        this.getRowTextAnchor = function() {
          var dir = document.documentElement.getAttribute("dir");
          var userAgent = navigator.userAgent.toLowerCase();
          var isIE = userAgent.indexOf('trident') != -1 || userAgent.indexOf('msie') != -1 || userAgent.indexOf('edge') != -1;
          // Unlike other browsers, IE11 and Edge treats left side of svg text as start in RTL, 
          // so set text-anchor to end to achieve consistent behavior
          return dir === 'rtl' && isIE ? 'end' : 'start';
        };
  
        this.rowLabelImagePath = {
          'Flag1': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//pe.png',
          'Flag2': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//pw.png',
          'Flag3': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//aq.png',
          'Flag4': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//bg.png',
          'Flag5': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//bl.png',
          'Flag6': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//ch.png',
          'Flag7': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//es.png',
          'Flag8': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//gg.png',
          'Flag9': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//id.png',
          'Flag10': 'https://raw.githubusercontent.com/stefangabos/world_countries/master/flags/24x24//lt.png',
        };
      }
  
      Bootstrap.whenDocumentReady().then(
        function()
        {
          dataArray = ko.observableArray([]);  
          ko.applyBindings(new ViewModel(dataArray), document.getElementById('gantt'));
        }
      );
    }
  );

Creamos una región estática y agregamos el CSS de la región Gantt
 



 <div id="componentDemoContent" style="width: 1px; min-width: 100%;">
          
          <oj-gantt id="gantt"
              axis-position="bottom"
              start="[[projectStartDate.toISOString()]]"
              end="[[projectEndDate.toISOString()]]"
              gridlines.horizontal="visible"
              gridlines.vertical="visible"
              major-axis.scale="months"
              major-axis.zoom-order='["quarters", "months", "weeks", "days"]'
              minor-axis.scale="weeks"
              minor-axis.zoom-order='["quarters", "months", "weeks", "days"]'
              row-axis.rendered="on"
              selection-mode="single"
              reference-objects='[[[{"value": currentDate.toISOString()}]]]'
              viewport-start="[[viewportStart.toISOString()]]"
              viewport-end="[[viewportEnd.toISOString()]]"
              task-data="[[dataProvider]]"
              :aria-label='[["Gantt Chart. Current date is " + currentDateString]]'
              style="width:100%;height:500px">
            <template slot="rowTemplate" data-oj-as="row">
              <oj-gantt-row
                  label="[[row.id]]">
              </oj-gantt-row>
            </template>
            <template slot="taskTemplate" data-oj-as="task">
              <oj-gantt-task
                  row-id="[[task.data.resource]]"
                  start="[[task.data.begin]]"
                  end="[[task.data.finish]]"
                  label="[[task.data.name]]">
              </oj-gantt-task>
            </template>
            <template slot="rowAxisLabelTemplate" data-oj-as="rowAxisLabel">
              <svg style="overflow:visible">
                <g>
                  <image
                      :xlink:href='[[rowLabelImagePath[rowAxisLabel.rowData.id.replace(" ", "")]]]'
                      xlink:href=""
                      :x="[[getRowImageX()]]"
                      width="24" height="24">
                  </image>
                  <text
                      :x="[[getRowTextX()]]"
                      y="16"
                      :text-anchor="[[getRowTextAnchor()]]">
                    <oj-bind-text value="[[rowAxisLabel.rowData.label]]"></oj-bind-text>
                  </text>
                </g>
              </svg>
            </template>
          </oj-gantt>
  
          
        </div>


Creamos un botón y lo definimos con una acción dinámica que ejecutara un JavaScript, la cual es la llamada AJAX


    apex.server.process("LOAD_DATA", {     
      },   
      {  
        success: function(pData) {   
         console.log(pData);
          dataArray(pData);
        }  
      }                          
    ); // apex process  

Creamos nuestro AjaxCallback


Por motivos didáctivos estoy usando unos select dentro de un for para generar data de forma dinámica.


declare
  l_begin_date date;
  l_end_date date;
begin
   apex_json.open_array();  
      -- for generate random data
      for i in 1..20
      loop      
        -- tasks 1
          select TO_DATE(TRUNC(DBMS_RANDOM.VALUE(TO_CHAR(DATE '2019-01-01','J'),TO_CHAR(DATE '2019-12-31','J'))),'J' ) random_date 
            into l_begin_date
            from dual;

          select TO_DATE(TRUNC(DBMS_RANDOM.VALUE(TO_CHAR(l_begin_date,'J'),TO_CHAR(DATE '2019-12-31','J'))),'J' ) random_date 
            into l_end_date
            from dual;

        apex_json.open_object;  
        apex_json.write('id', 'task1-'||i);  
        apex_json.write('begin', l_begin_date );  
        apex_json.write('finish', l_end_date);  
        apex_json.write('name', 'Label 1-'||i);  
        apex_json.write('resource', 'Flag'||i);  
        apex_json.close_object;  

        -- tasks 2 
        select TO_DATE(TRUNC(DBMS_RANDOM.VALUE(TO_CHAR(DATE '2019-01-01','J'),TO_CHAR(DATE '2019-12-31','J'))),'J' ) random_date 
          into l_begin_date
          from dual;

        select TO_DATE(TRUNC(DBMS_RANDOM.VALUE(TO_CHAR(l_begin_date,'J'),TO_CHAR(DATE '2019-12-31','J'))),'J' ) random_date 
          into l_end_date
          from dual;

        apex_json.open_object;  
        apex_json.write('id', 'task1-'||i);  
        apex_json.write('begin', l_begin_date );  
        apex_json.write('finish', l_end_date);  
        apex_json.write('name', 'Label 1-'||i);  
        apex_json.write('resource', 'Flag'||i);  
        apex_json.close_object;  
      end loop;

  apex_json.close_array();  
end;


En el network la llamada ajax debe tener la siguiente estructura, la misma del ejemplo del cookbook.




Y finalmente el resultado






Share:

Sunday, June 30, 2019

Getting the Oracle APEX certificate , Tips


I recently took the certification exam to become an Oracle certified developer in APEX. I have to say it was a little complex, when I finished I thought I was not going to pass the test but I did.



I want to write some tips, and the way that I followed to get this Oracle APEX Certificate.
I hope this information will be useful for you, and don't worry I will write it also in Spanish :P

FYI: 
You must have an Oracle Account and register on http://www.pearsonvue.com/oracle

Tip 1:

Watch, understand and try to replicate the examples of office hours videos.

I will recommend these topics:

APEX 18.1 New Features

Application Features

Data Visualization with Oracle APEX

Interactive Grids

Dynamic Actions

Universal Theme / Mobile Applications

Web Source Modules / REST Enabled SQL

Exposing RESTful Services using APEX and ORDS

Tip 2:

Read the official documentation about APEX 18

  


Tip 3:

Install Applications from the gallery,  try to reproduce or just try to understand things that you don’t know.


Tip 4 - Small tips:

  • Review Universal Theme and all components.
  • Review the components with data source and its type of data source.
  • Review all the things that you can do on shared components.
  • Personally, I didn't see any question about JavaScript.
  • Create your own application and try to force errors, determinate the error and solve it.
  • Understand the basic concepts, for example what is the structure of an URL, what is schema authorization, authentication.

   
Tip 4 The most important: 

On the exam web you can find all the topics that you need to study.






Share:

Sunday, June 23, 2019

Mi primera aplicación con Oracle APEX Parte 2/2, Creando Aplicativo Empleados

En este post veremos cómo usar un dataset de empleados para crear nuestra primera aplicación con Oracle APEX.

Ir a Sql Workshop -> Utilities -> Sample Datasets

Seleccionamos el de Install EMP/DEPT, y next en la ventana que se abre.

Install Datasets


Create Application

Las paginas se habrán creado por defecto con alguna configuración adicional. Le damos en create.


Ejecutamos la aplicación

Y finalmente tendremos nuestra aplicación creada.


Share:

Mi primera aplicación con Oracle APEX Parte 1/2, Solicitando un workspace

Para empezar nuestro desarrollo en APEX, requerimos un espacio de trabajo (Workspace).


Existen dos formas de poder tener un workspace:
La primera es de forma local instalando oracle aquí les dejo un link con este procedimiento que toma un poco más de tiempo.
La segunda forma es socitar un espacio de trabajo en https://apex.oracle.com/
Para esto nos dirigimos a apex.oracle.com y le damos en "Get started for free"


Luego "Request a free workspace"


En los puntos 1,2,3 ingresamos nuestra información básica, Para el punto 4 el nombre del WORKSPACE puede ser cualquiera, por ejemplo, algo que represente al uso que le daremos.


Una encuesta que marcamos a nuestra preferencia


Luego una pequeña justificación por que solicitamos el workspace, en mi caso entrenamiento

Aceptamos los términos y condiciones

Confirmamos nuestros datos y enviamos la solicitud.

A los pocos minutos recibiremos un mensaje que hemos solicitado un espacio de trabajo.
Aquí nos indica el nombre de nuestro workspace y le damos en crear workspace.

Un mensaje de que fue creado satisfactoriamente y le damos en siguiente.


Luego nos pedirá ingresar nuestra contraseña para poder acceder.

Finalmente nos llevara al entorno de APEX.


Para volver a ingresar le vamos a https://apex.oracle.com/pls/apex/ y le damos en "Sign In".
Ingresamos nuestros datos y accedemos.

Share:

Sunday, May 19, 2019

Validaciones en apex_item Oracle Apex

Buen día, en esta entrada responderé una pregunta que me hicieron en un video sobre apex_items, como agregar una validación que solo permita números en un apex_item.


Esto se puede lograr usando JavaScript y en este punto con JS tenemos muchos caminos, aquí mostrare uno usando una clase CSS como selector.

Teniendo como base mi ejemplo de este post Apex_item parte 3 , usare la columna SAL para validar que solo acepte números.



Vamos al Query del reporte y agregamos una clase que nos servirá de identificador.


Creamos una acción dinámica:
Evento: Key Press
Tipo: Jquery Selector
Selector: .item_sal


En el código JS validaremos que solo se ingrese números usando el KeyCode y si no cancelamos la acción y mostraremos un mensaje en consola.


 var be = this.browserEvent;

if (be.keyCode < 48 || be.keyCode > 57)
{
    be.preventDefault();
  console.log( be.key + " is not number");
}




Pueden ver la demo aqui. user/pass: demo/demo
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