i have some <div></div> elements with draggable="true" attribute but same thing gets applied on child elements,but i dont want to apply it on child elements, So how do i prevent this default behavior?
code :
<div draggable="true" ondragstart="play(event)" ondrop="pause(event)" id="move">
<span id="text">
drag me
</span>
</div>
as i used dragable="true" on <div> so span also gets the same property.
I was having a similar event with a sortable drag-and-drop "list" I created. Each "row" of the list looks like this.
<div class='row' draggable='true'>
<div class='drag-handle' ></div>
<img class='icon-image' draggable='false'>
<input type='text' name='demo' >
<button class='remove-btn' onclick='removeItem(this,event)'>Remove</button>
</div>
When I tried selecting the text inside of the "input" element, somehow I would start dragging the whole "row". As frustrating as this was, the best solution I found was to simply apply the draggable='true' property to the item with the class="drag-handle" which would be my dragging icon that would fire the ondragstart(e) event.
The rest can be handled in JS
In JS, reference the parent element "row" by using the closest(".row") method
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll('.drag-handle').forEach(handle => {
handle.addEventListener("dragstart", dragStart)
handle.addEventListener("drag", dragging)
handle.addEventListener("dragend", dragEnd)
})
function dragStart(e) {
document.querySelectorAll(".row").forEach(row=>{
row.addEventListener("dragover", dragOver)
})
var target_row = e.target.closest(".row")
target_row.classList.add("dragging")
}
Note:
I added a class of "dragging" to the one "row" that was going to be dragged so I could do a querySelectorAll('.row:not(.dragging)') for other operations, classes, etc, however, this is NOT required for the intended purpose to work. Just a bit more context that hope helps your problem.
Related
For my site, I code a button allowing to change the css of a class present in a div card. My button is located in the card-footer. Having several cards, I can't / don't think to retrieve the element with an id (as there will be X times the same ID)
In order to circumvent this system, I therefore use a parentElement which goes up to the div card
<div class="card">
<div class="card-body">
<p class="change">Change one</p>
<p class="change">Change two</p>
<p class="change">Change three</p>
</div>
<div class="card-footer">
<i id="updateData">change</i>
</div>
</div>
jQuery($ => {
$('#updateData').click(e => {
var element = e.target.parentElement.parentElement;
$('.change').css('display','none');
});
});
I would like to indicate that only the class "changes" present in my element variable and not all the classes in the page.
I don't know how to add a variable to my ".css" command, do you know how ?
Thanks in advance !
First of all since you will have multiple elements with same id that means that you should not use ID and use class instead. Id is meant to be unique. So yours id="updateData" should become class="updateData". Now you can grab all of those buttons and assign event to all of them instead of just first like you were by using id selector.
$('.updateData').click(e=> {});
Next in order to be able to use clicked element in jQuery way convert from arrow function to regular anonymous function since arrow function overrides this keyword. And now you can use jQuery to hide like
$('.updateData').click(function() {
element = $(this).parent().parent();
element.hide();
});
If you want more precise selection to hide only .change elements use
$('.updateData').click(function() {
element = $(this).parent().parent();
element.find(".change").hide();
});
Not bad, but more efficient, when you have multiple click targets, is delegation:
$(document).on("click", ".updateData", function() { ... });
Also .hide() is convenient, but rather then "change the css of a class" add a class "hidden" or something! In best case the class further describes what the element is. CSS is just on top.
I have a lot of divs, they are the same but the data are differen(I use variable(array of objs) and for loop) but these details aren't important
<div class="item_wrapper">
<div class="item_wrapper_info">
<div class="left-line"></div>
<div class="subject">1</div> <== click here
</div>
<div class="additional_info"> <== display this block
some text
</div>
</div>
I want to achieve this:
If I click .item_wrapper_info div then I want to show .additional_info div
It should be probably done using this keyword.
If I click . item_wrapper_info block I want to find a div with the class name of . additional_info and make display = flex but I don't know how to trigger exactly its . additional_info div.
Probably I can click on .item_wrapper_info > . subject and then show its next neighbour
SOLUTION:
$(document).ready(() => {
$(".item_wrapper").click(function(){
var index = $(".item_wrapper").index(this); get index of a certain clicked .item_wrapper element on my page
$('.additional_info').eq(index).toggle(); using .eq toggle that certain element
});
})
It works for me
I haven't tested this code. Feel free to test it in a runnable snippet.
$(document).ready(() => {
$(".item_wrapper").click(function () {
var index = $(".item_wrapper").index(this)
$('.additional_info').eq(index).css("display","flex");
});
});
So I'm working with Angular and I'm trying to make a button that when clicked disappears. I have tried to use [hidden], (click)="showHide = !showHide", and a bunch of other methods. Nothing is working so far.
My html (currently):
<div class="rows">
<div class="a-bunch-of-styles-for-my-button">
<a type="button" class="more-styles" (click)="inboundClick = !inboundClick" [routerLink]="['/inbound']" href="">
</a>
</div>
</div>
and my component:
export class AppComponent {
inboundClick = false;
}
In essence I have 2 buttons on a page and when one button is clicked I want to hide both buttons and display a set of new buttons.
I'm very new to Angular and I'm very confused why this won't work.
Your HTML
<div class="yourCssClass" *ngIf="this.isButtonVisible" (click)="this.isButtonVisible = false">
...
</div>
Your TypeScript
export class AppComponent {
private isButtonVisible = true;
}
This should do the job. *ngIf automatically hides the element, if the condition evaluates false, so setting the variable to false is sufficient.
The problem I see here is, that you don't control the visibility at any point. Using [ngClass] to add a specific class, if a condition is met, or *ngIf is helpful, whenever you try to change elements on user interaction.
For more information on [ngClass], you can read about its usage here: https://angular.io/api/common/NgClass
You can read about *ngIf here: https://angular.io/api/common/NgIf
Especially the "Common Use" part should be interesting for you.
Edit:
Reading your comment below it seems you did not notice what [hidden] and (click) actually do. [hidden] controls the visibility of the element, usually dependent on a certain condition. (click) however is a quick way to bind a Click-Event to your element.
Using both of those tools enables to hide an element, by changing a variable, if a user clicks on your element (the new value of the variable may be assigned by a function called by (click) or inline, as demonstrated in the example code).
Edit2: Yep, you meant Angular2/4 ;) So this should do the job.
Here is how you can achieve that:
In your component.html:
<a type="button" class="more-styles"
[hidden]="!inboundClick"
(click)="inboundClick = !inboundClick"
[routerLink]="['/inbound']" href="">
</a>
<a type="button" class="more-styles"
[hidden]="!outboundClick "
(click)="outboundClick = !outboundClick "
[routerLink]="['/outbound']" href="">
</a>
... and in your AppComponent:
export class AppComponent {
inboundClick = true;
outboundClick = true;
}
PLUNKER DEMO
Here is a neat way to hide/remove items, specially handy if there is a list of items.
Note how it takes advantage of Angular's template variables (#ListItem).
So your template can either be something like:
<a type="button" #ButtonA
(click)="onClick(ButtonA)"
[routerLink]="['/inbound']" href="">
</a>
<a type="button" #ButtonB
(click)="onClick(ButtonB)"
[routerLink]="['/outbound']" href="">
</a>
Or like this:
<ng-container *ngFor="let item of list">
<div #ListItem>
<button (click)="onClick(ListItem)">
</div>
</ng-container>
Depending on how you want to hide - if you want to remove it from DOM, or just hide it with CSS. And depending if you want to toggle it or just remove it completely. There are a few options:
Remove element from DOM (no way to get it back):
close(e: HTMLElement) {
e.remove();
}
Hiding it with the hidden attribute - beware that the hidden attribute can be overriden by CSS, it will happen if you are changing the display property and the rule has more precedence:
close(e: HTMLElement) {
e.toggleAttribute('hidden');
}
Hiding it "manually" with CSS:
close(e: HTMLElement) {
e.classList.toggle('hide-element');
}
.hide-element {
display: none;
}
When using ng-hide or ng-show directives a .ng-class is added or removed so DOM elements are visible or not.
However they kinda get positional "removed" as for example, hiding or showing two continous div elements one on top of the other.
<div ng-show="condition1">First div</div>
<div ng-show="condition2">Second div</div>
So, if condition1 evaluates to false first div will be hidden BUT second div will take the position which the just hidden div took.
How can I avoid that? I only want DOM elements to be invisible but not to get somehow removed.
First workaround.
I tried to overried .ng-hide class and getting a secondary class, only-hide, for elements on which I wanted this effect:
.ng-hide.only-hide {
visibility: hidden !important;
}
But didn't get results so far.
I achieved it with this second class approach by setting:
.ng-hide.only-hide {
visibility: hidden !important;
display: block !important;
}
As Angular sets .ng-hide with display:none, I make it invisible but present setting display:block.
To preserve and maintain the space occuped by the div you can't use directly ng-hide or ng-show.
You can use the ng-style directive as following:
<div ng-style="conditionHide1">First div</div>
<div ng-style="conditionHide2">Second div</div>
then your conditionHide1 and conditionHide2 should be like
if (condition1)
$scope.conditionHide1= {'visibility': 'hidden'}; // then div1 will hidden.
else
$scope.conditionHide1= {'visibility': 'visible'}; // then div1 will visible.
if (condition2)
$scope.conditionHide2= {'visibility': 'hidden'}; // then div2 will hidden.
else
$scope.conditionHide2= {'visibility': 'visible'}; // then div2 will visible.
You can change the visibility of the button by changing the $scope.conditionHide1 and $scope.conditionHide2 according to your conditions.
Solution2 by using a custom directive:
Create a new directive named condition and relative to an Attribute. Set-up a watch to watch the value of the attribute and, based on the value, set to the element (in this case the div) an appropriate css style. The value is mapped to the variable showDiv which change his value by clicking on the button. Clicking on the button, the value showDiv became the opposite !showDiv and the watch change the visibility from visible to hidden and vice-versa.
angular.module('MyModule', [])
.directive('condition', function() {
return {
restrict: 'A',
link: function(scope, element, attributes) {
scope.$watch(attributes.condition, function(value){
element.css('visibility', value ? 'visible' : 'hidden');
});
}
};
})
.controller('MyController', function($scope) {
$scope.showDiv = true;
});
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='MyModule' ng-controller='MyController'>
<div condition='showDiv'>Div visible/invisible</div>
<button ng-click='showDiv = !showDiv'>Hide div or show it</button>
</div>
I have a structure like this:
<ul id="container">
<li>
<div tabindex="1" class="selectThis">
<div>
<div>
<span class="textToEdit" contenteditable="true"></span>
</div>
</div>
</div>
</li>
<ul>
Where it works to bind an event to the contenteditable span:
$("#container").on("keydown", ".textToEdit", function (e) {
alert("yes");
});
But the div itself doesn't react:
$("#container").on("keydown", ".selectThis", function () {
alert("no");
});
Using .on because the whole thing is dynamically generated, besides the container. I'm using jquery UI's sortable on said container. What is wrong with the binding? I've tried giving the ul and li a tabindex too, but the div still won't give me an alert.
The problem was that the div wasn't being focused after sortable is called on the ul--manually calling $(".selectThis").focus() makes it work. Thanks to Pilgerstorfer Franz for making me aware of this!