Text binding between input and span in Angular - javascript

How can I bind input texts to span innerHTML in Angular6?
ts file
...
finance_fullname: string;
...
template file
<input type="text" id="finance_fullname" [(ngModel)]="finance_fullname">
<span class="fullname" ngBind="finance_fullname"></span>

I can say most secure way would be innerText or textContent.
<span class="fullname" [textContent]="finance_fullname"></span>
<span class="fullname" [innerText]="finance_fullname"></span>
Even AngularJS were using textContent for one way binding. It only extract the model value and dump directly inside the specified html node. Even though if you pass html it will add that html as a text(decoded html) on the page.
Demo
innerHTML would also work for you, but it could be dangerous, as it will give a chance to inject malicious content on the page in form of html.

I don't know why you are reading from angularjs since you are working with angular 6.
If you want double binding just do it like this.
<input type="text" id="finance_fullname" [(ngModel)]="finance_fullname">
<span class="fullname">{{finance_fullname}}</span>

You can do it in two ways
(i) You can use [innerHTML]
<input type="text" id="finance_fullname" [(ngModel)]="finance_fullname">
<span class="fullname" [innerHTML]="finance_fullname"></span>
STACKBLITZ DEMO
(ii) Just bind using the two way data binding
STACKBLITZ DEMO
<input type="text" id="finance_fullname" [(ngModel)]="finance_fullname">
<span class="fullname">{{finance_fullname}}</span>

Related

Angular - Adding an input's value with a number from $scope

I have the following code:
<div data-ng-controller="MainController">
<input class="amount" type="text" name="" value="" />
<input class="result" type="text" name="" value=""/>
</div>
I want to take a numerical value from $scope and add it to a number entered by a user in the input with class "amount" and display the result in the input with class "result". So, basically, the variable is defined in the MainController function as the following:
$scope.cost = 100;
I'm a bit confused as to what the best way is to do this, I see there are ng-value and ng-model directives at my disposal but I am having a hard time understanding which is the right one for this application (and how to properly use them).
Seems like your application is asking for an inputs and they are going to submit there values OR gonna store it somewhere in DB. So ng-model (two way binding) will suits you application, which will update the value on model & view both.
Markup
<div data-ng-controller="MainController">
<input class="amount" type="text" ng-model="cost"/>
</div>
Above field will pre-populated as 100 and as you update it will also change $scope.cost value and the value if it is displayed on view anywhere.
Don't think about the ng-value that is only one way sort of binding. You can assign the value to input using ng-value="cost" that will only update the value attribute of input but when you update input from html you will never get those changes reflected inside cost scope variable as ng-value is meant for single way binding. Thinks like you should use use ng-value only when you want to display a value.
you should use ng-model
ng-value : Its a directive useful for evaluating expression and the value is bound to $scope used for evaluating expressions
ng-model : helps in two-way data binding ,view-->controller and vice versa moreover its a directive binds the value of HTML controls

Dynamically generating validation attribute on input using interpolation

Edit: This question is no longer relevant as of Angular version: 1.3.0-beta.12 you can now parse ng-minlength and ng-maxlength dynamic values. See: https://github.com/angular/angular.js/issues/5319
My problem is quite simple: I need to dynamically create input validation (ex. ng-minlength) using interpolation.
And doing that I am running into some issues specifically generating the validation attributes for ng-minlength and ng-maxlength. I assume this is due to them only taking constants?
Below you can see my code, the reason I am using a wrapper through outerForm is that I cannot dynamically generate the name attribute of input elements using interpolation, and that I have to wrap each set of repeated inputs in an ngForm directive and nest these in an outer form element.
So again, the problem lies in the attribute ng-minlength="field.ValidationAttributes['data-val-length-min']" not being properly set.
When I print the value directly using {{field.ValidationAttributes['data-val-length-min']}} the value appears correct.
Do I have to create a directive to parse my information, do I need to create my own min/max validation or am I simply running into a syntax error?
<form name="outerForm">
<div ng-repeat="field in logEntry.StringValues">
<ng-form name="innerForm">
<input type="text" name="foo" ng-model="item.foo" ng-minlength="field.ValidationAttributes['data-val-length-min']" required/>
<span ng-show="innerForm.foo.$error.required">required</span>
<span ng-show="innerForm.foo.$error.minlength">to short</span>
</ng-form>
</div>
</form>
Hi you can use double {} to interpolate dynamic validation rules please see here: http://jsbin.com/xayiro/1/
If you can post you field.ValidationAttributes model I can update jsbin.
HTML:
<ng-form name="innerForm">
<input type="text" name="foo" ng-model="item.foo" ng-minlength="{{validation.minlength}}" required/>
<span ng-show="innerForm.foo.$error.required">required</span>
<span ng-show="innerForm.foo.$error.minlength">to short</span>
</ng-form>
JS:
$scope.validation= {
maxlength:20,
minlength:3
};

Angular.js: update binding after manual modification

