draggable element becomes null - javascript

I have made this which is based of a tutorial i followed and i've tried to add some more functionality to it myself, so i can add tasks when i click on the button, which works fine, but the issue occurs when i try to drag one of the added elements, it loses the value and just prints null and also loses the class i've assigned to it.
function addItem() {
var newItem = document.createElement("div");
newItem.className = "list-item";
newItem.innerHTML = "Hello World!";
newItem.draggable = true;
document.getElementById("content").appendChild(newItem).appendChild(text);
}
My end goal is to make it look like the hard coded task and im sure i can achieve this, but i just dont understand why the value and class is lost when i drag the element.

Looking at the HTML, it looks like you're close, but the elements you're generating with your add item button aren't structurally the same as the one that you're trying to imitate. The "standard" item has an nested inside it - not just simply inner html/text.

Related

How to swap <div> elements by using "mouseover" event?

let wrapperSt = document.querySelector(".wrapper");
for(i=0; i<100; i++){
let divGroup = document.createElement('div');
wrapperSt.append(divGroup);
divGroup.className= 'pixel';
divGroup.textContent= '';
}
I've created the div element called "pixel" by using loop because, i need couple hundreds of them. (I'll use them as a little boxes that could change color)
But, i want these boxes ("pixel" div) to turn brown and sustain (style.backgroundColor ="brown";)
So, i created another div that will replace the previous div ("pixel").
let selectPx = document.getElementsByClassName("pixel");
selectPx.addEventListener("mouseover", function(){
let pxChange = createElement("div");
//This is where i got stuck!
})
I could not finish my code, i found it a bit complicated even if it is probably something very simple.
Any suggestions or piece of information would be very helpful. Thank you.
Not sure exactly what you are trying to do... I think you are trying to change the color of the div that your mouse is over? If so, you have a couple of issues with your code. Instead of adding the event listener to the list of divs, you need to add it to each one individually. Also, you should only need to change the background color of each element instead of creating a new one each time.
let selectPx = document.querySelectorAll(".pixel");
selectPx.forEach(pixel => {
pixel.addEventListener("mouseover", () => {
pixel.style.backgroundColor = "brown";
});
});
I'm not sure why you have to create a new div inside the first one. In your code, when you trigger the mouseover event you can get the div under the mouse and apply the style to it:
let selectPx = document.getElementsByClassName("pixel");
selectPx.addEventListener("mouseover", function(evt){
let divUnderMouse = evt.target;
divUnderMouse.style.backgroundColor ="brown";
})
I haven't tried it but it should work

How can I override javascript click event for only certain elements?

I'm working off of a tutorial from codrops. There is a hover event for each item, as well as a click event that triggers an anime.js function.
I'm trying to work this so certain items (grid cells) don't trigger the anime.js function when clicked, but the hover function still works.
I've tried simple css pointer-events, but that disables the hover function.
I've constructing the two groups as separate items in JS, but then the animation doesn't work the same (it staggers the two different classes).
I've tried things to stop the default javascript behavior, but it seems to have no impact on the code.
Help!!!
I've made a functioning codepen - in the option there I'm trying to disable click event for any grid item with the id="noClick" - to no avail.
$('noClick').observe('click', function(event) {
Event.stop(event);
});
This is the primary function that creates the event
this.DOM.items.forEach((item, pos) => {
// The item's title.
const title = item.dataset.title;
// Show the title next to the cursor.
item.addEventListener('mouseenter', () => cursor.setTitle(title));
item.addEventListener('click', () => {
// Position of the clicked item
this.pos = pos;
this.title = title;
// Start the effect and show the content behind
this.showContent();
// Force to show the title next to the cursor (it might not update because of the grid animation - the item under the mouse can be a different one than the one the user moved the mouse to)
cursor.setTitle(title);
});
});
where 'item' is
this.DOM.grid = this.DOM.el.querySelector('.grid');
// Thr grid items
this.DOM.items = [...this.DOM.grid.children];
// totla number of grid items
this.itemsTotal = this.DOM.items.length;
I've tried to create multiple items
this.DOM.grid = this.DOM.el.querySelector('.grid');
this.DOM.yesClick = this.DOM.el.querySelector('.yes-click');
this.DOM.yesClickTwo = this.DOM.el.querySelector('.yes-click-2');
this.DOM.noClick = this.DOM.el.querySelector('.no-click');
// Thr grid items
this.DOM.items = [...this.DOM.yesClick.children, ...this.DOM.yesClickTwo.children];
this.DOM.itemsNo = [...this.DOM.noClick.children];
this.DOM.allItems = [...this.DOM.noClick.children, ...this.DOM.yesClick.children, ...this.DOM.yesClickTwo.children];
// totla number of grid items
this.itemsTotal = this.DOM.allItems.length;
This works, but messes with the animaton.
Here is the codepen
I feel this is really simple and I'm missing something. Looking to learn, so a push in the right direction or any help would be greatly appreciated!
1. You have multiple elements with the same ID. But ID attribute must be unique.
2. You used $('noClick'), but ID selector would look like #noClick
If you want to mark few elements, use a class and select them like .elementclass. It is possible for element to have multiple classes, separated by space.
Your selector doesn't seem correct so you either need #noClick or .noClick as the selector however you can stop the javascript from bubbling like this :-
$(".noClick").click(function(e) {
// Do something?
e.stopPropagation();
});

Reverting to original element ID

