I'm working on a simple aplication based on localStorage and I have a problem with removing an item.
So, I'm adding new items to LS and display them as divs in for loop.
I created an easy "X" button on every card and here is a thing. How can I get an ID/position of this specific card after clicking "X" and pass it to remove function?
I'll present you my code:
// Display activities
var fetchActivities = function() {
var activities = JSON.parse(localStorage.getItem("activitie"));
const actCountContainer = document.getElementById("actCountContainer");
actCountContainer.innerHTML = "";
actCountContainer.innerHTML += "<div class='col-md-12'>" +
"<p>Your activities ("+activities.length+")";
var actCardContainer = document.getElementById("actCardContainer");
actCardContainer.innerHTML = "";
for (let i = 0; i < activities.length; i++) {
actCardContainer.innerHTML += '<div class="col-md-4">'+
'<div class="card">' +
'<div class="card-block">' +
'<div id="remove" class="remove">X</div>' +
'<h4 class="card-title">'+ activities[i].name + '</h4>' +
'<ul class="card-text">' +
'<li>Total time spent: 2h 25min 34sec</li>' +
'</ul>' +
'Go to this activity' +
'</div>' +
'</div>' +
'</div>'
}
const removeButton = document.getElementById("remove");
if (removeButton) {
removeButton.addEventListener("click", removeActivity);
};
};
// Add activity function
var addActivity = function() {
const actInput = document.getElementById("activityInput").value;
// Main activity object
var activity = {
name: actInput
};
if (localStorage.getItem("activitie") == null) {
var activities = [];
activities.push(activity);
localStorage.setItem("activitie", JSON.stringify(activities));
} else {
var activities = JSON.parse(localStorage.getItem("activitie"));
activities.push(activity);
localStorage.setItem("activitie", JSON.stringify(activities));
}
fetchActivities();
};
// Remove activity function
var removeActivity = function() {
};
const addButton = document.getElementById("addBtn");
addButton.addEventListener("click", addActivity);
I'd be very grateful if you can give me an idea how can I handle this remove function.
I would rewrite fetchActivities as follows
var fetchActivities = function() {
var activities = JSON.parse(localStorage.getItem("activitie"));
const actCountContainer = document.getElementById("actCountContainer");
actCountContainer.innerHTML = "";
actCountContainer.innerHTML += "<div class='col-md-12'>" +
"<p>Your activities ("+activities.length+")";
const actCardContainer = document.getElementById("actCardContainer");
actCardContainer.innerHTML = "";
let items = "";
for (let i = 0; i < activities.length; i++) {
itemsHTML += '<div class="col-md-4">'+
'<div class="card" data-id="' + activities[i].id + '">' +
'<div class="card-block">' +
'<div class="remove" data-id="' + activities[i].id + '">X</div>' +
'<h4 class="card-title">'+ activities[i].name + '</h4>' +
'<ul class="card-text">' +
'<li>Total time spent: 2h 25min 34sec</li>' +
'</ul>' +
'Go to this activity' +
'</div>' +
'</div>' +
'</div>'
}
actCardContainer.innerHTML = items;
// ... for attach event read on
};
Notes:
Do not set the same id if an element appears many times
Set innerHTML once not for each loop iteration
Set unique id for every item (you could generate random numbers for example)
To attach events you would need to do it as follows (taken from question ):
var removeLink = document.querySelectorAll('.remove');
Then you would loop:
for (var i = 0; i < deleteLink.length; i++) {
removeLink[i].addEventListener('click', function(event) {
var acrtivityId = event.currentTarget.getAttribute('data-id');
removeActivity(acrtivityId);
// Use
});
}
Now for the removal you can find current activity in the activity array and remove it. Use find and then splice for example. And save the change array to local storage. On creation assign an id.
Related
I am writing a piece of code to basically call in the top money earner and the top five money earners in a given data set. While writing the code, I realized that there were a couple of spots where I was rewriting the code, basically copying and pasting it. While that works, I wanted to throw the duplicate portion of the code and call it from a function. However, that is not working and I don't exactly know why. Here is the code that is duplicated:
for (let i = 0; i < len; i++) {
html +=
'<li class="top">' +
'<h2>' +
topSalaries[i][8] +
'</h2>' +
'<h3>' +
topSalaries[i][11] +
'</h3>';
}
container.innerHTML = '<ul id = "topSalaries">' + html + '</ul>';
Here is the function I made to be called. However, when I call it, it's not working as expected, where the information shows up on the webpage. I'm using VS Code and am running this on live server so when I save, the webpage automatically updates.
function createHtmlElements(len, html) {
for (i = 0; i < len; i++) {
html +=
'<li class="top">' +
'<h2>' +
topFiveSalaries[i][8] +
'</h2>' +
'<h3>' +
topFiveSalaries[i][11] +
'</h3>' +
'</li>';
}
return html
}
function getTopSalaries(boston, container) {
const people = boston.data;
const len = 5; // only want top five
let topFiveSalaries = sortPeople(people).slice(0,len);
// create the list elements
html = createHtmlElements(len, html);
container.innerHTML = '<ul id = topSalaries">' + html + '</ul>';
}
For one thing topFiveSalaries is going to be undefined in the function createHtmlElements you've created, you must pass it to the function
Ok. So, Thanks Dave for the help. It looks like I also was missing a piece in that I needed to pass the array into the function as well. This is what I wrote and how I called it.
function getTopSalaries(boston, container) {
const people = boston.data;
const len = 5; // only want top five
var topFiveSalaries = sortPeople(people).slice(0,len);
let html = '';
// create the list elements
html = createHtmlElements(len, html, topFiveSalaries);
container.innerHTML = '<ul id = topSalaries">' + html + '</ul>';
}
function getTopEarner(boston, container){
const people = boston.data;
const len = 1;
let highEarner = sortPeople(people).slice(0,len);
var html = '';
// create the list elements
createHtmlElements(len, html, highEarner);
container.innerHTML = '<ul id = topSalaries">' + html + '</ul>';
}
// sort people by income in descending order
function sortPeople(people) {
people.sort(function(a, b) {
return b[11] - a[11];
})
return people
}
function createHtmlElements(len, html, array) {
for (i = 0; i < len; i++) {
html +=
'<li class="top">' +
'<h2>' +
array[i][8] +
'</h2>' +
'<h3>' +
array[i][11] +
'</h3>' +
'</li>';
}
return html
}
I'm creating a timeline page with data from database, and I want to show a image from the object in the View.
The method Get it's working fine, when it returns the var imgSrc receives the data from the byte array converted to base64, but when I try to use the var in the it shows undefinied when I inspect the page.
Someone can give me a hand on how can I solve this?
$.getJSON("../ReportsAuditsTimeLine/GetAuditsResultbyAudit", { AuditID: ID },
function (data) {
var datafromaudit = '';
var div = document.createElement('div');
$('#timeLine').empty();
for (var i = 0; i < data.length; i++)
{
var base64 = "";
var imgSrc = "";
if (data[i].AUDIT_PICTURE != null)
{
//CHECK IMAGE
try {
base64 = Convert.ToBase64String(data[i].AUDIT_PICTURE);
imgSrc = String.Format("data:image/png;base64,{0}", base64);
console.log("Imagem:", imgSrc);
}
catch (Exception) {
}
//END IMAGE
}
if (data[i].AUDIT_ITEM_STATUS == "PASS") {
if (data[i].AUDIT_PICTURE != null) {
datafromaudit += '<li><i class="fa fa-camera bg-green"></i> ' +
'<div class="timeline-item">' +
'<span class="time">' +
'</span>' +
'<h3 class="timeline-header"><b>ID:' + data[i].ID + " - " + data[i].DESCRIPTION +
'</b></h3>' +
'<div class="timeline-body"> WEIGHT: <b>' + data[i].OD + '</b> STATUS: <b style=color:green;>' + data[i].AUDIT_ITEM_STATUS + '</b>' + '<img src="' + $.imgSrc + '"class="margin" ></img>' + ' </div>' +
'<div class="timeline-footer"/>'
'</div></li>'
}
else
{
datafromaudit += '<li><i class="fa fa-pencil-square-o bg-green"></i> ' +
'<div class="timeline-item">' +
'<span class="time">' +
'</span>' +
'<h3 class="timeline-header"><b>ID:' + data[i].ID + " - " + data[i].DESCRIPTION +
'</b></h3>' +
'<div class="timeline-body"> WEIGHT: <b>' + data[i].OD + '</b> STATUS: <b style=color:green;>' + data[i].AUDIT_ITEM_STATUS + '</b>' + ' </div>' +
'<div class="timeline-footer"/>'
'</div></li>'
}
}
}
CONTROLLER
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetAuditsResultbyAudit(string AuditID)
{
var viewModel = new ReportsAuditTimeLineViewModel();
int auditID = Int32.Parse(AuditID);
var auditResults = viewModel.GetAuditsResultbyAudit(auditID);
return Json(auditResults, JsonRequestBehavior.AllowGet);
}
VIEWMODEL
public List<AuditsResultData> GetAuditsResultbyAudit(int AuditID)
{
var list = new List<AuditsResultData>();
var context = new OnlineAuditsEntities();
using (context)
{
var query = from audits in context.tb_Audits
join i in context.tb_AuditItem on audits.AUDIT_ITEM_ID equals i.ID
join a in context.tb_Audit on audits.AUDIT_ID equals a.ID
join s in context.tb_Audit_ItemStatus on audits.STATUS_ID equals s.ID
where audits.AUDIT_ID == AuditID
select new { audits, i,a,s};
foreach (var s in query)
{
var Photo = (from pic in context.tb_AuditPictures
where pic.AUDIT_ID == s.audits.ID
select pic.PICTURE).FirstOrDefault();
if (Photo!=null)
{
list.Add(new AuditsResultData
{
ID = s.audits.ID,
AUDIT_ITEM_ID = s.audits.AUDIT_ITEM_ID,
DESCRIPTION = s.i.SUBCATEGORY_DESCRIPTION,
HASFIND = s.i.HAS_FINDING ?? false,
FINDS = s.audits.FINDINGS ?? 0,
STATUS_ID = s.audits.STATUS_ID,
AUDIT_ITEM_STATUS = s.s.STATUS_DESCRIPTION,
OD = s.audits.OD ?? 0,
COMMENTS = s.audits.COMMENTS,
SCANS = s.audits.SCANNED_CODE,
AUDIT_ID = s.audits.AUDIT_ID,
AUDIT_PICTURE = Photo
});
}
}
}
return list;
}
You should pass picture to view as Base64String from controller. Then convert it to picture like:
var picture = "data:image/jpg;base64," + data.base64image;
I'm making a page with a list of products (which are loads using ajax) but i want to show only 6 products/page but i don't know how to do it and i don't find any examples that implements what i want. So for example if i have 20 products i want to show 6 in the first page, 6 in the second, .. etc to the last product in the last page (the page is always the same only the products change).
So in the end of the page i must have page 1-n
Can someone help me?
this is the js that load the products and show them one below the other:
$(document).ready(function () {
$.ajax({
type: "GET",
url: "json/projects.json",
dataType: "json",
success: function (data) {
showInfo(data);
},
});
});
function showInfo(data) {
var htmlString = "";
if (data.length == 0) {
htmlString =
"<span id = " +
"message>" +
"Non รจ stato trovato alcun progetto" +
"</span>";
$("#list").append(htmlString);
} else {
//altrimenti stampo data
for (i = 0; i < data.length; i++) {
//scorro tutto il mio file json
htmlString =
"<div class = " + "project id = " + data[i].id + ">" +
"<div class =" + "row-list>" +
"<div class = " + "title>" + data[i].title + "</div>" +
"<div class = " + "info>" + "<img src = " + "img/user.png>" + data[i].username + "</div>" +
"<div class = " + "info>" + "<img src = " + "img/budget.png>" + data[i].budget + "</div>" +
"<div class = " + "info>" + "<img src = " + "img/data.png>" + data[i].data + "</div>" +
"<div class = " + "flag>" + data[i].flag + "</div>" +
"</div>";
// collego al div #list le informazioni
$("#list").append(htmlString);
}
// aggiungo l'handler per visualizzare i dettagli quando un progetto viene cliccato
$(".project").click(function () {
window.location.href = "details.php?id=" + $(this).attr("id");
});
}
}
If the page doesn't change, you can stay on the same page while simply changing the products shown.
Here's a simplified version to demonstrate how this could work:
// create 20 product names
let products = [];
for (let i=1; i<=20; i++) {
products.push(`This is Product Name ${i}`);
}
let firstShown = 0;
const display = document.getElementById('display');
// display up to 6 products on page
function addToDisplay(first) {
display.innerHTML = '';
let last = Math.min(first+5, products.length-1);
for (let i = first; i <= last; i++) {
let li = document.createElement('li');
li.innerHTML = products[i];
display.appendChild(li);
}
}
function forward () {
display.innerHTML = '';
firstShown += 5;
addToDisplay(firstShown);
}
function back () {
display.innerHTML = '';
firstShown = Math.max(firstShown-5, 0);
addToDisplay(firstShown);
}
// show initial 6 producs
addToDisplay(firstShown);
<p>Display multiple products 6 at a time<br/>
<button type="button" onclick="back();">Back</button>
<button type="button" onclick="forward();">Forward</button>
</p>
<ul id="display"></ul>
Im trying to change the cursor logo when Im building a dynamic div. Depending on how much data it can take up a few seconds to load so I need the cursor change.
The problem Im having is that the cursor isnt changing until my code has fully executed.
Im have a dynamically generated chart with the points in the chart set to popup more data when they are clicked. This is the eventListener Ive created and it works fine apart from my CSS update not getting applied until it has exited the function.
Any idea how I can force it to update immediately
point.addEventListener('click', function (evt) {
document.body.className = 'waiting';
var evtPoint = document.getElementById(evt.currentTarget.id);
var index = evtPoint.id.substring(evtPoint.id.lastIndexOf('-') + 1, evtPoint.id.length);
var chartOptions = Charts.options[elementId];
var txnData = chartOptions.data.txn[index];
var txnFullData = chartOptions.data.txnFull;
var theDate = new Date(txnData.time);
// pop up
var txnsPerMinutePopUp = document.getElementById('txnsPerMinutePopUp');
txnsPerMinutePopUp.innerHTML = '<div id = "txnsPerMinutePopUp-bg"></div>' +
'<div id = "txnsPerMinutePopUp-body">' +
'<div id = "txnsPerMinutePopUp-body-heading"></div>' +
'<div id = "txnsPerMinutePopUp-body-txns">';
var txnsPerMinutePopUpHeading = document.getElementById('txnsPerMinutePopUp-body-heading');
var txnsPerMinutePopUpBody = document.getElementById('txnsPerMinutePopUp-body-txns');
function addZero(i) {
if (i < 10) {
i = '0' + i;
}
return i;
}
for (var i = 0; i < txnFullData.length; i++) {
// console.log("loop" + i, txnFullData);
var date = new Date(txnFullData[i].time);
if (date.getTime() === theDate.getTime()) {
txnsPerMinutePopUpHeading.innerHTML = '<div class="txnsPerMinutePopUp-body-heading-title">Tweets</div><div class="txnsPerMinutePopUp-body-heading-time">' + addZero(theDate.getHours()) + ':' + addZero(theDate.getMinutes()) + '</div>';
var child = '<div class = "txnsPerMinutePopUp-txns">' +
'<div class = "txnsPerMinutePopUp-txns-img">' +
'<object data = "' + txnFullData[i].profile_image_url + '" class = "border-rad-25 cross-series-profile-img" width = "50px" height = "50px" type = "image/jpeg">' +
'<img src = "assets/img/engager_profile_default-47.svg" class = "border-rad-25 cross-series-profile-img" width = "50px" height = "50px" alt = "' + txnFullData[i].screen_name + ' profile image" />' +
'</object>' +
'</div>' +
'<div class = "txnsPerMinutePopUp-txns-screen-name">' +
'#' + txnFullData[i].screen_name + '' +
'</div>' +
'<div class = "txnsPerMinutePopUp-txns-text">' + Charts.lineChart.parseText(txnFullData[i].text) + '</div>' +
'</div>';
txnsPerMinutePopUpBody.innerHTML += child;
}
}
txnsPerMinutePopUp.innerHTML += '</div>' +
'</div>';
//document.body.style.cursor='default';
txnsPerMinutePopUp.style.visibility = 'visible';
var bg = document.getElementById('txnsPerMinutePopUp-bg');
bg.addEventListener('click', function (evt) {
txnsPerMinutePopUp.style.visibility = 'hidden';
});
}, false);
My CSS then is just
body.waiting * { cursor: wait; }
UPDATE
From researching potential causes I found out that most browsers wont update the DOM immediately and I need to interrupt the javascript to allow for the DOM to get updated.
Ive updated my code to move the bulk of the operations out to a separate function and tried to set a timeout value on it and its still not updating the cursor until everything completes.
I also tried to add a mousedown event to try and get ahead of the javascript in the on click but it didnt work either
EventListener
point.addEventListener('click', function (evt) {
//document.body.className = 'waiting';
// setTimeout(function() {
Charts.lineChart.changeCursor();
// },10);
var evtPoint = document.getElementById(evt.currentTarget.id);
var index = evtPoint.id.substring(evtPoint.id.lastIndexOf('-') + 1, evtPoint.id.length);
var chartOptions = Charts.options[elementId];
var txnData = chartOptions.data.txn[index];
var txnFullData = chartOptions.data.txnFull;
var theDate = new Date(txnData.time);
function addZero(i) {
if (i < 10) {
i = '0' + i;
}
return i;
}
setTimeout(function() {
Charts.lineChart.breakOut( txnFullData,theDate );
},100);
document.body.style.cursor='default';
txnsPerMinuteTweetsPopUp.style.visibility = 'visible';
}, false);
and the following code was moved into the breakout function
breakOut
Charts.lineChart.breakOut = function(txnFullData,theDate){
function addZero(i) {
if (i < 10) {
i = '0' + i;
}
return i;
}
var txnsPerMinutePopUp = document.getElementById('txnsPerMinutePopUp');
txnsPerMinutePopUp.innerHTML = '<div id = "txnsPerMinutePopUp-bg"></div>' +
'<div id = "txnsPerMinutePopUp-body">' +
'<div id = "txnsPerMinutePopUp-body-heading"></div>' +
'<div id = "txnsPerMinutePopUp-body-txns">';
var txnsPerMinutePopUpHeading = document.getElementById('txnsPerMinutePopUp-body-heading');
var txnsPerMinutePopUpBody = document.getElementById('txnsPerMinutePopUp-body-txns');
for (var i = 0; i < txnFullData.length; i++) {
// console.log("loop" + i, txnFullData);
var date = new Date(txnFullData[i].time);
if (date.getTime() === theDate.getTime()) {
txnsPerMinutePopUpHeading.innerHTML = '<div class="txnsPerMinutePopUp-body-heading-title">Tweets</div><div class="txnsPerMinutePopUp-body-heading-time">' + addZero(theDate.getHours()) + ':' + addZero(theDate.getMinutes()) + '</div>';
var child = '<div class = "txnsPerMinutePopUp-txns">' +
'<div class = "txnsPerMinutePopUp-txns-img">' +
'<object data = "' + txnFullData[i].profile_image_url + '" class = "border-rad-25 cross-series-profile-img" width = "50px" height = "50px" type = "image/jpeg">' +
'<img src = "assets/img/engager_profile_default-47.svg" class = "border-rad-25 cross-series-profile-img" width = "50px" height = "50px" alt = "' + txnFullData[i].screen_name + ' profile image" />' +
'</object>' +
'</div>' +
'<div class = "txnsPerMinutePopUp-txns-screen-name">' +
'#' + txnFullData[i].screen_name + '' +
'</div>' +
'<div class = "txnsPerMinutePopUp-txns-text">' + Charts.lineChart.parseText(txnFullData[i].text) + '</div>' +
'</div>';
txnsPerMinutePopUpBody.innerHTML += child;
}
}
txnsPerMinutePopUp.innerHTML += '</div>' +
'</div>';
var bg = document.getElementById('txnsPerMinutePopUp-bg');
bg.addEventListener('click', function (evt) {
txnsPerMinutePopUp.style.visibility = 'hidden';
});
}
This is my code, everything works, but I can not pass the variable "obj" inside the function $$('.create-popup').on('click', function () {...
I need to get the data into the variable {{contenido}}, but I can not access.
Create-popup function works, the popup is generated, but I can not get the data variable to pass them into the function.
myApp.showPreloader('Cargando notas');
$$.getJSON("http://fabianleguizamon.com.ar/wp-json/wp/v2/posts", function(jsondata){
myApp.hidePreloader();
var old=jsondata;
//next - your code
//var old=data;
var obj=[];
for(var i=0;i<old.length;i++){
var tit=old[i]["title"];
var con=old[i]["content"];
var exc=old[i]["excerpt"];
var fec=new Date(old[i]["date_gmt"]);
var fec2 = fec.getDate() + '/' + (fec.getMonth() + 1) + '/' + fec.getFullYear();
var img=old[i]["better_featured_image"]["media_details"]["sizes"]["oblique-entry-thumb"];
var bdy=old[i]["acf"];
var o=[];
var t={};
var z={};
t.id=i+1;
t.titulo=tit["rendered"];
t.contenido=con["rendered"];
t.bajada=exc["rendered"];
t.enlace=img["source_url"];
t.fecha=fec2;
obj.push(t);
}
var myList = myApp.virtualList('.list-block.media-list.virtual-list.accordion-list', {
items: obj,
// Custom search function for searchbar
searchAll: function (query, items) {
var found = [];
for (var i = 0; i < items.length; i++) {
if (items[i].title.indexOf(query) >= 0 || query.trim() === '') found.push(i);
}
return found; //return array with mathced indexes
},
template:
'<li class="accordion-item">' +
'<a href="#" data-popup="popup{{id}}" class="item-link item-content create-popup">' +
'<div class="item-inner">' +
'<div class="item-title-row">' +
'<div class="item-title">{{titulo}}</div>' +
'</div>' +
'<div class="item-text">{{fecha}}</div>' +
'</div>' +
'</a>',
height: 100,
});
$$('.create-popup').on('click', function () {
var popupHTML = '<div class="popup">'+
'<div class="content-block">'+
'<p>{{contenido}}</p>'+ <---- I can't access here!!!!!
'<p>Cerrar</p>'+
'</div>'+
'</div>'
myApp.popup(popupHTML);
});
});