How do I get Photoswipe caption text? - javascript

I'm hoping this isn't too silly of a question, but I've been stuck on this problem for hours now and could use some help/guidance with it.
I'm using ACF Gallery in WP, and I'm now trying to turn this into a popup slider. So I decided to use the Photoswipe plugin to achieve this.
I have the slider working fine, it's just that I can't figure out how to output the image caption with each image.
<?php
$popup_gallery = get_field('popup_gallery','option');
$popup_gallery_json = json_encode($popup_gallery,JSON_FORCE_OBJECT);
?>
<div class="popup-gallery-data" data-json='<?php echo $popup_gallery_json;?>'
data-json-length="<?php echo count($popup_gallery);?>" >
</div>
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<div class="pswp__bg"></div>
<div class="pswp__scroll-wrap">
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
var galleryArr = [];
var galleryJson = $('.popup-gallery-data').data('json');
// get the number of objects
var jsonLength = $('.popup-gallery-data').data('json-length');
// push each object into the array;
for (let i = 0; i < jsonLength; i++) {
galleryArr.push(galleryJson[i]);
}
$('a[href*="#popup-gallery"]').click(function (e) {
e.preventDefault();
// Prevent errors.
if (jsonLength > 0) {
popUpGallery(galleryArr);
}
})
var popUpGallery = function (data) {
const json = data;
var pswpElement = document.querySelectorAll('.pswp')[0];
// build items array
var items = [];
json.map((img) => {
items.push({
src: img.url,
w: img.width,
h: img.height
})
})
// define options (if needed)
var options = {
};
var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
}

caption should be an available key so you can update your code like below:
json.map((img) => {
items.push({
src: img.url,
w: img.width,
h: img.height,
title: img.caption
})
})

Related

Bootstrap modal not showing with JavaScript " $("#attributeUpdateModal").modal('show');"

I am new to JavaScript and I'm working on a project with openlayers and geoserver and I need to add features to a layer. I succeeded to draw a feature but for saving it I need to enter its attributes which I implemented in a bootstrap modal but when I finish drawing the modal doesn't show I get just a transparent page and it stays like that.
Here it is my html code :
<!-- Attribute Update Modal -->
<div class="modal " id="attributeUpdateModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="exampleModalLabel">Attributes</h3>
<button class="btn-close btn-light" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="attribute-body">
<div id="attributeContainer"></div>
</div>
<div class="modal-footer">
<div class="col-md-12 text-center">
<button id="btnSave" type="button" class="btn btn-success">
Save
</button>
<button id="btnCancel" type="button" class="btn btn-warning">
Cancel
</button>
</div>
</div>
</div>
</div>
</div>
Here it is my JavaScript code :
drawInteraction.on("drawend", function (e) {
var feature = e.feature;
feature.set("geometry", feature.getGeometry());
modifiedFeatureList.push(feature);
var featureProperties = editGeoJSON
.getSource()
.getFeatures()[0]
.getProperties();
document.getElementById("attributeContainer").innerHTML = "";
for (var key in featureProperties) {
if (featureProperties.hasOwnProperty(key)) {
if (key != "geometry") {
if (key != "id") {
var div = document.createElement("div");
div.className = "mb-3";
var lbl = document.createElement("label");
lbl.className = "form-label";
lbl.innerHTML = key;
var inputBox = document.createElement("input");
inputBox.className = "form-control";
inputBox.id = key;
inputBox.value = "";
div.appendChild(lbl);
div.appendChild(inputBox);
document.getElementById("attributeContainer").appendChild(div);
}
}
}
}
$("#attributeUpdateModal").modal('show');
});
Does anyone have an idea about this issue?

How to insert html element inside the index.html from javascript

