Removing HTML from a jQuery .append() - javascript

I have a Parse.com backend and am rendering its data, ultimately, with a jQuery append, like this:
$(".albums").append(
"<div class='col-xs-6 col-6 col-sm-3 col-lg-3'><div class='flip animated fadeInDown' style='-webkit-animation-delay:" + i * 0.1 + "s'><div class='card'><div class='album front' style='background-image:url(" + bigImg + ")'><img class='artwork' src='" + artwork + "' alt='" + collectionName + "' /></div><div class='album back' style='background-image:url(" + back + ")'><img class='artwork' src='" + back + "' alt='" + collectionName + "' /></div></div></div></div>");
It's a for loop hence the need for the various HTML elements and their classes. I know it's an appalling, shameful way to do it (and I believe it's causing a memory leak).
My questions are: How can I remove as much of the HTML from this append statement as possible? Should I be using a templating language?

If you think you might want to use a templating language you can start by building your own, super simple, template.
Simply replace
"some string stuff " + someValue + " some more stuff"
// instead
var myTemplate = "some string stuff {someValue} some more stuff";
// now render
myTemplate.replace('{someValue}', someValue);
It's easy to go further, and wrap this in a function to "render" that takes an object as an argument and iterates over keys. Done carefully this will provide you a subset of the functionality provided by "off-the-shelf" templating libraries so you can always cut-over later.
This will allow you to predefine your "template" and render using the data input provided. The next question is where do you want to define your template. Generally you would relocate it to a separate free-standing file that the designers would have access to, perhaps in a "templates" directory. But then you have to load it.
If you have lots of templates, some libraries would allow you to pack them together in one file, load the file, then ask the library for a specific template by name. Your designers would then control this file and the CSS that goes with it. If you have a lot of this, then the architectural overhead starts to make sense.
Whether you want to go down that road really depends on your specific circumstances and the structure of your project team.

I like Handlebar for this sort of thing.
This would be the template
<script id="albumsTemplate" type="text/x-handlebars-template">
<div class='col-xs-6 col-6 col-sm-3 col-lg-3'>
<div class='flip animated fadeInDown' style='-webkit-animation-delay:{{delay}}s'>
<div class='card'>
<div class='album front' style='background-image:url({{bigImg}})'>
<img class='artwork' src='" + artwork + "' alt='{{collectionName}}' />
</div>
<div class='album back' style='background-image:url({{back}})'>
<img class='artwork' src='" + back + "' alt='{{collectionName}}' />
</div>
</div>
</div>
</div>
</script>
And then you would use it like this:
var source = $("#albumsTemplate").html();
var template = Handlebars.compile(source);
var html = template({delay:i*0.1,
bigImg:bigImg,
collectionName:collectionName,
back:back});
$(".albums").append(html)

Adding html() to the call should do it. That'll return the html inside of .albums. To get everything including .albums you do $('.albums').append(...).parent().html().

Related

Split javascript file into multiple files

i am not familiar with javascript/jquery, that's why my question:
I want to split existing javascript file to make code more readable.
I have multiple text blocks, which i want to put in separate file/files.
What is the best way to realise it?
if (facet === "FACET_NAME") {
$(this.target).append(
$('<span> </span><a class="click" onclick="show_hidePopUpWindow(\'foo\');"
onmouseover="" style="cursor: pointer;"> ' + info_button + "</a>" +
"" + '<div class="menu" id="foo" style="display:none">
<a onclick="show_hidePopUpWindow(\'foo\');">' +close_button +"</a><b> TEXT </b>\n"
+"<br><b>CONTENT:</b> Fulltexts of all articles from the inception ...\n" +
"<br><b>NOTE:</b> To see the image-PDF of the issue you will have go to the database ... \n</div>"
));}
You can insert your js file into another file with the line:
<script src="/path/to/script.js"></script>

Using Javascript to write html code and change file and description

Hello I am trying to write coding for my website using Javascript and HTML. I have images on my website that I would like to have pop up or float on the side of the screen when you have your mouse over the link. I know I need to use onmouseover for this in the HTMl but I am having a lot of trouble understand Javascript and how to make this happen. The book I am using says to make add a statement to the function I made to set the value of the HTML code for the element with pix to the text
are file and desc already in javascripts language? does it know what those mean or do I need to add cariables for them and if so how do I do that?
I know it wants the file value to be the file name and the desc to be the text in the alt section of my HTML.
this is the coding that I made.
function switchPix(file, desc){
document.getElementById("pix").innerHTML=("<img src=\"images/file.jpg\" width\"480\" height=\"270\" alt=\"desc\" />");
}
I noticed that a lot of the ways everyone was refering to the image was with http but the image i have is just an image file like museum.jpg that I am suppose to be taking from a folder and putting into the website. can I just reference it like normal? "
If your images are part of your style and not part of critical content use them as background images and change them with css (img:hover for example). For effects use transitions and animations in css. It's 2016 and they are pretty good supported nowadays. This year I have moved as much as possible UI effects into CSS.
Solution for your question in pure js.
//First of all learn more about concatenation.
function switchPix(file, desc){
document.getElementById("pix").innerHTML=('<img src="' + file + '" width="480" height="270" alt="' + desc + '" />');
}
//Place first pic you want people to see
switchPix("firstPicURL", "My alt");
var pix = document.getElementById("pix");
//Use second pic for mouseover
pix.addEventListener('mouseover', function(){
switchPix("secondPicURL", "My alt");
}, false);
//Use firstPic for mouseout
pix.addEventListener('mouseout',function() {
switchPix("firstPicURL", "My alt");
},false)
I think the main problem is the concat you're using
function switchPix(file, desc){
document.getElementById("pix").innerHTML=('<img src="' + file + '" width="480" height="270" alt="' + desc + '" />');
}
switchPix("https://http.cat/100", "Continue");
https://jsfiddle.net/coins5/vu80586x/
As you have tagged jquery, I've taken the liberty to use it.
Below is an example on how to do this using jquery, I've thrown in a couple comments along the way to help explain what's going on
Edit: Note that it does show the image in fullsize, but you will have to scroll down to see it, I've made a commented javascript where I hope you'll take your time to read the comments and try to understand what's going on, but you'll be the one to style it to your needs
// The dollar sign is the object which contains everything related to jquery
// If you get an error about it not finding jquery, make sure you have the jquery script reference in the html.
// $("css selecter") - In this clase the class "picture"
// hover has 2 arguments, first is the function to call when your mouse moves in above an element
// 2nd is when your mouse leaves the lement
$(".picture").hover(function() {
// "this" is the element that is hovered above
// $(this).attr(propertyName) returns a property from "this"
// In the snippet you included, you added the the names of the variables as string literals
// That means if we do something like this
// var src = "image.jpg";
// var img1 = "<img src=\"src\" >";
// var img2 = "<img src=\"" + src + "\" >";
// img1 is now => <img src="src" />
// img2 is now => <img src="image.jpg" />
// Be sure to understand what's going on in these 5 lines above, I do believe that's what went wrong in your own script.
$("#pictureDisplayContainer").html("<img src=\"" + $(this).attr("data-displaySrc") + "\" />");
},
function() {
$("#pictureDisplayContainer").html("");
});
.picture {
display: block;
max-width: 100px;
margin-bottom: 10px;
}
#pictureDisplayContainer > img {
display: block;
max-width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Out of pure laziness, I've used the same image for thumbnail and full-size, I recommend having 2 different pictures which are both scaled to match the purpose.</p>
<img class="picture" src="http://cdn.artobserved.com/2014/02/Andisheh-Avini-Marianne-Boesky-Gallery-8.jpg" data-displaySrc="http://cdn.artobserved.com/2014/02/Andisheh-Avini-Marianne-Boesky-Gallery-8.jpg" />
<img class="picture" src="http://www.wentrupgallery.com/media/gallery.jpg" data-displaySrc="http://www.wentrupgallery.com/media/gallery.jpg" />
<div id="pictureDisplayContainer"></div>
Including a sample snippet to play around with.
We have created a sample HTML page with few links and the idea is to show the relevant image based on the action (here I am including click action / event; it can be changed to anything based on your requirement) on those links.
To answer the questions:
I am having a lot of trouble understand JavaScript and how to make
this happen
As stated, we have included an handler to the click event to the element a. Upon the action (which is click), the handler would be called with the parameters which we have passed. In this case - a file (an image) and description (description of the image).
function switchPix(file, desc) {
// construct the HTML
var html = "<img src='" + file + "' width='480' height='270' alt='" + desc + "' />";
// Find the element and set as it's inner HTML
document.getElementById("pix").innerHTML = html;
}
.navlist {
list-style-type: none;
}
.navlist li {
display: inline-block;
padding: 20px;
background-color: #F3F3F3;
}
.navlist li a {
text-decoration: none;
color: #76432a;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>My Website</title>
</head>
<body>
<div class="nav">
<ul class="navlist">
<li>
<a href="#" onclick='switchPix("https://upload.wikimedia.org/wikipedia/commons/b/bf/Bucephala-albeola-010.jpg", "Duck");'>Duck</a>
</li>
<li><a href="#" onclick='switchPix("https://upload.wikimedia.org/wikipedia/commons/0/08/South_Shetland-2016-Deception_Island%E2%80%93Chinstrap_penguin_%28Pygoscelis_antarctica%29_04.jpg", "Penguin");'>Penguin</a>
</li>
<li><a href="#" onclick='switchPix("https://upload.wikimedia.org/wikipedia/commons/b/bb/Kittyply_edit1.jpg", "Cat");'>Cat</a>
</li>
</ul>
</div>
<div id="pix">
</div>
</body>
</html>
I know it wants the file value to be the file name and the desc to be
the text in the alt section of my HTML.
The JavaScript function can be constructed and invoked based on our choice. Coming to this case, we are giving an image element a source (file) and alt(description; when the image cannot be loaded, we have to at least show what we intended).

how to dynamically action an angular ng-include command

Is it possible to dynamically add an ng-include element to a HTML page and have it actioned?
I have a Drag N Drop application where you can drag an element onto the page and in the drop zone the element is replaced with a more detailed element. For examples you drag a box that says Calendar and when it is dropped a calendar is presented. To be clear a new Element is created and added to the DOM, it does not exist before the drop.
When the element is dropped, I'm hoping that I can replace it with a chunk of HTML that looks like below. Instead of having the markup defined in a string like it is at the moment which is not very nice:
<div class='panel panel-default'>
<div class='panel-heading'>
<h3 class='panel-title'>
<span class='glyphicon glyphicon-remove'></span>
WIDGET NAME
<spanclass='glyphicon glyphicon-cog'></span>
</h3>
</div>
<div class='widgetContainer' ng-include="'widgets/widget.html'"></div>
</div>
When the above HTML is inserted into the page the referenced HTML file is not included.
What I would like to happen is a HTML file is loaded containing the widget markup and included at the appropriate position.
I'm new to Angular so I don't know if this is because:
dynamically adding ng-include isn't supported
whether I need to do something with the controller to handle this logic
should I be using the tag instead of the attribute?
it just isn't possible.
Please provide examples with solutions, as I said I'm new to Angular.
Thanks
UPDATE
The code used to created the HTML that I want to dynamically add to the page looks like this
$("#template").append(
" \
<div class='panel panel-default'>\
<div class='panel-heading'>\
<h3 class='panel-title'>\
<span style='padding-right: 10px; cursor:pointer;' class='glyphicon glyphicon-remove' onclick='removeElement(this)'></span>\
" + widgetDetail['serviceName'] + "\
<span style='float:right; cursor:pointer;' class='glyphicon glyphicon-cog' onclick='toggleWidgetDetail(this)'></span>\
</h3>\
</div>\
<div class='markupContainer' ng-include=\"'widgets/" + id +".html'\"></div>\
</div>\
"
);
I've uploaded the complete code to GitHub. The drag and drop aspects are being handled currently by HTML5 javascript, which can be seen in the file /public/javascripts/js_dragndrop.js. The new widget being added to the page (the code above) is in /public/javascripts/jq_dragndrop.js
I'm in the prototyping phase trying to work out the DragNDrop elements so don't expect high quality code :)
I found a way of achieving what I wanted by moving the HTML5 drop and drop code into AngularJS directives and then (using this [ Compile dynamic template from outside of angular ] as a guide) got the html templates being loaded where I wanted them.
The main code change looks like this:
angular.element(document).injector().invoke(function ($compile) {
var widgetDetail = widgets[e.dataTransfer.getData('Text')];
var obj = $("#template");
var scope = obj.scope();
obj.append(
"<div class='panel panel-default'><div class='panel-heading'><h3 class='panel-title'>\
<span style='padding-right: 10px; cursor:pointer;' class='glyphicon glyphicon-remove' onclick='removeWidget(this)'></span>\
" + widgetDetail['serviceName'] + "\
<span style='float:right; cursor:pointer;' class='glyphicon glyphicon-cog' onclick='toggleWidgetDetail(this)'></span>\
</h3></div><div class='markupContainer' ng-include=\"'widgets/" + widgetDetail['serviceId'] + ".html'\"></div>\
"
);
$compile(obj.contents())(scope);
scope.$digest();
});
You can find the full code in the Git Project /public/controllers/template.js if you are interested.

Calling and json file and displaying it on html

I want to display images from my json file on a html page and organise them into rows of 3 or 4. Below is an example of the layout I want my page but this is hard coded,I have included images because I have having difficulty pasting the code (I can put this on fiddler) don't mind some of the word under the pictures some p tags needed taken out:
HTML:
<div id="container">
<div class="row">
<div class="product-container"> </div>
<div class="col-sm-4">
<img src="Image/iphone5.jpg" alt="StrappyMeshInsertDress" style="width:200px;height:250px">
<p><span> class="bold">Iphone5s</span><br />
</div>
Here is a snip from my json file:
json data
I am using this script to call the data although it has not been calling the json file:
the script
I have positioned the images when hard coding like this:
I have been at this for over a day and cannot get it to work, If anyone has any ideas on how to get this to work I would be very grateful.
Kind regards!
Please make sure that you are appending JSON data dynamically so please remove the HTML content, or only make a parent container who will hold all this Output data.Make a JSON file with the name 'iproducts.json' on the same path.
$.getJSON('iproducts.json',function(products){
var output=" <table border='1'><thead><th>Product_id</th><th>Info</th><th>Imgpath</th><th>Price</th><tbody>";
$.each(products.appleitems,function(index,value){
output+="<tr><td>" + value.Product_id + "</td><td></td></td><td>" + value.Information+"</td><td>"+"<img src ='images/" + value.Imgpath + ".jpg' alt='applepro' id='appleinf'" + value.Price +"</td><td>"
});
output+="</tbody></table>";
console.log("output =" + output);

jQuery Mobile JSON parsing

I'm trying to make a cross platform mobile application using jQuery Mobile.
I have a JSON string that displays information about a specific object (check it out here: http://app.calvaryccm.com/mobile/web/teachings/json?callback=?) and I want it to turn it into a list view that connects to a single item view. The problem is, the listview isn't displaying like a list at all. It is almost like HTML without CSS. Check it out here: http://mbeta.calvaryccm.com/#teachings
This is the Javascript for parsing the JSON string:
<!-- Getting Teaching Data -->
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("http://app.calvaryccm.com/mobile/web/teachings/json?callback=?",
function (data) {
//remove any characters from the query that might be unsafe to use as an ID for a page
//data.pageId = data.MessageNumber.replace(/[^\w]/, "");
//Feed the data to the template and add the new page to the body.
var res = $("#teachingTemplate").tmpl(data); //.appendTo(document.body);
$("#teachings").append(res);
//Grab a reference to that shiny new page
//var newpage = $("#" + data.pageId);
});
});
//Makes date readable
function GetDate(jsonDate) {
var value = new Date(parseInt(jsonDate.substr(6)));
return value.getMonth() + 1 + "/" + value.getDate() + "/" + value.getFullYear();
}
This is supposed to be the list view:
<script id="teachingTemplate" type="text/x-jquery-tmpl">
<div id="${MessageNumber}">
<div data-role="header">
<a data-icon="arrow-l" href="#" data-rel="back">Back</a>
<h1>${Title}</h1>
</div>
<div data-role="content">
<div class="teachingsForm">
<ul data-role="listview">
<li><a href="singleTeachingView" class="tableImage">
<img src="" alt=""/>
<h3>${Title}</h3>
<p>${Speaker} - ${GetDate(MessageDate)} - ${MessageNumber} {{if Book != null}} - ${Book.BookName} ${ChapterVerse}{{/if}}</p>
</a>
</li>
</ul>
</div>
</div>
<div data-role="footer">
<h4>2011 Calvary Chapel Melbourne</h4>
</div>
I cannot figure out why my listview isn't displaying right. If you want to see it in action look here: http://mbeta.calvaryccm.com/#teachings . I need help getting my listview to display right and direct to the right page.
It looks exactly like what your template says it should look like. Note that each of your <ul> elements only has one <li> element in it.
Your template starts off with an outer <div>, and then there's a "header" <div> with the <h1> title. Then there's the "content" <div>, and ultimately the <ul>, and finally the "footer". That's what your result page looks like. If you want to do some sort of iteration, well, you'll have to explicitly do that in your template, because otherwise the template code will assume you just want it to re-apply the template to each object in the array you pass it.
There's nothing wrong with the "JSON parsing". Note that in your JSON, there's no need to quote "/" characters with "\" and in fact (though it doesn't matter for JSONP) it's not valid JSON.
edit — OK so now that I've pulled my head out from wherever it was I think I see what you're doing. The problem may be that you just need to call
$.mobile.changePage();
at the end of your JSONP callback function. However I note that your "$.mobile" doesn't have a "changePage()" function ... I don't know what that means. You're using a pretty old version of jQuery too.

Categories