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