Refreshing a page returns [object CSSStyleDeclaration] - javascript

When I edit a content and saved changes, it shows [object CSSStyleDeclaration] instead of my updated content when refreshing the page.
function newElement() {
let li = document.createElement("li");
let inputvalue = document.querySelector("#myInput").value;
let savedNote = document.createTextNode(inputvalue);
li.appendChild(savedNote);
if (inputvalue === '') {
alert("Please write something")
} else {
document.querySelector("#myNotes").appendChild(li);
}
document.querySelector("#myInput").value = '';
}
function saveEdits() {
let editElement = document.querySelector("#saved-notes");
editElement = document.querySelector("#myNotes");
let userVersion = editElement.innerHTML;
userVersion = editElement.style;
localStorage.userEdits = userVersion;
document.querySelector("#update").innerHTML = "Edits saved. Refresh the page to see changed content";
}
function checkEdits() {
if (localStorage.userEdits != null)
document.querySelector("#saved-notes").innerHTML = localStorage.userEdits;
document.querySelector("#myNotes").style = localStorage.userEdits;
}
ul {
margin: 0;
padding: 0;
}
ul li {
cursor: pointer;
position: relative;
padding: 12px 8px 12px 40px;
background: #eee;
font-size: 18px;
transition: 0.2s;
}
<html>
<head>
<meta charset="utf-8">
</head>
<body onload="checkEdits()">
<div id="myDiv" class="new-note">
<textarea id="myInput"></textarea><br>
<button onclick="newElement()" class="save-button">Create</button>
<button onclick="saveEdits()" class="edit-button">Save Changes</button>
</div>
<div id="update"></div>
<div id="saved-notes"></div>
<ul id="myNotes">
</ul>
</body>
</html>
It will work if I removed userVersion = editElement.style;, but there will no CSS style. Just plain text.
I want to understand why this happens and learn from it. Thanks in advance.

It's because the Function localStorage.set can only save Strings, so it will call .toString() on the Object before it get stored and the Result of it is it's type [object CSSStyleDeclaration]. Did you tried to stringify it before you safe it?
userVersion = JSON.stringify(editElement.style);
document.querySelector("#myNotes").style = JSON.parse(localStorage.userEdits);

Related

id values turns always same from foreach in mvc view page

