I'm having issues with the xeditable directive. The onbeforesave is not firing, even though the in-place editing works fine on the client side. I can't get any reaction out of either onbeforesave or onaftersave.
I've included angular version 1.5.0 in my project.
I'm setting up the element like this, it's in a table:
<tr ng-repeat="job in jobs">
<td>{{ job._id }}<i ng-click="removeJob(job._id)" class="fa fa-trash-o" aria-hidden="true"></i></td>
<td>{{ job.title }}</td>
<td editable-text="job.description" onbeforesave="alert('hello');">{{ job.description || "empty" }}</td>
</tr>
But I haven't been able to make the alert go off when clicking save.
If you look at the documentation:
One way to submit data on server is to define onbeforesave attribute pointing to some method of scope
The onbeforesave is taking in a scope method, so alert('hello') in this case is trying to call some $scope.alert method that doesn't exist. To make this work try something like
// in your controller
$scope.test = function(data) {
alert(data);
};
// in your template
<tr ng-repeat="job in jobs">
<td>{{ job._id }}<i ng-click="removeJob(job._id)" class="fa fa-trash-o" aria-hidden="true"></i></td>
<td>{{ job.title }}</td>
<td editable-text="job.description" onbeforesave="test($data)">{{ job.description || "empty" }}</td>
</tr>
You have to give e-form as shown below (I just extracted the wrong code snippet only).
Html
<td editable-text="job.description" e-form="tableform"
onbeforesave="checkJob(job)">{{ job.description || "empty" }}</td>
JS
$scope.checkJob= function(data) {
//your logic
};
Related
I want to show the text online or offline, depending on the value of a property. So if the property camera.key is null there the text offline has to be shown. Otherwise, the text online has to be shown.
So I have this template:
<h3>Camera sensoren</h3>
<table>
<th>Name</th>
<th>Last update</th>
<th>Status sensor</th>
<tr *ngFor="let camera of sensorStatusCollection.cameraSensors">
<td>{{ camera.key }}</td>
<td>{{ camera.latestTimestamp }}</td>
<td *ngIf ="camera.key === null ? online : offline "></td>
</tr>
</table>
But what I have to declare in the typescript part?
Thank you
just modify your code, put it in td body
<td>{{camera.key === null ? "online" : "offline" }}</td>
for better understanding to *ngIF if you want to use it, it an angular structural directive here you can find more about it, what is it and how to use it NgIf, here is an example for you:
<td *ngIf ="camera.key === null">online</td>
<td *ngIf ="camera.key !== null">offline</td>
I have a table that is populated with ngRepeat and I have a input[text] where you can filter the table.
This works fine but now I came up with the idea to have the possibility to double-click on an element in the table and add the text to the search input[text] so the filter is applied straight when you double-click on the text.
Unfortunately it does not work as expected.
I have done this:
<input type="text" placeholder="Search..." data-ng-model="userinput" />
<p data-ng-dblclick="userinput='query'">Double click to use query to search</p>
And in the ngRepeat I use the ng-model "userinput" to filter but the value of the text input is not changing.
I also tried to specify the model "userinput" as variable in the controller and then change it per function but it is not working.
Is there something I'm missing?
Normally I would change the variable in the controller and it should automatically change the text input since it uses this variable as model. Then with this it should change the filter too but nothing happens.
WORKING
Code ngRepeat
<tr data-ng-repeat="dat in data | filter: userInput | filter: tsSelect | filter: advSelect | filter: checkedFilter | orderBy: ['client', 'ssrstatus'] | limitTo: totalDisplay" id="{{ dat.bannerid }}"> <!-- | unique: 'bannerid' | filter: errorSelect| -->
<td>
<input type="checkbox" id="checked" data-ng-model="dat.checked" data-ng-change="updateCheckedStatus(dat._id['$id'], dat.checked)">
<label for="checked">Checked</label>
</td>
<td data-ng-dblclick="search(dat.clientid)">{{ dat.clientid }}</td>
<td data-ng-dblclick="search(dat.client)" class="txtleft">{{ dat.client }}</td>
<td data-ng-dblclick="search(dat.tsengineer)">{{ dat.tsengineer }}</td>
<td data-ng-dblclick="search(dat.bannerid)">{{ dat.bannerid }}</td>
<td data-ng-dblclick="search(dat.bannertype)" class="txtleft">{{ dat.bannertype }}</td>
<td data-ng-dblclick="search(dat.width + 'x' + dat.height)">{{ dat.width == 0 ? 0 : dat.width - 50 }}x{{ dat.height == 0 ? 0 : dat.height - 50 }}</td>
<td data-ng-dblclick="search(dat.ssrstatus)" class="txtleft">{{ dat.ssrstatus }}</td>
<td data-ng-dblclick="search(dat.datebegin)">{{ dat.datebegin }}</td>
<td data-ng-dblclick="search(dat.dateupdated)">{{ dat.dateupdated }}</td>
<td>
<button class="preview {{ dat.bannerid }}" data-ng-click="showPreview(dat.bannerid, dat.clicktotestbanner, dat.width, dat.height)"></button>
</td>
<!-- <td id="{{ dat.bannerid }}" class="banner-preview"></td> -->
Controller
$scope.userInput = "";
$scope.search = function(query){
$scope.userInput = query;
}
I think it's because of your userinput='query' evaluated inside ng-repeat.
Let's name your outer scope "scopeA". The ng-model="userinput" of the search input would be referencing scopeA.userinput.
As we know, a new scope is created for every ng-repeat items. If you run userinput='query' in one of these scopes (name it scopeB), you would be assigning 'query' to scopeB.userinput instead of scopeA.userinput.
In this situation, scopeB is likely to be a child of scopeA. If you use angular-batarang Chrome extension to have a look at the scope tree, you would find both scopes to have userinput field.
One solution would be to use a function to assigning value to userinput instead of ng-dblclick expression. Like:
<p data-ng-dblclick="setUserinput('query')">Double click to use query to search</p>
And add a function setUserinput to your scope:
$scope.setUserinput = function(newValue) {
$scope.userinput = newValue;
}
I have some code that lists out items in a table from a database. The click function toggles the cells between green and red
<div class="row">
<div class="logs-table col-xs-12">
<table class="table table-bordered table-hover" style="width:100%">
<tr>
<th>Name</th>
<th>Seed</th>
<th>Division</th>
</tr>
<tr ng-repeat="team in Pool">
<td ng-class="{'btn-danger': started, 'btn-success': !started}" ng-click="inc()">{{ team.chrTeamName }}</td>
<td>{{ team.intSeed }}</td>
<td>{{ team.chrDivision }}</td>
</tr>
</table>
</div>
</div>
My click function is below
$scope.inc = function () { $scope.started = !$scope.started }
The only problem is that this is changing all of the cells in the first column. I'm thinking i need to pass a parameter in my click function, but I'm not sure what.
If you don't use the started value in your controller, you don't really need to define a function.
You could use ng-init to initialize an array keeping track of the started value for each team.
Something like this:
<tr ng-repeat="team in Pool" ng-init="started = []">
<td ng-class="{'btn-danger': started[$index], 'btn-success': !started[$index]}" ng-click="started[$index] = !started[$index]">{{ team.chrTeamName }}</td>
<td>{{ team.intSeed }}</td>
<td>{{ team.chrDivision }}</td>
</tr>
Somehow cleaner would be if there was a started property on every team instance:
<tr ng-repeat="team in Pool">
<td ng-class="{'btn-danger': team.started, 'btn-success': !team.started}" ng-click="team.started = !team.started">{{ team.chrTeamName }}</td>
<td>{{ team.intSeed }}</td>
<td>{{ team.chrDivision }}</td>
</tr>
Yes, passing a parameter into your function will help. Currently you have a $scope level variable ($scope.started) which selects your css ng-class. You probably want a team-by-team property. To do this, you should refer to the actual team object from within your ng-repeat.
<tr ng-repeat="team in Pool">
<td ng-class="{'btn-danger': started, 'btn-success': !team.started}" ng-click="inc(team)">{{ team.chrTeamName }}</td>
<td>{{ team.intSeed }}</td>
<td>{{ team.chrDivision }}</td>
</tr>
And in your javascript:
$scope.inc = function (team) { team.started = !team.started; }
Now that your are using the actual individual object (team) from your ng-repeat, everything should work fine.
How I pass an object as a parameter in a ng-click within a ng-repeat?
Example:
<tr data-ng-repeat="table in tables">
<td>{{ table.name }}</td>
<td>{{ isActive(table.active) }}</td>
<td>{{ table.initialDate }}</td>
<td>{{ table.finalDate }}</td>
<td>
<button data-ng-click="updateTable(table)">Update</button>
</td>
</tr>
Inside the ng-click updateTable(HERE), I want to pass my object table.
Can someone help me?
In your component.html edit your code as shown below :
<td><button (click)=updateTable(table)>Update</button></td></tr>
then in your typescript code just declare the function
updateTable(table){
console.log(table); //write your own code here!.
}
I have a table where the last column in each row contains a little loading icon which I would like to display when a button inside the table is clicked.
When each table row is generated with ng-repeat, the loader shows up in every row rather than the individual one. How can I set ng-show to true or false for only the current index clicked?
Template:
<tr ng-repeat="record in records">
<td>{{ record.name }}</td>
<td><a ng-click="someAction(record.name)">Some Action</a></td>
<td ng-show="loading">Loading...</td>
</tr>
Controller:
$scope.someAction = function(recordName) {
$scope.loading = true;
};
You can pass in the $index parameter and set/use the corresponding index. $index is automatically available in the scope of an ng-repeat.
<td><a ng-click="someAction(record.name, $index)">Some Action</a></td>
<td ng-show="loading[$index]">Loading...</td>
$scope.someAction = function(recordName, $index) {
$scope.loading[$index] = true;
};
Here's a generic sample with all the logic in the view for convenience: Live demo (click).
<div ng-repeat="foo in ['a','b','c']" ng-init="loading=[]">
<p ng-click="loading[$index]=true">Click me! Item Value: {{foo}}<p>
<p ng-show="loading[$index]">Item {{$index}} loading...</p>
</div>
There are many ways to handle this.
The problem here is that your variable loading is sharing the scope between the rows.
One approach could be use $index
HTML
<tr ng-repeat="record in records">
<td>{{ record.name }}</td>
<td><a ng-click="someAction(record.name, $index)">Some Action</a></td>
<td ng-show="loading">Loading...</td>
</tr>
JS
$scope.someAction = function(recordName, $index) {
$scope.loading[$index] = true;
};
Using a property in your object record:
HTML
<tr ng-repeat="record in records">
<td>{{ record.name }}</td>
<td><a ng-click="someAction(record)">Some Action</a></td>
<td ng-show="record.loading">Loading...</td>
</tr>
JS
$scope.someAction = function(record) {
var name = record.name;
record.loading = true;
};
Best regards
The scope inside ng-repeat is different form the one outside. Actually the scope outside ng-repeat is the parent of the one inside. So the html code goes here
<tr ng-repeat="record in records">
<td>{{ record.name }}</td>
<td><a ng-click="someAction(record)">Some Action</a></td>
<td ng-show="$parent.loading">Loading...</td>
</tr>