Angular directive to disable a button when clicked, allowing re-enabling as needed

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












I have written an Angular Directive that disables a button after it has been clicked, to prevent double posting / saving of data. This works fine in most of our use cases. However, in some situation we want to re-enable the button. For example: the button-click triggers a form submit, but the server-side validation fails. We want to allow the user to submit again, so we need to re-enable the button.



My solution uses an EventEmitter that is owned by the 'host' Component. This EventEmitter is passed on to the button's Directive. This Directive then subscribes to it. Whenever the host wants to instruct the button to re-enable, is emits an event. The Directive will take care of enabling the button.



As an alternative, one could use the disabled property of the button to control its state. However, I would like to reserve that property for other logic that is part of the host Component (e.g. are all required fields correctly filled, etc.). I would like to keep the code for the double posting safeguard contained to the Directive as much as possible.



I'd like to learn if there might be a cleaner way to accomplish what I'm after. Here's what I do now:



The button as used in the host Component template



<button [appDisableAfterClick]="reenableButton"
(click)="doStuff()">My button</button>


Inside the host Component



private reenableButton = new EventEmitter<boolean>();

doStuff()
// Make some external call.
// In case of an error, re-enable the button:

this.reenableButton.emit();



The DisableAfterClick Directive



Several null checks and unsubscribe calls omitted for brevity.



@Directive(
selector: '[appDisableAfterClick]'
)
export class DisableAfterClickDirective implements OnChanges, OnDestroy
@Input('appDisableAfterClick') reenableButton: EventEmitter<boolean>;

ngOnChanges(changes: SimpleChanges)
this.reenableButton = changes.reenableButton.currentValue;

this.reenableButton.subscribe(_ =>
(<HTMLButtonElement>this.el.nativeElement).disabled = false;
);


@HostListener('click')
onClick()
(<HTMLButtonElement>this.el.nativeElement).disabled = true;








