How to animate the removal of a MUI datagrid row in a react app - material-ui

I am new to using MUI and I'm trying to create a simple animation which would trigger when a row is removed by the click of a row button (either fade out or even better have it compress). I currently have a workaround solution in which I grab the row through the data-id using document.querySelector and then add a class to it, but I would like to know how to do this using inline css.
After research it looks like I would have to use something like adding a keyframe (which I've seen done for individual elements) but I'm unclear how to do that for a row in a MUI data grid.
I've tried using UseGridApiRef and then using the getRowElement to add the below keyframe to that but can't get the syntax right.
I want to do this because currently I believe I am changing the DOM directly (very slow) by doing this:
let el = document.querySelector(`.MuiDataGrid-row[data-id="${id}"]`);
el.classList.add("animate-launch-case");
// Global css Page
.animate-launch-case {
opacity: 0;
transition: opacity 1s ease-in;
}
I want to be able to change the virtual DOM instead but having trouble understanding how to do it with state. Here is a Sandbox of my datagrid and here is an example of a keyframe I think would work:
const myEffectExit = keyframes`
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(-200%);
}
`;

Related

How to change layout of sap.uxap.ObjectPage Blocks

Demo
I have 2 + 5 blocks here, in small screen, each panel in blocks are in full width.
But in large screen, blocks are in 3:3:3 or 6:3. I want them all in a single row.
each section is contained in <div class="sapUiRespGridSpanL4 sapUiRespGridSpanM6 sapUiRespGridSpanS12 sapUiRespGridSpanXL3">
How to change it to class="sapUiRespGridSpanL12 sapUiRespGridSpanM12 sapUiRespGridSpanS12 sapUiRespGridSpanXL12" ?
I've tried to add layout in Panel, but not working.
Refrence:
sap.uxap.ObjectPageLayout Documentation
layout of blocks, blocks are in the same color, hard to specify
Finally after 1.5 hours figured out
Reason: Blocks will have to be extended from BlockBase to apply columnLayout.
Extending the BlockBase:
sap.ui.define(["sap/uxap/BlockBase"], function (BlockBase) {
"use strict";
var BlockPanel = BlockBase.extend("sap.uxap.sample.ObjectPageSubSectionSized.blocks.BlockPanel", {
metadata: {
/* no additional views provided */
}
});
return BlockPanel;
});
Then create a view and controller using the above new ui5 extended control. Use that in your page with columnLayout
xmlns:sample="sap.uxap.sample.ObjectPageSubSectionSized.blocks"
...
...
<uxap:blocks>
<sample:BlockPanel columnLayout="4"/>
</uxap:blocks>
columnLayout can't be applied if you don't extend block base. (which is really pathetic design). Nevertheless, values range from 1-4 and "auto".
Created working plnkr here
How to build custom SAPUI control?
You can wrap the target controls up with sap.uxap.BlockBase[API]. BlockBase controls are intended to be used inside sap.uxap.ObjectPageSubSection (hence the name <blocks>) and support customizing the grid spans with the property columnLayout.
Here is a demo: https://embed.plnkr.co/lSrDk9/?show=view%2FHome.view.xml,preview
<uxap:ObjectPageSubSection>
<block:MyBlock columnLayout="4"/>
<block:MyBlock columnLayout="4"/>
</uxap:ObjectPageSubSection>
Provide a not elegant, but very fast way: Overwrite CSS
<uxap:ObjectPageSubSection class="fullWidthPanel">
/* CSS specificity */
.fullWidthPanel .sapUiRespGrid.sapUiRespGridHSpace1 > div {
width: 98.88888889%;
width: -webkit-calc(100% - 1rem);
width: calc(100% - 1rem)
}

Adding custom transition to tabstrip in openui5

Can the navigation between tabs be customized to as in the navcontainer i.e. while selecting tabs the view should scroll and change from left to right like swipe navigation with new page as in navcontainer.
You could achieve the slide in effect rather easily by adding the following CSS to your application
#keyframes slidein {
from {
right: -100%;
}
to {
right: -6px;
}
}
.sapUiTabPanel {
overflow:hidden;
}
.sapUiTabPanel > * {
animation: slidein 500ms;
position: absolute;
}
Note that you may need to add CSS with vendor prefixes depending on which browsers you are supporting.
To achieve the slide out of the current displayed tab is a bit tricky, one possible way this could be achieved is with the following code added to somewhere like the onInit method of your controller
oTabStrip1.attachBrowserEvent("mousedown",function(oEvent){
var oTarget = oEvent.target;
if(oTarget.className==="sapUiTabClose"){
return;
}
var iIdx = oTabStrip1.getItemIndex(oTarget);
if (iIdx > -1) {
if ((iIdx !== oTabStrip1.getSelectedIndex()) && (oTabStrip1.getTabs()[iIdx].getEnabled())) {
oEvent.stopPropagation();
oEvent.preventDefault();
jQuery.each(
oTabStrip1.getTabs()[oTabStrip1.getSelectedIndex()].getContent(),function(i,o){
var sAnimateLeft = (o.$().innerWidth() * -1) + "px";
o.$().animate({left:sAnimateLeft},500);
});
setTimeout(function(){
oTabStrip1.selectTabByDomRef(oTarget);
},250);
}
}
});
The above is assuming oTabStrip1 is the instance of your tabstrip control. Although it's often not good practice to modify the DOM directly within UI5 applications, in this case it's probably safe as the content of the displayed tab is removed and replaced with the clicked tab content, so all we are doing is delaying this until the slide out animation is complete.
You can see a working example at http://jsbin.com/vukibi - the code has been taken directly from the tabstrip example with the above CSS and JS added

