Jquery to interact with multiples images - javascript

SO I'm creating multiple info pictures with their own ids.
var inc = "";
for(int i = 0; i < itemList.length; i++)
{
var inf = "info";
var conc = inf.concat(i); //dinamically creating info0, info1, info2, info3.....
inc += "<span id=" + '"' + conc + '"' + ">";
inc += "<a class='infobutton' ";
inc += ' href="Javascript: void(0)">';
inc += '<img border="0" width="30" height="30" src="images/info.png"></a></span>';
}
So, each image is going to have an id called, info0, info1, etc..
And I want to use jquery to create individual dialogs to each image, and i'm using this.
$(function ()
{
for(var i = 0; i < itemList.length; i++)
{
$("#info" + i).on("click", function ()
{
$("#dialog").dialog("open");
});
}
$("#dialog").dialog(
{
autoOpen: false
});
$("#dialog").dialog(
{
modal: true,
resizable: false,
buttons:
{
"Close": function ()
{
$(this).dialog("close");
}
}
});
});
Needless to say, it's not working, and i don't have a clue, maybe i'm trying to use something and it's not how jquery works. Thanks.

Use http://api.jquery.com/delegate/ for the event. You inserting to the DOM dynamicly so they wont work on inserted elements.
$('body').delegate($("#info"+i), 'click', function(){
$("#dialog").dialog("open");
});
Also it's better to use a class like .open_dialog and create the event once rather then attaching in the loop in every iteration to a single element.

I believe instead:
for(var i = 0; i>itemList.length; i++)
{
$("#info" + i).on("click", function ()
{
$("#dialog").dialog("open");
});
}
can do this(entering your images into a div):
$("div").on("click", "img", function{});

Related

Best way to add delete button in to do list

I'm creating a to do list with vanilla JS. I ideally want to keep my adding, deleting functions separate to keep everything tidy.
My issue is if I create a delete button when I add a to do I don't know how to reference the delete button.
JSFiddle: https://jsfiddle.net/ped1j6kf/11/
Any ideas?
Thanks
HTML
<body>
<!-- Main -->
<div id="main"></div>
<!-- Add -->
<input id="to-do-value" type="text" placeholder="Enter to do">
<button id="add">Add</button>
<script type="text/javascript" src="main.js"></script>
</body>
JS
// To do
var toDo = {
cacheDom: function() {
this.toDo = ['test'];
this.main = document.getElementById('main');
this.add = document.getElementById('add');
this.toDoValue = document.getElementById('to-do-value');
},
init: function() {
this.cacheDom();
this.bindEvents();
this.displayToDos();
},
bindEvents() {
this.add.addEventListener("click", this.addToDo.bind(this));
},
displayToDos: function() {
var html = '<ul>';
for(i=0; i < this.toDo.length; i++) {
html += '<li>' + this.toDo[i] + '</li>' + '<button>delete</button>';
}
html += '</ul>';
this.main.innerHTML = html;
},
addToDo(){
var toDoValue = this.toDoValue.value;
this.toDo.push(toDoValue);
this.displayToDos();
},
deleteToDo() {
console.log("make this delete button work");
}
}
toDo.init();
With some minor changes, you can make it work the way you have it now.
One of the changes would be that you could theoretically have multiple to do items named the same (for some reason), it might simply be easier to store the todo as an object, and save it in your todo list with an identifier, like so:
addToDo( text ){
this.toDo.push({ id: this._id++, text: text});
this.displayToDos();
}
This does require some other minor changes, but it offers the possibility to reference the onClick event directly, like this:
displayToDos: function() {
var html = '<ul>';
for(i=0; i < this.toDo.length; i++) {
html += '<li>' + this.toDo[i].text + '</li>' + '<button onClick="toDo.deleteToDo(' + this.toDo[i].id + ')">delete</button>';
}
html += '</ul>';
this.main.innerHTML = html;
}
You now have both a text that is displayed in the todo list as an Id that can be referenced when you want to delete that data
And then the delete function works like this
deleteToDo( id ) {
for (var i = 0; i < this.toDo.length; i++) {
if (this.toDo[i].id === id) {
// removes 1 item from the array at position i
this.toDo.splice(i, 1);
break;
}
}
this.displayToDos();
}
var toDo = {
_id: 0,
cacheDom: function() {
this.toDo = [];
this.main = document.getElementById('main');
this.add = document.getElementById('add');
this.toDoValue = document.getElementById('to-do-value');
},
init: function() {
// must run first
this.cacheDom();
this.bindEvents();
// now it can also allow for adding
this.addToDo('test');
this.displayToDos();
},
bindEvents() {
this.add.addEventListener("click", () => this.addToDo(this.toDoValue.value));
},
displayToDos: function() {
var html = '<ul>';
for(i=0; i < this.toDo.length; i++) {
html += '<li>' + this.toDo[i].text + '</li>' + '<button onClick="toDo.deleteToDo(' + this.toDo[i].id + ')">delete</button>';
}
html += '</ul>';
this.main.innerHTML = html;
},
addToDo( text ){
var toDoValue = text;
this.toDo.push({ id: this._id++, text: toDoValue});
this.displayToDos();
},
deleteToDo( id ) {
for (var i = 0; i < this.toDo.length; i++) {
if (this.toDo[i].id === id) {
this.toDo.splice(i, 1);
break;
}
}
this.displayToDos();
}
}
toDo.init();
<body>
<!-- Main -->
<div id="main"></div>
<!-- Add -->
<input id="to-do-value" type="text" placeholder="Enter to do">
<button id="add">Add</button>
<script type="text/javascript" src="main.js"></script>
</body>
I am assuming you want to reference the delete button so that if some one clicks it you want to perform a delete operation. Easiest way to do this would be :-
html += '<li>' + this.toDo[i] + '<button onclick="deleteSomething(this)">delete</button></li>';
Please note that the button element now comes under li.
and then in the deleteSomething function you get the parent element and delete it :--
function deleteSomething(el){
val = el.value;
i = this.toDo.indexOf(val);
if (i > -1) {
array.splice(i, 1);
}
el.parentElement.remove();
}