I am using mvc .net core for a project and I have a view page. I need some id values from this page for using them inside partial view. Because I am using those id values for foreign key in another table to post. From main page these values posts in database correctly. I always post 5 values and always 5 id there in database I saw when I checked. But when I click the accordion this id always turns first id from these 5 values. if I posted as 6,7,8,9,10 it just turns me 6 and it doesn't matter if I clicked the last one in the page or first one. But context and title always correct when I check it from database and from page.
I tried a few jquery code but they didn't work correctly. I need the correct id values when I click other accordions.
I would be glad for any kind of help. Thanks a lot.
Here is my code:
#model IEnumerable<match>
#{
ViewData["Title"] = "Home Page";
}
<head>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<style>
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
</style>
</head>
<body>
<h4>Title List:</h4>
<table class="table table-hover">
#foreach (var item in Model)
{
<tr class="yzt">
<td class="xyz" id="item_title" >
<button class="accordion" id="title" >#Html.DisplayFor(modelItem => item.title)</button>
<div class="panel">
<p id="modelId" hidden>#Html.DisplayFor(modelItem=>item.Id)</p>
<p>#Html.DisplayFor(modelItem => item.context)</p>
#await Html.PartialAsync("Create", item.Exams#*, Exams*#)
</div>
</td>
</tr>
}
</table>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function () {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
//document.querySelectorAll('.accordion').forEach(link => this.addEventListener('click', myFunction))
//function myFunction() {
// document.getElementById("matchId").value = document.getElementById("modelId").innerHTML;
// console.log("value is" + document.getElementById("matchId").value);
//}
document.querySelectorAll('.panel').forEach(link => this.addEventListener('click', myFunction))
function myFunction() {
document.getElementById("matchId").value = document.getElementById("modelId").innerHTML;
console.log("value is" + document.getElementById("matchId").value);
}
//document.querySelectorAll(".accordion")
//document.getElementById("match_title").value = document.getElementById("title").innerHTML;
</script>
</body>
I recommend you to write like this:
<div class="panel" id=#item.Id onclick="test(#item.Id)">
function test(val){
alert(val);
}
Your code will create multiple having id "title" and multiple having id "modelId", and this is also the reason why you always get the id from the first item, what you write document.getElementById("modelId").innerHTML will always get the first dom element which id = "modelId"

how to save toogle class with localstorage. so can someone check what's wrong with this code

if( localStorage.getItem("color") == "black" ) {
{
var element = document.getElementById("body");
element.classList.toggle("bdark");
}
{
var element = document.getElementById("theader");
element.classList.toggle("hdark");
}
{
var element = document.getElementById("sh");
element.classList.toggle("shh");
}
}
function myFunction() {
{
var element = document.getElementById("body");
element.classList.toggle("bdark");
}
{
var element = document.getElementById("theader");
element.classList.toggle("hdark");
}
{
var element = document.getElementById("sh");
element.classList.toggle("shh");
}
var hs = document.getElementById("hs");
var color;
if(localStorage.getItem("color") == "black") {
color = "black";
localStorage.setItem("color",color)
}
.bdark {
background-color: #333;
color: white;
}
.hdark {
background-color: black;
color: white;
}
.shh {
display: none;
}
.hs {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body id="body" class="light">
<p id="theader">Click the "Try it" button to toggle between adding and removing the "mystyle" class name of the DIV element:</p>
<button id="button" onclick="myFunction()">Try it</button>
<div id="aaas">
<div id="sh" class="sh">☾</div>
<div id="hs" class="hs">☀</div>
</div>
</body>
</html>
i want this code to onclick toggle class and when i refresh the page those toggled class remain same as they were before reloading the page with localstorage. so can someone check what's wrong with this code. help me with something similar/alternative to this one. thanks for reading this.
Details:-
i want this code to work as (onclick class change + saved with cokies/localstorage/or anything) so whenever i refresh or reopen the page it would be same class as it was when i left. or some alternative code that works same.
I fixed your code
if( localStorage.getItem("color") == "black" ) {
{
let element = document.getElementsByTagName("body");
element.classList.toggle("bdark");
}
{
let element = document.getElementById("theader");
element.classList.toggle("hdark");
}
{
let element = document.getElementById("sh");
element.classList.toggle("shh");
}
}
function myFunction() {
{
let element = document.getElementsByTagName("body");
element.classList="bdark";
}
{
let element = document.getElementById("theader");
element.classList="hdark";
}
{
let element = document.getElementById("sh");
element.classList="shh";
}
{
let hs = document.getElementById("hs");
}
let color;
if(localStorage.getItem("color") != "black") {
color = "black";
localStorage.setItem("color", color)
}
}
.bdark {
background-color: #333;
color: white;
}
.hdark {
background-color: black;
color: white;
}
.shh {
display: none;
}
.hs {
display: none;
}
<p id="theader">Click the "Try it" button to toggle between adding and removing the "mystyle" class name of the DIV element:</p>
<button id="button" onclick="myFunction()">Try it</button>
<div id="aaas">
<div id="sh" class="sh">☾</div>
<div id="hs" class="hs">☀</div>
</div>

JavaScript Function

Hello everybody I have this code that I have made alone.
function appearafter() {
document.getElementById("buttonappear").style.display = "block";
document.getElementById("button").style.display = "block";
document.getElementById("hinzufuegen").style.display = "none";
function myFunction() {
var itm = document.getElementById("myList2").lastChild;
var cln = itm.cloneNode(true);
document.getElementById("myList1").appendChild(cln);
}
function allFunction() {
myFunction();
appearafter();
}
#button {
display: none;
}
#buttonappear {
display: none;
}
#test {
width: 300px;
height: 300px;
background-color: red;
}
<!DOCTYPE html>
<html>
<body>
<button id="hinzufuegen" onclick="allFunction()">ADD</button>
<div id="myList1">
<button id="button" onclick="">DELETE</button>
<div id="myList2">
<div id="test">
</div>
</div>
</div>
<button onclick="allFunction()" id="buttonappear">ADD</button>
</body>
</html>
What I want to make is that the red square whenever you are clicking on the ADD button it will be a clone and when you click on the DELETED button that the clone is deleted. Can somebody help me, please?
In addition to missing } as was mentioned in the comments, there was a not-so-obvious problem with finding the <div> to clone. The lastChild was actually a text node containing the \n (newline), after the <div>. It's better to search for <div> by tag:
var itm = document
.getElementById('myList2')
.getElementsByTagName('div')[0];
Since there's only one <div> we can use the zero index to find this first and only one.
And for delete function you can use a similar approach and get the last <div> and remove it.
function appearafter() {
document.getElementById("buttonappear").style.display = "block";
document.getElementById("button").style.display = "block";
document.getElementById("hinzufuegen").style.display = "none";
}
function myFunction() {
var itm = document.getElementById("myList2").getElementsByTagName("div")[0];
var cln = itm.cloneNode(true);
document.getElementById("myList1").appendChild(cln);
}
function deleteFunction() {
var list1 = document.getElementById("myList1");
var divs = Array.from(list1.getElementsByTagName("div"));
// If the number of divs is 3, it means we're removing the last
// cloned div, hide the delete button.
if (divs.length === 3) {
document.getElementById("button").style.display = "none";
}
var lastDivToDelete = divs[divs.length - 1];
list1.removeChild(lastDivToDelete);
}
function allFunction() {
myFunction();
appearafter();
}
#button {
display: none;
}
#buttonappear {
display: none;
}
#test {
/* make it smaller so it's easier to show in a snippet */
width: 30px;
height: 30px;
background-color: red;
}
<button id="hinzufuegen" onclick="allFunction()">ADD</button>
<div id="myList1">
<button id="button" onclick="deleteFunction()">DELETE</button>
<div id="myList2">
<div id="test"></div>
</div>
</div>
<button onclick="allFunction()" id="buttonappear">ADD</button>

