I have an html template with a reusable modal that gets ng-included like this:
myPartial.html
... SOME HTML ...
<ng-include src="'form.html'"></ng-include>
modal.html
...
<form>
<input ng-model="comment.value" />
<button type="submit" ng-click="save(comment.value)" />
</form>
...
What is the best way to clear the form -- particularly from the controller if possible. I'd like to clear the form from my save() method after a successful http call, but since ng-include creates it's own scope, i'm not sure how to do this.
Here's a plunker to show my problem: http://plnkr.co/edit/zkxZOZr3f7sHJZfCiuoT?p=preview
If you take the contents of form.html and put them directly into index.html it works just fine.
You almost got it. Just initialize the comment instance in your controller and update the correct value in save. I believe the behaviour your experiencing is called "prototypal inheritance" and you can read about it at Understanding scopes. This is not exclusive to AngularJS btw, but can be found in regular JavaScript as well.
angular.module('app', []).controller('appcontroller', function($scope) {
// create comment
$scope.comment = { value: 'test' };
$scope.save = function(value) {
console.log('in here ');
// and update comment.value, not comment.
$scope.comment.value = null;
};
});
I updated your plunker.
Related
I'm new to AngularJS and I'm working on a small project to get the hang of how things work.
Basically I want to have a single-page app where I can dynamically change part of the page to include html from some other file. This other file has a controller and such. I would like the url to stay the same. I need the page to be loaded dynamically with a variable name.
Right now, I can get the HTML to load from the imported template, but a lot of HTML is excluded and all of the "ng" tags are gone. I take this to mean that this new page can't find the controller or a lot of the stuff is getting compiled out or something. Maybe I'm not importing things in the correct order? I have no idea. Here's my basic layout:
app.js
var app = angular.module('myApp', []);
app.controller('Main', function($scope) {
$scope.htmlContent = 'somepage.html';
$scope.externalPage = 'otherpage';
$scope.changePage = function(page) {
$scope[page]();
}
$scope.otherpage = function() {
$scope.htmlContent = 'otherpage.html';
}
});
app.controller('InternalPage', function($scope) {
alert('hello world');
$scope.content = "This is not showing";
});
index.html
<div ng-controller="Main">
<!-- This all works. Clicking "Change Page" changes the
HTML referenced by the <div> tag -->
<a ng-click="changePage(externalPage)">Change Page</a>
<div ng-bind-html="htmlContent"></div>
</div>
otherpage.html
<div ng-controller="InternalPage">
<p>{{content}}</p>
</div>
I have tried including the javascript in the html file itself to no avail. I also could not get the ng-include thing to work either.
Try looking into ng-include instead of ng-bind-html:
https://www.w3schools.com/angular/angular_includes.asp
Let's say I have an laravel controller that contains one method that parsing value from other sites. On client side I'm using Angular. When user presses button it have to execute this Laravel controller method and value that parsed by this method have to fill an input field in form. Im completely new in angular. So is it possible to execute this laravel method from angular? If it is possible can you give some examples how can I achieve this?
this is just a little example to show how to use $http to transport data. I'm not worked with laravel much.
view.html
<html ng-app = 'myAPP'>
<head>
//include required css or js files
</head>
<body>
<div ng-controller = 'MainCtrl'>
<button ng-click = 'sendData()'>Click me</button>
</div>
</body>
</html>
main.js
angular.module('myAPP').controller('MainCtrl',['$scope','$http','$log',function($scope,$http){
$scope.sendData = function(){
$http.post('url',data).success(function(returnData){});
}
}]);
after http post, from laravel controller it must be catch those data in jason format you either can use it in that format or you can decode it and then use it.
I am working on MVC4 with angular JS and using ng-include to call a partial view inside my main view. Issue comes when I am trying to click a button inside my partial view.
I have two different controllers in angular, one for main and other one for a partial view both are working under same module.
My file structure is as follows
Scripts..
|
--Main.js
|--ProjectPage.js
(Main.js)
var app = angular.module("Layout", []);
app.controller("LoadPage", function ($scope) {
$scope.templateUrl = '/Home/DefaultPage';
};
(ProjectPage.js)
angular.module("Layout")
.controller("CNTRL", function ($scope) {
$scope.clickBtn1 = function () {
alert("ABU");
};
});
and this is the HTML, I am using for partial page
<body ng-app="Layout" ng-controller="CNTRL">
<button ng-click="clickBtn1 ()" id="click">click</button>
The partial view is working fine when its called up independently(not inside the main view). No error is coming inside the browser but click event is not working.
The problem is probably because you are calling the "app" twice. Once in your layout (html) page and then in your partial page. You can fix this by replacing:
<body ng-app="newLayout" ng-controller="CNTRL">
With:
<div ng-controller="CNTRL">
<!-- button code here -->
NOTE: The change from body to div (can be any html container tag) and removal of ng-app directive.
Here! You have same module name so it will consider first one.
Just different name both and it will works..
main.js
var app = angular.module("Layout", []);
app.controller("LoadPage", function ($scope) {
$scope.templateUrl = '/Home/DefaultPage';
};
ProjectPage.js
angular.module("newLayout")
.controller("CNTRL", function ($scope) {
$scope.clickBtn1 = function () {
alert("ABU");
};
});
Body content
<body ng-app="newLayout" ng-controller="CNTRL">
<button ng-click="clickBtn1 ()" id="click">click</button>
I'm rather new to angular and I'm trying to use Angular Wizard.
https://github.com/mgonto/angular-wizard
I have my code in plunker, and I have the wizard running. However, I'm having trouble getting the validation functions to be called. I'm guessing I'm going out of scope somewhere. I set the validation functions to return false, but I'm still continuing to the next step.
However, the function for the wizard being completed is being called.
HTML
<wz-step title="Starting" canexit="exitValidation">
<h1>This is the first step</h1>
<p>Here you can use whatever you want. You can use other directives, binding, etc.</p>
<input type="submit" wz-next="" value="Continue" />
</wz-step>
<wz-step title="Continuing" canenter="enterValidation">
<h1>Continuing</h1>
<p>You have continued here!</p>
<input type="submit" wz-next="" value="Go on" />
</wz-step>
JS
var app = angular.module('registration', ['mgo-angular-wizard']);
app.controller('WizardController', ['$scope', 'WizardHandler',
function($scope, WizardHandler) {
$scope.finishedWizard = function() {
alert('Completed!');
};
$scope.enterValidation = function() {
alert('entering validation');
return false;
};
$scope.exitValidation = function() {
alert('exiting validation');
return false;
};
}
]);
http://plnkr.co/edit/QR9mpXH67ErhUzAKmN4c?p=preview
This question is different from the below because step validation was added after it was asked.
I'm trying to get form validations to work with an Angular Wizard
If you are using the newest version of angular wizard (0.5.5) it works. There was probably a bug in the older version. Here is a working Plunker
http://plnkr.co/edit/QR9mpXH67ErhUzAKmN4c?p=preview
Here are the URLs
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-wizard/0.5.5/angular-wizard.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-wizard/0.5.5/angular-wizard.css" />
I've been learning angular a bit here and there, but I don't quite get what the angular way of handling success/error responses from the server would be. The typical jQuery way to do it would be:
Serialize data from form
$.post the data to server
server validates data, responds with success or error data
use jQuery to maniuplate DOM to display success/error data from server.
In angular, we have directives that manipulate the DOM and we have controllers that deal with the models. Say we have the following:
form.html
<div ng-controller="myController">
<span class="hidden success-message"></span>
<form>
<label> Name </label>
<input type="text" name="name" ng-model="name">
<span class="name-error hidden"></span>
<label> Occupation </label>
<input type="text" name="occupation" ng-model="occupation">
<span class="occupation-error hidden"></span>
<input submit-directive type="submit" id="submit" value="Submit">
</form>
</div>
app.js
angular.module('app', []).controller('myController', [$scope, $http, function($scope, $http) {
$scope.name = "";
$scope.occupation = "";
$scope.doSubmit: function(formData) {
$http.post("/save", formData)
.success(function(response) {
$scope.name = response['name']
$scope.occupation = response['occupation']
// How to pass success messages back to directive?
}.fail(function(err) {
// How to pass error messages back to directive?
}
}
});
angular.module('app', []).directive('submit-directive', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.click(function() {
// Pass form data back to controller
scope.$apply('doSubmit(\"' + $("form").serialize() +'\")');
});
// How do I get the success/fail results from the Controller so that I can manipulate the DOM?
}
};
});
Here, a user enters their name and occupation. Upon submitting, the directive grabs the form data and presents it to the controller for a POST request. When the response is returned, the directive should either display a success message or display the error messages.
It's not clear how I would pass the response from the controller to the directive for DOM manipulation.
The only way I've thought of is to create a $watch:
// in controller
$scope.isFormPostSuccess = false;
$scope.formResponse = null;
// ....
.success(function(response) {
$scope.isFormPostSuccess = true;
$scope.formResponse = response;
}.fail(function(err) {
$scope.isFormPostSuccess = false;
$scope.formResponse = err;
}
Then in the directive, I would watch those variables for changes and act accordingly. However, this way of doing it feels very messy and doesn't seem to scale well for larger applications or when having many independent forms. I could also move all the DOM manipulation into the controller, but that's just bad design.
What is the proper angular way?
Actually, the so-called "Angular way" should be to combine the usage of models($scope.foo) with directives(like ng-model, ng-bind, ng-show, etc., or your custom directives) to achieve the goal of a DOM operation. It's not like to initiate a DOM operation by hand within your controller, but to change your models in the controller and the DOM will update itself accordingly, with the help of directives.
In your case, if you just want to display the success/error message, I don't think you need to use a custom directive.
First, you should wrap related form fields in a single modal object instead of multiple modal objects. Like:
<input type="text" name="name" ng-model="person.name">
and
<input type="text" name="occupation" ng-model="person.occupation">
Secondly, you should use ng-submit or ng-click for the form submitting action, like:
<input type="submit" id="submit" value="Submit" ng-click="doSubmit(person)">
or
<form ng-submit="doSubmit(person)">
...
<input type="submit" id="submit" value="Submit">
</form>
Thirdly, you should use ng-model to get the data out of the form instead of serialize(). Like discussed in How can I post data as form data instead of a request payload? :
$scope.doSubmit = function(formData) { // use `=` instead of `:` here
$http({
method: "POST",
url: "/save",
data: $.param(formData),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
// ...
}
And finally, if you want to show some feedback other than text to the user, you should use ng-show, ng-switch, ng-class or ng-style when possible. Like:
<span class="name-error" ng-show="errorMessage.name" ng-bind="errorMessage.name"></span>
And in the fail() callback when you want to display a name error message:
errorMessage.name = "Some error message here."; // don't forget to initialize errorMessage to an empty object
And that's it!
Update
For the questions you ask in the comments, I think, in Angular, people may prefer using separate cohesive directives for individual DOM elements, or nested directives, and then connecting them with models or controllers(nested directives).
In your example, I would suggest you use a combination of both.
First, use a set of nested directives for the UI purpose. You may have a directive binding to the body tag and accessing viewport info there. Then you can access that in the inside directives with require: '^ParentDirective'.
Then, you can bind your models to the inside directives. Thus, you separate data and UI manipulation.
e.g.
<body auto-size-messages>
<div ng-repeat="message in messages" message="message"></div>
</body>
In auto-size-messages, you get viewport attributes and assign that to the controller. And in message, you manipulate the DOM to place the message on your desired position and show the content according to the message attribute.
You can refer to the Creating a Directive that Wraps Other Elements section in https://docs.angularjs.org/guide/directive for nested directives.