I'm cloning input fields and then when I edit the cloned input field I'm trying to put the new values into an outside div as a text string. Thanks for your help in advance!
function cloneClue(target){
clueCount++;
var myClueField = $(target).prev().find('#textClue');
var myClone = myClueField.clone().attr('id','textClue' + clueCount);
var clueName = myClone.find('.clueName');
var clueContent = myClone.find('.clueContent');
var clueRemove = myClone.find('.clueRemove');
var clueNamePreview = myClone.find('.clueNamePreview');
var clueContentPreview = myClone.find('.clueContentPreview');
clueName.attr('name', "clueName" + clueCount);
clueName.attr('id', "clueName" + clueCount);
clueContent.attr('name', "clueContent" + clueCount);
clueContent.attr('id', "clueContent" + clueCount);
clueRemove.attr('id', "clueRemove" + clueCount)
clueNamePreview.attr('id', "clueNamePreview" + clueCount);
clueContentPreview.attr('id', "clueContentPreview" + clueCount);
clueRemove.click(function() {
$(this).parent().remove();
});
$('#clueField').append(myClone);
myClone.show();
}
var clueCount = 0;
$(document).ready(function() {
$("#addTextClue").click(function(){
cloneClue(this)
});
$('.clueName').keyup(function(){
var nameVal = $(this).val();
$(this).parent().find('.clueNamePreview').html(nameVal);
});
$('.clueContent').keyup(function(){
var contentVal = $(this).val();
$(this).parent().find('.clueContentPreview').html(contentVal);
});
});
Here's the jsfiddle
You need to use the .on for any element that is dynamically added to the DOM.
Change your jQuery to:
$(document).on("keyup", ".clueName", function() {
....
}
etc...
Your problem is that you define you keyup listeners in your document.ready function. at this point your cloned elements aren't in your DOM, so there aren't any Listeners attached to your clones. Just move this part of code right after you appended your input clone like this:
http://jsfiddle.net/8yv5x7dg/2/
Related
Working on a practice app with localStorage, but the stored data is getting cleared on page refresh. Based on answers to similar questions, I've used JSON.stringify(); on setItem, and JSON.parse(); on getItem, but still no luck. Am I using those methods in the wrong way? For reference, #petType and #petName are input IDs, and #name and #type are ul IDs. Thanks!
var animalArray = [];
var addPet = function(type,name) {
var type = $("#petType").val();
var name = $("#petName").val();
localStorage.setItem("petType", JSON.stringify(type));
localStorage.setItem("petName", JSON.stringify(name));
animalArray.push(type,name);
};
var logPets = function() {
animalArray.forEach( function(element,index) {
//empty array
animalArray.length = 0;
//empty input
$("input").val("");
var storedName = JSON.parse(localStorage.getItem("petName"));
var storedType = JSON.parse(localStorage.getItem("petType"));
//append localStorage values onto ul's
$("#name").append("<li>" + storedName + "</li>");
$("#type").append("<li>" + storedType + "</li>");
});
};
//click listPets button, call logPets function
$("#listPets").on("click", function() {
logPets();
$("#check").html("");
});
//click enter button, call addPet function
$("#enter").on("click", function() {
addPet(petType,petName);
$("#check").append("<i class='fa fa-check' aria-hidden='true'></i>");
});
It appears to clear because you are not loading data from it when the page loads. There are multiple bugs in the code:
It appears that you're only saving the last added pet to localStorage, which would create inconsistent behaviour
Setting animalArray.length to 0 is incorrect
animalArray.push(type, name); is probably not what you want, since it adds 2 items to the array, do something like animalArray.push({type: type, name: name});
logPets can just use the in memory array, since it's identical to the one saved
Fixed code:
var storedArray = localStorage.getItem("animalArray");
var animalArray = [];
if(storedArray) {
animalArray = JSON.parse(storedArray);
}
var addPet = function(type,name) {
var type = $("#petType").val();
var name = $("#petName").val();
animalArray.push({type: type, name: name});
localStorage.setItem("animalArray", JSON.stringify(animalArray));
};
var logPets = function() {
animalArray.forEach( function(element,index) {
//empty input
$("input").val("");
//append localStorage values onto ul's
$("#name").append("<li>" + element.name + "</li>");
$("#type").append("<li>" + element.type + "</li>");
});
};
//click listPets button, call logPets function
$("#listPets").on("click", function() {
logPets();
$("#check").html("");
});
//click enter button, call addPet function
$("#enter").on("click", function() {
addPet(petType,petName);
$("#check").append("<i class='fa fa-check' aria-hidden='true'></i>");
});
A quick fiddle to demo it: https://jsfiddle.net/rhnnvvL0/1/
I have an 'a' tag, so when I do click over it, It shows other html content (list). The JS code is generic to others tabs...
What I need is when I press the (link) "Title" again, the list gets hide.
What should I do?
I've done this demo
JS
$(".nav_tab>ul>li>a").click(function(event) {
$(".nav_tab>ul>li>a").parent().removeClass("activo");
$(this).parent().toggleClass("activo");
var capa = $(this).prop('href').split('#');
$(".nav_tabcontent").slideUp("fast");
$("#"+capa[1]).slideDown("slow");
event.preventDefault();
});
$(".nav_tab>ul>li>h3").click(function(event) {
$(".nav_tab>ul>li>a").parent().removeClass("activo");
var o = $(this).parent().find("a");
o.parent().toggleClass("activo");
var capa = o.prop('href').split('#');
$(".nav_tabcontent").slideUp("fast");
$("#"+capa[1]).slideToggle("slow");
event.preventDefault();
});
All you have to do is use jQuery toggle class. Here is the fiddle: http://jsfiddle.net/d90ac70w/2/. Just check to see if the div has a class of active.
$(".nav_tab>ul>li>h3").click(function (event) {
$(".nav_tab>ul>li>a").parent().removeClass("activo");
var o = $(this).parent().find("a");
o.parent().toggleClass("activo");
var capa = o.prop('href').split('#');
if(!$("#" + capa[1]).hasClass('active')){
$("#" + capa[1]).slideDown();
$("#" + capa[1]).toggleClass('active');
}else{
$("#" + capa[1]).slideUp();
$("#" + capa[1]).toggleClass('active');
}
event.preventDefault();
});
Since we are calling the same jQuery selector. We can chain the methods together.
$(".nav_tab>ul>li>h3").click(function (event) {
$(".nav_tab>ul>li>a").parent().removeClass("activo");
var o = $(this).parent().find("a");
o.parent().toggleClass("activo");
var capa = o.prop('href').split('#');
if(!$("#" + capa[1]).hasClass('active')){
$("#" + capa[1]).slideDown().toggleClass('active');
}else{
$("#" + capa[1]).slideUp().toggleClass('active');
}
event.preventDefault();
});
At the moment i have a list of elements and when clicked on one of them
it will get the number accordingly. However i need a different approach
that won't count the number of elements but returns the id number of that
specific element.
http://jsfiddle.net/FN4fy/
$('#outputData').on('click', 'li.element', function() {
var num = $('#outputData li.element').index(this);
alert(num);
var loc = window.location + "";
var pos = loc.indexOf('#');
if (pos > -1) {
loc = loc.substring(0, pos);
};
loc = loc + '#ti' + num;
window.location = loc;
});
try this
$('#outputData li').click(function() {
var idOfLi = $(this).attr('id');
alert(idOfLi);
// rest of your code
});
and this is jsfiddle
$(this).attr("id") will give the current element id, because event binded to li.
$('#outputData').on('click', 'li.element', function() {
window.location += $(this).attr("id") ;
});
Javascript:
JSFiddle with ti
JSFiddle without ti
jQuery
JSFiddle With ti
JSFiddle - Without ti
Answer
You can use this.id if you want ti#, or this.id.substring(2) if you just want the number.
You can also use
window.location += "#"+this.id.substring(2);
If you want to go to the location on the current page.
Here is the jsFiddle
$('#outputData').on('click', 'li.element', function() {
var num = $(this).attr('id');
alert(num); // returns id
});
In case you want to fetch the number alone, then
$('#outputData').on('click', 'li.element', function() {
var num = parseInt($(this).attr('id').match(/\d+$/),10);
alert(num); // returns number
});
I'm having a problem with my code, lemme first paste my code, most of it isn't important, just the context of it.
$("#navbar > a").click(function(event) {
$('#controls').show();
var currentNum = parseInt($(this).attr('class'), 10);
document.getElementById('pNum').innerHTML = "pg. " + (currentNum + 1);
event.preventDefault();
var t2 = ($(this).attr('id')).split("#");
var $tr = $(zip.file(localStorage.selected + "/" + t2[0]).asText());
document.getElementById('main').innerHTML = "";
$('#main').append($tr);
document.getElementById(t2[1]).scrollIntoView()
current = ($(this).attr('class'));
$(function() {
$("#main img").each(function() {
var imgPath = localStorage.selected + "/" + $(this).attr('src');
var imageData = zip.file(imgPath).asBinary();
$(this).attr('src', 'data:image/jpeg;base64,' + btoa(imageData));
});
});
$("#main a").click(function(event){
event.preventDefault();
var elems = ($(this).attr('href')).split("#");
var $path = $(zip.file(localStorage.selected + "/" + elems[0]).asText());
document.getElementById('main').innerHTML = "";
$('#main').append($path);
});
});
Now the click event at the bottom only works if I place it inside the code that creates the content, which shouldn't be the case and secondly it only works once, after I call it for the first time it refuses to work, any suggestions ?
It sounds like you want to use event delegation instead. For example:
$(document).on('click', '#main a', function(event){
event.preventDefault();
var elems = ($(this).attr('href')).split("#");
var $path = $(zip.file(localStorage.selected + "/" + elems[0]).asText());
document.getElementById('main').innerHTML = "";
$('#main').append($path);
});
The problem is that the $('#main a').click(...) approach requires that the #main a elements already be present on the page at the time that the click handler is bound.
Event delegation allows you to listen for a click event on the document (or any other element that will always be present), and see if that event originated from a #main a element. This allows you to add/remove elements on the fly without worrying about which ones have or haven't already had click handlers bound.
I've had this problem before, have you tried using this?:
$("<element id>").on( 'click', this, function ()
{
// Your code here
}
reference: http://api.jquery.com/on/
edit* Sorry did not see an answer before ( better explanation in answer above ) - but I'll keep mine for reference.
I have a modal box in jQuery which I have created to display some embed code. I want the script to take the id of the link that is clicked but I can't seem to get this working.
Does anyone know how I can do that or why this may be happening?
My jQuery code is:
function generateCode() {
var answerid = $('.openembed').attr('id');
if($('#embed input[name="comments"]:checked').length > 0 == true) {
var comments = "&comments=1";
} else {
var comments = "";
}
$("#embedcode").html('<code><iframe src="embed.php?answerid=' + answerid + comments + '" width="550" height="' + $('#embed input[name="size"]').val() + '" frameborder="0"></iframe></code>');
}
$(document).ready(function () {
$('.openembed').click(function () {
generateCode();
var answerid = $('.openembed').attr('id');
$('#box').show();
return false;
});
$('#embed').click(function (e) {
e.stopPropagation()
});
$(document).click(function () {
$('#box').hide()
});
});
My mark-up is:
Embed
Embed
Your problem is here:
$('.openembed')
returns an array of matched elements. Your should instead select only the clicked element.
$('.openembed') works correctly if you assing a click event to all elements that have this class. But on the other hand, you're unable do know which is clicked.
But fortunately in the body of handler function click you could call $(this).
$(this) will return the current (and clicked element).
// var answerid = $('.openembed').attr('id'); // Wrong
var answerid = $(this).attr('id'); // Correct
// Now you can call generateCode
generateCode(answerid);
Another error is the body of generateCode function. Here you should pass the id of selected element. This is the correct implementation.
function generateCode(answerid) {
if($('#embed input[name="comments"]:checked').length > 0 == true) {
var comments = "&comments=1";
} else {
var comments = "";
}
$("#embedcode").html('<iframe src="embed.php?answerid=' + answerid + comments + '" width="550" height="' + $('#embed input[name="size"]').val() + '"frameborder="0"></iframe>');
}
Here I have implemented your code with the correct behavior: http://jsfiddle.net/pSZZF/2/
Instead of referencing the class, which will grab all members of that class, you need to reference $(this) so you can get that unique link when it is clicked.
var answerid = $(this).prop('id');
$('.openembed').click(function () {
generateCode();
var answerid = $(this).attr('id');
$('#box').show();
return false;
});
Use $(this). $('.openembed') refers to multiple links.
var answerid = $('.openembed').attr('id');
needs to be
var answerid = $(this).prop('id');
The other answers are trying to fix the click() function, but your issue is actually with the generateCode function.
You need to pass the clicked element to the generateCode function:
$('.openembed').click(function () {
generateCode(this);
And modify generateCode:
function generateCode(element) {
var answerid = element.id;
Of course var answerid = $('.openembed').attr('id'); within the click code isn't correct either, but it doesn't seem to do anything anyway.
Get the id when the correct anchor is clicked and pass it into your generateCode function
$('.openembed').click(function () {
var answerid = $(this).attr('id');
generateCode(answerid)
$('#box').show();
return false;
});
Change your function
function generateCode(answerid) {
// dont need this line anymore
// var answerid = $('.openembed').attr('id');