how to return created attribute in javascript - javascript

I'm having trouble retrieving data from a data-tag attribute on a button that is created by createElement
chatbot.js
const selectServiciosMoviles = document.querySelector('#selectServiciosMoviles')
const addSelect = (select, id, datatag) => {
const selection = document.createElement('button')
selection.classList.add('chatbot__selection')
selection.id = id
selection.setAttribute("data-tag", datatag)
selection.innerHTML = select
messageArea.appendChild(selection)
scrollToBottom(messageArea)
}
selectServiciosMoviles.addEventListener('click', () => {
setTimeout(() => {
addSelect('Portabilidad', 'selectPortabilidad', '{"categoria":"chatbot", "nombre":"chatbot","ubicacion":"home_b2b", "accion":"seleccionar", "etiqueta":"subcategoria_portabilidad"}')
addSelect('Planes Moviles', 'selectMoviles', '{"categoria":"chatbot", "nombre":"chatbot","ubicacion":"home_b2b", "accion":"seleccionar", "etiqueta":"subcategoria_planes_moviles"}')
addSelect('Roaming', 'selectRoaming', '{"categoria":"chatbot", "nombre":"chatbot","ubicacion":"home_b2b", "accion":"seleccionar", "etiqueta":"subcategoria_roaming"}')
addSelect('Seguro Movil', 'selectSeguros', '{"categoria":"chatbot", "nombre":"chatbot","ubicacion":"home_b2b", "accion":"seleccionar", "etiqueta":"subcategoria_seguro_movil"}')
scrollToBottom()
}, 2000)
});
html
<button class="chatbot__selection" id="selectPortabilidad" data-tag="{"categoria":"chatbot", "nombre","chatbot", "ubicacion":"home_b2b", "accion":"seleccionar","etiqueta":"subcategoria_portabilidad"}">Portabilidad</button>
<button class="chatbot__selection" id="selectMoviles" data-tag="{"categoria":"chatbot", "nombre","chatbot", "ubicacion":"home_b2b", "accion":"seleccionar","etiqueta":"subcategoria_portabilidad"}">Planes Moviles</button>
<button class="chatbot__selection" id="selectRoaming" data-tag="{"categoria":"chatbot", "nombre","chatbot", "ubicacion":"home_b2b", "accion":"seleccionar","etiqueta":"subcategoria_portabilidad"}">Roaming</button>
<button class="chatbot__selection" id="selectSeguros" data-tag="{"categoria":"chatbot", "nombre","chatbot", "ubicacion":"home_b2b", "accion":"seleccionar","etiqueta":"subcategoria_portabilidad"}">Seguro Movil</button>
libreria.js
var tagItems = document.querySelectorAll('[data-tag]')
tagItems.forEach(function (e) {
e.addEventListener('click', function (e) {
if(e.target.dataset.tag != undefined){
var data = JSON.parse(e.target.dataset.tag)
console.log(data)
}
})
})
the problem when seeing the console nothing appears to me, the data-tag of the button does not rescue me. please i need help, thanks

Related

How can I get action events to work with template strings

