JavaScript class - Override class function when specified? - javascript

I have a JavaScript class with some functions in it. One of those functions is an drop event which handles dragging and dropping files into a area. As soon the client dropped a file, a function named onDrop should be executed.
This onDrop function is located inside the class and should only be executed when the user drops a file. However, I need an possiblty to override the default class function onDrop with an own specified function from the class instance constructor. But, when there is no own specified function, use the default onDrop class function.
One of the two problems I have right now is that the default class function onDrop is executed immediately after creating a new instance of the class (which is wrong because this function should only be executed when the user draggend and dropped a file).
The second problem I have is when an user dropped a file, the onDrop function is never executed because an error in the console, which tells that the function onDrop is undefined.
Obviously I'm doing something wrong here but at this time I don't know exactly what. Maybe someone can tell me more about this problem?
Let me explain this situation with the following code (and at the very bottom a codepen example)
class myClass
{
constructor(area, events)
{
this.events = Object.assign
({
ondrop: this.onDrop()
}, events);
area.addEventListener('dragover', ev =>
{
ev.preventDefault();
});
area.addEventListener('drop', ev =>
{
ev.preventDefault();
this.events.ondrop(ev);
});
}
onDrop(ev)
{
alert('This is the onDrop function from the class itself');
}
}
var area = document.getElementById('file-upload');
var events = {
// remove the comment tags to overwrite the default onDrop function from the class
//ondrop: function() {alert('This is the onDrop function from the instance')}
};
var instance = new myClass(area, events);
body {
font-family : sans-serif;
}
#file-drag {
border : 2px dashed #555;
border-radius : 7px;
color : #555;
cursor : pointer;
display : block;
font-weight : bold;
margin : 1em 0;
padding : 3em;
text-align : center;
transition : background 0.3s, color 0.3s;
}
#file-drag:hover {
background : #ddd;
}
#file-drag:hover,
#file-drag.hover {
border-color : #3070A5;
border-style : solid;
box-shadow : inset 0 3px 4px #888;
color : #3070A5;
}
#file-upload-form {
margin : auto;
width : 40%;
}
<div id="file-upload">
<label for="file-upload" id="file-drag">
Drag a file into this box
</label>
</div>
Full Codes in Codepen

Related

I'm trying to solve below challenge but stuck on function call in ADDEVENTLISTNER [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 months ago.
Improve this question
Challenge:
In this scenario we want the color of the circle to change depending on the type of cursor movement. Use the function toggleColor to turn the circle orange when the cursor moves onto it. Reuse the same function to turn it black when the cursor leaves it.
The tricky part is that you have to call toggleColor with different values for the parameter isEntering. Verify that your code is working by hovering the circle with the mouse cursor and leaving it again.
I tried to solve this challenge but it's showing an error. Where have I gone wrong?
My HTML HERE
<div id="element">
Hover Me
</div>
My JAVAScript here
const element = document.querySelector('#element');
const toggleColor = (isEntering) => {
element.style.background = isEntering ? 'orange' : 'black';
};
element.addEventListener('mouseover',toggleColor(value));
element.addEventListener('mouseout',toggleColor());
If you want to pass parameter to function which is being called on certain event you must call that function in anonymous funtion(). In your case By calling toggleColor(value) inside the anonymous function will do the work. Below is javascript style.
const element = document.querySelector('#element');
const toggleColor = (isEntering) => {
element.style.background = isEntering ? 'orange' : 'black';
};
element.addEventListener('mouseover', function(){
toggleColor(true);
});
element.addEventListener('mouseout', function(){
toggleColor(false);
});
#element{
position: relative;
height: 250px;
width: 250px;
background-color: #ddd;
}
<div id="element"></div>
You can achieve this with pure css by using :hover.
#element {
position: relative;
height: 250px;
width: 250px;
background-color: orange;
}
#element:hover{
background-color: black;
}
<div id="element"></div>
Your problem is already very obvious, you just want to add hover background effect to dom through mouse events. But the problem is that your side effect function is directly passed into the event callback. But your side-effects function explicitly needs a state tag. Used to determine whether the mouse has entered the away state. If you need to explicitly pass a parameter as an event callback, you should wrap your logic function toggleColor again. Because the event handler, by default, goes back to calling the event handler and passing the event object as the default parameter
just like do this
const element = document.querySelector("#element");
const toggleColor = (isEntering) => {
element.style.background = isEntering ? "orange" : "black";
};
element.addEventListener("mouseover", () => toggleColor(true));
element.addEventListener("mouseout", () => toggleColor(false));
The listener needs to be assigned a function that it can use. At the moment you're assigning the result of calling toggleColor to the listener instead. One way of achieving this is to return a new function from toggleColor.
const element = document.querySelector('#element');
const toggleColor = (value) => {
return function () {
element.className = value ? 'orange' : 'black';
}
};
element.addEventListener('mouseover', toggleColor(true));
element.addEventListener('mouseout', toggleColor(false));
#element { padding: 0.4em; }
#element:hover { cursor: pointer; }
.orange { background-color: orange; color: black; }
.black { background-color: black; color: white; }
<div id="element">Hover Me</div>

Drag and drop file to specific target

