I did some tests with FoxInCloud and it is according to what I am looking for. I would like to start a new project from the login screen without migrating my current source code because I will redo my system using FoxInCloud. What is the best way for me to do this? Are there any demo projects with just the login screen and a start form? How does the question of security between forms? What would be best?
Why would you rewrite instead of adapt your application (not migration involved…)? If you want to adapt part of your project, you can just create a new project with just the necessary stuff, exclude the references you don't need yet and adapt that (FAA can ignore excluded files).
You have a demo project with a simple login in home(1) + 'tools\ab\aw\samples\fic\ficdemo'
.
The simplest way to deal with user identification is:
- in your login form, set at design time
.wlAnonymousAllowed = .T.
- upon user login, call
thisForm.wUserLogin(userID)
where userID is the user ID for your application (generally integer or string, can be of any type) - upon user logoff, call
thisForm.wUserLogoff()
You can get the current user's ID by thisForm.wUserGet()
See the aw.vcx!awFrm.wUser*
methods for more details.
There are other possible ways if this one does not match your specs.
Okay, I'll try. How do I start adaptation already in the responsive way?
You choose responsive mode by setting properties in server classes that FAA's step 3
generates ('xxx
' being your application code):
- class
xxxServer
: for both test and production - class
xxxServerTest
: for your test server only - class
xxxServerProd
: for your production server only
modify command xxxServer
to see the properties and description:
, lBootstrapAdd; && Load Bootstrap
, lFontAwesomeAdd; && Load FontAwesome
, lBStreeViewAdd; && Load Bootstrap Treeview
, BSlHTMLgen; && Generate all HTML / CSS/ JS in Bootstrap mode (you can also decide form by form using form.wlBSlHTMLgen)
For responsive mode,
Because FAS (awHTML) needs to group controls into Bootstrap's grid system,
An important thing is to make sure that form members do not unintentionally overlap;
This may happen with labels and containers a little larger than strictly necessary.
We may add a warning in the future (based on your feedback), however it's good to type ctrl+a
and check how controls are positioned relative to one another.
Exactly, we know internally a bit of bootstrap even we have a system made in Zen Mojo Intersystems that way. That's why I wanted to start a new project, to predict and adjust it.
FoxInCloud saves you the Bootstrap learning hassle!
You just need to visually arrange your controls (into rows and columns, labels close to matching control, move related buttons closer) and FoxInCloud will build the grid system, form groups, button groups, etc., for you.
The wBS*
properties that each adapted visual object inherits from aw.vcx!aw*
let you influence the rendering; you can just take a look at these properties.
OK! I started the project soon I will bring you news!
Setting the properties to true, displays this error when I try to run
What if you hit debug? Do you get more details?
Otherwise the error should display in the page after choosing ‘ignore’
I found out. The following error is set in the xxxxserver.prg variable BSlHTMLgen = .T., If this is the same in each form, the problem does not occur.
I understand that:
xxxServer.BSlHTMLgen = .T.
> KOxxxFrm.wBSlHTMLgen = .T.
> OK
Can't reproduce the error on our end…
do you remember in which procedure error occurred?
I am installing the fonts that I will adapt in our project on our server. Then I can try to reproduce the error again.
Can I pass only a few forms to the responsive mode? Since I have the limitation of 10 forms in the test version. Can you run the program xxxTest.css.prg only in some forms?
Can you run the program xxxTest.css.prg only in some forms?
You can do this:
do xxxTest with "form0.scx, form1.scx, …, form9.scx"
I'll try! Thank you!
When I try to run xxxTest.css.prg in a small project for testing to ja it leaves them responsive. This is happening in the picture.
please hit debug
to see the full message and check if .Load()
has a dodefault()
after all views are loaded
There was a bad command at the beginning of my desktop system that certainly caused a major problem in my tests. "CLOSE DATABASES ALL". I'm so angry at myself.
no reason why desktop startup program would interfere with web execution…
above all, no close all
in app code!
The command was in xxxsets.prg and it caused the problems I experienced. I removed it and everything worked. But I'm going to continue the tests to make sure it was that.
yes, alas, developers often overlook xxxSets.prg
it requires a careful review.
Perhaps commenting on this command (CLOSE DATABASES ALL) in the adaptation would be an idea for future versions.
How do I do the clause in the cursor adapter? I need to filter id 81,82,83. How would you do that? Would you create a variable for each possible id? I tried the code below and it did not work.
thisform.varid = '81,82,83'
select * from table where id IN (?thisform.varid)
select * from table where Inlist(ID,&thisform.varid)
in sqlexec works?
VFP's SQL engine probably substitutes thisform.varID
as a string.
If you can assume a maximum number of choices, you could try this:
procedure cursorAdapter.Init
thisForm.addProperty("IDs[10]", .null.)
this.selectCmd = "select * from table where ID in ("
+ " ? thisForm.IDs[01]";
+ ", ? thisForm.IDs[02]";
+ ", ? thisForm.IDs[03]";
+ ", ? thisForm.IDs[04]";
+ ", ? thisForm.IDs[05]";
+ ", ? thisForm.IDs[06]";
+ ", ? thisForm.IDs[07]";
+ ", ? thisForm.IDs[08]";
+ ", ? thisForm.IDs[09]";
+ ", ? thisForm.IDs[10]";
+ ")"
procedure someUserEvent
…
thisForm.IDs = .null.
thisForm.IDs[01] = 81
thisForm.IDs[02] = 82
thisForm.IDs[03] = 83
thisForm.dataEnvironment.cursorAdapter.cursorRefresh
You can't use a class property as a parameter directly. Best to store query parameters to variables and then use those:
LOCAL lcVarId
thisform.varid = '81,82,83'
lcVarId = thisform.varid
select * from table where id IN ?lcVarId
Tore's approach also works, and while less verbose I'd avoid the Macro substitution.
This addresses the syntax error, but likely not the SQL logic error - you're working on strings an IN
doesn't work on that so that query is not likely to get you a valid result.
Depending on what your backend is, you are probably best off doing a LIKE
or contains style query (which will be different depending on SQL dialect).
If you're using SQL Server and the IDs you can probably use PATINDEX()
(https://technet.microsoft.com/en-us/library/ms188395(v=sql.105).aspx), but I don't think you'll be able to do that using a CursorAdapter - you'll need to use SQL Exec.
+++ Rick ---
A class property can indeed be used as a .selectCMD
parameter, that's the benefit of the cursorAdapter to operate object-oriented:
LOCAL oCAD as CursorAdapter
oCAD = CreateObject("CursorAdapter")
oCAD.DataSourceType = "Native"
oCAD.Alias = 'foxcode_'
oCAD.SelectCmd = "select * from (_foxcode) where abbrev = ?this.abbrev"
oCAD.AddProperty("abbrev", 'ADEL') && for instance
? oCAD.CursorFill(), Alias(), Reccount() && .T. foxcode_ 1
browse last
I don't think you'll be able to do that using a CursorAdapter - you'll need to use SQL Exec.
Like remote views, cursorAdapter
is just a wrapper around SQLexec
Can I increase the size of a responsive modal window? How do I get this?
play with .wBSwidth
; you can start with .wBSwidth=1.5
The HTML that the FIC generates. It can be changed by a webdesigner.
The html is created for every hit at the server. So if you want to change the design, you must change the forms and the code that creates the html.
Tore,
FoxInCloud generates the form HTML/CSS/JS at server startup. Subsequent page changes are handled by AJAX, without HTML page reload (technology of the 90's, before the so called Web 2.0
).
You can alter the default HTML/CSS/JS generated by implementing the .wcHTMLgen()
method that every control inherits from aw.vcx.
Here is a sample implementation:
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
if thisForm.wBSlHTMLgen && Bootstrap HTML generation
toHTMLgen.lHTMLaddInside = .T. && change innerHTML only
text to toHTMLgen.cHTMLadd textmerge noshow flags 1 pretext 3
<img src="images/logo.svg" alt="logo Dooxi">
<h1>Compromis en ligne</h1>
<h2>Rédigez votre compromis de vente <span>en 4 étapes</span></h2>
endtext
endif
Arcadio,
your web designer can work 2 ways:
- based on the generated HTML, implement custom CSS/JS in
xxx.css
andxxx.js
- do a completely 'free' design and you implement custom HTML using the
.wcHTMLgen()
methods
below is an example of case 2. (see http://doo.foxincloud.com/bs/):
- VFP form screenshot
- Web page screenshot
- VFP form source code
- custom CSS from the Web designer (no specific JS in this example)
- form generated HTML
**************************************************
*-- Form: login (c:\vhdev\appli\dooxi\progs\login.scx)
*-- ParentClass: vhcfrm (c:\vhdev\classes\vhc.vcx)
*-- BaseClass: form
*-- Time Stamp: 11/11/17 09:47:03 AM
*
#INCLUDE "c:\vhdev\fichiers\constant.h"
*
DEFINE CLASS login AS vhcfrm
Height = 500
Width = 522
DoCreate = .T.
AutoCenter = .T.
BorderStyle = 0
Caption = "dooxi - compromis en ligne"
TitleBar = 0
WindowType = 1
BackColor = RGB(255,255,255)
wlanonymousallowed = .T.
wbslhtmlgen = .T.
wbscolclass = "col-sm-5"
Name = "Login"
waitpic.Height = 20
waitpic.Left = 0
waitpic.Top = -24
waitpic.Width = 20
waitpic.ZOrderSet = 0
waitpic.Name = "waitpic"
ADD OBJECT cntheader AS vhccnt WITH ;
Top = 0, ;
Left = 0, ;
Width = 519, ;
Height = 447, ;
BackStyle = 0, ;
BorderWidth = 0, ;
ZOrderSet = 1, ;
wcssclassadd = "text-center", ;
Name = "cntHeader"
ADD OBJECT login.cntheader.lbltitle AS awlbl WITH ;
FontSize = 18, ;
Alignment = 2, ;
BackStyle = 0, ;
Caption = "Bienvenue sur le site des compromis en ligne !", ;
Height = 27, ;
Left = 0, ;
Top = 0, ;
Width = 519, ;
TabIndex = 6, ;
ForeColor = RGB(64,128,128), ;
ZOrderSet = 4, ;
Name = "lblTitle"
ADD OBJECT login.cntheader.label1 AS vhclbl WITH ;
FontSize = 14, ;
Anchor = 768, ;
Alignment = 2, ;
BackStyle = 0, ;
Caption = "Rédigez votre compromis de vente avec Dooxi", ;
Height = 25, ;
Left = 12, ;
Top = 36, ;
Width = 491, ;
TabIndex = 4, ;
ForeColor = RGB(64,128,128), ;
ZOrderSet = 2, ;
Name = "Label1"
ADD OBJECT login.cntheader.imgapp AS awimg WITH ;
Picture = "..\images\logo.png", ;
Stretch = 1, ;
Height = 124, ;
Left = 107, ;
Top = 328, ;
Width = 265, ;
ZOrderSet = 9, ;
Name = "imgApp"
ADD OBJECT login.cntheader.label3 AS vhclbl WITH ;
FontItalic = .T., ;
FontSize = 15, ;
Anchor = 768, ;
BackStyle = 0, ;
Caption = "Rapide et très fiable", ;
Height = 27, ;
Left = 156, ;
Top = 312, ;
Width = 181, ;
TabIndex = 5, ;
ForeColor = RGB(64,128,128), ;
ZOrderSet = 3, ;
Name = "Label3"
ADD OBJECT cntacces AS vhccnt WITH ;
Top = 84, ;
Left = 0, ;
Width = 519, ;
Height = 235, ;
BackStyle = 0, ;
BorderWidth = 0, ;
ZOrderSet = 2, ;
wcssclassadd = "text-center", ;
Name = "cntAcces"
ADD OBJECT login.cntacces.lbllogin AS awlbl WITH ;
FontSize = 12, ;
BackStyle = 0, ;
Caption = "Code du dossier", ;
Height = 21, ;
Left = 89, ;
Top = 15, ;
Width = 317, ;
TabIndex = 4, ;
ZOrderSet = 0, ;
wbsllinked = .T., ;
Name = "lblLogin"
ADD OBJECT login.cntacces.txtlogin AS awtxt WITH ;
FontSize = 12, ;
Height = 32, ;
Left = 89, ;
Margin = 4, ;
StatusBarText = "Code du dossier", ;
TabIndex = 1, ;
Top = 39, ;
Width = 317, ;
ZOrderSet = 1, ;
wcpropsave = "backcolor", ;
Name = "txtLogin"
ADD OBJECT login.cntacces.lblresult AS vhclbl WITH ;
FontBold = .T., ;
FontSize = 10, ;
BackStyle = 0, ;
Height = 46, ;
Left = 89, ;
Top = 127, ;
Visible = .F., ;
Width = 317, ;
TabIndex = 5, ;
ForeColor = RGB(255,0,0), ;
ZOrderSet = 5, ;
wcpropsave = "Caption, Visible", ;
wueffecthide = .F., ;
wcssclassadd = "alert alert-danger", ;
Name = "lblResult"
ADD OBJECT login.cntacces.valide AS vhccmd WITH ;
Top = 75, ;
Left = 89, ;
Height = 42, ;
Width = 317, ;
FontSize = 12, ;
Caption = "Se \<connecter", ;
TabIndex = 2, ;
ZOrderSet = 4, ;
wcssclassadd = "btn-primary btn-block", ;
Name = "Valide"
ADD OBJECT login.cntacces.creation AS vhccmd WITH ;
Top = 176, ;
Left = 89, ;
Height = 42, ;
Width = 317, ;
FontSize = 12, ;
Caption = "\<Nouveau dossier", ;
TabIndex = 3, ;
ZOrderSet = 4, ;
wcssclassadd = "btn-primary btn-block", ;
Name = "Creation"
PROCEDURE cntheader.wchtmlgen
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
if thisForm.wBSlHTMLgen && Bootstrap HTML generation
toHTMLgen.lHTMLaddInside = .T. && change innerHTML only
text to toHTMLgen.cHTMLadd textmerge noshow flags 1 pretext 3
<img src="images/logo.svg" alt="logo Dooxi">
<h1>Compromis en ligne</h1>
<h2>Rédigez votre compromis de vente <span>en 4 étapes</span></h2>
endtext
endif
ENDPROC
PROCEDURE lbltitle.wchtmlgen
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
return !thisForm.wBSlHTMLgen && do not generate in Bootstrap mode
ENDPROC
PROCEDURE label1.wchtmlgen
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
return !thisForm.wBSlHTMLgen && do not generate in Bootstrap mode
ENDPROC
PROCEDURE imgapp.wchtmlgen
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
return !thisForm.wBSlHTMLgen && do not generate in Bootstrap mode
ENDPROC
PROCEDURE label3.wchtmlgen
LPARAMETERS toHTMLgen AS awHTMLgen OF awHTML.prg, tlInnerHTML && {en} doc in Parent Code {fr} doc dans le code parent
return !thisForm.wBSlHTMLgen && do not generate in Bootstrap mode
ENDPROC
PROCEDURE cntacces.Init
lparameters useless_parm_simple_reminder_to_call_doDefault_anywhere_in_your_subclass_code
if thisForm.wBSlHTMLgen
this.Left = 0
endif
return DoDefault()
ENDPROC
PROCEDURE txtlogin.wformcallback
LPARAMETERS tuUserChoice && @ {en} User's choice {fr} Choix de l'utilisateur
WITH THIS
IF Arobase + Arobase $ .Value .AND. Mquest # "Abandon"
.Value = Cdossiers_p.Numero
.Valid
ENDIF
ENDWITH
ENDPROC
PROCEDURE txtlogin.Valid
if thisForm.wlHTMLgen
return
endif
thisForm.Refresh
THIS.Parent.Valide.Click
ENDPROC
PROCEDURE lblresult.refresh_
this.Visible = .F.
ENDPROC
PROCEDURE valide.Click
lparameters nButton, nShift, nXcoord, nYcoord && {en} doc in Parent Code {fr} doc dans le code parent
if m.thisForm.wlHTMLgen
return
endif
WITH THIS.Parent.txtLogin
IF EMPTY (.Value)
.SetFocus
ENDIF
IF Arobase + Arobase $ .Value
DO Tabbord IN \VHDev\Appli\Dooxi\Dooxi.prg
RETURN
ENDIF
LOCAL success
success = .T. and SEEK ("DOO_" + TRIM (.Value), "Vi", "Numerodos")
ENDWITH
with this.Parent.lblResult as vhcLbl of vhc.vcx
.caption = Iif(m.success;
, "OK";
, wcIconFA('question-circle', 'lg') + "Cette référence de dossier est inconnue. Une erreur de saisie peut-être. Merci de bien vouloir réessayer …";
)
.Visible = !m.success
endwith
IF m.success
Mnumdos = TRIM (Vi.Numerodos)
THISFORM.wUserLogIn(Mnumdos) && 2016-08-31 thn
IF THISFORM.wlLAN
DO FORM Dooxi WITH Mnumdos
ELSE
THISFORM.wNavigate(, "Dooxi.doo")
ENDIF
ENDIF
ENDPROC
PROCEDURE creation.refresh_
lparameters void_parameter_reminder_implement_your_Refresh_code_in_this_method
this.Enabled = Empty(this.Parent.txtLogin.Value)
ENDPROC
PROCEDURE creation.Click
lparameters nButton, nShift, nXcoord, nYcoord && {en} doc in Parent Code {fr} doc dans le code parent
IF THISFORM.wlHTMLgen
RETURN .T.
ENDIF
DO Creation IN \VHDev\Appli\Dooxi\Dooxi.prg
WITH THIS
.Enabled = .F.
.Parent.txtLogin.SetFocus
ENDWITH
ENDPROC
ENDDEFINE
*
*-- EndDefine: login
**************************************************
#login_scx_body.bootstrap {
background: url(images/fond1-seconnecter.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
#login_scx_body.bootstrap footer {
display: none;
}
#login_scx_body.bootstrap #login_scx {
margin-top: 15px;
padding: 25px 6px 10px;
position: relative;
}
#login_scx_body.bootstrap #login_scx .titre-header {
padding: 10px;
}
#login_scx_body.bootstrap #login_scx h1 {
font-size: 130%;
margin: 0;
padding: 0;
font-weight: 700;
line-height: 130%;
}
body.bootstrap h2 {
font-size: 100%;
margin: 0;
padding: 0;
line-height: 130%;
}
body.bootstrap #login_scx-cntheader {
margin-top: 8%;
margin-bottom: 15px;
}
body.bootstrap #login_scx-cntheader h2 {
margin: 8% 0;
font-weight: 700;
}
body.bootstrap #login_scx-cntheader span {
color: #19ACF1;
}
body.bootstrap #login_scx-cntacces .alert {
background: #D9534F;
color: #FFF;
}
body.bootstrap #login_scx-cntacces-valide {
background: #19ACF1;
margin: 20px 0;
padding: 10px;
}
body.bootstrap #login_scx-cntacces-valide:not([disabled]):hover {
background: #2ECC71;
/* anim/transition bouton */
-webkit-transition: all 0.3s ease;
-moz-transition: all 1s ease;
-ms-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
body.bootstrap #login_scx-cntacces a {
color: #19ACF1;
}
<!-- Generated on 10/11/2017 10:40:24 in 0,42 sec. by FoxInCloud version 2.26.0-beta.2 of 09/11/2017 17:17:29 /-->
<div id="login_scx" class="login_scx form bootstrap" style="position:relative;">
<div class="row">
<div class="col-sm-5">
<span id="login_scx-waitpic" class="fa fa-2x fa-spinner fa-pulse" aria-hidden="true" style="position:absolute;display:none;"></span>
<div id="login_scx-cntheader" class="login_scx-cntheader text-center">
<img src="images/logo.svg" alt="logo Dooxi">
<h1>Compromis en ligne</h1>
<h2>Rédigez votre compromis de vente <span>en 4 étapes</span></h2>
</div>
<div id="login_scx-cntacces" class="login_scx-cntacces text-center">
<div class="form-group-lg text-left form-group awBSgrp-txtlogin p001">
<label for="login_scx-cntacces-txtlogin" id="login_scx-cntacces-lbllogin" class="login_scx-cntacces-lbllogin control-label">Code du dossier</label>
<input type="text" id="login_scx-cntacces-txtlogin" class="login_scx-cntacces-txtlogin form-control input-lg" tabindex="4" autocomplete="off" placeholder="Code du dossier">
</div>
<div class="form-group form-group-lg">
<button type="button" id="login_scx-cntacces-valide" class="login_scx-cntacces-valide btn-primary btn-block btn btn-lg" tabindex="5" accesskey="c">Se connecter</button>
</div>
<div class="form-group">
<p id="login_scx-cntacces-lblresult" class="login_scx-cntacces-lblresult alert alert-danger" style="display:none;"><strong>Label1</strong></p>
</div>
<div class="form-group form-group-lg">
<button type="button" id="login_scx-cntacces-creation" class="login_scx-cntacces-creation btn-primary btn-block btn btn-lg" tabindex="6" accesskey="N">Nouveau dossier</button>
</div>
</div>
</div>
</div>
</div>
<!--/ Generated on 10/11/2017 10:40:24 in 0,42 sec. by FoxInCloud version 2.26.0-beta.2 of 09/11/2017 17:17:29 -->
Thank you for the tips! We will be testing them. A question, which is the method that simulates the unload in a web form.
A question, which is the method that simulates the unload in a web form
Not sure what you mean… thisForm.release()
closes the form;
- if it's a 'master' form, displayed as a full blown HTML page,
thisForm.release()
returns to home page (root of application site, eg. http://app.my.com/); - if it's a 'child' form, displayed in a 'window' over a master form, it'll close the window and execute the call back method if any.
Make sure your app code in .release()
ends with return dodefault()
Ok! Is there any way to avoid closing the form when pressing the ESC key in responsive mode or triggering some method?
As of now, in Bootstrap mode
, hitting the escape key closes the form unless its .QueryUnload()
method is implemented.
I think we should also add the case where the form is modal. Is it what you mean?
Unless we missed something, when the Bootstrap modal closes, we can't identify whether the escape key was pressed, so we're not able to execute .click()
of the .Cancel
commandButton if any. So we need some workaround, or completely remove this feature.
I'm using modal! The problem is that I can not delete the recordsource of the grid if the user presses esc and this is causing me to have a blank grid or a deformed grid.
We will remove escape close on modal forms in next beta (V 2.26.0-beta.5
).
Perfect! I'll wait! I'll check other things then and I'll leave that aside for now! Thank you!
Hi Arcadio,
Can you provide some preliminary feedback?
- How many forms could you adapt and use in your browser? In which delay?
- How do you rate the adaptation time estimates in FAA?
- Did you find some road blocks that FAA could better anticipate / work around?
- Any must-have feature that could be missing for you?
- …
Thanks in advance.
Thierry,
We're going in parts. First we want to put our internal system to work on foxincloud. Because of this I am adapting our data entry class. Gave some work but it is something that every day I understand a little more. It's a 15 forms initially. And going well we will go to another project that will be more than 300 forms. I believe that currently the only problem I had was the grids that you are solving. If this initial project is successful, we will go to our main system. I still have nothing I can tell you that it is necessary to improve. But surely in time we will have.
I found a way to get around the grid recordsource problem in modal reponsive forms. Before calling the forms I'm looking for all forms and deleting the recordsource. Apparently he solved my problem. Even giving ESC in the modal the grid did not deform anymore.
LOCAL nForm As Integer
FOR nForm = _Screen.FormCount To 1 Step -1
TRY
IF VARTYPE(_Screen.Forms(nForm).grid_padrao1) = "O"
_Screen.Forms(nForm).grid_padrao1.RecordSource = ""
ENDIF
CATCH
ENDTRY
ENDFOR
thisForm.wForm("form\cad_empresa.scx",'wFormCallBack1')
EXTERNAL FORM cad_empresa.scx
Bug in google chrome. If you move the grid for some time, it no longer accepts mouse clicks. Only the keyboard arrows work, I tested this in the FIC site test application and the problem also occurs. By clicking the right mouse button on the grid you can simulate the problem. In IE the problem apparently does not occur.
Thanks for reporting, we'll try to reproduce.
Got it, using Google Chrome, right clicking in the grid makes it no longer respond to .Click()
No JavaScript error that we could have a grasp upon.
Perhaps an issue in the grid component; will report to ActiveWidgets ASAP.
Thanks again for sharing.
How can I block new user actions while the system processes something? Type something spinning or something like that to prevent the user from clicking the buttons while processing something.
Another problem, the details of a record that I'm editing on one machine, is appearing in another that is not related to the record. I made the filter as explained, putting the filter variables in this.wcPropSave and init of the form I do the cursorrefresh. What can I be missing?
you can disable the controls during the request to the server:
procedure some.click
if thisform.wlHTMLgen
local cJS
text to cJS textmerge noshow
jQuery('#<<thisForm.wcID>>').data('buttonDisabled', true).find('button').each(function(button){
var $button = jQuery(button);
$button.data('disabled_', $button.prop('disabled'));
});
endtext
return thisform.wcScriptEventClientServer(m.cJS)
endif
and restore disabled status after the request is complete:
// xxx.js
jQuery.extend(FoxInCloud, {
…
// ------------------------------------------------------------------------------
AjaxComplete_: function (jqXHR) {
// shell method to be implemented in xxx.js
if (jQuery(this.oForm).data('buttonDisabled')){
jQuery(this.oForm).data('buttonDisabled', false).find('button').each(function(button){
var $button = jQuery(button);
$button.prop('disabled', $button.data('disabled_'));
})
}
},
…
}
do you have a dodefault()
in .cursorFill()
and .cursorRefresh()
?
was adapted by the FAA and had no code before, do you need dodefault anyway?
I found the error, I should not put the word "thisform" in wcPropSave. That was why it was not working. Thank you!
rock and roll! I would probably not have guessed this one…
We will remove escape close on modal forms in next beta (V 2.26.0-beta.5).
Will it be in this next version?
yes, scheduled beginning of December
we should release beta.5
at the end of this week
Properties that I create on _screen, do I need to declare in wcPropSave? If it's necessary how do I do it?
Please see in xxxServer.prg
Can I report the values of wcpropsave in the form load or init? How would you do? Can I inherit from a class and then complement it?
Hi Arcadio,
Yes, in the form's load method, you can had any properties in wcpropsave. Of course, you can use classes to put your defaut properties to be save by FIC in wcpropsave's propertie of any objects of the classes
Regards Gilles
&& class or object
procedure init && load for a form
local success
success = dodefault(...)
wcPropSaveEdit(this, 'prop1, prop2, etc.') && modify command awPublic
return m.success
for more similar utilities, modify command awPublic
wcPropSave[Not]Edit()
keeps unique properties in the list (case insensitive).
help with grids, I have 2 grids on different machines accessing the same cursor. When I change the registry on a machine. The other machine is losing the order of the grid. How do I handle this?
It looks like the problem is related to the cursorrefresh . If I send a cursorrefresh on a machine and click on the grid on another machine. Is the refresh cursor done in both instances? What is the best way to work with it?
In the sample dataupdate form the problem also happens.
You mean the data ‘leak’ between users or just the sort order?
Sort order, the problem occurs if the user at one station changes a record that is being viewed at another station. With different records in different stations the problem does not happen.
OK, thanks for the feedback, we need to reproduce to understand and fix.
a video would help,
Thanks
Great. I'm going to record it and send it to you.
follow the link with the video
Did you see the video?
Yes, thanks for the video!
What happens: sort is made on client side JavaScript; Server is not aware of it.
When data changes, server send a new set of data and client fails to restore the sort order; if you implement server side sort order (through header.click()
generally), server will respect the sort order upon data change.
We'll fix that in 2.27 (release date TBD): whenever user clicks in a header and no server-side sorting is implemented, keep track of the sort order (on client or server, TBD) and restore in case of a data update.
I tried to use the index on header.click () and it did not work. Would the data modifications be ignored so the problem does not happen? In my case it is already that way nowadays. Otherwise I'll have to wait for the new version anyway.
I tried to use the index on header.click () and it did not work.
can you show your code?
LPARAMETERS nButton, nShift, nXcoord, nYcoord
IF (Type('m.thisForm.wlHTMLgen') == 'L' AND m.thisForm.wlHTMLgen)
#if .f. && {en} ========= IMPLEMENTATION DOCUMENTATION ========== {en}
Value returned indicates to FoxInCloud Application Server how browser should handle this event:
RETURN .T. && EXECUTE THIS VFP EVENT CODE on FoxInCloud server
RETURN <JavaScript code> && EXECUTE THIS JAVASCRIPT CODE
RETURN .F. && IGNORE EVENT
For more details and options, see code inherited from aw*
#endif && {en} ======= / IMPLEMENTATION DOCUMENTATION ========== {en}
RETURN .T. && Process event on server (your code after this IF ... ENDIF block)
ENDIF && Added by FoxInCloud Adaptation Assistant version 2.25 (source mode) on 11/01/2017 22:02
m.fez =TABLEUPDATE(.T.,.F.,"CRPAGAR")
m.fez =CURSORSETPROP("Buffering",3,"CRPAGAR")
SELECT CRPAGAR
INDEX ON ID TAG ID
GO TOP IN CRPAGAR
m.fez =CURSORSETPROP("Buffering",5,"CRPAGAR")
thisform.grID_PADRAO1.Refresh()
Here is a working code on another app. (WebTemp is a view):
procedure Form.Load
* Grid columns sorting && binary not supported
INDEX ON DIVISION TAG DIVISION
INDEX ON logo TAG logo
INDEX ON carrier TAG carrier
INDEX ON ACCT_NUM TAG ACCT_NUM && Upper() in WebTemp && modify command ipData
INDEX ON PAYER_CODE TAG PAYER_CODE
INDEX ON PAYER TAG PAYER
…
procedure grid.Init
…
* Delegate Header.Click() to a form-level method
success = aoClassCont(@m.laGrh, m.this, 'Header', .T.) > 0
assert m.success
if m.success
FOR EACH loGrh IN laGrh FOXOBJECT
BindEvent(m.loGrh, 'Click', m.thisform, 'grhClick', 1)
ENDFOR
endif
procedure form.grhClick
lparameters lcTag;
, llAsc; && for programmatic grid order change
, llGOTOP;
IF m.thisForm.wlHTMLgen
return
endif
local llEvent;
, laEvent[1];
, loGrh as Header;
, loSelect as abSelect;
, lcDesc;
llEvent = Empty(Pcount())
if m.llEvent
AEvents(laEvent, 0) && 0 specifies that AEVENTS( ) returns a three-element array containing: 1- object reference to the current event source, 2- the name of the triggered event, 3- how the event was triggered.
loGrh = m.laEvent[1]
lcTag = Upper(JustField(Evl(m.loGrh.Parent.Tag, m.loGrh.Parent.ControlSource)))
endif
if lTag(m.lcTag, 'WebTemp')
loSelect = abSelect('WebTemp') && Descending() does not accept an alias as parameter
lcDesc = Iif(Order() == m.lcTag AND Descending() or m.llAsc, 'ASCENDING', 'DESCENDING')
set order to (m.lcTag) &lcDesc in WebTemp
llGOTOP = lTrue(m.llGOTOP)
if m.llGOTOP
go top in WebTemp
endif
thisform.WebTempPageUpdate(;
.T.; && do not refresh form
)
if m.llGOTOP
go top in WebTemp_Page
endif
if m.llEvent
loGrh.Parent.Parent.setFocus
else
thisForm.Refresh(.T., .T., .T., .T.)
endif
endif
OK! I'll try.
Is this giving error in the variable @ m.laGrh than it is?
I already found it in another form. Disregard my last message.
What the "WebTempPageUpdate" method does?
Arcadio,
It's just a sample code excerpt that you need to adapt to your case
the main point is to create the indexes in form.Load()
and either set, or revert index order in header.click()
this sample code uses a bindEvent()
because the grid has 10 columns and most of them can be sorted. This way we avoid duplicating the code in each header.Click()
method (we hate copying and pasting code).
I understand perfectly and the code worked. But it did not solve the problem. There is no way to disable this automatic update of changed data in the grid and leave this to the user chooses when to do?
OK, cool
User can trigger update when using a paged grid (eg. http://foxincloud.com/tutotest/bs/Eventlog.tuto).
The reason why the grid refreshes automatically is: FoxInCloud does not support conflict on where clause (DBGetProp('someView',"VIEW","WhereType")
); so the user needs to know at any time what is the current state of the data.
However the updated data should respect server-side Order() or ORDER BY
(regardless of client-side click in the column header as previously discussed); if you have a use case where it does not work, we need to investigate further.
The header click is not being captured in web mode. Then the code sent did not work properly in this mode. How should I do?
Hi, You need to use a VCX class adapted by FoxInCloud for managing your grids in which you specify the use of PRG classes for your columns and headers.
* ========================================
DEFINE CLASS my_Col AS awGrc OF awPublic.prg && V1.26 COLUMN
* ========================================
HEADERCLASS = 'my_header'
HEADERCLASSLIBRARY = 'globalinit.fxp'
FONTSIZE = 8
BACKCOLOR=RGB(255,255,213) && jaune clair
FORECOLOR=RGB(184,133,105) && marron clair
READONLY = .F.
* ========================================
ENDDEFINE && CLASS my_Col
* ========================================
* ========================================
DEFINE CLASS my_header AS HEADER && awGrh OF awPublic.prg
* ========================================
CAPTION = 'Header'
ALIGNMENT = 2
FONTBOLD = .T.
FONTSIZE = 7
BACKCOLOR = RGB(184,133,105) && marron clair
FORECOLOR = RGB(255,255,255) && blanc
* ========================================
ENDDEFINE && CLASS my_header
* ========================================
* ========================================
* In Design IDE in your VCX for your class My_Grid
* you set :
* My_Grid.MemberClass = 'my_col'
* My_Grid.MemBerClassLibrary = 'C:\MyProject\Prg\My_Class.prg'
* ========================================
Regards Gilles
Hi Arcadio,
Gilles is right, you need to manually change xxxGrd.memberClass[Library]
to awGrc of awPublic.prg
:
It should not destroy the columns in your grid sub-classes or objects.
UPDATE: this will destroy your columns defined at design time -- I'll give you more instructions later on.
Hello, Thierry.
After I made that change the form did not work anymore. How should I proceed?
Hi Arcadio,
That's the issue I anticipated… can you post .properties
of record 27 of your scx
or vcx
, and the name of your column sub-class?
How could I do this if I can not open the form? Would you open it using the "USE" command?
yes:
use …my.scx
go 27
_cliptext = properties
use
then paste here
FontBold = .F.
FontUnderline = .F.
Caption = "Parcela"
Name = "Header1"
Ok! Done!
OK thanks; that's pretty complex… 3 solutions:
- if you have client-side sorting: wait until we release
2.26.1-beta.1
where client-side sorting is preserved when reloading the grid (should be this evening), and remove/cleargrid.memberClass|grid.memberClassLibrary
- if you have server-side sorting (
set order to…
):- wait until FAA changes
grid.memberClass|grid.memberClassLibrary
automatically - hack as explained below:
- wait until FAA changes
use my.scx
copy to … && backup
replace properties with strtran(properties, 'Column', 'xxxGrc') for Baseclass = 'grid' && xxxGrc being your subclass of awGrc
replace class with 'xxxGrh' for Baseclass = 'header' && xxxGrh being your subclass of awGrh
use
modify form my
If I wait for the new version, will not I have to do anything else or do I have to do all the steps?
just restore a backup with grid.memberClass = '' and grid.memberClassLibrary = ''
So I'll wait for the new version before continuing.
notification email bounced again:
Soft bounce Jan 10, 2018 3:32 PM
550-X-Warning: RecipientError: 550-X-Warning: 213.32.130.86 is listed at b.barracudacentral.org (127.0.0.2: 550-Client host blocked using Barracuda Reputation, see 550 http://www.barracudanetworks.com/reputation/?r=1&ip=213.32.130.86)
Sent Jan 10, 2018 3:32 PM
Sent a request to unblock:
Got this reply:
Thank you for contacting Barracuda Networks regarding your issue. Your issue is important to us. We have assigned a confirmation number: BBR21515597659-26421-19151 to this case.
We apologize for any inconvenience that this may have caused you. We have removed 213.32.130.86 (Please wait 24-48 hours) from our blocklist for 30 days, at which time it will be re-evaluated.
There are a number of reasons your IP address may have been listed as "poor", including:
The email server at this IP address contains a virus and has been sending out spam
The email server at this IP address may be configured incorrectly
The PC at this IP address may be infected with a virus or botnet software program
An individual in the organization at this IP address may have a PC infected with a virus or botnet program
This IP address may be a dynamic IP address which was previously utilized by a known spammer
The marketing department of a company at this IP address may be sending out bulk emails that do not comply with the CAN-SPAM Act
This IP address may have a insecure wireless network attached to it which could allow unknown users to use it's network connection to send out bulk email
In some rare cases, your recipients' Barracuda Spam Firewall may be misconfigured
If you do not think any of the above apply, please also contact the person who manages this IP address, as they may be better able to investigate this issue.
Thank you for your time and understanding.
You should receive the mail.
Honestly, I do not know what it's about.
another email address without barracuda?
My emails, arcadio.neto@gmail.com or arcadio@softeasy.com.br
oops, avoid posting as plain text or you might be spammed!! eg. {arcadio dot neto at gmail dot com}
I'll resend to gmail; @softeasy.com.br seems barracuded
just resent on gmail
I received the link in gmail. I'm going to do the tests.
I have to test better, but apparently the problem has been solved, only with the update. Thank you very much, that was a very important detail for us to pursue.
No problem will ever block your project; it's just a matter of when we'll solve it.
Thierry,
Can you make another change in the modal window? I would like it when the user clicks the black part of the screen, I would like it not to close, just like you did with the ESC key. It's possible?
OK, will be in 2.26.1-beta.3
When a modal form has .QueryUnload() or a callback method, disable closing form by pressing the escape key or by clicking in the modal backdrop (Bootstrap).
Ok! Thank you! Another thing on my machine tastrader is closing the table when opening the project in the browser.
Fixed in 2.26.1-beta.3
Perfect! Thanks!
Issues fixed in update! Thank you!