Passing onclick event in template literal - javascript

I'm trying to pass url through onclick event, its not working.
there is <body onload="displayBookmarks()"> to initialise displayBookmarks function as soon as the page gets loaded
function deleteBookmark(url){
alert(url);
};
function displayBookmarks(){
bookmarksResults.innerHTML = "";
for (let a in bookmarks){
let name = bookmarks[a].name;
let url = bookmarks[a].url;
bookmarksResults.innerHTML += `<div class="well"> <h3> ${name} <a class="btn btn-default" target="_blank" href=${url} >Visit</a> <a onclick=${deleteBookmark(url)} class="btn btn-danger" >Delete</a></h3></div>`
}
}
The main problem is onclick=${deleteBookmark(url)}
As soon as the page loads it starts displaying the url but I want to to be shown only when delete button is pressed.

I've found that there is another way to do this with encapsulation. I don't know if I would recommend doing it like this at all but since you've asked the question.
const app = document.getElementById("app");
const button = ((app) => {
let _url;
const _log = (data) => {
console.log(data);
}
let _content = `<button onclick="(${_log})('${_url}')">test</button>`;
const _setContent = () => {
_content = `<button onclick="(${_log})('${_url}')">test</button>`;
}
const _setUrl = (url) => {
_url = url;
}
return {
setUrl: (url) => {
_setUrl(url);
_setContent();
},
render: () => {
app.innerHTML = _content;
}
}
})(app)
const url = 'www.something.com';
button.setUrl(url);
button.render();
<section id="app">...</section>

const markUp = `
<button onclick="myFunction()">Click me</button>
`;
document.body.innerHTML = markUp;
window.myFunction = () => {
console.log('Button clicked');
};

Related

Use id from Template strings item

i'm having a trouble using the id from a template string item
const elementoParaInserirJogosNaLista = document.getElementById("listaJogos");
function exibirJogosNaTela(listaDeJogos) {
elementoParaInserirJogosNaLista.innerHTML = "";
listaDeJogos.forEach((jogo) => {
elementoParaInserirJogosNaLista.innerHTML += `
<div class="jogo">
<a href="paginajogo.html">
<img class="jogo__imagem" src="${jogo.imagem}" alt="${jogo.titulo}" />
</a>
<h2 class="jogo__titulo">${jogo.titulo}</h2>
<p class="jogo__preco" id="preco">R$${jogo.preco}<a ><img class="jogo__carrinho" id="addCarrinho" src="./images/addcart.png" alt="Adicionar ao carrinho"/></p><a/>
</div>
`;
});
}
i've tried to use the id "addCarrinho" and nothing happens
i'm newb on developing
const botoesAddCarrinho = [];
botoesAddCarrinho = document.querySelectorAll(".jogo__carrinho");
botoesAddCarrinho.forEach((evento) =>
evento.addEventListener("click", addNoCarrinho)
);
function addNoCarrinho () {
console.log('ok')
}
i've changed the selector to by the class, but nothings happens, is like the nothing was selected
i'm using the exibirNaTela on the fetch with the json
let jogos = [];
const endpointDaAPI ="jogos.json"
getBuscarJogosDaAPI();
async function getBuscarJogosDaAPI() {
const respost = await fetch(endpointDaAPI);
jogos = await respost.json();
exibirJogosNaTela(jogos.jogos);
}

How to add an image from a template form with JS?