I want to insert the card into container using javascript. How do I do it. or make those card display in flex. So it's not like shown in below pic. I have used insertAdjancentHTML to insert the data in note class using javascript. However i'm unable to put them in container.
const addBtn = document.getElementById("add");
const addNewNote = (text = "") => {
const note = document.createElement("div");
note.classList.add("note");
const htmlData = `<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-primary">
<i class="bi bi-trash"></i>
</button>
</span>
</div>
<hr />
<p class="card-text">
Some quick example text to build on the card title and make up the
bulk of the card's content.
</p>
</div>
</div>`;
note.insertAdjacentHTML("afterbegin", htmlData);
console.log(note);
document.body.appendChild(note);
};
addBtn.addEventListener("click", () => {
addNewNote();
});
Firstly, just use innerHTML - it's an empty element:
note.innerHTML = htmlData;
Secondly, you need to select the element to append this note to. Add an ID:
<div class="container d-flex" id="noteContainer">
And append it like so:
document.getElementById("noteContainer").appendChild(note);
You can add an identifier to the div an use the appendChild to this div instead of the body of the document
<div id="myDiv" class="container d-flex"></div>
And at the end of your function
document.getElementById("myDiv").appendChild(note);
Working example
const button = document.getElementById("addButton")
const addNote = () => {
const myElement = document.createElement('p')
myElement.innerHTML = "Hello world !"
const div = document.getElementById("myDiv")
div.appendChild(myElement)
}
button.addEventListener("click", addNote)
<button id="addButton">Add element</button>
<div id="myDiv"></div>
Cache the container element.
Return the note HTML from the function (no need to specifically create an element - just wrap the note HTML in a .note container), and then add that HTML to the container.
(In this example I've used unicode for the icons, and a randomiser to provide some text to the note.)
const container = document.querySelector('.container');
const addBtn = document.querySelector('.add');
function createNote(text = '') {
return`
<div class="note">
<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">🖉</button>
<button class="btn btn-primary">🗑</button>
</span>
</div>
<hr />
<p class="card-text">${text}</p>
</div>
</div>
</div>
`;
};
function rndText() {
const text = ['Hallo world', 'Hovercraft full of eels', 'Two enthusiastic thumbs up', 'Don\'t let yourself get attached to anything you are not willing to walk out on in 30 seconds flat if you feel the heat around the corner'];
const rnd = Math.round(Math.random() * ((text.length - 1) - 0) + 0);
return text[rnd];
}
addBtn.addEventListener('click', () => {
const note = createNote(rndText());
container.insertAdjacentHTML('afterbegin', note);
});
<div>
<button type="button" class="add">Add note</button>
<div class="container"></div>
</div>

Uncaught TypeError: Cannot read properties of undefined (reading 'indexOf') in my click function

I have this function connected to the click of a button, but it gives me this problem, how could I solve it?
function ClickHelp() {
if ($("#text_help").html()=="" || $("#text_help").html().indexOf("non presente per il")>0){
if ($("#frameapplication").length>0)
var titolo2=document.getElementById("frameapplication").contentWindow.location.href.replace(".html","").split("/");
var url = '';
var nomecompleto = '';
if (titolo2.length > 0) url = titolo2[titolo2.length - 1];
nomecompleto = "/htdocs/" + url.replace(/\.[^/.]+$/, "") + "_help.html";
$("#text_help").load(nomecompleto);
}
}
<div class="help-container" id="help-container" onclick="ClickHelp()">
<button class="menu" id="sized" onclick="document.getElementById('help').style.display='block'">
<i class="fa fa-question"></i></button>
</div>
<div class="modal" id="help">
<div class="modal-content_menu animated fadeInRight">
<div class="w3-container">
<div class="modal-header_menu">
<span class="close"onclick="document.getElementById('help').style.display='none'">×</span>
<div id="text_help" class="modal-body_menu"></div>
</div>
</div>
</div>
</div>

How to bind this within js nested object iteration within a function. Jquery

again, probably a terrible title - but what I'm trying to do is to make a simple search feature on my website. You click a nav button, which updates the search bar, whi in turn triggers an onchange event to update the current appended list.
function update() {
var list = $("#comic__modern-list");
list.empty();
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var filter = comics[this].type;
var publisher = comics[this].publisher;
if (search == "") {
if(filter == "modern") {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
} else if (search == publisher) {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
});
}
The current list is generated by this, which works fine:
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var currentObject2 = comics[this].type;
console.log(currentObject2);
if (search == "") {
if(currentObject2 == "modern") {
var list = $("#comic__modern-list");
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
}
});
From what I can gather, this has to do with the keyword "this" no longer meaning what it did when it was outside of the function, so I'm assuming the fix will be to do with bind(), but I can't make heads nor tails of it.
p.s, if there's an easier/simpler way to set up a search system, please enlighten me!

