I have the following ng-repeat call which displays flat 'AVAILABLE' or 'FULL' on the front end. Need to make it more dynamic by modifying html to read from $scope.
<tbody>
<tr ng-repeat="hour in workhours">
<td >{{hour}}:00 - {{hour+1}}:00</td>
<td ng-class="{'full' : !entry.HoursAvailable.includes(hour)}"
ng-click="checkSlotAvailability(hour, jobLength, entry, data)"
ng-repeat="entry in data.calendar" >
{{entry.HoursAvailable.includes(hour) ? 'AVAILABLE' : 'FULL'}}
</td>
</tr>
</tbody>
In place of 'AVAILABLE', I want to read the response from $scope.data.response in controller.js
You can do this
<span ng-if="entry.HoursAvailable.includes(hour)">
{{ data.response }}
</span>
<span ng-if="!entry.HoursAvailable.includes(hour)">
FULL
</span>
Related
I am using vue.js library for front-end development.
I came a cross a scenario where my JavaScript method returns a list, which has objects, object's number of properties can change each time after method execution.
example my list can contain these type of objects in 2 different executions.
var obj = {
Name : "John",
2020-Jan: 1,
2020-Jul: 2
}var obj = {
Name: "John",
2020-Jan: 1,
2020-Jul: 2,
2021-Jan: 3,
2021-Jul: 4
}
Since Property name is dynamically changes is there any way to bind to HTML ?
<div >
<table>
<thead>
<tr>
<th v-for ="row in Result.Headers">
{{row}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in Result.Data ">
<td>
{{item.2020-Jan}} // Because don't know the number of properties until run time
</td> // No of <td/>'s can change on no of properties.
<td> // exactly don't know how many <td>'s needed there.
{{item.2020-Jul}}
</td> <td>
{{item.2021-Jan}}
</td>
</tr>
</tbody>
</table>
</div>
Is there way to bind these type of object to fronted in vue.js ?
You need to loop over the item's keys again. This will show all the values in the object
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="(value, key, index) in item">
{{value}}
</td>
</tr>
</tbody>
If you want to filter some of them, for instance check that the keys are valid dates you need to add a v-if and use Date.parse to check for this.
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="(value, key, index) in item" v-if="Date.parse(key) !== NaN">
{{value}}
</td>
</tr>
</tbody>
if u wana show all attr-> u can use this:
<ul v-for="item in Result ">
<li v-for="(value,key,index) in item">{{value}}</li>
</ul>
if u wana show all days u can use v-if and compute to complete youself fillter
<div id="app">
<ul v-for="item in Result" >
<li v-for="(value,key,index) in item" v-if="canShow(key)"> index:{{index}}------ key: {{key}} ------ value:{{value}} </li>
</ul>
</div>
<script>
var vue=new Vue({
el:'#app',
data:{
Result:[{
name: 'SkyManss',
2020-Jan: 1,
2020-Jul: 2
},{
name: 'SkyManss2',
2020-Jan: 1,
2020-Jul: 2,
2021-Jan: 3,
2021-Jul: 4
}]
},
computed:{
canShow(){
return function(skey){
return skey.indexOf('-') > -1;
}
}
}
});
</script>
after some research and some of your suggestions I came up with an answer.
<div>
<table>
<thead>
<tr>
<th v-for ="row in Result.Headers">
{{row}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in Result.Data ">
<td v-for="row in Result.Headers">
{{item[row]}}
</td>
</tr>
</tbody>
</table>
</div>
Javascript code
this.Result.Headers = Object.keys(result.data[0]);
this.Result.Data = result.data;
But this code only worked for the first time. second time data didn't get updated. So I updated JavaScript code to following code.
Vue.set(self.Result, 'Headers', []);
Vue.set(self.Result, 'Result', []);
this.Result.Headers = Object.keys(result.data[0]);
this.Result.Data = result.data;
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. That I got to know from following post.
vue.js is not updating the DOM after updating the array
Thank You All !!!
I am trying to do the following in Vue.js
<table>
<tr v-for="item in messages">
<td><router-link to="'/user/' + item.id">{{ item.name }}</router-link></td>
</tr>
</table>
My messages property has an array of objects in it. Each object has an id property, which I want to be appended on to my to attribute. So if I had two items in the messages array with ids of 1 and 2, I would expect to get something like this:
<table>
<tr v-for="item in messages">
<td><router-link to="/user/1">{{ item.name }}</router-link></td>
</tr>
<tr v-for="item in messages">
<td><router-link to="/user/2">{{ item.name }}</router-link></td>
</tr>
</table>
I also tried putting doing {{ message.id }}, but that gives me an interpolation error. How can I get this to render the actual value for message.id in the "to" attribute? The item.name attribute renders as expected.
Just add v-bind: before to
<table>
<tr v-for="item in messages">
<td><router-link v-bind:to="'/user/' + item.id">{{ item.name }}</router-link></td>
</tr>
</table>
Without v-bind: you're literally using 'user' + item.id as value.
For more clarification check this docs section
I have an issue with angular, I want to use two nested ng-repeat in a data table where the first get the data, and the second get the name of field to be retrieved from the data (retrieved in the first ng-repeat)
here is what I tried to do with code :
<table md-table flex-order-gt-sm >
<thead md-head>
<tr md-row >
//1st : get the name of fields, not a problem
<th md-column ng-repeat="field in fields">{{item.name}}</th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-repeat="item in items">
<td md-cell ng-repeat="field in fields" >
//here is the problem I want to get the item that it's field name is field
{{item.{{field}} }}</td>
</tr>
</tbody>
</table>
for example if fields contain :{'a','b','c'}
and items contains {'a':'1','b':'2','c':'3'};
I want for example for the 1st iteration of {{item.{{field}} }} to return 1
Use toString() to retrieve the scope data in an scope object.
<tr md-row ng-repeat="item in items">
<td md-cell ng-repeat="field in fields" >
{{item[field.toString()]}}
</td>
</tr>
Here is the plunker
As an alternative you could also use a filter:
<td md-cell ng-repeat="field in fields | filter: { name: 'field' }">
</td>
You need to get fields collection according to item of items collection after
getFieldsByItem(item)
Then you can get field from fields collection
{{field}}
I have to display table in html page using ng-repeat.
most of the entries in table have null data but i am unable to replace null with either empty space or string null. I tried {{ row || 'null' }} but it didnt help. When it generate table it mess it up completely if rows have large number of nulls.
<table>
<tr>
<th ng-repeat="colname in sqldata.collist">{{colname}}</th>
</tr>
<tr ng-repeat="rows in sqldata.tablist">
<td ng-repeat="row in rows">{{ row || 'null' }}</td>
</tr>
</table>
How about the old ng-show and ng-hide trick to show something if a value is 'null'.
Replace
{{ row || 'null' }}
with
<div ng-show="row">{{row}}/div>
<div ng-hide="row">null</div>
A better option would be to use a filter. This means no duplicated DOM elements, a hidden and shown element. It also keeps logic out of your view.
Plus it makes the 'no data' message standard across your application as you can use it in almost all data binding cases.
<div ng-app="test" ng-controller="ClientCtrl">
<div ng-repeat="elem in elems">
{{elem | isempty}}
</div>
</div>
And your JavaScript
angular.module('test', []).filter('isempty', function() {
return function(input) {
return isEmpty(input) ? 'No Value' : input;
};
function isEmpty (i){
return (i === null || i === undefined);
}
})
http://jsfiddle.net/5hqp5wxc/
Docs: https://docs.angularjs.org/guide/filter
Another option is ng-if
<table>
<tr>
<th ng-repeat="colname in sqldata.collist">{{colname}}</th>
</tr>
<tr ng-repeat="rows in sqldata.tablist">
<td ng-repeat="row in rows">
<span ng-if="row" >{{ row }} </span>
<span ng-if="!row" > null </span>
</td>
</tr>
</table>
I try to make a version of "tic tac toe" with AngularJS and be as minimalistic as possible. The only solution for my problem is to assign every button a unique ID (f+i).
HTML
<table>
<tr ng-repeat="f in [5,10,15]">
<!-- numbers chosen for unique combos-->
<td ng-repeat="i in [0,1,2]">
<button ng-click="toTrue()" >
<div >
{{getXO()}}
</div>
</button>
</td>
</tr>
</table>
JavaScript
$scope.XObool=false;
$scope.toTrue = function() {
if(!$scope.XObool){
$scope.XObool=true;
}
else if($scope.XObool) {
$scope.XObool=false;
}
};
$scope.getXO = function(){
if($scope.XObool){
return 'X';
}
else {
return 'O';
}
};
ng-repeat gives you several variables to work with, namely $index. In your case you'll want something like:
<button id="{{$index}}" ...>
More info on the ng-repeat docs.
Second Option
Use the f and i variables to create unique IDs.
<table ng-app>
<tr ng-repeat="f in [5,10,15]" data-id="{{$index}}">
<td ng-repeat="i in [0,1,2]">
<button id={{'id' + (i+f)}} ng-click="toTrue()">
{{'id'+(i+f)}}
</button>
</td>
</tr>
</table>
Here's a demo.
You don't need to assign each button a unique ID.
Instead, you can pass your f and i variables into your functions to track the board state:
<table>
<tr ng-repeat="f in [0,1,2]">
<!-- numbers chosen for unique combos-->
<td ng-repeat="i in [0,1,2]">
<button ng-click="setState(f, i)">
<div >
{{ getXO(f,i) }}
</div>
</button>
</td>
</tr>
</table>
Working fiddle here: http://jsfiddle.net/m76w3kf5/
try markup binding with {{}} or $index
<div id="{{someObject.id}}" class="some-class" ng-repeat="f in [ array ]">
..
</div>
or a slightly extended example with $index, listing thumbnails in array with clicks to reference position by index
<tr ng-repeat="array in thumbnails track by $index">
<td ng-repeat="object in array track by object.id"
ng-click="tableClickHandler($index, object)">
<img class="user-thumbnail" src="{{object.src}}">
</td>
</tr>