I have li blocks which onclick will change class ID as follows:
onclick = "document.getElementById('procblock1').id = 'procblock1Clicked';"
"document.getElementById('procblock2Clicked').id = 'procblock2';"
"document.getElementById('procblock3Clicked').id = 'procblock3';"
"document.getElementById('procblock4Clicked').id = 'procblock4';"
The line document.getElementById('procblock2Clicked').id = 'procblock2'; should revert any clicked elements (blocks) back to their original ID names.
The code works for changing the original id to the clicked id but doesn't have any effect in reverting previously clicked to the original as per lines 2,3 & 4.
I have searched hard for similar questions but can find nothing that covers this specific issue.
#Matthias - I acted upon your advice and came up with a very simplified jquery solution :
`$(function() {
$(".showinfo").click(function() { //using class instead of ID
$(".showinfo").removeClass("clicked"); //Remove all existing clicks
$(this).addClass("clicked"); //add the class to the clicked element });
});`
Posted solution in case anyone else has same query. Your help was appreciated.
If this really is part of the code you're using lines 2-4 won't work; onclick will only handle the first line. You should wrap it as a function to be called onclick, like onclick = "doStuff()" and add a function doStuff () {/* your code here */}. But that's just guessing as you only provide some part of the code in question.
In addition would be good to know what you want to achieve - in case you want to mark clicked elements, it would be a cleaner approach to add a class, e.g. "clicked" or "active", that you simply remove later on instead of changing ids.

Read more opens 1st one all the time

I've a page with about 10 short articles.
Each of them as a "Read More" button which when pressed displays hidden text
The issues I have at the moment is when I press the "Read More" on any of the 10 button it shows the 1st articles hidden content and not the selected one.
I think I need to set a unique ID to each article.. and the read more button be linked to it.. But I don't know how to set it.
I looked at this but couldn't get it working how to give a div tag a unique id using javascript
var WidgetContentHideDisplay = {
init:function() {
if ($('#content-display-hide').size() == 0) return;
$('.triggerable').click(function(e){
var element_id = $(this).attr('rel');
var element = $('#'+element_id);
element.toggle();
if (element.is(':visible')) {
$('.readmore').hide();
} else {
$('.readmore').show();
}
return false;
});
}
}
var div = documentElemnt("div");
div.id = "div_" + new Date().gettime().toString;
$(document).ready(function(){ WidgetContentHideDisplay.init(); });
OP Edit: Sorry, the original code wasn't in caps. I kept getting errors when trying to post, so I copied the code into Dreamweaver and it made it all caps for some reason.
Instead of selecting the element to toggle with an ID (i.e. $('#'+ELEMENT_ID)) you could setup a class for your item and use the class selection (e.g. $('.DETAILED-ARTICLE)') to select the child (or the brother, etc. depending how you built the HTML page).
In theory each ID should point to a single element but each class can be put to as many elements as you want.
If you're getting errors, read the errors and see what they are. Off of a quick read of your code, here are a couple things I noticed that will probably cause issues:
"documentElemnt" is misspelled, which will render it useless. Also, documentElement is a read-only property, not a function like you're using it.
toString is a function, not a property, without the parentheses (.toString()) it isn't going to function like you want it to.
Run the code, look at the errors in the console, and fix them. That's where you start.

Tracking changes in web application

I have an application in which the user needs to see the changes that have been made during the latest edit.
By changes I mean, the changes made in all inputs like a textarea, dropdowns.
I am trying to implement this by showing a background image on the right top and then when the user clicks this background image, a popup is shown which shows the difference.
I am using prototype 1.7.0.
My First question would be:-
1. What would be the best approach to implement this functionality?
2. Can I put a onClick on the background image?
There some functions in the jQuery library that I believe would be helpful to you. If you are using prototype, I would guess that there is some similar functionality you may utilize.
I would suggest writing some code like this:
var $input = $('input').add('textarea').add('select');
$input.each(function() {
var id = $(this).attr('id');
var value = $(this).val();
var hiddenId = 'hidden' + id;
var newHiddenInput = $("<input type='hidden'").val(value).attr('id',hiddenId);
$(this).after(newHiddenInput);
});
The above code will create a new hidden input for each input, textarea, and select on your page. It will have the same value as the input it duplicates. It will have an id equivalent to prepending the id with the word 'hidden'.
I don't know if you can attach a click handler to a background image. If your inputs are enclosed inside a <div>, you may be able to get the result you want by attaching the click handler to your div.
In any case, you should now have the old values where you can easily compare them to the user's input so that you can prepare a summary of the difference.
Prototype gives us the Hash class which is almost perfect for this but lacks a way of calculating the difference with another hash, so let's add that...
Hash.prototype.difference = function(hash)
{
var result = this.clone();
hash.each(function(pair) {
if (result.get(pair.key) === undefined)
// exists in hash but not in this
result.set(pair.key, pair.value);
else if (result.get(pair.key) == pair.value)
// no difference so remove from result
result.unset(pair.key);
// else exists in this but not in hash
});
return result;
};
This is no way to tell if an element was clicked on just it's background image - you can find out the coordinates where it was clicked but that is not foolproof, especially since CSS3 adds complications like multiple backgrounds and transitions. It is better to have an absolutely positioned element to act as a button.
$('button-element').observe('click', function() {
var form_values = $H($('form-id').serialize(true));
if (old_values) {
var differences = old_values.difference(form_values);
if (differences.size()) {
showDiffPopup(differences);
}
}
window.old_values = form_values;
});
// preset current values in advance
window.old_values = $H($('form-id').serialize(true));
All that remains is to implement showDiffPopup to show the calculated differences.

Categories