Pass ID from one html element to another with JavaScript

my problem is pretty simple. I'm trying to switch 2 elements id by clicking either of them using only vanilla JavaScript.
It works on the first click to use the correct CSS for the new id, but afterward, it does not seem to recognize click events to the new id. Here is a short code example to illustrate this:
document.addEventListener("DOMContentLoaded", function(){
var blueSpin = document.getElementById("blue-spinner");
var orangeSpin = document.getElementById("orange-spinner");
blueSpin.addEventListener("click", function() {
document.getElementById("h1").innerHTML = "You've Clicked Blue";
blueSpin.setAttribute("id","orange-spinner");
orangeSpin.setAttribute("id", "blue-spinner")
});
orangeSpin.addEventListener("click", function() {
document.getElementById("h1").innerHTML = "You've Clicked Orange";
orangeSpin.setAttribute("id", "blue-spinner");
blueSpin.setAttribute("id", "orange-spinner");
});
});
h1, h2 {
font-weight: bold;
text-align: center;
font-size: 45px;
font-family: 'VT323', monospace;
margin: 15px;
}
#blue-spinner {
color: blue;
}
#orange-spinner {
color: goldenrod;
}
<script src="https://use.fontawesome.com/releases/v5.0.2/js/all.js"></script>
<html>
<body>
<h1 id="h1">Click Something:</h1>
<h2 id="blue-spinner"><i class="fa fa-cubes fa-spin" aria-hidden="true"></i></h2>
<h2 id="orange-spinner"><i class="fa fa-cubes fa-spin" aria-hidden="true"></i></h2>
</body>
</html>
My expectation is that upon clicking either spinner, the colors will switch, and the header will identify which one was clicked before the change. After that, you should be able to click either of the spinners with the same result.
Any help anyone can provide would be appreciated! Happy X-mas Eve Eve!
I would use class selectors in css instead of id. Something along these lines:
var btns = document.getElementsByClassName("btn");
for(var i = 0; i < btns.length; i++){
btns[i].addEventListener("click", function(e) {
var clss = e.target.getAttribute("class")
if(clss === undefined || cls === null){clss = "";}
if(cls.indexOf("blue-spinner") > -1){
var output = "You clicked a blue spinner";
e.target.setAttribute("class", "orange-spinner");
}else{
e.target.setAttribute("class", "blue-spinner");
var output = "You clicked an orange spinner";
}
var h = document.getElementById("h1");
h.innerHTML = output;
});
}
Since you change the id for the element you have to update your code after the change.
document.addEventListener("DOMContentLoaded", function() {
var blueSpin = document.getElementById("blue-spinner");
var orangeSpin = document.getElementById("orange-spinner");
var blueSpinClick = function() {
document.getElementById("h1").innerHTML = "You've Clicked Blue";
blueSpin.removeEventListener('click', blueSpinClick);
orangeSpin.removeEventListener('click', orangeSpinClick);
blueSpin.removeEventListener('click', blueSpinClick);
blueSpin.setAttribute("id","orange-spinner");
orangeSpin.setAttribute("id", "blue-spinner");
blueSpin = document.getElementById("blue-spinner");
orangeSpin = document.getElementById("orange-spinner");
blueSpin.addEventListener("click", blueSpinClick);
orangeSpin.addEventListener("click", orangeSpinClick);
}
document.getElementById("blue-spinner").addEventListener("click", blueSpinClick);
var orangeSpinClick = function() {
document.getElementById("h1").innerHTML = "You've Clicked Orange";
orangeSpin.removeEventListener('click', orangeSpinClick);
blueSpin.removeEventListener('click', blueSpinClick);
blueSpin.setAttribute("id","orange-spinner");
orangeSpin.setAttribute("id", "blue-spinner");
blueSpin = document.getElementById("blue-spinner");
orangeSpin = document.getElementById("orange-spinner");
blueSpin.addEventListener("click", blueSpinClick);
orangeSpin.addEventListener("click", orangeSpinClick);
}
document.getElementById("orange-spinner").addEventListener("click", orangeSpinClick);
});
h1, h2 {
font-weight: bold;
text-align: center;
font-size: 45px;
font-family: 'VT323', monospace;
margin: 15px;
}
#blue-spinner {
color: blue;
}
#orange-spinner {
color: goldenrod;
}
<script src="https://use.fontawesome.com/releases/v5.0.2/js/all.js"></script>
<html>
<body>
<h1 id="h1">Click Something:</h1>
<h2 id="blue-spinner"><i class="fa fa-cubes fa-spin" aria-hidden="true"></i></h2>
<h2 id="orange-spinner"><i class="fa fa-cubes fa-spin" aria-hidden="true"></i></h2>
</body>
</html>

