April 20, 2024
A standard feature of many web sites is to use colour to indicate bad entries needing user attention.
With EWB you can set the font colour to red if you dislike a value, but that doesn’t show up if the field is empty, and the convention is more often to use background colour to convey this information.
eg.
procedure TForm1.edYearChange(Sender: TObject);
begin
if strtointDef( edYear.Text, -1 ) < 2000 then
edYear.Font.Color := clRed
else
edYear.Font.Color := clWhite
end;
But sometimes you have other needs such as
-
notes you want to set to a different background colour, like Yellow for a TMultiLine edit which would look like a PostIT(tm) note
-
you want an empty value to show colour, setting the font has no effect if the empty string is in there
Consider this sample, a Year field which shows up as pinkish unless the year is valid, which we define as 2000 or later.
Standard EWB doesn’t let you create such a coloured entry as there is no background attribute for TEdits.
We’re going to add exactly that feature in this blog post.
First, create a edYear TEdit with an OnChange event pointing to
procedure TForm1.edYearChange(Sender: TObject);
begin
if strtointDef( edYear.Text, -1 ) < 2000 then
SetBackground( edYear, 'rgb(255,200,200)') // rose
else
SetBackground( edYear, 'rgb(255,255,255)' ); // white
end;
Now we just need to write the code to implement the SetBackground function.
The first thing to note is that TEdits point to an HTML DIV or container which holds the actual HTML Edit. So edYear points to a container whose first and only child is an actual Edit, which is what we will be modifying.
In the case of a TMultiLineEdit, there is no DIV. So we just use the first child if and only if it exists.
Next thing worth considering is that we need to set the TEdit’s ID field so we can use getElementByClientID(). This is done with TEdit’s ClientID = … syntax.
However, note that if we have two EWB forms open with identically named TEdit’s (edYear), the browser won’t know which of the edYear values will be referenced. So we append a unique integer to the ClientID. With JavaScript’s 52 bit integers, we won’t run out of one anytime soon.
Finally, once we have the EDIT HTMLelement, we need to set the style.backgroundColour portion to an RGB() valued colour.
With all those notes, here is the resulting function.
var
increasingInt : integer = 1; // used to give a unique ClientID
procedure SetBackground( c : TControl ; cl : string );
var
domele : TDomElement;
nam : string; // our temporary name
begin
// get a fresh integer
inc( increasingInt );
// come up with a unique name
nam := c.name + '_'+ IntToStr(increasingInt);
// give it an ID so getElementById will work
c.ClientID := nam;
domele := window.document.getElementById( nam );
if not Assigned( domele ) then
Showmessage('Could not find element ' + c.name + ' ('+nam+')' )
else begin
// if Element points to a DIV, we want the first child....
if Assigned( domele.childNodes[0] ) then
domele := variant(domele.childNodes[0]);
// and set the style.backgroundColor....
THTMLElement(domele).style.backgroundColor := cl;
end;
end;
To have a yellow TMultiLineEdit background, call the following from the form’s OnShow event handler.
// set the note to yellow
SetBackground(multilineedit1, 'rgb(255,255,0 )');
Tip
|
The TEdit’s cell background will be reset if it changes focus. One way of dealing with that is to have edYearChange( nil) called from a TTimer event. TMultiLineEdit does not change when swithcing focus. |