Loading a field value without overwriting - angularjs

I have several fields loaded within a directive call for a page, each of which should be loaded with prepopulated data from either a REST call or Local Storage.
Right now, the mechanism I use loads the field through $scope, but when the page finishes loading, the value itself is never populated. When loaded using a jQuery alter, the value is initalized, and then vanishes on page load. I am not sure what the cause is here, and being fairly new to Angular, I am not sure how to best work around this trivial measure.
The directive form markup is below:
<form name="testfield" ng-controller="testfieldApp" ng-submit="verify(testform)" novalidate>
<input type="text" name="testfield" id="testfield" ng-model='testfield' value="{{TestField}}" required />
</form>
The wrapping Controller
app.controller('testfieldApp', function ($scope, $window, $http, $localStorage) {
$scope.TestField = "Test Name";
//Additional $scope. methods exist for validation and submit, omitted
});

You only need ng-model, but it is case sensitive. ng-model will override whatever you have in value. Try this instead:
<input type="text" name="testfield" id="testfield" ng-model="TestField" required />

Related

Angular Form HTML from API with ng-model not binding

So I'm generating form HTML on the server and serving it up via an API for angular to use. The reason for this is that the forms need to be generated by server-side plugins. This may not be the best way do to it for Angular, but I'm asking whether it will be possible...
template.html
<form>
<div ng-bind-html="form"></div>
<button ng-click="save"></button>
</form>
directive.js (abridged)
ExtensionManagementService.getConfiguration({
extension_id: $scope.extension.id,
configuration_id: configuration.id || null
}).$promise.then(function(data) {
$scope.form = $sce.trustAsHtml(data['form']);
$scope.configuration = data.data;
})
The code above binds successfully into the div and I can see the form as I expect.
Example markup:
<p>
<label for="id_name">Name:</label>
<input id="id_name" name="name" ng-model="configuration.name" type="text" />
</p>
I have a save event that passes the scope.configuration into a controller which I then console out the values.
However configuration.name is always blank, I expect because angular hasn't registered the binding of the inserted markup.
Is there a way to essentially give Angular a nudge?
As #originof suggested, and a colleague almost beat him to it, the $compile module is the key to this:
ExtensionManagementService.getConfiguration({
extension_id: $scope.extension.id,
configuration_id: configuration.id || null
}).$promise.then(function(data) {
var form_element = $element.find('div[role="form"]');
form_element.html(data['form']);
$scope.configuration = data.data;
$compile(form_element.contents())($scope);
});

How get form by name in $scope?

How to get form by name in $scope?
Test example:
<div ng-controller="solod">
<form name="good_f">
<input type="text" name="super">
</form>
</div>
<script>
function solod($scope){
console.log($scope.good_f) //undefined
}
</script>
Is it possible?
Thank you
You usually don't want the controller to access the form like this, that's coupling the controller to the structure of the view too tightly. Instead, pass the form to the controller like this...
<div ng-controller="solod">
<form name="good_f" ng-submit="submit(good_f)">
<input type="text" name="super">
</form>
</div>
<script>
function solod($scope){
$scope.submit = function(theForm){
console.log(theForm)// not undefined
console.log($scope.good_f) // will exist now also
};
// do stuff in a watch
$scope.$watch("good_f", function(formVal){ console.log(formVal);});
}
</script>
Otherwise, if you just want to track the value of the text input, give it an ng-model
Edit:
On further research, $scope will have good_f as a property, just not when you're logging it in the constructor. You could set up a watch on good_f if you wanted, but I still think you should pass it in.
name (optional) string Name of the form. If specified, the form
controller will be published into related scope, under this name.
https://docs.angularjs.org/api/ng/directive/form
Another possible way is to use ng-form, this will help you to access the form via scope easily.
<div ng-controller="solod">
<ng-form name="good_f">
<input type="text" name="super">
</ng-form>
</div>
Script code in your controller:
EDIT:
As JeremyWeir mentioned, to solve your problem you can use $timeout service of angularjs
function solod($scope){
$timeout(function(){
console.log($scope.good_f);
});
}
Caution: Don't use this - seriously
Angular is not jQuery.
As par as your question is concerned you can use $element in your controller(if you are not concrete with the $scope usage for this use case) -
myApp.controller("myCtrl", function($scope, $element){
alert($element.find('form').attr('name'));
$scope.myFormName = $element.find('form').attr('name');
});
PLNKR DEMO

$scope undefined in Angularjs