jQuery Animated Text Colors

I'm trying to get each letter color to swap from red to green and back to red.
What I have now works, but I don't like the fading, is there a better way to do this?
const ltr = $('h1').text().split('');
function colorChange() {
$( 'h1' ).fadeOut(500, function() {
redGreen();
}).fadeIn(500).fadeOut(500, function() {
greenRed();
}).fadeIn(500);
}
setInterval( function() {
colorChange();
}, 1);
function redGreen() {
$('h1').text('');
for(var i = 0; i < ltr.length; i++) {
if(i % 2 == 0) {
$('h1').append('<span class="red">' + ltr[i] + '</span>');
} else {
$('h1').append('<span class="green">' + ltr[i] + '</span>');
}
}
}
function greenRed() {
$('h1').text('');
for(var i = 0; i < ltr.length; i++) {
if(i % 2 == 0) {
$('h1').append('<span class="green">' + ltr[i] + '</span>');
} else {
$('h1').append('<span class="red">' + ltr[i] + '</span>');
}
}
}
Referred to the solution for toggling class animation here : ToggleClass animate jQuery?. You should change your colorChange function to something like this :
function colorChange() {
$( 'h1 > span' ).toggleClass( "red green", 1000, "easeInOutQuad" );
}
And make sure you build the spans at the beginning with alternative classes to each item (use one of your redGreen() or greenRed() function for the first time only).
Check this Fiddle
You need to include jQuery UI to have the effect.
I managed to remove the fade effect by using setTimeout.
See the plunker here

Using jQuery with meteor giving errors

