Script that change the HTML-content of another page? - javascript

On my first page I have two input boxes and a button that will add the input to localStorage. When the data has been added I want to trigger an event that will write out the contents of localStorage on ANOTHER page. My problem is that my script can't find the element on the second page.
Code that adds the data to localStorage:
$("#submitLocal").click(function () {
var key = inputKey.value;
var value = inputValue.value;
localStorage.setItem(key, value);
if (newWindow == null || newWindow.closed) {
newWindow = window.open("local.html", "localWindow");
}
window.dispatchEvent(new Event("storage"));
});
I add the event listener:
window.addEventListener("storage", myFunc);
Which calls the function:
function myFunc(event) {
document.getElementById("addInfo").innerHTML = "";
for (var i = 0; i < localStorage.length; i++) {
$("#addInfo").append(
localStorage.key(i) +
" " +
localStorage.getItem(localStorage.key(i)) +
"<br>"
);
}
}
Right now, the element "addInfo" is on the FIRST page, and the data in localStorage gets written out on the page. But how can I do to write it on the second page if it cant find the elements on that page?
Im new to stackoverflow so I hope I managed to describe the problem well enough.
Thanks in advance.

It ALWAYS helps to post relevant code. In this case what is $("#submitLocal") ? If it is a submit button in a form, use the form submit event and preventDefault!
Why dispatch events in an event?
Just use the one you are in and the load event in page2
main page
$("#myForm").on("submit", function (e) {
e.preventDefault();
var key = inputKey.value;
var value = inputValue.value;
localStorage.setItem(key, value);
if (newWindow == null || newWindow.closed) {
newWindow = window.open("local.html", "localWindow");
}
});
local.html
function myFunc(event) {
$("#addInfo").empty();
for (var i = 0; i < localStorage.length; i++) {
$("#addInfo").append(
localStorage.key(i) +
" " +
localStorage.getItem(localStorage.key(i)) +
"<br>"
);
}
}
window.addEventListener("load",myFunc)

Related

How to not lose my event listener in Javascript each time I use .insertBefore?

I am attempting to move a div (which contains text and other elements) each time the user clicks the up or down arrow. The goal is to simply allow users to rearrange divs to their liking, based on clicking the appropriate arrows.
The issue I'm running into is -- when I use .insertBefore to rearrange these elements? It only allows me to click the arrow and perform that action once. After that, nothing happens. It appears that I'm losing my event listener each time I do this. Is there a way for me to somehow say: "Keep that old event listener after it gets moved?"
Here is the code:
for (let i = 0; i < NumberOfSavedIdeas; i++) {
document.getElementById('DeleteIdeaButton' + [i]).addEventListener('click', () => {
var DivToDelete = document.getElementById("SavedIdeaDiv" + [i]);
DivToDelete.remove();
let ArrayContentMatch = FullSavedIdeasArray.indexOf(FullSavedIdeasArray[i])
FullSavedIdeasArray.splice(ArrayContentMatch, 1);
chrome.storage.local.set({SavedIdeas: FullSavedIdeasArray});
});
document.getElementById('MoveIdeaUp' + [i]).addEventListener('click', () => {
var DivToMove1 = document.getElementById("SavedIdeaDiv" + [i]);
var ParentDiv1 = document.getElementById("DivTesting");
ParentDiv1.insertBefore(DivToMove1, ParentDiv1.children[i-1]);
});
document.getElementById('MoveIdeaDown' + [i]).addEventListener('click', () => {
alert('move down')
});
}
Thanks!
This is because new element doesn't exist in DOM when all event listeners are set. Add an event listener on document instead of an element.
It should be wrapped like:
for (let i = 0; i < NumberOfSavedIdeas; i++) {
document.body.addEventListener( 'click', function (e) {
if (e.target.id == 'YourId' + [i]) {
yourFunction();
}
} );
}

element.onclick not doesn't call function when element is clicked

