Cards view, responsive, in Oracle ADF 11g - Tarjetas de vista, adaptables, en Oracle ADF 11g
Hoy en día gran cantidad de aplicaciones corren en la versión 11g de adf, debido a sus complejos desarrollos se hace casi imposible migrar a nuevas versiones del framework en la mayoría de casos, pero nuestros clientes nos exigen diseños fronted interactivos, y cuando hablamos de interactivos encerramos todas las nuevas tendencia de diseño como lo son las card view en ingles.
Web:
Para esto encontré una solución muy buena que me permitió crear un diseño de fronted muy cómodo y satisfactorio a la vista.
![]() |
| He ocultado datos confidenciales. |
Móvil:
Así quedaría nuestro diseño, ahora explicare como lo hice.
Mis estilos css, para el diseño y la adaptabilidad fueron los siguientes:
y mi xml del jsff fue el siguiente:
Mis estilos css, para el diseño y la adaptabilidad fueron los siguientes:
.btnCards, .btnCards:focus, .btnCards:hover, .btnCards:active, .btnCards:focus:hover, .btnCards:focus:hover:active{
font-weight: normal;
font-size: 11px;
color: #13335a;
border-top-color: #E5E8EE;
border-left-color: #E5E8EE;
border-style: solid;
border-width: 1px;
text-decoration: none;
white-space: nowrap;
background-position: top;
background-repeat: repeat-x;
margin: 0px;
padding-top: 1px;
padding-bottom: 3px;
padding: 1px 1px 0px 2px;
padding-right: 9px;
background: rgba(148, 235, 231, 1);
background: -moz-radial-gradient(center, ellipse cover, rgba(148, 235, 231, 1)0%, rgba(148, 235, 231, 1)9%, rgba(132, 201, 196, 1)45%, rgba(70, 156, 129, 1)82%, rgba(70, 156, 129, 1)100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(148, 235, 231, 1)), color-stop(9%, rgba(148, 235, 231, 1)), color-stop(45%, rgba(132, 201, 196, 1)), color-stop(82%, rgba(70, 156, 129, 1)), color-stop(100%, rgba(70, 156, 129, 1)));
background: -webkit-radial-gradient(center, ellipse cover, rgba(148, 235, 231, 1)0%, rgba(148, 235, 231, 1)9%, rgba(132, 201, 196, 1)45%, rgba(70, 156, 129, 1)82%, rgba(70, 156, 129, 1)100%);
background: -o-radial-gradient(center, ellipse cover, rgba(148, 235, 231, 1)0%, rgba(148, 235, 231, 1)9%, rgba(132, 201, 196, 1)45%, rgba(70, 156, 129, 1)82%, rgba(70, 156, 129, 1)100%);
background: -ms-radial-gradient(center, ellipse cover, rgba(148, 235, 231, 1)0%, rgba(148, 235, 231, 1)9%, rgba(132, 201, 196, 1)45%, rgba(70, 156, 129, 1)82%, rgba(70, 156, 129, 1)100%);
background: radial-gradient(ellipse at center, rgba(148, 235, 231, 1)0%, rgba(148, 235, 231, 1)9%, rgba(132, 201, 196, 1)45%, rgba(70, 156, 129, 1)82%, rgba(70, 156, 129, 1)100%);
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#94ebe7', endColorstr='#469c81', GradientType=1);
}
.user {
width: 280px;
height: 240px;
margin: 150px 10px 0 10px;
text-align: center;
background-color: #FFC8C3;
transition: 0.5s cubic-bezier(.55, 0, .1, 1);
}
.user {
visibility: visible;
padding-bottom: 45px;
}
.cardsBackgroundApprove{
background-color: #A2EDCE;
}
.cardsBackgroundReject{
background-color: #FFC8C3;
}
.cardsBackgroundPend{
background-color: #FAE187;
}
.profile {
width: 50%;
height: auto;
float: left;
margin: 0 auto;
z-index: 2;
transition: 0.2s cubic-bezier(.55, 0, .1, 1);
}
.profiles {
display: inline-block;
}
.avatar {
margin-top: 15px;
margin-bottom: 5px;
width: 60px;
height: 60px;
font-size:2em;
line-height:60px;
color: #37474f;
border-radius: 50%;
background-color: #ffd54f;
transition: 0.6s ease-in-out;
cursor: pointer;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
}
.span {
margin-bottom: -10px;
line-height: 40px;
font-size: 1.2em;
font-weight: 600;
display: block;
font-style: none;
color: #37474f;
}
.card {
height: 400px;
width: 300px;
font-family: Roboto;
display: block;
position: relative;
margin: 50px auto;
border-radius: 5px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.2s ease-in-out;
}
.date {
top: 0;
left: 0;
background-color: #77d7b9;
color: #fff;
padding: 0.8em;
}
.date .spanDay {
display: block;
text-align: center;
}
.date{
font-weight: 700;
font-size: 24px;
text-shadow: 2px 3px 2px rgba(0, 0, 0, 0.18);
}
.date{
text-transform: uppercase;
}
.date{
font-size: 12px;
}
.float{
position:relative;
width:30px;
height:30px;
bottom:-13px;
left:89px;
margin-left: 10px;
background-color:#0C9;
color:#FFF;
border-radius:50px;
text-align:center;
box-shadow: 2px 2px 3px #999;
}
.my-float{
margin-top:22px;
}
y mi xml del jsff fue el siguiente:
<jsp:root version="2.1" xmlns:af="http://xmlns.oracle.com/adf/faces/rich" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:jsp="http://java.sun.com/JSP/Page">
<jsp:directive .page="" contenttype="text/html;charset=UTF-8">
<c:set value="#{adfBundle['com.rhla.rhsuite.process.view.resources.ProcessViewControllerBundle']}" var="processviewcontrollerBundle">
<af:resource source="../js/jquery-3.2.1.min.js" type="javascript">
<af:resource source="../js/materialize.min.js" type="javascript"> </af:resource>
<link href="../css/materialize.min.css" rel="stylesheet" type="text/css"></link>
<af:panelgrouplayout id="pgl1" layout="vertical" rendered="false" styleclass="containerMain">
<af:panelgrouplayout id="pgl2" inlinestyle="margin-top:30px;" layout="vertical" rendered="false" styleclass="divTable">
<af:panelgrouplayout id="pgl4" layout="vertical">
<af:table binding="#{VacationMB.tableApprove}" emptytext="#{bindings.RhTWfRequestApproveVO.viewable ? 'No data to display.' : 'Access Denied.'}" fetchsize="#{bindings.RhTWfRequestApproveVO.rangeSize}" filtermodel="#{bindings.RhTWfRequestApproveVOQuery.queryDescriptor}" filtervisible="true" id="t1" querylistener="#{bindings.RhTWfRequestApproveVOQuery.processQuery}" rowbandinginterval="0" rows="#{bindings.RhTWfRequestApproveVO.rangeSize}" rowselection="single" selectedrowkeys="#{bindings.RhTWfRequestApproveVO.collectionModel.selectedRow}" selectionlistener="#{bindings.RhTWfRequestApproveVO.collectionModel.makeCurrent}" styleclass="AFStretchWidth" value="#{bindings.RhTWfRequestApproveVO.collectionModel}" var="row" varstatus="vs">
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.IdPerson.label}" id="c1" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.IdPerson.name}" width="105">
<af:inputtext columns="#{bindings.RhTWfRequestApproveVO.hints.IdPerson.displayWidth}" id="it1" label="#{bindings.RhTWfRequestApproveVO.hints.IdPerson.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.IdPerson.precision}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.IdPerson.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.IdPerson.tooltip}" value="#{row.bindings.IdPerson.inputValue}">
<f:validator binding="#{row.bindings.IdPerson.validator}">
</f:validator></af:inputtext>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.IdEmp.label}" id="c2" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.IdEmp.name}" width="105">
<af:inputtext columns="#{bindings.RhTWfRequestApproveVO.hints.IdEmp.displayWidth}" id="it2" label="#{bindings.RhTWfRequestApproveVO.hints.IdEmp.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.IdEmp.precision}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.IdEmp.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.IdEmp.tooltip}" value="#{row.bindings.IdEmp.inputValue}">
<f:validator binding="#{row.bindings.IdEmp.validator}">
</f:validator></af:inputtext>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.StartDate.label}" id="c3" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.StartDate.name}" width="106">
<f:facet name="filter">
<af:inputdate id="id1" value="#{vs.filterCriteria.StartDate}">
<af:convertdatetime pattern="#{bindings.RhTWfRequestApproveVO.hints.StartDate.format}">
</af:convertdatetime></af:inputdate>
</f:facet>
<af:inputdate columns="#{bindings.RhTWfRequestApproveVO.hints.StartDate.displayWidth}" id="id2" label="#{bindings.RhTWfRequestApproveVO.hints.StartDate.label}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.StartDate.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.StartDate.tooltip}" value="#{row.bindings.StartDate.inputValue}">
<f:validator binding="#{row.bindings.StartDate.validator}">
<af:convertdatetime pattern="#{bindings.RhTWfRequestApproveVO.hints.StartDate.format}">
</af:convertdatetime></f:validator></af:inputdate>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.EndDate.label}" id="c4" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.EndDate.name}" width="104">
<f:facet name="filter">
<af:inputdate id="id3" value="#{vs.filterCriteria.EndDate}">
<af:convertdatetime pattern="#{bindings.RhTWfRequestApproveVO.hints.EndDate.format}">
</af:convertdatetime></af:inputdate>
</f:facet>
<af:inputdate columns="#{bindings.RhTWfRequestApproveVO.hints.EndDate.displayWidth}" id="id4" label="#{bindings.RhTWfRequestApproveVO.hints.EndDate.label}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.EndDate.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.EndDate.tooltip}" value="#{row.bindings.EndDate.inputValue}">
<f:validator binding="#{row.bindings.EndDate.validator}">
<af:convertdatetime pattern="#{bindings.RhTWfRequestApproveVO.hints.EndDate.format}">
</af:convertdatetime></f:validator></af:inputdate>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.ApprovedAmmount.label}" id="c5" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.ApprovedAmmount.name}" width="105">
<af:inputtext columns="#{bindings.RhTWfRequestApproveVO.hints.ApprovedAmmount.displayWidth}" id="it3" label="#{bindings.RhTWfRequestApproveVO.hints.ApprovedAmmount.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.ApprovedAmmount.precision}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.ApprovedAmmount.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.ApprovedAmmount.tooltip}" value="#{row.bindings.ApprovedAmmount.inputValue}">
<f:validator binding="#{row.bindings.ApprovedAmmount.validator}">
</f:validator></af:inputtext>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.AvailableAmmount.label}" id="c6" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.AvailableAmmount.name}" width="105">
<af:inputtext columns="#{bindings.RhTWfRequestApproveVO.hints.AvailableAmmount.displayWidth}" id="it4" label="#{bindings.RhTWfRequestApproveVO.hints.AvailableAmmount.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.AvailableAmmount.precision}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.AvailableAmmount.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.AvailableAmmount.tooltip}" value="#{row.bindings.AvailableAmmount.inputValue}">
<f:validator binding="#{row.bindings.AvailableAmmount.validator}">
</f:validator></af:inputtext>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.label}" id="c7" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.name}" width="105">
<af:inputtext columns="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.displayWidth}" id="it5" label="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.precision}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.tooltip}" value="#{row.bindings.RequestedAmmount.inputValue}">
<f:validator binding="#{row.bindings.RequestedAmmount.validator}">
<af:convertnumber groupingused="false" pattern="#{bindings.RhTWfRequestApproveVO.hints.RequestedAmmount.format}">
</af:convertnumber></f:validator></af:inputtext>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.Comments.label}" id="c8" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.Comments.name}" width="105">
<af:inputtext autosubmit="true" columns="#{bindings.RhTWfRequestApproveVO.hints.Comments.displayWidth}" id="it6" label="#{bindings.RhTWfRequestApproveVO.hints.Comments.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.Comments.precision}" required="#{bindings.RhTWfRequestApproveVO.hints.Comments.mandatory}" rows="3" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.Comments.tooltip}" value="#{row.bindings.Comments.inputValue}">
<f:validator binding="#{row.bindings.Comments.validator}">
</f:validator></af:inputtext>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.RequestType.label}" id="c9" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.RequestType.name}" width="105">
<af:inputtext columns="#{bindings.RhTWfRequestApproveVO.hints.RequestType.displayWidth}" id="it7" label="#{bindings.RhTWfRequestApproveVO.hints.RequestType.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.RequestType.precision}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.RequestType.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.RequestType.tooltip}" value="#{row.bindings.RequestType.inputValue}">
<f:validator binding="#{row.bindings.RequestType.validator}">
</f:validator></af:inputtext>
</af:column>
<af:column filterable="true" headertext="#{bindings.RhTWfRequestApproveVO.hints.Status.label}" id="c10" sortable="true" sortproperty="#{bindings.RhTWfRequestApproveVO.hints.Status.name}" width="102">
<af:inputtext columns="#{bindings.RhTWfRequestApproveVO.hints.Status.displayWidth}" id="it8" label="#{bindings.RhTWfRequestApproveVO.hints.Status.label}" maximumlength="#{bindings.RhTWfRequestApproveVO.hints.Status.precision}" readonly="true" required="#{bindings.RhTWfRequestApproveVO.hints.Status.mandatory}" shortdesc="#{bindings.RhTWfRequestApproveVO.hints.Status.tooltip}" value="#{row.bindings.Status.inputValue}">
<f:validator binding="#{row.bindings.Status.validator}">
</f:validator></af:inputtext>
</af:column>
</af:table>
</af:panelgrouplayout>
</af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl25" layout="vertical" styleclass="containerMain">
<af:panelgrouplayout id="pgl10" layout="vertical" styleclass="container flex-direction">
<af:panelgrouplayout id="pgl11" layout="vertical" styleclass="div1 sizeBlocks">
<af:panelgrouplayout id="pgl8" inlinestyle="padding-top:15px;" layout="vertical">
<af:outputformatted id="of9" inlinestyle="padding-top:2px;" styleclass="textBlocks" value="#{processviewcontrollerBundle.FECHA_INGRESO}#{bindings.FechaInicio.inputValue}">
</af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl12" layout="vertical" styleclass="div2 sizeBlocks">
<af:panelgrouplayout id="pgl5" inlinestyle="padding-top:15px;" layout="vertical">
<af:outputformatted id="of11" styleclass="textBlocks" value="#{processviewcontrollerBundle.SALARIO_ACTUAL}#{bindings.SalarioActual.inputValue}">
</af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl13" layout="vertical" styleclass="div3 sizeBlocks">
<af:panelgrouplayout id="pgl6" inlinestyle="padding-top:15px;" layout="vertical">
<af:outputformatted id="of13" styleclass="textBlocks" value="#{processviewcontrollerBundle.DIAS_VAC_PENDIENTES}#{bindings.Pendientes.inputValue}">
</af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl14" layout="vertical" styleclass="div4 sizeBlocks">
<af:panelgrouplayout id="pgl7" inlinestyle="padding-top:15px;" layout="vertical">
<af:outputformatted id="of15" styleclass="textBlocks" value="#{processviewcontrollerBundle.DIAS_VAC_DISFRUTADAS}#{bindings.Disfrutada.inputValue}">
</af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl24" inlinestyle="margin-top:20px;" layout="vertical" styleclass="container flex-direction">
<af:iterator id="i1" value="#{bindings.RhTWfRequestApproveVO.collectionModel}" var="row" varstatus="vs">
<af:panelgrouplayout id="pgl9" layout="vertical" partialtriggers="cb1" styleclass="user card #{row.Status eq 'PENDIENTE' ? ' cardsBackgroundPend' : row.Status eq 'APROBADA' ? ' cardsBackgroundApprove' : row.Status eq 'RECHAZADA' ? ' cardsBackgroundReject' : '' }">
<af:panelgrouplayout id="pgl26" layout="vertical" styleclass="date">
<af:outputformatted id="of8" styleclass="spanDay" value="#{processviewcontrollerBundle.SOLICITUD_NO_}#{row.bindings.WfRequestId.inputValue}">
</af:outputformatted></af:panelgrouplayout>
<af:panelgrouplayout id="pgl16" layout="vertical">
<af:image id="i2" source="/showphotoemployee?id_person=#{row.bindings.IdEmp.inputValue}" styleclass="avatar">
</af:image></af:panelgrouplayout>
<af:panelgrouplayout id="pgl15" layout="vertical" styleclass="profiles">
<af:panelgrouplayout id="pgl17" layout="vertical">
<af:outputformatted id="of1" styleclass="span" value="#{row.bindings.PersonName.inputValue}">
</af:outputformatted></af:panelgrouplayout>
<af:panelgrouplayout id="pgl18" layout="vertical" styleclass="profile">
<af:panelgrouplayout id="pgl20" layout="vertical">
<af:outputformatted id="of2" styleclass="span" value="#{row.bindings.StartDate.inputValue}">
<af:outputformatted id="of3" value="#{processviewcontrollerBundle.FECHA_INICIO}">
</af:outputformatted></af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl21" layout="vertical" styleclass="profile">
<af:panelgrouplayout id="pgl22" layout="vertical">
<af:outputformatted id="of4" styleclass="span" value="#{row.bindings.EndDate.inputValue}">
<af:outputformatted id="of5" value="#{processviewcontrollerBundle.FECHA_FIN}">
</af:outputformatted></af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl19" layout="vertical" styleclass="profile">
<af:panelgrouplayout id="pgl23" layout="vertical">
<af:outputformatted id="of6" styleclass="span" value="#{row.bindings.RequestedAmmount.inputValue}">
<af:outputformatted id="of7" value="#{processviewcontrollerBundle.DIAS}">
</af:outputformatted></af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl27" layout="vertical" styleclass="profile">
<af:panelgrouplayout id="pgl28" layout="vertical">
<af:outputformatted id="of12" styleclass="span" value="#{row.bindings.Status.inputValue}">
<af:outputformatted id="of10" value="#{processviewcontrollerBundle.ESTADO}">
</af:outputformatted></af:outputformatted></af:panelgrouplayout>
</af:panelgrouplayout>
</af:panelgrouplayout>
<af:panelgrouplayout id="pgl29">
<af:commandbutton actionlistener="#{VacationMB.approveVac}" icon="/images/comprobado.png" id="cb1" styleclass="float btnCards">
<f:attribute name="itemVal" value="#{row.WfRequestId}">
</f:attribute></af:commandbutton>
<af:commandbutton icon="/images/cancelar.png" id="cb2" styleclass="float btnCards">
<f:attribute name="itemVal" value="#{row.WfRequestId}">
</f:attribute></af:commandbutton>
</af:panelgrouplayout>
</af:panelgrouplayout>
</af:iterator>
</af:panelgrouplayout>
</af:panelgrouplayout>
</af:resource></c:set></jsp:directive></jsp:root>
Como vemos no fue nada complicado, en oracle adf usaremos un <af:panelGroupLayout> en layout vertical se comportara como un div de html, use un <af:iterator> para iterar todos los registro del view object y crear una tarjeta por cada registro, y uso un <af:attribute> para capturar el id de la tarjeta en cada iteración y poderla enviar a los diferentes métodos de lógica de negocio.
Espero sea de gran ayuda para darle otra cara a tus desarrollos.
Espero sea de gran ayuda para darle otra cara a tus desarrollos.


Comentarios
Publicar un comentario