How to disable button click until item selected/activated? - angularjs

Trying to disable button in table. and enable it only when item selected/clicked/activated
button code
<td><a class="btn btn-info" ng-disabled="isDisabled">Edit</a></td>
disabled bool
$scope.isDisabled = false;
trying to enable button only when selected is true
$scope.selectedRow = false; // initialize our variable to null
$scope.setClickedRow = function(index) { //function that sets the value of selectedRow to current index
$scope.selectedRow = index;
$scope.isDisabled = true;
}
any help please?
http://plnkr.co/edit/llmcbXCA93kuTVTzpQlm?p=catalogue
the full table
<thead>
<tr>
<th class="hidden-xs">ID</th>
<th>Name</th>
<th>Date</th>
<th>Grade</th>
<th>Subject</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="trainee in trainees | filter: search" ng-class="{'selected':$index == selectedRow}" ng-click="setClickedRow($index)">
<td class="hidden-xs">{{$index+1}}</td>
<td>{{trainee.name}}</td>
<td>{{trainee.date | date:'d/M/yyyy'}}</td>
<td>{{trainee.grade}}</td>
<td>{{trainee.subject}}</td>
<td><a class="btn btn-info">Edit</a></td>
</tr>
</tbody>
</table>

First make the plunk work!
You were referencing a file that didn't exist in the plunk, so had to change:
<script src="main.js"></script> to <script src="script.js"></script>.
Amend your ng-disabled directive:
Also had to add ng-disabled="selectedRow !== $index" on your link button:
<td><a class="btn btn-info" ng-disabled="selectedRow !== $index">Edit</a></td>
I don't think you need the $scope.disabled variable as the $scope.selectedRow along with $index takes care of enabling/disabling each edit button.
Prevent click events from bubbling up the DOM tree:
The ng-click on your tr tag will be triggered by any ng-click that you place on your edit link button, to fix that you have to add $event.stopPropagation(); after any function that you put there:
<a class="btn btn-info"
ng-disabled="selectedRow === $index"
ng-click="onEditButtonClicked(); $event.stopPropagation();">
Edit
</a>
Fix Invalid HTML Markup:
Moved the following up and out of the table:
<div class="form-inline">
<input class="form-control" type="text" placeholder="Search" ng-model="search">
<a type="button" href="#add-form" class="btn btn-info" ng-click="addForm()">Add new trainee</a>
<button class="btn btn-danger" ng-click="removeTrainee(trainee)">Remove</button>
</div>
Styles.css 404 not Found:
Last but not least styles.css doesn't exist and gets a 404 not found, and so the following can be removed: <link rel="stylesheet" href="styles.css">
Working Plunk

Related

Uncheck radio button Angular ui-bootstrap

My function:
$scope.DownloadedUncheck = function (event) {
if (event.target.value === lastChecked) {
delete $scope.$parent.selectedDownloaded
lastChecked = null
} else {
lastChecked = event.target.value
delete $scope.$parent.selectedDownloading
}
};
Here's my plunker : http://plnkr.co/edit/g1t4pludTTIAJYKTToCK?p=preview
I wan't to uncheck radio button after click on it.
My code works with normal radio, but not with ui.bootstrap.
Thanks for asnwers in advance!
I guess this is what you need:
HTML:
<body ng-controller="FirstCtrl">
<label class="btn btn-default" uib-btn-radio="'True'" ng-model="$parent.selectedDownloaded" uncheckable>Downloaded
</label>
<br />
<label class="btn btn-default" uib-btn-radio="'False'" ng-model="$parent.selectedDownloaded" uncheckable>To Download
</label>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>#</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="name in name | filter:{Download:selectedDownloaded}">
<td>{{name.Download}}</td>
</tr>
</tbody>
</table>
</body>
Changes:
You don't have to bind a method on click.
Upgrade your bootstrap-tpls lib to ver 2.5.0
Use proper element name for bootstrap radio button. which is uib-btn-radio
Use uncheckable attribute of uib-btn-radio, to make that radio button un-check-able
updated plnkr here

Decent way to toggle the text of bootstrap popover?

