Show / hide image function with remove classname - javascript

I'm using the following function to display the image on which the user clicks on in an above div.
In the event the user clicks again on the populated image (in the div), I would like to remove the image in the div and have the original image visible again.
<img id="<?php echo $id; ?>" src="img/.." url=".." name="..." onClick="changeImage(this)"/>
function changeImage(item) {
var url_img = $(item).attr('url');
var name_item = $(item).attr('name');
var item_id = $(item).attr('id');
document.getElementById('test').innerHTML += '<div style=\'display:inline-block\'><img src=' + url_img + ' url = ' + url_img + ' onClick=document.getElementById(' + item_id + ').classname=\'\'; /> ' + name_item + '</div>';
$(item).toggleClass('hideitem');
}
.hideitem is a class with display:none;
The onClick event in the function does not work (I was trying to remove the classname) and I'm not able to remove the div image when it is clicked with the onClick event.
Would anyone have an idea to fix this?
Thanks

There were some missing quotes and stuff in your code.
For this HTML:
<img id="myImgID" src="http://placehold.it/350x150" url="http://placehold.it/150x150" name="Example Dot Com" onClick="javascript:changeImage(this)" />
<div id="test">
<p>this is only a test</p>
</div>
This JS:
changeImage = function (item) {
var $item = $(item),
$test = $('#test'),
url_img = $item.attr('url'),
name_item = $item.attr('name'),
newDiv = $('<div/>').css('display', 'inline-block').text(name_item),
newImg = $('<img/>').attr({'src':url_img, 'url':url_img})
.click(function(e){$item.removeClass('hideitem')}).prependTo(newDiv);
$test.append(newDiv)
$item.toggleClass('hideitem');
}
See it in action here

Related

Javascript (JQuery) and Bootstrap modals

