4

I created a custom directive in angular so that I can fade out a form on submit and replace it with a template with a custom message. The desired workflow is as follows:

  • The user completes the form and clicks submit.
  • The controller updates the model with a new object and emits a "formSubmitted" event with some args.
  • The directive listens for the event and fades out the form.
  • The directive loads a partial html filled with the args from the event.

I resolved the first 3 steps, but I wasn't able to get around the final step (I don't want to hardcode the html as Strings, I want to pull it from another file if possible).

How can it be done?

Edit: some sample code (simplified):

This is the form:

<section class="hero-unit {{containerClass}}" tk-jq-replace-children>
    <h2>{{formTitle}}</h2>
    <form class="form-search" name="solform" novalidate>
        <fieldset>
        ...

This is the controller:

if( formWasSavedOk ){
    $scope.formSubmittedMsg = msg;
//Here emits the custom event
    $scope.$emit( 'solicitud:formSubmitted' );
}

This is the directive:

.directive( 'tkJqReplaceChildren', function( $compile ){
    return {
        link: function( $scope, $iElement/*, $iAttrs*/ ){
            //The directive listens for the event
            $scope.$on( 'solicitud:formSubmitted', function( /*event*/ ){
                $iElement
                    .children()
                    .fadeOut(1000)
                    .promise()
                    .done(function(){
                        var $detachedElments = $(this).detach();
                        //The html is compiled and added to the DOM
                        $iElement.html( $compile( "<h2>{{formSubmittedMsg}}</h2>" )($scope) );
                        $scope.$apply();
                      });
            });
        }
    };
});

<h2>{{formSubmittedMsg}}</h2> is the code I want to pull from app/partials/create/createdOk.html (it is way more than just a header, that's why I want to load it from a file)

rvignacio
  • 1,710
  • 1
  • 18
  • 33
  • @blesh, I've come up with two alternatives: 1- put html in a String in the directive 2- make an ajax call for the file, compile it and append it to the DOM Option 2 is the most appealing right now, but I would love to know if there's a more standard solution using angular – rvignacio Feb 28 '13 at 18:00
  • Do you have any code to show that we can have a look at and/or try to fix? – Ben Lesh Feb 28 '13 at 19:27
  • @blesh, I've added some sample code to the question, thanks in advance! – rvignacio Feb 28 '13 at 19:48

2 Answers2

2

I believe the "Angular way" to fetch an external html snippet would be to use the ng-include directive:

<ng-include
       src="{string}"
       [onload="{string}"]
       [autoscroll="{string}"]>
</ng-include>

As for why your directive didn't work, my guess is that you're fetching the html at the directive's link phase, rather than compile phase. There's a nice explanation on the difference on this answer, but it's pretty much this:

If you are going to make DOM transformation, it should be compile if you want to add some features are behavior changes, it should be in link.

I would recommend moving most of that logic away from the directive, to the controller: fetching the data using a $resource or $http service, and then passing the results to the newly created scope of the ng-directive.

Community
  • 1
  • 1
Felipe Castro
  • 1,623
  • 11
  • 10
  • The ng-include must be in the view. I'm trying to keep the views clean. If I include it on load, then I must add a ng-hide directive too and I'm afraid I will end up with a lot of html widgets loaded and messing the html. I would like a solution that just adds the necessary html. I've added some sample code if it helps to get what I'm trying to do. Thanks for your time! – rvignacio Feb 28 '13 at 19:56
  • If you're using Angular UI, use the `ui-if` directive - it's the same syntax of ng-show, but it doesn't even add the html if the condition is not true. – Felipe Castro Feb 28 '13 at 20:05
2

I'm not sure if you are looking for the $http service. I have created a plunker http://plnkr.co/edit/13kFLh9RTsIlO4TaFIFQ?p=preview, which doesn't cover the first three steps, but covers the 4th step you need.

In the plunker click on the text "Click here to submit the form", and notice the new text is is inserted. This new text is from the external file called tmpl.html. In the firebug console, you can notice a get call after you clicked the text, to fetch the tmpl.html

Rajkamal Subramanian
  • 6,884
  • 4
  • 52
  • 69
  • Thanks, this is similar to one of the options I mentioned to blesh in the question comments, and is the best approach I've found till now. – rvignacio Mar 01 '13 at 12:36