How to get Button label in AngularJS? - javascript

I have following lines of code in my AngularJS project.
<div ng-show="update">
<table border="1">
<tr ng-repeat="x in names">
<td>{{ x.uname}}</td>
<td>{{ x.upass}}</td>
<td><button ng-model="index" ng-click="show()"
ng-value="{{x.index}}">Edit</button></td>
</tr>
</table>
When Particular button is clicked I want to retrieve that button label.
For that I have written code in Show function:
var v = $scope.index;
alert(v);
But alert box is displaying "Undefined" when i click on button.
Please suggest me where I am wrong??
Thanks in advance

What about providing your value as an argument to the onclick function ?
<div ng-show="update">
<table border="1">
<tr ng-repeat="x in names">
<td>{{ x.uname}}</td>
<td>{{ x.upass}}</td>
<td><button ng-click="show(x.index)">Edit</button></td>
</tr>
</table>
and then
function show(id){
alert(id);
}
This should works. Also ng-model does not work on button.

under ng-click = show(item) - this gives the particular item object.
function show(obj){ console.log(obj)}
this function give the particular clicked obj from view.
ng-model doesn't work on button.

You can pass the index of the repeat iteration to the show method like this:
<button ng-click="show($index)" ...
and use it like this:
function show(i){
var v = names[i];
alert(v);
}
You can see it in action here: PLNKR DEMO
NOTE: if you are passing the index to the backend service the index may not match up with the actual array if you are using a filter in your view to alter/reduce the ng-repeat expression
Another option as pointed out by #Grundy is to just pass the object back, which saves you the step of having to access it from the array... (note: this is the suggested best practice)

I am assuming that you want the button label that you have clicked on and the index of it in the list provided. Here is what you can do.
<div ng-repeat="buttonId in testdata2">
<button ng-bind="buttonId" ng-click="clickedMe(buttonId, $index)"></button>
</div>
$scope.clickedMe = function(buttonId, index) {
console.log(buttonId + " - " + index);
};
Have your files in local and run them.

Related

generate dropdown using angularJS controller

I am trying to dynamically add a dropdown using $sce.trustAsHtml() function but I am getting an empty list in the UI. Here is the code:
$scope.addRowtrain = function() {
$scope.locomotivesList = [{"name": "loco1", "value":"1"}, {"name": "loco2", "value":"2"}];
tableData[id] = $sce.trustAsHtml('CTRun'+counter++);
tableData[type] = $sce.trustAsHtml("<select data-ng-model='selectedLoco' data-ng-options='loco.name for loco in locomotivesList'></select>");
}
In the HTML, I want to render it as a table:
<table>
<tbody>
<tr ng-repeat="data in tableData track by $index">
<td ng-repeat="(k, p) in data track by $index"><span ng-bind-html=p>{{p}}</span></td>
</tr>
</tbody>
<a class="btn btn-danger" ng-click="addRowtrain()">Add Run</a>
...
</table
but it is displaying an empty table, please help
you are adding it dynamically you must not pass binding values instead pass Complete JSON object.
It's working with
this example
md-select in angular material

Angularjs -Updating individual values in ng-repeat from outside its scope using "this" keyword