I am building a Modal dynamically. I want to make some buttons in this modal to open a SubModal. The buttons show up in html, but clicking these buttons does nothing.
Here is my code.
const subtaskList = document.getElementById('subtaskList');
for (const subtaskIndex in task.subtasks) {
const subtaskButton = document.createElement('button');
subtaskButton.classList.add('taskModalSubtaskButton');
subtaskButton.onclick = () => {
openSubTaskModal(task.subtasks[subtaskIndex], task);
}
subtaskButton.innerText = task.subtasks[subtaskIndex].name;
subtaskList.appendChild(subtaskButton);
subtaskList.innerHTML += '<br>';
}
While troubleshooting I made an array to hold the buttons and used console.log() to see its elements. They all had the onclick function. I've clicked the buttons from the dev console by getting their class name and nothing, so I know it's not a display issue. I feel like I am misunderstanding something and any help would be appreciated.
The problem is subtaskList.innerHTML += '<br>'; it is good idea to use subtaskList.appendChild(document.createElement("br")); instead.
Here is working snippet:
function doSomething(url) {
alert(url);
}
const subtaskList = document.getElementById('subtaskList');
for (var i = 0; i < 3; i++) {
const subtaskButton = document.createElement('button');
subtaskButton.classList.add('taskModalSubtaskButton');
subtaskButton.innerText = "name" + i;
subtaskButton.onclick = (function (url) {
return function () {
doSomething(url);
};
})("URL #" + i)
subtaskList.appendChild(subtaskButton);
subtaskList.appendChild(document.createElement("br"));
}
<div id="subtaskList"></div>
Also I change a bit onclick function to send correspond index to doSomething function

How to access links within repeat control via CSJS in XPages?