Omitting the keydown input : function(event) { and } gives me an error along the lines of
"While building the application:
client/client.js:33:11: Unexpected token ("
which is basically the starting. I'm wondering why I need the javascript function right at the start. To not get the error. This is an issue especially because I don't want the click function to run every time the key is pressed. In any case it would be great to either figure out how I can just use jQuery instead of javascript here or change the keydown input.
Template.create_poll.events = {
'keydown input' : function(event) {
$("input").keypress(function() {
var active_element = $(this).parent().attr("id");
var last_child = $('ul li:last').attr("id");
var option_number_index = last_child.lastIndexOf("-");
var option_number = last_child.substring(option_number_index+1);
option_number = option_number/1;
//console.log(option_number);
//console.log(last_child);
if (last_child == active_element) {
console.log(active_element);
option_number += 1;
console.log(option_number);
$('ul').append('<li id="poll-choice-' + option_number + '"><input name="choice" type="text" placeholder="Option ' + option_number + '">');
}
});
$("#poll_create").click(function() {
console.log("Button works");
var choices = new Array();
var counter = 0;
$("ul li input").each(function() {
choices[counter] = $(this).val();
counter++;
});
console.log(choices[1]);
console.log(choices[5]);
});
}
}
Template.create_poll.events expects an eventMap which is:
An event map is an object where the properties specify a set of events to handle, and the values are the handlers for those events. The property can be in one of several forms:
Hence, you need to pass in the 'keydown input' : function (event, templ) { ... } to make it a valid Javascript object.
In this case, you should follow #Cuberto's advice and implement the events using Meteor's event map:
Template.create_poll.events = {
'press input' : function(event) {
var active_element = $(this).parent().attr("id");
var last_child = $('ul li:last').attr("id");
var option_number_index = last_child.lastIndexOf("-");
var option_number = last_child.substring(option_number_index+1);
option_number = option_number/1;
//console.log(option_number);
//console.log(last_child);
if (last_child == active_element) {
console.log(active_element);
option_number += 1;
console.log(option_number);
$('ul').append('<li id="poll-choice-' + option_number + '"><input name="choice" type="text" placeholder="Option ' + option_number + '">');
}
},
'click #poll_create' : function (event) {
console.log("Button works");
var choices = new Array();
var counter = 0;
$("ul li input").each(function() {
choices[counter] = $(this).val();
counter++;
});
console.log(choices[1]);
console.log(choices[5]);
}
}
However, if you want to use certain jQuery specific events, then you can attach them in the rendered function:
Template.create_poll.rendered = function () {
$("input").keypress(function() {
var active_element = $(this).parent().attr("id");
var last_child = $('ul li:last').attr("id");
var option_number_index = last_child.lastIndexOf("-");
var option_number = last_child.substring(option_number_index+1);
option_number = option_number/1;
//console.log(option_number);
//console.log(last_child);
if (last_child == active_element) {
console.log(active_element);
option_number += 1;
console.log(option_number);
$('ul').append('<li id="poll-choice-' + option_number + '"><input name="choice" type="text" placeholder="Option ' + option_number + '">');
}
});
$("#poll_create").click(function() {
console.log("Button works");
var choices = new Array();
var counter = 0;
$("ul li input").each(function() {
choices[counter] = $(this).val();
counter++;
});
console.log(choices[1]);
console.log(choices[5]);
});
};

FadeIn div content one by one

I have some content in div, basically div will be hide, now i want when i press button the div content will be show with fadeIn function, now my problem i want show the div content one by one means one alphabet fadeIn then other but in my case it will be done word by word.
HTML
<div>
<span> THIS IS EXAMPLE OF FADE IN WORLD ONE BY ONE IN ALPHABETIC ORDER</span>
</div>
<input type='button' value='click me'/>
JS
$("input[type=button]").click(function(){
$("div").show();
$("span").each(function(index) {
$(this).delay(400*index).fadeIn(300);
});
});
CSS
div { display:none }
Fiddle Here
The trick is to split your span into smaller spans, one for every letter, and to use setTimeout to fade those spans one after the other :
$("input[type=button]").click(function(){
var $div = $('div');
$div.html($div.text().split('').map(function(l){
return '<span style="display:none;">'+l+'</span>'
}).join('')).show().find('span').each(function(i, e){
setTimeout(function(){ $(e).fadeIn() }, i*100);
});
});
Demonstration
you could also do:
$("input[type=button]").click(function(){
$("div").find("span").hide();
$("div").show();
var spanEle = $("span"),
contentArray = spanEle.text().split(""),
current = 0;
spanEle.text('');
setInterval(function() {
if(current < contentArray.length) {
spanEle.text(spanEle.text() + contentArray[current++]).fadeIn("slow");
}
}, 100);
});
Demo:: jsFiddle
DEMO
$(function () {
$('#test').click(function () {
var dest = $('div span#char');
var c = 0;
var string = dest.text();
dest.text('').parent().show();
var q = jQuery.map(string.split(''), function (letter) {
return $('<span>' + letter + '</span>');
});
var i = setInterval(function () {
q[c].appendTo(dest).hide().fadeIn(1000);
c += 1;
if (c >= q.length) clearInterval(i);
}, 100);
});
});
Demo http://jsfiddle.net/krasimir/4GmSF/1/
HTML
<div>THIS IS EXAMPLE OF FADE IN WORLD ONE BY ONE IN ALPHABETIC ORDER</div>
<input type='button' value='click me'/>
CSS
div {
display: none;
}
div span {
opacity: 0;
}
JavaScript
var transformText = function(selector) {
var div = $(selector);
var words = div.text().split(" ");
var newHTML = '';
for(var i=0; word=words[i]; i++) {
newHTML += '<span>' + word + '</span> ';
}
div.html(newHTML);
}
$("input[type=button]").click(function(){
transformText("div");
$("div").show();
$("div span").each(function(index) {
(function(span, index) {
setTimeout(function() {
span.css("opacity", 0);
span.animate({
opacity: 1
});
}, index*100);
})($(this), index);
});
});

How to show all div's inside images titles onmouseover?

I have a div containing images and I want to show all of the inside image's titles onmouseover.
So, I have something like this :
<div id=MyDiv onmouseover="highlight(this);">
And my javascript :
function highlight(element) {
for (var i = 0; i < element.children.length; i++) {
if (element.children[i].tagName == "IMG")
element.children[i].title.show();
}
}
But all i get is a message - Object "X" has no method show.
You are using plain JavaScript. title is a string, and as the message says, it has no method show.
If what you want to do is alert all the titles in a pop-up, you can do this:
function highlight(element) {
for (var i = 0; i < element.children.length; i++) {
if (element.children[i].tagName == "IMG")
alert(element.children[i].title);
}
}
If, on the other hand you want to show them on your page you need something like this:
function highlight(element) {
var outputelement = document.getElementById("idofsomeelementyouhaveonyourpage");
for (var i = 0; i < element.children.length; i++) {
if (element.children[i].tagName == "IMG")
outputelement.innerHTML += element.children[i].title;
}
}
Of course, with the second method, you'd need an onmouseout handler that hides the titles as well.
Here is an example using jQuery:
HTML:
<div id="MyDiv">
<img src="http://chandra.harvard.edu/photo/2012/m101/m101_xray_thm100.jpg" title="img1" />
<img src="http://passport-cdn.mobilenations.com/avatars/000/004/072/100x100_4072871.jpg?r=1" title="img2" />
</div>
jQuery:
$("#MyDiv").mouseenter(function () {
$mydiv = $(this);
$.each($('img', $mydiv), function () {
var pos = $(this).position();
$('<div>', {
class: 'imgtitle'
}).css({
position: 'absolute',
color: 'red',
top: pos.top + 5,
left: pos.left + 5
})
.html($(this).attr('title'))
.insertAfter($(this));
});
}).mouseleave(function () {
$('.imgtitle').remove();
});
Here's a jsfiddle showing it in action: http://jsfiddle.net/obryckim/k5hcJ/

Categories