dynamically Adding and removing elements based on checkbox values with DOM

I'm just trying to dynamically add to a div within a form depending on which checkboxes are checked. So, I am creating the li tag and then they are added as li elements within an ol parent element so its just a list of values. I do not know what is wrong with my code, I'm not sure how to remove the appropriate value if the relevant checkbox is unchecked, and when I uncheck and then recheck a checkbox, it keeps adding the value over and over again.
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
input {
margin: 18px;
}
#o {
list-style-type: none;
}
.u {
list-style: none;
}
</style>
</head>
<body style="width: 700px">
<div style="float: left; width: 340px; height: 250px; border: 1px solid black; padding: 20px 0 10px 20px;">
<form id="myForm">
<ul class="u">
<li><input id="showAlert1" type="checkbox" name="thing" value="laptop">laptop</li>
<li><input id="showAlert2" type="checkbox" name="thing" value="iphone">iphone</li>
</ul>
</form>
</div>
<div id="myDiv" style="float: right; width: 317px; height: 250px; border: solid black; border-width: 1px 1px 1px 0; padding: 20px 0 10px 20px;">
<ol id="o">
</ol>
</div>
<script>
document.getElementById('myForm').addEventListener('change', function () {
var a = document.getElementsByName('thing');
for (var i = 0; i < a.length; i++) {
if (a[i].checked){
createDynamicElement();
} else if (!a[i].checked){
removeDynamicElement();
}
}
function createDynamicElement(){
var node = document.createElement("LI");
node.setAttribute("id1", "Hey");
var textnode = document.createTextNode(event.target.nextSibling.data);
node.appendChild(textnode);
document.getElementById("o").appendChild(node);
}
function removeDynamicElement() {
document.querySelector("#o li").innerHTML = "";
}
});
</script>
</body>
</html>
It looks like that you are adding an event listener to the form instead of the input elements themselves. I dont think the change event will be fired when an input element in a form changes. (see: https://developer.mozilla.org/en-US/docs/Web/Events/change)
On your event listener, try targeting the input elements themselves.
} else if (!a[i].checked){
removeDynamicElement();
}
...
function removeDynamicElement() {
document.querySelector("#o li").innerHTML = "";
}
Will empty the first or all matches(not sure) but wont remove them. Instead you should give li tags a unique ID and remove them completely via something like:
for (var i = 0; i < a.length; i++) {
if (a[i].checked){
console.log(a[i])
createDynamicElement(a[i].value);
} else if (!a[i].checked){
removeDynamicElement(a[i].value);
}
}
function createDynamicElement(id){
var node = document.createElement("LI");
node.setAttribute("id", id);
var textnode = document.createTextNode(id);
node.appendChild(textnode);
console.log(node)
document.getElementById("o").appendChild(node);
}
function removeDynamicElement(id) {
var target = document.getElementById(id)
target.parentElement.removeChild(target);
}
Or you could clear the ol completely on every change and repopulate it again like:
var a = document.getElementsByName('thing');
document.getElementById("o").innerHTML = null;
for (var i = 0; i < a.length; i++) {
if (a[i].checked){
console.log(a[i])
createDynamicElement(a[i].value);
}
}
function createDynamicElement(id){
var node = document.createElement("LI");
var textnode = document.createTextNode(id);
node.appendChild(textnode);
console.log(node)
document.getElementById("o").appendChild(node);
}
Edit:
A proper FIFO solution:
var a = document.getElementsByName('thing');
for (var i = 0; i < 2; i++) {
var target = document.getElementById(a[i].value);
if (a[i].checked && !target){
createDynamicElement(a[i].value);
} else if ((!a[i].checked) && target){
removeDynamicElement(a[i].value);
}
}
function createDynamicElement(id){
var node = document.createElement("li");
node.setAttribute("id", id);
var textnode = document.createTextNode(id);
node.appendChild(textnode);
document.getElementById("o").appendChild(node);
console.log("a")
}
function removeDynamicElement(id) {
target.parentElement.removeChild(target);
}
});

Categories