I'm currently writing an app where I have many columns in a MUI Grid, scrolling horizontally. It's a task planner app, and when I create a task, I want to be able to drag it between the different columns that are visible on the screen. I'm using hello-pangea/dnd to control the drag and drop functionality of the tasks, and as mentioned earlier, Material UI for the Grid that stores the columns.
However, I don't like the fact that it scrolls while I'm dragging - the Grid automatically scrolls while I'm dragging tasks. I want to disable this.
I already tried dynamically setting the overflow CSS style of the Grid depending on whether or not I'm dragging - if dragging, set overflow-x to hidden, otherwise, keep it as scroll. I expected this to disable the ability to scroll in the Grid, because if I initialize the Grid to have overflow-x: hidden, then scrolling is disabled. But, as you can see below, this does not help. Even though the style changes from overflow: scroll to overflow: hidden, the Grid still scrolls while dragging:
(yes the UI needs work, I'll get to it eventually)
I tested this on both Google Chrome as well as Safari. I also tried using a state variable and setting the sx of the Grid component as follows. This didn't work either. My code looks something like the following:
const View = (props) => {
const [currentOverflow, setCurrentOverflow] = useState("scroll");
// ...definition of taskView, etc...
// props.dragging is a boolean passed down from the parent element
// that is true when an item is being dragged, otherwise false
useEffect(() => {
setCurrentOverflow((props.dragging) ? "hidden" : "scroll");
}, [props.dragging])
return (
<Grid
id={taskViewGridId}
className="taskview"
sx={{
overflow: currentOverflow
}}
>
{taskView}
</Grid>
)
}
The way I was trying to set the overflow parameter using CSS as I showed in that GIF before this code snippet was similar to the above, except the callback in the useEffect looked like this:
var gridElt = document.getElementById(taskViewGridId);
if (props.dragging) {
gridElt.classList.remove("enable-scroll");
gridElt.classList.add("disable-scroll");
} else {
gridElt.classList.remove("disable-scroll");
gridElt.classList.add("enable-scroll");
}
where the associated CSS classes were just
.disable-scroll {
overflow-x: hidden;
}
.enable-scroll {
overflow-x: scroll;
}
Can someone please help me figure this out? How do I disable scrolling in the MUI Grid depending on whether or not something is being dragged?
Thank you.
Fixed this. The #hello-pangea/dnd library automatically scrolls the window while dragging. An option to disable this has now been added to the library in their latest release.
Related
Situation:
Currently I have two tabs on my site, both containing a text. The text has a fixed height and the content-overflow is not shown (overflow: hidden).
Problem:
I would like to add three dots (icon) if my text is overflowing. To detect if overflowing occurs I use the following expression, that works perfectly and adds an expandButton if overflowing occurs.
isOverflown: boolean;
hasExpandButton: boolean;
[...]
const overflown = this.isOverflown() ? this.hasExpandButton = true : this.hasExpandButton = false;
The problem is, that I don't know where I should check if my content is overflowing, because I use this statement in two differnet locations (here: tabs).
If I choose ngAfterViewInit, const overflown is getting set to true if my content is overflowing on the first tab. BUT not on the second tab (if the content is there also overflowing). The reason for that is, that the view only gets rendered on the first tab and not on the second tab. Therefore if I switch to the second tab the ngAfterViewInit will not trigger.
I also tried to use other lifecycle-hooks, but none of them worked for me.
I thought maybe about ngAfterContentInit and use a variable to detect if ngAfterContentInit is called for the first time, but this did not work for me either.
Thank you in advance.
SOLUTION
I disabled lazy loading for this component and that solved the issue.
You can check it after the view inits (ngAfterViewInit) AND when user switches tab - add (click)="checkOverflow()" to the tab tag in html.
Try solving this using CSS:
.txt-overflow {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
so you can get rid of extra component logic
I have noticed this for a while however that when using Lightswitch and setting properties to "Stretch to Container", that the screen sometimes appears to be over-stretched and moves items down to the next line, for example:
When pressing the "See My Projects Only" the buttons switch (so I hide this one and display the other option" using the below code:
if (screen.ChangeDefaultValue.count > 0) {
screen.ChangeDefaultValue.selectedItem = screen.ChangeDefaultValue.data[0];
screen.ChangeDefaultValue.selectedItem.HomepageProjectsDefault = false;
screen.DefaultOption = null;
myapp.applyChanges();
setTimeout(function () {
screen.Projects.refresh();
}, 100);
screen.findContentItem("SeeAllProjects").isVisible = false;
screen.findContentItem("SeeMyProjectsOnly").isVisible = true;
}
else {
}
This works perfectly, however as you can see in the 2nd image above, the button moves down below the parameter search box as if it has been overstretched. I have tried changing the margin and padding of the .msls-content however this error still occurs here and on multiple of my other pages.
Has anyone found a fix to this problem?
Further information:
I am using msls-2.5.3.css and is declared in the default.htm file
I have tried this https://social.msdn.microsoft.com/Forums/vstudio/en-US/fb1305c5-ac13-474e-8ae0-df74ebf12590/html-client-custom-control-stretch-to-container-sizing-bug-problem?forum=lightswitch
THE PROBLEM
this small block of code in the msls-2.5.3.css appears to be the issue however if I comment it out then other screens break. all of the padding in the height appears to disappear and they all overlap each other on the modal screens
.msls-clear {
clear: both;
}
In LightSwitch HTML, we can use column layout option to render the control in each column. By setting "stretch to container" property, column is only stretched to container size and not the control inside each column is stretched with container. Controls are properly rendered inside the container. Issue occurs due to the column width stretches when hide and show the content item and this is not related with component used in the page. Follow the below workaround solution while remove the content item dynamically by click on the button. Please remove the class ‘msls-clear’ on button click or apply clear: none to the class ‘msls-clear’.
this.element.parents(".msls-column").next(".msls-clear").removeClass("msls-clear")
Hope this will helps you..!
Thanks,
Francis
Im no expert in CSS but this appears to have fixed my issues:
.msls-clear {
clear: right;
max-width: 1850px;
}
all of the machines I have tested have a resolution of 1920 x 1080 so by reducing the width down slightly it will never over stretch the items.
I did originally comment out the clear: right; which worked in internet explorer, however I tested some Syncfusion controls in google chrome/firefox. I could not click on any of them and therefore had to add in the max-width.
If someone can propose a better solution I would be grateful but at least for now this works
This question was initially a flexbox issue but has been altered to a highcharts resizing one.
The problem:
I got the chart to resize perfectly in relation to it's parent (I was setting 100% height/width of it's parent) on window resize. The issue is that this only happens on a window resize event so when the page is initially loaded, the chart is not the size I want it (usually smaller)
Code:
HTML:
<div id="datalogger">
<div id="DataLoggerChartContainer" ng-show="dataAvailable"></div>
</div>
CSS/LESS: (I was using flex but the styling does not matter)
#datalogger {
display: flex;
flex: auto;
justify-content: center;
align-items: center;
width: 100%;
#DataLoggerChartContainer {
display: flex;
flex: auto;
width: 100%;
}
}
JS: (to resize chart)
function reflowChart() {
var parent = angular.element(element[0]);
chart.setSize(parent.width(), parent.height());
}
#brightmatrix helped my realise that highcharts setSize() method will only resize the chart ONCE and is therefore not an ideal responsive solution. The reflow() and redraw(), as suggested, were not what I was looking for either. These methods aren't meant for responsiveness but mainly for if data is dynamically added to the chart and needs to be reloaded. reflow() is advertised on Highcharts API to dynamically resize to it's parent if it's size is altered. However, I think this only works if the window is not resized. So, the chart still has to be on the same sized window and the parent just has to resize within it's own container (on button click event for example (as in Highcharts API))
(Solution is below)
The problem is that as soon as you set fixed values for chart.setSize(), the responsive nature your chart is removed. I would suggest either adding percentage values, using the chart.redraw() function, or tying the chart.reflow() function to a resize event.
Here are the links to both functions in the API documentation so you can see which is best suited for your application:
chart.redraw(): http://api.highcharts.com/highcharts#Chart.redraw
chart.reflow(): http://api.highcharts.com/highcharts#Chart.reflow
I hope this helps!
The solution:
After digging through previous code in other areas of this application, I decided to attempt to redraw (manually - not using the redraw() method) the chart on a window resize event. For example:
$(window).on("resize", function() {
chart.destroy();
initChart();
reflowChart();
});
My initChart() function looks like this:
function initChart() {
chart = new Highcharts.Chart(options);
}
My reflowChart() function is still the same as is mentioned above, however, the manual resizing does not matter as it resizes to the CURRENT height/width of the parent of the CURRENT window size. Because it is destroyed and recreated on each resize of the the window, this is an ideal solution.
N.B: It is not required but is recommended to call the destroy() method as it keeps the DOM nice and tidy.
Also, I call the initChart() and reflowChart() when the page first loads as well
I hope this helps anyone that may come across this problem in the future!
I'm working on a phonegap app that has a fixed sidebar behind the page and I found an behavior issue.
The sidebar is hidden, the user can see it with a tap on a menu icon. When the user tap on he icon the page go to the right and it shows the sidebar that is in a minor z-index.
If the user want to close the menu he have to drag the visible part of the page to the left.
My problem was that in the sidebar I have a block that is vertically scrollable. It works fine but the thing is, if I put the .scroll (overflow-y: scroll; -webkit-overflow-scrolling: touch;) class in this element and the user swipe horizontally from right to left over it the sidebar and the page start a drag.
We're using snap.js for the sidebar interaction.
I want to disable this drag. I tried with CSS and preventing horizontal scroll but it doesn't work.
I attach a pic for more visual details.
Use iScroll5 for scrolling.
Then hook into the onScrollStart event:
myScroll.on('beforeScrollStart', function(event)
{
if (isPanelOpen){
myScroll.disable();
}
else{
myScroll.enable();
}
});
Or - if you not wanna use iScroll5, you can set a global bool, which indicates, if a panel is open (you've gotta do this anyway).
If a Panel is open (meaning, you're showing the sidebar) set the bool to true in snap.js - this subsequently means, you've gotta tweak snap.js.
Then, on touchmove, check the bool if it is true. Then you know, a panel is open, and you can do a event.stopPropagation on touchmove in order to prevent the event bubbling up to get recognized by snap.js and avoid the panels closes too early.
Woop! We found it!
The problem was that we're catching the touchmove event for each element with .scroll class and we're stoping the propagation of it.
We had notice that when we tried to start a horizontal scroll all page was moving like a drag so we added this CSS property:
html, body, .ui-mobile .ui-page-active { overflow-x: hidden; }
And...it works fine!
P.S. we don't actually need the horizontal scroll in any element, so, this is fine for us.
I'd like to show a modal dialog using a 3D flip effect, exactly like the "3D flip (horizontal)" example in the Effeckt.css library.
However I really don't need the whole Effeckt library, since I just want this one effect. So I've tried to strip out the relevant bits of the library into free-standing CSS and JavaScript.
This is my attempt, but it's not working: http://jsfiddle.net/eJsZx/
As the JSFiddle demonstrates, it's only showing the overlap - not the modal itself. This is odd, because the element inspector suggests that the modal should be visible - it has display: block, visibility: visible and zindex: 2000 (higher than the overlay element).
This is the JavaScript:
$('button').on('click', function() {
$("#effeckt-modal-wrap").show();
$("#effeckt-modal-wrap").addClass('md-effect-8');
$("#effeckt-modal-wrap").addClass("effeckt-show");
$('#effeckt-overlay').addClass("effeckt-show");
$(".effeckt-modal-close, .effeckt-overlay").on("click", function() {
$("#effeckt-modal-wrap").fadeOut();
$('#effeckt-modal-wrap').removeClass("effeckt-show");
$("#effeckt-modal-wrap").removeClass('md-effect-8');
$('#effeckt-overlay').removeClass("effeckt-show");
});
});
What am I doing wrong?
There were a couple of issues in the code.
First, your styles were missing the following:
.effeckt-show .effeckt-modal {
visibility: visible;
}
This was causing the modal to remain invisible.
Once the dialog was visible, the dialog would rotate in just fine, however when being dismissed it would not rotate out. This was due to the following line:
$("#effeckt-modal-wrap").removeClass('md-effect-8');
If you want to remove this class, it would need to be done after the animation is complete otherwise the 3d effect is lost. It doesn't necessarily need to be removed, but that depends on what the rest of your content needs.
The final issue was that the wrapper, on completion of the fadeout, was getting its local style set to display: none. Because of this, the second time showing the dialog would cause it to simply appear because it was moving from display: none to display: block. There are a couple of options here.
Use CSS to animate the fade in/out.
Use window.setTimeout after calling $.show on the element to give the dom a chance to update.
The final result: Working Fiddle