I am dynamically populating an unordered list with JS for my mobile app. I am using JQuery mobile and Phonegap for developing.
In my list I want to call a function with parameters when clicked. I am able to call the function downloadPdf() without using any parameters, but not if I add them. I think it has something to do with quotes/double qoutes.
var $li = $("<li><a href='#' onclick='downloadPdf('"+val.title+"', '"+val.url+"')'>"+val.title+"</a></li>");
I am not able to debug as I am running this on my phone, so I hope someone with a more trained eye is able to see what's wrong here. Both val.title and val.url holds values of string type.
Do not use inline events. You are using jQuery, it makes it easy to attach events
var li = $("<li><a href='#'>"+val.title+"</a></li>");
li.find("a").on("click", function(){ downloadPdf(val.title,val.url); });
or use Data Attributes and a generic onclick handler
var li = $("<li><a class='download' href='#'>"+val.title+"</a></li>");
li.find("a").data("title", val.title).data("url", val.url);
and the generic click
$(document).on("click", "a.download", function (event) {
var anc = $(this);
downloadPdf( anc.data("title"), anc.data("url"));
event.preventDefault();
}
#epascarello is right, do not use inline event handlers.
But answering directly on the question just escape double quotes:
$("<li><a href='#' onclick='downloadPdf(\""+val.title+"\", \""+val.url+"\")'>"+val.title+"</a></li>");
Produces:
<li><a href='#' onclick='downloadPdf("value1", "value2")'>title</a></li>
Escape your quotes
var val = {title: 'foo', url: 'http://foo'}
var $li = $('<li>' + val.title + '</li>');
function downloadPdf() {
alert('params:' + JSON.stringify(arguments, null, 2));
}
$('body').append($li);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
or for better practice use click event handlers as #epascarello suggested.
Solution
First I advice putting the code in multiple lines just to ease reading.
var $li = $(''
+ '<li>'
+ '<a href="#" onclick="downloadPdf(\"' + val.title + '\", \"' + val.url + '\")">' + val.title
+ '</a>'
+ '</li>');
I specially do this for this awful templates.
Second you need to escape the quotes using \" or \'
Real advice
pay some attention to what epascarello is saying there. His way is way better and easy to understand, than the escaping mess in a single line.
Related
For a course assignment, I'm tasked with 'fixing' an instagram-like page that isn't working properly.
I need to render the hashtags from a tags list by creating an 'a' tag and an 'li' tag. eg. '#beachday (4)'
this is my (unsuccessful) code currently:
I assume the tags should show up with the photos that have been rendered on the page.
function renderTags (tags) {
var tagList = $('.tag-list ul');
tags.forEach(function (tag)
var a = $('<a>').text('#' + tag.tags + '(' + tag.tag_count + ')');
var li = $('<li>').addClass('u-pull-left');
li.append(a);
tagList.append(li);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Missing HTML here perhaps?</div>
I'm only beginning to learn CSS/html/jQuery so any help understanding where I'm wrong, or a point to any resource (looked at jQuery docs) is greatly appreciated.
~thank you
As I write the javascript code, the LiveServer webpage should reflect the code and changes and at the moment none of my edits have produced results.
1.Ensure the forEach method is properly wrapped in brackets
2.Attach the 'href' attribute to the 'a' tag to make it clickable
function renderTags (tags) {
var tagList = $('.tag-list ul');
tags.forEach(function (tag) {
var a = $('<a>').text('#' + tag.tags + '(' + tag.tag_count + ')');
a.attr('href', '#');
var li = $('<li>').addClass('u-pull-left');
li.append(a);
tagList.append(li);
});
}
We're making a To-do list
Here is the instructions:
Perfect! Now we want to add our HTML element to the document. We can do this using our handy .append() function.
Let's go ahead and append to our div with the .list class. We'll append a with class="item", since we'll want a way to target our appended s later when we remove them. (A "to do" list is no good if we can't check things off it.)
We'll want the contents of our div to be the contents of our input field, which we saved in the variable toAdd. That means when we append, we'll want to append:
'<div class="item">' + toAdd + '</div>'
Go ahead and .append() a with class="item" to the .list div of your HTML document, then MAKE SURE to click your button to add an item—the exercise will wait for you to do so!
I can't understand what needs to be done.
I tried this:
$(document).ready(function() {
$("button").click(function () {
var toAdd = $("input[name=checkListItem]").val();
$(".list").append("div class='item'" + toAdd + "div");
});});
But it doesn't work when I type anything and click the button.
Close! Try this:
$(document).ready(function() {
$("#button").click(function() {
var toAdd = $("input[name=checkListItem]").val();
$(".list").append("<div class='item'>" + toAdd + "</div>");
});
});
You didn't have the HTML angle brackets inside your append(). Also, the $("button") should be $("#button") as it is ID "button", not a real <button>.
$(".list").append("div class='item'" + toAdd + "div");
should instead be:
$(".list").append("<div class='item'>" + toAdd + "</div>");
or
$(".list").append($('<div>').addClass('item').text(toAdd));
People on here are recommending that I use jQuery, but when I changed the code to jQuery and used .html() it is like it did nothing. I even removed half of the html code that needed to be added as someone suggested I was asking way to much of innerHTML and HTML.
In Simple task, all I want is for when a user click on the DIV that it runs the onClick event.
html += "<div onClick='loadnewsstory();' class='news'> this is a test story, for this test story we are not getting data from JSON</div>";
I have tried both
$("#activecontent").html(html);
document.getElementById("activecontent").innerHTML
The problem I have is relating to the following code.
function newsstories()
{
document.getElementById("activecontent").innerHTML = "<h1 class='newsheader'>Latest News</h1>";
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","http://test.com/?uri=loadnews",false);
xmlhttp.send();
var newsreponse = JSON.parse(xmlhttp.responseText);
for (var i = 0, len = newsreponse.length; i < len; ++i) {
var news = newsreponse[i];
if(i % 2 == 0){
cssclass = "even";
}
else
{
cssclass = "odd";
}
// alert(news.featured_image);
document.getElementById("activecontent").innerHTML = document.getElementById("activecontent").innerHTML + "<div class='news " + cssclass + "'><div class='newstitle'><div class='newstitlecolor' id='news_"+ countstory+"'><a href='javascript:loadnewsstory();'>" + news.post_title + "</a></div></div><div class='base' style='background: url('" + news.featured_image + "');'><img src='" + news.featured_image + "' style='width:100%; height:100%;'/></div></div>";
}
}
you will see in this area i have a link
<a href='javascript:loadnewsstory();'>" + news.post_title + "</a>
it suppose to fire
function loadnewsstory()
{
navigator.notification.alert(device.uuid);
}
but I am not getting that fire.
Yes this is a web app for iOS and Cordova but I believe this is a javascript issue.
Don't use +=, as it is used in an improper instance and returns an "unexpected token" error because var html was not previously equal to anything. I removed it and it appeared to fix the problem. Fiddle
If you must use += set var html = $("#activecontent").html(), then you may afterwards use += when you re-define the variable (Fiddle 2)
If your structure looks like
html
<div id="activecontent">
<div class='news'>Story 1</div>
<div class='news'>Story 2</div>
</div>
and you want each div.news to by dynamic and clickable, you could do that like this with jQuery
javascript
$(function(){
$("#activecontent").on('click', '.news', function(){
//You clicked the div
console.log( 'Clicked', $(this) );
});
});
And if you want to append divs to your #activecontent with an ajax request. Let's assume your JSON looks like
json
[
{ "id": 1, "content": "My first story" },
{ "id": 2, "content": "Another one" },
{ "id": 3, "content": "Last story" }
]
Your javascript to load that could look like
javascript
$.getJSON( "http://url_of_json.json", function(result){
for(var i in result){
$("#activecontent").append( $("<div>").addClass('news').html(result[i].content) );
}
});
alternative javascript for the ajax which is faster on the DOM
$.getJSON( "http://url_of_json.json", function(result){
var newHtml = "";
for(var i in result){
newHtml += "<div class='news'>" + result[i].content + "</div>";
}
$("#activecontent").append( newHtml );
// Or $("#activecontent").html( newHtml );
// if you want to replace what the page loaded with
});
Now to explain. The first piece of javascript with the .on, what were doing there is binding an event listener to your parent div, #activecontent. We do that because it will always exist in your page. You will be adding and maybe removing divs from that container based on your AJAX call, so instead of having to bind a click (or inline some javascript for every div), you can bind once to the parent, and then delegate that click to '.news'. You can alternatively bind the click to each new div, but delegating is cleaner.
As for the part about loading the JSON and writing it. If you are going to add some stuff to a node's innerHTML, the jQuery way is to use .append(). It's just a shortcut to something like
//vanilla js way
var e = document.getElementById('myThing');
e.innerHTML = e.innerHTML + "Thing I want to append";
// vs jQuery way
$("#myThing").append("Thing I want to append");
//To continue this example, to replace your myThing's html
//vanilla
e.innerHTML = "my new html";
//jQuery
$("#myThing").html("my new html");
Hopefully this clears things up for you. If you are just jumping into jQuery, know that it's not always that it's faster to write than the vanilla javascript, but rather that when you do something like ..html('new stuff');, it's going to use a method that works best with all browsers. So if there's some rogue version of IE out there than wants to use .innerHTMLmsIsNeat instead of .innerHTML, jQuery will sort that for you.
I had asked a question about How to open option list of HTML select tag on onfocus(). At that time it solved my problem but I missed one problem that every time on opening a html select option onfocus next select option went disappear.
I not able to find whats going wrong with this code.
here is link for that problematic question jsFiddle.
Yes, that's what the lines
var x = "select[tabindex='" + (parseInt($(this).attr('tabindex'),10) + 1) + "']";
$(x).fadeTo(50,0);
do. They hide the next select, because otherwise it would show on top of the expanded one.
This isn't a good solution at all though. Instead i'd use z-index to prevent that from happening:
$('select').focus(function(){
$(this).attr("size",$(this).attr("expandto")).css('z-index',2);
});
$('select').blur(function(){
$(this).attr("size",1).css('z-index','1');
});
$('select').change(function(){
$(this).attr("size",1).css('z-index','1');
});
It would be even better to use a class instead of inline style. But i used that just as a demonstration.
http://jsfiddle.net/PpTeF/1/
Just comment out the fadeTo function. check this http://jsfiddle.net/PpTeF/2/
$(document).ready(function(){
$('select').focus(function(){
$(this).attr("size",$(this).attr("expandto"));
var x = "select[tabindex='" + (parseInt($(this).attr('tabindex'),10) + 1) + "']";
//$(x).fadeTo(50,0);
});
$('select').blur(function(){
$(this).attr("size",1);
var x = "select[tabindex='" + (parseInt($(this).attr('tabindex'),10) + 1) + "']";
//$(x).fadeTo('fast',1.0);
});
$('select').change(function(){
$(this).attr("size",1);
var x = "select[tabindex='" + (parseInt($(this).attr('tabindex'),10) + 1) + "']";
//$(x).fadeTo('fast',1.0);
});
});
Cheers!!
Using javascript I'm looping through my H3 elements like this:
$('h3').each(function(){ });
I'm then generating an anchor for that tag formatted like this: "section-x" where x increments for each H3 on the page. The problem I have is that I'd like the first letter of the header to be an anchor link, like this:
*H*eading
.. where H is underlined, representing a link. I can format the anchors however I don't know how to wrap a hyperlink tag around the first letter in each heading. Some help would be greatly appreciated.
Regards,
kvanberendonck
Something like this?
$('h3').each(function(){
var currentHeading = $(this).text();
$(this).html("<a href='link'>" + currentHeading.substr(0,1) + "</a>" + currentHeading.substr(1, currentHeading.length - 1));
});
Let's throw some plain javascript into the mix:
$('h3').html(function(i){
var self = $(this)
, html = self.html()
return html[0].anchor('section-'+i) + html.substring(1)
})
html (and most other setter functions) accepts a function as an argument and uses the return value for each element
"string".link(target) creates the code string. A nice vintage useful method
edit: switched from .link to .anchor. Anchors are deprecated though, you should start using IDs for that:
$('h3').html(function(i){
var self = $(this)
, text = self.text()
// give the H3 an id and link to it
// ideally the headers should already have an id
this.id = 'section-'+i
return text[0].link('#section-'+i) + text.substring(1)
})
$('h3').each(function(i){
var firstLetter = $(this).text()[0];
$(this).html('' + firstLetter + '' + $(this).text().substr(1));
});
Not sure where you'd like to put section-x in that heading, but you can use i inside that each() to get the current iteration index.