cdk drag and drop on images is not working - css

I want to drag an image from one div to another div. I tried creating two arrays containing src of images and looping through all the src thereby two lists will be displayed so that I'm able to drag and drop easily by creating a function (cdkDropListDropped)="drop($event)"
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
}
}
but here I'm using only a single image and no array is being used. So, how can I drag and drop and I'm not aware of the function I should use for an image getting drop perfectly into another div.
html:
<div class="example1"
cdkDropList
id = "pic1"
[cdkDropListConnectedTo]="['pic2']"
style="background-color:red;"
>
<div cdkDrag class="example-box">
<img width="350px" height="250px" src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
</div>
</div>
<div class="example2"
cdkDropList
id = "pic2"
style="background-color:yellow;"
[cdkDropListConnectedTo]="['pic1']"
>
<div cdkDrag class="example-box">
</div>
</div>

Related

Tailwind css in React: how can I get grid-cols to render with needed width only, not equally-wide?

Using Tailwind CSS in React, I want to:
Have a two-column page. Column 1, which holds the "Menu" component, should take up 20% of the screen. Column 2, which holds the "Templates" component, should take up 80% of the screen.
Column 2, the "Templates" component, renders 4 dropdowns of varying width. I want each of the dropdowns to render in a column, but I want each column to be only as wide as it needs to be to display the dropdown. I don't want the columns to have equal width. My problem is that the columns are of equal width. How can I get each column width to only be as wide as the dropdown that gets rendered inside it?
In other words, I want the page to look like this:
[menu button] [Carrier Groups] [States] [Policy Types] [Statuses]
...instead of like this:
[menu button] [Carrier Groups] [States] [Policy Types] [Statuses]
To render the 2-column page I'm doing this in my App component. This works fine. In the parent div I have "grid-cols-5", and in the 2nd child div I have "col-span-4" to consume 80% of the page.
function Content(){
return (
<div className="w-screen h-screen grid grid-cols-5 gap-3">
<div>
<Menu />
</div>
<div className="col-span-4">
<Templates/>
</div>
</div>
);
}
function App() {
const queryClient = new QueryClient()
return (
<QueryClientProvider client={queryClient}>
<Content />
<ReactQueryDevtools />
</QueryClientProvider>
);
}
export default App;
This is the Templates component that renders in the 2nd child div. I am rendering 4 components in 4 columns. As mentioned each component renders a dropdown. The 4 columns are of equal width. Is there anything I can change so that the 4 columns are only as wide as needed to render each dropdown?
const Templates = () => {
return (
<form>
<h1 className="prose-2xl m-0">Templates</h1>
<div className='w-screen grid grid-cols-4 gap-3'>
<div>
<h2>Carrier Group</h2>
<CarrierGroups />
</div>
<div>
<h2>State</h2>
<States />
</div>
<div>
<h2>Policy Type</h2>
<PolicyTypes />
</div>
<div>
<h2>Status</h2>
<Statuses/>
</div>
</div>
</form>
);
}
export default Templates;
To create a two-column 20% / 80% layout I would do how you suggest. When using grid-cols-{n} you are creating an explicit grid and the columns will be equal widths.
When you need columns of varying widths you can create an implicit grid, the key class here being auto-cols-min. You also need to include a col-start-{n} class for each column that you want.
<div class="grid auto-cols-min gap-2 bg-zinc-500 p-5">
<div class="col-start-1 w-20 bg-zinc-100 p-5">col 1</div>
<div class="col-start-2 w-40 bg-zinc-100 p-5">col 2</div>
<div class="col-start-3 w-24 bg-zinc-100 p-5">col 3</div>
<div class="col-start-4 w-48 bg-zinc-100 p-5">col 4</div>
</div>
Demo of above: https://play.tailwindcss.com/gKRtn7vFgi?layout=horizontal
More info:
https://tailwindcss.com/docs/grid-auto-columns
https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-columns

featherlight.js first picture clicked in gallery doesn't have navigation arrows

