I recently tried to make a page that saves the input and displays it on the page. Everything works but i want to add a delete button at every input, which deletes only one input. I tried so many different ways, but none of them worked. If you have any idea how to solve this, I would be grateful.
Here is the code:
let savedinput = []
Localstoragesaves = localStorage.getItem("Zaznamki")
const Predpomnjenipodatki = JSON.parse(Localstoragesaves)
const DeleteButtonHTML = document.getElementById("izbrisi-gumb")
const userinput = document.getElementById("vnos-pr")
const inputsavebutton = document.getElementById("vnos-gumb")
const LabelHTML = document.getElementById("seznamzaznamkov")
const SaveTab = document.getElementById("zavihek-gumb")
const DeleteLast = document.getElementById("pocisti-zadnjo")
if (Localstoragesaves) {
savedinput = Predpomnjenipodatki
Render(savedinput)
}
DeleteLast.addEventListener('click', function(){
savedinput.pop()
Render(savedinput)
})
SaveTab.addEventListener('click',
function(){
browser.tabs.query({active: true, currentWindow: true}, function(tabs){
savedinput.push(tabs[0].url)
localStorage.setItem("Zaznamki", JSON.stringify(savedinput))
Render(savedinput)
console.log( localStorage.getItem("Zaznamki") )
})
})
function Render(parameter) {
let tabslabel = ""
for (i = 0; i < parameter.length; i++) {
tabslabel += `
<li>
<a href='${parameter[i]}' target='_blank'>${parameter[i]}</a>
</li>
`
}
LabelHTML.innerHTML = tabslabel
}
DeleteButtonHTML.addEventListener('dblclick',
function() {
localStorage.clear()
savedinput = []
LabelHTML.textContent = ''
})
inputsavebutton.addEventListener("click", function(){
const Vsebinavnosa = userinput.value
savedinput.push(Vsebinavnosa)
localStorage.setItem("Zaznamki", JSON.stringify(savedinput))
Render(savedinput)
userinput.value = ""
console.log( localStorage.getItem("Zaznamki") )
})
I solved this problem myself. I'm quite proud 😁. I want to thank you for your really quick responses even if I didnt get the solution here.
If someone has the same problem I had, I will tell you what I did.
In function render, I added a button with onclick function with argument, so that this new function which will be called will know which item from array needs to remove:
<button id="${parameter[i]}" onclick="Delete(${i})">Delete</button>
and then somewhere in this document I added this function which gets value from button click and knows which item from the array savedinput and localstorage needs to remove:
function Delete(parameter) {
mojizaznamki.splice(parameter, 1)
console.log(savedinput)
localStorage.setItem("Zaznamki", JSON.stringify(savedinput))
Render(savedinput)
}
Hope this helps others.
Greetings from Slovenia
Related
I have this to-do list where the to-Do list is saved in local storage, but I do not know how to add the storage value back in the page where it was before when the page is refreshed.
JS:
let inputField = document.querySelector('#inputField');
let submitBtn = document.querySelector('#submit-btn');
let toDoList = document.querySelector('#toDoList');
let toDoItems = document.querySelector('.toDoItems');
submitBtn.addEventListener('click', function(){
event.preventDefault();
let newLi = document.createElement('li');
newLi.className = 'toDoItems';
toDoList.appendChild(newLi);
newLi.textContent = inputField.value;
localStorage.setItem(inputField.value, inputField.value);
inputField.value = "";
});
toDoList.addEventListener('click', function(e){
e.target.remove();
});
What I have accomplished right now
So you have everything saved successfully, so now its just a matter of retrieving on load.
This documentation outlines how to use the window's load event. From there, inside that listener you can retrieve the data and display it using something like this:
for (let i = 0; i < localStorage.length; i++) {
let toDoString = localStorage.key(i)
// Do something similar to submitBtn.addEventListener('click', function(){})
// to create the list item and add it to the page
}
You want to store all the todoes in a single array, rather than as individual values. There are two reasons for this.
First, you can easily get and set the storage by using the same key.
Second, you can easily loop through and add them back, since they are already an array.
The example below won't work with local storage, as it's seen as not safe...
However, you should be able to copy the code and try it yourself.
const inputField = document.querySelector('#inputField');
const submitBtn = document.querySelector('#submitBtn');
const toDoList = document.querySelector('#toDoList');
const todoes = [];
function addTodo(todo) {
event.preventDefault();
let newLi = document.createElement('li');
newLi.className = 'toDoItems';
toDoList.appendChild(newLi);
newLi.textContent = inputField.value;
todoes.push(inputField.value)
//! -- commented out to not cause an error in stackoverflow --
// localStorage.setItem("todoes", JSON.stringify(todoes));
inputField.value = "";
}
submitBtn.addEventListener('click', addTodo);
toDoList.addEventListener('click', function(e) {
e.target.remove();
});
window.addEventListener('load', (event) => {
console.log('page is fully loaded');
//! -- commented out to not cause an error in stackoverflow --
// todoes = JSON.parse(localStorage.getitem("todoes"));
// todoes.forEach(todo => addTodo(todo));
});
<input id="inputField" type="text" placeholder="What to do?" />
<button id="submitBtn">ADD</button>
<ul id="toDoList"></ul>
I have some code that unpacks an array and returns an array of JSX elements. This works fine, however, when one element is clicked, the "selectedEl" css class is removed from all other elements.
I'm pretty sure I've just made some stupid mistake but I can't seem to figure it out. Thanks
Code that unpacks the array and assigns onClick method:
function UnpackReccArray() {
const renderArray = []
for (let renderEl = 0; renderEl < self.state.capMethod; renderEl++) {
renderArray.push(
<span className="topicElement" onClick={self.pushToChosen.bind(this, self.state.reccDataQuery[renderEl].topicID, renderEl + "topicEl")} id={renderEl + "topicEl"}>
<p className="fontLibre">{self.state.reccDataQuery[renderEl].displayName}</p>
</span>
)
if (renderEl + 1 === self.state.capMethod) {
return (
<self.ResultRender title="Popular Subjects" renderContent={renderArray} />
)
}
}
}
Code that handles onClick function
pushToChosen = (id, elID) => {
const self = this
const localChoseArray = this.state.subjectChosenArray
const index = localChoseArray.indexOf(id.toString())
if (index > -1) {
localChoseArray.splice(index, 1);
self.setState({
subjectChosenArray: localChoseArray
}, () => {
document.getElementById(elID).classList.remove("selectedEl")
})
} else {
self.setState({
subjectChosenArray: [...this.state.subjectChosenArray, id.toString()]
}, () => {
document.getElementById(elID).classList.add("selectedEl")
})
}
document.getElementById(elID).classList.toggle("selectedEl")
}
GIF of the code in action
Thanks!
i didn't fully understand the code but it seems that the toggle is what causing the issue since the if and else handles all possible cases , toggle is probably going to do the opposite of the if else bloc .
We are able to get a selection range via window.getSelection().
I'm wondering whether there is a way to subscribe to window.getSelection changes.
The only way which came to me is to use timeouts (which is obviously bad) or subscribe to each user's key \ mouse press event and track changes manually.
ANSWER UPD: You are able to use this library, I've published it, as there are no more suitable ones: https://github.com/xnimorz/selection-range-enhancer
Use the onselect event.
function logSelection(event) {
const log = document.getElementById('log');
const selection = event.target.value.substring(event.target.selectionStart, event.target.selectionEnd);
log.textContent = `You selected: ${selection}`;
}
const textarea = document.querySelector('textarea');
textarea.onselect = logSelection;
<textarea>Try selecting some text in this element.</textarea>
<p id="log"></p>
For specific cases such as span contenteditable, you can make a polyfill:
function logSelection() {
const log = document.getElementById('log');
const selection = window.getSelection();
log.textContent = `You selected: ${selection}`;
}
const span = document.querySelector('span');
var down = false;
span.onmousedown = () => { down = true };
span.onmouseup = () => { down = false };
span.onmousemove = () => {
if (down == true) {
logSelection();
}
};
<span contenteditable="true">Try selecting some text in this element.</span>
<p id="log"></p>
if Im undesrting in right way you want to know when user start selection on page you can use DOM onselectstart.
document.onselectstart = function() {
console.log("Selection started!");
};
more info MDN
I have a following trouble in APIFY. I would like to write a function that saves HTML body of a current page and then click to the next page, saves HTML body etc.
I tried this:
var result = [];
var scrapeAndClick = function() {
$("div.ui-paginator.ui-paginator-top.ui-widget-header.ui-corner-top").each(function() {
result.push(
$(this).html()
);
//klikej na dalsi stranky
var nextButton = $('a.ui-paginator-next.ui-state-default.ui-corner-all');
console.log('Click next button');
nextButton.click().delay(4000)
});
};
scrapeAndClick();
In Google Chrome console it returns me only the HTML body of the first page. APIFY does not return anything.
Can someone see, where is the problem?
If is someone interested in the whole Page function:
async function pageFunction(context) {
const { log } = context;
const searchSelector = 'div.ui-panel-content.ui-widget-content > button';
//vyber "Gemeenschappelijk Landbouw Beleid" z Kies subsidie:
const subsidySelector = $("span.column2 > select.jsTruncate").val("10000");
log.info('Select CAP ')
subsidySelector
//klikni na Zoek
log.info('Click search.')
$(searchSelector).eq(0).click()
//loopujeme dalsi stranky a ukladame html body
var result = [];
var scrapeAndClick = function() {
$("div.ui-paginator.ui-paginator-top.ui-widget-header.ui-corner-top").each(function() {
result.push(
$(this).html()
);
//klikej na dalsi stranky
var nextButton = $('a.ui-paginator-next.ui-state-default.ui-corner-all');
console.log('Click next button');
nextButton.click().delay(4000)
});
};
scrapeAndClick();
return result;
}
StartURL is this: https://mijn.rvo.nl/europese-subsidies-2017
I found an old question on APIFY forum (https://forum.apify.com/t/clickable-link-that-doesnt-change-the-url/361/3), however it seems that it was done on old version of APIFY crawler.
Thanks a lot for any help!
Am getting key Combination from the server. Based on that am assigning key Combination to function dynamically. The below code is working for last iteration in loop. how below code is work for all iterations.
In my page i have two buttons save and cancel the below code is working for last iteration in for loop, It means btnCanel button triggers if i press key for save function.Any suggestions. hope understand my question.
$(document).ready(function fn() {
var keyCombination = new Object();
keyCombination['btnAdd'] = "Alt+S";
keyCombination['btnCancel'] = "Alt+C";
for (var k in keyCombination) {
if (keyCombination.hasOwnProperty(k)) {
shortcut.add(String(keyCombination[k]), function () {
var btnAdd = document.getElementById(String(k));
btnAdd.focus();
btnAdd.click();
});
}
}
});
if i give like this means it is working
shortcut.add("Alt+S", function () {
var btnAdd = document.getElementById('btnAdd ');
btnAdd .focus();
btnAdd .click();
});
shortcut.add("Alt+C", function () {
var btnCancel = document.getElementById('btnCancel');
btnCancel.focus();
btnCancel.click();
});
but if i try to add dynamically its overriding help me this issue.
Thanks in Advance.
I created a separate function outside the document.ready function like this now its working fine.
$(document).ready(function fn() {
var keyCombination = new Object();
keyCombination['btnAdd'] = "Alt+S";
keyCombination['btnCancel'] = "Alt+C";
for (var k in keyCombination) {
if (keyCombination.hasOwnProperty(k)) {
Set_KeyCombinations(k, keyCombination);
}
}
});
function Set_KeyCombinations(k, keyCombination) {
shortcut.add(String(keyCombination[k]), function () {
var eleId = document.getElementById(String(k));
if (eleId) {
if ($('#' + String(k).trim()).css('display') !== 'none' && eleId.getAttribute("disabled") !== "disabled") {
eleId.click();
eleId.focus();
}
}
});
}
Try this:
var keyCombinations = [ "Ctrl+Shift+X" , "Ctrl+Shift+Y" ];
for(var i=0; i<keyCombinations.length; i++){
(function(shorcutCombination){
shortcut.add(shorcutCombination,function() {
alert("i am " + shorcutCombination);
});
})(keyCombinations[i]);
}
The idea is that you need to preserve the value of keyCombinations[i]
as i increases in the loop. Tested this here: Openjs