I am currently working on a project that displays some information about movies(pulled from omdbapi.com) in a modal depending on the link that is clicked. Previously this was all done using PHP in the back end and was working without any issues, but as a page can have anywhere from 5-100 movie links on it, creating all of the modals was causing the page to take a while to load.
Now I want to move the modal creation/popup to the front with JS so that it is only created when and if that particular movie link is clicked. Moving it to use Javascript I have encountered two issues I am not able to solve.
The movie title link must be clicked twice in order for the modal to appear and I am not sure what is causing this. Looking at the dev tools I can see that on the first click a modal is created, but for some reason not displayed. On the second click another is created and displayed.
Once a modal is displayed I am unable to get my "X" button to close it. The code I was using in PHP"<button type=\"button\" class=\"close exit-button\" data-dismiss=\"modal\">×</button>"
no longer works. Bootstrap does have the ability to show/hide a modal with $("#movieInfo").modal("hide"), but if I create a function to run this when the button is clicked it still does not hide.
Here is the JS code that I am using:
window.addEventListener("load", function() {
var movielink = document.getElementById("movie");
movielink.addEventListener("click", function(){generateModal(this.innerHTML);}, false);
}, false);
function generateModal(movieT) {
var movieTitle = encodeURIComponent(movieT).replace(/%20/g, '+');
var url = "https://www.omdbapi.com/?t="+movieTitle+"&y=&plot=short";
$.getJSON(url, function(json) {
$('#modalContainer').html("<div id = \"movieInfo\" class = \"modal fade\" role = \"dialog\">"
+ "<div class \"modal-dialog modal-sm\">"
+ "<div class = \"modal-content\">"
+ "<div class = \"modal-body\">"
+ "<div class = \"poster\">"
+ "<img src = "+json.Poster+" width = 200 height = 300>"
+ "</div>"
+ "<div class = \"movie-specs\">"
+ "<button id = \"closebtn\" type=\"button\" class=\"close exit-button\"s onclick = \"closeModal()\">×</button>"
+ "<h3 class = \"movie-title\">"+json.Title+" ("+json.Year+")</h3>"
+ "<p class = \"topmargin-gone\">"+json.Rated+" | "+json.Runtime+" | "+json.Genre+"</p>"
+ "<p class = \"topmargin-gone\">"+json.Released+"</p><hr>"
+ "<div class = \"ratingInfo\">"
+ "<h4 class = \"topmargin-gone\"><strong>Ratings</strong></h4><p class = \"topmargin-gone\">Rated: "+json.imdbRating+"/10 "
+ "from "+json.imdbVotes+" users | Metascore: "+json.Metascore+"</p>"
+ "</div><hr>"
+ "<div class = \"plot-actors\">"
+ "<p>"+json.Plot+"</p><p><strong>Director: </strong>"+json.Director+"</p>"
+ "<p><strong>Writers: </strong>"+json.Writer+"</p>"
+ "<p><strong>Actors: </strong>"+json.Actors+"</p>"
+ "</div>"
+ "</div>"
+ "</div>"
+ "</div>"
+ "</div>"
+ "</div>");
});
$("#movieInfo").modal("show");
}
This is how the the links are created inside a loop in PHP:
$allDisplay .= "<li><em><a id ='movie' href = '#'>"
. "$title[$z]</a></em> - $nominees[$z]</li>";
And finally this is how the HTML looks where the links and modal reside:
<html>
<head>
<meta charset = "utf-8">
<title>Award Search</title>
<!-- jQuery Library -->
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!--Bootstrap CSS -->
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- Styles CSS sheet -->
<link rel = "stylesheet" href = "/src/styles/styles_awardQuery.css">
<!--Bootstrap JavaScript -->
<script src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src = "/src/php/modalCreation.js"></script>
</head>
<body>
<div class = "site-wrapper">
<div class = "site-wrapper-inner">
<div class = "cover-container">
<div class = "masthead clearfix">
<div class = "inner">
<h3 class = "masthead-brand">Award Search</h3>
<ul class = "nav masthead-nav">
<li>Home</li>
<li>About</li>
<li>Logout</li>
</ul>
</div>
</div>
<div class = "inner cover">
<h1 class = "cover-heading">Academy Award Show Number <?php echo $academyNumber; ?>
<?php echo "($year[1])<br><span class = \"small\">Hosted by $acHost</span>"; ?></h1>
<?php echo $allDisplay; ?>
<div id ="modalContainer"></div>
</div>
</div>
</div>
</div>
</body>
</html>
I realize this looks messy, but just want to get it functioning right now. If anyone has any insight into either of the issues it would be much appreciated.
Thanks.
The $("#movieInfo").modal("show"); is triggered before the bloc was actually append to your web page. This is due to the network latency and the Async behaviour of AJAX call that allow your script to continue without waiting to get an answer.
To avoid this, you should put this line at the end of the network callback :
function generateModal(movieT) {
var movieTitle = encodeURIComponent(movieT).replace(/%20/g, '+');
var url = "https://www.omdbapi.com/?t="+movieTitle+"&y=&plot=short";
$.getJSON(url, function(json) {
$('#modalContainer').html('<div id="movieInfo" class="modal fade" role="dialog">'
+ '<div class "modal-dialog modal-sm">'
+ '<div class="modal-content">'
+ '<div class="modal-body">'
+ '<div class="poster">'+'<img src='+json.Poster+' width=200 height=300>'+'</div>'
+ '<div class="movie-specs">'
+ '<button id="closebtn" type="button" class="close exit-button"s onclick="closeModal()">×</button>'
+ '<h3 class="movie-title">'+json.Title+' ('+json.Year+')</h3>'
+ '<p class="topmargin-gone">'+json.Rated+' | '+json.Runtime+' | '+json.Genre+'</p>'
+ '<p class="topmargin-gone">'+json.Released+'</p><hr>'
+ '<div class="ratingInfo">'
+ '<h4 class="topmargin-gone"><strong>Ratings</strong></h4><p class="topmargin-gone">Rated: '+json.imdbRating+'/10 '
+ 'from '+json.imdbVotes+' users | Metascore: '+json.Metascore+'</p>'
+ '</div><hr>'
+ '<div class="plot-actors">'
+ '<p>'+json.Plot+'</p><p><strong>Director: </strong>'+json.Director+'</p>'
+ '<p><strong>Writers: </strong>'+json.Writer+'</p>'
+ '<p><strong>Actors: </strong>'+json.Actors+'</p>'
+ '</div>'+'</div>'+'</div>'+'</div>'+'</div>'+'</div>');
// after we have made the modal, we show it
$("#movieInfo").modal("show");
});
// code here will be fired before the end of the AJAX call
}
For your other bug, I think the double modal may explain the behaviour, so patch this first, and told us if you still can't close your modal ;)

