Re: How to Change a button state when textFields become not empty

Josh Freeman <[email protected]> Fri, 27 Feb 2026 16:07:06 -0500
Newsgroups gmane.comp.lib.gnustep.general
Message-ID <[email protected]>
Hi Patrick,

    The SaveLink instance is being set up as an observer for NSControlTextDidChangeNotifications from within -[SaveLink observe:], but that method isn't called anywhere, except as the textfields' IBAction:

- Notifications won't be observed until one of the textfields sends its action (user presses <Enter> while the textfield's active)

- The SaveLink instance will be re-registered for the notifications each time the textfields send the action

    I suggest moving the -[NSNotificationCenter addObserver:...] calls to -awakeFromNib; That gets called only once, automatically, after loading the .gorm file:

<<-
- (IBAction) observe:(id)sender
{
// Register for notifications
   [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(textDidChange:)
                                                  name:NSControlTextDidChangeNotification
                                                object:name];
                                                  [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(textDidChange:)
                                                  name:NSControlTextDidChangeNotification
                                                object:link];
}

->>
- (IBAction) observe:(id)sender
{
}

- (void) awakeFromNib
{
   // Register for notifications
   [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(textDidChange:)
                                                  name:NSControlTextDidChangeNotification
                                                object:name];

   [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(textDidChange:)
                                                  name:NSControlTextDidChangeNotification
                                                object:link];
}

    Also, in -[SaveLink textDidChange:]:

- Calling [[urlLink substringToIndex: 4] isEqualToString: @"http"] will throw an exception if urlLink's length is less than 4, so suggest replacing it with [urlLink hasPrefix: @"http"]

- Nesting the urlLink check within the nameLink check can leave the savebutton enabled in cases where the nameLink has non-zero length but the urlLink has no http prefix, so suggest un-nesting the checks:

<<-
- (void)textDidChange:(NSNotification *)notification
{
...
   if([nameLink length])
   {
     if([[urlLink substringToIndex: 4] isEqualToString: @"http"])
     {
       NSLog(@"Button save enabled");
       [savebutton setEnabled:YES];
     }
   }
   else
   {
     [savebutton setEnabled:NO];
   }
}

->>
- (void)textDidChange:(NSNotification *)notification
{
...
   if([nameLink length] && [urlLink hasPrefix: @"http"])
   {
     NSLog(@"Button save enabled");
     [savebutton setEnabled:YES];
   }
   else
   {
     [savebutton setEnabled:NO];
   }
}

    Lastly, in SaveLink_main.m's main() function:

int
main(int argc, const char *argv[])
{
   [NSApp setDelegate: [SaveLink new]];
   return NSApplicationMain (argc, argv);
}

    I suggest removing the call to [NSApp setDelegate: [SaveLink new]]:

- NSApp isn't valid until NSApplication is initialized, within NSApplicationMain()

- A SaveLink object will be instantiated when loading the .gorm file (and its IBOutlets & IBActions will be connected correctly), so calling [SaveLink new] will just allocate (& leak) a different SaveLink instance, one without its outlets & actions connected

    Hope this is helpful!

Cheers,

Josh


On 2/27/26 10:37 AM, Patrick CARDONA wrote:
> Hello Riccardo,
> Hello All,
> 
> On 2026-02-26 22:06:48 +0100 Riccardo Mottola
> <[email protected]> wrote:
> 
>> Patrick CARDONA wrote:
>>> Hello,
>>
>>> I am working on an Internet Shortcuts Manager (aka SaveLink).
>>
>>> I associated the same action (statechange:) on my two fields ('name' and 'link').
>>> If they are not empty, the 'savebutton' should be enabled.
>>> But my button state does never change. Initial state is disabled and it remains in this state.
>>
>>
>> I didn't download your project, just reading the code.
>>
>> Are you sure you get statechange called? is it connected?
> 
> It was never called.
> 
>> Put an NSLog(@"statechange called") and check.
> 
> Si I modified  several things:
> - I removed the method statechange.
> - I set the class 'SaveLink'  as an NSApp delegate.
> - I added two new methods: (1) 'observe' and (2) 'textDidChange' (see
> below)
> - I connected the textFields to the action 'observe:'
> 
>>
>> Put an NSLog(@"Enable"); here so you are sure that the condition is matched and the issue is in setEnabled.
> 
> - I put all NSLog messages as recommended.
> 
>>
>> You can easily write this condition as:
>>
>> if([nameLink length] && [urlLink length])
>>
>> It checks that both string are valid and longer than zero. Not necessary, but it can also be quicker, since it will bail out on a nil string.
> 
> - I used better comparison statements.
> 
>>
>> you could also try to trim spaces.
> 
> - I added trim spaces on nameLink.
> 
>>
>> Riccardo
>>
> 
> Testing:
> - Opening a link... then save : working as expected.
> - NewLink command or reset button, then save :  working as expected.
> - Typing in the form just after the App has started: I did not yet
> find the way to make it work.
> 
> The code improved:
> 
> <SaveLink.m>
> 
> 
> <SaveLink_main.m>
> 
> and the whole project...
> 
> <SaveLink.tar.gz>
>