getElementById() display from several variables - javascript

I want to display via document.getElementById from an external javascript file a compilation of links to social networks depending on the language version of my website. The problem is it works perfectly for the first ID ("sociallv") but doesn't work for others ("socialen" and "socialru") if I use them separately on a webpage. What should I change?
/* Social networks start */
var start = "<div class='social justify-content-between'>"
var end = "</div>"
var facebook = "<a href='https://www.facebook.com/maggitekstils.lv' title='Facebook' rel='noreferrer' target='_blank'><div class='social-button facebook'></div>";
var draugiem = "<a href='https://www.draugiem.lv/maggitekstils.lv' title='Draugiem' rel='noreferrer' target='_blank'><div class='social-button draugiem'></div>";
var youtube = "<a href='https://www.youtube.com/channel/UC2H9dhm1Nzw3i4wveNTgHnQ/playlists' title='YouTube' rel='noreferrer' target='_blank'><div class='social-button youtube'></div></a>";
document.getElementById("sociallv").innerHTML = start + facebook + draugiem + youtube + end;
document.getElementById("socialen").innerHTML = start + facebook + youtube + end;
document.getElementById("socialru").innerHTML = start + facebook + youtube + end;
/* Social networks end */
<div class="social-media" id="socialen"></div>

Did you check if there are any errors in your JS Console ?
For Chrome: https://developers.google.com/web/tools/chrome-devtools/open
For Firefox: https://developer.mozilla.org/en-US/docs/Tools/Web_Console
I supspect that the execution of your Javascript is abborted because you're trying to set a value for a property on an object which does not exists and therefore the blocks
document.getElementById("socialen").innerHTML = start + facebook + youtube + end;
document.getElementById("socialru").innerHTML = start + facebook + youtube + end;
are never reached. You should always do a check if the queried element exists or not:
// ...
if ( document.getElementById("socialen") ) {
document.getElementById("socialen").innerHTML = start + facebook + youtube + end;
}
// ...

In the html provided, you only have an element with id socialen which is why when you set the innerHTML of socialen it works. However socialru and sociallv aren't html elements therefore its not actually setting anything.
If you add the following to your html, you should get the expected result
<div class="social-media" id="sociallv"></div>
<div class="social-media" id="socialru"></div>

Related

How do I prevent loading the same image multiple times when generating elements?

I have a script that generates product "cards" on my website. These product cards contain images of the products. When they initially load, they have tiny-sized placeholder images to indicate that the actual product images are still loading (lazy-loading).
However, when I check the network activity, the placeholder image [blank.gif] is being downloaded and re-downloaded for every instance of it on the page. This impacts the loading of the page, which cuts into the time saved with the lazy-load script.
screenshot of images loading in the network tab of dev console
Currently, the cards' HTML is assembled into a variable then it's appended to its respective place in the body of the page's HTML, one at a time. See Below
How can I make it so that the image only loads from the server once, and shows up in the multitude of places it belongs?
Card Code:
// Simplified for Stack Exchange
// A JSON file contains activeCards which this script pulls data from
var cardImgs = '';
for (let i of activeCards) {
cardImgs = "<img class='soloImg' src='images/blank.gif' data-src='images/" + i.img + "' alt='" + i.imgAlt + "' />";
// Builds card HTML from elements above
card = "<div class='card' id='" + i.id + "'>" +
"<div class='cardImagesCont'>" + cardImgs + "</div>" +
"<h2>" + i.title + "</h2>" +
"<h4 class='itemDesc'>" + i.description + "</h4></div>";
// Adds card to section
$('.cardSection').append(card);
}
Lazy Load Code:
function lazyload() {
for (let i of $('img[data-src]')) {
$(i).attr('src', $(i).attr('data-src'));
}
}
I'm self-taught, so please don't be too cruel if there's something shockingly wrong with this code (but do let me know)

Cannot show TrustPilot HTML when inserted with JavaScript (jQuery)

If I added the TrustPilot html code directly on the HTML page, it works fine but I needed to insert it with jQuery. I see the HTML code when inserted but it's not displaying.
$(window).on('load', function () {
var el = $('#some-element');
el.html( trustPilotHtml() );
function trustPilotHtml() {
var str = "<div " +
"class='trustpilot-widget' " +
"data-locale='en-GB' " +
"data-template-id='123456' "+
"data-businessunit-id='123456' " +
"data-style-height='500px' " +
"data-style-width='100%' " +
"data-theme='light' " +
"data-stars='4,5' " +
"data-schema-type='Organization'>" +
"<a " +
"href='https://some-url.com' target='_blank'>Trustpilot</a> " +
"</div>";
return $(str);
}
});
Is the only way of getting the element to display properly is to directly inserted into the HTML without javascript?
No it's not the only way.
You should have a bootstrap script in your inside the HEAD part of your HTML (or close to it).
This script takes care of initializing all the widgets (TrustBoxes in Trustpilot lingo) that you have in your HTML.
Of cause that doesn't work if you are injecting the HTML dynmically, so it's also possible to call window.Trustpilot.loadFromElement(trustbox); yourself, when if you need to.
Here trustbox is a HTMLElement, you could get by using document.getElementById("some-element") or similar.
Reference: https://support.trustpilot.com/hc/articles/115011421468
The following worked for me on a product list page which returned filtered list via ajax
var element = document.getElementsByClassName("trustpilot-widget");
for(var i=0; i<element.length; i++) {
window.Trustpilot.loadFromElement(element[i]);
}
On the first page load all product reviews are displayed as expected, but if the page is updated via ajax call (using filters for example) the reviews are lost. Running the above code after ajax, reloads the reviews