I have a set of elements of media files listed like this.
I want to upload a a media file from windows explorer to a specific target of this list(for eg- It should be possible to add file above 'Title A' or below 'Title A'... ). How to achieve this?I know how to upload a file and it is achievable for me if it's to add to the end of the list. What I don't get is how to get that specific position which I need to upload.
(If it's a DOM element, I could have used jQuery draggable droppble, but again it's not possible here! :(. )
I am using ember and I have created component and added it after each element
abc: $('<div class="bla"></div>'),
didInsertElement() {
this._super(...arguments);
var self = this;
$('.xyz').bind("dragenter", function (evt) {
event.preventDefault();
event.stopPropagation();
var targetElement = $(evt.target).prev();
var holder = self.get('abc');
targetElement.after(holder);
});
$('.xyz').bind("dragleave", function (evt) {
event.preventDefault();
$('.bla').detach();
});
$('.xyz').bind("drop", function (evt) {
event.preventDefault();
$('.bla').detach();
});
},
With this I could successfully add a div below the target element. But with 'dragleave' it's executing every time and hence it's detaching everytime and also if I don't want to drop it or drop outside the window, it's not detaching at all.(something like dragend?)
.bla{
position: relative;
clear: both;
cursor: default;
margin-top: 2px;
min-height: 32px;
line-height: 32px;
overflow: hidden;
background-color: white;
border: 1px solid #999;
}
Any help?!
Thank you.

Prevent label active state using javascript

I have a quite simple scenario where I am trying to prevent the orange background on mouse down:
document.querySelector('label').addEventListener('mousedown', (event) => {
console.log('mouse down')
event.preventDefault();
})
label:active {
background: orange;
}
<label>Press mouse down</label>
Unfortunately the event.preventDefault() has no effect and the label becomes orange. (Tested in Chrome and Safari and IE11)
Can anyone explain me the reason behind that or maybe tell me how to prevent the active state programatically without hacks?
Codepen: https://codepen.io/anon/pen/pPZVrO
It seems like an old issue. If you want, you can fix it, by using pointer-events property. Also, support for the same is pretty much decent (including IE11)
label:active {
background: orange;
}
label {
pointer-events: none;
}
<label>Press mouse down</label>
Make sure you have some class or an id declared on the label element so that you don't target all of them.
JavaScript Solution - Just giving a shot
The idea is to add a class on mousedown and override it with CSS class having an :active pseudo class, and later, remove the class on mouseup .. something like
var overrideActive = function() {
var labelElm = document.querySelector('label');
var bodyElm = document.querySelector('body');
function init() {
//on mousedown, add a class and override it with css
labelElm.addEventListener('mousedown', (event) => {
event.target.className = 'disable-active';
});
//onmouseout get rid of the class
bodyElm.addEventListener('mouseup', (event) => {
labelElm.classList.remove('disable-active');
});
}
return {
init: init
}
}();
overrideActive.init();
label:active {
background: orange;
}
.disable-active:active {
background-color: transparent;
}
<label>Press mouse down</label>
You can disable mouse events via css. Adding this CSS will will prevent the background from turning orange.
label {
pointer-events: none;
}
If you don't want to do it in every case, use a class and apply the noclick class only when needed (ie, as part react's render() method, or when the page is generated, depending on the framework you're using.
.noclick {
pointer-events: none;
}

Using event.className to change event color for ui-calendar

I am new to ui-calendar and am having some issues setting the event's className property in my code based upon a condition. I haven't been able to find may examples using className like this, but here is what I attempted in my project:
eventRender: function (event, element) {
if (event.HighPriority == 1) {
event.className ='highPriority';
}
},
In my css file I have:
.highPriority{
background-color: red;
color: white;
}
This line "event.className ='highPriority';" does not work. Has anyone done something similar with angular ui-calendar? Any help on the matter would be appreciated!
I opened an issue with ui-calendar on GitHub. Between this comment from vaHuntsMan:
eventRender is a callback. So you are changing the classname probably
too late. Try adding className when you create the event, before
adding it to the source array.
And this Stack Overflow post, I was able to get my CSS coloring properly.
ui-calendar setup:
events: function (start, end, timezone, callback) {
...
$http.get(url).success(function (result) {
$scope.myEvents = result.value;
for (var i = 0; i < $scope.myEvents.length; i++) {
...
if ($scope.myEvents[i].HighPriority) {
$scope.myEvents[i].className = ['highPriority'];
}
}
callback($scope.myEvents);
})
},
CSS:
.highPriority,
.highPriority div,
.highPriority span {
background-color: red; /* background color */
border-color: white; /* border color */
color: white; /* text color */
}

Style select box option:disabled when it's checked

In the image below, I want Exp. Year (the disabled option) to be grey on page load like a placeholder, and when an option is clicked (2016), I want it to turn to black. It is possible to do this without js?
JSFiddle
What is currently does:
What I want it to do: (Exp. Month is grey on page load, then 2016 is black on select)
.select-box {
border: 1px solid $ghBlack;
height: 36px;
background: transparent;
margin: 10px 0 14px 0;
color: #000;
}
option:disabled {
color: #a9a9a9;
}
option:not(:checked) {
color: #a9a9a9;
}
One way to do this is as follows:
// binding an anonymous function as the change-event handler:
$('select').change(function () {
// adjusting the 'color' property of the select element:
$(this).css('color', function () {
// caching the 'this' variable for efficiency (give repeated use):
var self = this,
// finding the options of the select element:
opts = self.options;
// getting the currently-selected option, and then checking if
// it's the default-selected option (returns a Boolean); if it is
// we set the colour to '#aaa', if not we set the colour to '#000':
return opts[self.selectedIndex].defaultSelected ? '#aaa' : '#000';
});
// triggering the change-event so that this runs on page-load:
}).change();
JS Fiddle demo.
Reference:
change().
css().
When you explained more what you try to do, then the answer is no, you can't do it without javascript, because the color of the main option is just one....its defined by this css selector
.select-box {
color: grey;
}
You can only change colors of the options (when the select is opened) - fiddle: http://jsfiddle.net/san6q621/

Categories

Resources