i'm studying JS and at the moment i'm not really good with it. I created a page (a kind of social network) and i need to add an image from an URL when i fill a form. The form has 2 fields: Image title and URL
the initial cards that i have on the page, i handle to insert them from an array. But i can't understand how to add a single photo from a form.
The new photo should appear as first image, the previous 1st image should be at the 2nd place and so on, cards can be deleted when i click on a button but i didn't really got how to do it, and the like buttons should work for every single cards... i've was looking for it on google and i found some stuffs but they didn't work for me.
how can i solve it?
my code:
HTML
<section class="cards" id="cards">
<!-- images will be added here-->
<div class="cards__add-form-overlay">
<form class="cards__add-form">
<button class="cards__add-form-close-icon"></button>
<p class="cards__add-form-text">New place</p>
<input type="text" placeholder="Name" class="cards__add-form-first-field" id="ImageName" value= "">
<input type="text" placeholder="Image URL" class="cards__add-form-second-field" id="URL" value= "">
<button type="submit" class="cards__add-form-submit">create</button>
</form>
</div>
</section>
<template class="elements" id="elements">
<div class="element">
<div class="element__card">
<img class="element__photo" src="" alt="">
<div class="element__button-container">
<button type="button" class="element__trash-button" id="trashbutton">
</div>
<div class="element__text">
<p class="element__place"></p>
<button type="button" class="element__like-button" id="likebutton" onclick="toggle()"></button>
</div>
</div>
</template>
<script type="text/javascript" src="./script.js"></script>
</body>
</html>
JS
// IMAGES //
// description: adding photos in the page from an array with JS //
const initialCards = [
{ name:'', link:''},
{ name:'', link:''},
{ name:'', link:''},
{ name:'', link:''},
{ name:'', link:''},
{ name:'', link:''}
];
initialCards.forEach(card => cardItem(card));
function cardItem(cardData) {
const container = document.getElementById("cards");
const cardTemplate = document.getElementById("elements").content;
const newCard = cardTemplate.cloneNode(true);
const elementImage = newCard.querySelector('.element__photo');
const elementText = newCard.querySelector('.element__place');
elementImage.src = cardData.link;
elementText.textContent = cardData.name;
container.append(newCard);
}
----- Until here all good
// description: adding popup when clicking on + button, and close with X button //
document.querySelector('.profile__add-button').addEventListener('click', function () {
document.querySelector('.cards__add-form-overlay').style.visibility = 'visible';
});
document.querySelector('.cards__add-form-close-icon').addEventListener('click', function () {
document.querySelector('.cards__add-form-overlay').style.visibility = 'hidden';
});
document.querySelector('.cards__add-form-submit').addEventListener('click', function () {
document.querySelector('.cards__add-form-overlay').style.visibility = 'hidden';
});
document.querySelector('.profile__add-button').addEventListener('click', function () {
document.querySelector('.cards__add-form').style.visibility = 'visible';
});
document.querySelector('.cards__add-form-close-icon').addEventListener('click', function () {
document.querySelector('.cards__add-form').style.visibility = 'hidden';
});
document.querySelector('.cards__add-form-submit').addEventListener('click', function () {
document.querySelector('.cards__add-form').style.visibility = 'hidden';
});
// description: adding photo through popup with 2 fields, name and URL //
const addPhoto = document.querySelector('.cards__add-form');
const imageNameInput = document.querySelector('.cards__add-form-first-field');
const imageUrlInput = document.querySelector('.cards__add-form-first-field');
function handleAddCardFormSubmit(evt) {
evt.preventDefault();
const element = createCard(imageNameInput.value, imageUrlInput.value);
elements.prepend(element);
imageNameInput.value = '';
imageUrlInput.value = '';
closePopup(evt.target.closest('.cards__add-form'));
}
function createCard(name, link) {
const elementTemplate = document.querySelector('#element-template').content;
const element = elementTemplate.querySelector('.element').cloneNode(true);
const elementImage = element.querySelector('.element__photo');
const elementTitle = element.querySelector('.element__place');
elementImage.src = link;
elementTitle.textContent = name;
//like button//
const likeButton = element.querySelector('.element__like-button');
likeButton.addEventListener('click', () => likeButton.classList.toggle('element__like-button_active'));
//delete cards //
element.addEventListener('click', function (evt) {
if (evt.target.classList.contains('element__trash-button')) {
evt.currentTarget.remove();
}
if (evt.target.classList.contains('element__photo')) {
openImagePopup(name, link);
}
});
return element;
}
initialCards.forEach(({name, link}) => elements.append(createCard(name, link)));
with this code, the new image doesn't appear, about like button console says that toogle() is not defined, and delete button don't delete the image but no error in the console