How do I allow multiple downloads using anchor tags via a Java Servlet?

I am trying to download multiple pdf's from one click from the user (working in chrome). Once the user clicks on the relevant button a for loop is triggered to see how many documents need to be downloaded, for which each needs a download dialog. In the for loop I am mimicking a click for each pdf (this is done via javascript's click event).
The Java servlet code is below:
out.print("<a id='exportAchievement' style='display:none' href='" + tempFileName + "'download='" + pdfName + "'></a>");
out.print("<script>document.getElementById(\"exportAchievement\").click();</script>");
This works perfectly for one pdf, but as soon as I do two or more then each dialog that pops up uses the first pdf (the name and actual pdf is the same as the first one).
I checked if my variables are getting mixed up but, by use of print outs before and after the above code, it shows that the variables are correct.
My assumption is that the error is on the browser side because of the dialog working when one pdf needs to be downloaded, but I am stumped.
The relevant for loop is as follows:
// pdfs.length determines the number of pdf's to download
for (int j = 0; j < pdfs.length; j++) {
if (pdfs[j].contains(".pdf")) {
try {
// build the path to the pdf
achFile = sub.getPath() + "\\" + pdfs[j];
// fills in relevant fields in the pdf
if (PDFFill.fillPDF(achFile, student, user, context)) {
String pdfName = student.getName() + "-" + achFile.substring(achFile.lastIndexOf("\\") + 1);
String tempFileName = Protocol.ACHIEVEMENT_PATH + "/" + pdfName;
out.print("<a id='exportAchievement' style='display:none' href='" + tempFileName + "' download='" + pdfName + "'></a>");
out.print("<script>document.getElementById(\"exportAchievement\").click();</script>");
} else {
this.printWithNoty("Could not print PDF. " + achievement, "warning");
}
} catch (NullPointerException n) {
System.out.println(n.getMessage());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
It's because you are using a single id for all of the elements. IDs are unique. If you're using the same ID for everything, there's no way to discern between them and therefore you cannot expect multiple results.
<a id='exportAchievement' ...>
You can make that ID unique for each element and then it should work.

JQuery click event firing multiple times

I know that there's lot here on already on multiple click events being fired off, I think I've read them all but still can't see what's going wrong here.
Hope fully I'm missing something obvious that someone else can pick up easily...
Some background
My code works inside an Enterprise Social Networking platform and creates a BI dashboard for content analysis (about a 1000 lines of the stuff, mostly domain specific, so too much to post in it's entirety).
The part that is causing me grief is the function that builds the dashboard visualisation itself.
Here goes...
function makePage(){
$("#policyCount").text(policyCount);
var docTypes=getGlobalDocTypes(polOwners); //returns a constrained vocab array
var statusTypes=getGlobalStatusTypes(polOwners); //returns a constrained vocab array
$.each(polOwners,function(){ // polOwners is a global array that contains the BI data to be visualised
html=""
var ownerName = this.name.split(":")[1]; // name is a str in format "Owner:HR"
html += "<div id='" + ownerName + "' class='ownerData'>";
html += "<div class='ownerHeading'>" + ownerName + "</div>";
html += this.policies.length + " Policy documents maintained<br />"; // policies is an array of docs managed by owner
divIDReview = "dboard_" + ownerName + "reviewchart";
html += "<div id='" + divIDReview + "' class='dboardelement'></div>";
divIDType = "dboard_" + ownerName + "typechart";
html += "<div id='" + divIDType + "' class='dboardelement'></div>";
divIDStatus = "dboard_" + ownerName + "statuschart";
html += "<div id='" + divIDStatus + "' class='dboardelement'></div>";
html += "<div id='" + ownerName + "ToggleTable' class='toggletable' owner='" + ownerName + "'>";
html += "Click to display all " + ownerName + " documents<br /></div>";
html += "<div id='" + ownerName + "polTable' class='poltable'>";
html += getPolTable(this.policies); // Returns an HTML table of doc metadata
html += "</div>";
html += "</div>";
  $("#owners").append(html); // When this function is called #owners is an empty div
$(".toggletable").mouseover(function(){
$(this).css({'cursor':'pointer','text-decoration':'underline'});
});
$(".toggletable").mouseout(function(){
$(this).css( {'cursor':'default','text-decoration':'none'});
});
$(".toggletable").each(function(i, elem){
$(elem).click(function(){
if ($(this).next(".poltable").css("display")=="none"){
// Currently hidden - so show
if (debug){console.log($(this).attr("id") + " was clicked")}
$(this).html("Click to hide " + $(this).attr('owner') + " documents<br/>");
$(this).next(".poltable").css("display","block");
} else {
if (debug){console.log($(this).attr("id") + " was clicked")}
$(this).html("Click to display all " + $(this).attr('owner') + " documents<br />");
$(this).next(".poltable").css("display","none");
}
});
});
// the next section calls functions that use the Google vis api to draw pie charts
drawPie(300,200, "Review Status", "Status", "Policies", getReviewStatus(this.policies), ["green","orange","red"], divIDReview);
drawPie(300,200, "Document Types", "Type", "Docs", getDocTypes(this.policies, docTypes), [], divIDType);
drawPie(300,200, "Document Status", "Status", "Docs", getStatusTypes(this.policies, statusTypes), [], divIDStatus);
});
}
Hopefully that's enough to illustrate the problem.
You'll see that the code builds a dashboard display for each polOwner consisting of three pie charts and an option to hide or display a table of underlying data.
I started by applying the click event to the .toggletable class. When that fired multiple times I used the method described on another answer here with the .each to attach a unique event to each instance of the class.
So, what happens?
There are currently 9 polOwners and at first glance, the click event only seems to be toggling the display state of every other table. The console log however shows that this is because it is firing 9 times for the first instance, 8 for the second, 7 for the third etc. with the odd numbers leaving the table in the alternate state (when this works the display will change to a .toggle animation).
For info, While I'm a text editor person, I do have a copy of MS Expression Web 4 which is a useful tool for error checking HTML. I've pasted in a copy of the entire generated markup (nearly 4000 lines) and can't see any bad nesting or structure errors.
Any ideas folks?
You've got some nested loops:
// jQuery each on polOwners
$.each(polOwners,function(){
// ... code that appends .toggletable class
// jQuery each on .toggletable class
$(".toggletable").each(function(i, elem){
// code that runs on the toggletable element
});
});
For each polOwner you are adding a div with the toggletable class. Then inside there you are looping through each div with a toggletable class and adding a click event.
This adds 1 click for the first polOwner, 2 for the second, three for the third and so on.
Move the toggletable each outside of the polOwner each and you should be good

Yelp API display only one ID using jQuery

Problem
I am trying to display the reviews of a Restaurant using Yelps API. I copied Smashing Magazines version of implementing API from their jQuery ebook. The problem is that using this method there are two stores being queried because the previous owners had the same phone number. Yelp can use phone numbers to query reviews and ratings. I need only the currently open store's reviews to display. I want to do it by some how showing Yelp's node elemnt ID. Each store has a unique identifier according to Yelps API and uses node element ID. The ID of the store i want to solely display is ID="Y6D43boKItksYx_d-RQL4g"
The Code Looks Like:
function showData(data) {
$.each(data.businesses, function(i,business){
// extra loop
var bizContent = '<p><img src="' + business.rating_img_url + '" img=""/><br>'+ business.review_count + ' reviews from Yelp.com</p>';
$(bizContent).appendTo('#yelpAVG');
$.each(business.reviews, function(i,review){
var content = '<div class="comments-block"><p>Posted by ' +review.user_name + ' on ' + review.date + 'via Yelp.com';
content += '<img src="' + review.user_photo_url + '" img=""/>';
content += '<p><img src="' + review.rating_img_url + '" img=""/><br>';
content += review.text_excerpt + '</p>';
content += '<p>Read the full review<br>';
$(content).appendTo('#yelpReviews');
});
});
}
function writeScriptTag(path) {
var yelpScript=document.createElement('script');
yelpScript.type='text/javascript';
yelpScript.src=path;
$("body").append(yelpScript);
}
$(document).ready(function(){
// note the use of the "callback" parameter
writeScriptTag( "http://api.yelp.com/phone_search?"+
"&categories.name=cafe"+
"&phone="+"(408) 292-2070"+
"&ywsid=Iua-78eDnxy0DTqm8I4mDw"+
"&limit=1"+
"&callback=showData");
});
Im a little new to jQuery so I wouldn't know where to begin or what I should start with to display queried results that only have
`ID="Y6D43boKItksYx_d-RQL4g"`
ShowOnly="id":"Y6D43boKItksYx_d-RQL4g" or something similar.
Thanks For Reading.
You can't with API vsersion 1.
but
With APIv2 you can query a specific business by id:
http://www.yelp.com/developers/documentation/v2/business
Some sample code to help you get started is available on github:
https://github.com/Yelp/yelp-api/blob/master/v2/js/business.html

Categories

Resources