Problem with add attr to img and set path - javascript

I have a little problem becouse I read values of labels and after that i want to set img src dependent on value label
Here some code and i see that is img attr don't add
getState generate divs with content
At the end is ajax call function where i get values from database and write them to the dynamically generated labels
The main problem now is then that don't read a values of labels correct becouse I got 3 labels with 3 diffrent states like "Active","Standby","Error" and it set for all Emergency Stop icon
function ChangeImage() {
let labels = $('label[data-id]');
$.each(labels, function (i, x) {
var states = $(x).text();
console.log(states);
if (states == "Active") {
var Active = "Images/kafle/zebatakActive.svg";
$(this).closest('img').attr("src", Active);
} else if (states == "Standby") {
var Standby = "Images/kafle/kafle_zebatka-01.svg"
$(this).closest('img').attr("src", Standby);
} else if (states == "Error") {
var error = "Images/kafle/kafle_zebatka-01.svg";
$(this).closest('img').attr("src", error);
} else if (states == "Setting") {
var Settings = "Images/kafel/kafle_zebatka-03.svg"
$(this).closest('img').attr("src", Settings);
} else {
var Emergency = "Images/kafle/kafle_status-yel-yel.svg";
$(this).closest('img').attr("src", Emergency);
}
});
}
function getState() {
try {
$.ajax({
type: "POST",
url: "Default.aspx/jsrequest",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#ajax").empty();
$.each(data, function () {
$("#ajax").append('<div id="ajaxcontent"></div>');
$("#ajaxcontent").addClass("ajaxcontent");
$.each(this, function (k,v) {
$("#ajaxcontent").append('<div class="view">' + ' <label id="IdOfMachine">' + v.MachineId + '</label>'
+ '<label class="MachineState" name="Values" data-id= "' + v.MachineId + ' " > ' + v.CurrentStatus + '</label > '
+ '<img class="ChangeImg" data-id="' + v.MachineId + '"> ' + '</img > '
+ '<label id="MachineName">' + v.MachineName + '</label>' + '</div>');
});
});
},
error: function (response) {
alert("cos źle")
}
});
} catch (err) { }
}
public static List<StateOfMachine> jsrequest()
{
List<StateOfMachine> MachineState = new List<StateOfMachine>();
string DBInfo = #"Data Source=STACJA45;Initial Catalog=AutoRefresh;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False";
string sqlrequest = "Select MachineID,CurrentStatus,MachineName from MachineStates";
SqlConnection connection = new SqlConnection(DBInfo);
SqlCommand command = new SqlCommand(sqlrequest, connection);
connection.Open();
SqlDataReader DataReader = command.ExecuteReader();
while (DataReader.Read()) {
StateOfMachine machines = new StateOfMachine();
machines.MachineId = DataReader["MachineID"].ToString();
machines.MachineName = DataReader["MachineName"].ToString();
machines.CurrentStatus = DataReader["CurrentStatus"].ToString();
MachineState.Add(machines);
}
DataReader.Close();
command.Dispose();
connection.Close();
return MachineState;
}

first of all, welcome to StackOverflow :)
2 things in your code to avoid in the future:
DRY: Don't Repeat Yourself - every time you're writing the same thing over and over, you're doing it wrong :)
To be precise, always use === instead of == the later will give true for 1 == "1" and it's better to avoid it since the start.
Relating to your issue, apart for repeating yourself and the use of == you are specifying $(this) and that is ok as long as you pass a jQuery event because it's a self function, the object this is not what you are assuming.
your code could be changed to something as:
function ChangeImage() {
var labels = $('label[data-id]');
$.each(labels, function (i, x) {
var url = '';
var path = 'Images/kafle';
var state = $(x).text();
switch(state) {
case "Active": url = path + "/zebatakActive.svg"; break;
case "Standby": url = path + "/kafle_zebatka-01.svg"; break;
case "Error": url = path + "/kafle_zebatka-01.svg"; break;
case "Setting": url = path + "/kafle_zebatka-03.svg"; break;
default: url = path + "/kafle_status-yel-yel.svg"; break;
}
$('img[data-id="' + state + '"]').attr("src", url);
console.log({path, state, url});
});
}
code edited from comments

remove closet() and put find()
function ChangeImage() {
let labels = $('label[data-id]');
$.each(labels, function (i, x) {
var states = $(x).text();
switch(states)
{
case "Active":
$(this).find('img').attr("src","Images/kafle/zebatakActive.svg");
break;
case "Standby":
$(this).find('img').attr("src", "Images/kafle/kafle_zebatka-01.svg");
break;
case "Error":
$(this).find('img').attr("src", "Images/kafle/kafle_zebatka-01.svg");
break;
case "Setting":
$(this).find('img').attr("src", "Images/kafel/kafle_zebatka-03.svg");
break;
default:
$(this).find('img').attr("src", "Images/kafle/kafle_status-yel-yel.svg");
break;
}
});
}

SOLUTION:
If you are using HTML as in the following code snippet, you can use siblings([selector]) to read the matching sibling element and to change the src of the image.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div>
<img src="#" class="image" height="100" width="100">
<label data-id="1" class="image-link">Active</label>
</div>
<div>
<img src="#" class="image" height="100" width="100">
<label data-id="2" class="image-link">Emergency</label>
</div>
<button onclick="changeImage()">Change</button>
<script>
function changeImage() {
let labels = $('label[data-id]');
$.each(labels, function (i, x) {
var states = $(x).text();
if (states == "Active") {
var Active = "https://atlas-content-cdn.pixelsquid.com/stock-images/golden-soccer-ball-3yLR9z1-600.jpg";
$(this).siblings('img').attr( {"src": Active });
} else {
var Emergency = "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
$(this).siblings('img').attr("src", Emergency);
}
});
}
</script>
</body>
</html>

Related

Dynamic Query Selector with own Event Listener

Hi i am using Javascript to Call a API for Pricefeed from Coingecko. I use a Function to add Div's from a button for choosing Coins that will display Prices in different "spaces".
HTML:
<button onclick="add_coin('coinspaceA', window.countA); return false;">Add Coin</button>
<button onclick="add_coin('coinspaceB', window.countB); return false;">Add Coin</button>
<button onclick="add_coin('coinspaceC', window.countV); return false;">Add Coin</button>
i call the Function fetch_coinlist() before the closing Body Tag
JS:
window.countA = 0;
window.countB = 0;
window.countC = 0;
var coins = {};
function fetch_coinlist(){
fetch("https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false")
.then(
function(response) {
if (response.status !== 200) {
alert('Can Not get Price Api! Status: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
coins = {};
for (let i = 0, l = data.length; i < l; i++) {
let {id, ...info} = data[i];
coins[id] = info;
}
});
}
)
.catch(function(err) {
alert('Can Not get Price Api! Status: ' + err);
});
}
function add_coin(space) {
if (space == "coinspaceA") {
coinspace(space, window.countA);
}
if (space == "coinspaceB") {
coinspace(space, window.countB);
}
if (space == "coinspaceC") {
coinspace(space, window.countC);
}
}
function coinspace(space, count){
const div = document.createElement('div');
count += 1;
div.id = space + count;
if (space == "coinspaceA"){
window.coinspace1 = count;
}
if (space == "coinspaceB"){
window.coinspace2 = count;
}
if (space == "coinspaceC"){
window.coinspace3 = count;
}
div.innerHTML = (`
<input type="button" value="-" class="curser-del" onclick="remove_coin(this,'` + space + `')"/>
<select id="` + space + count + `select" placeholder="Choose Coin"></select>
<input type="numbers" >
<label id="` + space + count + `info">Coins</label>
`);
document.getElementById(space).appendChild(div);
show_coinlist(space, count);
}
function show_coinlist(space, count){
for (let id in coins) {
let item = coins[id];
console.log(item);
const toplist = document.createElement("option");
toplist.value = id;
console.log(toplist.value);
// selector actions
const selector = document.querySelector("#" + space + count + "select");
const info = document.querySelector("#" + space + count + "info");
console.log(selector);
console.log(info);
selector.addEventListener('change', event => {
info.innerHTML = "Selected item: " + coins[toplist.value].name + " : " + coins[toplist.value].current_price;
});
console.log(coins[toplist.value].name);
console.log(coins[toplist.value].current_price);
toplist.innerHTML = item.symbol.toUpperCase() + " - " + item.name;
console.log(toplist.innerHTML);
console.log(toplist);
document.getElementById("#" + space + count + "select").appendChild(toplist);
}
}
When i use the selector on its own with a static ID it works and i get the Price Displayed from the Coin i choose, in the example above it gives me the right Values to the Console but when i try to run the loop it gets aborted after the first cycle with the error:
Uncaught TypeError: Cannot read property 'appendChild' of null
I tryed to put the script at the End of the Site so everything can load, but it does not change the Error, i tryed with static ID this works but i need to have as many selections as the User wants to add, i tryed to put selector Actions outside the loop but it did not work either. When i use console.log(toplist) before ...appendChild(toplist) it gives me the correct option i try to append,
<option value="bitcoin">BTC - Bitcoin</option>
but the loop stops with the Error: Uncaught TypeError: Cannot read property 'appendChild' of null, what am i doing wrong?

JavaScript arrays adding last element instead of recently added input

Good evening. I am new to JavaScript and I need help with my mini-project and I have only one issue here and it is in the this.Add = function ().
It works properly when I enter a duplicate value from my list therefore it displays an alert that no dupes are allowed. But... when I enter a unique value, it only adds up the last element present (Wash the dishes) from myTasks list. instead of the one I recently entered and the list goes on adding the same ones. Did I just misplace something?
This is my final activity yet and I want to finish it to move to the next function. Thank you in advance.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tasks CRUD</title>
<style>
#tasks{
display: none;
}
</style>
</head>
<body>
<center>
<form action="javascript:void(0);" method="POST" onsubmit="app.Add()">
<input type="text" id="add-task" placeholder="Add another card">
<input type="submit" value="Add">
</form>
<div id="tasks" role="aria-hidden">
<form action="javascript:void(0);" method="POST" id="saveEdit">
<input type="text" id="edit-task">
<input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a>
</form>
</div>
<p id="counter"></p>
<table>
<tr>
<th>Name</th>
</tr>
<tbody id="myTasks">
</tbody>
</table>
</center>
<script>
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
if (task ) {
for(task of this.myTasks)
{
var ctr = 0;
if(document.getElementById("add-task").value == task){
ctr = 1;
break;
}
}
if(ctr == 1)
{
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task.trim());
// Reset input value
el.value = '';
// Dislay the new list
this.FetchAll();
}
}
};
this.Edit = function (item) {
var el = document.getElementById('edit-task');
// Display value in the field
el.value = this.myTasks[item];
// Display fields
document.getElementById('tasks').style.display = 'block';
self = this;
document.getElementById('saveEdit').onsubmit = function() {
// Get value
var task = el.value;
if (task) {
// Edit value
self.myTasks.splice(item, 1, task.trim());
// Display the new list
self.FetchAll();
// Hide fields
CloseInput();
}
}
};
this.Delete = function (item) {
// Delete the current row
this.myTasks.splice(item, 1);
// Display the new list
this.FetchAll();
};
}
app.FetchAll();
function CloseInput() {
document.getElementById('tasks').style.display = 'none';
}
</script>
</body>
</html>
In your for loop:
for (task of this.myTask) {
}
You are not declaring a new task variable, but instead assigning to the outer task variable, hence the repeated addition of tasks already in your list.
You can declare a new variable in the for scope like so:
for (const task of this.myTask) {
}
Your HTML as it is.
And your Javascript goes like below. You have a bug while checking if the task already exists in the array. As you're comparing string value either use simple for loop with triple equals or do as i have attached below.
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
console.log(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
console.log(task);
if (task ){
var arrayContainsTask = (this.myTasks.indexOf(task) > -1);
if(arrayContainsTask == true){
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task);
// Reset input value
el.value = '';
}
// Dislay the new list
this.FetchAll();
}
}
}

How to fix retrieving data in HTML5 after the Firebase Function finished OK?

I can't seem to find the error. In the code below, when I change the asset field, I send the values to firebase, then the function finished with status: 'ok'.
And the value event method does not read the data changes at database path
firebase.database().ref("code/" + uuid + "/result")
Could you help me please?
This is my code.
<div class='asset'></div>
<main class="app__content prop-to-show hidden" style="height: inherit;"></main>
<main class="app__content data-to-show hidden" style="height: inherit;"></main>
<script src="https://www.gstatic.com/firebasejs/5.9.0/firebase.js"></script>
<script>
var config = { ... };
firebase.initializeApp(config);
</script>
<script type="module">
import PPE from "../js/ppe.min.js";
PPE.WORKER_PATH = '../js/ppe-worker.min.js';
// step 1.: Working fine
document.querySelector('.asset').addEventListener("change", coPPE);
function coPPE() {
const asset = document.querySelector('.asset').value;
const re = new PPE (asset, result => setResult(result));
};
// step 2.: Working fine
async function setResult(content) {
await setID(content);
};
// step 3.: Working fine
function setID(reid) {
var uid = firebase.auth().currentUser.uid;
var d = new Date();
var timestamp = d.getTime();
firebase.database().ref("ppe/" + uid).set({
code: reid,
timestmp: timestamp
});
};
</script>
<!--
step 4.: Working fine - cloud function set 'firebase.database().ref("code/" + id + "/result");' wnen ref('ppe/{Id}') is updated;
-->
<script type="text/javascript">
// step 5.: Nothing happens after step 4
var uuid = firebase.auth().currentUser.uid;
var statusRef = firebase.database().ref("code/" + uuid + "/result");
statusRef.on('value', function (snapshot) {
var getPropertyValue = snapshot.val();
var list = document.querySelector('.data-to-show');
var content = '';
while (list.firstChild) {
list.removeChild(list.firstChild);
}
if (getPropertyValue.rs == 0) {
content = "<div class='verified y5p' id='ok'> ... </div>";
} else if (getPropertyValue.rs == 1) {
content = "<div class='doublecheck y6p' id='twice'> ... </div>";
} else if (getPropertyValue.rs == 2) {
content = "<div class='notverified y7p' id='reject'> ... </div>";
}
document.querySelector('.data-to-show').innerHTML = content;
document.querySelector('.prop-to-show').classList.add('hidden');
document.querySelector('.data-to-show').classList.remove("hidden");
}, function (error) {
console.log("Error: " + error.code);
});
</script>

