How to make link sharing in php - javascript

Videos come from a folder and are automatically displayed on my website. But I am having a problem at implementing share feature. All I want to do is when share button is pressed, video's whole path like https:\\example.com\vid.mp4 should show up. I tried but it just shows the location of very last video on my page.
My php:
$exten = '.mp4';
$dir = __DIR__ . DIRECTORY_SEPARATOR . "gallery" . DIRECTORY_SEPARATOR;
$videos = glob("$dir*.{mp4}", GLOB_BRACE);
$alt = glob("$dir*.{webm,mp4,ogg}", GLOB_BRACE);
if (count($videos) > 0) { foreach ($videos as $vid) {
$base = basename($vid,'.mp4');
printf("<div class='vi'><video src='gallery/%s' id='basename($vid,'.mp4')' loop='loop'></video>", rawurlencode(basename($vid)));
echo '<div class="sh"><button class="share" onclick="phprun()">SHARE</button></div>' ;
echo "<div class='title'>".basename($vid,'.mp4')."</div></div>";
}}
?>
My js:
var result ="<?php echo('http://victure.freecluster.eu/gallery/'.basename($vid)); ?>"
const copy = document.getElementById("copy");
const h1 = document.getElementById("h1");
const h2 = document.getElementById("h2");
function phprun(){
if (copy.style.display === "none") {
copy.style.display = "block";
} else {
copy.style.display = "none";
}
h1.innerHTML="SHARE: "+"<?php echo(basename($vid,'.mp4')); ?>";
h2.innerHTML=result;
// alert(result)
}
It makes a div appear with video's path but it is showing the path of only one video.
Note:
Keep in mind it is automated.
In short:
How to display path of each video?
You can see working problem here:
Problem
Thanks in advance:)

What you need is to get the onclick target (like explained here) in order to make your content dynamic.
1. 'onclick' event: pass the 'this' parameter to your function phprun(). For an event, 'this' as a parameter refers to the target of the event (the div on which the event has been fired).
<div class="vi">
<video src="..." id="..." loop="..."></video>
<div class="sh">
<button class="share" onclick="phprun(this)"> // <-----(GET THE EVENT TARGET)
<svg class="..."></svg>
</button></div>
<div class="title">Demo from ShazamBolt8</div>
</div>
2. In your function: inject the event target ( phprun(target){...} ) then use it in your logic. Example of code for your function:
function phprun(target) { // <-----( INJECT THE EVENT TARGET)
// get the video element from the target
let videoEl = target.parentNode.parentNode.childNodes[0];
// retrieve the data you want (eg. the video url and title)
let videoUrl = videoEl.getAttribute('src');
let videoTitle = videoEl.documentQuerySelector('.title');
// inject it into the desired containers
h1.innerHTML = 'Share:' + videoTitle;
h2.innerHTML = videoUrl;
// do more stuff...
if (copy.style.display === "none") {
copy.style.display = "block";
} else {
copy.style.display = "none";
}
}

Related

How to use PHP - AJAX with mouseover event?