TinyMCE: Get orignial textarea reference within initialization

Problem
Width of the <textarea> is defined by CSS class, for ex.: wMax or wDefault. In first case it is 100%, in the second, lets say 200px. By default TinyMCE converts everything to fixed width in pixels. Ofcourse I can set width:100% inside tinyMCE.init(), but that will not cover textarea's with wDefault / fixed with.
What I need
I need TinyMCE width to behave the same as original, % or px depending on it's CSS class.
If I could find a reference to the original textarea element within tinyMCE.init() procedure, then I could read CSS class from it, and set width: (textarea.hasClass('wMax') ? '100%' : null) or something like that
I am aware of the getElement() function, which gets me exactly that textarea. But where do I run it from? tinyMCE.activeEditor is null within init().
I'm currently still using TinyMCE 3, but it would be nice if you could answer this also for 4.x version, if there is any difference ofcourse...
Found the solution myself. Sharing.
Answering my own question in the title: It's not possible to refer to the textarea within init() procedure directly, because it does not run for each tinyMCE instance. It runs only once. But: TinyMCE has a customizable setup function, which does run for every instance and has all required references to solve the mentioned problem.
With the following code:
tinyMCE.init({
// ... your settings here ...
setup: function(ed){
if(ed.getElement().hasClass('wMax')){
ed.settings.width = '100%';
}
}
});
Any textarea with CSS class 'wMax' (replace with your own) will be replaced by TinyMCE instance having 100% width. All others will have a fixed width, equal to the width of the textarea at the moment of initialization. You can expand this approach with any width, like wHalf width:50% etc.
Note: .hasClass() function is a part of Mootools JS library. Replace with another if you use a different library.
I don't know if this will lead you into the right direction. I use this code to adjust the iframe height to fit the entered content. You could tweak it a bit to adjust its height and width to your needs (you will need to get the textarea by $('#' + ed.id) onInit.
Here is the function. Basically it changes the style attributes explicitly of the editor iframe
resizeIframe: function(frameid) {
var frameid = frameid ? frameid : this.editor.id+'_ifr';
var currentfr=document.getElementById(frameid);
if (currentfr && !window.opera){
currentfr.style.display="block";
if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) { //ns6 syntax
currentfr.height = currentfr.contentDocument.body.offsetHeight + 26;
}
else if (currentfr.Document && currentfr.Document.body.scrollHeight) { //ie5+ syntax
currentfr.height = currentfr.Document.body.scrollHeight;
}
styles = currentfr.getAttribute('style').split(';');
for (var i=0; i<styles.length; i++) {
if ( styles[i].search('height:') ==1 ){
styles.splice(i,1);
break;
}
};
currentfr.setAttribute('style', styles.join(';'));
}
},

