Having javascript apply to multiple elements created by php foreach loop - javascript

I have this php foreach loop, which read the videos saved in a folder and load them into my page.
Under the videos I have created a like and dislike button, which i would like to work with javascript.
The problem is that I cant figure out, how to point js to buttons, when i create unique ID's for the buttons, with a counter in my foreach loop.
My php.
$i=1;
foreach($allfiles as $file) {
if($file != '.' && $file != '..' && $file != video/ini) // sikre den ikke
producere . og .. files
{
echo "<div>
<div>
<video width=\"$videoW\" height=\"$videoH\"
controls>
<source src=\"". $dir . $file ."\" type=\"video/mp4\">
<source src=\"". $dir . $file ."\" type=\"video/ogg\">
</video>
</div>
<div><strong> Recorded:</strong> $file </div> </div>";
echo '<img src="/img/like-icon.png" id="like'.$i.'"
style="width:40px;height:40px;">';
echo '<img src="/img/dislike-icon.png" id="dislike'.$i.'"
style="width:40px;height:40px;">';
echo '<p style=display:none; id="text'.$i.'">Submitted!</p>';
$i++;
My javascript
<script type='text/javascript'>
for (var i = 0; i < 100; i++) {
var button = document.getElementById(like[i]);
var button2 = document.getElementById(dislike[i]);
button.onclick = function() {
var text = document.getElementById(text[i]);
var like = document.getElementById(like[i]);
var dislike = document.getElementById(dislike[i]);
if (text.style.display !== 'none') {
text.style.display = 'none';
}
else {
text.style.display = 'block';
like.style.display = 'none';
dislike.style.display = 'none';
}
};
button2.onclick = function() {
var text = document.getElementById(text[i]);
var dislike = document.getElementById(dislike[i]);
var like = document.getElementById(like[i]);
if (text.style.display !== 'none') {
text.style.display = 'none';
}
else {
text.style.display = 'block';
like.style.display = 'none';
dislike.style.display = 'none';
}
};
};

Your code is very weird... Why are you looping a hundred time to select one element ?
You should look at querySelector and querySelectorAll with which you can select anything using a css selector. For example :
document.querySelectorAll('.like');
Will return a node list (which you can loop over) containing every element with class="like"
In this case you might want to add an event listener over each element. You can imagine something like this :
var likes = document.querySelectorAll('.like');
for (var i = 0, length = likes.length; i < length; i++) {
likes[i].addEventListener('event', myFunction);
}
If you don't like querySelectors, you still have some other ways to select multiple elements such as :
getElementsByClassName
getElementsByTagName
Also, you shouldn't overwrite style attribute. It's more comfortable to work on project where it is easy to find initial state and changed state. Maybe you should think of a class hidden (for example) which would be like this :
.hidden {
display: none;
}
So if you want to hide them all, you'd juste have to run :
var likes = document.querySelectorAll('.like');
for (var i = 0, length = likes.length; i < length; i++) {
likes[i].classList.add('hidden');
}
In case this is resulting of an action :
var likes = document.querySelectorAll('.like');
for (var i = 0, length = likes.length; i < length; i++) {
likes[i].addEventListener('event', myFunction);
}
function myFunction() {
this.classList.toggle('hidden');
}

If I am not wrong,you want like/dislike for perticular video,then try
onclick event on like/dislike image icon .
onclick="user_responce(responce,id)"
where,
responce:- 1:like,2:dislike
id:- unique video id
In user_responce function do what you want according to responce.
Hope this work for you.

Related

Is there an error in my code or have I simply written it wrong?

I'm making a code where if you press the button after the name it will move to the other list. Pressing a button give me the error: "missing ) after argument list". I can't seem to find anything wrong in the code.
<!DOCTYPE html>
<html>
<title>Favoritter</title>
<body>
<p>Hotell</p>
<p id="hotellDiv"></p>
<p>Favoritter</p>
<p id="favDiv"></p>
</body>
<script>
let hotelliste = ["Norwegian Wild", "Stofjord Hotel", "Norefjell Ski og Spa", "Brikdalsbre Fjellstove", "Gudvangen Fjordtell"];
let favoritter = [];
skrivhliste();
skrivfliste();
function skrivhliste(){
document.getElementById("hotellDiv").innerHTML = "";
for (var j = 0; j < hotelliste.length; j++){
document.getElementById("hotellDiv").innerHTML += hotelliste[j] + "<input type=\"button\" onclick=\"leggTil("+hotelliste[j]+")\"><br>";
}
}
function skrivfliste(){
document.getElementById("favDiv").innerHTML = "";
for (var j = 0; j < favoritter.length; j++){
document.getElementById("favDiv").innerHTML += favoritter[j] + "<input type=\"button\" onclick=\"fjern("+favoritter[j]+")\"><br>";
}
}
function leggTil(hotell){
if (hotelliste.indexOf(hotell) > -1) {
hotelliste.splice(hotelliste.indexOf(hotell), 1);
}
favoritter.push(hotell);
skrivhliste();
}
function fjern(hotell){
if (favoritter.indexOf(hotell) > -1) {
favoritter.splice(favoritter.indexOf(hotell), 1);
}
hotelliste.push(hotell);
skrivfliste();
}
</script>
</html>
Look at this:
"<input type=\"button\" onclick=\"fjern("+favoritter[j]+")\">
What string are you going to end up with when you insert the value of favoritter[j]?
<input type="button" onclick="fjern(Norwegian Wild)">
There you don't have the string "Norwegian Wild", you have the variable Norwegian followed by a space followed by the variable Wild (and neither of those variables exist).
If you are programatically generating JavaScript then you need to generate the quotes that go around strings you generate.
This is hard to do well. Especially when that JS gets embedded in HTML that you are also generating on the fly. You have multiple levels of escape sequences to deal with.
Avoid generating strings like this. Use direct DOM methods instead.
For example:
Once, so it can be reused:
function clickHandler(event) {
const button = event.currentTarget;
const hotel = button.dataset.hotel;
leggTil(hotel);
}
Then inside your loop:
const button = document.createElement('input');
button.type = 'button';
button.value = 'display label';
button.dataset.hotel = hotelliste[j];
button.addEventListener('click', clickHandler);
document.getElementById("hotellDiv").appendChild(button);
Your code is ok, please make a string into onclick function like below.
Pass the value in single quotes into both onclick function.
document.getElementById("favDiv").innerHTML += favoritter[j] + "<input type=\"button\" onclick=\"fjern('"+favoritter[j]+"')\"><br>";

Dynamically add <img> tags with via PHP loop, via calling a JavaScript function on each loop

I have a PHP function that loops through image results in a database, formats them with HTML, then returns the variable containing the HTML layout to my page.php. This is all working okay, but in the loop I have some script tags that call a function in my script.js file. It takes two parameters (url and count). I am trying to pass the url of the result from the database to the function, create a new img element, and append the passed url to the src attribute of the newly created img tag.
This appears to be working so far - when I console.log the result, I get a load of <img> tags, all with corresponding src attached to them.
I am having trouble with actually getting these back to the front end, though.
My code below shows the part of the php that gets looped through, followed be the Javascript function it calls on each loop.
public function getResultsHtml($page, $pageSize, $term) {
$fromLimit = ($page - 1) * $pageSize;
$query = $this->con->prepare("SELECT * FROM images
WHERE (title LIKE :term
OR alt LIKE :term) AND broken=0
ORDER BY clicks DESC
LIMIT :fromLimit, :pageSize");
$searchTerm = "%" . $term . "%";
$query->bindParam(":term", $searchTerm);
$query->bindParam(":fromLimit", $fromLimit, PDO::PARAM_INT);
$query->bindParam(":pageSize", $pageSize, PDO::PARAM_INT);
$query->execute();
$resultsHtml = "<div class='image-results'>";
$count = 0;
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$count++;
$id = $row["id"];
$imgUrl = $row["imgUrl"];
$siteUrl = $row["siteUrl"];
$title = $row["title"];
$alt = $row["alt"];
if($title){
$displayText = $title;
} else if ($alt) {
$displayText = $alt;
} else {
$displayText = $imgUrl;
}
$resultsHtml .= "<div class='grid-item image$count'>
<a href='$imgUrl'>
<script>
document.addEventListener('DOMContentLoaded', function() {
loadImage(\"$imgUrl\", \"image$count\");
});
</script>
<span class='details'>$displayText</span>
</a>
</div>";
}
$resultsHtml .= "</div>";
return $resultsHtml;
}
var loadImage = function(src, className){
var image = document.createElement("img");
var aTag = document.querySelectorAll("." + className + " a");
image.onload = function(){
aTag.innerHTML = image;
};
image.onerror = function(){
};
image.setAttribute("src", src);
}
At the moment I'm not geting any results at the front end. In the page source, I can see that inside each anchor tag are script tags, which show the function preloaded with the parameters (loadImage(http://www.com, image22)), but it isn't actually getting a return from the function.
The solution for this with jQuery is below, but I really don't want to use jQuery!
function loadImage(src, className) {
var image = $("<img>");
image.on("load", function() {
$("." + className + " a").append(image);
});
image.on("error", function() {
});
image.attr("src", src);
}
I know that there is some trouble with dynamically writing <script> tags with .innerHTML, but I don't think this is the problem as the script tags are written before the function is called.
I think I have something firing in the wrong order, or I'm missing something that jQuery handles automatically with the .append function.
I have also tried aTag.appendChild(image);, which also gives no results.
I have been using jQuery for a few months, but I am trying to learn Vanilla JS thoroughly - I'm trying to grasp how the jQuery functions actually work, rather than just relying on them blindly.
Any help is massively appreciated!
Beware of that querySelectorAll() returns an array-like NodeList (https://developer.mozilla.org/en-US/docs/Web/API/NodeList), so it should be like this:
(If you only want one element returned user querySelector(), then you don't need the loop)
function loadImage(src, className) {
var image = document.createElement("img");
image.src = src;
image.onload = function() {
var tags = document.querySelectorAll("." + className + " a");
for (var i = 0; i < tags.length; i++) {
tags[i].appendChild(image);
}
}
}
<div class='grid-item image2'>
<a href='https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg'>
<script>
document.addEventListener('DOMContentLoaded', function() { loadImage("https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg", "image2");
});
</script>
<span class='details'>Star Wars 1</span>
</a>
</div>
The problem is that you are using querySelectorAll, which returns a NodeList instead of a single DOM node. This means, you have to iterate over the NodeList and append the image to all the nodes within. For this, you have can either create new copies for each place you want to insert the image, or use cloneNode multiple times.
var each = function (xs, func) {
for (var i = 0; i < xs.length; i += 1) {
func(xs[i]);
}
return xs;
}
var loadImage = function(src, className){
var image = document.createElement("img");
var aTag = document.querySelectorAll("." + className + " a");
image.onload = function(){
each(aTag, function (a) {
a.appendChild(image.cloneNode());
});
};
image.onerror = function(){};
image.alt = '';
image.src = src;
}
loadImage('http://www.fillmurray.com/500/300', 'wrap')
<div class="wrap">
</div>

Not working in PHP file

I am trying to make a PHP page that embeds a JavaScript into the page that makes some YouTube videos on the page and so on, that works fine, but I have another script on the page that should sort these YouTube videos based on the amount of views they have. That normally works, but since I started working on PHP for the page so I don't have to hardcode everything, it doesn't work.
Code:
<script src="jquery-3.2.1.min.js"></script>
<html>
<body>
<?php
$youtubeID = array("KxEhALUc_xo", "HHuOu8L5f58", "DANypN7iXsI");
$len = count($youtubeID);
for ($i = 0; $i < $len; $i++) {
$embedCode = "<script>
var id = ('" . $youtubeID[$i] . "')
$.getJSON('https://www.googleapis.com/youtube/v3/videos?part=statistics&id=" . $youtubeID[$i] . "&key=', function(data) {
$.getJSON('https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" . $youtubeID[$i] . "&key=', function(data2) {
var tags = data2.items[0].snippet.tags;
var likes = data.items[0].statistics.likeCount;
var viewcount = data.items[0].statistics.viewCount;
var title = data2.items[0].snippet.title;
var channel = data2.items[0].snippet.channelTitle;
$('div#videocontainer').append('<div class = videoframe><iframe src = \"https:\\\\\\\\www.youtube.com\\\\embed\\\\" . $youtubeID[$i] . "\" width = 854 height = 510 frameborder= 0 allowfullscreen></iframe><div class = countercontainer><div class = counter>View count:'+viewcount+'</div></div><div class = titlecontainer><div class = title>'+title+'</div></div><div class = likescontainer><div class = likes>'+likes+'</div></div></div>');
});
});
</script>
";
echo $embedCode;
}
?>
<script>
$('button#viewsasc').click(function() {
var videos = $('div.videoframe').get();
videos.sort(function(a,b) {
return parseInt($(a).find('div.counter').text()) - parseInt($(b).find('div.counter').text());
});
$('div#sortedcontainer').html($(videos));
});
$('button#viewsdesc').click(function() {
var videos = $('div.videoframe').get();
videos.sort(function(a,b) {
return parseInt($(b).find('div.counter').text()) - parseInt($(a).find('div.counter').text());
});
$('div#sortedcontainer').html($(videos));
});
</script>
<button id = 'viewsasc'>desc</button>
<button id = 'viewsdesc'>asc</button>
<div id = 'videocontainer'></div>
<div id = 'sortedcontainer'></div>
</body>
</html>
I know it all looks like a mess, but its just a prototype ;).
So as you can see, I have a little array with 3 YouTube video IDs, I then try to embed a JavaScript code that will get som JSON data, make some divs, and show the video with youtubes "iframe".
That all works good, I have 3 YouTube videos showing on my page, and I have the external text with all the views, title, and likes showned.
WHAT's not working is this part:
<script>
$('button#viewsasc').click(function() {
var videos = $('div.videoframe').get();
videos.sort(function(a,b) {
return parseInt($(a).find('div.counter').text()) - parseInt($(b).find('div.counter').text());
});
$('div#sortedcontainer').html($(videos));
});
$('button#viewsdesc').click(function() {
var videos = $('div.videoframe').get();
videos.sort(function(a,b) {
return parseInt($(b).find('div.counter').text()) - parseInt($(a).find('div.counter').text());
});
$('div#sortedcontainer').html($(videos));
});
</script>
<button id = 'viewsasc'>desc</button>
<button id = 'viewsdesc'>asc</button>
<div id = 'videocontainer'></div>
<div id = 'sortedcontainer'></div>
So when i press these buttons:
<button id = 'viewsasc'>desc</button>
<button id = 'viewsdesc'>asc</button>
it will indeed move the "videoframe" div into the "sortedcontainer" div, but it is not sorted, it's just moved to another div, so that's pretty useless. Here is gyazo so you can see what i mean: https://gyazo.com/dc9baa1f1342ffc08c66b2db41d3a4d0
I am very confused by PHP and not very good at it as you can guess, there is probably some obvious rule I didn't know about, I only just started to study PHP.

Image OnClick to Javascript function

I am making a registration page that allows you to register an account to a mysql database for my uni project.
In this page you can also 'select' your avatar picture. Here is the code below:
<u>Select your avatar:</u><br>
<?php
// open this directory
$image_dir = opendir("images/avatars");
// get each entry
while( $image = readdir( $image_dir ) )
{
$dirArray[] = $image;
}
// close directory
closedir($image_dir);
// count elements in array
$indexCount = count($dirArray);
// loop through the array of files and print them all in a list
for($index=0; $index < $indexCount; $index++)
{
$extension = substr($dirArray[$index], -3);
if( $extension == "jpg" || $extension == "gif" )
{
//echo("<a href='#'>");
echo("<img id='$index' onClick='SetAvatar($index)' img src='images/avatars/$dirArray[$index]' class='o'> ");
//echo("</a>");
}
}
?>
<script>
function SetAvatar(id) {
var image = document.getElementById(id);
if( CurSelectedImage != null && id != CurSelectedImage )
{
var image_to_unselect = document.getElementById(CurSelectedImage);
image_to_unselect.Selected = false;
image_to_unselect.style.border = null;
}
if( image.Selected != true )
{
image.style.border = 'medium solid blue';
image.Selected = true;
SelectedImage = id;
}
else
{
image.style.border = null;
image.Selected = false;
SelectedImage = null;
}
}
</script>
This selects the avatar picture, makes the border blue and stores the selected image id in a variable but how would I pass the variable with the selected image id back to php so I can save it??
Thanks
can you show your CSS codes too ?
or you can find here jQuery select and unselect image
your answer
You have to think about your application design. Mixing PHP and Javascript isn't the best idea. Use a API instead of mixing code. You can call this API with Ajax. I think this is a good design choice:
Create a getImages API in PHP: You output the data in a json array.
You calling this api with javascript and generating the DOM with the json
You creating a click handler in javascript and calling again a API in PHP
You getting the json data in PHP and saving it in your db
:)
My suggestion would be to use a CSS class. Remove any existing instances of the class then add the class to the selected image.
function SetAvatar(id) {
//remove existing border(s) a while loop is used since elements is a live node list which causes issues with a traditional for loop
var elements = document.getElementsByClassName("selected-avatar");
while (elements.length > 0) {
var element = elements.item(0);
element.className = element.className.replace(/(?:^|\s)selected-avatar(?!\S)/g , '');
}
var image = document.getElementById(id);
image.className += " selected-avatar";
}
To pass the avatar value, I'd suggest using a form to pass all of your registration data to process_register (if you are not already). You can add an input of type hidden to your form and populate the value through javascript on submit.
html:
<form id="registration-form" action="process_register.php" method="put">
<input id="registration-avatar" type="hidden" />
<button id="registration-submit">Submit</button>
</form>
javascript:
document.getElementById("registration-submit").onclick = function(){
var avatarValue; //you'll need to write some code to populate the avatarValue based on the selected avatar image
document.getElementById("registration-avatar").value = avatarValue;
document.getElementById('registration-form').submit();
};
Then in php you can get the values using $_POST
http://php.net/manual/en/reserved.variables.post.php

How can I consolidate duplicated javascript functions?

I have a site to allow someone to place food orders. Images of potential ingredients (determined by a MySQL query) can be clicked to add or remove them, and the image will toggle on each click.
The problem I'm having is for each new item I am having to duplicate the function and just change the variable names for each new function. I'm sure there must be a way to simplify to dynamically apply to all of the ingredients without all of the redundant code.
Here is the code just for two. There are dozens. Any suggestions would be appreciated.
window.onload = function () {
var ProductElement = document.getElementById('Ketchup');
if (ProductElement != null) {
Ketchupobj = document.getElementById('Ketchup')
document.getElementById('Ketchuptogg').onclick = function () {
Ketchuptoggle();
}
}
var ProductElement = document.getElementById('Mustard');
if (ProductElement != null) {
Mustardobj = document.getElementById('Mustard')
document.getElementById('Mustardtogg').onclick = function () {
Mustardtoggle();
}
}
}
function Ketchuptoggle() {
if (Ketchuptggle == 'on') {
Ketchupobj.src = "Ketchup.jpg";
Ketchuptggle = 'off';
} else {
Ketchupobj.src = "noKetchup.jpg";
Ketchuptggle = 'on';
}
}
function Mustardtoggle() {
if (Mustardtggle == 'on') {
Mustardobj.src = "Mustard.jpg";
Mustardtggle = 'off';
} else {
Mustardobj.src = "noMustard.jpg";
Mustardtggle = 'on';
}
}
<table class="ing">
<tr>
<?php
for ($x=0; $x<5 AND $row = mysql_fetch_row($result);$x++ ) {
$caps=$row[1];
$caps=strtoupper($caps);
echo <<<image
<td><b>$caps</b><br>
<a id="$row[0]" class="toggle" href="#"><img id="$row[0]img" class="toggimg"
src="$row[0].jpg" style="border-style: none" alt=""/></a>
</td>
image;
}
echo"</tr></table>";
Implicit this is your friend:
var toggles = document.getElementsByClassName('toggle');
for (var i=0; i<toggles.length; i++) {
toggles[i].isOn = true;
toggles[i].onclick = function(ev){
var condiment = this.id;
this.isOn = !this.isOn;
document.getElementById(condiment+'img').src=(this.isOn?'':'no')+condiment+'.png';
};
}
With html you have the ability to add your property for an element, so you could do:
<button class="btnProduct" data-type="mostard"> Mostard</button>
<button class="btnProduct" data-type="ketchup"> Ketchup</button>
<button class="btnProduct" data-type="barbecue"> Barbecue</button>
Then with a help of jquery you can do:
$('btnProduct').click(function(){
//So, here you could use a switch or some logic
// to do different things for data-type
console.log($(this).attr('data-type'))
}

Categories