I'm using the angular + bootstrap to create a table and for each row, it will have a popover button. What I want to do is to change 'Show Password' to 'Hide Password' when the popover is shown, and change back when the popover is closed.
<tr ng-repeat="entry in data">
<td>{{ entry.site }}</td>
<td>{{ entry.username }}</td>
<td>
<button popover-placement="right" uib-popover="{{calculatePassword(entry)}}" class="btn btn-primary btn-sm">Show Password</button>
</td>
</tr>
I tried to use lines such as 'displayed? "Show Password":"Hide Password"' but I can't find a proper spot to toggle 'displayed'. I can't find a built-in feature of uib-popover to do that neither. Please help. Thanks!
You could use ng-click to toggle a variable each time the button is clicked and change the text accordingly.
<button ng-click="entry.passwordDisplayed = !entry.passwordDisplayed">
{{entry.passwordDisplayed ? 'Hide' : 'Show'}} Password
</button>
var app = angular.module("app", ["ui.bootstrap"]);
app.controller("controller", function($scope, $sce) {
$scope.data = [
{
site: "Facebook",
username: "jsmith",
password: "abc123"
}
];
var trusted = {};
$scope.htmlPopover = function(entry) {
var html = '<b>Password:</b> ' + entry.password;
return trusted[html] || (trusted[html] = $sce.trustAsHtml(html));
};
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.2.0/ui-bootstrap-tpls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.2.0/ui-bootstrap-tpls.min.js"></script>
<div ng-app="app" ng-controller="controller">
<div class="wrapper">
<table class="table">
<thead>
<tr>
<th>Site</th>
<th>Password</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="entry in data">
<td>{{ entry.site }}</td>
<td>{{ entry.username }}</td>
<td>
<button ng-click="entry.passwordDisplayed = !entry.passwordDisplayed" class="btn btn-primary btn-sm" uib-popover-html="htmlPopover(entry)" class="btn btn-default">{{entry.passwordDisplayed ? 'Hide' : 'Show'}} Password</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>

Angular-Xeditable loading page with all rows in Edit Mode

I am trying angular-xeditable for the first time and managed to get everything working EXCEPT the page loads with all the table rows in Edit Mode and I need the default behavior. (Clicking the 3 cancel buttons after load shows what I am looking to create).
I have a stripped-down plunker (no CRUD methods) that shows what I mean ... plunker
I also created the same using $scope but I would prefer not to use $scope ... plunker with $scope
here is my view:
<body ng-controller="DistributorsController as dist">
<fieldset>
<legend>Distributors</legend>
<table class="table table-striped table-bordered">
<tbody>
<tr>
<th style="width:22%;">Name</th>
<th style="width:15%;">Phone</th>
<th style="width:12%;">Email</th>
<th style="width:6%;"> </th>
</tr>
<tr ng-repeat="dis in dist.distributors" ng-dblclick="rowform.$show()">
<td>
<span editable-text="dis.name" e-name="name" e-form="rowform" e-style="width:100%;">
{{ dis.name || '--' }}
</span>
</td>
<td>
<span editable-text="dis.phone" e-name="phone" e-form="rowform" e-style="width:100%;">
{{ dis.phone|phone }}
</span>
</td>
<td>
<span editable-text="dis.email" e-name="email" e-form="rowform" e-style="width:100%;">
{{ dis.email || '--' }}
</span>
</td>
<td style="white-space: nowrap">
<!-- form -->
<form editable-form="" name="rowform" onbeforesave="dist.saveRecord($data, dis.id)" ng-show="rowform.$visible" class="form-buttons form-inline" shown="inserted == distributor">
<button type="submit" ng-disabled="rowform.$waiting">
<span class="glyphicon glyphicon-ok-sign" style="color:#006837;"></span>
</button>
<button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()">
<span class="glyphicon glyphicon-remove-sign" style="color: #990000;"></span>
</button>
</form>
<div class="buttons" ng-show="!rowform.$visible">
<span class="glyphicon glyphicon-trash" style="color: #990000;" ng-click="dist.removeRecord($index, dis.id)"></span>
</div>
</td>
</tr>
</tbody>
</table>
<p>
<a ng-click="dist.insertRecord()" class="btn btn-xs btn-default">
<span class="glyphicon glyphicon-plus-sign" style="color:#006837;"></span>
Add New</a>
</p>
</fieldset>
</body>
and my controller
(function(){
'use strict';
angular
.module('app')
.controller('DistributorsController', DistributorsController);
DistributorsController.$inject = ['$filter'];
/* #ngInject */
function DistributorsController($filter) {
/* jshint validthis: true */
var vm = this;
vm.distributors = [
{id: 1, name: "Jonah's Whale", phone: '3185551212', email: 'jwhale#distributors.org'},
{id: 2, name: "Paul's Thorn", phone: '5015551212', email: 'pthorne#distributors.org'},
{id: 3, name: "Lot's Wife", phone: '5045551212', email: 'lwife#distributors.org'}
];
}
})();
Doc Says
To show several editable elements together and submit at once you
should wrap them into tag. The
name attribute of form will create variable in scope (normal angular
behavior) and editable-form attribute will add a few methods to that
variable:
You need to have ng-form attribute on each tr as other elements are not supported in table tag
Markup
<tbody>
<tr ng-form editable-form name="editableForm"
ng-repeat="dis in dist.distributors" ng-dblclick="rowform.$show()">
...................
..editable input elements here..
...................
</tr>
</tbody>
Wokring Plunkr

How to remove entire row from table onclick of button?

I have two button in each row of a table. Onclick of any of the button the entire row should be removed from the table and also I'm sending some value to spring controller. It should be updated in database and also the entire row should be removed. I'm using angularjs,spring-mvc and mongodb.
// .html file
<table class="table table-bordered">
<thead>
<tr>
<th style="text-align: center;">Task name</th>
<th style="text-align: center;">Owner name</th>
<th style="text-align: center;">Authorize</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="task in taskDetails">
<td style="text-align: center;">{{task.name}}</td>
<!-- <td style="text-align: center;">{{task.owners}}</td> -->
<td style="text-align: center;">
<span ng-repeat="owner in task.owners">{{owner.ownerName.name}}{{$last ? '' : ', '}}</span>
</td>
<td style="text-align:center;">
<!-- <button class="btn btn-mini btn-primary" ng-click="approveTask(taskDetails.indexOf({{task.id}}), task)" value="approveTask">Approve</button>
<button class="btn btn-mini btn-danger" ng-click="rejectTask(taskDetails.indexOf({{task.id}}), task)" value="approveTask">Reject</button>
-->
<button class="btn btn-mini btn-primary" ng-click="approveTask(task)" value="approveTask">Approve</button>
<button class="btn btn-mini btn-danger" ng-click="rejectTask(task)" value="rejectTask">Reject</button>
</td>
</tr>
</tbody>
</table>
//controller.js
$scope.approveTask = function(task) {
$http.put("/task/approve/"+ task.id).success(function(data) {
alert("Approved! "+ data);
});
}
$scope.rejectTask = function(task) {
$http.put("/task/reject/"+ task.id).success(function(data) {
alert("Rejected! "+ data);
});
}
Well you're using ng-repeat for your rows, iterating over taskDetails so you can just remove that one entry from within the array like so
$scope.rejectTask = function (index, task) {
$scope.taskDetails.splice(index, 1);
}
In your HTML :
<button class="btn btn-mini btn-danger" ng-click="rejectTask($index)" value="rejectTask">Reject</button>
// We just need to pass the index for accessing the relevant object.
In your Javascript :
$scope.rejectTask = function($index) {
$scope.currentIndex = $index;
// You may want to show some screen loader to prevent user intervention during the ajax call.
$http.put("/task/reject/"+ task.id).success(function(data) {
// AS the ajax call is complete, it is now safe to splice the array.
$scope.taskDetails.splice($scope.currentIndex, 1);
$scope.currentIndex = -1;
//Remove the loader here
});
}

AngularJS/Bootstrap - Select row and open details in modal with button

I'm using AngularJS, Bootstrap, and data-toggle to open a modal. I want to click on a row in a table, get the index number and store it, and click a button to open a modal that displays more details for that row using the stored index.
My code right now can get the index of the clicked row and my button opens a modal, but they're not connected so that the button grabs the row index and shows those details in the modal. My modal shows all row data instead of the details for the one clicked row. How can I connect the clicked row to the button and how do I get my modal to show details for one app instead of all apps? Any help would be much appreciated!
Here is my JS Fiddle.
Here is the code snippet for the click functions:
$scope.selectedRow = null;
$scope.clickRow = function(index) {
$scope.selectedRow = index;
console.log(index);
};
$scope.getDetails = function(index) {
$scope.selectedRow = index;
console.log(index);
};
And here is the code for my table and modal that call the click functions:
<div id="tableDiv">
<table id="myTable" class="table display">
<thead>
<tr>
<th ng-repeat="(i, th) in head" value="{{th.id}}" class="{{th.class}}"><span>{{th.name}}</span></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="app in apps | filter:search" ng-click="clickRow($index)" ng-class="{selected: $index === selectedRow}">
<td>{{app.appName}}</td>
<td>{{app.dateCreated}}</td>
<td>{{app.dateUpdated}}</td>
<td>{{app.payload}}</td>
<td>{{app.status.name}}</td>
<td>{{app.errorCode.name}}</td>
<td>{{app.errorDesc}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th ng-repeat="(i, th) in head" value="{{th.id}}"><span>{{th.name}}</span></th>
</tr>
</tfoot>
</table>
</div>
<div id="details">
<button class="btn btn-default" data-toggle="modal" data-target="#myModal" ng-click="getDetails($index)">Launch</button>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Details</h4>
</div>
<div class="modal-body">
<table class="table display">
<thead>
<tr>
<th ng-repeat="(i, th) in details" value="{{th.id}}"
class="{{th.class}}"><span>{{th.name}}</span></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="app in apps">
<td>{{app.appName}}</td>
<td>{{app.errorDesc}}</td>
<td>{{app.recordCount}}</td>
<td>{{app.recordFail}}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
The first thing I'll point out is that you're not actually using angular-ui-bootstrap, you're using the jQuery version without angular directives, and by doing so making life harder for yourself. If you're going to do much more with this or making more modals I recommend switching.
You can still make this work though.
Instead of passing the $index in clickRow($index), pass the app itself clickRow(app) and assign that to your scope property.
It's a variable created in your ng-repeat loop that can be accessed by other expressions in the loop.
$scope.clickRow = function(app) {
$scope.selectedApp = app
};
Then, in your modal's html, you can bind to the properties of selectedApp. It should only show you the data for that one app.

Resources