Insert $index into name attribute in an ng-repeat angularJS - javascript

In order for ASP.NET MVC to correctly bind a list of items on a form post, the name attribute has be along the lines of
name='Show.Days[0].OpenHour'
name='Show.Days[1].OpenHour'
The user can enter the number of days the show will be into a form field, which then updates the model and the ng-repeat.
I'd like to be able to insert the appropriate index into the name field, something like
name='Show.Days[$index].OpenHour'
Is this possible with angular?

Use name="Show.Days[{{$index}}].OpenHour". With this, AngularJS evaluates $index and replaces it with the correct value.

It seems that you forgot to wrap the expression with {{ and }} in the view. Do you need something like this?
var app = angular.module('myApp', []);
app.controller("myCtrl", function ($scope) {
$scope.Show = {
Days: [
{OpenHour: '8am'},
{OpenHour: '10am'}
]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div ng-repeat="day in Show.Days">
<input type="text" ng-model="Show.Days[$index].OpenHour" name="{{Show.Days[$index].OpenHour}}">
</div>
</div>
</div>
or like this?
var app = angular.module('myApp', []);
app.controller("myCtrl", function ($scope) {
$scope.Show = {
Days: [
{OpenHour: '8am'},
{OpenHour: '10am'}
]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div ng-repeat="day in Show.Days">
<input type="text" ng-model="Show.Days[$index].OpenHour" name="Show.Days[{{$index}}].OpenHour">
</div>
</div>
</div>

Related

Show html tags on the page with ng-bind-html

Please see below given code:
<div ng-app="myApp" ng-controller="myCtrl">
<p ng-bind-html="myText"></p>
</div>
<script>
var app = angular.module("myApp", ['ngSanitize']);
app.controller("myCtrl", function($scope) {
$scope.myText = "My name is: <h1>John Doe</h1>";
});
</script>
The output is: My Name is:
John Doe
How can i show the text as it is. For example: My Name is : <h1>John Doe</h1>
I want to show the HTML tags on the page.
Please use the $sce of angularjs.
var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope, $sce) {
$scope.myText = $sce.trustAsHtml("My name is: <h1>John Doe</h1>");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<div ng-app="myApp" ng-controller='MyController'>
<p ng-bind-html="myText"></p>
</div>
Reference:
How to use $sce
First create a filter using $sce:
app.filter("html", ['$sce', function($sce) {
return function(input){
return $sce.trustAsHtml(input);
}
}]);
Then:
<div ng-bind-html="myText | html"></div>
Use ng-bind instead ng-bind-html
<div ng-app="myApp" ng-controller="myCtrl">
<p ng-bind="myText"></p>
</div>
Or simply
<p>{{myText}}</p>
I think you should use like this
in your controller
$scope.mytext="&lth1&gtJohn Doe&lt/h1&gt"
in you html page
<p ng-bind-html="myText"></p>

How to display an array with html content without ng-repeat? AngularJS

I have this
"items" : ["<p>Item 1</p>","<span>Item 2</span>"]
I would like this
<div id="container">
<p>Item 1</p>
<span>Item 2</span>
</div>
How can I do it without using ng-repeat ?
You can use directly like this..
$scope.itemNames = {"items" : ["<p>Item 1</p>","<span>Item 2</span>"]};
<div ng-bind-html-unsafe="itemNames.items"> </div>
or else
use $sce.
.controller('ctrl', ['$scope', '$sce', function ($scope, $sce) {
$scope.itemNames = {"items" : ["<p>Item 1</p>","<span>Item 2</span>"]};
$scope.newNames= $sce.trustAsHtml($scope.itemNames.items);
}]);
<div ng-bind-html="newNames"> </div>
In AngularJS you can use the ng-bind-html directive to print html and for that you must include the $sanitize service.
Now, to pass the array as an html string to the view you can use Array.prototype.join():
angular
.module('App', ['ngSanitize'])
.controller('AppController', ['$scope', function ($scope) {
var obj = {
"items": ["<p>Item 1</p>","<span>Item 2</span>"]
};
$scope.items = obj.items.join('');
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.10/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.5.10/angular-sanitize.min.js"></script>
<div ng-app="App" ng-controller="AppController">
<div id="container" ng-bind-html="items"></div>
</div>

Is there an angular directive that can restrict scope for an element in the DOM

Hi I was just wondering if there is some built-in angular directive (ng-some-directive) that allows you to restrict the scope to a particular model for the desired DOM element.
I belive I have seen something similar done before, but maybe I am thinking of knockout.js
<script>
angular.module('example', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.heading = 'Some Value';
$scope.complexModel = {...}
}]);
</script>
<div ng-controller="ExampleController">
<h1>{{ heading }}</h1>
<div ng-some-directive='complexModel.to.long.really.annoying'>
<input type='text' ng-model='variable' /> // Actually coming from complexModel.to.long.really.annoying.variable
</div>
</div>
This is a drastically simplified version
Though its not meant for it
<div ng-init='sn = complexModel.to.long.really.annoying'>
<input type='text' ng-model='sn' />
</div>

AngularJS Dynamic Template with indexed scope variable arrays

I'm using AngularJS and trying to create a form where I can dynamically add new inputs, similar to this fiddle: http://jsfiddle.net/V4BqE/ (Main HTML below, working code in fiddle).
<div ng-app="myApp" ng-controller="MyCtrl">
<div add-input>
<button>add input</button>
</div>
</div>
I would like to be able to use a HTML template for my form since the input I'm adding is ~300 lines long. My issue is I cannot figure out how to index the scope variable containing the data when used in a template. I've tried to make my own modified version of the above code on plnkr http://plnkr.co/edit/4zeaFoDeX0sGTuBMCQP2?p=info . However, when I click the button no form elements appear.
Online (plnkr) I get a 404 not found for my template.html, but I think that is just a plnkr limitation. On my machine with a Python HttpServer I get an Error: [$parse:syntax] for the $templateRequest and a TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. when using the $http.get method.
Any advice for getting the indexed scope variable array to work with an external html file?
Thanks, JR
Edit: Update plnkr link
You can do it without directive & external template
what you are trying to do does not require a directive (it actually much simple with the basic angularjs tools)
http://plnkr.co/edit/LVzGN8D2WSL2nR1W7vJB?p=preview
html
<body>
<div class="container" ng-app="myApp" ng-controller="MyCtrl">
<button class="btn btn-primary" type="button" ng-click="addPhoneInput()">add input</button>
<form>
<div ng-repeat="item in telephoneNumbers">
<hr>
<input type="text" ng-model="item.phone">
</div>
</form>
<hr>
<div class="well">
<h4>Phone Numbers,</h4>
<p ng-repeat="item in telephoneNumbers">{{item.phone}}</p>
</div>
</div>
</body>
js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function($scope) {
// Define $scope.telephone as an array
$scope.telephoneNumbers = [];
$scope.addPhoneInput = function() {
$scope.telephoneNumbers.push({});
};
// This is just so you can see the array values changing and working! Check your console as you're typing in the inputs :)
$scope.$watch('telephoneNumbers', function(value) {
console.log(value);
}, true);
}]);
If you insist using a directive,
http://plnkr.co/edit/BGLqqTez2k9lUO0HZ5g1?p=preview
phone-number.template.html
<div>
<hr>
<input type="text" ng-model="ngModel" >
</div>
html
<body>
<div class="container" ng-app="myApp" ng-controller="MyCtrl">
<button class="btn btn-primary" type="button" ng-click="addPhoneInput()">add input</button>
<form>
<phone-number ng-repeat="item in telephoneNumbers" ng-model="item.phone"></phone-number>
</form>
<hr>
<div class="well">
<h4>Phone Numbers,</h4>
<p ng-repeat="item in telephoneNumbers">{{item.phone}}</p>
</div>
</div>
</body>
js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function($scope) {
// Define $scope.telephone as an array
$scope.telephoneNumbers = [];
$scope.addPhoneInput = function() {
$scope.telephoneNumbers.push({});
};
// This is just so you can see the array values changing and working! Check your console as you're typing in the inputs :)
$scope.$watch('telephoneNumbers', function(value) {
console.log(value);
}, true);
}]);
app.directive('phoneNumber', function(){
return {
replace:true,
scope: {
ngModel: '=',
},
templateUrl: "phone-number.template.html"
}
});

Avoiding Dupes when pushing values from form to array in AngularJS

I'm having problems avoiding dupes with my code. Here is a simplified example. I know the problem is in the array object being a reference of the same scope variable, but what is the best way to avoid it?
<div ng-app="myApp">
<div ng-controller="myCtrl">
<input type="text" ng-model="item" />
<div ng-repeat="item in items">
{{ item }}
</div>
<button ng-click="save()">Save</button>
</div>
</div>
<script>
angular.module('myApp', []).
controller('myCtrl', function ($scope) {
$scope.items = [];
$scope.save = function() {
$scope.items.push($scope.item);
}
});
</script>
Here is a fiddle that demonstrates the problem:
http://jsfiddle.net/u8Fuk/8/
Use track by syntax to fix this problem.
<div ng-repeat="item in items track by $index">
{{ item }}
</div>
Here is a fiddle.
Depends on what your goal is.
If you want to allow for duplicate values you need to change the code a bit as each item in the ngRepeat has to have a unique id. See the track by section here.
That would work like this:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<input type="text" ng-model="item" />
<div ng-repeat="item in items">
{{ item.value }}
</div>
<button ng-click="save()">Save</button>
</div>
</div>
<script>
angular.module('myApp', []).
controller('myCtrl', function ($scope) {
$scope.items = [];
$scope.save = function() {
$scope.items.push({value:$scope.item});
}
});
</script>
See the updated fiddle here.
If you don't want to allow for the same values you need to search for it.
<div ng-app="myApp">
<div ng-controller="myCtrl">
<input type="text" ng-model="item" />
<div ng-repeat="item in items">
{{ item }}
</div>
<button ng-click="save()">Save</button>
</div>
</div>
<script>
angular.module('myApp', []).
controller('myCtrl', function ($scope) {
$scope.items = [];
$scope.save = function() {
var found = $scope.items.reduce(function(previous, i){
if ($scope.item === i) return true;
return previous;
}, false);
if (found){
alert('duplicate value');
}
else{
$scope.items.push($scope.item);
}
}
});
</script>
See the updated fiddle here.

Categories

Resources