3

I need to load html from json file. So I found dform as best solution for that. Since it's the jQuery plugin and I need that in Angular. I am lucky that I found it's directive on jsfiddle.

The only difference is that I had my own json file and I have written the code separately. I am using service to get data from json file through http request. After that I am using the directive similar to the jsfiddle one.

app.js

var app = angular.module('angularApp', []);

service.js

app.service('loaderService', ['$http', function ($http) {
    this.getLoadedHtml = function (callback)
    {
        return $http.get('../source/file.json')
           .then(function (res) {
               callback(res.data);
           });
    }
}])

controller.js

app.controller('mainCtrl', ['$scope', 'loaderService', function ($scope, loaderService) {
    loaderService.getLoadedHtml(function (data) {
        $scope.fields = data;
    });
}]);

directive.js

app.directive('dform', function () {
    return {
        scope: {
            action: '@',
            method: '@',
            html: '='
        },
        link: function (scope, elm, attrs) {
            var config = {
                "action": scope.action,
                "method": scope.method,
                "html": scope.html
            };
            elm.dform(config);
        }
    };
})

index.html

<div class="container-fluid" ng-app="angularApp">
        <div ng-controller="mainCtrl" style="background-color:green; margin-top:100px; height:1000px;">
            <div class="col-sm-3" id="source-area">
                <div action="index.html" method="get" html="fields" dform></div>
            </div>
        </div>
    </div>

file.json

[
  {
    "type": "p",
    "html": "You must login"
  },
  {
    "name": "username",
    "id": "txt-username",
    "caption": "Username",
    "type": "text",
    "placeholder": "E.g. [email protected]"
  },
  {
    "name": "password",
    "caption": "Password",
    "type": "password"
  },
  {
    "type": "submit",
    "value": "Login"
  }
]

I have used jquery and dform library too.

Since I have not got any error. My array is coming fine into controller and $scope.fields is also working fine in controller. By I cannot see any html rendered? I have used the same as in jsfiddle.

8
  • Approach of using jquery plugin makes no sense. What does json look like and what are expecped results from it. This should be easily achieved using angular templating and some data mapping Commented Dec 25, 2016 at 17:31
  • @charlietfl why is it running in jsfiddle? Question is that and why not it running in my code? Commented Dec 25, 2016 at 17:32
  • But why are you even doing it this way in the first place? Strongly suggest you read stackoverflow.com/questions/14994391/… Commented Dec 25, 2016 at 17:55
  • i know using Jquery with angular js is not a good practise. I am unable to find alternate of this plugin in angular. Commented Dec 25, 2016 at 17:57
  • Although I agree with other commentators, for your specific problem, I bet the problem is that elm.dform(config); is running only once, it is not aware of html changes. So I would try to create a $watch on html property and in callback just call elm.dform(config); again. Commented Dec 25, 2016 at 17:59

1 Answer 1

2

Elaborating on my comment. So what I think happens is dform does not reload automatically when the html changes (just not expecting it to change). What you could do in your directive is watch on html and update dform on change:

...
link: function (scope, elm, attrs) {
    var config = {
        "action": scope.action,
        "method": scope.method,
        "html": scope.html
    };

    scope.$watch('html', function() {
        elm.dform(config);
    });

    elm.dform(config);
}
...

But wait, there is more! As I mentioned, dform also supports loading external forms from server. According to documentation, that should be possible by using url subscriber. So your directive would look something like this:

app.directive('dform', function () {
  return {
    scope: {
        action: '@',
        method: '@',
        url: '='
    },
    link: function (scope, elm, attrs) {
        var config = {
            "action": scope.action,
            "method": scope.method,
            "url": scope.url
        };
        scope.$watch('url', function() {
          elm.dform(config);
        });

        elm.dform(config);
    }
  };
})

This eliminates the need in loader service. Now, I haven't tried this, so it maybe will require some tweaking from your side, by the idea should be clear by now.

UPDATE:

Ok, I've done a demo (which you should do next time you ask the question). The big problem was that the config.html needed to be reassigned after change in html property. So our link function now looks like this:

link: function(scope, elm, attrs) {
  scope.$watch('html', function() {
    if (!scope.html)
      return;
    var config = {
      "action": scope.action,
      "method": scope.method,
      "html": scope.html
    };

    $(elm).dform(config);
  });
}

P.S. I have replaced http call with timeout, but that makes absolutely no difference.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your time, I am in situation where I cannot load it from server directly. I have added watcher too but it gives me the same output that is nothing. Only I get in html is form tag and nothing inside.
Can you console.log the new value In the $watch expression for html property? Are you sure you get the fields from server and they make it to the directive?
I get nothing in html property, the workaround is that I need to get html from service again in directive's scope.$watch. I reassign new html and it works fine than. Is there any way through which I can get new value of scope.fields under $watch i.e. I need updated value for html in directive after it changes in controller?
Please see updated answer. Now it should be very clear how to do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.