JavaScript :Ajax - Symfony 6 : trying to send form with plain js ajax

I have a little problem or a big one, I don't know. I'm trying to send a form with ajax with Symfony, and native JavaScript, but I don't really know how. I managed to do ajax with GET request to try to find a city (which is included in this form).
So I've got my form, I also want to send 2 arrays 1 for images (multiple images with different input) the input are created with js via CollectionType::class, then I'm putting my images in array which I want to send.
And the other array is for the city I want my product to be in. I've got an input text and via ajax it's searching city then by clicking on the city I've got a function putting it on an array.
but now I find difficulties trying to send it everything I found on the web mostly uses jQuery.. but I want to learn JavaScript so I believe I have to train with native first.
so I tried to send my form, but nothing happened when I submit it, not even an error, it just reload the page, and in my console I've got a warning for CORB issues I think it's due to my browser blocking my request because something is wrong in it?
I'm trying to find a way to send it and save it in my database.
so here's the code:
{% extends "base.html.twig" %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-lg-6 mx-auto mt-5">
{{form_start(form)}}
{{form_errors(form)}}
{{form_row(form.title)}}
{{form_row(form.description)}}
{{form_row(form.surface)}}
{{form_row(form.piece)}}
{{form_row(form.type)}}
<div class="container">
<div class="select-btn">
<span class="btn-text d-flex">
<input type="text" oninput="getData(this.value)" class="rel" name="ville" id="">
<span class="arrow-dwn">
<i class="fa-solid fa-chevron-down"></i>
</span>
</span>
</div>
<ul class="list-items js-result"></ul>
</div>
<button type="button" class="btn btn-primary btn-new opacity-100" data-collection="#foo">ajouter une image</button>
<div id="foo" class="row" data-prototype="{{include ("include/_Addimage.inc.html.twig", {form: form.image.vars.prototype})|e("html_attr")}}" data-index="{{form.image|length > 0 ? form.image|last.vars.name +1 : 0}}">
{% for image in form.image %}
<div class="col-4">
{{ include ("include/_Addimage.inc.html.twig", {form: image}) }}
</div>
{{form_errors(form.image)}}
{% endfor %}
</div>
<div class="col-4 mt-5">
{{form_row(form.submit)}}
</div>
{{form_widget(form._token)}}
{{form_end(form, {render_rest: false})}}
</div>
</div>
</div>
{% endblock %}
here the code of my JavaScript, everything is in my twig file, because as you will see I added eventListener on some input, I didn't see a better way maybe someone can correct me.
{% block javascripts %}
<script type="text/javascript">
/////////////// GET INPUT TEXT VALUE AND SHOW A LIST OF CITIES
function getData(text) {
const param = new URLSearchParams();
param.append('text', text);
const url = new URL(window.location.href);
fetch(url.pathname + "?" + param.toString() + "&ajax=1", {
header: {
"X-Requested-With": "XMLHttpRequest"
}
})
.then(response => response.json())
.then(data => {
handle_result(data);
});
}
////////////////////////////// CREATE MY OPTIONS WITH CITIES NAME
function handle_result(response)
{
let result_div = document.querySelector(".js-result");
let str = "";
for (let i = response.length - 1; i >= 0; i--) {
str += "<option" + ' ' + "onclick=" + "addTag(this.value)" + ' ' + "class=" + "item" + ' ' + "value=" + response[i].ville + ">" + response[i].ville + "</option>";
}
result_div.innerHTML = str;
};
// //////////////////////////// ADD THE CITY NAME IN A CONTAINER WHEN I USER CLICK ON IT
const selectBtn = document.querySelector(".select-btn");
const rel = document.querySelector(".rel");
items = document.querySelectorAll(".item");
rel.addEventListener("click", () => {
selectBtn.classList.toggle("open");
});
function createTag(label) {
const div = document.createElement('div');
div.setAttribute('class', 'tag');
const span = document.createElement('span');
span.innerText = label;
const closeBtn = document.createElement('i');
closeBtn.setAttribute('data-item', label);
closeBtn.setAttribute('onclick', 'remove(this)');
closeBtn.setAttribute('class', 'material-icons');
closeBtn.innerHTML = 'close';
div.appendChild(span);
div.appendChild(closeBtn);
return div;
}
btnText = document.querySelector(".btn-text");
let tags = [];
function addTags()
{
reset();
for (let a of tags.slice().reverse()) {
const tag = createTag(a);
selectBtn.prepend(tag);
}
}
function addTag(value) {
input = document.querySelector('.rel');
console.log(input);
if (tags.includes(value)) {
alreadyExist(value);
}
else {
tags.shift();
tags.push(value);
addTags();
}
input.value = "";
}
function alreadyExist(value) {
const index = tags.indexOf(value);
tags = [
... tags.slice(0, index),
... tags.slice(index + 1)
];
addTags();
}
function reset() {
document.querySelectorAll('.tag').forEach(function (tag) {
tag.parentElement.removeChild(tag);
})
}
function remove(value) {
const data = value.getAttribute('data-item');
const index = tags.indexOf(data);
tags = [
... tags.slice(0, index),
... tags.slice(index + 1)
];
addTags();
}
//////////////////////////////////////////////////////// CREATING IMAGE ARRAY TO SEND WITH AJAX REQUEST ?
images = [];
function image_to_array(value) {
if(!images.includes(value))
{
images.push(value);
}else{
return false;
}
}
const form =
{
title: document.getElementById('product_form_title'),
description: document.getElementById('product_form_description'),
surface: document.getElementById('product_form_surface'),
piece: document.getElementById('product_form_piece'),
type: document.getElementById('product_form_type'),
}
const submit = document.getElementById('submit', () => {
const request = new XMLHttpRequest();
const url = new URL(window.location.href);
const requestData =
`
title=${form.title.value}&
description=${form.description.value}&
surface=${form.surface.value}&
piece=${form.piece.value}&
image=${JSON.stringify(images)}&
type=${JSON.stringify(tags)}&
ville=${tags}
`;
fetch(requestData , url.pathname ,{
header: {
"X-Requested-With": "XMLHttpRequest"
}
})
request.addEventListener('load', function(event) {
console.log(requestData);
});
request.addEventListener('error', function(event) {
console.log(requestData);
});
});
////////////////////////////// CREATE NEW FILE INPUT
const newItem = (e) => {
const collectionHolder = document.querySelector(e.currentTarget.dataset.collection);
const item = document.createElement('div');
item.classList.add('col-4');
item.innerHTML = collectionHolder.dataset.prototype.replace(/__name__/g, collectionHolder.dataset.index);
item.querySelector('.btn-remove').addEventListener('click', () => item.remove());
collectionHolder.appendChild(item);
collectionHolder.dataset.index ++;
}
document.querySelectorAll('.btn-new').forEach(btn => btn.addEventListener('click', newItem));
</script>
{% endblock %}
here my controller but I don't think it is the issue, I didn't finish it since I'm quite lost on the js part
class AdminController extends AbstractController
{
#[Route('/admin/create_product', name: 'create_product', methods: ['POST', 'GET'])]
public function createProduct(EntityManagerInterface $em, SluggerInterface $slugger, Request $request, LieuxRepository $villeRepo, SerializerInterface $serializer): Response
{
$product = new Product;
$ville = new Lieux;
$form = $this->createForm(ProductFormType::class, $product);
$form->handleRequest($request);
$list = $villeRepo->findAll();
$query =$request->get('text');
if($request->get('ajax')){
return $this->json(
json_decode(
$serializer->serialize(
$villeRepo->handleSearch($query),
'json',
[AbstractNormalizer::IGNORED_ATTRIBUTES=>['region', 'departement', 'products']]
), JSON_OBJECT_AS_ARRAY
)
);
}
if($request->isXmlHttpRequest())
{
if ($form->isSubmitted() && $form->isValid()) {
$product->setCreatedAt(new DateTime());
$product->setUpdatedAt(new DateTime());
$product->setVille($form->get('ville')->getData());
$product->setType($form->get('type')->getData());
$em->persist($product);
$em->flush();
}
}
return $this->render(
'admin/create_product.html.twig',
['form' => $form->createView() ]
);
}
hope it's clear, thank you

li element vanish after page reload

I am trying to add a li element in the below div (Functionality is to upload an attachment)
See below pic 1
My JavaScript functionality of Submit button adds the Li in the div perfectly fine. But, when I refresh the page it's gone.
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>
<button type="button" id="submit-button" onclick="Submit()">Submit</button>
<div id="collapseThree">
</div>
<script>
const realFileBtn = document.getElementById("real-file");
const customBtn = document.getElementById("custom-button");
const customTxt = document.getElementById("custom-text");
const submitBtn = document.getElementById("submit-button");
const slides = [];
var str = '';
customBtn.addEventListener("click", function() {
realFileBtn.click();
});
window.addEventListener('load', (event) => {
console.log(slides)
console.log('The page has fully loaded yo');
// document.getElementById("collapseThree").innerHTML
});
/* window.onload = document.getElementById("slideContainer").innerHTML
*/
function Submit() {
console.log("going in");
document.getElementById("collapseThree").innerHTML += str
}
realFileBtn.addEventListener("change", function() {
if (realFileBtn.value) {
customTxt.innerHTML = realFileBtn.value.match(
/[\/\\]([\w\d\s\.\-\(\)]+)$/
)[1];
console.log(customTxt.innerHTML)
slides.push(customTxt.innerHTML);
slides.forEach(function(slide) {
str = '<li>' + slide + '</li>';
});
console.log(arr)
console.log(slides)
} else {
customTxt.innerHTML = "No file chosen, yet.";
}
});
</script>
You can use localStorage to save and read data. Simply call
function getSlides() {
var slidesJson = localStorage.getItem('slides') || '[]';
return JSON.parse(slidesJson);
}
to get all current slides and
function setSlides(slides) {
localStorage.setItem('slides', JSON.stringify(slides))
}
to save the current state of the array.

why check is undefined in my code? 'pure js'

** I want when to click on the active button if the checkbox is checked to add filtered class in HTML element but it doesn't work and give me an undefined error in this line check.parentElement.classList.add("filtered"); **
<ul class="ul-list"></ul>
</section>
</main>
<footer class="footer">
<button class="all footer-btn">All</button>
<button class="active footer-btn">Active</button>
<button class="complete footer-btn">Complete</button>
</footer>
let check = document.querySelectorAll(".complete-txt");
let complete_btn = document.querySelector(".complete");
let active_btn = document.querySelector(".active");
let all_btn = document.querySelector(".all");
let edit_list = document.querySelector(".edit-list");
let main_text = document.querySelector(".main-text");
let list_item = document.querySelector(".list-item");
let footer = document.querySelector(".footer");
const generateTemplate = (todo) => {
const html = `
<li class="list-item">
<input type="checkbox" class="complete-txt" name="" id="check"><span class="main-text">${todo}</span><div class="edit-list"></div><div class="delete-list"></div>
</li>
`;
list.innerHTML += html;
};
// add todos event
addForm.addEventListener("submit", (e) => {
e.preventDefault();
const todo = addForm.add.value.trim();
if (todo.length) {
generateTemplate(todo);
addForm.reset();
}
});
active_btn.addEventListener("click", function () {
let check_id = document.querySelector(".complete-txt");
// check.forEach(function () {
debugger;
if (check.checked !== "true") {
check.parentElement.classList.add("filtered");
console.log("hi");
}
// });
// console.log("hi");
console.log("hi");
// console.log(check.checked.value);
});
if the larger document fixes all other inconcistencies you should be able to change the eventlistener to
active_btn.addEventListener("click", function () {
let check_id = document.querySelector(".complete-txt");
if (check_id.checked !== "true") {
check_id.parentElement.classList.add("filtered");
}
});
BUT!!! this will not "fix" all of your errors, like defining let check before the checkbox is created with generateTemplate

Categories

Resources