add additional fields while maintaining input content

I'm trying to make an input form with multiple fields and generate a preview of this content in a div. I would like the user to be able to add additional fields as they wish. I have the basic functionality working but anytime I "add" an additional field, the entered content of my previous fields are wiped out. Any suggestions would be greatly appreciated. I've included the relevant code below.
function addInput(){
var inpts = document.getElementById("inputs");
var inputCounter = Number(document.getElementById("inputCounter").innerHTML);
var incCount = inputCounter+1;
var currentInfo = inpts.innerHTML;
var newField = "<textarea id=\"" + incCount + "\" rows=\"2\" onblur=\"updatePreview()\"></textarea> <div onclick=\"addInput()\" style=\"display: inline-block;\">+</div><br />";
inpts.innerHTML = currentInfo + newField;
document.getElementById("inputCounter").innerHTML = incCount;
}
The call to the function looks like this...
<div style="display: none;" id="inputCounter">1</div>
<div id='inputs'>
<textarea id='1' rows="2" onblur="updatePreview()"></textarea> <div onclick="addInput()" style="display: inline-block;">XX</div><br />
</div>
innerHTML returns the HTML structure but it excludes the value property of form elements (such as textarea).
Instead, you could create a new element to hold the additional field, then append that element to inputs:
function addInput(){
var inpts = document.getElementById("inputs"),
inputCounter = Number(document.getElementById("inputCounter").innerHTML),
incCount = inputCounter+1,
div = document.createElement('div');
div.innerHTML= "<textarea id=\"" + incCount + "\" rows=\"2\" onblur=\"updatePreview()\"></textarea> <div onclick=\"addInput()\" style=\"display: inline-block;\">+</div><br />";
inpts.appendChild(div);
document.getElementById("inputCounter").innerHTML = incCount;
} //addInput
Working Fiddle
An alternative to creating a new element is to use insertAdjacentHTML:
function addInput(){
var inpts = document.getElementById("inputs"),
inputCounter = Number(document.getElementById("inputCounter").innerHTML),
incCount = inputCounter+1;
inpts.insertAdjacentHTML(
'beforeend',
"<textarea id=\"" + incCount + "\" rows=\"2\" onblur=\"updatePreview()\"></textarea> <div onclick=\"addInput()\" style=\"display: inline-block;\">+</div><br />"
);
document.getElementById("inputCounter").innerHTML = incCount;
} //addInput
Working Fiddle #2

replaceWith inside each don't work with my own tag

Hello I have function which take text with my own tag and convert this tag to a:
//<link src="" title=""> -> title
function ProceedLinkTag(text) {
var items = text.filter("link");
items.each(function () {
var currentElement = $(this);
var title = currentElement.attr("title");
var source = currentElement.attr("src");
var newElement = $("<a>" + title +"</a>");
newElement.attr("href", source);
$(this).replaceWith("<a href='" + source + "'>" + title + "</a>"); //don't work
});
}
It work fine(it is detect my own tag even without close tag), I don't get any errors, but it is don't replaceWith().
Try it:
var text = "<link src='http://lenta.ru/' title='title'>";
ProceedLinkTag($(text));
alert(text);
I also try use it with close tag:
var text = "<link src='http://lenta.ru/' title='title'/>";
ProceedLinkTag($(text));
alert(text);
But it don't work too.
#sqykly find error:
Text in my instance was not a part of document. I change it and now it work.

