I have an HTML page that gathers data from a database and uses that data to produce dynamic HTML elements. The problem is that these elements have to create a button that submits data without refreshing the page and then call a function productList(formId);
.
This is the current function:
function getWidgets(){
var listUrl = base_url + widgetsPath + url_auth;
console.log("Sending GET to " + listUrl);
function getSuccess(obj){
var dataWidget = obj.data;
for (let i=0; i< dataWidget.length; i++){
var id = dataWidget[i].id;
var description = dataWidget[i].description;
var price = dataWidget[i].pence_price;
var url = dataWidget[i].url;
var index = i;
console.log("index: ",i);
console.log(dataWidget[i].id);
console.log(dataWidget[i].description);
console.log(dataWidget[i].pence_price);
console.log(dataWidget[i].url);
console.log(" ");
var template =`<!-- product -->
<div class="container" class="product" id="productId_${index}">
<form action="" class="product">
<img src="${url}"></img>
<p class="product_Description">${description}</p>
<input type="hidden" class="productId" value=${id}>
<input type="hidden" class="price" value="0.${price}">
<label for="quantity">Quantity:</label>
<input type="number" class="quantity" value="1" min="1">
<button class="submit">Add to cart</button>
</form>
</div>
<script>
document.addEventListener("DOMContentLoaded",() =>{
const product${index} = document.querySelector("#productId_${index}")
product1.addEventListener("submit",e=>{
e.preventDefault();
var formId = "productId_${index}";
productList(formId);
});
});
</script>
<!-- END product -->`
$("#widgetContainer").append(template);
}
console.log("success");
console.log(dataWidget);
};
$.ajax(listUrl, {type: "GET", data: {},success: getSuccess });
};
getWidgets();
2
Answers
You do not need to dynamically add a
<script>
block for each widget you append to your page. Instead, you can add a singlesubmit
event handler that will be able to handle thesubmit
event for all of the<form>
elements you add dynamically. The code would look like the following:The above code is using Event Delegation to handle the
submit
event for any<form>
element with a class of "product". In the handler, we get theid
attribute of the<form>
element’s parent.Here is a fiddle for reference.
Under the hood, jQuery’s
append()
parses the HTML-string by usingElement.innerHTML
.As mentioned in MDN’s section Security considerations for
innerHTML
:So instead of executing the code by appending a
<script>
tag, simply execute it:Or better, use event delegation as 76484’s answer shows. That way you wouldn’t have to add individual listeners.