I'm using the featherlightGallery add on for featherlight.js.
It works OK except when I click on the 1st image in a set, the image opens but not as a "gallery". In other words, there is no "next" navigation button.
If I click the 2nd (or later) image, the gallery opens and I can click next and forward as expected.
<div class="tidy">
<div class="pfTitle" data-fid="12">
Photos-Misc
<div class="tih"><img src="img/upload.png" class="tup" alt="upload" title="upload"></div>
</div>
<div class="tpHolder">
<div class="tiWrap">
<div class="tiLink" data-imglink="ANNAWAN/Photos-Misc/100_0708.jpg">
<img src="../data/towerFiles/ANNAWAN/Photos-Misc/100_0708.jpg"
class="ssImg Photos-Misc" title="Photos-Misc"
data-featherlight-gallery="Photos-Misc"
data-featherlight-target-attr="src">
</div>
<div class="tiDel"><img src="img/x.png" class="ssImg delTpic" title="delete"></div>
</div>
<div class="tiWrap">
<div class="tiLink" data-imglink="ANNAWAN/Photos-Misc/IMGP6500.JPG">
<img src="../data/towerFiles/ANNAWAN/Photos-Misc/IMGP6500.JPG"
class="ssImg Photos-Misc" title="Photos-Misc"
data-featherlight-gallery="Photos-Misc" data-featherlight-target-attr="src">
</div>
<div class="tiDel"><img src="img/x.png" class="ssImg delTpic" title="delete"></div>
</div>
<div class="tiWrap">
<div class="tiLink" data-imglink="ANNAWAN/Photos-Misc/IMGP6501.JPG">
<img src="../data/towerFiles/ANNAWAN/Photos-Misc/IMGP6501.JPG"
class="ssImg Photos-Misc" title="Photos-Misc"
data-featherlight-gallery="Photos-Misc" data-featherlight-target-attr="src">
</div>
<div class="tiDel"><img src="img/x.png" class="ssImg delTpic" title="delete"></div>
</div>
</div>
When a thumbnail is clicked (bound to class tiLink) , this function is run:
// obj is the object (image thumbnail) that as clicked
function tiLink(obj){
var ilink=$(obj).data("imglink");
if( !ilink ){return;}
// var viewLink="../data/towerFiles/"+ilink;
var gal=$(obj).find("img").attr("title");
// single view
//$.featherlight(viewLink);
// gallery view
$("."+gal).featherlightGallery({
previousIcon: '◀', /* Code that is used as previous icon */
nextIcon: '▶', /* Code that is used as next icon */
galleryFadeIn: 100, /* fadeIn speed when slide is loaded */
galleryFadeOut: 300 /* fadeOut speed before slide is loaded */
});
}
One other note: the image data is loaded and created dynamically.
Why doesn't the 1st image have prev/next navigation if it is chosen first?
EDIT: the "non-gallery" problem happens with whatever picture I click first in the set.
EDIT #2:
JSFiddle demonstrating the problem
Looks like you're over complicating things. You have a single gallery, just bind it once. Call something like this once:
$('.tiLink').featherlightGallery({targetAttr: 'data-imglink', ...})
If you have multiple independent galleries, bind them individually, probably something like:
$('.gallery').each(function() { $(this).find('.item').featherlightGallery(...) })

Expand/Collapse all elements of a Semantic UI accordion

I don't find any clue to do that from the Semantic UI documentation/API, is there a clean way to do that?
For now, what I see is to play with :
$('.ui.accordion > .title').addClass('active')
$('.ui.accordion > .content').css('display', 'block')
You actually can do this like so:
$('.ui.accordion .individual').each(function(i){
$(this).parent().accordion('open',i);
});
You just iterate through each individual element to get its index position, then ask the parent (the accordion) to open each one. This way you still get the transition.
Here is the answer:
onOpen(commentID: string){
jQuery(`.replies${commentID}`).accordion('open', 0);
}
<div class="ui accordion replies{{commentID}}">
<div class="title" (click)="onClick(commentID);">
</div>
<div class="content">
hello
</div>
</div>

How to keep Bootstrap panel expanded/collapsed when changing view