share|improve this question



























    up vote
    3
    down vote

    favorite












    I have written an Angular Directive that disables a button after it has been clicked, to prevent double posting / saving of data. This works fine in most of our use cases. However, in some situation we want to re-enable the button. For example: the button-click triggers a form submit, but the server-side validation fails. We want to allow the user to submit again, so we need to re-enable the button.



    My solution uses an EventEmitter that is owned by the 'host' Component. This EventEmitter is passed on to the button's Directive. This Directive then subscribes to it. Whenever the host wants to instruct the button to re-enable, is emits an event. The Directive will take care of enabling the button.



    As an alternative, one could use the disabled property of the button to control its state. However, I would like to reserve that property for other logic that is part of the host Component (e.g. are all required fields correctly filled, etc.). I would like to keep the code for the double posting safeguard contained to the Directive as much as possible.



    I'd like to learn if there might be a cleaner way to accomplish what I'm after. Here's what I do now:



    The button as used in the host Component template



    <button [appDisableAfterClick]="reenableButton"
    (click)="doStuff()">My button</button>


    Inside the host Component



    private reenableButton = new EventEmitter<boolean>();

    doStuff()
    // Make some external call.
    // In case of an error, re-enable the button:

    this.reenableButton.emit();



    The DisableAfterClick Directive



    Several null checks and unsubscribe calls omitted for brevity.



    @Directive(
    selector: '[appDisableAfterClick]'
    )
    export class DisableAfterClickDirective implements OnChanges, OnDestroy
    @Input('appDisableAfterClick') reenableButton: EventEmitter<boolean>;

    ngOnChanges(changes: SimpleChanges)
    this.reenableButton = changes.reenableButton.currentValue;

    this.reenableButton.subscribe(_ =>
    (<HTMLButtonElement>this.el.nativeElement).disabled = false;
    );


    @HostListener('click')
    onClick()
    (<HTMLButtonElement>this.el.nativeElement).disabled = true;








    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I have written an Angular Directive that disables a button after it has been clicked, to prevent double posting / saving of data. This works fine in most of our use cases. However, in some situation we want to re-enable the button. For example: the button-click triggers a form submit, but the server-side validation fails. We want to allow the user to submit again, so we need to re-enable the button.



      My solution uses an EventEmitter that is owned by the 'host' Component. This EventEmitter is passed on to the button's Directive. This Directive then subscribes to it. Whenever the host wants to instruct the button to re-enable, is emits an event. The Directive will take care of enabling the button.



      As an alternative, one could use the disabled property of the button to control its state. However, I would like to reserve that property for other logic that is part of the host Component (e.g. are all required fields correctly filled, etc.). I would like to keep the code for the double posting safeguard contained to the Directive as much as possible.



      I'd like to learn if there might be a cleaner way to accomplish what I'm after. Here's what I do now:



      The button as used in the host Component template



      <button [appDisableAfterClick]="reenableButton"
      (click)="doStuff()">My button</button>


      Inside the host Component



      private reenableButton = new EventEmitter<boolean>();

      doStuff()
      // Make some external call.
      // In case of an error, re-enable the button:

      this.reenableButton.emit();



      The DisableAfterClick Directive



      Several null checks and unsubscribe calls omitted for brevity.



      @Directive(
      selector: '[appDisableAfterClick]'
      )
      export class DisableAfterClickDirective implements OnChanges, OnDestroy
      @Input('appDisableAfterClick') reenableButton: EventEmitter<boolean>;

      ngOnChanges(changes: SimpleChanges)
      this.reenableButton = changes.reenableButton.currentValue;

      this.reenableButton.subscribe(_ =>
      (<HTMLButtonElement>this.el.nativeElement).disabled = false;
      );


      @HostListener('click')
      onClick()
      (<HTMLButtonElement>this.el.nativeElement).disabled = true;








      share|improve this question













      I have written an Angular Directive that disables a button after it has been clicked, to prevent double posting / saving of data. This works fine in most of our use cases. However, in some situation we want to re-enable the button. For example: the button-click triggers a form submit, but the server-side validation fails. We want to allow the user to submit again, so we need to re-enable the button.



      My solution uses an EventEmitter that is owned by the 'host' Component. This EventEmitter is passed on to the button's Directive. This Directive then subscribes to it. Whenever the host wants to instruct the button to re-enable, is emits an event. The Directive will take care of enabling the button.



      As an alternative, one could use the disabled property of the button to control its state. However, I would like to reserve that property for other logic that is part of the host Component (e.g. are all required fields correctly filled, etc.). I would like to keep the code for the double posting safeguard contained to the Directive as much as possible.



      I'd like to learn if there might be a cleaner way to accomplish what I'm after. Here's what I do now:



      The button as used in the host Component template



      <button [appDisableAfterClick]="reenableButton"
      (click)="doStuff()">My button</button>


      Inside the host Component



      private reenableButton = new EventEmitter<boolean>();

      doStuff()
      // Make some external call.
      // In case of an error, re-enable the button:

      this.reenableButton.emit();



      The DisableAfterClick Directive



      Several null checks and unsubscribe calls omitted for brevity.



      @Directive(
      selector: '[appDisableAfterClick]'
      )
      export class DisableAfterClickDirective implements OnChanges, OnDestroy
      @Input('appDisableAfterClick') reenableButton: EventEmitter<boolean>;

      ngOnChanges(changes: SimpleChanges)
      this.reenableButton = changes.reenableButton.currentValue;

      this.reenableButton.subscribe(_ =>
      (<HTMLButtonElement>this.el.nativeElement).disabled = false;
      );


      @HostListener('click')
      onClick()
      (<HTMLButtonElement>this.el.nativeElement).disabled = true;










      share|improve this question












      share|improve this question




      share|improve this question








      edited Aug 1 at 19:16









      200_success

      123k14143398




      123k14143398









      asked Aug 1 at 14:51









      Daan

      1161




      1161

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200757%2fangular-directive-to-disable-a-button-when-clicked-allowing-re-enabling-as-need%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200757%2fangular-directive-to-disable-a-button-when-clicked-allowing-re-enabling-as-need%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation