let bricks = document.querySelectorAll(".brick");
bricks.forEach((brick) => {
brick.addEventListener("click", function () {
let bricktype = brick.getAttribute("type");
console.log(bricktype);
});
});
from the above code ...
bricks variable get updated while the page first load. then i have form to add extra items to the bricks variable.. but i can't get update it .. if i try to reload page all the value eraes from memory
i want add values to that brocks array while i dynamicall add values in the html page
Yes, that code will only be executed at page load. This is a design problem, try refactoring your system some like this:
First, a function to add a listener for a single brick
function setupBrick(brick) {
brick.addEventListener("click", function () {
let bricktype = brick.getAttribute("type");
console.log(bricktype);
});
}
Now, in first page load:
let bricks = document.querySelectorAll(".brick");
bricks.forEach((brick) => {
setupBrick(brick)
});
And when user dynamically push a brick, do the following:
// get brick from form and store it in the "brickToPush" variable
setupBrick(brickToPush) // before push the brick
bricks.push(brickToPush)
That should solve your problem, you need to manually add that listener somehow, and encapsulating that logic in a function is a good practice
Related
For a radar chart, I'm trying to toggle (with a switch button) or slide (with a slider) between different sets of data to display. (I'll include the button here first, but I'm eventually try to extend that to a slider later.). 1. Initialize button and keep track of user toggle. 2. Pick which data set to use. both generateRadarData and generateRadarData2 work well on their own if I use chart.data = either one.
The below is the edited attempt:
var chartSwitchButton = chart.chartContainer.createChild(am4core.SwitchButton);
chartSwitchButton.events.on("toggle", function () {chart.data = whichData();})
function whichData() {
var dataToUse = chart.data;
if (chartSwitchButton.isActive) {dataToUse = generateRadarData();
} else {
dataToUse = generateRadarData2();}
return dataToUse};
chart.data = whichData();
I have tried commenting out the last line (since ideally it would have been updated via the event listener), but then no data displays.
Here is a more recent attempt to update the data using invalidateRawData:
chartSwitchButton.events.on("toggle", function (event) {
chart.data = whichData();
chart.invalidateRawData();
});
function whichData() {
var data = [];
if (chartSwitchButton.isActive) {
chart.data = generateRadarData();
} else {
chart.data = generateRadarData2();
}
chart.invalidateRawData(); //also tried invalidateData. tried this command in event listener as well as here.
data.push(chart.data); //attempt to replace/update raw data
//console.log(chart.data);
return chart.data; //this return line is necessary to output data but theoretically shouldn't be.
}
and have tried implementing the if-else w/in the event listener without having to use whichData as a separate function like so:
chartSwitchButton.events.on("toggle", function () {if (chartSwitchButton.isActive) {
chart.data = generateRadarData();
} else {
chart.data = generateRadarData2();
}
chart.invalidateRawData();})
I'm still unable to switch between the two sets of data with user interaction. In fact, if I don't return something for chart.data or declare what chart.data is supposed to be outside of the events.on or whichData(), then none of my data prints at all.
If anybody has suggestions on how to do this with a button (or a slider would be even better) that would be awesome.
Basically, after setting up the button, I tried to (a) keep track of the state of the button (as determined by user), (b) determine which state the button is in, and (c) pick a data set to use based off of that info. This version is edited from a previous attempt as per initial comments below. Thanks for your help.
Documentation is "toggled" not "toggle" in the events listener. The event does not recognize "toggle" but needed "toggled". https://www.amcharts.com/docs/v4/reference/switchbutton/#toggled_event
Have an interval that loads the html every 3 secs, but want to refresh it and not keep adding more under the already made code.
async function Products(){
setInterval(async function() {
const response = await fetch('http://localhost:3000/api/products');
const data = await response.json();
const mainContainer = document.getElementById("myData");
for (let obj of data) {
const div = document.createElement("div");
div.innerHTML = `${obj["sku"]}: ${obj["name"]}`;
mainContainer.appendChild(div);
}
}, 10000)
}
When I click a start button everything works, but how do i make it refresh the already made HTML rather than repeatedly recreating it with the interval. Trying to figure out a good approach to this. Thanks
Create and append a <div> immediately, and in the interval, assign to its innerHTML:
function Products() {
const container = document.getElementById("myData").appendChild(document.createElement("div"));
setInterval(async function () {
const response = await fetch('http://localhost:3000/api/products');
const data = await response.json();
container.innerHTML = '';
for (let obj of data) {
container.innerHTML += `${obj["sku"]}: ${obj["name"]}`;
}
}, 10000)
}
I think what you are trying to do is implement a Serie of observable elements that you can look only for those who have changed instead of all the data, something like React does with the virtual DOM.
Considering the code tout already posted, refreshing elements at a set interval is a bad idea. What if you have 1000 user refreshing at the same time? What if it cause your response tone to be more then 3 seconds?
That said, if you really want to work on creating something like that, you have to find a way to load not all the products from the api, but only the ones that are different. Again, if you want to keep it that way, here are, in my opinion, what you could do:
Start by loading all the product on the page, but set an interval to check a new Endpoint which would tell you what products have been added after the last one.
Use either an index or a key to identify which product is which, so tout know the ones you have.
You need a way to know quick product was updated since the last load.
That's a start. You can implement these in different way. I would suggest having a timestamp for the time created and updated, so you can then query only those who fall after this timestamp.
Add a dynamic ID to your product elements, (e.g. <div id=${sku} >**Product Here**<\div>
That way, you can track your product and recreate only the ones who changed/are new.
That's obviously a complicated way of implementing an open connection, if you want another solution, you could also open a Socket with your api, which would send event for data updated and created and would ultimately make your 3 second ping obsolete, resulting in a better scalability in my opinion.
function display() {
document.querySelector(".recipeList").innerHTML = "";
for (var i = 0; i < arrayOfRecipes.length; i++)
+document.querySelector(".recipeList").innerHTML += "<button onclick='buttonDirect(" + i + ")'>Start Cooking</button>";
}
function buttonDirect(indexNum) {
localStorage.setItem("indexNumber", JSON.stringify(indexNum));
window.location.href = "/display.html";
buttonClicked();
}
function buttonClicked() {
JSON.parse(localStorage.getItem("indexNumber"));
console.log(indexNumber);
}
I am trying to get data (index number) from one function to carry on running after the HTML page has been changed.
Currently, I have a button which runs a function called "buttonDirect(indexNum)" I want this function to change from one page to another, hence why I used the window.location.href = "/display.html"; code within the function. After this, the page changes so I attempt to save the index number by saving it to local storage with the localStorage.setItem("indexNumber", JSON.stringify(indexNum)); code. Then since JavaScript reads the code from top to bottom, I tried to make it run the buttonClicked(); function after the page has changed so that it doesn't run until the next page has loaded. That way, I can retrieve the index number on the next page using JSON.parse(localStorage.getItem("indexNumber")); and then console log that number with console.log(indexNumber);.
I quickly realised that this will not work, because the buttonClicked() function will run before the page actually changes, meaning that the indexNumber will not get logged once the page changes. What is the best way to achieve what I am trying to do?
It looks like buttonClicked() won't get called because you would have left the page.
You can, when the page loads, get the data you want from local storage:
window.onload = function() {
const indexNumber = JSON.parse(localStorage.getItem("indexNumber"));
console.log(indexNumber);
}
(I added a variable for the result of JSON.parse.)
By the way, on the fourth line, I don't know if the + there is a typo
+document.querySelector...
^
I have a filter_horizontal selector in my Django admin that has a list of categories for products (this is on a product page in the admin). I want to change how the product change form looks based on the category or categories that are chosen in the filter_horizontal box.
I want to call a function every time a category is moved from the from or to section of the filter_horizontal.
What I have now is:
(function($){
$(document).ready(function(){
function toggleAttributeSection(choices) {
$.getJSON('/ajax/category-type/', { id: choices}, function (data, jqXHR) {
// check the data and make changes according to the choices
});
}
// The id in the assignment below is correct, but maybe I need to add option[]??
var $category = $('#id_category_to');
$category.change(function(){
toggleAttributeSection($(this).val());
});
});
})(django.jQuery);
The function never gets called when I move categories from the left side to the right side, or vice versa, of the filter_horizontal.
I assume that $category.change() is not correct, but I don't know what other events might be triggered when the filter_horizontal is changed. Also, I know there are multiple options inside of the select box. I haven't gotten that far yet, but how do I ensure all of them are passed to the function?
If anyone can point me in the right direction I would be very grateful. Thank!
You need to extend the SelectBox.redisplay function in a scope like so:
(function() {
var oldRedisplay = SelectBox.redisplay;
SelectBox.redisplay = function(id) {
oldRedisplay.call(this, id);
// do something
};
})();
Make sure to apply this after SelectBox has been initialized on the page and every time a select box refreshes (option moves, filter is added, etc.) your new function will be called.
(Code courtesy of Cork on #jquery)
I finally figured this out. Here is how it is done if anyone stumbles on this question. You need to listen for change events on both the _from and _to fields in the Django filter_horizontal and use a timeout to allow the Django javascript to finish running before you pull the contents of the _from or _to fields. Here is the code that worked for me:
var $category = $('#id_category_to');
$category.change(function(){
setTimeout(function () { toggleAttributeSection(getFilterCategoryIds()) }, 500);
});
var $avail_category = $('#id_category_from');
$avail_category.change(function(){
setTimeout(function () { toggleAttributeSection(getFilterCategoryIds()) }, 500);
});
And this is how I get the contents of the _to field:
function getFilterCategoryIds() {
var x = document.getElementById("id_category_to");
var counti;
var ids = [];
for (counti = 0; counti < x.length; counti++) {
ids.push(x.options[counti].value);
}
return ids;
}
I know it was a convoluted question and answer and people won't come across this often but hopefully it helps someone out.
i am having trouble solving this, i'm trying to load a page which process a variable given by an input form then show the content based on the input, this worked fine, but i am also trying to refresh and update that input every 2 seconds
Below are my codes
<script>
$(document).ready(function(){
function getData(){
$("#dateslot").change(function(){
var inputField= $('#dateslot').val();
$("#timeslot").load('burgerorder_check.php?dateselect='+inputField);
});
setTimeout(getData,1000);
};
getData();
});
</script>
I'm trying to create a function that if someone else picked that, you won't be able to, which i successfully coded but not for the refresh part.
You have the methods and variables in the wrong order. You should probably set a variable outside the getData scope that can change at anytime, then just use that variable when fetching data.
Also, use setInterval if you want to repeat the function. setTimeout is simply a delay.
var val; // the select value is stored here
$("#dateslot").change(function(){
val = $(this).val(); // change the value
}
setInterval(getData,1000);
getData();
function getData(){
if ( val ) {
$("#timeslot").load('burgerorder_check.php?dateselect='+val);
}
}