optimize css on dropdown buttons that uses ngIf - html

I have a dropdown that at the moment exists of one button. I would like this button to be disabled and that the color changes when it is disabled. I created this behaviour already with the code underneath.
Can't this be written cleaner? Because now I actually create 2 buttons but only one is seen..
I have tried this but I get stuck when adding the css background-color in the button code.
<div class="block-options">
<div class="dropdown">
<!-- Options -->
<button type="button" class="btn-block-option dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="si si-settings"></i></button>
<div class="dropdown-menu dropdown-menu-right" x-placement="bottom-end">
<!-- Disable buttons based on selected packages -->
<div *ngIf="checkIfValidVersion()">
<button class="dropdown-item js-swal-confirm" (click)="createMajors()">Create major version</button>
</div>
<div *ngIf="!checkIfValidVersion()">
<button [disabled]="!checkIfValidVersion()" style = "background-color:grey; color:black" class="dropdown-item js-swal-confirm">Create major version</button>
</div>
</div>
</div>
</div>

Ok, what you have to do is write a styling class for your button that will take effect if the button is disabled
Something similar to this will do the trick:
.my-button:disabled {
background-color: grey;
color: black
}
and your HTML will look like this:
<div class="block-options">
<div class="dropdown">
<!-- Options -->
<button type="button" class="btn-block-option dropdown-toggle" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false"><i class="si si-settings"></i></button>
<div class="dropdown-menu dropdown-menu-right" x-placement="bottom-end">
<!-- Disable buttons based on selected packages -->
<button class="dropdown-item js-swal-confirm my-button" (click)="createMajors()"
[disabled]="!checkIfValidVersion()">Create major version</button>
</div>
</div>
</div>
Related topic here

<button class="dropdown-item js-swal-confirm" [class.disabledStyle] ="!checkIfValidVersion()"> Create major version </button>
The above code will add a class name "disabledStyle" to the existing class if the function returns true.
disabledStyle {
background: grey;
}

You are duplicating the code. You just require one line which is already there. Based on condition it will put disable attribute in your button. Do not put css code at button level.
<button [disabled]="!checkIfValidVersion()" class="dropdown-item js-swal-confirm">Create major version</button>
Now put css at button level for disable scenario:
button[disabled=disabled], button:disabled {
background-color:grey;
color:black;}
This is most cleaner way.

Related

How can I vertically align elements in a Bootstrap dropdown list that are unaligned due to different-width icons preceding them?

I have a Bootstrap 4 dropdown menu whose clickable items are made of an icon and a short text next to the icon. I would like to have the icons and the text of all elements aligned. Naturally, I tried to do this with a table. Unfortunately, Bootstrap's dropdown-item class seems to interfere with the table layout, as shown by this JSfiddle:
HTML:
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<table class="clickable-rows">
<tbody>
<tr class="dropdown-item" data-href="#">
<th><i class="fa fa-credit-card-alt"></i></th>
<td>Credit card</td>
</tr>
<tr class="dropdown-item" data-href="#">
<th><i class="fa fa-eur"></i></th>
<td>Cash</td>
</tr>
</tbody>
</table>
</div>
</div>
Javascript:
$( document ).ready(function() {
$('table.clickable-rows tr').click(function() {
window.location = $(this).data('href');
});
});
CSS:
table.clickable-rows td:hover {
cursor: pointer;
}
This gives me:
Instead of this, I would like to have the Credit card and Cash aligned as indicated by the red line, as well as icons centered within their column. How can I achieve this?
Note: The CSS and JS code are not directly related to the question. They ensure that whole rows behave like a clickable link. I have included them just to show a fully functional example.
The internet has enough say about why not to use <table /> to structure your HTML elements so I'm not going to repeat that here.
Your problem can be easily fixed by setting a fixed width on the icons, or better using FontAwesome's .fa-fw fixed width class. FontAwesome icons are center aligned by default inside the i.fa tag.
No need to set cursor: pointer; CSS, and no need to write JavaScript to get the data-href because the .dropdown-item is now a true anchor tag.
JSFiddle demo: https://jsfiddle.net/davidliang2008/6s18j09L/12/
Live demo...
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown button</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">
<i class="fas fa-credit-card fa-fw"></i> Credit card
</a>
<a class="dropdown-item" href="#">
<i class="fas fa-euro-sign fa-fw"></i> Cash
</a>
</div>
</div>
<!-- Demo CSS libs -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet" />
<!-- Demo jQuery and JS bundle w/ Popper.js -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js"></script>
The answer is pretty simple and fortunately, as you are using Bootstrap, there is a class called .fa-fw. This class adds consistency and proper spacing to the FontAwesome icons which helps in solving your problem.
Use it in this way: <i class="fa fa-credit-card-alt fa-fw"></i>
Code:
<table class="clickable-rows">
<tbody>
<tr class="dropdown-item" data-href="#">
<th><i class="fa fa-credit-card-alt fa-fw"></i></th>
<td>Credit card</td>
</tr>
<tr class="dropdown-item" data-href="#">
<th><i class="fa fa-eur fa-fw"></i></th>
<td>Cash</td>
</tr>
</tbody>
</table>
Sandbox link to check:
https://codesandbox.io/s/wizardly-beaver-92vrg?file=/index.html
this may also do..
.dropdown-item .fa:before {
display: inline-block;
min-width: 35px;
text-align: center;
}

URL linking to collapsible element's child link?