I am trying to update quantity number of individual items in a table whenever the user clicks the item in another table.
For example, I have list of all items in Table A
<tr ng-repeat="item in items">
<td>{{item.fid}}</td>
<td{{ item.fname }}</td>
<td>{{ item.calorie }}</td>
<td>{{ item.protein }}</td>
<td>{{ item.carb }}</td>
<td>{{ item.fat }}</td>
<td><button ng-click=additem(values)>Add</button>
<tr>
Now when the user clicks this Add button, the selected item gets added to another table (Table B).
I have disabled duplicates in Table B and want that if the user is repeatedly adding same item then the quantity of the item in Table B should increase.
Table B
<tr ng-repeat="sitem in sitems>
<td>{{sitem.fname}}</td>
<td>{{sitem.calorie}}</td>
<td>{{sitem.protein}}</td>
<td>{{sitem.carb}}</td>
<td>{{sitem.fat}}</td>
<td>*</td>
<td><button ng-click="removeItem(values)">Remove</button></td>
</tr>
is the one where i want the increased quantity to be shown.
I have tried using "this" keyword but didn't worked, I am new to angular so i don't know what all are my options and got mixed up.
You have to keep track of two separate array to accomplish this.
This is the code snippet: `
$scope.additem = function(item) {
var index = $scope.sitems.indexOf(item);
if (index === -1) {
item.quantity = 1;
$scope.sitems.push(item);
return;
}
item.quantity++;
$scope.sitems[index] = item;
};
`
Complete Working fiddle: https://jsfiddle.net/nbakliwal18/4kbo7Lfo/2/
Also you check for quantity before adding.
You can simply pass item to the function addItem() :
<td><button ng-click=addItem(item)>Add</button>
and push this item to your array sitems in your function :
$scope.addItem = function(item) {
$scope.sitems.push(item);
}
A workaround for the duplicates in ng-repeat is to add track by $index to it :
<tr ng-repeat="sitem in sitems track by $index">
Update 1:
Updated my answer with working example in Plunker
Update 2:
Here is an example with lodash for quantity Plunker

How pick up checkbox result in post method angularjs

I have a table that sets out a list of rules. When the checkboxes are clicked, I need them to take this "true" value and post to an API endpoint. This has been set up, but what I am getting back is that "associated_rule" is undefined.
I have tried setting $scope.associated_rule.selected = true; in my controller, but this still doesn't define the variable and throws up the same error in the console.
Here is my HTML form:
<form name="rules_form" method="post" ng-submit="attach()">
<table class="table table-striped table-hover" ng-model="associated_rules">
<thead>
<th>Rule Types:</th>
<th>Description:</th>
<th>Start Time:</th>
<th>End Time:</th>
<th>Apply Rule to Vehicle:</th>
</thead>
<tr ng-repeat="associated_rule in associated_rules">
<td>#{{ associated_rule.resource_ids.accounts }}</td>
<td>#{{ associated_rule.description }}</td>
<td>#{{ associated_rule.start_time }}</td>
<td>#{{ associated_rule.end_time }}</td>
<td><input type="checkbox" ng-model="associated_rule.selected" aria-label="rule"></td>
</tr>
</table>
<button class="btn btn-primary" ng-click="attach()">Attach</button>
</form>
My Controller event:
$scope.attach = function () {
$scope.associated_rule.selected = true;
var i;
for (i = 0; i < $scope.associated_rule.selected.length; i++) {
//need to create a loop where the true value is picked up and then I can send the data using a POST method. But I'm stuck on this.
}
console.log(the result of the event);
};
For now, I just want the results to console.log, so I can see that the event is creating the loop and displaying the results. After that, I should be OK.
Any help would be much appreciated.
I have fixed this by defining the $scope.rule as an empty array and setting the $scope.rule.selected to "false" by default.
Great! step one! But the checkboxes are ALL selecting when you click A checkbox - think this may be the ng-repeat causing me a pain in the backside.
$scope.rule = [];
$scope.rule.selected = false;
So, how do I ensure that only the checkboxes set that I select and not all at once?
Fixed this too; as the above was just making the entire array selected; as i wasn't drilling down into the array. This did it:
ng-model="rules.selected[associated_rule.id]"
by modelling the a rule within that defined array, it shows up when testing. Brill. :)
By mistake you are changing the value of your check box on clicking the button:
$scope.associated_rule.selected = true;
This will give the current value, selected or not selected
$log.log($scope.associated_rule.selected);

Parsing JSON result to object by using checkbox

