Respuestas de foro creadas
-
AutorEntradas
-
Alfredo Sanz
SuperadministradorSeguramente será algún problema con la encriptación de datos que hacemos al quitar el modo debug.
Pincha en donde pone @soft:6 y en @soft:11 para poder ver el html que da el error y mándame el código que te sale.
Alfredo Sanz
SuperadministradorBueno, como diría el amigo Quim, lo tengo hecho "a cuchillo" para comprobar que funciona.
Ahora falta darle "el toque Néfele"
En unos días estará terminado.
Alfredo Sanz
SuperadministradorSí,
En néfele vamos a tener inicialmente dos browses.
- wArrayBrowse: lo estamos diseñando desde cero, basado en tablas html. Con funciones limitadas pero sencillo de implementar
- DataTables.net: Va a incorporar todas las funcionalidades de este fantástico plugin (filtrar, ordenar, paginar, etc....)
El DataTables lo estamos cocinando y espero poder enseñar algo muy prontito.
El wArrayBrowse, ya es funcional, lo que no quiere decir que no le incorporemos más "cosicas" según se necesiten, por ejemplo:
Contenido no disponible.
Por favor, acepta las cookies haciendo clic en este aviso-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
Alfredo Sanz
SuperadministradorTomo nota.
Alfredo Sanz
SuperadministradorTal y como lo tienes, cuando metas un dato en el wEdit "cliente", pasado 1 segundo sin modificar el dato, ejecutará tu función "DatosClte" por Ajax.
En esta función es en la que tienes que verificar si el dato introducido existe o no y devolver la acción correspondiente.
Fíjate en el ejemplo 5 de los formularios de https://samples.nefele.dev/ejemplo
Puedes hacer, por ejemlo:
- Si el código existe, rellenas los campos que faltan.
- Si el código no existe, muestras un alert que diga que el código no se ha encontradoContenido no disponible.
Por favor, acepta las cookies haciendo clic en este avisoCon esto conseguimos que nos verifique si existe o no el código antes de pulsar el botón aceptar.
Luego, cambiarás la función "Visparam" ( que se ejecuta cuando pulsas acertar) por tu propia función, en la que guardarás los datos, etc...
123456789101112131415161718with object WForm():New(:WO):cId := "formulario":cFunction := "VisParam"with object WEdit():New(:WO):nTimeOut := 1:cAjaxTimeOut := "DatosClte":cId := "cliente":cTitle := "Código Clte":cHint := "":cIcon := "person"/* Estas propiedades estaran disponibles en la próxima actualización de Néfele:lShadowSheet := .T.::cShadowSheetTitle := "Buscando información de cliente"::cShadowSheetSubTitle := "Un Momento ..."*/:SetRequired():Create()end withy en DatosClte
12345678910111213141516171819202122232425262728293031323334353637383940414243PROCEDURE DatosClte()LOCAL cDato := oCGI:GetCgiValue("key","")LOCAL aClientes := {{"123","Alfredo","Sanz","Pérez"},;{"456","Pedro","Amaro","Perdomo"},;{"789","Fernando","Martín","Regalde"}}LOCAL nIdx := HB_Ascan(aClientes,{|x| x[1]==cDato})LOCAL cHtmlif nIdx > 0cHtml := UpdateValues( aClientes[nIdx,2], aClientes[nIdx,3], aClientes[nIdx,4] )ELSEcHtml := UpdateValues( "", "", "" )IF Val(cDato) > 0WITH OBJECT WMsgAlert():New():cText := "Dato no encontrado":cType := "error":lModal := .T.:Create()cHtml += :fullhtml()ENDELSEIF !Empty(cDato)cHtml := nfl_Tag("script","window.location.href='https://www.google.es/search?q="+cDato+"'")ENDIFENDIFoCGI:SendScript( cHtml )RETURN//------------------------------------------------------------------------------FUNCTION UpdateValues( cNombre, cApellido1, cApellido2 )LOCAL cSalidatext into cSalidadocument.getElementById('nombre').value='[[nombre]]';document.getElementById('apellido1').value='[[apellido1]]';document.getElementById('apellido2').value='[[apellido2]]'endtextcSalida := StrTran(cSalida, "[[nombre]]", cNombre)cSalida := StrTran(cSalida, "[[apellido1]]", cApellido1)cSalida := StrTran(cSalida, "[[apellido2]]", cApellido2)RETURN cSalidaAlfredo Sanz
SuperadministradorYes, We Can!
Es buena idea, la "nefelizaremos" para la próxima versión.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172PROCEDURE xeviMiBrowse()Local aItems := {}Local nFor n:=1 To 50AAdd( aItems, { "Registro " + ToString(n), "Columna2" } )NextWITH OBJECT TWebPage():New()WSeparator():New(:WO):Create()WSeparator():New(:WO):Create()//Un contenedor del BrowseWITH OBJECT WBevel():New(:WO):oStyle:cPadding_left := 0 //No dejo márgenes a la izquierda:oStyle:cPadding_right := 0 //No dejo márgenes a la derechaWITH OBJECT WArrayBrowse():New(:WO):cId := "table":lIncludeArray := .f.:nStyle := xc_Striped // Estilo visual, con pautado pijama:cClrHeadPane := "black" // Color de Fondo a las cabeceras:cClrHeadText := "white" // Color del texto de cabeceras:oStyle:cLine_height := 0 //Quito altura entre registro y registro:cCSS += "table.striped>tbody>tr>td { border: 1px solid #dee2e6; }" // Borde al Browse, interlineado y entre columnas:cCSS += "#table_head1 { padding-top: 0px; padding-bottom: 2px; }" // Menos alto título columnas:cCSS += "#table_head2 { padding-top: 0px; padding-bottom: 2px; }" // debo establecerlas a TODAS:cCSS += cssMakeScrollable()// Añadimos ColumnasWITH OBJECT :AddCol( "Col1", xc_Right, xc_Right ) AS WItemColBrowse // texto cabecera, alineacion cabecera, alineacion datos AS wItemColBrowse:nWidth := 25END WITHWITH OBJECT :AddCol( "Col2", xc_Center, xc_Left ) AS WItemColBrowse:lBold := .T.:nWidth := 75END WITH:aItems := AsciiHTML(aItems) // Le alimentamos datos directamente de la consulta:Create()END WITH //ArrayBrowse:Create()END WITH //BeveloCgi:SendPage( :Create() )END WITH //WebPageRETURN//------------------------------------------------------------------------------FUNCTION cssMakeScrollable()LOCAL cTxt//https://stackoverflow.com/questions/47723996/table-with-fixed-thead-and-scrollable-tbodyTEXT INTO cTxt.table > thead { display:table; width: 100%; background: black; }.table > thead > tr { width: calc(100% - 17px); }.table > thead > tr > th { border-bottom: 1px black solid; }.table > tbody { max-height: 485px; overflow-y: scroll; display: block; }tr { display: table; width: 100%; }ENDTEXTRETURN cTxt//------------------------------------------------------------------------------Contenido no disponible.
Por favor, acepta las cookies haciendo clic en este aviso-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
Alfredo Sanz
SuperadministradorHola!
Estamos trabajando ya en el control del datatables, en breve tendremos los primeros ejemplos.
Alfredo Sanz
SuperadministradorEs algo que hemos discutido entre nosotros más de una vez, el problema principal es el diseño responsive.
Si lo pones en un móvil y son más de 2 botones, la cosa se complica.
De todas formas, aprovecho para "hacer publicidad" de una de las opciones del foro que nadie está usando.
En el menú de arriba, tenéis una opción que pone peticiones.
En él podéis añadir vuestras ideas y mejoras a Néfele y otros usuarios pueden votar por ellas, así nosotros podemos saber "qué rumbo" seguir en todas estas cuestiones.
Lo cierto es que es un plugin de Wp que no funciona muy bien, pero es el único que he encontrado. Si veo que se usa, mi idea es crear un programa en Néfele con las mismas funcionalidades pero que funcione como me gustaría que lo hiciera este.
He añadido la que comentas, así que .... a votar por ella.
16-10-2020 a las 00:32 en respuesta a: Cual es la forma correcta de llamar procedimientos al dar click en un control ? #1251Alfredo Sanz
SuperadministradorNada, encantado de resolver tus dudas
15-10-2020 a las 22:08 en respuesta a: Cual es la forma correcta de llamar procedimientos al dar click en un control ? #1247Alfredo Sanz
SuperadministradorNo, no, no ...
Eso no, no,no ...
No es así ..😳
Realmente, lo que puedes hacer es pasarle valores por GET en lugar de por POST.
La sintaxis sería &<nombre variable>=<valor>
Por ejemplo:
https://samples.nefele.dev/cgi-bin/usuarios.exe?visparam&Nombre=Alfredo&Apellidos=Sanz Pérez
en tu caso pondrías
1:aLinks:= { {"Los mejores desayunos", oCGI:GetEnv("HTTP_REFERER")+"?tuprocedure&tipo=1" }}Alfredo Sanz
SuperadministradorHola tocayo (y por cierto, mi segundo apellido es Pérez),
Aún no están totalmente "nefelizados" los Font Awesome. Para usarlos tendrás que ir "a pelo"
123456789101112131415WITH OBJECT WBevel():New( :WO ):oStyle:cPadding := 15:AddHTML( '<a class="waves-effect waves-light btn-floating blue"><i class="fa fa-twitter faa-burst faa-fast animated-hover"></i> </a>' ):AddHTML( ' ' ):AddHTML( '<a class="waves-effect waves-light btn-floating red" title="Google"><i class="fa fa-google faa-spin animated-hover"></i> </a>' ):AddHTML( ' ' ):AddHTML( ' ' ):AddHTML( '<a class="waves-effect waves-light btn blue" style="color:yellow"> <i class="fa fa-bell faa-ring animated faa-slow"></i></a>' ):AddHTML( ' ' ):AddHTML( '<a class="waves-effect waves-light btn yellow" style="color:#1983d8"> <i class="fa fa-bell faa-ring animated faa-fast"></i></a>' ):AddHTML( ' ' ):AddHTML( ' ' ):AddHTML( '<a class="waves-effect waves-light btn social " style="padding: 9px 9px;color:white"><i class="fa fa-rebel faa-flash animated faa-slow" style="color:#CDDC39"></i>Que la fuerta te acompañe</a>' ):Create()END-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
Alfredo Sanz
SuperadministradorNo, El ListView tiene sus propios botones y métodos para usarlos
123456789101112131415161718192021222324252627282930313233343536PROCEDURE MainPage()WITH OBJECT TWebPage():New()WITH OBJECT WListView():New(:WO):lTitleItem := .T.:cCSS += ".secondary-content { margin-top: -25px;}" //como solo hay una línea, ajustamos el botón un poquico:nItemInPage := 6:nPage := 1:cOnChangePage := "FacturesAjaxChangePage" // Esta es la función a Llamar al cambiar de página:cAjaxPages := "pages" // Este es el wBevel que contiene el wListView y al que hay que enviar la respuesta del AJAXFOR n:=1 TO 10WITH OBJECT :AddItem(N,, "Factura Nº: " + ToString(N) ) AS WItemListViewIF N <> 3 .AND. N <> 6:cOnClickEdit := "visparam":cIconEdit := "print":lEdit := .t.ENDIF:lDelete := .t.:cOnClickDelete := "#alert('aquí lo borramos')"END WITHNEXT:Create()END WITHoCgi:SendPage( :Create() )END WITHRETURNContenido no disponible.
Por favor, acepta las cookies haciendo clic en este aviso-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
Alfredo Sanz
SuperadministradorFenomenal!!
Alfredo Sanz
SuperadministradorAlfredo Sanz
SuperadministradorEstamos preparando una nueva clase para acceso a datos sql basada en ADO y "nefelizada" para su uso en los cgi-
En unos días podré contar algo más
Alfredo Sanz
SuperadministradorRecordad:
Todas las funciones y procedimientos del cgi a las que accedamos desde el navegador (el procedure inicial, los que lanzamos al pulsar un botón, etc) así como los que llamamos por Ajax tienen que estar declarados en el enrutador del main.prg
123456Class TCgi FROM XCgiMETHOD ArrayBrowseAlertOnClick() Inline ArrayBrowseAlertOnClick()METHOD DatosRegistro() Inline DatosRegistro()END CLASSEn cambio, en este caso la función GetRowValue() no hace falta declararla en el enrutados, porque es una función a la que no accedemos "desde fuera" del Cgi, sino que la usamos internamente dentro del propio Cgi. Por lo tanto, no hace falta que la pongamos en el enrutador.
Os dejo el ejemplo funcionando en
https://samples.nefele.dev/cgi-bin/usuarios.exe?ArrayBrowseAlertOnClick
-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
Alfredo Sanz
SuperadministradorEntiendo.
Para el slider realmente las imágenes son fondos de un div.
Lo más sencillo es que todas las imágenes tengan las mismas dimensiones
De todas formas, se puede hacer retocando el css
123456789101112131415161718192021WITH OBJECT TWebPage():New():cCSS += ".img-slider{background-size:contain !important;background-repeat:no-repeat;background-color:white}":cCSS += ".slider .slides{background-color:white}" // y le quitamos el color de fondo de la transición, que queda muy feoWITH OBJECT WSlider():New(:WO):AddItem( "http://xevicomas.duckdns.org:8069/images/@Soft/harbour.png" ):AddItem( "http://xevicomas.duckdns.org:8069/images/@Soft/Nefele Logo.jpg" ):aWidth := {4}:aOffset := {4}:nHeight := 250:nTime := 5:nAnimation := 2:lIndicators := .f.:Create()ENDoCgi:SendPage( :Create() )END WITHRETURN-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
Alfredo Sanz
SuperadministradorTienes las siguientes property
cTitle - Título en negrita
cText - Texto
cBackGroundColor - Color de fondo
cImageUrl - imagen a mostrar en la parte superiorAlfredo Sanz
Superadministrador1 ejemplo, please
Alfredo Sanz
SuperadministradorEso lo viste en los ejemplos de datatables que tiene su propia paginación
El paginador que usamos de materialize es mucho más simple y dá para lo que dá.
De todas formas me apunto buscar un control de paginación más flexible.
Alfredo Sanz
SuperadministradorEn este caso en concreto, si el prg lo tienes como utf-8, StrToXml() realmente te está devolviendo lo mismo que le has enviado. Se puede quitar tranquilamente
Alfredo Sanz
SuperadministradorMe corrijo.
La verdad es que es muy buena idea eso de los ejemplos autocontenidos, he copiado el código que ha publicado Xevi, he compilado y he dado con el problema de una manera muy sencilla ( he tardado 4 minutos)
Tanto es así, que estoy pensando habrir una nueva sección dentro del foro que sea "ejemplos de usuarios" ¿Qué os parece?
Bueno, al lío.
AsciiHTML() es una función que se usa cuando recuperamos datos que nos vienen de otras fuentes distintas al prg ( una base de datos, un archivo de texto, un jSon, etc...)
Como en este caso estamos haciendo referencia a unos caracteres que ya tenemos codificados utf-8 (porque se lo hemos dicho en editor de xailer), no hace falta hacer nada más, Si a una cadena utf-8 le volvemos a decir que nos la codifique en utf-8 (cons el AsciiHTML) nos va ha devolver cosas raras porque ya estaba codificada inicialmente
Para que salga bien, tan solo hace falta quitar los AsciiHTML
Si por ejemplo, la codificación del prg en Xalier es ANSI, para pasar a utf-8 y que se muestren bien, tendríamos que usar
1:cText := StrToXml("Pruebas Néfele4Harbour!!! çÇ ñÑ")Alfredo Sanz
SuperadministradorEso es un problema con las páginas de código
Prueba con StrToXml( cCadena) en lugar de con AsciiHTML y me cuentas.
Alfredo Sanz
SuperadministradorPrueba enlazando el image.o que te adjunto y me cuentas si funciona.
1234567WITH OBJECT WImage():New(:WO):cImage := "https://www.descargarstickers.com/img/2020/09/898758.png":cAction := "https://www.google.com":cUrlParam :="/search?q=nefele":cTarget := "_blank":Create()END WITH-
Esta respuesta fue modificada 3 años, 10 meses por
Alfredo Sanz.
Adjuntos:
Debes acceder para ver los archivos adjuntos.Alfredo Sanz
SuperadministradorHola Daniel,
Pueden ser varias cosas,
Mira en la barra inferior del editor de código de Xailer.
Si te pone ANSI pincha encima y cámbialo a utf-8 en todos los prg
Si no te funcionas probaremos otra cosa
Alfredo Sanz
SuperadministradorAl final del todo, en la línea 123 prueba a poner
class WTabs FROM ZTabs
ENDCLASSVoy a revisarlo, pero creo que nos dejamos por definir la wTabs
Alfredo Sanz
SuperadministradorCorrecto!
Ten en cuenta que cuanto tú ves el html en el navegador, el cgi ya se ha hecho todo su trabajo e incluso se ha descargado de la memoria del servidor. Así, cuando un usuario está viendo la página web realmente no está consumiendo ningún recurso del servidor. El servidor solo entra en acción cuando construimos la página, con lo cual puedes dar servicio a una gran cantidad de clientes con un servidor con pocos recursos.
Creo que lo he comentado alguna vez: https://samples.nefele.dev es un servidor web con 1Gb de memoria ram.
Alfredo Sanz
SuperadministradorMe corrijo.
Entre la línea 6 y la 7 pon:
:lAlerts := .T.
El problema lo tienes porque al ser una llamada Ajax, el WebPage no tiene constancia de que se van a usar alertas y por lo tanto no carga el módulo js correspondiente
Poniendo :lAlerts := .t. en el Webpage le estamos diciendo que aunque (de momento) no lo necesite, carge el módulo de alertas porque no va a hacer falta luego
Alfredo Sanz
Superadministradorponle un ocgi:console( cHtml ) antes de la línea 53 a ver qué nos dice
Alfredo Sanz
SuperadministradorTen en cuenta que la programación web utiliza un protocolo "stateless", esto es, cada llamada a una página es indendiente de la anterior, por lo cual no pueden exister variables públicas tal y como las conocemos y tenemos que "hacer magia" para conseguirlas
En néfele esta magia la hacen dos métodos de la clase oCgi
oCgi:SetUserData( cVar, uVal )
Permite guardar una variable y su valor para ser recuperada posteriormente en otra llamada al cgi
oCgi:GetUserData( cVar, uDefaultVal, lCreate )
Recupera una variable previamente guardada
cVar: Nombre de la variable a recuperar
uDefaultVal: Valor por defecto a asignar en caso de que la variable indicada no exista
lCreate: Si la variable no existe, la crea para futuros usosAlfredo Sanz
SuperadministradorOk Xevi,
Gracias por le aporte
Alfredo Sanz
SuperadministradorNo.
La llamada la tienes que hacer por Ajax,
debajo del :cOnClick := "xCopyAndShow" pon:
:cAjaxBevel := "nflCargo"
y cuando haces el SendScript no hace falta que pongas el Tag("script
Es suficiente poner
oCGI:SendScript( "window.open( '/download/" +cPdf+".pdf' )" )
Pruébalo y me cuentas
Alfredo Sanz
SuperadministradorHola Daniel.
Es un tipo de datos conocido como Hash.
Son muy parecidos a las matrices o arrays, pero con la peculiaridad de que puedes hacer referencia a los elementos, no por un número, sino por un nombre
Con arrays tendríamos esto:
aDatos := {}
aAdd( aDatos, Alfredo)
oCGI:Console( aDatos[1])
y nos mostraría Alfredo en el nefele console
Con Hasesh lo haríamos así
hDatos := {=>}
hDatos["nombre"] := "Alfredo"
oCGI:Console( hDatos["nombre"])
Alfredo Sanz
SuperadministradorCorrecto, le pasas parámetros adicionales cuando pulsas en la imagen.
Alfredo Sanz
SuperadministradorPrueba con oCGI:GetCodefCookie("acceso"):Valor y con oCGI:GetCodefCookie("acceso"):Raw
Alfredo Sanz
SuperadministradorEso es porque están en "modo debug"
Para facilitar la programación, cuando compilas con el debug no la encripta para que puedas ver su contenido.
Si compilar sin debug es cuando te la encripta
Alfredo Sanz
SuperadministradorEso es porque no tienes las librerías de Néfele asignadas al proyecto
Vete a las propiedades del proyecto y revisa que en la sección librerías tienes la correspondiente a NefeleProject.
Si no la tienes pulsa en añadir y localiza el fichero libNefeleProject.a y añádelo
Alfredo Sanz
SuperadministradorSi claro,
Revisa este vídeo https://www.youtube.com/watch?v=6P10L0UdnPM
Ten en cuenta que Néfele es Xailer, por lo cual tanto el cliente como el servidor del api rest puede estar en la app de Néfele.
Alfredo Sanz
SuperadministradorLo que nos está avisando Néfele es que tenemos un control sin oParent (el WMsgAlert():New()) cosa que en este caso es correcto
Tenemos que afinar aún un poquito estos mensajes
Alfredo Sanz
SuperadministradorXevi,
oCGI:SendCodefCookie("acceso","102",600,600,"2")
Las hemos nombrado empezando con Send y no con Set porque es un dato que enviamos al naveador del cliente
Alfredo Sanz
SuperadministradorResumen modificaciones Néfele 0.3
- NéfeleWizard
+ Podemos indicarle la carpeta de Apache y de Xailer de manera manual
+ Nos permite crear un proyecto Néfele vacio, solo con el enrutados y una página con "Hola Mundo"
% Si seleccionamos un combre de carpeta con un espacio, se sustituye en el proyecto y en el alias por un guion medio "-"- wArrayBrowse
+ PROPERTY lIncludeArray INIT .t. // incluye un array json en el html con los datos de la tabla
+ PROPERTY aSaveData INIT {} // Datos a incluir en el array anterior, por defecto toda la tabla
+ FUNCTION jSonToArray( cId ) // Retorna el codigo javascript para convertir el json en un array javascript RETURN 'JSON.parse(document.querySelector("'+cId+'").value)'
% el Width de la columna ahora puede ser un % (si :nWidth es numérico) o la medida css indicada ( si es una cadena)
+ Ahora el valor de cada elemento del array a mostrar puede ser a su vez un array de tipo { valor a mostrar, tooltip a mostrar }- wItemColBrowse
+ PROPERTY cMacro INIT "" // Control a evaluar en la creación de la columna
+ PROPERTY cToolTip INIT "" // tooltip de la celda- wBadge
// Nuevo Control para la creación de Badge
% Para forzar a que calcule correctamente el ancho del Badge en lChip, reemplazamos los espacios de cText por
+ PROPERTY lChips // El Badget se presenta como un wChips
+ PROPERTY lPulse // Se presenta con efecto Pulse
+ PROPERTY lShadow // Se presenta con sombra
+ PROPERTY cImage // Imagen
+ PROPERTY cAltImage // texto Alternativo
+ PROPERTY cIcon // Icono que aparecera a la izquierda
+ PROPERTY cClrIcon // Color del Icono
% METHOD Set( cText, cClass, lBold, lNew, lPulse, cClrPane, cClrText )
+ METHOD SetArray( aProperties ) // aProperties := {cText, cClass, lBold, lNew, lPulse, cClrPane, cClrText}- wBevel
+ Incorporadas funcionalidades de wPanel
+ PROPERTY lShowFocus INIT .f. // Se resalta al pasar el raton por encima
+ PROPERTY lUseCard INIT .f.
+ PROPERTY nShadowDeep INIT 2 // Tipo de sombra a usar
+ PROPERTY cText INIT "" WRITE INLINE ::FcText := ::AdjustText( Value )
+ PROPERTY cClrTitle INIT "" WRITE INLINE ::FcClrTitle := CheckClr(Value)
+ PROPERTY nFontTitle INIT 5 // Tamaño de la Fuente segun Materialize para el Titulo
+ PROPERTY cTitleAlign INIT xc_Left // Alineación del Titulo
+ PROPERTY lLine INIT .F. // Pone una linea horizontas bajo el Title
+ PROPERTY cBackground // Fondo de la Página (realmente: fondo del tag <main>
+ PROPERTY cBackgroundSize // Tamaño del fondo
+ PROPERTY cBackgroundColor INIT "" // Color del fondo
+ PROPERTY lBackgroundRepeat INIT .T.
+ PROPERTY cBackgroundAlign INIT "center center" // Horizontal y Vertical- wBevelFoot
+ PROPERTY lScroolBars INIT .f. // para que no salgan las barras en el footer modal
% El cId de bevelfooter pasa a ser el cId del bevel + "_" + ::cClassId- wButton
+ PROPERTY cClrText INIT "" // Anunque la heredaba de wControl no se estaba aplicando en el Create
! PROPERTY lBold Ponia <strong> y no se notaba, lo sustitui por <b>
+ PROPERTY lHide INIT .f. // oculta el botón
// Llamada a URL externa con o sin parametros por POST y GET
cAction := URL a llamar
cUrlParam := Parametros a enviar por GET
aParams := Parametros a enviar por POST
Por defecto los parametros por POST se encriptan, se puede deshabilitar en ::lEncript
+ PROPERTY aDefaultClass INIT {'waves-effect waves-light'} //Clases por defecto a aplicar al boton
+ PROPERTY cIconWidth INIT "20px" // Tamaño por defecto del icono
+ PROPERTY nIconRotate // Rotacion en º a aplicar al icono
+ PROPERTY cToolTip- wCard
+ Pasa a ser un objeto contenedor dentro del que podemos añadir otros controles, se incuyen en la parte baja
del card en el area difinida como 'class="card_action"'.- wChips
+ PROPERTY lPulse // Se presenta con efecto Pulse
+ PROPERTY lShadow // Se presenta con sombra- tCGI
+ METHOD aParamsToHash( lMini )
// lMini == .T. { Params1 => value1, Params2 => value2, ... }
// lMini == .F. { Params1 => { value => value1, tmpfile => tmpfile, type => type}, ...}
! SendHardCookie no funcionaba bien para formatos fechas. Formato correcto: oCGI:SendHardCookie("Variable","Valor","2020100215:00:00")
+ METHOD SendJSon( cJSon ) // Para hacer envios de JSon bien declarado, no envia cTTFB
+ PROPERTY aColors INIT ArrayColors()
+ PROPERTY cSameSitePolicy INIT "lax" //protección cookies //https://www.tarlogic.com/blog/same-site-cookies-ataques-csrf/
% Modificado SendStatus para que funcione lNoCache en Firefox
% METHOD SendScript // Lo he modificado para que no incluya <script></script> porque ya enviamos el tipo mime como application/javascript"
+ METHOD TimeSuicide() // para contener todo el codigo a ejecutar para "Suicidar" nuestro CGI
% Modificado Suicide() para que utilize TimeSuicide()
+ PROPERTY nSuicideInterval INIT 50 // segundos para que arranque el suicide
+ PROPERTY lPreloadCss INIT .f. //lee los css en modo precarga
% En las cookies codificadas, el cambio de navegador ahora informa de un error pero no invalida el cookie- wEdit
+ Aplicación de la propiedad cAlingSymbol del oMask cuando ::oMask:cPicture == "currency"
% En la creación de Edit de Fecha se estaba definiendo dos veces minDate y faltaba maxDate
+ METHOD Code() INLINE ::ohtml:cInMain
+ PROPERTY cToolTip
% cAjaxTimeout ahora se ejecuta cambién cuando el control pierde el foco- wFileOpenDlg
+ PROPERTY cAcceptExt INIT {} // extensiones permitidas
+ PROPERTY lRequired INIT .t.
+ PROPERTY cHint // Mensaje que aparece en el control cuando esta vacio, tenga o no el foco- wImage
+ PROPERTY cImage2 INIT "" // imagen a mostar si pasamos el cursor sobre la principal
+ PROPERTY cAlt2 INIT ""
+ PROPERTY lClickZoom INIT .T. // Zoom al hacer click en la imagen
% Quitado el cursor default a pointer. Da la sensación de que se puede hacer click para ir a otro sitio y puede resultar confuso. siempre tenemos :cCursor
+ PROPERTY cAlt INIT "" // permite asignar un alt a la imagen- wItemListView
% En Firefox en el Badge se cortaba cText, si era lChips no pasaba
- PROPERTY cBadgeClass INIT "bold" // clase a aplicar a los badges en el listview
+ PROPERTY oBadge // para aplicar los badges en el listview- wMask
+ PROPERTY cAlingSymbol INIT xc_Right Valores xc_right,xc_left
// Para posicionar el simbolo de la moneda a la Derecha o a la Izquierda
+ PROPERTY lAutoUnmask INIT .t. // Elimina los caracteres propios de la máscara al consultar el valor
+ PROPERTY cValidatorAPlaceHolder INIT " " //Caracter del placeholder
+ PROPERTY cValidatorBPlaceHolder INIT " " //Caracter del placeholder- NefeleFunctions
+ FUNCTION ArrayColors() // Nos da la lista completa de los colores de Materialize { "#rrggbb", "nombre", .F.}
% FUNCTION CheckClr( cClr )
cClr puede ser:
Un valor númerico resultante de rgb(50,255,255)
Una cadena "#rrggbb"
o una cadena "rgb(r,g,b)"
Si corresponde con un color de Materialize nos renorna la Clase del color, si no crea una clase nueva nfl-rrggbb
y la añade a oCGI:aColors para evitar duplicados
+ FUNCTION ReplaceClrMaterialize( cItem, nCol ) // Busca cItem en la lista de colores Materialize y nos retorna la hexadecimal, si no lo encuentra nos retorna cItem
% Ahora, la creación de iconos en todo nefele se hace a través de FUNCTION PutIcon()
+ UpdateAjaxById( {{ "id del elemento", valor},{...}}) // actualiza el .value del control con el id indicado con el nuevo valor
+ ReplaceChars( cInput, cSearch, cReplace ) -> cOutput
+ FUNCTION PreloadCss( cCss ) // Permite la precarga del css indicado para evitar bloqueos- wPanel
% Pasa a heredar las funcionalidades de wBevel
+ PROPERTY lUseCard INIT .T. // si .f. no pone la clase Card al panel, que en algunos casos de problemas de ajuste- wRebar
% si cClrText tiene contenido, se lo asigna a cClrTitle, dado que en la mayoría de los controles usamos cCrlText- wSeparator
+ PROPERTY cProgressClr INIT ""
+ PROPERTY cProgressPane INIT ""
+ PROPERTY nProgress // muestra un preloader horizontal dentro del separator con el % de linea indicado. si es -1 lo hace indeterminate https://materializecss.com/preloader.html- wSideNav
% METHOD AddItem(cText,cOnClick,cIcon,nStyle,aParams,cAction,aBadge) // añadido aBadge {{texto[, clase a utilizar (new) y color]}} // añade badges al menu
+ PROPERTY cTitleClass INIT "z-depth-5" // Clase a aplicar al Title del menu- wItemSidenav
+ PROPERTY oBadge // para aplicar los badges en el SideNav- wSplitButton
% METHOD AddItem(cOnClick, cIcon, cText, lDivider, aParams, cAjaxBevel, lModalResult, aBadge) // añadido aBadge {{texto[, clase a utilizar (new) y color]}} // añade badges- wItemFloatButton
+ PROPERTY oBadge // para aplicar los badges en el wSpliButton
// Pordefecto oBadge:lNew := .T.- wTabs
// Nuevo Control de Tabs
+ PROPERTY cClassId INIT "tab"
+ PROPERTY aWidth init {,,,} // Ojo que no funciona bien materialize
+ PROPERTY aItems INIT {}
+ PROPERTY lFixedWidth INIT .t.
+ METHOD AddItem( cTitle, cTarget, lDisabled, lDefault)- wItemTabs
+ PROPERTY cFolder // id del bevel asociado
+ PROPERTY cTitle
+ PROPERTY lDisabled INIT .f.
+ PROPERTY lDefault INIT .F. // Pestaña por defecto- tWebPage.prg
+ PROPERTY aBreadCrumbs INIT {} // Pone breadcrumbs al pie de página {{url,texto},...}
+ PROPERTY lSnippet INIT .T. // si .f. no pone description en serp
+ PROPERTY cDescription INIT Application:cDescription //permite un meta description personalizado para la página
% Movida la sábana al pie de página para que no afecte al seo en buscadores
% No se estaban cerrando bien los <div> del Footer cuando habia Links
+ PROPERTY lCanonical INIT .T. // permite establecer la url canónica de la web. de momento: la misma url sin acentos y cambiando espacios por guiones
! En el fooder no aplicaba bien :cTitleFooter
% si no se establece :cTitleFooter por defecto pasa a ser :cTitle
+ PROPERTY cUri // cambia la url de la barra del navegador
+ PROPERTY cSearchConsoleCode INIT "" // Identificador para validar Search Console
+ PROPERTY lIndex INIT .T. // Si los robots indexan o no la página
+ PROPERTY lFollow INIT .T. // Si los robot hacen un follo de la página
+ PROPERTY lTrackUserAgent INIT .T. // Crea el fichero TrackUserAgent donde se registra fecha, hora, ip y useragent de todos los accesos
+ PROPERTY lJsMaterialize INIT .t. //Usamos Javascript materialize
% Actualizada versión de jQuery a la 3.5.1
% Cambiada la posición del shadowsheet para que ocupe toda la páginaAlfredo Sanz
SuperadministradorVaya,
Por favor, comprueba que en el proyecto estás utilizando la librería correspondiente a la última versión.
He compilado tu ejemplo y no me da ningún error
https://samples.nefele.dev/ejemplo?ejemplo
Alfredo Sanz
SuperadministradorVaya, tendría que ver el código para saber qué está saliendo mal.
Mándame la sección de tu prg en la que defines el wArrayBrowse y su columnas y lo reviso.
Este es un fragmento de uno de nuestros ejemplos, por si te puede servir de ayuda
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950WITH OBJECT oBrowse := WArrayBrowse():New( oPanel ):cId := "Bancos":nStyle := xc_Striped:cOnClick := "VisParam":cCursor := "pointer":cAjaxBevel := "modal1":lModalResult := .T.:aWidth[ _movil ]:= 12:oStyle:cPadding := "0px":cClrHeadText := "red":nIndexValue := 1:cAjaxUrl := 'recuperartabla':cAjaxSearch := "buscar":nAjaxPaginate := 20:nContador := nContador// Añadimos ColumnasWITH object :AddCol( "Cod" ) AS wItemColBrowse:cClrPane := "red":cOnClick := "pruebaspedro":cClrText := "white":nWidth := 1END WITHWITH object :AddCol( "BIC",, xc_Right ) AS WItemColBrowse:lBold := .T.:nWidth := 5:cClass := "hide-on-small-only" //https://materializecss.com/helpers.html#hidingEND WITHWITH object :AddCol( "Entidad", xc_Left, xc_Left ):nWidth := 100WITH object :oStyle as wStyle:cColor := "blue"ENDENDWITH object :AddCol( "", xc_Center, xc_Center ):cId := "editar":nWidth := 1:cClrText := "blue":cOnClick := "editarmodalNew":cAjaxBevel := "NflCargo"ENDAlfredo Sanz
SuperadministradorRev.214b (12-08-2020)
oEdit:oMask
+ PROPERTY lAutoUnmask INIT .t. // Elimina los caracteres propios de la máscara al consultar el valorAlfredo Sanz
SuperadministradorRev.214 (12-08-2020)
WebPage
% Cambiada la posición del shadowsheet para que ocupe toda la páginaCgi
% En las cookies codificadas, el cambio de navegador ahora informa de un error pero no invalida el cookie-
Esta respuesta fue modificada 4 años por
Alfredo Sanz.
Alfredo Sanz
Superadministrador===== PUBLICADA LA VERSIÓN 0.02 DE NEFELE ====
Os la podéis descargar de https://nefele.dev/blog/download/nefele-wizard-0-02/
Alfredo Sanz
SuperadministradorHola Ramón:
Hemos publicado la versión 0.02 de Néfele.
Descárgatela de https://nefele.dev/blog/download/nefele-wizard-0-02/ y me cuentas si se ha solucionado el problema
Alfredo Sanz
SuperadministradorPrueba con
1:oMask:lShowMask := .f.Alfredo Sanz
SuperadministradorYa, entiendo.
Si ponemos :oMask:cPicture := "A{1,25}" estamos diciendo que nos aplique el picture de tipo A con una longitud máxima de campo de 25 caracteres, con lo cual no hace falta usar la propiedad :nLength
12345WITH OBJECT WEdit():New( :WO ):cId := "Titulo":oMask:cPicture := "A{1,20}":Create()END WITHes lo mismo que
123456WITH OBJECT WEdit():New( :WO ):cId := "Titulo":oMask:cPicture := "A":nLenght := 20:Create()END WITHPero procura no ponerlos juntos
123456WITH OBJECT WEdit():New( :WO ):cId := "Titulo":oMask:cPicture := "A{1,20}":nLenght := 20:Create()END WITHPorque esto intenta asignar la longitud dos veces y no funcionará
Alfredo Sanz
SuperadministradorEfectivamente, he detectado un bug en lUpperCase
Por ahora, puedes probar con :oMask:cPicture := "A{ 1, nLen }", donde nLen es la longitud máxima de caracteres a introducir
Delphi/Pascal12345WITH OBJECT WEdit():New( :WO ):cId := "Titulo":oMask:cPicture := "A{1,20}":Create()END WITHYa nos contarás si te funciona
La clase oMask está basada en el InputMask de Robin Herbots (https://github.com/RobinHerbots/Inputmask)
-
Esta respuesta fue modificada 4 años por
Alfredo Sanz.
-
Esta respuesta fue modificada 4 años por
Alfredo Sanz.
-
Esta respuesta fue modificada 4 años por
Alfredo Sanz.
-
AutorEntradas