Best way of solving multiple click on button

Multiple click on button on browser, sends multiple request to server.
The easiest way to solve it is to stop multiple click on browser by JavaScript.
Can anybody suggest what could be better way to solve it?
For easiness i'll give litter design overview
BROWSER ---to---> WEB[all controllers] ----to-->rest call to service.
Adding More information:
Note: we are sending CSRF token
Step 1: we are on /page/show - GET
Step 2: we Post the form /page/show -POST [srf token included in it]
Step 3: ON-SUCCESSFUL completion of save we redirect again to /page/show
Thanks
There are 2 ways you can solve this
why not when the button is clicked disable the button and show some loading gif. Loading gif is very important to inform the user something is happening.
If you want that after the button click user should not be able to interact with the page at all then create a div with background color as grey with some opacity so that user is able to see the page behind and increase its z index so that its on top and thus stops user from interacting with the page. (You can also add loading gif icon in side div using same technique)
if you want to take second approach, here is small example to get you going
css for the div
#overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
filter:alpha(opacity=50);
-moz-opacity:0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
z-index: 10000;
}
//function to show overlay
function ShowOverLay(){
var overlay = $('<div id="overlay"> </div>');
overlay.appendTo(document.body)
}
//function to hide overlay
function DeleteOverLay(){
$('.overlay').remove();
}
//function to get data
function GetData(){
//at first show the overlay
ShowOverLay()
//now make an ajax call
$.ajax({
url: url,
data: data,
success: function(data){
if(data){
//some processing with data if successfull
//hide the overlay now
DeleteOverLay();
}
},
dataType: dataType
});
}

Twitter Bootstrap Modal Form: How to drag and drop?

I would like to be able to move around (on the greyed-out background, by dragging and dropping) the modal form that is provided by Bootstrap 2. Can anyone tell me what the best practice for achieving this is?
The bootstrap doesn't come with any dragging and dropping functionality by default, but you can add a little jQuery UI spice into the mix to get the effect you're looking for. For example, using the draggable interaction from the framework you can target your modal ID to allow it to be dragged around within the modal backdrop.
Try this:
JS
$("#myModal").draggable({
handle: ".modal-header"
});
Demo, edit here.
Update: bootstrap3 demo
Whatever draggable option you go for, you might want to turn off the *-transition properties for .modal.fade in bootstrap’s CSS file, or at least write some JS that temporarily disables them during dragging. Otherwise, the modal doesn’t drag exactly as you would expect.
You can use a little script likes this.
simplified from Draggable without jQuery UI
(function ($) {
$.fn.drags = function (opt) {
opt = $.extend({
handle: "",
cursor: "move"
}, opt);
var $selected = this;
var $elements = (opt.handle === "") ? this : this.find(opt.handle);
$elements.css('cursor', opt.cursor).on("mousedown", function (e) {
var pos_y = $selected.offset().top - e.pageY,
pos_x = $selected.offset().left - e.pageX;
$(document).on("mousemove", function (e) {
$selected.offset({
top: e.pageY + pos_y,
left: e.pageX + pos_x
});
}).on("mouseup", function () {
$(this).off("mousemove"); // Unbind events from document
});
e.preventDefault(); // disable selection
});
return this;
};
})(jQuery);
example : $("#someDlg").modal().drags({handle:".modal-header"});
Building on previous answers utilizing jQuery UI, this, included once, will apply to all your modals and keep the modal on screen, so users don't accidentally move the header off screen so they can no longer access the handle. Also sets the cursor to 'move' for better discoverability.
$(document).on('shown.bs.modal', function(evt) {
let $modal = $(evt.target);
$modal.find('.modal-content').draggable({
handle: ".modal-header",
containment: $modal
});
$modal.find('.modal-header').css('cursor', 'move')
});
evt.target is the .modal which is the translucent overlay behind the actual .modal-content.
jquery UI is large and can conflict with bootstrap.
An alternative is DragDrop.js: http://kbjr.github.io/DragDrop/index.html
DragDrop.bind($('#myModal')[0], {
anchor: $('#myModal .modal-header')
});
You still have to deal with transitions, as #user535673 suggests. I just remove the fade class from my dialog.