I have this levelselector.php page, where players can pick one of the levels. This works fine, but I want to add an extra thing. The table of the levels shows the level name, the difficulty, the count of completers (solved), and if the actual player has completed it.
This is the table with the levels
Here's what I want to do with AJAX: If I move the mouse over the CELL which shows how many players have completed the map, I want a little DIV that follows the mouse to show who the completers are. I already have the div which only appeares when the player moves over the "Solved" CELL, but I want to fill this "div" with the completers of the actual map. These completers are stored in a database, in which all the levels are stored with all their parameters, in another file, it doesn't matter.
This is the div which I want to fill with the actual level's completers
I was thinking this way: with Javascript I get the name of the Level name by getting the first "TD"-s innerHTML, and if I could give this name to PHP it would fill the DIV with the completers of the level the mouse over on is.
Here is my script.js code:
function delegate(parent, selector, type, fn) {
function delegatedFunction(event) {
let handler = this;
let target = event.target;
const closest = target.closest(selector);
if (handler.contains(closest)) {
fn.call(closest, event);
}
}
parent.addEventListener(type, delegatedFunction);
}
delegate($("table"), "td[id=completed]", "mouseover", showCompleters);
delegate($("table"), "td[id=completed]", "mouseout", hideCompleters);
async function showCompleters() {
var cursorsdiv = document.getElementById("completers");
cursorsdiv.style.visibility = "visible";
var levelname = this.closest("tr").firstElementChild.innerHTML;
const formData = new FormData();
formData.set("name", levelname);
const response = await fetch('levelselector.php', {
method: "POST",
body: formData
});
const data = await response;
document.addEventListener('mousemove', function(e){
var x = e.clientX;
var y = e.clientY;
cursorsdiv.style.left = x + 20 + 'px';
cursorsdiv.style.top = y + 10 + "px";
} )
}
function hideCompleters() {
var cursorsdiv = document.getElementById("completers");
cursorsdiv.style.visibility = "hidden";
}
(I used this delegate function to add each lines of the table mouseover events)
And here is the levelselector.php's html table part:
<table id="levelsTable">
<tr>
<th>Level</th>
<th>Difficulty</th>
<th>Solved</th>
<th>Completed by me</th>
</tr>
<?php foreach($levels as $level): ?>
<tr id="level">
<td id="levelname"><?= $level['level'] ?></td>
<td><?= $level['difficulty'] ?></td>
<td id="completed"><?= count($level['completed_by']) ?></td>
<td><?php if(in_array($_SESSION['username'],$level['completed_by'])) {
echo "Yes";
} else {
echo "No";
} ?></td>
</tr>
<?php endforeach; ?>
</table>
<div id="completers"><?= CONTENT WITH THE ACTUAL LEVEL'S COMPLETERS ?></div>
<script src="./levels/script.js" type="text/javascript" charset="utf-8"></script>
This DIV with the "completers" id would be the div which displays the completers, according to which level you move the mouse over.
Aaand here is what I could figure out in the PHP part:
<?php
$levels = load_file("levels.json");
if($_POST) {
$levelname = $_POST['name'];
}else {
$levelname = "";
}
?>
But sadly I don't understand how this AJAX works.
The question: How do you properly use AJAX in this case to fill the DIV with different content each line of the table if the mouse is moved over?
Hope you understood my english, thanks for all your help, appreciate it!!!
Peter

Javascript seems not to be working on mobile

I have a text toggle option on my (WordPress) website:
If you click on the red "info" link on the right the text under it opens. The problem is that it doesn't seem to work on mobile (iPhone 4). See the screenshot attached. It seems to me the javascript is not loading at all or just not working?
html link:
<div id="<?php the_ID(); ?>" class="projectTitel">
<?php the_title( sprintf( '<h2 class="entry-title"><button rel="bookmark" class="show">', esc_url( get_permalink() ) ), '<div class="info">Info ↓</div><div class="close_info">X</div></button></h2>' ); ?>
</div>
javascript code:
<script type="text/javascript">
var divs = document.getElementsByClassName("projectTitel");
[...divs].forEach(someDiv => someDiv.addEventListener("click", handler));
// by default, all Inhoud divs are hidden
hideElements("Inhoud");
hideElements("close_info");
jQuery('.info').show();
function handler(event) {
// get the clicked project's index :
var projectIndex = getClickedProjectIndex(event);
// toggle the right Inhoud div :
toggleDiv(document.getElementsByClassName("Inhoud")[projectIndex]);
toggleDiv(document.getElementsByClassName("close_info")[projectIndex]);
toggleDiv(document.getElementsByClassName("info")[projectIndex]);
}
// hide all elements that have the provided class name
function hideElements(className) {
var elements = document.getElementsByClassName(className);
[...elements].forEach(element => element.style.display = "none");
}
function getClickedProjectIndex(event) {
var elements = document.getElementsByClassName("projectTitel");
var projectIndex = 0;
[...elements].forEach((element, index) => {
if (element.id == event.currentTarget.id) {
projectIndex = index;
}
});
return projectIndex;
}
function toggleDiv(element) {
if (element.style.display === 'none') {
element.style.display = 'block';
} else {
element.style.display = 'none';
}
}
</script>
Replace "[...divs]" on "Array.from(divs)"
And do it for all other instances of [...{a}].

Read txt file to array + increment variable on click to access next array element: PHP or Javascript?

