in reply to how to disable the button untill certain fields are filled?

There were a number of bugs in your sample code which I've cleaned up in the code below. It's generally a good idea not to use global variables if you can avoid it, and generally you can. It's also a good idea to use Perl style for loops when you can rather than C style, and again generally you can.

use strict; use warnings; use Tk; use Tk::Table; use Tk::Entry; use Tk::Label; use constant kRows => 3; use constant kCols => 3; main (); # Use a main sub to ensure that there are no global variables +s sub main { my $mw = new MainWindow; $mw->Label ( -text => "Enter any character", -foreground => "red", -font => "verdanafont 10 bold" )->pack (-side => "top"); my $table_frame = $mw->Frame ()->pack (-padx => "10"); my $table = $table_frame->Table ( -columns => kCols, -rows => kRows, -scrollbars => "o", -fixedrows => 1, -fixedcolumns => 1, -relief => 'raised', -pady => "20", -takefocus => "0" ); my $press = $mw->Button ( -text => "Press Me", -command => [\&PressMe, $mw, $table], # pass parameters into c +allback -font => "verdanafont 10 bold", -state => 'disabled', )->pack ( -side => "left", -padx => "5", -ipadx => "5" ); my $filled = 0; for my $col (0 .. kCols - 1) { my $tmp_label = $table_frame->Label (-text => "$col")->pack () +; $table->put (0, $col, $tmp_label); } for my $row (0 .. kRows - 1) { for my $col (0 .. kCols - 1) { my $ent1 = $table->Entry ( -font => "verdana 10", -validate => 'key', # Pass button widget and a ref to $filled into callbac +k. Need a # ref because we manipulate $filled in the callback -vcmd => [\&onEdit, $press, \$filled], )->pack (-ipady => "15"); $table->put ($row, $col, $ent1); } } $table->pack (); MainLoop; } sub onEdit { my ($button, $filled, $new, $edit, $current, $idx, $type) = @_; return 1 if $new eq $current; if (length $new && !length $current) { ++$$filled; } elsif (!length $new && length $current) { --$$filled; } if ($$filled == kRows * kCols) { $button->configure (-state => 'normal'); } else { $button->configure (-state => 'disabled'); } return 1; } sub PressMe { my ($mw, $table) = @_; my $message = "alphanumeric entered"; Outer: for my $row (0 .. kRows - 1) { for my $col (0 .. kCols - 1) { my $name = $table->get ($row, $col); my $val = $name->get (); next if $val =~ m/^[a-z0-9]+$/i; $message = "Bad entry ($val) in row " . ($row + 1) . ", column " . ($col + 1); last Outer; } } my $response = $mw->messageBox ( -type => "ok", -message => $message, -icon => "info", -title => "info!!" ); }

Note the array technique used to pass extra parameters into the call back routines. The extra parameters are passed before the normal parameters.

Note too the use of named constants to provide row and column counts rather than relying on using the correct manifest constants everywhere (four places for each in this small sample script!). Also note that the column and row indexes range from 0 to count - 1: easier to see and get right with the Perl for loops using the range operator than with the C style for loops.

I also reworked your validation checking in the button call back so that the message box is only shown once and only for the first bad cell value found. You could of course check all the cells and report all the errors found by not terminating the loop early and by concatenating error messages together.


Perl reduces RSI - it saves typing

Replies are listed 'Best First'.
Re^2: how to disable the button untill certain fields are filled?
by Anonymous Monk on Oct 26, 2008 at 15:33 UTC
    Thanks a lot!!!!GodFather.. Superbbb... since i am new to perl, i did those mistakes, thanks for correcting them too. Well i am bit confused about the working of onEdit function in the solution provided. can you please explain a little, how and which extra parameters you are passing and why?? Thanks in advance

      In the configuration code where the table entries are being set up the fragment:

      my $ent1 = $table->Entry ( -font => "verdana 10", -validate => 'key', # Pass button widget and a ref to $filled into callbac +k. Need a # ref because we manipulate $filled in the callback -vcmd => [\&onEdit, $press, \$filled], )

      configures the validation call back to be called when an edit is made and to pass the additional parameters $press and \$filled (a reference to $filled) to the call back function onEdit. onEdit receives a number of parameters:

      sub onEdit { my ($button, $filled, $new, $edit, $current, $idx, $type) = @_; return 1 if $new eq $current;

      The first two are the two extra parameters that were passed in when the call back was set up. The remainder are the normal parameters to the validation call back. If not changes will be made to the entry contents ($new eq $current) an early exit is made. Next a check is made to see if and empty cell has had characters added, or a non-empty cell has had its contents deleted and $filled is adjusted appropriately:

      if (length $new && !length $current) { ++$$filled; } elsif (!length $new && length $current) { --$$filled; }

      Finally, depending on the count in $filled, the button is enabled or disabled:

      if ($$filled == kRows * kCols) { $button->configure (-state => 'normal'); } else { $button->configure (-state => 'disabled'); }

      Perl reduces RSI - it saves typing
      sorry...read grandfather instead of godfather..