This commit is contained in:
@@ -438,7 +438,7 @@ Projekte
|
||||
|
||||
**Inhalt:**
|
||||
|
||||
- **Exkurs: DOM Inhalte über mit REST API Express**
|
||||
- **Exkurs: DOM Inhalte mit REST API Express**
|
||||
- **Erweiterung Frontend um REST API**
|
||||
- CRUD - (Create - Read) - Update - Delete
|
||||
- BREAD - Browse - Read - Edit - Add - Delete
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
if(typeof ShadowRoot==='undefined'){return false;}var OwnElement=getWindow(node).ShadowRoot;return node instanceof OwnElement||node instanceof ShadowRoot;}
|
||||
|
||||
// and applies them to the HTMLElements such as popper and arrow
|
||||
function applyStyles(_ref){var state=_ref.state;Object.keys(state.elements).forEach(function(name){var style=state.styles[name]||{};var attributes=state.attributes[name]||{};var element=state.elements[name];// arrow is optional + virtual elements
|
||||
function applyStyles$1(_ref){var state=_ref.state;Object.keys(state.elements).forEach(function(name){var style=state.styles[name]||{};var attributes=state.attributes[name]||{};var element=state.elements[name];// arrow is optional + virtual elements
|
||||
if(!isHTMLElement(element)||!getNodeName(element)){return;}// Flow doesn't support to extend this property, but it's the most
|
||||
// effective way to apply styles to an HTMLElement
|
||||
// $FlowFixMe[cannot-write]
|
||||
Object.assign(element.style,style);Object.keys(attributes).forEach(function(name){var value=attributes[name];if(value===false){element.removeAttribute(name);}else {element.setAttribute(name,value===true?'':value);}});});}function effect$2(_ref2){var state=_ref2.state;var initialStyles={popper:{position:state.options.strategy,left:'0',top:'0',margin:'0'},arrow:{position:'absolute'},reference:{}};Object.assign(state.elements.popper.style,initialStyles.popper);state.styles=initialStyles;if(state.elements.arrow){Object.assign(state.elements.arrow.style,initialStyles.arrow);}return function(){Object.keys(state.elements).forEach(function(name){var element=state.elements[name];var attributes=state.attributes[name]||{};var styleProperties=Object.keys(state.styles.hasOwnProperty(name)?state.styles[name]:initialStyles[name]);// Set all values to an empty string to unset them
|
||||
var style=styleProperties.reduce(function(style,property){style[property]='';return style;},{});// arrow is optional + virtual elements
|
||||
if(!isHTMLElement(element)||!getNodeName(element)){return;}Object.assign(element.style,style);Object.keys(attributes).forEach(function(attribute){element.removeAttribute(attribute);});});};}// eslint-disable-next-line import/no-unused-modules
|
||||
var applyStyles$1 = {name:'applyStyles',enabled:true,phase:'write',fn:applyStyles,effect:effect$2,requires:['computeStyles']};
|
||||
var applyStyles = {name:'applyStyles',enabled:true,phase:'write',fn:applyStyles$1,effect:effect$2,requires:['computeStyles']};
|
||||
|
||||
function getBasePlacement(placement){return placement.split('-')[0];}
|
||||
|
||||
@@ -86,12 +86,12 @@
|
||||
|
||||
function expandToHashMap(value,keys){return keys.reduce(function(hashMap,key){hashMap[key]=value;return hashMap;},{});}
|
||||
|
||||
var toPaddingObject=function toPaddingObject(padding,state){padding=typeof padding==='function'?padding(Object.assign({},state.rects,{placement:state.placement})):padding;return mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));};function arrow(_ref){var _state$modifiersData$;var state=_ref.state,name=_ref.name,options=_ref.options;var arrowElement=state.elements.arrow;var popperOffsets=state.modifiersData.popperOffsets;var basePlacement=getBasePlacement(state.placement);var axis=getMainAxisFromPlacement(basePlacement);var isVertical=[left,right].indexOf(basePlacement)>=0;var len=isVertical?'height':'width';if(!arrowElement||!popperOffsets){return;}var paddingObject=toPaddingObject(options.padding,state);var arrowRect=getLayoutRect(arrowElement);var minProp=axis==='y'?top:left;var maxProp=axis==='y'?bottom:right;var endDiff=state.rects.reference[len]+state.rects.reference[axis]-popperOffsets[axis]-state.rects.popper[len];var startDiff=popperOffsets[axis]-state.rects.reference[axis];var arrowOffsetParent=getOffsetParent(arrowElement);var clientSize=arrowOffsetParent?axis==='y'?arrowOffsetParent.clientHeight||0:arrowOffsetParent.clientWidth||0:0;var centerToReference=endDiff/2-startDiff/2;// Make sure the arrow doesn't overflow the popper if the center point is
|
||||
var toPaddingObject=function toPaddingObject(padding,state){padding=typeof padding==='function'?padding(Object.assign({},state.rects,{placement:state.placement})):padding;return mergePaddingObject(typeof padding!=='number'?padding:expandToHashMap(padding,basePlacements));};function arrow$1(_ref){var _state$modifiersData$;var state=_ref.state,name=_ref.name,options=_ref.options;var arrowElement=state.elements.arrow;var popperOffsets=state.modifiersData.popperOffsets;var basePlacement=getBasePlacement(state.placement);var axis=getMainAxisFromPlacement(basePlacement);var isVertical=[left,right].indexOf(basePlacement)>=0;var len=isVertical?'height':'width';if(!arrowElement||!popperOffsets){return;}var paddingObject=toPaddingObject(options.padding,state);var arrowRect=getLayoutRect(arrowElement);var minProp=axis==='y'?top:left;var maxProp=axis==='y'?bottom:right;var endDiff=state.rects.reference[len]+state.rects.reference[axis]-popperOffsets[axis]-state.rects.popper[len];var startDiff=popperOffsets[axis]-state.rects.reference[axis];var arrowOffsetParent=getOffsetParent(arrowElement);var clientSize=arrowOffsetParent?axis==='y'?arrowOffsetParent.clientHeight||0:arrowOffsetParent.clientWidth||0:0;var centerToReference=endDiff/2-startDiff/2;// Make sure the arrow doesn't overflow the popper if the center point is
|
||||
// outside of the popper bounds
|
||||
var min=paddingObject[minProp];var max=clientSize-arrowRect[len]-paddingObject[maxProp];var center=clientSize/2-arrowRect[len]/2+centerToReference;var offset=within(min,center,max);// Prevents breaking syntax highlighting...
|
||||
var axisProp=axis;state.modifiersData[name]=(_state$modifiersData$={},_state$modifiersData$[axisProp]=offset,_state$modifiersData$.centerOffset=offset-center,_state$modifiersData$);}function effect$1(_ref2){var state=_ref2.state,options=_ref2.options;var _options$element=options.element,arrowElement=_options$element===void 0?'[data-popper-arrow]':_options$element;if(arrowElement==null){return;}// CSS selector
|
||||
if(typeof arrowElement==='string'){arrowElement=state.elements.popper.querySelector(arrowElement);if(!arrowElement){return;}}if(!contains(state.elements.popper,arrowElement)){return;}state.elements.arrow=arrowElement;}// eslint-disable-next-line import/no-unused-modules
|
||||
var arrow$1 = {name:'arrow',enabled:true,phase:'main',fn:arrow,effect:effect$1,requires:['popperOffsets'],requiresIfExists:['preventOverflow']};
|
||||
var arrow = {name:'arrow',enabled:true,phase:'main',fn:arrow$1,effect:effect$1,requires:['popperOffsets'],requiresIfExists:['preventOverflow']};
|
||||
|
||||
function getVariation(placement){return placement.split('-')[1];}
|
||||
|
||||
@@ -101,8 +101,8 @@
|
||||
function roundOffsetsByDPR(_ref,win){var x=_ref.x,y=_ref.y;var dpr=win.devicePixelRatio||1;return {x:round(x*dpr)/dpr||0,y:round(y*dpr)/dpr||0};}function mapToStyles(_ref2){var _Object$assign2;var popper=_ref2.popper,popperRect=_ref2.popperRect,placement=_ref2.placement,variation=_ref2.variation,offsets=_ref2.offsets,position=_ref2.position,gpuAcceleration=_ref2.gpuAcceleration,adaptive=_ref2.adaptive,roundOffsets=_ref2.roundOffsets,isFixed=_ref2.isFixed;var _offsets$x=offsets.x,x=_offsets$x===void 0?0:_offsets$x,_offsets$y=offsets.y,y=_offsets$y===void 0?0:_offsets$y;var _ref3=typeof roundOffsets==='function'?roundOffsets({x:x,y:y}):{x:x,y:y};x=_ref3.x;y=_ref3.y;var hasX=offsets.hasOwnProperty('x');var hasY=offsets.hasOwnProperty('y');var sideX=left;var sideY=top;var win=window;if(adaptive){var offsetParent=getOffsetParent(popper);var heightProp='clientHeight';var widthProp='clientWidth';if(offsetParent===getWindow(popper)){offsetParent=getDocumentElement(popper);if(getComputedStyle$1(offsetParent).position!=='static'&&position==='absolute'){heightProp='scrollHeight';widthProp='scrollWidth';}}// $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
|
||||
offsetParent=offsetParent;if(placement===top||(placement===left||placement===right)&&variation===end){sideY=bottom;var offsetY=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.height:// $FlowFixMe[prop-missing]
|
||||
offsetParent[heightProp];y-=offsetY-popperRect.height;y*=gpuAcceleration?1:-1;}if(placement===left||(placement===top||placement===bottom)&&variation===end){sideX=right;var offsetX=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.width:// $FlowFixMe[prop-missing]
|
||||
offsetParent[widthProp];x-=offsetX-popperRect.width;x*=gpuAcceleration?1:-1;}}var commonStyles=Object.assign({position:position},adaptive&&unsetSides);var _ref4=roundOffsets===true?roundOffsetsByDPR({x:x,y:y},getWindow(popper)):{x:x,y:y};x=_ref4.x;y=_ref4.y;if(gpuAcceleration){var _Object$assign;return Object.assign({},commonStyles,(_Object$assign={},_Object$assign[sideY]=hasY?'0':'',_Object$assign[sideX]=hasX?'0':'',_Object$assign.transform=(win.devicePixelRatio||1)<=1?"translate("+x+"px, "+y+"px)":"translate3d("+x+"px, "+y+"px, 0)",_Object$assign));}return Object.assign({},commonStyles,(_Object$assign2={},_Object$assign2[sideY]=hasY?y+"px":'',_Object$assign2[sideX]=hasX?x+"px":'',_Object$assign2.transform='',_Object$assign2));}function computeStyles(_ref5){var state=_ref5.state,options=_ref5.options;var _options$gpuAccelerat=options.gpuAcceleration,gpuAcceleration=_options$gpuAccelerat===void 0?true:_options$gpuAccelerat,_options$adaptive=options.adaptive,adaptive=_options$adaptive===void 0?true:_options$adaptive,_options$roundOffsets=options.roundOffsets,roundOffsets=_options$roundOffsets===void 0?true:_options$roundOffsets;var commonStyles={placement:getBasePlacement(state.placement),variation:getVariation(state.placement),popper:state.elements.popper,popperRect:state.rects.popper,gpuAcceleration:gpuAcceleration,isFixed:state.options.strategy==='fixed'};if(state.modifiersData.popperOffsets!=null){state.styles.popper=Object.assign({},state.styles.popper,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.popperOffsets,position:state.options.strategy,adaptive:adaptive,roundOffsets:roundOffsets})));}if(state.modifiersData.arrow!=null){state.styles.arrow=Object.assign({},state.styles.arrow,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.arrow,position:'absolute',adaptive:false,roundOffsets:roundOffsets})));}state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-placement':state.placement});}// eslint-disable-next-line import/no-unused-modules
|
||||
var computeStyles$1 = {name:'computeStyles',enabled:true,phase:'beforeWrite',fn:computeStyles,data:{}};
|
||||
offsetParent[widthProp];x-=offsetX-popperRect.width;x*=gpuAcceleration?1:-1;}}var commonStyles=Object.assign({position:position},adaptive&&unsetSides);var _ref4=roundOffsets===true?roundOffsetsByDPR({x:x,y:y},getWindow(popper)):{x:x,y:y};x=_ref4.x;y=_ref4.y;if(gpuAcceleration){var _Object$assign;return Object.assign({},commonStyles,(_Object$assign={},_Object$assign[sideY]=hasY?'0':'',_Object$assign[sideX]=hasX?'0':'',_Object$assign.transform=(win.devicePixelRatio||1)<=1?"translate("+x+"px, "+y+"px)":"translate3d("+x+"px, "+y+"px, 0)",_Object$assign));}return Object.assign({},commonStyles,(_Object$assign2={},_Object$assign2[sideY]=hasY?y+"px":'',_Object$assign2[sideX]=hasX?x+"px":'',_Object$assign2.transform='',_Object$assign2));}function computeStyles$1(_ref5){var state=_ref5.state,options=_ref5.options;var _options$gpuAccelerat=options.gpuAcceleration,gpuAcceleration=_options$gpuAccelerat===void 0?true:_options$gpuAccelerat,_options$adaptive=options.adaptive,adaptive=_options$adaptive===void 0?true:_options$adaptive,_options$roundOffsets=options.roundOffsets,roundOffsets=_options$roundOffsets===void 0?true:_options$roundOffsets;var commonStyles={placement:getBasePlacement(state.placement),variation:getVariation(state.placement),popper:state.elements.popper,popperRect:state.rects.popper,gpuAcceleration:gpuAcceleration,isFixed:state.options.strategy==='fixed'};if(state.modifiersData.popperOffsets!=null){state.styles.popper=Object.assign({},state.styles.popper,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.popperOffsets,position:state.options.strategy,adaptive:adaptive,roundOffsets:roundOffsets})));}if(state.modifiersData.arrow!=null){state.styles.arrow=Object.assign({},state.styles.arrow,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.arrow,position:'absolute',adaptive:false,roundOffsets:roundOffsets})));}state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-placement':state.placement});}// eslint-disable-next-line import/no-unused-modules
|
||||
var computeStyles = {name:'computeStyles',enabled:true,phase:'beforeWrite',fn:computeStyles$1,data:{}};
|
||||
|
||||
var passive={passive:true};function effect(_ref){var state=_ref.state,instance=_ref.instance,options=_ref.options;var _options$scroll=options.scroll,scroll=_options$scroll===void 0?true:_options$scroll,_options$resize=options.resize,resize=_options$resize===void 0?true:_options$resize;var window=getWindow(state.elements.popper);var scrollParents=[].concat(state.scrollParents.reference,state.scrollParents.popper);if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.addEventListener('scroll',instance.update,passive);});}if(resize){window.addEventListener('resize',instance.update,passive);}return function(){if(scroll){scrollParents.forEach(function(scrollParent){scrollParent.removeEventListener('scroll',instance.update,passive);});}if(resize){window.removeEventListener('resize',instance.update,passive);}};}// eslint-disable-next-line import/no-unused-modules
|
||||
var eventListeners = {name:'eventListeners',enabled:true,phase:'write',fn:function fn(){},effect:effect,data:{}};
|
||||
@@ -161,26 +161,26 @@
|
||||
function computeAutoPlacement(state,options){if(options===void 0){options={};}var _options=options,placement=_options.placement,boundary=_options.boundary,rootBoundary=_options.rootBoundary,padding=_options.padding,flipVariations=_options.flipVariations,_options$allowedAutoP=_options.allowedAutoPlacements,allowedAutoPlacements=_options$allowedAutoP===void 0?placements:_options$allowedAutoP;var variation=getVariation(placement);var placements$1=variation?flipVariations?variationPlacements:variationPlacements.filter(function(placement){return getVariation(placement)===variation;}):basePlacements;var allowedPlacements=placements$1.filter(function(placement){return allowedAutoPlacements.indexOf(placement)>=0;});if(allowedPlacements.length===0){allowedPlacements=placements$1;}// $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...
|
||||
var overflows=allowedPlacements.reduce(function(acc,placement){acc[placement]=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding})[getBasePlacement(placement)];return acc;},{});return Object.keys(overflows).sort(function(a,b){return overflows[a]-overflows[b];});}
|
||||
|
||||
function getExpandedFallbackPlacements(placement){if(getBasePlacement(placement)===auto){return [];}var oppositePlacement=getOppositePlacement(placement);return [getOppositeVariationPlacement(placement),oppositePlacement,getOppositeVariationPlacement(oppositePlacement)];}function flip(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;if(state.modifiersData[name]._skip){return;}var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?true:_options$altAxis,specifiedFallbackPlacements=options.fallbackPlacements,padding=options.padding,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,_options$flipVariatio=options.flipVariations,flipVariations=_options$flipVariatio===void 0?true:_options$flipVariatio,allowedAutoPlacements=options.allowedAutoPlacements;var preferredPlacement=state.options.placement;var basePlacement=getBasePlacement(preferredPlacement);var isBasePlacement=basePlacement===preferredPlacement;var fallbackPlacements=specifiedFallbackPlacements||(isBasePlacement||!flipVariations?[getOppositePlacement(preferredPlacement)]:getExpandedFallbackPlacements(preferredPlacement));var placements=[preferredPlacement].concat(fallbackPlacements).reduce(function(acc,placement){return acc.concat(getBasePlacement(placement)===auto?computeAutoPlacement(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding,flipVariations:flipVariations,allowedAutoPlacements:allowedAutoPlacements}):placement);},[]);var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var checksMap=new Map();var makeFallbackChecks=true;var firstFittingPlacement=placements[0];for(var i=0;i<placements.length;i++){var placement=placements[i];var _basePlacement=getBasePlacement(placement);var isStartVariation=getVariation(placement)===start;var isVertical=[top,bottom].indexOf(_basePlacement)>=0;var len=isVertical?'width':'height';var overflow=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,altBoundary:altBoundary,padding:padding});var mainVariationSide=isVertical?isStartVariation?right:left:isStartVariation?bottom:top;if(referenceRect[len]>popperRect[len]){mainVariationSide=getOppositePlacement(mainVariationSide);}var altVariationSide=getOppositePlacement(mainVariationSide);var checks=[];if(checkMainAxis){checks.push(overflow[_basePlacement]<=0);}if(checkAltAxis){checks.push(overflow[mainVariationSide]<=0,overflow[altVariationSide]<=0);}if(checks.every(function(check){return check;})){firstFittingPlacement=placement;makeFallbackChecks=false;break;}checksMap.set(placement,checks);}if(makeFallbackChecks){// `2` may be desired in some cases – research later
|
||||
function getExpandedFallbackPlacements(placement){if(getBasePlacement(placement)===auto){return [];}var oppositePlacement=getOppositePlacement(placement);return [getOppositeVariationPlacement(placement),oppositePlacement,getOppositeVariationPlacement(oppositePlacement)];}function flip$1(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;if(state.modifiersData[name]._skip){return;}var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?true:_options$altAxis,specifiedFallbackPlacements=options.fallbackPlacements,padding=options.padding,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,_options$flipVariatio=options.flipVariations,flipVariations=_options$flipVariatio===void 0?true:_options$flipVariatio,allowedAutoPlacements=options.allowedAutoPlacements;var preferredPlacement=state.options.placement;var basePlacement=getBasePlacement(preferredPlacement);var isBasePlacement=basePlacement===preferredPlacement;var fallbackPlacements=specifiedFallbackPlacements||(isBasePlacement||!flipVariations?[getOppositePlacement(preferredPlacement)]:getExpandedFallbackPlacements(preferredPlacement));var placements=[preferredPlacement].concat(fallbackPlacements).reduce(function(acc,placement){return acc.concat(getBasePlacement(placement)===auto?computeAutoPlacement(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,padding:padding,flipVariations:flipVariations,allowedAutoPlacements:allowedAutoPlacements}):placement);},[]);var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var checksMap=new Map();var makeFallbackChecks=true;var firstFittingPlacement=placements[0];for(var i=0;i<placements.length;i++){var placement=placements[i];var _basePlacement=getBasePlacement(placement);var isStartVariation=getVariation(placement)===start;var isVertical=[top,bottom].indexOf(_basePlacement)>=0;var len=isVertical?'width':'height';var overflow=detectOverflow(state,{placement:placement,boundary:boundary,rootBoundary:rootBoundary,altBoundary:altBoundary,padding:padding});var mainVariationSide=isVertical?isStartVariation?right:left:isStartVariation?bottom:top;if(referenceRect[len]>popperRect[len]){mainVariationSide=getOppositePlacement(mainVariationSide);}var altVariationSide=getOppositePlacement(mainVariationSide);var checks=[];if(checkMainAxis){checks.push(overflow[_basePlacement]<=0);}if(checkAltAxis){checks.push(overflow[mainVariationSide]<=0,overflow[altVariationSide]<=0);}if(checks.every(function(check){return check;})){firstFittingPlacement=placement;makeFallbackChecks=false;break;}checksMap.set(placement,checks);}if(makeFallbackChecks){// `2` may be desired in some cases – research later
|
||||
var numberOfChecks=flipVariations?3:1;var _loop=function _loop(_i){var fittingPlacement=placements.find(function(placement){var checks=checksMap.get(placement);if(checks){return checks.slice(0,_i).every(function(check){return check;});}});if(fittingPlacement){firstFittingPlacement=fittingPlacement;return "break";}};for(var _i=numberOfChecks;_i>0;_i--){var _ret=_loop(_i);if(_ret==="break")break;}}if(state.placement!==firstFittingPlacement){state.modifiersData[name]._skip=true;state.placement=firstFittingPlacement;state.reset=true;}}// eslint-disable-next-line import/no-unused-modules
|
||||
var flip$1 = {name:'flip',enabled:true,phase:'main',fn:flip,requiresIfExists:['offset'],data:{_skip:false}};
|
||||
var flip = {name:'flip',enabled:true,phase:'main',fn:flip$1,requiresIfExists:['offset'],data:{_skip:false}};
|
||||
|
||||
function getSideOffsets(overflow,rect,preventedOffsets){if(preventedOffsets===void 0){preventedOffsets={x:0,y:0};}return {top:overflow.top-rect.height-preventedOffsets.y,right:overflow.right-rect.width+preventedOffsets.x,bottom:overflow.bottom-rect.height+preventedOffsets.y,left:overflow.left-rect.width-preventedOffsets.x};}function isAnySideFullyClipped(overflow){return [top,right,bottom,left].some(function(side){return overflow[side]>=0;});}function hide(_ref){var state=_ref.state,name=_ref.name;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var preventedOffsets=state.modifiersData.preventOverflow;var referenceOverflow=detectOverflow(state,{elementContext:'reference'});var popperAltOverflow=detectOverflow(state,{altBoundary:true});var referenceClippingOffsets=getSideOffsets(referenceOverflow,referenceRect);var popperEscapeOffsets=getSideOffsets(popperAltOverflow,popperRect,preventedOffsets);var isReferenceHidden=isAnySideFullyClipped(referenceClippingOffsets);var hasPopperEscaped=isAnySideFullyClipped(popperEscapeOffsets);state.modifiersData[name]={referenceClippingOffsets:referenceClippingOffsets,popperEscapeOffsets:popperEscapeOffsets,isReferenceHidden:isReferenceHidden,hasPopperEscaped:hasPopperEscaped};state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-reference-hidden':isReferenceHidden,'data-popper-escaped':hasPopperEscaped});}// eslint-disable-next-line import/no-unused-modules
|
||||
var hide$1 = {name:'hide',enabled:true,phase:'main',requiresIfExists:['preventOverflow'],fn:hide};
|
||||
function getSideOffsets(overflow,rect,preventedOffsets){if(preventedOffsets===void 0){preventedOffsets={x:0,y:0};}return {top:overflow.top-rect.height-preventedOffsets.y,right:overflow.right-rect.width+preventedOffsets.x,bottom:overflow.bottom-rect.height+preventedOffsets.y,left:overflow.left-rect.width-preventedOffsets.x};}function isAnySideFullyClipped(overflow){return [top,right,bottom,left].some(function(side){return overflow[side]>=0;});}function hide$1(_ref){var state=_ref.state,name=_ref.name;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var preventedOffsets=state.modifiersData.preventOverflow;var referenceOverflow=detectOverflow(state,{elementContext:'reference'});var popperAltOverflow=detectOverflow(state,{altBoundary:true});var referenceClippingOffsets=getSideOffsets(referenceOverflow,referenceRect);var popperEscapeOffsets=getSideOffsets(popperAltOverflow,popperRect,preventedOffsets);var isReferenceHidden=isAnySideFullyClipped(referenceClippingOffsets);var hasPopperEscaped=isAnySideFullyClipped(popperEscapeOffsets);state.modifiersData[name]={referenceClippingOffsets:referenceClippingOffsets,popperEscapeOffsets:popperEscapeOffsets,isReferenceHidden:isReferenceHidden,hasPopperEscaped:hasPopperEscaped};state.attributes.popper=Object.assign({},state.attributes.popper,{'data-popper-reference-hidden':isReferenceHidden,'data-popper-escaped':hasPopperEscaped});}// eslint-disable-next-line import/no-unused-modules
|
||||
var hide = {name:'hide',enabled:true,phase:'main',requiresIfExists:['preventOverflow'],fn:hide$1};
|
||||
|
||||
function distanceAndSkiddingToXY(placement,rects,offset){var basePlacement=getBasePlacement(placement);var invertDistance=[left,top].indexOf(basePlacement)>=0?-1:1;var _ref=typeof offset==='function'?offset(Object.assign({},rects,{placement:placement})):offset,skidding=_ref[0],distance=_ref[1];skidding=skidding||0;distance=(distance||0)*invertDistance;return [left,right].indexOf(basePlacement)>=0?{x:distance,y:skidding}:{x:skidding,y:distance};}function offset(_ref2){var state=_ref2.state,options=_ref2.options,name=_ref2.name;var _options$offset=options.offset,offset=_options$offset===void 0?[0,0]:_options$offset;var data=placements.reduce(function(acc,placement){acc[placement]=distanceAndSkiddingToXY(placement,state.rects,offset);return acc;},{});var _data$state$placement=data[state.placement],x=_data$state$placement.x,y=_data$state$placement.y;if(state.modifiersData.popperOffsets!=null){state.modifiersData.popperOffsets.x+=x;state.modifiersData.popperOffsets.y+=y;}state.modifiersData[name]=data;}// eslint-disable-next-line import/no-unused-modules
|
||||
var offset$1 = {name:'offset',enabled:true,phase:'main',requires:['popperOffsets'],fn:offset};
|
||||
function distanceAndSkiddingToXY(placement,rects,offset){var basePlacement=getBasePlacement(placement);var invertDistance=[left,top].indexOf(basePlacement)>=0?-1:1;var _ref=typeof offset==='function'?offset(Object.assign({},rects,{placement:placement})):offset,skidding=_ref[0],distance=_ref[1];skidding=skidding||0;distance=(distance||0)*invertDistance;return [left,right].indexOf(basePlacement)>=0?{x:distance,y:skidding}:{x:skidding,y:distance};}function offset$1(_ref2){var state=_ref2.state,options=_ref2.options,name=_ref2.name;var _options$offset=options.offset,offset=_options$offset===void 0?[0,0]:_options$offset;var data=placements.reduce(function(acc,placement){acc[placement]=distanceAndSkiddingToXY(placement,state.rects,offset);return acc;},{});var _data$state$placement=data[state.placement],x=_data$state$placement.x,y=_data$state$placement.y;if(state.modifiersData.popperOffsets!=null){state.modifiersData.popperOffsets.x+=x;state.modifiersData.popperOffsets.y+=y;}state.modifiersData[name]=data;}// eslint-disable-next-line import/no-unused-modules
|
||||
var offset = {name:'offset',enabled:true,phase:'main',requires:['popperOffsets'],fn:offset$1};
|
||||
|
||||
function popperOffsets(_ref){var state=_ref.state,name=_ref.name;// Offsets are the actual position the popper needs to have to be
|
||||
function popperOffsets$1(_ref){var state=_ref.state,name=_ref.name;// Offsets are the actual position the popper needs to have to be
|
||||
// properly positioned near its reference element
|
||||
// This is the most basic placement, and will be adjusted by
|
||||
// the modifiers in the next step
|
||||
state.modifiersData[name]=computeOffsets({reference:state.rects.reference,element:state.rects.popper,placement:state.placement});}// eslint-disable-next-line import/no-unused-modules
|
||||
var popperOffsets$1 = {name:'popperOffsets',enabled:true,phase:'read',fn:popperOffsets,data:{}};
|
||||
var popperOffsets = {name:'popperOffsets',enabled:true,phase:'read',fn:popperOffsets$1,data:{}};
|
||||
|
||||
function getAltAxis(axis){return axis==='x'?'y':'x';}
|
||||
|
||||
function preventOverflow(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?false:_options$altAxis,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,padding=options.padding,_options$tether=options.tether,tether=_options$tether===void 0?true:_options$tether,_options$tetherOffset=options.tetherOffset,tetherOffset=_options$tetherOffset===void 0?0:_options$tetherOffset;var overflow=detectOverflow(state,{boundary:boundary,rootBoundary:rootBoundary,padding:padding,altBoundary:altBoundary});var basePlacement=getBasePlacement(state.placement);var variation=getVariation(state.placement);var isBasePlacement=!variation;var mainAxis=getMainAxisFromPlacement(basePlacement);var altAxis=getAltAxis(mainAxis);var popperOffsets=state.modifiersData.popperOffsets;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var tetherOffsetValue=typeof tetherOffset==='function'?tetherOffset(Object.assign({},state.rects,{placement:state.placement})):tetherOffset;var normalizedTetherOffsetValue=typeof tetherOffsetValue==='number'?{mainAxis:tetherOffsetValue,altAxis:tetherOffsetValue}:Object.assign({mainAxis:0,altAxis:0},tetherOffsetValue);var offsetModifierState=state.modifiersData.offset?state.modifiersData.offset[state.placement]:null;var data={x:0,y:0};if(!popperOffsets){return;}if(checkMainAxis){var _offsetModifierState$;var mainSide=mainAxis==='y'?top:left;var altSide=mainAxis==='y'?bottom:right;var len=mainAxis==='y'?'height':'width';var offset=popperOffsets[mainAxis];var min$1=offset+overflow[mainSide];var max$1=offset-overflow[altSide];var additive=tether?-popperRect[len]/2:0;var minLen=variation===start?referenceRect[len]:popperRect[len];var maxLen=variation===start?-popperRect[len]:-referenceRect[len];// We need to include the arrow in the calculation so the arrow doesn't go
|
||||
function preventOverflow$1(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0?true:_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0?false:_options$altAxis,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,padding=options.padding,_options$tether=options.tether,tether=_options$tether===void 0?true:_options$tether,_options$tetherOffset=options.tetherOffset,tetherOffset=_options$tetherOffset===void 0?0:_options$tetherOffset;var overflow=detectOverflow(state,{boundary:boundary,rootBoundary:rootBoundary,padding:padding,altBoundary:altBoundary});var basePlacement=getBasePlacement(state.placement);var variation=getVariation(state.placement);var isBasePlacement=!variation;var mainAxis=getMainAxisFromPlacement(basePlacement);var altAxis=getAltAxis(mainAxis);var popperOffsets=state.modifiersData.popperOffsets;var referenceRect=state.rects.reference;var popperRect=state.rects.popper;var tetherOffsetValue=typeof tetherOffset==='function'?tetherOffset(Object.assign({},state.rects,{placement:state.placement})):tetherOffset;var normalizedTetherOffsetValue=typeof tetherOffsetValue==='number'?{mainAxis:tetherOffsetValue,altAxis:tetherOffsetValue}:Object.assign({mainAxis:0,altAxis:0},tetherOffsetValue);var offsetModifierState=state.modifiersData.offset?state.modifiersData.offset[state.placement]:null;var data={x:0,y:0};if(!popperOffsets){return;}if(checkMainAxis){var _offsetModifierState$;var mainSide=mainAxis==='y'?top:left;var altSide=mainAxis==='y'?bottom:right;var len=mainAxis==='y'?'height':'width';var offset=popperOffsets[mainAxis];var min$1=offset+overflow[mainSide];var max$1=offset-overflow[altSide];var additive=tether?-popperRect[len]/2:0;var minLen=variation===start?referenceRect[len]:popperRect[len];var maxLen=variation===start?-popperRect[len]:-referenceRect[len];// We need to include the arrow in the calculation so the arrow doesn't go
|
||||
// outside the reference bounds
|
||||
var arrowElement=state.elements.arrow;var arrowRect=tether&&arrowElement?getLayoutRect(arrowElement):{width:0,height:0};var arrowPaddingObject=state.modifiersData['arrow#persistent']?state.modifiersData['arrow#persistent'].padding:getFreshSideObject();var arrowPaddingMin=arrowPaddingObject[mainSide];var arrowPaddingMax=arrowPaddingObject[altSide];// If the reference length is smaller than the arrow length, we don't want
|
||||
// to include its full size in the calculation. If the reference is small
|
||||
@@ -188,7 +188,7 @@
|
||||
// reference is not overflowing as well (e.g. virtual elements with no
|
||||
// width or height)
|
||||
var arrowLen=within(0,referenceRect[len],arrowRect[len]);var minOffset=isBasePlacement?referenceRect[len]/2-additive-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis:minLen-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis;var maxOffset=isBasePlacement?-referenceRect[len]/2+additive+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis:maxLen+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis;var arrowOffsetParent=state.elements.arrow&&getOffsetParent(state.elements.arrow);var clientOffset=arrowOffsetParent?mainAxis==='y'?arrowOffsetParent.clientTop||0:arrowOffsetParent.clientLeft||0:0;var offsetModifierValue=(_offsetModifierState$=offsetModifierState==null?void 0:offsetModifierState[mainAxis])!=null?_offsetModifierState$:0;var tetherMin=offset+minOffset-offsetModifierValue-clientOffset;var tetherMax=offset+maxOffset-offsetModifierValue;var preventedOffset=within(tether?min(min$1,tetherMin):min$1,offset,tether?max(max$1,tetherMax):max$1);popperOffsets[mainAxis]=preventedOffset;data[mainAxis]=preventedOffset-offset;}if(checkAltAxis){var _offsetModifierState$2;var _mainSide=mainAxis==='x'?top:left;var _altSide=mainAxis==='x'?bottom:right;var _offset=popperOffsets[altAxis];var _len=altAxis==='y'?'height':'width';var _min=_offset+overflow[_mainSide];var _max=_offset-overflow[_altSide];var isOriginSide=[top,left].indexOf(basePlacement)!==-1;var _offsetModifierValue=(_offsetModifierState$2=offsetModifierState==null?void 0:offsetModifierState[altAxis])!=null?_offsetModifierState$2:0;var _tetherMin=isOriginSide?_min:_offset-referenceRect[_len]-popperRect[_len]-_offsetModifierValue+normalizedTetherOffsetValue.altAxis;var _tetherMax=isOriginSide?_offset+referenceRect[_len]+popperRect[_len]-_offsetModifierValue-normalizedTetherOffsetValue.altAxis:_max;var _preventedOffset=tether&&isOriginSide?withinMaxClamp(_tetherMin,_offset,_tetherMax):within(tether?_tetherMin:_min,_offset,tether?_tetherMax:_max);popperOffsets[altAxis]=_preventedOffset;data[altAxis]=_preventedOffset-_offset;}state.modifiersData[name]=data;}// eslint-disable-next-line import/no-unused-modules
|
||||
var preventOverflow$1 = {name:'preventOverflow',enabled:true,phase:'main',fn:preventOverflow,requiresIfExists:['offset']};
|
||||
var preventOverflow = {name:'preventOverflow',enabled:true,phase:'main',fn:preventOverflow$1,requiresIfExists:['offset']};
|
||||
|
||||
function getHTMLElementScroll(element){return {scrollLeft:element.scrollLeft,scrollTop:element.scrollTop};}
|
||||
|
||||
@@ -239,15 +239,15 @@
|
||||
// one.
|
||||
function runModifierEffects(){state.orderedModifiers.forEach(function(_ref){var name=_ref.name,_ref$options=_ref.options,options=_ref$options===void 0?{}:_ref$options,effect=_ref.effect;if(typeof effect==='function'){var cleanupFn=effect({state:state,name:name,instance:instance,options:options});var noopFn=function noopFn(){};effectCleanupFns.push(cleanupFn||noopFn);}});}function cleanupModifierEffects(){effectCleanupFns.forEach(function(fn){return fn();});effectCleanupFns=[];}return instance;};}
|
||||
|
||||
var defaultModifiers=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1,offset$1,flip$1,preventOverflow$1,arrow$1,hide$1];var createPopper=/*#__PURE__*/popperGenerator({defaultModifiers:defaultModifiers});// eslint-disable-next-line import/no-unused-modules
|
||||
var defaultModifiers=[eventListeners,popperOffsets,computeStyles,applyStyles,offset,flip,preventOverflow,arrow,hide];var createPopper=/*#__PURE__*/popperGenerator({defaultModifiers:defaultModifiers});// eslint-disable-next-line import/no-unused-modules
|
||||
|
||||
var Popper = /*#__PURE__*/Object.freeze({
|
||||
__proto__: null,
|
||||
afterMain: afterMain,
|
||||
afterRead: afterRead,
|
||||
afterWrite: afterWrite,
|
||||
applyStyles: applyStyles$1,
|
||||
arrow: arrow$1,
|
||||
applyStyles: applyStyles,
|
||||
arrow: arrow,
|
||||
auto: auto,
|
||||
basePlacements: basePlacements,
|
||||
beforeMain: beforeMain,
|
||||
@@ -255,22 +255,22 @@
|
||||
beforeWrite: beforeWrite,
|
||||
bottom: bottom,
|
||||
clippingParents: clippingParents,
|
||||
computeStyles: computeStyles$1,
|
||||
computeStyles: computeStyles,
|
||||
createPopper: createPopper,
|
||||
detectOverflow: detectOverflow,
|
||||
end: end,
|
||||
eventListeners: eventListeners,
|
||||
flip: flip$1,
|
||||
hide: hide$1,
|
||||
flip: flip,
|
||||
hide: hide,
|
||||
left: left,
|
||||
main: main,
|
||||
modifierPhases: modifierPhases,
|
||||
offset: offset$1,
|
||||
offset: offset,
|
||||
placements: placements,
|
||||
popper: popper,
|
||||
popperGenerator: popperGenerator,
|
||||
popperOffsets: popperOffsets$1,
|
||||
preventOverflow: preventOverflow$1,
|
||||
popperOffsets: popperOffsets,
|
||||
preventOverflow: preventOverflow,
|
||||
read: read,
|
||||
reference: reference,
|
||||
right: right,
|
||||
@@ -780,12 +780,14 @@
|
||||
* jQuery
|
||||
*/defineJQueryPlugin(Toast);
|
||||
|
||||
// Factory Function
|
||||
const ProductManager=(el=null,options={})=>{// === DOM & VARS =======
|
||||
const module=el||document.querySelector('.product-manager')||console.warn('Product Manager Element not found');if(!module)return;const DOM={module,table:module.querySelector('.table-products'),tbody:module.querySelector('tbody'),inputName:module.querySelector('.input-product-name'),inputPrice:module.querySelector('.input-product-price'),btnAdd:module.querySelector('.button-product-add'),templateRow:module.querySelector('.template-row')};const SERVER_BASE_URL='http://127.0.0.1:8000';// console.log(DOM);
|
||||
const module=el||document.querySelector('.product-manager')||console.warn('Product Manager Element not found');if(!module)return;const DOM={module,table:module.querySelector('.table-products'),tbody:module.querySelector('tbody'),inputName:module.querySelector('.input-product-name'),inputPrice:module.querySelector('.input-product-price'),btnAdd:module.querySelector('.button-product-add'),templateRow:module.querySelector('.template-row'),// Modal
|
||||
modalEdit:module.querySelector('.modal-edit'),formEdit:module.querySelector('.form-product-edit'),inputEditName:module.querySelector('.input-edit-name'),inputEditPrice:module.querySelector('.input-edit-price'),inputEditId:module.querySelector('.input-edit-id'),inputEditPosition:module.querySelector('.input-edit-position'),btnUpdate:module.querySelector('.button-product-update')};const SERVER_BASE_URL='http://127.0.0.1:8000';const bsModalEdit=new Modal(DOM.modalEdit,{backdrop:'static',keyboard:true});// console.log(DOM);
|
||||
// === INIT =============
|
||||
const init=()=>{// Funktionsaufrufe zu beginn der Anwendung
|
||||
initProducts();DOM.btnAdd.disabled=true;// Event-Lauscher zu beginn der Anwendung
|
||||
DOM.btnAdd.addEventListener('click',onClickAdd);window.addEventListener('keyup',onKeyUp);};// === EVENTHANDLER =====
|
||||
DOM.btnAdd.addEventListener('click',onClickAdd);DOM.formEdit.addEventListener('submit',onSubmitEdit);window.addEventListener('keyup',onKeyUp);};// === EVENTHANDLER =====
|
||||
const onKeyUp=e=>{DOM.btnAdd.disabled=!(DOM.inputName.value!==''&&DOM.inputPrice.value!=='');// if (DOM.inputName.value !== '' && DOM.inputPrice.value !== '') {
|
||||
// DOM.btnAdd.disabled = false;
|
||||
// } else {
|
||||
@@ -794,7 +796,13 @@
|
||||
};const onClickAdd=e=>{const product={name:DOM.inputName.value,//
|
||||
price:Number(DOM.inputPrice.valueAsNumber)};// async API request
|
||||
createProduct(product).then(data=>{console.log(data);if(data.success){loadProducts();resetInputFields();disableNonFunctionalButtons();}});// addProduct(product);
|
||||
};const onClickRemove=e=>{const btn=e.currentTarget;const currentRow=parents(btn,'tr')[0];// btn.closest('tr'); // btn.parentNode.parentNode;
|
||||
};const onSubmitEdit=e=>{e.preventDefault();// Standardverhalten unterbinden (Modal Form nicht versenden)
|
||||
const product={name:DOM.inputEditName.value,price:Number(Number(DOM.inputEditPrice.value).toFixed(2)),_id:DOM.inputEditId.value,position:parseInt(DOM.inputEditPosition.value)};// console.log(Object.fromEntries(new FormData(DOM.formEdit)));
|
||||
console.log(product);DOM.btnUpdate.querySelector('i').classList.add('fa-spin');// async Fetch Request
|
||||
updateProduct(product).then(data=>{console.log(data);if(data.success){DOM.btnUpdate.querySelector('i').classList.remove('fa-spin');resetInputFields();bsModalEdit.hide();loadProducts();}});};const onClickEdit=e=>{const btn=e.currentTarget;const currentRow=parents(btn,'tr')[0];// btn.closest('tr'); // btn.parentNode.parentNode;
|
||||
const id=currentRow.dataset.id;// async API request
|
||||
fetchProduct(id).then(data=>{// console.log(data);
|
||||
showModalEdit(data);});};const onClickRemove=e=>{const btn=e.currentTarget;const currentRow=parents(btn,'tr')[0];// btn.closest('tr'); // btn.parentNode.parentNode;
|
||||
currentRow.remove();// currentRow.parentNode.removeChild(currentRow); // IE11 support
|
||||
disableNonFunctionalButtons();};const onClickMoveUp=e=>{const btn=e.currentTarget;const currentRow=parents(btn,'tr')[0];currentRow.previousElementSibling.before(currentRow);// DOM.tbody.insertBefore(currentRow, currentRow.previousElementSibling);
|
||||
disableNonFunctionalButtons();};const onClickMoveDown=e=>{const btn=e.currentTarget;const currentRow=parents(btn,'tr')[0];currentRow.nextElementSibling.after(currentRow);// DOM.tbody.insertBefore(currentRow, currentRow.nextElementSibling.nextElementSibling);
|
||||
@@ -820,11 +828,24 @@
|
||||
// (B)READ - Browse - auslesen aller Produkte
|
||||
const fetchProducts=async()=>{try{const response=await fetch(`${SERVER_BASE_URL}/api/products`);// HTTP-Request URL
|
||||
if(!response.ok){throw new Error('Fetch went wrong.');}const data=await response.json();// HTTP-Response-Body in JS-Objekt geparsed -> Promise
|
||||
return data;}catch(error){console.error(error);throw error;}};// HTTP - Methode - GET
|
||||
// C(R)UD - Read
|
||||
// B(R)EAD - Read - auslesen eines Produkts
|
||||
const fetchProduct=async id=>{try{const response=await fetch(`${SERVER_BASE_URL}/api/products/${id}`);// HTTP-Request URL
|
||||
if(!response.ok){throw new Error('Fetch went wrong.');}const data=await response.json();// HTTP-Response-Body in JS-Objekt geparsed -> Promise
|
||||
return data;}catch(error){console.error(error);throw error;}};// HTTP - Methode - PUT
|
||||
// CR(U)D - Update
|
||||
// BR(E)AD - Edit - aktualisieren eines Produkts
|
||||
const updateProduct=async product=>{try{const response=await fetch(`${SERVER_BASE_URL}/api/products`,{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(product)});// HTTP-Request URL
|
||||
if(!response.ok){throw new Error('Fetch went wrong.');}const data=await response.json();// HTTP-Response-Body in JS-Objekt geparsed -> Promise
|
||||
return data;}catch(error){console.error(error);throw error;}};// === FUNCTIONS ========
|
||||
const initProducts=()=>{fetchProducts().then(products=>{products.forEach(addProduct);disableNonFunctionalButtons();});};const loadProducts=()=>{DOM.tbody.innerHTML='';fetchProducts().then(data=>{// TODO: add fade Animation
|
||||
data.forEach(addProduct);disableNonFunctionalButtons();});};const addProduct=product=>{const{name,price}=product;// https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/template#anwendungshinweise
|
||||
const trEl=DOM.templateRow.content.firstElementChild.cloneNode(true);const tdNameEl=trEl.querySelector('.td-name');const tdPriceEl=trEl.querySelector('.td-price');const btnDragEl=trEl.querySelector('.button-product-drag');const btnRemoveEl=trEl.querySelector('.button-product-remove');const btnMoveUpEl=trEl.querySelector('.button-product-move-up');const btnMoveDownEl=trEl.querySelector('.button-product-move-down');// Drag 'n Drop hinzufügen.
|
||||
btnDragEl.addEventListener('mousedown',onMouseDownDrag);btnDragEl.addEventListener('mouseup',onMouseUpDrag);trEl.addEventListener('dragstart',onDragStart);trEl.addEventListener('dragover',onDragOver);trEl.addEventListener('drop',onDrop);tdNameEl.textContent=name;tdPriceEl.textContent=Number(price).toFixed(2);btnRemoveEl.addEventListener('click',onClickRemove);btnMoveUpEl.addEventListener('click',onClickMoveUp);btnMoveDownEl.addEventListener('click',onClickMoveDown);DOM.tbody.appendChild(trEl);};const disableNonFunctionalButtons=()=>{DOM.tbody.querySelectorAll('tr').forEach(tr=>{tr.querySelector('.button-product-move-up').disabled=!tr.previousElementSibling;tr.querySelector('.button-product-move-down').disabled=!tr.nextElementSibling;});};const resetInputFields=()=>{DOM.inputName.value=DOM.inputPrice.value='';DOM.btnAdd.disabled=true;};// Helper
|
||||
data.forEach(addProduct);disableNonFunctionalButtons();});};const addProduct=product=>{const{name,price,_id:id}=product;// https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/template#anwendungshinweise
|
||||
const trEl=DOM.templateRow.content.firstElementChild.cloneNode(true);const tdNameEl=trEl.querySelector('.td-name');const tdPriceEl=trEl.querySelector('.td-price');const btnDragEl=trEl.querySelector('.button-product-drag');const btnEditEl=trEl.querySelector('.button-product-edit');const btnRemoveEl=trEl.querySelector('.button-product-remove');const btnMoveUpEl=trEl.querySelector('.button-product-move-up');const btnMoveDownEl=trEl.querySelector('.button-product-move-down');// Drag 'n Drop hinzufügen.
|
||||
btnDragEl.addEventListener('mousedown',onMouseDownDrag);btnDragEl.addEventListener('mouseup',onMouseUpDrag);// Id vom Produkt auf HTML data-Attribut ablegen
|
||||
trEl.dataset.id=id;// <tr data-id="..."></tr>
|
||||
trEl.addEventListener('dragstart',onDragStart);trEl.addEventListener('dragover',onDragOver);trEl.addEventListener('drop',onDrop);tdNameEl.textContent=name;tdPriceEl.textContent=Number(price).toFixed(2);btnEditEl.addEventListener('click',onClickEdit);btnRemoveEl.addEventListener('click',onClickRemove);btnMoveUpEl.addEventListener('click',onClickMoveUp);btnMoveDownEl.addEventListener('click',onClickMoveDown);DOM.tbody.appendChild(trEl);};const showModalEdit=product=>{const{name='',price=0,_id:id,position}=product;DOM.inputEditName.value=name;DOM.inputEditPrice.value=price;DOM.inputEditId.value=id;DOM.inputEditPosition.value=position;};const disableNonFunctionalButtons=()=>{DOM.tbody.querySelectorAll('tr').forEach(tr=>{tr.querySelector('.button-product-move-up').disabled=!tr.previousElementSibling;tr.querySelector('.button-product-move-down').disabled=!tr.nextElementSibling;});};const resetInputFields=()=>{DOM.inputName.value=DOM.inputPrice.value='';DOM.btnAdd.disabled=true;DOM.formEdit.reset();// Modal Formular leeren
|
||||
};// Helper
|
||||
// function parents(el, selector) {
|
||||
// const parents = [];
|
||||
// while ((el = el.parentNode) && el !== document) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
+50
-14
@@ -17,7 +17,7 @@
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<div class="col-12 col-md-6 col-lg-7">
|
||||
<input
|
||||
type="text"
|
||||
name="product-name"
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">€</span>
|
||||
<input
|
||||
type="number"
|
||||
name="prodcut-price"
|
||||
@@ -36,6 +35,7 @@
|
||||
aria-label="Product price"
|
||||
min="0"
|
||||
step="0.01" />
|
||||
<span class="input-group-text">€</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg">
|
||||
@@ -64,7 +64,7 @@
|
||||
<button
|
||||
class="btn btn-sm btn-primary button-product-edit"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#exampleModal">
|
||||
data-bs-target="#modal-product-edit">
|
||||
<i class="fas fa-pen"></i>
|
||||
<span class="visually-hidden">Edit Product</span>
|
||||
</button>
|
||||
@@ -86,25 +86,61 @@
|
||||
|
||||
<!-- ▼ Modal Edit Product ▼ -->
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
|
||||
Launch demo modal
|
||||
</button>
|
||||
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
|
||||
<div
|
||||
class="modal fade modal-edit"
|
||||
id="modal-product-edit"
|
||||
tabindex="-1"
|
||||
aria-labelledby="modal-product-edit-label"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
|
||||
<h1 class="modal-title fs-5" id="modal-product-edit-label">Edit Product</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">...</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary">Save changes</button>
|
||||
</div>
|
||||
|
||||
<form class="form-product-edit" method="post">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8">
|
||||
<div class="mb-3">
|
||||
<label for="input-edit-name" class="form-label">Product Name</label>
|
||||
<input type="text" id="input-edit-name" class="form-control input-edit-name" name="name" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md">
|
||||
<div class="mb-3">
|
||||
<label for="input-edit-price" class="form-label">Product price</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
step="0.01"
|
||||
min="0"
|
||||
id="input-edit-price"
|
||||
class="form-control input-edit-price"
|
||||
name="price" />
|
||||
<span class="input-group-text">€</span>
|
||||
</div>
|
||||
<input type="hidden" name="id" class="input-edit-id" />
|
||||
<input type="hidden" name="position" class="input-edit-position" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary button-product-update">
|
||||
<i class="fas fa-arrow-rotate-right"></i>
|
||||
Update Product
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ▲ /Modal Edit PRoduct ▲ -->
|
||||
<!-- ▲ /Modal Edit Product ▲ -->
|
||||
|
||||
<!-- ▼ Dialog Edit Product ▼ -->
|
||||
<!-- <button type="button" class="btn-solid theme-primary" data-bs-toggle="dialog" data-bs-target="#slideDownDialog">
|
||||
|
||||
+124
-2
@@ -1,5 +1,7 @@
|
||||
import { parents } from '../utils/helpers.js';
|
||||
import 'bootstrap';
|
||||
|
||||
import { Modal } from 'bootstrap';
|
||||
//import 'bootstrap';
|
||||
|
||||
// Factory Function
|
||||
const ProductManager = (el = null, options = {}) => {
|
||||
@@ -17,10 +19,24 @@ const ProductManager = (el = null, options = {}) => {
|
||||
inputPrice: module.querySelector('.input-product-price'),
|
||||
btnAdd: module.querySelector('.button-product-add'),
|
||||
templateRow: module.querySelector('.template-row'),
|
||||
|
||||
// Modal
|
||||
modalEdit: module.querySelector('.modal-edit'),
|
||||
formEdit: module.querySelector('.form-product-edit'),
|
||||
inputEditName: module.querySelector('.input-edit-name'),
|
||||
inputEditPrice: module.querySelector('.input-edit-price'),
|
||||
inputEditId: module.querySelector('.input-edit-id'),
|
||||
inputEditPosition: module.querySelector('.input-edit-position'),
|
||||
btnUpdate: module.querySelector('.button-product-update'),
|
||||
};
|
||||
|
||||
const SERVER_BASE_URL = 'http://127.0.0.1:8000';
|
||||
|
||||
const bsModalEdit = new Modal(DOM.modalEdit, {
|
||||
backdrop: 'static',
|
||||
keyboard: true,
|
||||
});
|
||||
|
||||
// console.log(DOM);
|
||||
|
||||
// === INIT =============
|
||||
@@ -30,6 +46,8 @@ const ProductManager = (el = null, options = {}) => {
|
||||
DOM.btnAdd.disabled = true;
|
||||
// Event-Lauscher zu beginn der Anwendung
|
||||
DOM.btnAdd.addEventListener('click', onClickAdd);
|
||||
|
||||
DOM.formEdit.addEventListener('submit', onSubmitEdit);
|
||||
window.addEventListener('keyup', onKeyUp);
|
||||
};
|
||||
|
||||
@@ -62,6 +80,45 @@ const ProductManager = (el = null, options = {}) => {
|
||||
// addProduct(product);
|
||||
};
|
||||
|
||||
const onSubmitEdit = (e) => {
|
||||
e.preventDefault(); // Standardverhalten unterbinden (Modal Form nicht versenden)
|
||||
|
||||
const product = {
|
||||
name: DOM.inputEditName.value,
|
||||
price: Number(Number(DOM.inputEditPrice.value).toFixed(2)),
|
||||
_id: DOM.inputEditId.value,
|
||||
position: parseInt(DOM.inputEditPosition.value),
|
||||
};
|
||||
|
||||
// console.log(Object.fromEntries(new FormData(DOM.formEdit)));
|
||||
|
||||
console.log(product);
|
||||
|
||||
DOM.btnUpdate.querySelector('i').classList.add('fa-spin');
|
||||
// async Fetch Request
|
||||
updateProduct(product).then((data) => {
|
||||
console.log(data);
|
||||
if (data.success) {
|
||||
DOM.btnUpdate.querySelector('i').classList.remove('fa-spin');
|
||||
resetInputFields();
|
||||
bsModalEdit.hide();
|
||||
loadProducts();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onClickEdit = (e) => {
|
||||
const btn = e.currentTarget;
|
||||
const currentRow = parents(btn, 'tr')[0]; // btn.closest('tr'); // btn.parentNode.parentNode;
|
||||
const id = currentRow.dataset.id;
|
||||
|
||||
// async API request
|
||||
fetchProduct(id).then((data) => {
|
||||
// console.log(data);
|
||||
showModalEdit(data);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickRemove = (e) => {
|
||||
const btn = e.currentTarget;
|
||||
const currentRow = parents(btn, 'tr')[0]; // btn.closest('tr'); // btn.parentNode.parentNode;
|
||||
@@ -93,11 +150,13 @@ const ProductManager = (el = null, options = {}) => {
|
||||
const currentRow = parents(btn, 'tr')[0]; // btn.closest('tr'); // btn.parentNode.parentNode;
|
||||
currentRow.draggable = true; // => <tr draggable="true" >...</tr>
|
||||
};
|
||||
|
||||
const onMouseUpDrag = (e) => {
|
||||
const btn = e.currentTarget;
|
||||
const currentRow = parents(btn, 'tr')[0]; // btn.closest('tr'); // btn.parentNode.parentNode;
|
||||
currentRow.draggable = false; // => <tr draggable="false" >...</tr>
|
||||
};
|
||||
|
||||
const onDragStart = (e) => {
|
||||
// console.log('DragEvent: ', e);
|
||||
const currentRow = e.currentTarget;
|
||||
@@ -107,9 +166,11 @@ const ProductManager = (el = null, options = {}) => {
|
||||
|
||||
// console.log('tr reference index: ', idx);
|
||||
};
|
||||
|
||||
const onDragOver = (e) => {
|
||||
e.preventDefault(); // WICHTIG: sonst funktioniet drop-EventHandler nicht
|
||||
};
|
||||
|
||||
const onDrop = (e) => {
|
||||
const currentRow = e.currentTarget; // <- Zielzeile, aud die gedroppt wird
|
||||
const targetIdx = [...currentRow.parentNode.children].indexOf(currentRow);
|
||||
@@ -179,6 +240,50 @@ const ProductManager = (el = null, options = {}) => {
|
||||
}
|
||||
};
|
||||
|
||||
// HTTP - Methode - GET
|
||||
// C(R)UD - Read
|
||||
// B(R)EAD - Read - auslesen eines Produkts
|
||||
const fetchProduct = async (id) => {
|
||||
try {
|
||||
const response = await fetch(`${SERVER_BASE_URL}/api/products/${id}`); // HTTP-Request URL
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Fetch went wrong.');
|
||||
}
|
||||
const data = await response.json(); // HTTP-Response-Body in JS-Objekt geparsed -> Promise
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// HTTP - Methode - PUT
|
||||
// CR(U)D - Update
|
||||
// BR(E)AD - Edit - aktualisieren eines Produkts
|
||||
const updateProduct = async (product) => {
|
||||
try {
|
||||
const response = await fetch(`${SERVER_BASE_URL}/api/products`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(product),
|
||||
}); // HTTP-Request URL
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Fetch went wrong.');
|
||||
}
|
||||
const data = await response.json(); // HTTP-Response-Body in JS-Objekt geparsed -> Promise
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// === FUNCTIONS ========
|
||||
const initProducts = () => {
|
||||
fetchProducts().then((products) => {
|
||||
@@ -197,7 +302,7 @@ const ProductManager = (el = null, options = {}) => {
|
||||
};
|
||||
|
||||
const addProduct = (product) => {
|
||||
const { name, price } = product;
|
||||
const { name, price, _id: id } = product;
|
||||
|
||||
// https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/template#anwendungshinweise
|
||||
const trEl = DOM.templateRow.content.firstElementChild.cloneNode(true);
|
||||
@@ -205,6 +310,7 @@ const ProductManager = (el = null, options = {}) => {
|
||||
const tdNameEl = trEl.querySelector('.td-name');
|
||||
const tdPriceEl = trEl.querySelector('.td-price');
|
||||
const btnDragEl = trEl.querySelector('.button-product-drag');
|
||||
const btnEditEl = trEl.querySelector('.button-product-edit');
|
||||
const btnRemoveEl = trEl.querySelector('.button-product-remove');
|
||||
const btnMoveUpEl = trEl.querySelector('.button-product-move-up');
|
||||
const btnMoveDownEl = trEl.querySelector('.button-product-move-down');
|
||||
@@ -213,12 +319,16 @@ const ProductManager = (el = null, options = {}) => {
|
||||
btnDragEl.addEventListener('mousedown', onMouseDownDrag);
|
||||
btnDragEl.addEventListener('mouseup', onMouseUpDrag);
|
||||
|
||||
// Id vom Produkt auf HTML data-Attribut ablegen
|
||||
trEl.dataset.id = id; // <tr data-id="..."></tr>
|
||||
|
||||
trEl.addEventListener('dragstart', onDragStart);
|
||||
trEl.addEventListener('dragover', onDragOver);
|
||||
trEl.addEventListener('drop', onDrop);
|
||||
|
||||
tdNameEl.textContent = name;
|
||||
tdPriceEl.textContent = Number(price).toFixed(2);
|
||||
btnEditEl.addEventListener('click', onClickEdit);
|
||||
btnRemoveEl.addEventListener('click', onClickRemove);
|
||||
btnMoveUpEl.addEventListener('click', onClickMoveUp);
|
||||
btnMoveDownEl.addEventListener('click', onClickMoveDown);
|
||||
@@ -226,6 +336,16 @@ const ProductManager = (el = null, options = {}) => {
|
||||
DOM.tbody.appendChild(trEl);
|
||||
};
|
||||
|
||||
const showModalEdit = (product) => {
|
||||
const { name = '', price = 0, _id: id, position } = product;
|
||||
|
||||
DOM.inputEditName.value = name;
|
||||
DOM.inputEditPrice.value = price;
|
||||
|
||||
DOM.inputEditId.value = id;
|
||||
DOM.inputEditPosition.value = position;
|
||||
};
|
||||
|
||||
const disableNonFunctionalButtons = () => {
|
||||
DOM.tbody.querySelectorAll('tr').forEach((tr) => {
|
||||
tr.querySelector('.button-product-move-up').disabled = !tr.previousElementSibling;
|
||||
@@ -236,6 +356,8 @@ const ProductManager = (el = null, options = {}) => {
|
||||
const resetInputFields = () => {
|
||||
DOM.inputName.value = DOM.inputPrice.value = '';
|
||||
DOM.btnAdd.disabled = true;
|
||||
|
||||
DOM.formEdit.reset(); // Modal Formular leeren
|
||||
};
|
||||
|
||||
// Helper
|
||||
|
||||
+50
-14
@@ -55,7 +55,7 @@
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<div class="col-12 col-md-6 col-lg-7">
|
||||
<input
|
||||
type="text"
|
||||
name="product-name"
|
||||
@@ -65,7 +65,6 @@
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">€</span>
|
||||
<input
|
||||
type="number"
|
||||
name="prodcut-price"
|
||||
@@ -74,6 +73,7 @@
|
||||
aria-label="Product price"
|
||||
min="0"
|
||||
step="0.01" />
|
||||
<span class="input-group-text">€</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg">
|
||||
@@ -102,7 +102,7 @@
|
||||
<button
|
||||
class="btn btn-sm btn-primary button-product-edit"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#exampleModal">
|
||||
data-bs-target="#modal-product-edit">
|
||||
<i class="fas fa-pen"></i>
|
||||
<span class="visually-hidden">Edit Product</span>
|
||||
</button>
|
||||
@@ -124,25 +124,61 @@
|
||||
|
||||
<!-- ▼ Modal Edit Product ▼ -->
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
|
||||
Launch demo modal
|
||||
</button>
|
||||
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
|
||||
<div
|
||||
class="modal fade modal-edit"
|
||||
id="modal-product-edit"
|
||||
tabindex="-1"
|
||||
aria-labelledby="modal-product-edit-label"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
|
||||
<h1 class="modal-title fs-5" id="modal-product-edit-label">Edit Product</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">...</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary">Save changes</button>
|
||||
</div>
|
||||
|
||||
<form class="form-product-edit" method="post">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8">
|
||||
<div class="mb-3">
|
||||
<label for="input-edit-name" class="form-label">Product Name</label>
|
||||
<input type="text" id="input-edit-name" class="form-control input-edit-name" name="name" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md">
|
||||
<div class="mb-3">
|
||||
<label for="input-edit-price" class="form-label">Product price</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
step="0.01"
|
||||
min="0"
|
||||
id="input-edit-price"
|
||||
class="form-control input-edit-price"
|
||||
name="price" />
|
||||
<span class="input-group-text">€</span>
|
||||
</div>
|
||||
<input type="hidden" name="id" class="input-edit-id" />
|
||||
<input type="hidden" name="position" class="input-edit-position" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary button-product-update">
|
||||
<i class="fas fa-arrow-rotate-right"></i>
|
||||
Update Product
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ▲ /Modal Edit PRoduct ▲ -->
|
||||
<!-- ▲ /Modal Edit Product ▲ -->
|
||||
|
||||
<!-- ▼ Dialog Edit Product ▼ -->
|
||||
<!-- <button type="button" class="btn-solid theme-primary" data-bs-toggle="dialog" data-bs-target="#slideDownDialog">
|
||||
|
||||
Reference in New Issue
Block a user