I have a group of accordion cards that collapse on my page, and an example of one is:
<div class="card" style="display:none" >
<div class="card-header" role="tab" id="mainHeading">
<h5 class="mb-0">
<a class="collapsed" data-toggle="collapse" href="#linkTarget" aria-expanded="false" aria-controls="linkTarget">
</a>
</h5>
</div>
<div id="linkTarget" class="collapse" role="tabpanel" aria-labelledby="mainHeading" data-parent="#accordion">
<div class="card-body">
<a id="fileLink" href="https://downloads/testFile.pdf" download="filename">Test File</a>
</div>
</div>
<script type="text/javascript">
if(window.location.href == "/FAQ/fileLink") {
document.getElementById('fileLink').click()
}
</script>
I currently have it hidden because I don't want it showing but I do want to be able to give someone a URL like
www.testSite/FAQ#linkTarget/filename
or something like that so that if I give someone the link and they click it or go to it, it acts exactly the same as if they collapsed it and clicked on the download link.
Is there a way I can do that
Yes, you can test the window href before any javascript code
if(window.location.href == "www.testSite/FAQ#linkTarget/filename") {
document.getElementsByClassName('CLASS').click();
}
Change the url to be the one you wanted, and change "CLASS" as the class of the element you want to click when it's the chosen url

How can I make a table row clickable for a link but the last column not have the same behavior?

Below is the code I am working with that demonstrates what I want to achieve
<tr *ngFor="let plan of list; index as i" class="success" (click)="platDetails(plan)">
<!-- the click event above takes us to the platDetails view-->
<td>{{plan.name}}
</td>
<td>{{plan.test}}
</td>
<td> <!-- I want to allow the user to click the dropdown btn without triggering the (click) event above. currently when i try to click this drop down the click event in the tr is triggered and takes me away. -->
<div class="input-group">
<button type="button" class="btnTransparent" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
<i class="fa fa-ellipsis-h"></i>
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" (click)="action(plan)">View Plan</a>
</div>
</div>
</td>
</tr>
How can I split this tr to allow for those two td or how ever many to be controlled by the tr click event and leave the last td on its own?
I hope that makes sense.
Move platDetails click event from row to column and leave last column
<tr *ngFor="let plan of list; index as i" class="success">
<!-- the click event above takes us to the platDetails view-->
<td (click)="platDetails(plan)">{{plan.name}}
</td>
<td (click)="platDetails(plan)">{{plan.test}}
</td>
<td> <!-- I want to allow the user to click the dropdown btn without triggering the (click) event above. currently when i try to click this drop down the click event in the tr is triggered and takes me away. -->
<div class="input-group">
<button type="button" class="btnTransparent" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
<i class="fa fa-ellipsis-h"></i>
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" (click)="action(plan)">View Plan</a>
</div>
</div>
</td>
You can probably just prevent event propagation:
First, pass the event through to your function:
<a class="dropdown-item" (click)="action(plan, $event)">View Plan</a>
Then in your function:
public function action(plan: Plan, event: any){
event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
...
}
You just need to stop the event propagation from your action() click, something like the following:
(click)=action(plan, $event)
action(plan, event) {
event.stopPropagation();
// do your other action business
}

Typescript, Prevent Bootstrap Dropdown from closing when button is clicked

I make a simple bootstrap dropdown to do a registration or login. Inside the dropdown we have text and button like "dont have account? register", "already have account?
login". The register and login are buttons for changing form. But when the button clicked the dropdown is closed and we have to click to open the dropdown again to see/use the other form. I wanted to prevent this bootstrap dropdown from closing when these buttons inside it are clicked. The dropdown is inside app.component and the form is inside app.parent. I'm using angular cli typescript.
//component.ts
changeForm() {
this.isNewUser = !this.isNewUser
}
<!--app.component.html-->
<div>
<ul class="nav navbar-nav">
<li class="dropdown">
REGISTER/LOGIN <span class="caret"></span>
<ul class="dropdown-menu">
<app-parent></app-parent>
</ul>
</li>
</ul>
</div>
<!--parent.component.html-->
<div *ngIf="isNewUser">
<p *ngIf="errorMessage.length > 0" class="text-danger">{{errorMessage}}</p>
<p *ngIf="error.message.length > 0" class="text-danger">{{error.message}}</p>
<form (ngSubmit)="onSignUp()">...</form>
<h4 class="text-primary">Already have an Account? <button type="submit" href="#" class="btn btn-primary btn-xs" (click)="changeForm()">Log In</button></h4>
</div>
<div *ngIf="!isNewUser">
<p *ngIf="errorMessage.length > 0" class="text-danger">{{errorMessage}}</p>
<p *ngIf="error.message.length > 0" class="text-danger">{{error.message}}</p>
<form (ngSubmit)="onLoginEmail()">...</form>
<h4 class="text-primary">Not have any Account yet? <button type="submit" href="#" class="btn btn-success btn-xs" (click)="changeForm()">Register</button></h4>
</div>
Just found the answer by using event.stopPropagation();​ function and put it inside my changeForm() function.
changeForm() {
this.isNewUser = !this.isNewUser;
event.stopPropagation();​
}
If you have included jquery in your app project then write in your component file var $ as any; then in your changeForm function you can write $("#dropdown").addClass('open'); where you have to give id attribute to your as dropdown.

Bind click event to disabled link in Twitter Bootstrap

HTML:
<a id="foo" href="#" class="btn btn-default btn-lg disabled" role="button">Link</a>
<a id="bar" href="#" class="btn btn-default btn-lg" role="button">Link</a>
jQuery:
$("#foo,#bar").click(function(e){
e.preventDefault();
alert('click');
});
The alert appears when clicking #bar, but not when clicking #foo. How can I fix this?
Fiddle: http://jsfiddle.net/VVw8S/
In Bootstrap you can read this code:
.btn.disabled, .btn[disabled], fieldset[disabled] .btn {
pointer-events: none;
}
If you want to have a disabled button which allowed click events, just overwrite this CSS with pointer-events: inherit;. Or simply remove disabled in the class of your first link.