Problem
Rendered HTML template literal action events won't work
Stack MEVN with handlebars
code
renderData.js
const template = function (data) {
return `<div class="vvn_siteContent sc_flex">
<span class="sc_flex">
<img src="https://images.wallpaperscraft.com/image/single/keyboard_backlight_light_159518_1280x720.jpg" alt="" class="sc_img">
<div class="sc_flex sc_column">
<label class="sc_label">${data.category} :: ${data.titles.main}</label>
<div class="sc_desc" style="word-wrap: break-word">
${data.desc.main}
</div>
<div class="vvn_editTypes">
<button class="sc_button sc_resetBTN">Delete</button>
<button class="sc_button sc_scheduleBTN" >Hide</button>
<button class="sc_button sc_sendBTN" dataset-data="${data._id}" onclick="myData()" >Edit!</button>
</div>
</div>
</span>
</div>`
}
export const renderData = function (key) {
const keyToLowerCase = key.toLowerCase();
const getKeyData = handleJSON(keyToLowerCase);
getContainer.innerHTML = " ";
const parser = new DOMParser();
for (let i = 0; i < getKeyData[0][0].pageContent.length; i++) {
const { ...data } = getKeyData[0][0].pageContent[i];
const html = template(data);
const parsedDoc = parser.parseFromString(html, "text/html");
getContainer.append(...parsedDoc.body.children);
}
}
oneCRUD.js //this is the file that is loaded via
<script type="module" src="../js/OneCRUD.js" type="text/javascript" data="{{data2}}"></script>
this script tag is at the bottom of the index.html
const allBtns = document.querySelectorAll('.vvn_editTypes').forEach(el => el.addEventListener('click', (e) => {
console.log(e.target)
console.log(e)
if(e.target.textContent === 'Delete') console.log('Deleting')
if(e.target.textContent === 'Hide') console.log('Hiding')
if(e.target.textContent === 'Edit!') console.log('Editing')
}))
function myData () {
console.log('this wont get called even if i gave the button onclick="myData()")
}
If I try to call a function in onclick I will get error function name undefined
My problem is pretty straight forward. I am trying to attach events to the buttons in renderData.js from file oneCRUD.js and its not working.
Appreciate the help
I found a solution
code
const allBtns = document.querySelectorAll('.vvn_siteContent').forEach(el => el.addEventListener('click', (e) => {
console.log(e.target)
console.log(e)
if(e.target.textContent === 'Delete') console.log('Deleting')
if(e.target.textContent === 'Hide') console.log('Hiding')
if(e.target.textContent === 'Edit!') console.log('Editing')
}))
notice how the element I'm selecting is inside the template literal
I need to select the parent of that element.
so now my code looks like this:
const allBtns = document.querySelectorAll('.vvn_siteContentList').forEach(el => el.addEventListener('click', (e) => {
console.log(e.target)
console.log(e)
if(e.target.textContent === 'Delete') console.log('Deleting')
if(e.target.textContent === 'Hide') console.log('Hiding')
if(e.target.textContent === 'Edit!') console.log('Editing')
}))
now the allBtns function works.
why does this work?
thats a good question

How to Disable this save/submit button?

I am wondering what is the best method to disable this save button after one click?
Here is the code :
<button data-bind="enable: !$root.isSaving(), click: $root.addNewCard.bind($data, $root)" class="primary button" role="button" data-size="sm">
Save
</button>
Above is the .cshtml code
Below is the javascript code:
BillingInformation.prototype.addNewCard = function (parent, creditCard) {
parent.isSaving(true);
parent.isSettingDefault(true);
creditCard.cardNumber(creditCard.cardNumber().replace(/-|\s/g, ''));
let $form = $('#addNewCardForm' + creditCard.walletItemId()),
cardNumber = creditCard.cardNumber();
parseDynamicFormElements($form);
if ($form.valid()) {
verifyAddress($form, function () {
authentication.checkReAuthenticatedThenLaunchLoginOrExecuteTask(() => {
creditCard
.save()
.then(response => {
if (response.status === HTTP_STATUS_OK) {
creditCard.walletItemId(response.content);
parent.walletItems.push(creditCard);
creditCard.lastFourDigits(
creditCard.cardNumber() ? creditCard.cardNumber().substr(-4) : ''
);
creditCard.obfuscatedCardNumber(cardNumber.replace(/.(?=.{4})/g, '*'));
parent.newCardInstance(new CreditCard({paymentType: 'creditCards'}));
checkForRedirect();
} else {
let container = document.createElement('div');
container.append(
'We were unable to save your payment information. Please try again or give us a call at 1-800-461-8898'
);
smartPak.ui.modal(container, {
title: 'Unable to Save Payment Method',
buttons: {
Close: function (modal) {
modal.close();
}
}
});
}
})
.then(() => {
parent.isSaving(false);
});
});
});
parent.isSaving(false);
} else {
parent.isSaving(false);
parent.isSettingDefault(false);
}
};
What is the best method to prevent this from being clicked more than once after submission? currently if clicked multiple times it will duplicate the cc.
Thank you!
Maybe the the enable property should bind to a variable, not a function like you do in
enable: !$root.isSaving()
did you try switching click:
$root.addNewCard.bind($data, $root) to click: $root.addNewCard.bind($root, $data) ?
according to your declaration:
BillingInformation.prototype.addNewCard = function (parent, creditCard)
creditCard = $data from the form and parent = $root ?

JQuery cloned element

I am stuck on this problem. I am coding a task platform app. Whenever I try to save, the task clones itself. After each "Save Changes," there are more and more clones. I have rewritten the code so many times. But still, I am not successful. Please help me to find the error.
$("#taskSave").click(() => {
const task = {
id: Date.now(),
imageUrl: $("#imageInput").val(),
title: $("#titleInput").val(),
description: $("#descriptionInput").val(),
type: $("#typeInput").val(),
};
$("#overlay").hide();
todos.push(task);
saveStorage(todos);
// reset input values
$("#imageInput").val("");
$("#titleInput").val("");
$("#descriptionInput").val("");
$("#typeInput").val("");
});
function saveStorage(todos) {
localStorage.setItem("todos", JSON.stringify(todos));
display(todos);
};
function display(todos) {
$("#taskBoard").innerHTML = "";
// .html("");
todos.forEach(item => {
let c = document.createElement("div");
c.setAttribute("class", "card");
c.setAttribute('id', item.id);
c.innerHTML = `
<div class="cardTop">
<div class="binContainer">
<div class="binImage"></div>
</div>
</div>
<img src="${item.imageUrl}" alt="task image">
<h2>${item.title}<h2>
<p>${item.description}</p>
<div class="cardType">${item.type}</div>
`;
$("#taskBoard").append(c);
// end
});
};
I've created a minimal working example, and the problem is in the cleanup of the HTML. You cannot use innerHTML on the JQuery object, or you use its html function or you need to retrieve the javascript object with $("#taskBoard")[0].
// You can use:
$("#taskBoard").html("");
// or
// document.getElementById("taskBoard").innerHTML = "";
// or
// $("#taskBoard")[0].innerHTML = "";
// But not:
// $("#taskBoard").innerHTML = "";
The working example here on JSFiddle (on SO dont work localStorage)
let todos = [];
$("#taskSave").click(() => {
const task = {
id: Date.now()
};
todos.push(task);
saveStorage(todos);
});
function saveStorage(todos) {
localStorage.setItem("todos", JSON.stringify(todos));
display(todos);
console.log(todos);
};
function display(todos) {
$("#taskBoard").html("");
// or
// document.getElementById("taskBoard").innerHTML = "";
// or
// $("#taskBoard")[0].innerHTML = "";
// But not
// $("#taskBoard").innerHTML = "";
todos.forEach(item => {
let c = document.createElement("div");
c.innerHTML = `
<p>${item.id}</p>
`;
$("#taskBoard").append(c);
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="taskSave">
SAVE
</button>
<div id="taskBoard">
</div>

Why when i am searching for something else is deleting the previous contents

Why when you are searching for something else is deleting the previous contents ?For example first you search for egg and show the contents but then when you search for beef the program deletes the egg and shows only beef.Code :
const searchBtn = document.getElementById('search-btn');
const mealList = document.getElementById('meal');
const mealDetailsContent = document.querySelector('.meal-details-content');
const recipeCloseBtn = document.getElementById('recipe-close-btn');
// event listeners
searchBtn.addEventListener('click', getMealList);
mealList.addEventListener('click', getMealRecipe);
recipeCloseBtn.addEventListener('click', () => {
mealDetailsContent.parentElement.classList.remove('showRecipe');
});
// get meal list that matches with the ingredients
function getMealList(){
let searchInputTxt = document.getElementById('search-input').value.trim();
fetch(`https://www.themealdb.com/api/json/v1/1/filter.php?i=${searchInputTxt}`)
.then(response => response.json())
.then(data => {
let html = "";
if(data.meals){
data.meals.forEach(meal => {
html += `
<div class = "meal-item" data-id = "${meal.idMeal}">
<div class = "meal-img">
<img src = "${meal.strMealThumb}" alt = "food">
</div>
<div class = "meal-name">
<h3>${meal.strMeal}</h3>
Get Recipe
</div>
</div>
`;
});
mealList.classList.remove('notFound');
} else{
html = "Sorry, we didn't find any meal!";
mealList.classList.add('notFound');
}
mealList.innerHTML = html;
});
}
It's because you are replacing the contents in the mealList element every time.
A simple workaround would be to retrieve the the innerHTML values before you update it.
Something like
let html = mealList.innerHTML;
rather than starting off empty every time you call the function should do the trick.

How do I get a list of checked checkboxes?

I am using Javascript to create an HTML form with some radio button questions and one checkbox question at the end. The reason I am using JavaScript is that the questions take data from a google cloud firestore database, and they need to be dynamic. when I get the data from the radio buttons, it shows it as a string, but when I get the data from the checkboxes, it leaves it blank. I want it to show a string with a list of boxes checked. Here is my code:
const OACanList = document.querySelector('#OAInput');
const setupOACans = (data) => {
let html = '';
if (data.length) {
data.forEach(doc => {
const OACan = doc.data();
const li = `
<style>
#OAInput [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
position: static;
opacity: 1;
pointer-events: initial;
}
</style>
<input type="checkbox" name="OAElection" value="${OACan.name}" style="display:block opacity:1;">${OACan.name}
<br>
`;
html += li
});
OACanList.innerHTML = html;
} else {
OACanList.innerHTML = html;
};
};
index.js:
const voteForm = document.querySelector('#vote-form');
voteForm.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('ballots').add({
OA: voteForm.OAElection.value
}).then(() => {
const modal = document.querySelector('#modal-vote');
M.Modal.getInstance(modal).close();
voteForm.reset();
}).then(() => {
const docRef = db.collection('users').doc(auth.currentUser.uid);
docRef.get().then(function(doc) {
doc.data().count++;
})
});
});

Categories