I have 3 Bootstrap panels that expand/collapse when their headers are clicked.
However when changing to another route id (for example for :id=CarModel1 to id=CarModel2 with /cars/details/:id as route), I want to keep their state as was in the previous id after the user messes around with the panels, so that the user can compare the different details immediately when changing views.
How can I keep the panel state? Please, keep in mind I'm using ngRoute and not ui-Router.
Sample panel:
<div id="details">
<div class="panel-heading detailsPanel">
<a data-toggle="collapse" data-parent="#details" data-target="#collapseDetailsPanel">
<h4>Additional Details</h4>
</a>
</div>
<div id="collapseDetailsPanel" class="panel-collapse collapse">
<div class="panel-body">
<div>Lorem Ipsum</div>
</div>
</div>
</div>
Managed to do it by adapting a solution found here and using sessionStorage instead of $.cookie.
$("#details").on('shown.bs.collapse', function() {
var activeDetails = $("#details .in").attr('id');
sessionStorage.setItem('activeDetailsGroup', activeDetails);
});
$("#details").on('hidden.bs.collapse', function() {
sessionStorage.setItem('activeDetailsGroup', "inactive");
});
var lastDetails = sessionStorage.getItem('activeDetailsGroup');
if (lastDetails !== "inactive") {
//remove default collapse settings
$("#details .panel-collapse").removeClass('in');
//show the account_last visible group
$("#" + lastDetails).addClass("in");
}

Copy text from a draggable angular-dnd-list div

I am using the angular drag & drop directive on my divs.
I am also using Bootstrap CSS paneling. The panel header is what I am using as the dnd dragHandle.
<div class="panel-heading dragHandle">
<h4>Click & drag here to move</h4>
</div>
I want the entire div to be draggable based on the header, but once inside the div (where text is displayed), I am using the directive dnd-nodrag. This currently works as you are not able to drag the div when the cursor is inside and not on the panel header; however, I would like to be able to copy the text inside the div.
<div dnd-nodrag class="panel-body" draggable="true">
<p> THIS IS THE TEXT I WANT TO COPY </p>
</div>
As it seems to me, the nodrag directive only allows selection/copying of text inside of an input element. I need to be able to copy the plain text from the div.
Both of the above code snippets are nested inside of a div with the class "panel" and the dnd-draggable directive.
Any work arounds? Any directives I am missing? Please help. Thanks ahead!
Also -- I have tried adjusting the user-select styling in the CSS with no luck.
My attempt:
<div class="panel-body" style="-webkit-user-select: all">
<p> THIS IS THE TEXT I WANT TO COPY</p>
</div>
This issue has been reported in the bugzilla,
Issue Link : https://github.com/react-dnd/react-dnd/issues/178
https://bugzilla.mozilla.org/show_bug.cgi?id=195361
https://bugzilla.mozilla.org/show_bug.cgi?id=800050
However I've fixed this issue using a work around,
When you inspect the Div element, you'll see the below code having draggable attribute set to true hence in firefox you cannot select the text using mouse cursor.
<li ng-repeat="item in models.lists.A" dnd-draggable="item" dnd-moved="models.lists.A.splice($index, 1)" dnd-effect-allowed="move" dnd-selected="models.selected = item" ng-class="{'selected': models.selected === item}" class="ng-scope" draggable="true">
<div dnd-nodrag="" draggable="true">
<div class="theheader" dnd-handle="" **draggable="true"**>A header</div>
<div class="thebody">
Selecting test works on Chrome/Safari. Doesn't work on Firefox/Edge
<input type="text" ng-model="item.label" class="ng-pristine ng-valid">
</div>
</div>
</li>
Workaround :
in html,
<input type="text" ng-model="item.label" class="ng-pristine ng-valid"
ng-click="vm.disableDrag()" ng-blur="vm.enableDrag()">
in JS file,
/**
*find li and disable the draggable feature, so the input can be edited using mouse in firefox
*/
vm.disableDrag= function($event) {
var $li = $event.currentTarget.parentNode;
angular.element($li).attr("draggable", false)
}
/**
* find li element and Enalbe the draggable feature, on blur of the editable input
*/
vm.enableDrag = function($event) {
var $li = $event.currentTarget.parentNode;
angular.element($li).attr("draggable", true)
}

Resources