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:

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