I'm only starting to dive into angular.js and have found this issue that I can't seem to get around. Consider this simple code:
<input type="text" ng-model="test">
<input type="text" value="{{test}}">
When I write in the first field, the second one is updated nicely. When I write in the second field and then go back to the first one, the binding is not updated anymore. Interestingly though, the HTML attribute value does get updated - it's just not displayed.
Equivalent (at least roughly) code in vanilla javascript does not suffer from this:
<input type="text" id="model">
<input type="text" id="binding">
<script>
var model = document.getElementById("model");
var binding = document.getElementById("binding");
model.addEventListener("keyup",function() {
binding.value = model.value;
});
</script>
Here's a fiddle for you to test both: http://jsfiddle.net/Q6b5k/
Any idea why this happens when using angular.js and how to fix this?
[EDIT] Judging by the initial replies, it appears I have not made it clear. I do not want the second field to update the first one. The binding is to be one-way only, e.g. to allow filtering or even manual corrections (such as automatic creation of a URL alias in a blog post creation form). http://jsfiddle.net/Q6b5k/1/
The value attribute is only used when rendering the initial HTML. After the page load, everything else happens in the Angular Event Loop and therefore you need to do something that event loop can pick up. You can use ng-change for what you are looking to do:
<input type="text" ng-model="test" ng-change="test2=test.toLowerCase();" />
<input type="text" ng-model="test2"">
This happens because {{value}} does not create a binding, it is used for interpolation.
The simplest solution is to use ng-model in both the fields
<div ng-app>
Angular.js:<br>
<input type="text" ng-model="test">
<input type="text" ng-model="test">
</div>
Demo: Fiddle

is `<element />` to `<element> </element>` valid?

Is it valid to replace elements with <element /> to <element></element>. In this case i want to have,
<input {attributes}></input>
just so i can append validation data within... Also could this be possible from a <br /> or <hr /> etc?
The <input> tag does not have a </input> and there is no need for one. Same for <br> and <hr>. You can put validation data as attributes on the input tag (or any tag) with custom attributes like this:
<input type="text" data-validate="num">
If what you mean by validation is separate HTML that you want to display near the input tag, then put it in it's own tags before or after the <input> tag:
<input type="text"><span class="validHint">This field accepts only numbers</span>
<input></input> is not valid in neither HTML4.01 nor HTML5.
According to W3C's validation service: (reason highlighted)
Validation Output: 1 Error
Line 9, Column 15: Stray end tag input.
<input></input>
So here you go, you can not replace <input> with <input></input>.
If you want to attach data to elements, why not use data-* attributes? (e.g. <input data-color="red" />) This is valid, and should be just as easy to implement.
In classic HTML up to and including HTML 4.01, <input></input> is invalid. In practice, browsers ignore the stray end tag. They do not ignore the content between the tags, so <input>foo</input> achieves nothing as compared with <input>foo. HTML5 does not propose to change this.
In XHTML, <input></input> is valid but should not be used on the Web, according to XHTML specs. If you put any content between the tags, it becomes invalid, because the input element has been declared with EMPTY content model.
So you should take a completely different approach. It really depends on what you are trying to achieve, and should be discussed under some other heading. Depending on the problem, the solution could be one of the new HTML5 attributes, or a data- attribute, or a hidden field, or an element hidden some way, or maybe just data in the document tree.

I'm having trouble traversing a newly appended DOM element with jQuery

I have a form that I want to be used to add entries. Once an entry is added, the original form should be reset to prepare it for the next entry, and the saved form should be duplicated prior to resetting and appended onto a div for 'storedEntries.' This much is working (for the most part), but Im having trouble accessing the newly created form... I need to change the value attribute of the submit button from 'add' to 'edit' so properly communicate what clicking that button should do. heres my form:
<div class="newTruck">
<form id="addNewTruck" class='updateschedule' action="javascript:sub(sTime.value, eTime.value, lat.value, lng.value, street.value);">
<b style="color:green;">Opening at: </b>
<input id="sTime" name="sTime" title="Opening time" value="Click to set opening time" class="datetimepicker"/>
<b style="color:red;">Closing at: </b>
<input id="eTime" name= "eTime" title="Closing time" value="Click to set closing time" class="datetimepicker"/>
<label for='street'>Address</label>
<input type='text' name='street' id='street' class='text' autocomplete='off'/>
<input id='submit' class='submit' style="cursor: pointer; cursor: hand;" type="submit" value='Add new stop'/>
<div id='suggests' class='auto_complete' style='display:none'></div>
<input type='hidden' name='lat' id='lat'/>
<input type='hidden' name='lng' id='lng'/>
</form>
</div>
ive tried using a hundred different selectors with jquery to no avail... heres my script as it stands:
function cloneAndClear(){
var id = name+now;
$j("#addNewTruck").clone(true).attr("id",id).appendTo(".scheduledTrucks");
$j('#'+id).filter('#submit').attr('value', 'Edit');
$j("#addNewTruck")[0].reset();
createPickers();
}
the element is properly cloned and inserted into the div, but i cant find a way to access this element... the third line in the script never works.
Another problem i am having is that the 'values' in the cloned form revert back to the value in the source of the html rather than what the user inputs.
advice on how to solve either of these issues is greatly appreciated!
I think you want to use find not filter
$j('#'+id).find('#submit')
That should work in practice, though you've got problems there because there are multiple elements with the same id. I'd change your HTML to use classes, or in this specific case, you don't need either:
$j('#' + id).find(":submit")
have you tried using .val()? and instead of .filter(), use .find()
$j('#'+id).find(':submit').val('Edit');
nickf solution works. (just wrote a piece of code to check that). Do check the definition of filter in jquery documentation.
Reduce the set of matched elements to those that match the selector or pass the function's test.
You have use find in this case. Also as nick mentioned having multiple elements with same id is troublesome, especially when you are doing dom manipulation. Better go with appropriate classes.

Categories