I'm creating an Angular app for learning (I'm all new to Angular) and currently stuck at this point.
Following is my Angular controller
cookingPad.controller('RecipeCreateController', function($scope, $http) {
$scope.recipeSave = function($scope, $http){
//code
};
});
Following is my form
<form id="signup-form_id" ng-submit="recipeSave()">
//some html
<input type="text" name="name" ng-model="recipeFormData.name" id="name" class="form-control input-lg no-border-radius" placeholder="Name">
// some more html
<button class="btn btn-lg btn-success" id="save1" type="submit"><i class="fa fa-save"></i> Save</button>
</form>
So when I enter something in the text box and click save it comes inside the recipeSave function. but when I check the $scope variable with chrome dev tools, it shows it as
$scope
undefined
What could be the reason? Everything else in my Angular works im on Angular 1.2.4, I found several SO questions but none of them works for me.
Don't re-declare the controller args in recipeSave:
$scope.recipeSave = function() {
Make that change and things should start working. Your template is explicitly invoking recipeSave() with no arguments, and you want to access your controller arguments via closure anyway, which will work fine.
This is due to the recipeSave method having $scope and $http as arguments. Dependency Injection works on the Controller/Service/Filter/etc level, atributes from different scopes as recipeSave won't solve dependency injection.
In other words, on the view you are not passing parameters when you execute the recipeSave function, so the function gets undefined as the value of both parameters.
Cheers

AngularJS post form to external URL

I have the following form in my AngularJS app which contain hidden fields with values filled based on user selection on some inputs on the form (radio buttons...etc), when the user click on the Submit link I should route the user to an external URL while passing hidden fields just as any normal form submission. Unfortunately I can't do this as some of the hidden field values are dependent on some calculations inside a function of the view related controller (as shown below in controller code, so I was wondering is there a way I can call the controller function from this form, then the controller function post the whole form and its field? Any example is highly appreciated. Thanks.
Note I am using link instead of a button.
<form name="clientPaymentForm" id="clientPaymentForm" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">>
<div>
<fieldset>
<input id="name" type="text" required placeholder="Client Name" ng-model="client.name">
...
...
<input type="hidden" name="amount" ng-value="order.total">
...
...
<a class="orderButton" href="javascript:{}" onclick="document.getElementById('clientPaymentForm').submit(); return false;">Order Now</a>
</fieldset>
</div>
</form>
Controller:
$scope.processOrder = function(){
//Order calculation happens here to update order.total value and can only happen after click click Order Now to place the order...
};
I guess this is a bit late, but what you want to use is the ng-click directive which will allow you to call functions defined directly on the scope.
Assuming that you've defined $scope.processOrder, change your a tag to the following:
<a class="orderButton" ng-click="processOrder()">Order Now</a>
And everything should work as hoped.
Alternatively, you could use ng-submit on the form to have it work when you press the "Enter" or "Return" key, as in:
<form name="clientPaymentForm" id="clientPaymentForm" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" ng-click="processOrder()">.

How to prevent transcluding directive to create new child scope for the form directive?

I have a problem with directive transclude and the form directive. As you may know, the form will end up in the "scope" if you add the "name"-property to the form tag, then you can check for form validation and so on.
My problem start when i put the form tag in a directive that uses transclude. I'm aware of how to deal with this problem with two-way data binding, as mention here https://stackoverflow.com/a/14484903/1029874 -- "use an object instead of a primitive"
But my form ends up in the transcluding directives scope. Here is an example of what i want to do.
<div ng-controller="appCtrl">
<widget>
<widget-header>{{model.property}}</widget-header>
<widget-body>
<!-- The form will end up in "widget-body":s scope instead of appCtrl:s scope -->
<form name="appForm" ng-submit="submit()">
<input type="text" required ng-model="model.property" />
<input type="submit" value="submit" />
</form>
</widget-body>
</widget>
</div>
And here is the fiddle, http://jsfiddle.net/WLksJ/1/
Is there a way that I can get around this behavior?
Thanks!
An interesting question, but a problem that's easily avoided by using
<form name="appForm" ng-submit="submit(appForm.$valid)">
and checking the parameter in the submit function.
http://jsfiddle.net/udMJ7/
Another (perhaps better) option is to use this which is set to the scope of the last controller (in this case the form controller, which we want)
$scope.submit = function(){
if(this.appForm.$valid){
//post the form!!
}
};
http://jsfiddle.net/udMJ7/1/

Resources