How to set ng-model to parent scope with a dynamic value - javascript

I am trying to dynamically generate a name for the ng-model on the select tags, and have it accessible in the parent scope like on table two, but obviously have them work independent of each other.
So my question is how do I set the ng-model to something like "$parent.ot1" data array of objects?
var overtimeapp = angular.module('overtime', []);
overtimeapp.controller('ctrlOvertime', function ($scope, $http) {
$scope.overtimes = [{"otid" : "ot1"}, {"otid" : "ot2"}];
$scope.overtimetypes = ['d', 'n', 'r', 's', 'h'];
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body>
<div ng-app="overtime" ng-controller="ctrlOvertime">
table one
<table class="table table-bordered">
<tbody>
<tr ng-repeat="o in overtimes">
<td>
<select class="w3-select" ng-model="o.otid" ng-options="x for x in
overtimetypes"></select>
</td>
</tr>
</tbody>
</table>
table two
<table class="table table-bordered">
<tbody>
<tr ng-repeat="o in overtimes">
<td>
<select class="w3-select" ng-model="$parent.selected" ng-options="x for x in
overtimetypes"></select>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

Initialize $scope.selected as an array in the controller:
$scope.selected = [];
Then use $index in the ng-model directive:
<table class="table table-bordered">
<tbody>
<tr ng-repeat="o in overtimes">
<td>
<select class="w3-select"
̶n̶g̶-̶m̶o̶d̶e̶l̶=̶"̶$̶p̶a̶r̶e̶n̶t̶.̶s̶e̶l̶e̶c̶t̶e̶d̶"̶
ng-model="selected[$index]"
ng-options="x for x in overtimetypes">
</select>
</td>
</tr>
</tbody>
</table>

Related

How to replace value in ng-repeat if value =="string" else don't display

I'm trying to replace my data in my table with strings "Yup" and " ": if the string is equal to "yes" then display "Yup" else don't display, Sorry I'm newbie and I saw some solutions and I tried this but doesn't work: {{ person.value ? "Yup":" "}} .. Any help please
angular.module('selectExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.register = {
value: [
{value:"Yes"},{value:"no"},{value:"yes"},
{value:"No"},{value:"no"}
],
};
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="selectExample" ng-controller="ExampleController">
<table id="example" width="100%">
<thead>
<tr align="center">
<th>Value</th>
<th>Replace</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in register.value">
<td align="center">{{ person.value }}</td>
<td align="center">{{ person.value ? "Yup":" "}}</td>
</tr>
</tbody>
</table>
</div>
If you can't change your values you can call toLowerCase() on the value to make sure it's lower case and then compare it to "yes"
angular.module('selectExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.register = {
value: [
{value:"Yes"},{value:"no"},{value:"yes"},
{value:"No"},{value:"no"}
],
};
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="selectExample" ng-controller="ExampleController">
<table id="example" width="100%">
<thead>
<tr align="center">
<th>Value</th>
<th>Replace</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in register.value">
<td align="center">{{ person.value }}</td>
<td align="center">{{ person.value.toLowerCase() == "yes" ? "Yup":" "}}</td>
</tr>
</tbody>
</table>
</div>
The reason your code wasn't working it because when you use a ternary (? :) it converts the values into truthy values, and a non-empty string will always be true, so every value is true and will always be "Yup"
angular.module('selectExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.register = {
value: [
{value:"Yes"},{value:"no"},{value:"yes"},
{value:"No"},{value:"no"}
],
};
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="selectExample" ng-controller="ExampleController">
<table id="example" width="100%">
<thead>
<tr align="center">
<th>Value</th>
<th>Replace</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in register.value">
<td align="center">{{ person.value }}</td>
<td align="center">{{ person.value.toLowerCase() == "yes" ? "Yup":" "}}</td>
</tr>
</tbody>
</table>
</div>

Why do I get the error message : Uncaught TypeError: Unable to process binding "text: function (){return $data.tracks.items[0].id }"...?

I'm getting the following error: Uncaught TypeError: Unable to process binding "text: function (){return $data.tracks.items[0].id }" Message: Cannot read property 'items' of undefined.
Basically, what I'm doing is bringing info this API provides https://developer.spotify.com/web-api/console/get-search-item/ and showing it accordginly.
I have checked whether I'm addressing the JSON wrong, but I think I'm not.
This is my html file:
<html>
<head>
<title>Spotify</title>
<link rel="stylesheet" href="css/design.css"/>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>
<h1>Spotify</h1>
<form data-bind="submit: guardar">
<div>
<label> Name (of the artist, track or album): </label><input type="text" id ='query' data-bind="value: query">
<p>
<select id = "itemType">
<option value="" >Choose item type...</option>
<option value="artist">Artist</option>
<option value="track">Track</option>
<option value="album">Album</option>
</select></p>
</div>
<button type="submit">Search</button>
</form>
<table id="artist" class="drop-down-show-hide">
<thead>
<tr>
<th>Name</th>
<th>Popularity</th>
<th>URI</th>
<th></th>
</tr>
</thead>
<tbody data-bind= "foreach: queries">
<tr>
<td data-bind="text: $data.artists.items[0].name"></td>
<td data-bind="text: $data.artists.items[0].popularity"></td>
<td data-bind="text: $data.artists.items[0].uri"></td>
<td></td>
</tr>
</tbody>
</table>
<table id="track" class="drop-down-show-hide">
<thead>
<tr>
<th>Artist</th>
<th>Album Type</th>
<th>URI</th>
<th></th>
</tr>
</thead>
<tbody data-bind= "foreach: queries">
<tr>
<td data-bind="text: $data.tracks.items[0].artists[1].name"></td>
<td data-bind="text: $data.tracks.items[0].album.album_type"></td>
<td data-bind="text: $data.tracks.items[0].uri"></td>
<td></td>
</tr>
</tbody>
</table> -->
<table id="album" class="drop-down-show-hide">
<thead>
<tr>
<th>URL to listen on Spotify</th>
<th>URI</th>
<th></th>
</tr>
</thead>
<tbody data-bind= "foreach: queries">
<tr>
<td data-bind="text: $data.albums.items[0].external_urls.spotify"></td>
<td data-bind="text: $data.albums.items[0].uri"></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<script src="libs/jquery-2.2.2.min.js"></script>
<script src="libs/knockout-3.4.0.js"></script>
<script src="js/app.js"></script>
</body>
This is my js file:
(function ($, ko) {
var vm = {
query: ko.observable('Muse'),
itemType: ko.observable('Artist'),
queries: ko.observableArray([]),
guardar: function () {
q = document.getElementById("query").value;
it = document.getElementById("itemType").value;
if (q !== "" && it !== "") {
$.getJSON('https://api.spotify.com/v1/search?q=' + q + '&type=' +
it ).done(function (response) {
vm.queries(response);
this;
});
} else {
alert("Llene todos los campos, por favor.");
}
}
};
ko.applyBindings(vm);
})(jQuery, ko);
$('.drop-down-show-hide').hide();
$('#itemType').change(function(){
$(this).find("option").each(function(){
$("#" + $(this).val()).hide();
console.log($(this));
});
$("#" + $(this).val()).show();
});
Thank youuuuu!
Couple of things
Replace - You declare vm.queries as an array but replace it with Spotify's response, which is a single object of either artists, tracks, or albums.
Solution: Replace <tbody data-bind="queries"> with <tbody data-bind="items">
items is an array that will be in the right context (see below)
Context - Items is undefined because queries contains either artists, tracks, or albums. Therefore $data.queries.albums will be absent when artists is requested.
Solution: Guard the table bindings using data-bind="with: queries().albums"
Simplify - Now that the table bindings are in the right context, simplify the table rows to
Example: tracks
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: popularity"></td>
<td data-bind="text: uri"></td>
</tr>
</tbody>
Here's a working demo.
Other things you can (optionally) consider are:
Binding the select drop down to itemType
Replacing the jQuery change event handler to subscribe to that drop down
Using ko.components for the tables

Render table in angularjs

I want to render tables out of JSONs. The keys should be the TH-tag and the value the TD-tad under it. I managed to render the tables the other way around:
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope){
$scope.init = function(){
$scope.json = {
"entities":{"bezeichnung":"Basis","name":"Basis","id":16},
"entities2":{"bezeichnung":"Basis2","name":"Basis2","id":17}
}
}
});
</script>
<div ng-app="myApp" ng-controller="myCtrl" ng-init="init()">
<div ng-repeat="(key,value) in json">
<table border="1">
<tr ng-repeat="(k,val) in value"><td>{{k}}</td><td>{{val}}</td></tr>
</table>
</div>
</div>
But how to do it the other way around?
jsfiddle
You need to iterate over the keys once for the headings, then iterate over the values for the row.
<div ng-app="myApp" ng-controller="myCtrl" ng-init="init()">
<div ng-repeat="(key, table) in json">
<table border="1">
<thead>
<tr>
<th ng-repeat="(key, _) in table">{{key}}</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="(_, value) in table">{{value}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Updated jsfiddle.
you also do like this
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="Scripts/angular.js"></script>
<script>
var app = angular.module('myApp',[]);
app.controller('MyCtrl', function ($scope) {
$scope.json = [
{ "bezeichnung": "Basis", "name": "Basis", "id": 16 },
{ "bezeichnung": "Basis2", "name": "Basis2", "id": 17 }
]
});
</script>
</head>
<body ng-app="myApp" ng-controller="MyCtrl">
<div>
<table>
<tr>
<td>Index</td>
<td>bezeichnung</td>
<td>name</td>
<td>Id</td>
</tr>
<tr ng-repeat="(key,value) in json">
<td>{{key}}</td>
<td>{{value.bezeichnung}}</td>
<td>{{value.name}}</td>
<td>{{value.id}}</td>
</tr>
</table>
</div>
</body>
</html>

How do I generate nested table in one column if it has list of values using angular js?

index.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.data =[{"Id":1,"Title":"en-US","Description":"UnitedStates","MyValues":[{"Id":100,"Value":"Save"}]},
{"Id":1,"Title":"en-UK","Description":"UK","MyValues":[{"Id":102,"Value":"Delete"}]}]
$scope.cols = Object.keys($scope.data[0]);
$scope.notSorted = function(obj){
if (!obj) {
return [];
}
return Object.keys(obj);
}
});
index.html
<table border=1>
<thead>
<tr>
<th ng-repeat="key in notSorted(cols)" ng-init="value=cols[key]">{{value}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td ng-if="!$last" ng-repeat="dat in notSorted(row)" ng-init="value=row[dat]">{{value}}</td>
</tr>
</tbody>
</table>
It gives me perfect table but problem is in one column MyValues.
I have list of data and want to create nested table with all List value.
How can I achieve this? Want to check if any column has List if yes
then generate nested table.
check this plunker http://plnkr.co/edit/Ixvp8B0dRwOBDHflmu2j?p=preview
You write your markup this way:
<table>
<thead>
<tr>
<th ng-repeat="(k,v) in data[0]">{{k}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)">
<table ng-if="isArr">
<thead>
<tr>
<th ng-repeat="(sh, sv) in value[0]">{{sh}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sub in value">
<td ng-repeat="(sk, sv) in sub">{{sv}}</td>
</tr>
</tbody>
</table>
<span ng-if="!isArr">{{value}}</span>
</td>
</tr>
</tbody>
</table>
Full code: https://gist.github.com/anonymous/487956892d760c17487c
I'm not really sure what you want to render, but this might give you some ideas.
see: http://plnkr.co/edit/znswagx45a2F7IThdQJn?p=preview
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.data =[{"Id":1,"Title":"en-US","Description":"UnitedStates","MyValues":[{"Id":100,"Value":"Save"}]},
{"Id":1,"Title":"en-UK","Description":"UK","MyValues":[{"Id":102,"Value":"Delete"}]}]
$scope.cols = Object.keys($scope.data[0]);
$scope.notSorted = function(obj){
if (!obj) {
return [];
}
return Object.keys(obj);
}
});
index.html
<table border=1>
<thead>
<tr>
<th ng-repeat="key in notSorted(cols)" ng-init="value=cols[key]">{{value}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td ng-if="!$last" ng-repeat="dat in notSorted(row)" ng-init="value=row[dat]">
<div ng-if="value[0].Id">
<table>
<tr>
<td>Id:</td><td>{{value[0].Id}}</td>
</tr>
<tr>
<td>Value:</td><td>{{value[0].Value}}</td>
</tr>
</table>
</div>
<div ng-if="!(value[0].Id)">
{{value}}
</div>
</td>
</tr>
</tbody>
</table>
If you need to be more general, maybe instead of <div ng-if="value[0].Id"> you could do something like <div ng-if="angular.isArray(value)">. I didn't have time to try and get that working though, but something to look into.

Angular: Show div content depending on which option chosen from drop down menu (ng-show/ng-switch)

So I'm completely new to front end (angular, bootsrap, etc), but I have here a JSFiddle link that I created, and what I am trying to do is basically if someone chooses the option "VA" in the drop-down menu, I want to use the appropriate ng (switch or show), and show the div class with the same name, in this case the div class="VA"
If they choose NY, I want it to show the div-class="NY", and not the VA div (in my example I only have two options, but I will have around varying options in my actual program (could be ~10)
Can anyone help me or put me in the right direction? Thanks.
JSFiddle link: http://jsfiddle.net/BootstrapOrBust/kw3qgL3f/
<section ng-controller="Ctrl as loc">
<select class="form-control">
<option>Choose Place</option>
<option value="DC">DC</option>
<option value="NY">NY</option>
</select>
</section>
...
...
...
<div class="DC">
<table class="table">
<thead>
<tr>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>Metro</td>
</tr>
<tr>
<td>Capital</td>
</tr>
</tbody>
</table>
</div>
<div class="NY">
<table class="table">
<thead>
<tr>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>Subway</td>
</tr>
<tr>
<td>Yankees</td>
</tr>
</tbody>
</table>
</div>
http://jsfiddle.net/kw3qgL3f/3/
First off - you have have ng-app somewhere so angular can start up.
<section ng-app="test" ng-controller="Ctrl as loc">
Second, everything that the controller controls has to be INSIDE the element with ng-controller, so we move your </section> below everything else.
When using select, you'll save yourself a lot of headache if you use ng-options instead of listing the options yourself, the one exception is the "choose one" option - put that in as the placeholder:
<select ng-model="showLoc" class="form-control" ng-options="place.abbreviation as place.name for place in places">
<option value="">Choose One</option>
</select>
$scope.places = [
{ abbreviation:'NY', name: 'New York'},
{abbreviation: 'DC', name:'District of Columbia'}
];
At which point you can do:
<div ng-switch="showLoc">
<div ng-switch-when="DC">
...
</div>
<div ng-switch-when="NY">
...
</div>
</div>
However, I would actually probably do it like this:
http://jsfiddle.net/kw3qgL3f/4/
<section ng-app="test" ng-controller="Ctrl as loc">
<select ng-model="selectedPlace" class="form-control" ng-options="place as place.name for place in places">
<option value="">Choose One</option>
</select>
<table ng-if="selectedPlace" class="table">
<thead>
<tr>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="property in selectedPlace.properties">
<td>{{property}}</td>
</tr>
</tbody>
</table>
</section>
$scope.places = [
{ abbreviation:'NY', name: 'New York', properties: ['Subway', 'Yankees']},
{abbreviation: 'DC', name:'District of Columbia', properties: ['Metro', 'Captial']}
];
here is the plunker i create a demo
demo
you can use ng-show with the selected value of the select

Categories

Resources