Reputation: 3014
I have a directive which is responsible for the functionality of a confirmation process (see pictures). It works as expected, except after clicking the Submit button, the check icon is displayed for all tr's. However, it should only be displayed at the tr, which has been confirmed.
Unfortunately, I could not create a working Plunker and hope that the pictures are enough for you to understand my problem.
What am I doing wrong?
Angular-Directive:
.directive('confirm', function($timeout) {
return {
restrict: 'A',
scope: true, // isolate the scope to trigger target individually
link: function(scope, element) {
$timeout(function() {
var barIcon = angular.element(element[0].querySelector('.config-menu-bars'));
var banIcon = angular.element(element[0].querySelector('.config-menu-ban'));
var checkIcon = angular.element(element[0].querySelector('.config-menu-checked'));
var confirmLink = angular.element(element[0].querySelector('.confirm'));
var textArea = angular.element(element[0].querySelector('.confirmation-note'));
// These elements are outside the scope of the directive
var confirmBox = angular.element('.accept-terminplanung');
var submitButton = angular.element('.submit-appointment');
var confirmCheckbox = angular.element('.appointment');
// Hide barIcon and show banIcon, textArea and confirmBox
confirmLink.bind('click', function() {
barIcon.hide();
banIcon.show();
textArea.show();
confirmBox.show();
});
// Hide banIcon, textArea, confirmBox and show barIcon
banIcon.bind('click', function() {
banIcon.hide();
textArea.hide();
confirmBox.hide();
barIcon.show();
confirmCheckbox.parent().removeClass('checked');
submitButton.addClass("disabled");
});
// Hide barIcon, textArea, confirmBox and show checkIcon after clicking the submitButton
submitButton.bind('click', function() {
banIcon.hide();
textArea.hide();
confirmBox.hide();
checkIcon.show();
confirmCheckbox.parent().removeClass('checked');
submitButton.addClass("disabled");
});
// checkbox functionality whithin the confirmBox
confirmCheckbox.on('ifChecked', function() {
submitButton.removeClass('disabled');
});
confirmCheckbox.on('ifUnchecked', function() {
submitButton.addClass('disabled');
});
});
}
}
});
HTML:
<table class="table table-hover">
<thead>
<tr>
<th>Ausbildung</th>
<th>Termine</th>
<th>Ausbildungsstätte</th>
</tr>
</thead>
<tbody>
<tr confirm>
<td>
<ul class="nav navbar-nav">
<li class="dropdown">
<a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown">
<i class="fa fa-bars"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;">
<i class="fa fa-ban"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;">
<i class="fa fa-check-square-o"></i>
</a>
<ul role="menu" class="dropdown-menu">
<li><a class="confirm" data-target="">Bestätigen</a></li>
<li><a class="move" data-target="">Verschieben</a></li>
</ul>
</li>
</ul>
</td>
<td>
<p><strong>Ausbildungsname</strong></p>
<p>Kürzel</p>
</td>
<td>
<p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
<p><strong class="text-navy">29.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
<p><strong class="text-navy">30.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
</td>
<td>
<p><strong>Ausbildungsstätte Wunderfull ABC</strong></p>
<p>Musterstraße 1, 1234 Musterstadt</p>
<p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p>
</td>
</tr>
<tr confirm>
<td>
<ul class="nav navbar-nav">
<li class="dropdown">
<a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown">
<i class="fa fa-bars"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;">
<i class="fa fa-ban"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;">
<i class="fa fa-check-square-o"></i>
</a>
<ul role="menu" class="dropdown-menu">
<li><a class="confirm" data-target="">Bestätigen</a></li>
<li><a class="move" data-target="">Verschieben</a></li>
</ul>
</li>
</ul>
</td>
<td>
<p><strong>Ausbildungsname</strong></p>
<p>Kürzel</p>
</td>
<td>
<p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
<p><strong class="text-navy">29.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
</td>
<td>
<p><strong>Ausbildungsstätte Wunderfull ABC</strong></p>
<p>Musterstraße 1, 1234 Musterstadt</p>
<p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p>
</td>
</tr>
<tr confirm>
<td>
<ul class="nav navbar-nav">
<li class="dropdown">
<a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown">
<i class="fa fa-bars"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;">
<i class="fa fa-ban"></i>
</a>
<a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;">
<i class="fa fa-check-square-o"></i>
</a>
<ul role="menu" class="dropdown-menu">
<li><a class="confirm" data-target="">Bestätigen</a></li>
<li><a class="move" data-target="">Verschieben</a></li>
</ul>
</li>
</ul>
</td>
<td>
<p><strong>Ausbildungsname</strong></p>
<p>Kürzel</p>
</td>
<td>
<p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p>
</td>
<td>
<p><strong>Ausbildungsstätte Wunderfull ABC</strong></p>
<p>Musterstraße 1, 1234 Musterstadt</p>
<p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p>
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-default confirm-panel accept-terminplanung" confirm>
<div class="panel-body text-muted ibox-heading">
<form action="#" method="post" role="form">
<div class="i-checks" ichecks>
<label class="">
<div class="icheckbox_square-green">
<input type="checkbox" class="i-checks appointment">
</div>
<p class="no-margins">Hiermit akzeptiere ich die Bedingungen des geschlossenen Dozentenvertrages und nehme den Bildungsauftrag für die ausgewählten Ausbildungen verbindlich an.</p>
</label>
</div>
<button type="button" name="termin-bestaetigen" class="btn btn-sm btn-w-m btn-warning submit-appointment disabled">Terminplanung übernehmen</button>
</form>
</div>
</div>
Images:
Upvotes: 0
Views: 60
Reputation: 1908
You're use scope: true
in your directive. What this does is create a new child scope which inherits from the parent scope, this is not the same as an isolate scope. If you have multiple directives on the same parent level (in your case confirm
) they will all use the same child scope.
To make it clear: using scope: true
will make a new child scope, unless one already exists (created by another directive for example). So in your case all the confirm directives are using the same scope.
What should you do to make an isolate scope?
scope: {...}
give it an object hash. This will create a completely isolated scope, which will allow a directive to be reused on the same scope level without them interfering with each other.
You can find a lot more info about this here: Angular JS Docs - Scope
The scope property can be false, true, or an object:
false (default): No scope will be created for the directive. The directive will use its parent's scope.
true: A new child scope that prototypically inherits from its parent will be created for the directive's element. If multiple directives on the same element request a new scope, only one new scope is created.
{...} (an object hash): A new "isolate" scope is created for the directive's template. The 'isolate' scope differs from normal scope in that it does not prototypically inherit from its parent scope. This is useful when creating reusable components, which should not accidentally read or modify data in the parent scope. Note that an isolate scope directive without a template or templateUrl will not apply the isolate scope to its children elements.
UPDATE:
You use confirm
four times, so it goes through the link function four times. Every time it goes through the link function you bind some functions to the buttons on the page. The button with the name termin-bestaetigen
has four events bound to it, three times by the confirm
on the tr
's and once on the div
. When you click the button all those events trigger and in all those events you don't check anything you simply show/hide everything.
In this case I suggest you break up your directive in more bite size chunks (at least separate the confirm
on the tr
's and the div
) and direct some functionality to a controller. You could add an attribute to the confirm
directive that you can watch inside the directive and once that attribute evaluates to true
you show/hide whatever.
Upvotes: 1