La idea era poder entender el funcionamiento del webview2, para poder aplicarlo a mediano plazo en nuestras aplicaciones, esta creado en html5, css y javascript puro, para los maestros, es posible que se pueda simplificar mucho el c贸digo usado, sobre todo del lado de javascript; ya teniendo otros recursos como un servidor, podemos enlazar librer铆as como jquery y boostrap.
Como digo fue montado para entender el funcionamiento webview2, lo compartimos por si alguien alg煤n d铆a llega a necesitarlo, le interesa y quiz谩s le sirva de gu铆a.
Con esto lo que pretendemos es poder mejorar en MUCHO la parte visual o interfase de usuario de nuestras apps, apoy谩ndonos en las maravillas que permite el html y sus amigos jejejeje.
Esperamos les sirva.
Pdta. Apenas nos quede un tiempito vamos a generar un reporte tipo html para ser enviado a la impresora.



webview_custo.prg
#include "FiveWin.ch"
static oWebView
static d_custo
function Main()
聽 聽 Local oWnd,cHtml
聽 聽 USE "customer.dbf" ALIAS d_custo NEW EXCLUSIVE VIA "DBFCDX"
聽 聽 INDEX ON d_custo->id TAG "id"
聽 聽 d_custo->(OrdSetFocus("id"))
聽 聽
聽 聽 cHtml := buildHtml()
聽 聽 DEFINE WINDOW oWnd TITLE "Information maintenance" SIZE 1200, 800
聽 聽 聽 聽 oWebView = TWebView2():New( oWnd )
聽 聽 聽 聽 oWebView:SetHtml( cHtml )
聽 聽 聽 聽 oWebView:InjectJavascript( cJavascript() )
聽 聽 聽 聽 oWebView:bOnBind = { | cJson, cCalls | whatscoming( cJson ) }聽 聽聽 聽
聽 聽 聽 聽 //oWebView:OpenDevToolsWindow()
聽 聽 ACTIVATE WINDOW oWnd CENTER ON RESIZE oWebView:SetSize( nWidth, nHeight ) VALID (d_custo->(DbCloseArea()),.T.)
聽 聽 oWebView:End()
return nil
function whatscoming( cJson )
聽 聽 Local oDlg,oGId,oGNm,oGAp,oGDi,oGEd,oGCi,oGSa
聽 聽 Local cName, cLast,cStreet,cCity,cAge,cSalary,cIdBack
聽 聽 Local nGId := 0
聽 聽 Local nGEd := 0
聽 聽 Local nGSa := 0
聽 聽 Local nIdDbf := 0
聽 聽 Local cGNm := space(0)
聽 聽 Local cGAp := space(0)
聽 聽 Local cGDi := space(0)
聽 聽 Local cGCi := space(0)
聽 聽 Local cIdRow := space(0)
聽 聽 Local cInsRow := space(0)
聽 聽 Local nAction := cJson[1]["action"]
聽 聽 if nAction==1
聽 聽 聽 聽 nGId := cJson[1]["datos"][1]
聽 聽 聽 聽 cGNm := cJson[1]["datos"][2]
聽 聽 聽 聽 cGAp := cJson[1]["datos"][3]
聽 聽 聽 聽 cGDi := cJson[1]["datos"][4]
聽 聽 聽 聽 cGCi := cJson[1]["datos"][5]
聽 聽 聽 聽 nGEd := val(cJson[1]["datos"][6])
聽 聽 聽 聽 nGSa := val(strtran(cJson[1]["datos"][7],",",""))
聽 聽 聽 聽
聽 聽 聽 聽 DEFINE DIALOG oDlg SIZE 350,250 PIXEL TRUEPIXEL TITLE "Edit Row"
聽 聽 聽 聽 聽 聽 @ 14, 聽15 SAY "Id :" SIZE 100,24 PIXEL OF oDlg
聽 聽 聽 聽 聽 聽 @ 10, 聽88 GET oGId VAR nGId SIZE 50,24 PIXEL OF oDlg PICTURE "999" RIGHT
聽 聽 聽 聽 聽 聽 @ 40, 聽15 SAY "Name :" SIZE 100,24 PIXEL OF oDlg
聽 聽 聽 聽 聽 聽 @ 36, 聽88 GET oGNm VAR cGNm SIZE 140,24 PIXEL OF oDlg PICTURE "@N"
聽 聽 聽 聽 聽 聽 @ 66, 聽15 SAY "Last :" SIZE 100,24 PIXEL OF oDlg
聽 聽 聽 聽 聽 聽 @ 62, 聽88 GET oGAp VAR cGAp SIZE 140,24 PIXEL OF oDlg PICTURE "@N"
聽 聽 聽 聽 聽 聽 @ 92, 聽15 SAY "Adress :" SIZE 100,24 PIXEL OF oDlg
聽 聽 聽 聽 聽 聽 @ 88, 聽88 GET oGDi VAR cGDi SIZE 200,24 PIXEL OF oDlg PICTURE "@N"
聽 聽 聽 聽 聽 聽 @ 118, 聽15 SAY "City :" SIZE 100,24 PIXEL OF oDlg
聽 聽 聽 聽 聽 聽 @ 114, 聽88 GET oGCi VAR cGCi SIZE 140,24 PIXEL OF oDlg PICTURE "@N"
聽 聽 聽 聽 聽 聽 @ 144, 聽15 SAY "Age :" SIZE 100,24 PIXEL OF oDlg
聽 聽 聽 聽 聽 聽 @ 140, 聽88 GET oGEd VAR nGEd SIZE 40,24 PIXEL OF oDlg PICTURE "999" SPINNER
聽 聽 聽 聽 聽 聽 @ 170, 聽15 SAY "Salary :" SIZE 100,24 PIXEL OF oDlg
聽 聽 聽 聽 聽 聽 @ 166, 聽88 GET oGSa VAR nGSa SIZE 100,24 PIXEL OF oDlg PICTURE "999,999.99" RIGHT
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 @ 220,15 BUTTONBMP OF oDlg PIXEL size 95, 24 PROMPT "Close" ACTION oDlg:End()
聽 聽 聽 聽 聽 聽 @ 220,120 BUTTONBMP OF oDlg PIXEL size 120, 24 PROMPT "Update" //ACTION oDlg:End()
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 oGId:disable()
聽 聽 聽 聽 聽 聽 oDlg:lHelpIcon := .F.
聽 聽 聽 聽
聽 聽 聽 聽 ACTIVATE DIALOG oDlg CENTERED聽 聽
聽 聽
聽 聽 elseif nAction==2
聽 聽 聽 聽 if msgnoyes("Confirm delete row ?","Confirm")
聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 nIdDbf := val(cJson[1]["datos"][1])
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 SELECT d_custo
聽 聽 聽 聽 聽 聽 DELETE FOR d_custo->id = nIdDbf
聽 聽 聽 聽 聽 聽 PACK
聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 cIdRow := "row_"+alltrim(cJson[1]["datos"][1])
聽 聽 聽 聽 聽 聽 oWebView:Eval( "deleterowhtmltable( '"+cIdRow+"' )" )
聽 聽
聽 聽 聽 聽 endif
聽 聽 elseif nAction==0
聽 聽
聽 聽 聽 聽 nIdDbf := cJson[1]["datos"][1]
聽 聽 聽 聽 cName := cJson[1]["datos"][2]
聽 聽 聽 聽 cLast := cJson[1]["datos"][3]
聽 聽 聽 聽 cStreet := cJson[1]["datos"][4]
聽 聽 聽 聽 cCity := cJson[1]["datos"][5]
聽 聽 聽 聽 cAge := val(cJson[1]["datos"][6])
聽 聽 聽 聽 cSalary := val(cJson[1]["datos"][7])
聽 聽
聽 聽 聽 聽 SELECT d_custo
聽 聽 聽 聽 Dbgotop()
聽 聽 聽 聽 if !dbseek(nIdDbf)
聽 聽 聽 聽 聽 聽 dbappend()
聽 聽 聽 聽 聽 聽 //d_custo->id := nIdDbf //Incremental
聽 聽 聽 聽 聽 聽 d_custo->first := cName
聽 聽 聽 聽 聽 聽 d_custo->last := cLast
聽 聽 聽 聽 聽 聽 d_custo->street := cStreet
聽 聽 聽 聽 聽 聽 d_custo->city := cCity
聽 聽 聽 聽 聽 聽 d_custo->age := cAge
聽 聽 聽 聽 聽 聽 d_custo->salary := cSalary
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 cIdBack := cValtochar(d_custo->id)
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 oWebView:Eval( "insertrowhtmltable('"+cIdBack+"','"+transform(cSalary,"999,999.99")+"');")
聽 聽 聽 聽 else
聽 聽 聽 聽 聽 聽 //With any of these options you can inform the user that the id already exists
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 //msginfo("The id you are trying to enter already exists","Error")
聽 聽 聽 聽 聽 聽 //oWebView:Eval( "document.getElementById('spn_id').innerHTML='<br>Exists'")
聽 聽 聽 聽 聽 聽 oWebView:Eval( "alert('The id you are trying to enter already exists');")
聽 聽 聽 聽 endif
聽 聽 聽 聽
聽 聽 聽 聽
聽 聽 聽 聽
聽 聽 endif
聽 聽
return nil
function buildHtml()
聽 聽 Local cHead,cFoot
聽 聽 Local cHtml := space(0)
聽 聽 Local cTable := space(0)
聽 聽
聽 聽 TEXT INTO cHead
聽 聽 聽 聽 <!DOCTYPE html>
聽 聽 聽 聽 <html lang="es">
聽 聽 聽 聽 <head>
聽 聽 聽 聽 聽 聽 <meta charset="UTF-8">
聽 聽 聽 聽 聽 聽 <style>
聽 聽 聽 聽 聽 聽 聽 聽 body {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 background-color: #e4f2ff;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 display: flex;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 flex-direction: column;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 min-height: 100vh;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .main-content {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 padding: 20px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 flex-grow: 1;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 overflow-y: auto;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .table-container {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 overflow-x: auto;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .table {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 background-color: #fff;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 min-width: 600px; /* Asegura que la tabla no se comprima demasiado en m贸viles */
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 h2 {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 color: #0064a5;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 footer {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 background-color: #0064a5;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 color: #fff;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 text-align: center;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 padding: 2rem 0;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 margin-top: auto;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .btntbl {
聽 聽 聽 聽 聽 聽 聽 聽 聽 border: none;
聽 聽 聽 聽 聽 聽 聽 聽 聽 color: white;
聽 聽 聽 聽 聽 聽 聽 聽 聽 padding: 5px 10px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 cursor: pointer;
聽 聽 聽 聽 聽 聽 聽 聽 聽 border-radius: 5px;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .primary {background-color: #007bff;}
聽 聽 聽 聽 聽 聽 聽 聽 .primary:hover {background: #0b7dda;}
聽 聽 聽 聽 聽 聽 聽 聽 .secondary {background-color: #e7e7e7; color: black;}
聽 聽 聽 聽 聽 聽 聽 聽 .secondary:hover {background: #ddd;}
聽 聽 聽 聽 聽 聽 聽 聽 .success {background-color: #04AA6D;}
聽 聽 聽 聽 聽 聽 聽 聽 .success:hover {background-color: #46a049;}
聽 聽 聽 聽 聽 聽 聽 聽 .warning {background-color: #ff9800;}
聽 聽 聽 聽 聽 聽 聽 聽 .warning:hover {background: #e68a00;}
聽 聽 聽 聽 聽 聽 聽 聽 .danger {background-color: #f44336;}
聽 聽 聽 聽 聽 聽 聽 聽 .danger:hover {background: #da190b;}
聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 聽 聽 .form-group {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 margin-bottom: 15px;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .form-group label {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 display: flex;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 font-size: 16px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 font-weight: bold;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 margin-bottom: 2px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 color: #0693e3;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .form-group input {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 width: 90%;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 padding: 5px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 font-size: 14px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 border-radius: 5px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 border: 1px solid #0693e3;
聽 聽 聽 聽 聽 聽 聽 聽 }聽 聽
聽 聽 聽 聽 聽 聽 聽 聽 .msg{
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 color: #f44336;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 聽 聽 /* The Modal (background) */
聽 聽 聽 聽 聽 聽 聽 聽 .modal {
聽 聽 聽 聽 聽 聽 聽 聽 聽 display: none; /* Hidden by default */
聽 聽 聽 聽 聽 聽 聽 聽 聽 position: fixed; /* Stay in place */
聽 聽 聽 聽 聽 聽 聽 聽 聽 z-index: 1; /* Sit on top */
聽 聽 聽 聽 聽 聽 聽 聽 聽 padding-top: 20px; /* Location of the box */
聽 聽 聽 聽 聽 聽 聽 聽 聽 left: 0;
聽 聽 聽 聽 聽 聽 聽 聽 聽 top: 0;
聽 聽 聽 聽 聽 聽 聽 聽 聽 width: 100%; /* Full width */
聽 聽 聽 聽 聽 聽 聽 聽 聽 height: 100%; /* Full height */
聽 聽 聽 聽 聽 聽 聽 聽 聽 overflow: auto; /* Enable scroll if needed */
聽 聽 聽 聽 聽 聽 聽 聽 聽 background-color: rgb(0,0,0); /* Fallback color */
聽 聽 聽 聽 聽 聽 聽 聽 聽 background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 /* Modal Content */
聽 聽 聽 聽 聽 聽 聽 聽 .modal-content {
聽 聽 聽 聽 聽 聽 聽 聽 聽 background-color: #fefefe;
聽 聽 聽 聽 聽 聽 聽 聽 聽 margin: auto;
聽 聽 聽 聽 聽 聽 聽 聽 聽 padding: 20px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 border: 1px solid #888;
聽 聽 聽 聽 聽 聽 聽 聽 聽 width: 40%;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 /* The Close Button */
聽 聽 聽 聽 聽 聽 聽 聽 .close {
聽 聽 聽 聽 聽 聽 聽 聽 聽 color: #aaaaaa;
聽 聽 聽 聽 聽 聽 聽 聽 聽 float: right;
聽 聽 聽 聽 聽 聽 聽 聽 聽 font-size: 28px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 font-weight: bold;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 .close:hover,
聽 聽 聽 聽 聽 聽 聽 聽 .close:focus {
聽 聽 聽 聽 聽 聽 聽 聽 聽 color: #000;
聽 聽 聽 聽 聽 聽 聽 聽 聽 text-decoration: none;
聽 聽 聽 聽 聽 聽 聽 聽 聽 cursor: pointer;
聽 聽 聽 聽 聽 聽 聽 聽 }聽 聽
聽 聽 聽 聽 聽 聽 聽 聽 table.tableSection {
聽 聽 聽 聽 聽 聽 聽 聽 聽 display: table;
聽 聽 聽 聽 聽 聽 聽 聽 聽 width: 100%;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 table.tableSection thead,
聽 聽 聽 聽 聽 聽 聽 聽 table.tableSection tbody {
聽 聽 聽 聽 聽 聽 聽 聽 聽 width: 100%;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 table.tableSection thead {
聽 聽 聽 聽 聽 聽 聽 聽 聽 overflow-y: scroll;
聽 聽 聽 聽 聽 聽 聽 聽 聽 display: table;
聽 聽 聽 聽 聽 聽 聽 聽 聽 table-layout: fixed;
聽 聽 聽 聽 聽 聽 聽 聽 聽 width: calc(100% - 16px); /* assuming scrollbar width as 16px */
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 table.tableSection tbody {
聽 聽 聽 聽 聽 聽 聽 聽 聽 overflow: auto;
聽 聽 聽 聽 聽 聽 聽 聽 聽 height: 500px;
聽 聽 聽 聽 聽 聽 聽 聽 聽 display: block;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽 table.tableSection tr {
聽 聽 聽 聽 聽 聽 聽 聽 聽 width: 100%;
聽 聽 聽 聽 聽 聽 聽 聽 聽 text-align: left;
聽 聽 聽 聽 聽 聽 聽 聽 聽 display: table;
聽 聽 聽 聽 聽 聽 聽 聽 聽 table-layout: fixed;
聽 聽 聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 聽 聽 table.tableSection tr:hover {
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 background-color: #f8f9fa;
聽 聽 聽 聽 聽 聽 聽 聽 }聽 聽聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 </style>
聽 聽 聽 聽 </head>
聽 聽 聽 聽 <body>
聽 聽 聽 聽 聽 聽 <div class="container-fluid">
聽 聽 聽 聽 聽 聽 聽 聽 <div class="row">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <!-- Contenido principal -->
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4 main-content">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <!-- Trigger/Open The Modal -->
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <button id="myBtn" onclick="openmodal();" class="btntbl success">New</button>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <h2 class="mb-4">Customer Table </h2>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="table-container">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <table class="tableSection" id="tbl_cstm">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <thead>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <tr>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th style="width:25px">ID</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th style="width:100px">Name</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th style="width:100px">Last</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th style="width:220px">Adress</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th>City</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th>Age</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th>Salary</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <th colspan="2">Actions</th>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </tr>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </thead>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <tbody id="tableBody">
聽 聽 ENDTEXT
聽 聽
聽 聽
聽 聽 TEXT INTO cFoot
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </tbody>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </table>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </main>
聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 <footer>
聽 聽 聽 聽 聽 聽 聽 聽 <p>漏 2024 My App. All rights reserved.</p>
聽 聽 聽 聽 聽 聽 </footer>
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 <!-- The Modal -->
聽 聽 聽 聽 聽 聽 <div id="myModal" class="modal">
聽 聽 聽 聽 聽 聽 聽 <!-- Modal content -->
聽 聽 聽 聽 聽 聽 聽 <div class="modal-content">
聽 聽 聽 聽 聽 聽 聽 聽 <span class="close" role="button" onclick="closemodal();" title="Close Modal (Cancel)">脳</span>
聽 聽 聽 聽 聽 聽 聽 聽 <h2>Customer data</h2>
聽 聽 聽 聽 聽 聽 聽 聽 <div id="form_data">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <label for="id">Id:</label>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <input type="text" id="id" name="id" class="myinput" value="0" disabled></input>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <span id="spn_id" class="msg"></span>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <label for="name">Name:</label>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <input type="text" id="name" name="name" class="myinput" >
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <span id="spn_name" class="msg"></span>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <label for="last">Last:</label>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <input type="text" id="last" name="last" class="myinput" >
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <span id="spn_last" class="msg"></span>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <label for="adress">Adress:</label>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <input type="text" id="adress" name="adress" class="myinput" >
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <span id="spn_adress" class="msg"></span>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <label for="city">City:</label>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <input type="text" id="city" name="city" class="myinput" >
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <span id="spn_city" class="msg"></span>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <label for="age">Age:</label>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <input type="number" id="age" name="age" class="myinput" >
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <span id="spn_age" class="msg"></span>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group">
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <label for="salary">Salary:</label>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <input type="number" id="salary" name="salary" class="myinput" >
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <span id="spn_salary" class="msg"></span>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <div class="form-group" >
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 <button type="submit" class="btntbl success" onclick="newdata();">Acept</button>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 聽 </div>
聽 聽 聽 聽 聽 聽 </div>聽
聽 聽 聽 聽 </body>
聽 聽 聽 聽 </html>聽
聽 聽 ENDTEXT聽
聽 聽 SELECT d_custo
聽 聽 Dbgotop()聽 聽
聽 聽 Do While !EOF()
聽 聽 聽 聽
聽 聽 聽 聽 cTable += "<tr id='row_"+cValtochar(d_custo->id)+"'>"
聽 聽 聽 聽 聽 聽 cTable += "<td style='width:25px'>"+transform(d_custo->id,"999")+"</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td style='width:100px'>"+alltrim(d_custo->first)+"</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td style='width:100px'>"+alltrim(d_custo->last)+"</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td style='width:220px'>"+alltrim(d_custo->street)+"</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td>"+alltrim(d_custo->city)+"</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td>"+transform(d_custo->age,"999")+"</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td align='right'>"+transform(d_custo->salary,"999,999.99")+"</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td>"
聽 聽 聽 聽 聽 聽 聽 聽 cTable += "<button onclick='how("+cValtochar(d_custo->id)+",1)' title='Edit' class='btntbl primary'>Edit</button>"
聽 聽 聽 聽 聽 聽 cTable += "</td>"
聽 聽 聽 聽 聽 聽 cTable += "<td>"
聽 聽 聽 聽 聽 聽 聽 聽 cTable += "<button onclick='how("+cValtochar(d_custo->id)+",2)' title='Delete' class='btntbl danger'>Delete</button>"
聽 聽 聽 聽 聽 聽 cTable += "</td>"
聽 聽 聽 聽 cTable += "</tr>"
聽 聽 聽 聽 d_custo->(DBSKIP())
聽 聽 EndDo聽 聽
聽 聽
聽 聽 cHtml := cHead+cTable+cFoot
return cHtml
function cJavascript()
聽 聽 Local cInyec
聽 聽 TEXT INTO cInyec
聽 聽 聽 聽 function how(id,acc){
聽 聽 聽 聽 聽 聽 var id_row = "row_"+id;
聽 聽 聽 聽 聽 聽 var therow = document.getElementById(id_row);
聽 聽 聽 聽 聽 聽 var aDatos = new Array();
聽 聽 聽 聽 聽 聽 var objeto = { action : 0 ,id : "", datos : []};
聽 聽 聽 聽 聽 聽 var elementsrow = therow.getElementsByTagName("td");
聽 聽 聽 聽 聽 聽 for(i=0;i<7;i++){
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(elementsrow[i].innerHTML);
聽 聽 聽 聽 聽 聽 }聽 聽聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 objeto.action = acc;
聽 聽 聽 聽 聽 聽 objeto.id = id;
聽 聽 聽 聽 聽 聽 objeto.datos = aDatos;
聽 聽 聽 聽 聽 聽 SendToFWH(objeto);聽
聽 聽 聽 聽 }
聽 聽 聽 聽
聽 聽 聽 聽 function openmodal(){
聽 聽 聽 聽 聽 聽 var lamodal = document.getElementById("myModal");
聽 聽 聽 聽 聽 聽 lamodal.style.display = "block";
聽 聽 聽 聽 }
聽 聽 聽 聽
聽 聽 聽 聽 function closemodal(){
聽 聽 聽 聽 聽 聽 var lamodal = document.getElementById("myModal");
聽 聽 聽 聽 聽 聽 lamodal.style.display = "none";
聽 聽 聽 聽 }
聽 聽 聽 聽
聽 聽 聽 聽 function newdata(){
聽 聽 聽 聽 聽 聽 var id_row = "row_0";
聽 聽 聽 聽 聽 聽 var aDatos = new Array();
聽 聽 聽 聽 聽 聽 var objeto = { action : 0 ,id : 0, datos : []};
聽 聽 聽 聽 聽 聽 var aErrores = new Array();
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 var theform = document.getElementById("form_data");
聽 聽 聽 聽 聽 聽 var theinputs = theform.getElementsByTagName("input");
聽 聽 聽 聽 聽 聽 for(i=0;i<theinputs.length;i++){
聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 聽 聽 var idname = theinputs[i].id;
聽 聽 聽 聽 聽 聽 聽 聽 var id_span = "spn_"+idname;
聽 聽 聽 聽 聽 聽 聽 聽 var oSpan = document.getElementById(id_span);
聽 聽 聽 聽 聽 聽 聽 聽 if(theinputs[i].value==""){
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 var cErro = "Please input "+idname;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aErrores.push(cErro);
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 oSpan.innerHTML = cErro;
聽 聽 聽 聽 聽 聽 聽 聽 }else{
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 oSpan.innerHTML = "";
聽 聽 聽 聽 聽 聽 聽 聽 }聽 聽聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 if (aErrores.length==0){
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(document.getElementById("id").value);
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(document.getElementById("name").value);
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(document.getElementById("last").value);
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(document.getElementById("adress").value);
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(document.getElementById("city").value);
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(document.getElementById("age").value);
聽 聽 聽 聽 聽 聽 聽 聽 aDatos.push(document.getElementById("salary").value);
聽 聽 聽 聽 聽 聽 聽 聽 objeto.datos = aDatos;
聽 聽 聽 聽 聽 聽 聽 聽 SendToFWH(objeto);聽
聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 }
聽 聽 聽 聽 function deleterowhtmltable(id){
聽 聽 聽 聽 聽 聽 var idrowdel = document.getElementById(id);
聽 聽 聽 聽 聽 聽 idrowdel.remove();
聽 聽 聽 聽 }
聽 聽 聽 聽 function insertrowhtmltable(idDbf,cSal){
聽 聽 聽 聽 聽 聽 var cIdRow = "row_"+idDbf;
聽 聽 聽 聽 聽 聽 var tbldata = document.getElementById("tbl_cstm").insertRow(-1);
聽 聽 聽 聽 聽 聽 tbldata.setAttribute("id", cIdRow );
聽 聽 聽 聽 聽 聽 var oCol1 = tbldata.insertCell(0);
聽 聽 聽 聽 聽 聽 var oCol2 = tbldata.insertCell(1);
聽 聽 聽 聽 聽 聽 var oCol3 = tbldata.insertCell(2);
聽 聽 聽 聽 聽 聽 var oCol4 = tbldata.insertCell(3);
聽 聽 聽 聽 聽 聽 var oCol5 = tbldata.insertCell(4);
聽 聽 聽 聽 聽 聽 var oCol6 = tbldata.insertCell(5);
聽 聽 聽 聽 聽 聽 var oCol7 = tbldata.insertCell(6);
聽 聽 聽 聽 聽 聽 var oCol8 = tbldata.insertCell(7);
聽 聽 聽 聽 聽 聽 var oCol9 = tbldata.insertCell(8);
聽 聽 聽 聽 聽 聽 oCol1.innerHTML = idDbf;
聽 聽 聽 聽 聽 聽 oCol1.style.width = "25px";
聽 聽 聽 聽 聽 聽 oCol2.innerHTML = document.getElementById("name").value;
聽 聽 聽 聽 聽 聽 oCol2.style.width = "100px";
聽 聽 聽 聽 聽 聽 oCol3.innerHTML = document.getElementById("last").value;
聽 聽 聽 聽 聽 聽 oCol3.style.width = "100px";
聽 聽 聽 聽 聽 聽 oCol4.innerHTML = document.getElementById("adress").value;
聽 聽 聽 聽 聽 聽 oCol4.style.width = "220px";
聽 聽 聽 聽 聽 聽 oCol5.innerHTML = document.getElementById("city").value;
聽 聽 聽 聽 聽 聽 oCol6.innerHTML = document.getElementById("age").value;
聽 聽 聽 聽 聽 聽 oCol7.innerHTML = cSal;
聽 聽 聽 聽 聽 聽 oCol7.setAttribute("align", "right");
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 oCol8.innerHTML = "<button onclick='how("+idDbf+",1)' title='Edit' class='btntbl primary'>Edit</button>";
聽 聽 聽 聽 聽 聽 oCol9.innerHTML = "<button onclick='how("+idDbf+",2)' title='Delete' class='btntbl danger'>Delete</button>";
聽 聽 聽 聽 聽 聽 location.hash = "#"+cIdRow;
聽 聽 聽 聽 聽 聽
聽 聽 聽 聽 聽 聽 closemodal();
聽 聽 聽 聽
聽 聽 聽 聽 }
聽 聽 ENDTEXT
Return cInyecLEANDRO AREVALO
Bogot谩 (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com
[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]