Many a hrefs from JSON, on toggle click make diffrent id appear

I have a JSON file with movies in theaters. I want to make info appear for right movie when I click on movie title which are many. My code is not working, but I am able to make all the movies appear on click, no matter what movie.
I want to be able to click, let's say, "Ender's Game", and then make info div appear with only info about that film. My code is here below:
JavaScript:
$(document).ready(function() {
$.getJSON('json/store.json', function(results) {
//Get movie title
for (var i = 0; i < results['results'].length; i++) {
var title = '<p>' + results['results'][i].title + '</p>';
$('#movies').append(title);
}
for (var i = 0; i < results['results'].length; i++) {
var title = $('#info').append("<p class='biohus'>" + results['results'][i].title + "</p>");
var img = $('#info').append("<img id='myndbio' width='200' height='300' class='img' src =" + results['results'][i].image + ">");
}
$('.title').click(function(){
$(this).parent().find('#info').slideToggle("slow");
});
$('.title').click(function(){
var dataMovieId = $(this).attr('data-movie-id');
$('#'+dataMovieId).slideToggle("slow");
});
});
});
Html:
<div id="bio" class = "content">
<center><h1 class="cinemaheadline">Myndir í bíó</h1></center>
<?php include 'php/curl.php';?>
<div id="movies" class="movies">
<!-- Movies -->
</div>
<div id="info" class="info">
<!-- info -->
</div>
</div>
and php for connection to api:
<?php
//check if you have curl loaded
if(!function_exists("curl_init")) die("cURL extension is not installed");
//url
$url = 'http://apis.is/cinema';
$storejson = 'json/store.json';
//skrifa
$fw = fopen($storejson, 'w');
//start curl
$ch=curl_init($url);
//set options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//execute
$r=curl_exec($ch);
//close curl
curl_close($ch);
$arr = json_decode($r,true);
fwrite($fw, json_encode($arr, TRUE));
?>
The main problem you have here is that you need some way of linking the title with the info. Either have the title and info wrapped in its own div for each movie, or use some attribute (data-movie) and give it a name or number which can associate the title and the info.
If the first way you'll need to do something like
$('.title').click(function(){
$(this).parent().find('.info').slideToggle("slow");
});
and the second way would be something like;
$('.title').click(function(){
var dataMovieId = $(this).attr('data-movie-id');
$('#'+dataMovieId).slideToggle("slow");
});
Lastly you should not be using ids the way you are. eg you will be outputting img tags with the same ids. You should only use an id once on a page.
EDIT: Full code;
$(document).ready(function() {
$.getJSON('json/store.json', function(results) {
for (var i = 0; i < results['results'].length; i++) {
// title link. note the data-id attr which is i, which we will put into the movie info, to tie them together
var title = '<p>' + results['results'][i].title + '</p>';
// info section
var infoTitle = "<p class='biohus'>" + results['results'][i].title + "</p>";
var infoImg = "<img id='myndbio' width='200' height='300' class='img' src =" + results['results'][i].image + ">";
// wrap title and image in a div with the data-id attr and i
var info = '<div class="movie-info data-id="'+i+'">'+infoTitle+infoImg+'</div>';
// place both title and info sections in the right spots
$('#movies').append(title);
$('#info').append(info);
}
});
// set up click handlers
$('#movies a').click(function(){
// find data id of clicked movie
var id = $(this).attr('data-id');
// find movie info with correct id and show
$('#info .movie-info[data-id="'+id+'"]').slideToggle("slow");
});
});

Div's content editor