I have loaded a JSON list into a table and I would like to parse 1 JSON result or multiple results into an object, so I can send it to the server.
My table looks like this so far:
HTML
<tr ng-repeat="t in student">
<td ng-model="herkanserNaam">{{ t.Name }}</td>
<td>{{ t.City }}</td>
<td>
<div class="checkbox" ng-click="laatzien(herkanserNaam, herkanserCheck)" ng-model="herkanserCheck">
<label>
<input type="checkbox">
</label>
</div>
</td>
</tr>
Controller
$scope.laatzien = function(name, active) {
var herkanser = [{
"name" : name,
"active" : false
}];
console.log(herkanser);
}
How would I be able to check one or multiple results and save the data(t.Name) into an object by using a checkbox? So far the function laatzien() is returning the empty values defined in herkanser.
The reason your laatzien method is failing is due to how you are using your directives. Let's work with the example you provided to get your laatzien method to fire.
HTML
<tr ng-repeat="student in students">
<td>{{ student.Name }}</td>
<td>{{ student.City }}</td>
<td>van</td>
<td>Huis</td>
<td>j.huis#student.han.nl</td>
<td>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="student.isActive" ng-change="laatzien(student)">
</label>
</div>
</td>
</tr>
Javascript
$scope.laatzien = function (student) {
var herkanser = [{
"name": student.name,
"active": student.isActive
}];
console.log(herkanser);
}
I have made some opinionated changes in your example for readability purposes, others were needed to get the directives to fire as expected. Below are the changes to your snippets.
Renamed the student array to students. This will require a change in your controller from $scope.student to $scope.students.
Renamed the t object to student.
Removed the ng-click directive from your div.
Added an ng-change directive on your checkbox. Now when you click the checkbox your laatzien method should fire.
Added an isActive property to your student. Inside of your laatzien method, you may now check the state of the checkbox. If the checkbox is checked, student.isActive = true. If the checkbox is not checked, student.isActive = false.
From your code, you seem to want to build the "list of checked students" and send that to the server. In other words, what you want, is to allow the user to check on multiple students and at the end collect everything that was checked and send it over to the server.
If that's the case then your strategy to put an ng-click over the checkbox is wrong.
What you need is to bind your checkbox to your $scope model. Such as this:
<input type="checkbox" ng-model="t.isChecked" ng-true-value="true" ng-false-value="false'">
When the user checks the checkbox for a student. Your model will automatically be updated.
To collect the data to send over the server you need to put an ng-click on a submit button. In the event handler, simply loop through every student in your $scope "students" model and only save the ones that have isChecked property to true to be sent over to the server.
Hope this helps!
You could make a function to push thet item into an obj like so...
$scope.students = [
{
"name":"John",
"city":"Boston"
},
{
"name":"Amy",
"city":"Dallas"
}
]
$scope.activeObj = [];
$scope.laatzien = function(obj) {
if($.inArray(obj, $scope.activeObj) == -1) {
$scope.activeObj.push(obj);
} else {
var index = $scope.activeObj.indexOf(obj);
$scope.activeObj.splice(index, 1);
}
}
http://jsfiddle.net/5fcnazb2/

ng-class directive call executed twice

Simple html:
<table class="table table-condensed">
<tr data-ng-repeat="customer in customers" data-ng-class="customerSelectedClass(customer)">
<td>
{{customer.Name}}
</td>
</tr>
</table>
In my controller - two functions to select customer and return proper class to highlight a table row:
$scope.customerSelectedClass = function (customer) {
if (customer == $scope.selectedCustomer) {
console.log('returing info for ' + customer.Name);
return "info";
}
return "";
};
$scope.selectCustomer = function (customer) {
console.log('selecting ' + customer.Name);
$scope.selectedCustomer = customer;
}
I noticed that when I click on a customer link, customerSelectedClass function executes twice. selectCustomer function on ng-click directive executes once, as it should. Angular is only included once on the page. I wonder if this is a bug in Angular or something that I am doing wrong?
Behind the scenes, angular is setting up a $watch on the function that is resolving the class name. Because angular uses dirty checking to see if there has been a change, this method will be called twice during the $digest cycle. This is ok.
I would suggest that you don't add this code the the controller though, because if you are managing many css classes, you could be adding a lot of unnecessary code. Try something like this instead:
<table class="table table-condensed">
<tr data-ng-repeat="customer in customers" data-ng-class="{'info': customer == selectedCustomer}">
<td>
{{customer.Name}}
</td>
</tr>
</table>
Then, there is no need for a controller function customerSelectedClass. This will only add the info class if the right-hand side of the : resolves to true. And there is no problem resolving the correct customer in the ng-repeat.
Hope this helps.

Categories

Resources