Mix static text and scope's variable inside directive - javascript

I've created a simple form with a name:
<form novalidate ng-controller="TestController" role="form" name="testForm">
<input type="number" min="10" name="textForm" value="4">
<input type="submit" ng-click="validate(testForm)">
</form>
and then I've created a controller:
angular.module("testModule", []).controller("TestController", function($scope){
$scope.validate = function(form){
alert("inside the function validate()");
}
});
This works correctly (since the alert pop up on screen) as you can see here.
Now I've added a variable to the scope $scope.testNumber = 5; and appended this version to the form's name name="testForm{{testNumber}}">and do the same thing on the input submit of the form <input type="submit" ng-click="validate(testForm{{testNumber}})">. And this doesn't work, since I can't see any alert, as you can see here. The syntax is not correct, but how can achieve what I want to do?

Since your ng-click is a function with a param, you need to concat the variables. So testForm + testnumber should give you the desired result.
Controller
angular.module("testModule", []).controller("TestController", function($scope){
$scope.testNumber = 5;
$scope.validate = function(form){
alert("inside the function validate()" + form);
}
});
Html
<form novalidate ng-controller="TestController" role="form" name="testForm{{testNumber}}">
<input type="number" min="10" name="textForm" value="4">
<input type="submit" ng-click="validate(testForm + testNumber)">
</form>
And a plunker to demo the changes

When you use the name attribute of the form element, you are publishing the form instance into the controller scope.
Thus, you will have a property testForm which you can access with $scope.testForm. (Documentation)
Strictly speaking, you don't have to pass the form to the function that you call when you submit as it is accessible from the scope.
However, if you do wish to carry it out, I suggest that you separate the code from the markup - define a scope property in your controller that will hold the name of the form like so:
$scope.myForm = 'testForm1';
You can then use this in your markup as:
<form name="{{myForm}}">
...
<input type="submit" data-ng-click="validate(myForm)"/>
</form>
You can easily create an array of form names and use them in your markup (by indexing them) without having to do string concatenation and cluttering your markup.

Related

When is a scope variable created in AngularJS?

I am new to Angular. Please, consider the following piece of code.
<form name="newEventForm">
<fieldset>
<label for="eventName">Event Name:</label>
<input id="eventName" required ng-model="event.name" type="text" placeholder="Name of your event...">
<button ng-click="saveEvent(event, newEventForm)" type="submit" class="btn btn-primary">Save</button>
<button ng-click="cancelEdit()" type="button" class="btn btn-default">Cancel</button>
</form>
My question is - why do we need to pass the event argument to the saveEvent function? Doesn't using ng-model auto generate an event.name variable through two-way binding on the Angular side? e.g.
<form name="newEventForm">
<fieldset>
<label for="eventName">Event Name:</label>
<input id="eventName" required ng-model="event.name" type="text" placeholder="Name of your event...">
<button ng-click="saveEvent( newEventForm)" type="submit" class="btn btn-primary">Save</button>
<button ng-click="cancelEdit()" type="button" class="btn btn-default">Cancel</button>
</form>
In this second version of the code, I am not explicitly injecting event as a function parameter. However, when pressing submit, this is the code for saveEvent
$scope.saveEvent = function(newEventForm)
{
alert(1);
alert(newEventForm.$valid);
if(newEventForm.$valid)
{
window.alert('event ' + event.name + ' saved!');
}
}
and event is undefined. Shouldn't it be defined? Apologies if the question is a newbie's question. Just trying to get my head around how scope items are created through ng-model, and how does two-way binding work. Thanks !
UPDATE
Doh, I should've used $scope.event. Then it works. Thanks, like I said - new to this and it only dawned to me after I asked the question :)
The view is creating the event variable under the associated scope, use $scope.event.name.
Good luck
Actually all variable or model which are specified in the html are scope variable.
Example
<div ng-controller="myController" ng-init="name='Hello World'">
{{name}}
<button ng-click="myFn(name)"> Click Me </button>
</div>
In this example, I have initiated a variable called name. It is actually a scope variable. This code will actually like
myApp.controller("myController", function($scope){
$scope.name = "Hello World";
$scope.myFn = function(param){
// here you can see that your variable name passed from html is same as your scope variable
if(param == $scope.name){
alert("Yes, two are equal !!!");
}
}
});
This two are same. You can either use html or js.

Passing $scope.master to next form

