I have created a carousel following a tutorial from a website. Here is the html code of my carousel;
<div class="row carousel" (mouseover)="mouseCheck()">
<!-- For the prev control button -->
<button class="control" style="left: 30px;" (click)="prevButton()">
<span class="arrow" style="transform: rotate(45deg);"></span>
</button>
<div class="row car-align">
<div *ngFor="let i of currentSlide;" style="width: 184px;" class="card CardBtw">
<div #carouselAnimation>
<!-- SOME CODE IN HERE -->
</div>
</div>
</div>
<!-- For the control buttons -->
<button class="control" style="right: 30px;" (click)="nextButton()">
<span class="arrow" style="transform: rotate(225deg);"></span>
</button>
</div>
I have succesfully implemented an animation. What I want is to let this carousel cycles in every 10 seconds, while the mouse is not on the carousel. If user puts the mouse on the carousel, then let this 10 seconds start from beginning. I have implemented a function called "mouseCheck()" to detect if mouse is on this . But I couldnt manage to make a cycle in every 10 seconds. How can I do that?
EDIT:
Here are the codes that you all wanted. My mouseover function just console logs when mouse is on (I have created it but couldnt fill it because I couldnt track the time :/ )
I select and hide the showing vector with the help of next and prev button. Here is the function from .ts (Just the next button func, cus prev is similar to this anyways);
//Start from the first vector
currentSlide = this.laptopSlide[0];
nextButton() {
//If the currentSlide is 0
if(this.currentSlide == this.laptopSlide[0])
this.currentSlide = this.laptopSlide[1]
//If currentSlide is 1
else if(this.currentSlide == this.laptopSlide[1])
this.currentSlide = this.laptopSlide[2]
//If current slide is 2
else if(this.currentSlide == this.laptopSlide[2])
this.currentSlide = this.laptopSlide[0];
}
you can create setTimeout function on mouseCheck() fn.
mouseCheck() {
if (condiction1 or click == true){
on.click() => {
"Give me a function conditione"
}
}else {
setTimeOut({
console.log("Change by inner content from typescript code on my component")
}, 2000)
}
Related
I have a menu, that on mouseover opens sidemenus, that are opened as long as the mouse is either on the correct item of the menu or above the corresponding sidemenu. But only certain items in this menu are supposed to be enabled. Unfortunately if the item in a sidemenu is disabled it won't start the onmouseover function and the menu closes. Is there a way to have the item still call the mouseover function while being disabled?
That's what I mean with menu and sidemenu
HTML
<!--MainMenu-->
<div class="menu">
<div class="menu-item" *ngFor=" let item of this.menuservice.mainmenuItems">
<button [disabled]="item.disabled"
(mouseover)="mouseMove(item.viewValue,true)" (mouseout)="mouseMove(item.viewValue,false)">
{{item.viewValue}}
</button>
</div>
</div>
<!--Settings-->
<div dHide [isHidden]="isSettingsMouseOver" class="side_menu"
(mouseover)="this.isSettingsMouseOver = true" (mouseout)="this.isSettingsMouseOver = false">
<div class="menu-item" *ngFor=" let item of this.menuservice.settingsItems">
<button [disabled]="item.disabled">
{{item.viewValue}}
</button>
</div>
</div>
Script
isSettingsMouseOver: boolean = false;
mouseMove(id: string, enter: boolean) {
if (id == 'Settings') {
this.isSettingsMouseOver = enter;
}
}
I have some cards dynamically generated with a loop. In one part, I have an accordion element that is triggered with a button (Bootstrap method). I change the background color of that button when the element accordion-body, which is contenteditable true, has value in it after losing focus. The problem is, I want to remove the button color if the accordion-body is empty, but the element accordion-body seems to still have a value after losing focus even when the user deletes all content.
This is the accordion code:
Why is it that $(this).val() never evaluates empty? I had a console message in the if statements, it never goes to the else validation.
$('.accordion-body').on('focusout', function() {
var style = $(this).closest('.accordion-item').find('button[id=infobtn]').attr('style');
//it will return string
style += ';background-color: #f4cccc;';
if ($(this).val() != '') {
$(this).closest('.accordion-item').find('button[id=infobtn]').attr('style', style);
} else {
$(this).closest('.accordion-item').find('button[id=infobtn]').attr('style');
}
});
<script> src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<span class="mySpan">
<div class="accordion accordion-flush py-0" id="accordionFlushExampleOne">
<div class="accordion-item py-0">
<h2 class="accordion-header" id="flush-headingOne">
<button class="accordion-button collapsed" id="infobtn" name="infobtn" style="height:25px; <?php if (!empty($additionalInfo)) echo " background-color: #f4cccc; " ?>" type="btn btn-sm" data-bs-toggle="collapse" data-bs-target="#flush-collapseOne>" aria-expanded="false"
aria-controls="flush-collapseOne">Additional Info
</button>
</h2>
<div id="flush-collapseOne" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#accordionFlushExampleOne">
<div class="accordion-body fw-bold" id="additionalInfo" name="additionalInfo" contenteditable="true">
<?php echo "$additionalInfo" ?>
</div>
</div>
</div>
</div>
</span>
Giving HTML block elements the attribute contenteditable="true" is responsible for that behaviour.
Removing the content of such an element in the browser, will set a replacement <br> instead in there.
Thus, if ($(this).val() != '') will never be true, because your containing element will never be empty.
Changing the containing div to an inline element such as span fixes the issue and your conditonal logic will get to work.
HTML - swap <div> with <span>
<span class="accordion-body fw-bold" id="additionalInfo" name="additionalInfo" contenteditable="true">
<?php echo "$additionalInfo" ?>
</span>
HTML & JQuery - inner <span> within <div> to preserve bootstrap accordion design
<div class="accordion-body fw-bold" id="additionalInfo" name="additionalInfo" contenteditable="true">
<span contenteditable="true">
<?php echo "$additionalInfo" ?>
</span>
</div>
$('.accordion-body span').on('focusout', function() {...
Thanks for all the recommendations and information about this matter. #bitski suggestion took me to the right direction. I tried all the options given, and somehow my accordion-body element always received the <br> value, it was never empty. I did some research and found a way to reset the content after losing focus (I ended up using blur instead).
So my accordion-body field looks like this now:
<div class="accordion-body fw-bold" id="additionalInfo" name="additionalInfo" contenteditable="true" onblur="event.target.scroll(0,0)">
And my jquery looks like this:
$('.accordion-body').on('blur', function() {
var style = $(this).closest('.accordion-item').find('button[id=infobtn]').attr('style'); //it will return string
style += ';background-color: #f4cccc;';
if ($(this).text().trim().length != 0) {
$(this).closest('.accordion-item').find('button[id=infobtn]').attr('style', style);
} else {
style += ';background-color: #FFFFFF'; //When field is empty, change the button background color back to white
$(this).closest('.accordion-item').find('button[id=infobtn]').attr('style', style);
}
});
That did the trick! Hope this helps someone else.
So, I am trying to get just one icon stay selected, I need to rewrite my function in the .ts file such that it ensures that when one icon is selected, only that icon changes color and the others are at default.If I select home only home icon changes color, if I select more, the home icon goes back to default while the more icon changes. Right now if I select one icon after the other, they all change color unless I refresh. Any help please?
.html
<div class="footer-container">
<div class="nav-icon-container">
<div [class.selected]="isHomeSelected" (click)="goToHome()">
<mat-icon class="icon-container"> home</mat-icon>
</div>
<div [class.selected]="isProfileSelected" (click)="goToProfile()">
<mat-icon class="icon-container" svgIcon="user"></mat-icon>
</div>
<div [class.selected]="isMessagesSelected" (click)="goToMessages()">
<mat-icon class="icon-container">message</mat-icon>
</div>
<div [class.selected]="ismoreSelected" (click)="goToMore()">
<mat-icon class="icon-container">more_horiz</mat-icon>
</div>
</div>
</div>
.ts
isHomeSelected = false;
goToHome() {
this.isHomeSelected = true;
this.router.navigate(['home']);
}
isProfileSelected = false;
goToProfile() {
this.isProfileSelected = true;
if(this.currentUser){
this.router.navigate(['profile/'+this.currentUser.uid]);
} else {
this.router.navigate(['signin', {params:'/profile/'+this.currentUser.uid}]);
}
}
isMessagesSelected = false;
goToMessages() {
this.isMessagesSelected = true;
if(this.currentUser){
this.router.navigate(['messages']);
} else {
this.router.navigate(['signin', {params: '/messages'}]);
}
}
ismoreSelected = false;
goToMore() {
this.ismoreSelected = true;
return true
}
.css
.selected {
color: #ff3588;
}
You could create an array and loop through the "links" and change the selected class based on which is clicked (neatly), but since you are using varying icon solution (with svgIcon in the mix), it would seem it's maybe easier to add ngClass and the click event on each and every item in your list. So that would would look like the following, where we use ngClass to toggle the class, and we use an unique string (in this case), which we assign a variable, which defines which "link" would be active. This variable doesn't necessary need to exist in the TS file, but use one if you want to have an initial "link" chosen.
So modify your code to such:
<div [ngClass]="{'selected': selectedLink === 'link1'}" (click)="goToHome(); selectedLink = 'link1'">
<mat-icon class="icon-container"> home</mat-icon>
</div>
<div [ngClass]="{'selected': selectedLink === 'link2'}" (click)="goToProfile(); selectedLink = 'link2'">
<mat-icon class="icon-container" svgIcon="user"></mat-icon>
</div>
<div [ngClass]="{'selected': selectedLink === 'link3'}" (click)="goToMessages(); selectedLink = 'link3'">
<mat-icon class="icon-container">message</mat-icon>
</div>
<div [ngClass]="{'selected': selectedLink === 'link4'}" (click)="goToMore(); selectedLink = 'link4'">
<mat-icon class="icon-container">more_horiz</mat-icon>
</div>
Maybe use some better names though ;)
Here's a demo: StackBlitz
I have a DIV with ng-show.
When I run ng-click on an element outside of the DIV, it works fine and I can hide it.
When I run ng-click on an element inside of the DIV, it does not work. I can see the variable beeing changed when i console.log it, but the view will not update.
I have tried to use $scope.$apply() but it gets an error and says it is already running $apply().
Parts of controller:
$scope.selectedActivity = {
"dayNr": 0,
"actNr": 0
};
$scope.resetSelectedActivity = function () {
console.log("SelAct: ", $scope.selectedActivity);
$scope.selectedActivity.dayNr = -1;
$scope.selectedActivity.actNr = -1;
console.log("SelAct: ", $scope.selectedActivity);
};
$scope.setSelectedActivity = function (dayNr, actNr) {
console.log("SelAct: ", $scope.selectedActivity);
$scope.selectedActivity.dayNr = dayNr;
$scope.selectedActivity.actNr = actNr;
console.log("SelAct: ", $scope.selectedActivity);
};
Parts of HTML:
<div ng-repeat="x in xs">
<ion-scroll>
<div ng-repeat="y in ys track by $index">
<div ng-click="setSelectedActivity($parent.$index, $index)">
<!--THE PROBLEM IS HERE-->
<div ng-show="selectedActivity.dayNr == $parent.$index && selectedActivity.actNr == $index">
<div>
<!--THIS LOGS OUT CORRECT VALUES BUT NG-SHOW IS NOT UPDATED-->
<div ng-click="resetSelectedActivity()">
Reset
</div>
</div>
</div>
<div>
<img src="img/checkButtonOverlay.png" />
</div>
</div>
<!--THIS LOGS OUT CORRECT VALUES AND NG-SHOW _IS_ UPDATED-->
<button ng-click="resetSelectedActivity()">reset</button>
</div>
</ion-scroll>
</div>
Please note that i have removed A LOT from the code because of confidentiality, but the principle should be the same.
Thank you!
Found the problem!
I had a ng-click that showed the DIV outside. When I clicked both ng-clicks got entered.
So First resetSelectedActivity() and then it got set again in setSelectedActivity().
Fixed it using:
<div ng-click="resetSelectedActivity($parent.$index, $index, $event)">
...
</div>
and:
$scope.setSelectedActivity = function (dayNr, actNr, event) {
$scope.selectedActivity.dayNr = dayNr;
$scope.selectedActivity.actNr = actNr;
//This cancel the mouseclick
event.stopPropagation();
};
What I am trying to do is have a drop down menu divided. In this example there are Five Options how can I split the drop down into categories? For example option 1 and 2 pop out of the environment category and option 3 and 4 sports category and 5 college category? http://jsfiddle.net/fc3550sk/
For example:
Drop down: Please Select when you click it Menus will be Environment, Sports, Colleges..
Then hover over Environment and it will let you choose from option 1 or 2... or hover over sports and it will let you chose from 3 or 4 and so on..
This is what I have so far:
<select name="SPECIAL" id="SPECIAL">
<option>Please Select</div>
<option data-img="/images/img/AnimalFriend.png" value="1">AnimalFriend</option>
<option data-img="/images/img/Aquaculture.png" value="2">Aquaculture</option>
<option data-img="/images/img/ProtectOurOceans.png" value="3">Protect Our Oceans</option>
<option data-img="/images/img/ConserveWildlife.png" value="4">Conserve Wildlife</option>
</select>
<!-- Modal -->
<div class="modal fade" id="modal_special" 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"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">Specialty Plate</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary accept">Accept</button>
</div>
</div>
</div>
</div>
$(function() {
$('#SPECIAL').on('change', function() {
if ($('option:selected', this).is('[data-img]')) {
$('#modal_special').find('.modal-body').html('<p>Image will go here:</p>')
.append('<img alt="coming soon" src="' + $('option:selected', this).data('img') + '"/>')
.end().modal('show');
}
});
$('.accept').on('click',function() {
//do something
$('#modal_special').modal('hide');
});
});
Any help would be greatly appreciated!!
I don't know of a way to attach a "hover" event listener to a standard drop-down menu, but it's not too much work to implement your own custom drop-down with jquery, html and css.
Custom Drop-down Advantage #01
You get to assign as many custom values to each entry as you want.
In your example, you have "Specialty Plates", and you may want to assign a price, a special code assigned to that plate, an image assigned to that plate, and so on. With an HTML/jQuery version, you can create your custom drop-downs with simple <span> tags like this:
<span data-code="SPRT01" data-image="" data-price="34.00">Sports 01</span>
<span data-code="SPRT02" data-image="" data-price="35.00">Sports 02</span>
<span data-code="SPRT03" data-image="" data-price="36.00">Sports 03</span>
Notice how each entry has three custom values assigned to it: data-code, data-image, and data-price. If you use an html drop-down, you don't have as much freedom. There are ways to extend the values associated with a standard drop-down, but getting at the values is messy, and you will still not have access to the hover behavior your features require.
Custom Drop-down Advantage #02
You can actually use the hover behavior in any way you want.
In your example, you want the "submenus" to show up when certain values in your drop-down are selected, but as far as I know, there isn't a way to gain access to the values that are "hovered" in a standard drop-down, and looking for an HTML-only solution just doesn't exist, so you would have to use javascript in one way or another.
Using jQuery, you can easily get to the values in your custom drop-down elements like this:
$("span").hover(
function(){
var text = $(this).text();
console.log("You have hovered on: ", text);
},
function(){
// You have hovered off the span
}
);
My Solution to Your Problem
Putting these ideas into practice, I put together a simple demo of how you can create a custom drop-down using your applications parameters.
You can review a jsfiddle of the demo here.
The Basic idea is that you create a hierarchy in html with the structure of your Top-level options (Environment, Sports, Colleges) in the div .drop_down_scroll_container, and you place all your sub-level divs (Environment 01, Environment 02, etc) below that div in a div classed .dropdown-subcategory. Where the magic happens, is that javascript looks up the index of the top-level option, and then reveals the dropdown-subcategory with that same index.
For example, in the following snippet of html, you can see the index positions of each of the spans within the drop_down_scroll_container div:
<div class="drop_down_scroll_container">
<span>Environment</span> <!-- index 0 -->
<span>Sports</span> <!-- index 1 -->
<span>Colleges</span> <!-- index 2 -->
</div>
So then, when you hover over any of those Top-level options (Environment, Sports, Colleges) you can ask jQuery to reveal the corresponding submenu div, which are sitting below the .drop_down_scroll_container div in div containers with a class of .dropdown-subcategory
<div id="dropdown" class="specialtyPlatesCategories">
<div class="selectHeader">Click to Select Plates:</div>
<!-- THIS IS WHERE YOU WILL PUT YOUR TOP-LEVEL OPTIONS -->
<div class="drop_down_scroll_container">
<span>Environment</span>
<span>Sports</span>
<span>Colleges</span>
</div>
<!-- THIS DIV IS AT INDEX 0 of: #dropdown.dropdown-subcategory -->
<!-- Will fade in when the drop_down_scroll_container index 0 is hovered -->
<div id="env_subcategories" class="dropdown-subcategory">
<span data-code="ENV01" data-image="" data-price="31.00">Environment 01</span>
<span data-code="ENV02" data-image="" data-price="32.00">Environment 02</span>
<span data-code="ENV03" data-image="" data-price="33.00">Environment 03</span>
</div>
<!-- THIS DIV IS AT INDEX 1 of: #dropdown.dropdown-subcategory -->
<!-- Will fade in when the drop_down_scroll_container index 1 is hovered -->
<div id="sports_subcategories" class="dropdown-subcategory">
<span data-code="SPRT01" data-image="" data-price="34.00">Sports 01</span>
<span data-code="SPRT02" data-image="" data-price="35.00">Sports 02</span>
<span data-code="SPRT03" data-image="" data-price="36.00">Sports 03</span>
</div>
<!-- THIS DIV IS AT INDEX 2 of: #dropdown.dropdown-subcategory -->
<!-- Will fade in when the drop_down_scroll_container index 2 is hovered -->
<div id="colleges_subcategories" class="dropdown-subcategory">
<span data-code="COLL01" data-image="" data-price="37.00">Colleges 01</span>
<span data-code="COLL02" data-image="" data-price="38.00">Colleges 02</span>
<span data-code="COLL03" data-image="" data-price="39.00">Colleges 03</span>
</div>
</div>
If none of that made any sense, here is another way of looking it at:
When the first item in the .drop_down_scroll_container is hovered, jQuery looks for the first instance of a .dropdown-subcategory below it. When the second item in the .drop_down_scroll_container is hovered, then jQuery will reveal the second instance of the .dropdown-subcategory, and so on. This lets you build as many options as you want, without having to worry about giving everything specific names, only the order matters in this case. So when the "Environment" option (who's index equals 0) is hovered, the .dropdown-subcategory with an index of 0 will show. That is the basic idea.
So now for the jQuery that puts it all together:
$(document).ready(function(){
// When the header for the custom drop-down is clicked
$(".selectHeader").click(function() {
// cache the actual dropdown scroll container
var dropdown = $(this).parent().find(".drop_down_scroll_container");
// Toggle the visibility on click
if (dropdown.is(":visible")) {
dropdown.slideUp();
$(this).parent().find(".dropdown-subcategory").fadeOut();
} else {
dropdown.slideDown();
}
});
// When a top-level menu item is hovered, decide if its
// coorespnding submenu should be visible or hidden
$(".drop_down_scroll_container span").hover(
// hover on
function() {
// Remove the "highlighted class from all other options
$(this).parent().find("span").removeClass("highlighted").removeClass("selected");
$(this).addClass("highlighted").addClass("selected");
// Get the index of the hovered span
var index = $(this).index();
// Use the hovered index to reveal the
// dropdown-subcategory of the same index
var subcategorydiv = $(this).parent().parent().find(".dropdown-subcategory").eq(index);
hideallSubmenusExceptMenuAtIndex($(this).parent().parent(), index);
subcategorydiv.slideDown();
},
// hover off
function() {
if (!$(this).hasClass("highlighted")) {
var index = $(this).index();
var subcategorydiv = $(this).parent().parent().find(".dropdown-subcategory").eq(index);
subcategorydiv.slideUp();
}
});
// Hide all submenu items except for the submenu item at _index
// This will hide any of the previously opened submenu items
function hideallSubmenusExceptMenuAtIndex(formElement, _index) {
formElement.find(".dropdown-subcategory").each(
function(index) {
if (_index != index) {
$(this).hide();
}
}
);
}
// When any menu item is hovered
$("span").hover(
function() {
$(".hoveredOver").text($(this).text());
},
function() {
$(".hoveredOver").text("");
}
);
// When a sub-menu option is clicked
$(".dropdown-subcategory span").click(function() {
$(".dropdown-subcategory span").removeClass("selected");
$(".clickedOption").text($(this).text());
$(this).addClass("selected");
$(this).parent().parent().find(".selectHeader").text($(this).text());
closeDropDown($(this).parent().parent());
showSpecialPlateModal($(this).text(), $(this).attr("data-image"), $(this).attr("data-price"), $(this).attr("data-code"));
});
// Close the dropdowns contained in divToSearch
function closeDropDown(divToSearch) {
divToSearch.find(".drop_down_scroll_container").fadeOut();
divToSearch.find(".dropdown-subcategory").fadeOut();
};
// Populate and Launch the bootstrap Modal Dialog Specialty Plates
function showSpecialPlateModal(name, image, price, code) {
$('#modal_special').find('.modal-body')
.html('<h2>' + name + '</h2>')
.append('<br/>Special Plate Code: <span class="code">' + code + '</span><br/>')
.append('<p>Image will go here:</p><br/><img alt="" src="' + image + '"/>')
.append('<br/><br/>Price: <span class="price">' + price + '</span><br/>')
.end().modal('show');
}
// When the modal "Accept" button is pressed
$('.accept').on('click', function() {
var modal_element = $('#modal_special');
var name = modal_element.find("h2").text();
var price = modal_element.find("span.price").text();
var code = modal_element.find("span.code").text();
$('#modal_special').modal('hide').end(alert(name + " was selected for a price of " + price));
});
});
Note: There may already be some open-source solutions that take care of this problem in a more elegant fashion. But this was my approach at solving an issue like this. As you can see, it only takes a little bit of setup to get going. You can easily control the styling of the drop-down in css, and you can extend this to do anything you want.
Again, you can review a jsfiddle to see all of this code in action here.
Hope this helps!
I am not sure if this is exactly what your were looking for but you could try something like this:
<select name="SPECIAL" id="SPECIAL">
<option>Please Select</div>
<optgroup label="Environmental">
<option
data-img="/images/img/AnimalFriend.png"
value="1">AnimalFriend</option>
<option
data-img="/images/img/Aquaculture.png"
value="2">Aquaculture</option>
</optgroup>
<optgroup label="Sports">
<option
data-img="/images/img/ProtectOurOceans.png"
value="3">Protect Our Oceans</option>
<option
data-img="/images/img/ConserveWildlife.png"
value="4">Conserve Wildlife</option>
</optgroup>
</select>