Error in d3.js using jQuery and dc.js

I'm new in programming, and I'm trying to implement a search button that can enable me to filter datas .
I have on my serv a JSON data at the url /tweets_complet . Then I want to get another JSON which depends on the input from the search button . Once I have the two JSON, I wrote some code, which I think is not important .
Here is the js code :
function main(){
$.getJSON("/tweets_complet", insererDonneesJson);}
function insererDonneesJson(data){
$('button').on('click', get_data);
function get_data() {
var cashtagg=$('#cash').val();
$.getJSON("/"+cashtagg, filter);
function filter(data2) {
//Tweets datas
var tweets = data;
var dateFormat = d3.time.format("%Y-%m-%d %H:%M:%S");
tweets.forEach(function(d) {
d["cleandate"] = dateFormat.parse(d["cleandate"]);
d["cleandate"].setSeconds(0);
});
//Create a Crossfilter instance
var ndx = crossfilter(tweets);
//Define Dimensions
var cleandateDim = ndx.dimension(function(d) { return d["cleandate"]; });
var sentimentDim=ndx.dimension(function(d) { return d["sentiment"]; });
var bnscoreDim=ndx.dimension(function(d) { return d["bnscore"]; });
var tickerDim=ndx.dimension(function(d) { return d["collection_name"];});
var newTickerDim = tickerDim.filter(cashtagg);
//Calculate metrics
var numTweetsByTicker=newTickerDim.group()
var numTweetsByDate = cleandateDim.group();
var numTweetsByBnscore = bnscoreDim.group();
var totalScoreByDate = cleandateDim.group().reduceSum(function(d) {
return d["sentiment"]*10/(numTweetsByDate.size());})
var all = ndx.groupAll();
var numTweetsBySentiment = sentimentDim.group();
//Define values (to be used in charts)
var minDate = cleandateDim.bottom(1)[0]["cleandate"];
var maxDate = cleandateDim.top(1)[0]["cleandate"];
//Datas cashtag
var datas = data2;
var dateFormatO = d3.time.format("%Y-%m-%d");
datas.forEach(function(d) {
d["Date"] = dateFormatO.parse(d["Date"]);
});
// Create a Crossfilter instance
var ndxO = crossfilter(datas);
// Define Dimensions
var dateDimO = ndxO.dimension(function(d) { return d["Date"]; });
var volumeDimO=ndxO.dimension(function(d) { return d["Volume"]; });
var scoreDimO=ndxO.dimension(function(d) { return d["Low"]; });
// Calculate metrics
var groupeVolumeO = dateDimO.group().reduceSum(function(d) { return d["Volume"]/10000000;});
var groupeScoreO = dateDimO.group().reduceSum(function(d) { return d["Low"];});
var allO = ndxO.groupAll();
// Define values (to be used in charts)
var minDateO = dateDimO.bottom(1)[0]["Date"];
var maxDateO = dateDimO.top(1)[0]["Date"];
var minVolumeO = (volumeDimO.bottom(1)[0]["Volume"])/10000000;
var maxVolumeO = (volumeDimO.top(1)[0]["Volume"])/10000000;
var minScoreO = scoreDimO.bottom(1)[0]["Low"];
var maxScoreO = scoreDimO.top(1)[0]["Low"];
//Charts
var timeChart = dc.barChart("#time-chart");
var pieChart= dc.pieChart("#pie-chart")
var numberTweetsND = dc.numberDisplay("#number-tweets-nd");
var hitslineChart = dc.lineChart("#chart-line-hitsperday");
var shareChart = dc.lineChart("#share-chart");
var volumeChart = dc.lineChart("#volume-chart");
numberTweetsND
.formatNumber(d3.format("d"))
.valueAccessor(function(d){return d; })
.group(all);
timeChart
.width(800)
.height(160)
.margins({top: 10, right: 50, bottom: 30, left: 50})
.dimension(cleandateDim)
.group(numTweetsByDate)
.transitionDuration(500)
.x(d3.time.scale().domain([minDate, maxDate]))
.elasticY(true)
.xAxisLabel("Day")
.yAxis().ticks(8);
pieChart.width(350)
.height(330)
.dimension(sentimentDim)
.group(numTweetsBySentiment)
.colors(['red','black','green']);
hitslineChart
.width(600).height(330)
.dimension(cleandateDim)
.group(totalScoreByDate)
.x(d3.time.scale().domain([minDate,maxDate]));
volumeChart
.width(800).height(330)
.dimension(dateDimO)
.group(groupeVolumeO)
.x(d3.time.scale().domain([minDateO,maxDateO]));
// .y(d3.scale.linear().domain([minVolumeO,maxVolumeO]));
shareChart
.width(800).height(330)
.dimension(dateDimO)
.group(groupeScoreO)
.x(d3.time.scale().domain([minDateO,maxDateO]));
// .y(d3.scale.linear().domain([minScoreO,maxScoreO]));
dc.renderAll();
}}};
$(document).on('ready', main);
And the HTML code :
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
<link rel="stylesheet" href="./static/lib/css//bootstrap.min.css">
<link rel="stylesheet" href="./static/lib/css/keen-dashboards.css">
<link rel="stylesheet" href="./static/lib/css/dc.css">
<link rel="stylesheet" href="./static/css/custom.css">
</head>
<body class="application">
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="./">InTwittiv</a>
</div>
<div>
<ul class="nav navbar-nav">
<li class="active">Description</li>
<li>Analyse</li>
</ul>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<!-- <a href="#" class="btn btn-default btn-lg"><span class="glyphicon glyphicon-search"></span>
<div class="col-sm-10">
<input type="text" class="form-control" id="cashtag" placeholder="Cashtag">
</div>
</a> -->
<div class="col-sm-3 col-md-3 pull-right">
<div class="form-group">
<input id="cash" type="text" placeholder="Change Cashtag here" >
<button class="btn btn-sm btn-success">Chercher</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<div class="row">
<div class="col-sm-12">
<div class="chart-wrapper">
<div class="chart-title">
Tweet Volume
</div>
<div class="chart-stage">
<div id="time-chart"></div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="chart-wrapper">
<div class="chart-title">
Sentiment repartition
</div>
<div class="chart-stage">
<div id="pie-chart"></div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="chart-wrapper">
<div class="chart-title">
Sentiment repartition
</div>
<div class="chart-stage">
<div id="chart-line-hitsperday"></div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="chart-wrapper">
<div class="chart-title">
Total nb of tweets
</div>
<div class="chart-stage">
<div id="number-tweets-nd"></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="row">
<div class="col-sm-12">
<div class="chart-wrapper">
<div class="chart-title">
Volume (*10^6)
</div>
<div class="chart-stage">
<div id="volume-chart"></div>
</div>
</div>
</div>
<div class="col-sm-12">
<div class="chart-wrapper">
<div class="chart-title">
Share Price
</div>
<div class="chart-stage">
<div id="share-chart"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<p class="small text-muted">Built by Keyrus Capital Markets</p>
</div>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="./static/lib/js/bootstrap.min.js"></script>
<script src="./static/lib/js/crossfilter.js"></script>
<script src="./static/lib/js/d3.js"></script>
<script src="./static/lib/js/dc.js"></script>
<script src="./static/lib/js/queue.js"></script>
<script src="./static/lib/js/d3.layout.cloud.js"></script>
<script src="./static/lib/js/keen.min.js"></script>
<script src='./static/js/graph2.js' type='text/javascript'></script>
</body>
</html>
When I run the serv, I can enter a value in the input (FB for example) and it works . However, from here, I can't change the "cash" value into something else like AAPL since I get the error
Uncaught TypeError: undefined is not a function
d3.js:2716
This line is :
var n = d3_time_numberRe.exec(string.slice(i, i + 4));
I have no clue about the reason of the issue since I'm not familiar with $ and buttons...
Any help would be appreciated :)

Categories

Resources