I have an array in $scope.master, and I've tried passing this when the form has submitted in the following manner:
<form novalidate class="css-form" method='post' action='www.example.com'>
<INPUT type='hidden' name='yourData' value='$scope.master'>
</form>
But the above seems to be passing the string "$scope.master".
I've also tried putting this in another javascript variable and passing the variable, but that doesn't seem to work either.
What would the best approach to this be?
Thank you for your help!
Use {{}} to write into the view with Angular (also omit the $scope when writing into the view):
<INPUT type='hidden' name='yourData' value='{{master}}'>
Try adding an ng-submit directive to your form.
<form novalidate ng-submit="SubmitForm()"
<input type="hidden" name="yourData" ng-model="master"/>
</form>
In your controller:
$scope.SubmitForm = function(){ $http.post('/someUrl',
$scope.master);
}

AngularJS forms not finding input elements

At some point during the development of my app, AngularJS forms stopped working... Yes that means they used to work. That is, form elements are supposed to create their own scope with every <input /> by their name. However all my forms are now completely empty, as if I had no input elements with the name attribute. Now I can't make any sort of form validation. I've tried even the most trivial forms and still nothing:
<form name="form>
<input type="text" name="input" required />
</form>
Any suggestions as to how to debug this?
Hi to do validation your input have to have model directive please see here: http://jsbin.com/deref/1/edit
<form name="form">
<input type="text" name="foo" required ng-model="input.model"/>
<span ng-show="form.foo.$error.required">required</span>
</form>
Try console.log on the scope
console.log($scope.form);
If you have your controllers set up correctly, your form should be attached to the scope of controller.

Coupling View and Controller in Javascript

First i have a very basic Question about coupling two input Elements. In my case it is a Slider and an input element:
<div class="userInput">
<input id="slider" type="range" min="0" max="100"/>
<input id="number" type="number" max="100"/>
</div>
js:
$('#slider').corresponding = $('#number');
$('#number').corresponding = $('#slider');
$('#slider').onchange(function(){this.corresponding.value = this.value;});
$('#number').onchange(function(){this.corresponding.value = this.value;});
So this works for me but also seems to me like a dirty hack, extending the jQuery object. The bad feeling even grows when appending the controller to jQuery Objects:
var MYController = new Controller();
$('#slider').controller = MYController;
$('#slider').onchange(function(){
this.corresponding.value = this.value;
this.controller.sliderChange(this.value);
});
I would appreciate any suggestions how this is done "the right way". I couldn't figure out a better way yet because i have a large and changing number of user inputs, each requiring its own controller Object, held in an array in my Mastercontroller Class.
Maybe you can put all the inputs inside a <form></form> tag in jsp and then call the form submit event or the serialize event. With the latter (serialize any value stored against a button would not be stored and it would need the name attribute in the jsp tags as well, so may be submit is a better option).
//jsp page
<form id="myForm" >
<input type="text" value="Enter here">
<input type="submit" value="Submit">
</form>
//js call
( "#myForm" ).submit(function( event ) {
// call the controller
});

angularjs form input suggestions

I have a problem with a form in angularjs.
Example with classic html & php
<form name="myForm" action="post.php" method="post" autocomplete="on">
<input name="namename" type="text" />
<input name="email" type="text" />
<input name="submit" type="submit" value="submit" />
</form>
which works as expected. On the second visit, after i submitted the form for the first time, i just need to type the first letter and the input field will suggest something based on the first post.
The same form in angular.
<form name="myForm" ng-submit="test(user)" autocomplete="on">
<input name="name" type="text" ng-model="user.name" autocomplete="given-name" />
<input name="email" type="text" ng-model="user.email" />
<input name="submit" type="submit" value="submit" />
</form>
On the second visit here the form will suggest nothing at all, which is very irritating.
Is there any fix for that?
Example
thanks in advance.
That behaviour you're describing is done by the browser and is not guaranteed to work in all situations. It's actually quite easy to do in AngularJS; just keep track of a shared state object. This can be done in several ways, the most easiest by using the value provider like this:
// Create an injectable object with the name 'userInput'
angular.module('myApp').value('userInput', {});
Now inject this object in the controller that is handling the form like this:
angular.module('myApp').controller('MyController', function($scope, userInput) {
// Assign the state object to the scope so it's available for our view
$scope.user = userInput;
});
Render the form as you did and you'll see that the state of the form is kept. In fact, this is one of the hidden gems when programming with Angular since it allows you to keep very complex state information, which was previously pretty impractical.
Live demo can be found in this plunker.
Edit
One way to get the autocomplete to work is to maintain datalist elements. Just store the previous entered values in an array and use a ng-repeat to render all the options. Associate the input element with the datalist using the list attribute and you'r good to go.
<input list="nameHistory" type="text" ng-model="user.name" />
<datalist id="nameHistory">
<option ng-repeat="item in userHistory.name" value="{{ item }}"></option>
</datalist>
Live demo can be found in this plunker.
Just add to the input tag this attribute autocomplete="off"

Categories

Resources