I have this code:
<html>
<head>
<title></title>
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#k123").click(function () {
//var text=$(this).val(); //this does not work
var text=$(this).text();
var k='<div id="k123"><textarea rows="10" cols="10">' + text + '</textarea><br /><input type="button" onclick="save();" value="save"><input type="button" onclick="cancel();" value="cancel"></div>';
$(this).replaceWith(k);
});
});
function save() {
}
function cancel() {
//alert(text);
var k='<div id="k123"></div>';
$("#k123").replaceWith(k);
}
</script>
</head>
<body>
<div id="k123">aaaaa</div>
</body>
</html>
My question is :
1)In both functions : cancel & save , How can I get content of div id->#k123->textarea->content
functions cancel & save are outside the scope and they are independent functions I cannot tell $(this).parent().
I need to ask about div which has id #k123 , then get inside to textarea's content and get it.
and I have also to get id #k123 automatically because if I have many divs I cannot tell save & cancel manually the div's id, cancel & save should know the div's id sender from the input type='button'`s parent id.
**please I do not prefer the suggestion of sending div id from input button
**We are assuming that both input buttons have no IDS or Names
I tried another way but still having same problem
I replaced
$(document).ready(function() {
$("#k123").click(function () {
var text=$(this).text();
var k='<div id="k123"><textarea rows="10" cols="10">' + text + '</textarea><br /><input type="button" value="save"><input type="button" value="cancel"></div>';
$(this).replaceWith(k);
});
//$("#k123 > input").click(function() {
$("#k123").children("input:second").click(function() {
alert("hi");
});
});
thank you.
I have the working code for you below. You don't even need an id.. just a container div and delegation of events. The below accomplishes what I thought you were after, in what I believe to be a much simpler, and much more efficient fashion:
(I've added comments to assist in understanding the code)
$(document).ready(function() {
$(".container").on('click', function(e) {
if (!$(e.target).is('input') && !$(e.target).is('textarea')) { //check to make sure the target is neither an input or a textarea
var div_text = $(e.target).text(); // use a variable named something other than text, because text is already a method for another element
$(e.target).data('text',div_text); // set the div's current contents as a hidden data attribute, to be retrieved later. You can get rid of this and the other line if you want cancel to completely wipe the div.
var k = '<textarea rows="10" cols="10">' + div_text + '</textarea><br /><input type="button" value="save"><input type="button" value="cancel">';
$(e.target).html(k); //set the inner HTML of the div, so we don't lose any data saved to that div
}
if ($(e.target).is('input') && $(e.target).val() == 'save') {
$(e.target).parent().html($(e.target).parent().find('textarea').val()); // replace the current contents of the parent div with the contents of the textarea within it.
} else if ($(e.target).is('input') && $(e.target).val() == 'cancel') {
$(e.target).parent().html($(e.target).parent().data('text')); //set the contents to the old contents, as stored in the data attribute. Just replace the contents of the .html() here with '' to completely clear it.
}
});
});​
DEMO
REVISED - WORKS
Check this out... not quite there but close!
REVISED JS Fiddle
function editit() {
var divId = $(this).attr('id');
var text = $(this).html();
var k = '<div id="' + divId + '" class="editable"><textarea id="newvalue' + divId +'" rows="10" cols="10">' + text + '</textarea><br /><input id="save' + divId + '" type="button" value="save"><input id="cancel' + divId + '" type="button" value="cancel"></div>';
$('#' + divId).replaceWith(k);
$('#cancel' + divId).click(function() {
$('#' + divId).replaceWith('<div id="' + divId + '" class="editable">' + text + '</div>');
$('.editable').bind('click', editit);
});
$('#save' + divId).click(function() {
$('#' + divId).replaceWith('<div id="' + divId + '" class="editable">' + $("#newvalue" + divId).val()+ '</div>');
$('.editable').bind('click', editit);
});
}
$('.editable').bind('click', editit);

Categories