Google Chrome Local Storage Adding Links

So I'm trying to add an option on my options page for people to set 1-3 letters as a link to a website. Currently I'm getting a NaN value for the linkNumber when I run the function.
The Function:
function addLink () {
chrome.storage.local.get('linkNumber', function (x) {
if (x.linkNumber == undefined) {
chrome.storage.local.set({'linkNumber': '0'}, function() {
addLink();
});
} else {
var linkNumberInteger = parseInt(x.linkNumber);
var handle = document.getElementById("short");
var link = document.getElementById("long");
var handleValue = handle.value;
var linkValue = link.value;
var handleNumber = x.linkNumber + '-handle';
var urlNumber = x.linkNumber + '-link';
var objectOne = {};
var objectTwo = {};
objectOne[handleNumber] = x.linkNumber + '-handle';
objectTwo[urlNumber] = x.linkNumber + '-link';
console.log(x.linkNumber);
console.log(handleNumber);
chrome.storage.local.set({handleNumber: handleValue}, function(y) {
console.log(y.handleNumber + ' handle saved');
});
chrome.storage.local.set({urlNumber: linkValue}, function(z) {
console.log(z.handleNumber + ' link saved');
});
var linkNumberIntegerNext = linkNumberInteger++;
var n = linkNumberIntegerNext.toString();
chrome.storage.local.set({'linkNumber': n}, function() {
});
alert('Link Added');
}
});
}
The Html:
<h3 class="option">Add Quick Link:</h3>
<input contenteditable="true" type="text" class="short-quicklink" id="short" maxlength="3">
<span>http://</span><input contenteditable="true" type="text" class="long-quicklink" id="long">
<button class="add">Add Quick Link</button>

help constructing while loop

Hi I am trying to create a while loop and I am having trouble with what to put in it so far I have:
function showSports(obj)
{
var groupId = obj.id.substring(0, 1);
var indx = obj.id.substring(obj.id.indexOf('_') + 1);
var id = indx.substring(0, indx.length + 1);
var displayInfo = false;
while (displayInfo)
{
if (indx == 1)
{
show('footballInfo');
hide('soccerInfo');
hide('baseballInfo');
}
if (indx == 2)
{
show('soccerdInfo');
hide('baseballInfo');
hide('footballInfo');
}
if (indx == 3)
{
show('baseballInfo');
hide('footballInfo');
hide('soccerdInfo');
}
displayInfo = true;
}
}
It is supposed to be able to loop through the links below and show/hide depending on which link is selected.
<a id='1link_1a' title="football Tab" onclick='showSports(this);'>
<span>FootBall</span>
</a>
<a id='1link_1b' title="soccer"
onclick='showSports(this); changeTab(this);'>
<span>Soccer</span>
</a>
<a id='1link_1c' title="baseball" onclick='showSports(this);'>
<span>Baseball</span>
</a>
I don't understand your use of the while statement. Perhaps you're thinking of a switch statement.
function showSports(obj)
{
var groupId = obj.id.substring(0, 1);
var indx = obj.id.substring(obj.id.indexOf('_') + 1);
var id = indx.substring(0, indx.length + 1);
switch (indx)
{
case 1:
show('footballInfo');
hide('soccerInfo');
hide('baseballInfo');
break;
case 2:
show('soccerdInfo');
hide('baseballInfo');
hide('footballInfo');
break;
case 3:
show('baseballInfo');
hide('footballInfo');
hide('soccerdInfo');
break;
}
}
RightSaidFred is correct, it sounds like you meant to use switch. One other point is that the line:
var id = indx.substring(0, indx.length + 1);
will have an index out of bounds error. I think you were thinking to do:
var id = indx.substring(0, indx.length - 1);

Categories

Resources