Cannot show TrustPilot HTML when inserted with JavaScript (jQuery) - javascript

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

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)

How to hard code text which are coming from javascript messages

Our application is been internationalized and being changed to different languages. For that reason we have to hard code all the messages. How can we do that for messages in javascript ?
This is how we are doing in html messages.
<span th:text="#{listTable.deletedFromTable}">deleted</span>
How do we hard code for javascript messages.(update the table)
$('#TableUpdate-notification').html('<div class="alert"><p>Update the Table.</p></div>');
You will need to put the messages in the DOM from the start, but without displaying them. Put these texts in span tags each with a unique id and the th:text attribute -- you could add them at the end of your document:
<span id="alertUpdateTable" th:text="#{listTable.updateTable}"
style="display:none">Update the Table.</span>
This will ensure that your internationalisation module will do its magic also on this element, and the text will be translated, even though it is not displayed.
Then at the moment you want to use that alert, get that hidden text and inject it where you need it:
$('#TableUpdate-notification').html(
'<div class="alert"><p>' + $('#alertUpdateTable').html() + '</p></div>');
You asked for another variant of this, where you currently have:
$successSpan.html(tableItemCount + " item was deleted from the table.", 2000);
You would then add this content again as a non-displayed span with a placeholder for the count:
<span id="alertTableItemDeleted" th:text="#{listTable.itemDeleted}"
style="display:none">{1} item(s) were deleted from the table.</span>
You should make sure that your translations also use the placeholder.
Then use it as follows, replacing the placeholder at run-time:
$successSpan.html($('#alertTableItemDeleted').html().replace('{1}', tableItemCount));
You could make a function to deal with the replacement of such placeholders:
function getMsg(id) {
var txt = $('#' + id).html();
for (var i = 1; i < arguments.length; i++) {
txt = txt.replace('{' + i + '}', arguments[i]);
}
return txt;
}
And then the two examples would be written as follows:
$('#TableUpdate-notification').html(
'<div class="alert"><p>' + getMsg('alertUpdateTable') + '</p></div>');
$successSpan.html(getMsg('alertTableItemDeleted', tableItemCount));

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

jquery: "Exception thrown and not caught" in IE8, but works in other browsers

My code works fine in other browsers, but in IE8 I get "error on page" - and when I click that it says:
"Exception thrown and not caught Line: 16 Char: 15120 Code: 0
URI: http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"
I tried linking to jquery.js (rather than jquery.min.js) and to 1.5.1/jquery.min.js,
but problem still remains.
Can someone correct/improve my code for me, or guide me as to where to look. Thanks
<script type="text/javascript">
function fbFetch()
{
var token = "<<tag_removed>>&expires_in=0";
//Set Url of JSON data from the facebook graph api. make sure callback is set with a '?' to overcome the cross domain problems with JSON
var url = "https://graph.facebook.com/<<ID_REMOVED>>?&callback=?&access_token=" + token;
//Use jQuery getJSON method to fetch the data from the url and then create our unordered list with the relevant data.
$.getJSON(url, function(json)
{
json.data = json.data.reverse(); // need to reverse it as FB outputs it as earliest last!
var html = "<div class='facebook'>";
//loop through and within data array's retrieve the message variable.
$.each(json.data, function(i, fb)
{
html += "<div class='n' >" + fb.name;
html += "<div class='t'>" + (dateFormat(fb.start_time, "ddd, mmm dS, yyyy")) + " at " + (dateFormat(fb.start_time, "h:MMtt")) + "</div >";
html += "<div class='l'>" + fb.location + "</div >";
html += '<div class="i"><a target="_blank" title="opens in NEW window" href="https://www.facebook.com/pages/<<id_removed>>#!/event.php?eid=' + fb.id + '" >more info...</a></div>';
html += "</div >";
}
);
html += "</div>";
//A little animation once fetched
$('.facebookfeed').animate({opacity: 0}, 500, function(){
$('.facebookfeed').html(html);
});
$('.facebookfeed').animate({opacity: 1}, 500);
});
};
Does the code do the job in IE8 or does it break? The reason I ask is because if it works as expected you could just wrap it in a try{ } catch{ \\do nothing } block and put it down to another thing IE is rubbish at.
You may be better off creating an object for the creation of the facebook div. Something like...
var html = $('<div />');
html.attr('class', 'facebook');
Then in your each loop you can do this...
$('<div />').attr('class', 'n').append(fb.name).appendTo(html);
$('<div />').attr('class', 't').append etc...
Then append html to the facebookfeed object
Doing this may remove the scope for error when using single quotes and double quotes when joining strings together, which in turn may solve your issue in IE8
$('.facebookfeed').fadeOut(500, function(){
$(this).append(html).fadeIn(500);
});
Hope this helps!
UPDATE
The append method is used to add stuff to a jquery object. For more info see here
So to surround the div's as you mentioned in the comments you would do something like this...
var nDiv = $('<div />').attr('class', 'n').append(fb.name);
$('<div />').attr('class', 't').append(fb.somethingElse).appendTo(nDiv);
// etc
And then you would need to append that to the html div like so...
html.append(nDiv);
So that would give you
<div class="facebook">
<div class="n">
value of fb.name
<div class="t">
value of fb.somethingElse
</div>
</div>
</div>
So what you have done is created a new jquery object and appended to that, then appended that to the html object which you have then appended to the facebookfeed div. Confusing huh?!

Categories

Resources