In my application I display a link in a repeat control. This link will open a dialog control which displays details for a chosen row in the repeat.
Now I want to make the links appear as "read" when they are clicked.
I have defined the following function that will register the link ID clicked in a cookie and change the CSS color property of the link.
I can store the link ID in a cookie but when I try to find it in the DOM and change the CSS I fail. What am I doing wrong?
// onclick
function saveId(id) {
if ($.cookie('idCookie')) {
$.cookie('idCookie', $.cookie('idCookie') + "," + id);
} else {
$.cookie('idCookie', id);
}
}
// make all links colored
function setVisited() {
if (null != $.cookie('idCookie')) {
var idArray = $.cookie('idCookie').split(',');
console.log("#ids:" + idArray.length);
for (var x = 0; x < idArray.length; x++) {
console.log("ID: " + x + "=" + idArray[x]);
if ($('#' + idArray[x]).length) {
//link exists
$('#' + idArray[x]).css('color', 'red');
}
}
}
// assign saveId()
$(document).ready(function() {
$('a').click(function() {
saveId($(this).attr('id'));
});
setVisited();
});
The problem is that you cannot use the : in your selector as described here:
How to get the element id in repeat control
so your code must look something like this:
// onclick
function saveId(id) {
if ($.cookie('idCookie')) {
$.cookie('idCookie', $.cookie('idCookie') + "," + id);
} else {
$.cookie('idCookie', id);
}
}
// make all links colored
function setVisited() {
if (null != $.cookie('idCookie')) {
var idArray = $.cookie('idCookie').split(',');
for (var x = 0; x < idArray.length; x++) {
var link = $(document.getElementById(idArray[x])).get();
if (link.length) {
$(link).css('color', 'red');
}
}
}
}
// assign saveId()
$(document).ready(function() {
$('a').click(function() {
saveId($(this).attr('id'));
});
setVisited();
});
good luck!
You probably need to use the x$ jQuery selector as your ids contains colons: https://openntf.org/XSnippets.nsf/snippet.xsp?id=x-jquery-selector-for-xpages.

Click event on every item on populated list with jQuery

Here is how I populate my list:
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
Here is my html file:
<ul id="myList"></ul>
I want to add a click event for every item of list (without having separate ids):
$(function() {
$('#myList').click(function() {
var listItem = this.find('a').text();
console.log(listItem); // never logged
});
});
However, when I click at a list item, click event doesn't fire.
What am I doing wrong?
I can only assume there's a js error in your console.
I've created a working sample for you. We can use event delegation and then retrieve the DOM node that was clicked. You need to ensure you call the bingNetworksList [assume typo in here and meant binD ;)] function when the DOM ready event has fired.
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
$(function() {
var list = ["foo", "bar"]
bingNetworksList(list);
$('#myList').click(function(evt) {
var listItem = $(evt.target).text();
console.log(listItem); // never logged
});
});
You need to wrap this inside $ as like this:
$(function() {
$('#myList').click(function() {
var listItem = $(this).find('a').text();
console.log(listItem); // will always be logged
});
});

how to make the jquery function load before one ajax function finish

How do I fire one event before the previous function completed its function?
I have the following AJAX code :
var BrainyFilter = {
//...
init: function (opts) {},
changeTotalNumbers: function (data) {
jQuery(BrainyFilter.filterFormId).find('.bf-count').remove();
jQuery(BrainyFilter.filterFormId).find('option span').remove();
jQuery(BrainyFilter.filterFormId).find('select').removeAttr('disabled');
jQuery('.bf-attr-filter').not('#bf-price-container').find('input, option')
.attr('disabled', 'disabled')
.parents('.bf-attr-filter')
.addClass('bf-disabled');
if (data && data.length) {
for (var i = 0; i < data.length; i++) {
jQuery('.bf-attr-' + data[i].id + ' .bf-attr-val').each(function (ii, v) {
if (jQuery(v).text() == data[i].val) {
var parent = jQuery(v).parents('.bf-attr-filter').eq(0);
var isOption = jQuery(v).prop('tagName') == 'OPTION';
var selected = false;
if (isOption) {
jQuery(v).removeAttr('disabled');
selected = jQuery(v)[0].selected;
} else {
parent.find('input').removeAttr('disabled');
selected = parent.find('input')[0].checked;
}
parent.removeClass('bf-disabled');
if (!selected) {
if (!isOption) {
parent.find('.bf-cell').last().append('<span class="bf-count">' + data[i].c + '</span>');
} else {
jQuery(v).append('<span> (' + data[i].c + ')</span>');
}
}
}
});
}
jQuery('.bf-attr-filter input[type=checkbox]').filter(':checked')
.parents('.bf-attr-block').find('.bf-count').each(function (i, v) {
var t = '+' + jQuery(v).text();
jQuery(v).text(t);
});
// since opencart standard filters use logical OR, all the filter groups
// should have '+' if any filter was selected
if (jQuery('.bf-opencart-filters input[type=checkbox]:checked').size()) {
jQuery('.bf-opencart-filters .bf-count').each(function (i, v) {
var t = '+' + jQuery(v).text().replace('+', '');
jQuery(v).text(t);
});
}
}
// disable select box if it hasn't any active option
jQuery(BrainyFilter.filterFormId).find('select').each(function (i, v) {
if (jQuery(v).find('option').not('.bf-default,[disabled]').size() == 0) {
jQuery(v).attr('disabled', 'true');
}
});
},
//...
} // close the BrainyFilter
I also have another jQuery file running to get the bf-count value using $('.bf-count').text().
When the page load, the bf-count value is empty. Since the code above inject the bf-count, I will need to wait until it finishes the for loop in order to get the bf-count value.
What is the best way to approach this?
without knowing how the second js file is loaded, I can only give you a guesstimate suggestion.
If you want to run the second js file code after the page is fully loaded, you can wrap the code in:
jQuery(window).load(function(){
//your code here. runs after the page is fully loaded
});
jQuery documentation: http://api.jquery.com/load-event/
"The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object."

Categories

Resources