I am reading a short text file on server into a PHP variable ($data), and first accessing the first 2 items in the array to display them.
Then when the user clicks one of the items (which also sends form data) I want to increment the PHP variable that specifies the array item ($counter).
Reading from the file seems to be easiest to do with PHP, but incrementing at click seems easier with Javascript - and I can't figure out a good way to forge the two. What is the best way to solve this? I am fairly new to both languages.
The php/html code for reading from file (working):
<?php
function getData($subtest_nr) {
$data = file("subtests/$subtest_nr.txt");
return $data;
}
$subtest_nr = "7";
$counter = 0;
$data = getData($subtest_nr); ?>
<form id="myform" method="post">
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
</form>
A quick attempt at incrementing variable in jQuery:
jQuery(function($) {
var counter = 0;
$("img").click(function(){
counter++;
$("p").text(counter);
});
});
So my question is if I should aim for either only PHP or Javascript/jQuery for both functionalities or if there is a way for me to merge the two?
Further to the comments, here's an approach that combines the font-end and the back-end into a single file.
The file makes use of the $_SERVER['PHP_SELF'] variable to find the name of the file that's executing. We use this to write the correct name of the backend php file to request into the javascript - this has the effect of allowing us to name the single-file solution anything we want and not worry about updating a hard-coded url somewhere in the source. (got a sore head yet? :p )
index.php
<?php
if ( isset($_GET['firstItem']) && isset($_GET['numItems']) )
{
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
die; // stop execution now - dont output the html below
}
?><!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
// we want to request data from this same file, so get php to print it into the javascript source
var filename = '<?php echo $_SERVER['PHP_SELF'];?>';
// construct the url from the filename and the (GET) parameters we'd like to pass to the php
var url = filename + '?firstItem=' + firstIndex + '&numItems=' + numItems;
// ask for it, fire the onDataReceived function with the XMLHttpRequest object as the only input
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
------------------------------------------------------------
format of html the onDataReceived function needs to create
- .four_images div just once for the whole response
- .flex-item once for each item returned
------------------------------------------------------------
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
// get the raw data - it'll be a string something like `["file1.txt\n","file2.swf\n"]`
var rawData = ajax.response;
// parse it and turn it from a string into some javascript objects.
// this has same the effect as typing the following into your source-code
//
// var parsedData = [ "file1.txt\n", "file2.swf\n" ];
//
// except, you can do it with unknown data. BUT: we must know the *format*
// of the data so we know what to do with it. We happen to know that
// the data will be an array
var parsedData = JSON.parse(rawData);
// make the outer wrapper - refer above for the structure of the created HTML
// this wrapper needs to exist so the makeItem function can append content
// to it in the forEach call
var div = newEl('div');
div.className = 'four_images';
// for each of the items in the parsedData array, call the makeItem function - once this forEach call is done,
// we have the contents of the form all sitting in the [div] element - the makeItem function is inside this onDataReceived function
// so that it can 'see' the [div] variable in order to append each item to it.
forEach(parsedData, makeItem);
// show the results
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
// this function has now finished executing. the makeItem function exists here (unfortunately) so that
// the [div] element remains in scope.
// called with the current element in the collection as dataItem, it's index in the collection as index and the collection itself as arrayOfItems
// we're making use of the item's index to correctly set the id of the radio-button and then to make the label refer to it (which it doesn't actually
// need to do in this case, since the label element contains the input)
// another use of index is to place a comma between items i.e "1,2,3,4,5,6" - there are two approaches. The naive one is to place a comma after each
// item except the last one. To do this - we need to know how many items there are in total - sometimes this is very expensive to compute.
// the other approach, is to put a comma _before_ all items except the first one.
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere'; // **** the example had 7.11 and 7.12 here - I've no idea how they were determined ***
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Retrieve records</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
Here's a rough example, sans error checking. I don't jQuery, so you'll need to convert this to make use of jQuery's ajax method. Can't tell what you're trying to achieve with each image click either, so you can edit that back in.
My primary aim, was to show a means by which the front-end can maintain state information and can use this to request to desired info from a (dumb) backend.
sampleInput.txt
file1.txt
file2.swf
file1.pdf
file1.exe
file1.asm
getItems.php
<?php
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
?>
getStuff.html
<!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
/////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
var url = 'getItems.php?firstItem=' + firstIndex + '&numItems=' + numItems;
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
var rawData = ajax.response;
var parsedData = JSON.parse(rawData);
var div = newEl('div');
div.className = 'four_images';
forEach(parsedData, makeItem);
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere';
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Submit</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
I guess the data you got is ajax data. So need to be $(document).on(...
var counter = 0;
$(document).on('click','img', function(){
counter++;
$("p").text(counter);
});

img tag being added onto an already open img tag

Excuse the vague question title. Not entirely sure on how to word this.
Basically my issue stems from a bit of jquery in which when setting the data attr in the html the img tag shows some odd behavior as shown below.
<img src="images/gallery/
<img src="/images/gallery/bob.png" class="thumbnail" data="1">
" class="popupImage">
From what I am seeing is the class "popupImage" is not replacing the class "thumbnail" however the img tag nested in the outer img tag should be a seperate entity all together, my mind is baffled, and have been at this for hours and probably just need a new pair of eyes to look over it.
Any help would be greatly appreciated
This is the full html code and jQuery code for the gallery.
If I can provide anymore information who needs it please ask and I shall try and give some more where possible.
HTML
<?php
$data = $db->query("SELECT * FROM `gallery_items` ORDER BY id ASC");
//display query results
?>
<br /><br />
<?php
foreach($data as $item)
{
echo "<a data='".$item['id']."' class='noStyle'>
<img src='/images/gallery/".$item['image']."' class='thumbnail' data='".$item['id']."'>
</a>";
}
if(count($data) < 1){
echo "<p style='text-align: center;'><br /><br />No results found</p>";
}
?>
<div class="image">
<button class="prev" data="unset"><</button>
<img src='' class="popupImage">
<button class="next" data="unset">></button>
</div>
jQuery
$(".noStyle").click(function(){
loadPopup($(this).attr("data"));
});
offFocus();
function loadPopup(id){
imgSrc = "/images/gallery/"+$("a[data='"+id+"']").html();
$("div.background").fadeIn(400, function(){
$(".popupImage").attr("src", imgSrc);
$(".image").fadeIn(500);
reFocus();
setPrevNext($("button[data='"+id+"']"));
});
$(window).resize(function(){
reFocus();
});
function reFocus(){
$(".image").css({"left": (($(window).width()/2) - ($(".image").width()/2))+"px", "top": (($(window).height()/2) - ($(".image").height()/2))+"px"});
};
}/*close loadPopup */
function setPrevNext(buttonObj){
objects = $(".button");
firstObj = $(".button:first");
lastObj = $(".button:last");
prev = undefined;
next = undefined;
if(buttonObj.attr("data") == firstObj.attr("data"))
prev = lastObj;
else
prev = objects.eq(objects.index(buttonObj)-1);
if(buttonObj.attr("data") == lastObj.attr("data"))
next = firstObj;
else
next = objects.eq(objects.index(buttonObj)+1);
$(".prev").attr("data", prev.attr("data"));
$(".next").attr("data", next.attr("data"));
//next = buttonObj.next("button").attr("data");
//$(".next").attr("data", "next");
}
function offFocus() {
$(".background").click(function(){
$(".background").css({"display": "none"});
$(".image").css({"display": "none"});
});
};

Hide inline edit image button not working

I have this problem. I can't figure what's wrong with my code. All i need to do is to hide the inline edit image button whenever the $principal_amt==$balance_amt but my code does nothing. Here's my code:
// Edit image button:
<td <?php echo $rowclass; ?>>
<?php echo $html->linkWithImage('Edit','cashadvance/update/' . $cashadvance["id"], array(), 'editicon.png', array('class' => 'try')); ?>
</td>
//JS:
$("#principal_amt").change(function(){
var principal = $("#principal_amt").val();
$("#balance_amt").val(principal);
if("#balance_amt" == "#principal"){
$('.try').show(true);
}
else{
$('.try').hide(true);}
});
you are comparing with the the ID's not there values in if("#balance_amt" == "#principal")
that should be :
$("#principal_amt").change(function(){
var principal = $("#principal_amt").val();
$("#balance_amt").val(principal);
if($("#balance_amt").val() == principal){
$('.try').show(true);
}
else{
$('.try').hide(true);}
});
you compare two different string:
if("#balance_amt" == "#principal"){
This means: if the string #balance_amt = #principal then.. but this is always false.
If I understand well your problem try to change to this your code:
$("#principal_amt").change(function(){
var principal = $("#principal_amt").val();
$("#balance_amt").val(principal);
if($("#balance_amt").val() == principal){
$('.try').show(true);
}
else{
$('.try').hide(true);
}
});
In this case is always true...

Categories

Resources