Add Google trust badge to Magento2 - javascript

I am struggling with google badge. i added: java script to footer Miscellaneous HTML. made the following changes in red.
<!-- BEGIN: Google Trusted Stores -->
<script type="text/javascript">
var gts = gts || [];
gts.push(["id", "XXXXXXX"]);
gts.push(["badge_position", "BOTTOM_RIGHT"]);
gts.push(["locale", "en_US"]);
(function() {
var gts = document.createElement("script");
gts.type = "text/javascript";
gts.async = true;
gts.src = "https://www.googlecommerce.com/trustedstores/api/js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(gts, s);
})();
</script>
<!-- END: Google Trusted Stores -->
..............................................................
the second part: what is the path to my to my success page in magento 2.1?
google requires some information, wwhat is the best way to obtain this, are these my attribute listed in my magento?
<!-- START Google Trusted Stores Order -->
<div id="gts-order" style="display:none;" translate="no">
<!-- start order and merchant information -->
<span id="gts-o-id">MERCHANT_ORDER_ID</span>
<span id="gts-o-email">CUSTOMER_EMAIL</span>
<span id="gts-o-country">CUSTOMER_COUNTRY</span>
<span id="gts-o-currency">CURRENCY</span>
<span id="gts-o-total">ORDER_TOTAL</span>
<span id="gts-o-discounts">ORDER_DISCOUNTS</span>
<span id="gts-o-shipping-total">ORDER_SHIPPING</span>
<span id="gts-o-tax-total">ORDER_TAX</span>
<span id="gts-o-est-ship-date">ORDER_EST_SHIP_DATE</span>
<span id="gts-o-est-delivery-date">ORDER_EST_DELIVERY_DATE</span>
<span id="gts-o-has-preorder">HAS_BACKORDER_PREORDER</span>
<span id="gts-o-has-digital">HAS_DIGITAL_GOODS</span>
<!-- end order and merchant information -->
<!-- start repeated item specific information -->
<!-- item example: this area repeated for each item in the order -->
<span class="gts-item">
<span class="gts-i-name">ITEM_NAME</span>
<span class="gts-i-price">ITEM_PRICE</span>
<span class="gts-i-quantity">ITEM_QUANTITY</span>
<span class="gts-i-prodsearch-id">ITEM_GOOGLE_SHOPPING_ID</span>
<span class="gts-i-prodsearch-store-id">ITEM_GOOGLE_SHOPPING_ACCOUNT_ID</span>
</span>
<!-- end item 1 example -->
<!-- end repeated item specific information -->
</div>
<!-- END Google Trusted Stores Order -->
Thank you

Related

Change html element's href using javascript

Details:
Hi experts. I want to change an existing HTML theme using only javascript, and I have problem in changing HTML element's href using javascript. But it seems I can't even get the elements by ClassName because the console.log value of javascript code below shows 0 length. Please help how should I fix the code.
(Note that I can't edit the existing HTML code, only can write custom code of javascript). Best regards
My javascript is as below:
var x8 = document.getElementsByClassName("slrofrpg-srvcs-backbtn");
console.log("length=",x8.length); --1st console
if (x8.length > 0){
console.log("ENTERED. length=", x8.length); --2nd console
x8[0].href = "javascript:history.back()";
}
My HTML is as below (some part of it):
<div class="slrofrpg-service-btn">
<a class="slrofrpg-srvcs-backbtn" href="javascript:void(0);">Back
</a>
<!-- react-text: 219 -->
<!-- /react-text -->
<a class="slrofrpg-srvcs-offerbtn" href="javascript:void(0);">Send now
</a>
</div>
1st console log result:
length=0
2nd console log result: No result
The code is working fine here. Your script is running before the the loading of html.You can
Move your <script> tag at end of the <body>
Or use the window.onload event
window.onload = function(){
var x8 = document.getElementsByClassName("slrofrpg-srvcs-backbtn");
console.log("length=",x8.length);
if (x8.length > 0){
console.log("ENTERED. length=", x8.length);
x8[0].href = "javascript:history.back()";
}
}
<div class="slrofrpg-service-btn">
<a class="slrofrpg-srvcs-backbtn" href="javascript:void(0);">Back
</a>
<!-- react-text: 219 -->
<!-- /react-text -->
<a class="slrofrpg-srvcs-offerbtn" href="javascript:void(0);">Send now
</a>
</div>
It seems you are running the javascript before the dom is loaded. Add javascript or add the external js file near the closing end of body tag
<body>
// html code
<script>
//js code here
</script>
</body>
var x8 = document.getElementsByClassName("slrofrpg-srvcs-backbtn");
console.log("length=", x8.length);
if (x8.length > 0) {
console.log("ENTERED. length=", x8.length);
x8[0].href = "javascript:history.back()";
}
<div class="slrofrpg-service-btn">
<a class="slrofrpg-srvcs-backbtn" href="javascript:void(0);">Back
</a>
<!-- react-text: 219 -->
<!-- /react-text -->
<a class="slrofrpg-srvcs-offerbtn" href="javascript:void(0);">Send now
</a>
</div>

Knockout JS - tabs in usercontrol not formatting

I've drilled down so I'm pretty sure I know the right question to ask - let's see how I've done.
I have a single-page app using Knockout 3.4.0. A main page, with a number of attached user controls. I have a tab set defined on the main page, and it works fine:
<div class="newportal documentsView" id="documentsView">
<div class="tabs">
<ul data-bind="foreach: tabs">
<li><a data-bind="attr: { href: '#tab-' + name }, css: { selected: $root.currentTab() == $data }, click: $root.updateTab, text: name"></a></li>
</ul>
<!-- ko foreach: tabs -->
<div class="area" data-bind="attr: { id: 'tab-' + name }, template: { name: template, data: $data.model().viewModel }">
</div>
<!-- /ko -->
</div>
</div>
I have a second set of tabs defined on one of the controls that houses the contents for one of those top tabs. The code's all but identical to the top one, save for referring to different data:
EDIT - duplicate IDs and tag names altered at suggestion of commenter - no change to format or functionality.
<div class="newportal documentsView" id="bulkDocumentsView">
Welcome to Bulk Documents
<div class="tabs">
<ul data-bind="foreach: bulktabs">
<li><a data-bind="attr: { href: '#bulktab-' + name }, css: { selected: $root.currentBulkTab() == $data }, click: $root.updateBulkTab, text: name"></a>
<!-- ko if: $root.currentBulkTab() == $data -->
(*)
<!-- /ko -->
</li>
</ul>
<!-- ko foreach: bulktabs -->
<!-- ko if: $root.currentBulkTab() == $data -->
<div class="area" data-bind="attr: { id: 'bulktab-' + name }, template: { name: template, data: $data.model().viewModel }">
</div>
<!-- /ko -->
<!-- /ko -->
</div>
</div>
</div>
The "$root.currentBulkTab" ko conditionals are in there so I can confirm that the links are correctly holding the correct selected tag and "highlighting" correctly - they do, and are.
However, the final page is only formatting the top set as tabs, the second set are displaying as an unformatted UI set:
The functionality is right - showing correct selected page, etc. If i don't have the second ko conditional around the template section, it displays all three, another thing that I believe should clear once the tab formatting applies properly.
The css file being used is jquery-ui-1.10.3.custom.css - I can comment the file out and the top tabset mimics the behavior of the second one.
There's clearly some additional link or tag I need to hit to get the data on the sub-page to format properly, but I don't know what it is. Can you only have one tabset per page, and it needs to be some sort of "sub tabset" of which I'm unaware?
I'm assuming the styles should cascade through (The word "cascade" is part of their title) but do they somehow function differently?
Thoughts?
Yes, jQuery UI allows nested tabs. My guess is you are calling the jquery UI .tabs() command on a selected limited to the outer/top tab set only.
Here, I'm calling it on the class selector:
$(".tabs").tabs();
I've removed all external CSS and hard-coded the HTML since your <ul>s and <li>s are showing, since I don't think this is a Knockout issue. You can see the nested tabs and that they are clickable and hide non-selected content.
$(".tabs").tabs();
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div>
<div class="tabs">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div id="tab-1">
<div>
1 - Top level tab content
<div class="tabs">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div id="bulktab-1">
1 - Second level tab content
</div>
<div id="bulktab-2">
2 - Second level tab content
</div>
<div id="bulktab-3">
3 - Second level tab content
</div>
</div>
</div>
</div>
<div id="tab-2">
<div>
2 - Top level tab content
</div>
</div>
<div id="tab-3">
<div>
3 - Top level tab content
</div>
</div>
</div>
</div>
I didn't scroll out enough, and if I had, you'd all have probably seen the problem.
The second snippet above is (was) contained within a conditional that checks that the dropdown has a selected value.
<!-- ko if: selectedSupplier() -->
<div class="newportal relative">
<div class="newportal documentsView" id="bulkDocumentsView">
Welcome to Bulk Documents
<div class="tabs">
<ul data-bind="foreach: bulktabs">
<li><a data-bind="attr: { href: '#bulktab-' + name }, css: { selected: $root.currentBulkTab() == $data }, click: $root.updateBulkTab, text: name"></a>
<!-- ko if: $root.currentBulkTab() == $data -->
(*)
<!-- /ko -->
</li>
</ul>
<!-- ko foreach: bulktabs -->
<!-- ko if: $root.currentBulkTab() == $data -->
<div class="area" data-bind="attr: { id: 'bulktab-' + name }, template: { name: template, data: $data.model().viewModel }">
</div>
<!-- /ko -->
<!-- /ko -->
</div>
</div>
</div>
<!-- /ko -->
It would appear to me that being within such a conditional blocks the stylesheet from properly seeing the code - I'm probably not saying that properly.
I move the conditional to only block the template underneath (and removing my test conditionals):
<div class="newportal relative">
<div class="newportal documentsView" id="bulkDocumentsView">
Welcome to Bulk Documents
<div class="tabs">
<ul data-bind="foreach: bulktabs">
<li><a data-bind="attr: { href: '#bulktab-' + name }, css: { selected: $root.currentBulkTab() == $data }, click: $root.updateBulkTab, text: name"></a>
</li>
</ul>
<!-- ko if: selectedSupplier() -->
<!-- ko foreach: bulktabs -->
<div class="area" data-bind="attr: { id: 'bulktab-' + name }, template: { name: template, data: $data.model().viewModel }">
</div>
<!-- /ko -->
<!-- /ko -->
</div>
</div>
</div>
And bingo.
Now that means it's going to be smarter for me to put a separate dropdown on each sub-page, but that'll solve a problem I was having on how to pass the selected values down to it anyway, so, you know, two birds.
98% finding the problem, and 2% fixing it.

How do I dynamically show more bootstrap tabs in a _Layout template?

I have an existing site using MVC and a _Layout page using a sectional control for the render. We are using bootstrap tabs throughout for data displays.
I have simplified this setup, but there are other VMs binding to this page, so I can't bind to the whole page, which would be the easy route for what I need.
I want to have a dynamic amount of tabs being rendered like:
<div class="panel panel-default">
<div id="tabContentParent" class="tab-content">
<div class="tab-pane active" id="result">
<!-- various details of a report -->
</div>
<!-- ko foreach: myVM -->
<div class="tab-pane" data-bind="attr: {'id': reportId}">
<!-- various bindings for reports -->
</div>
<!-- /ko -->
</div>
</div>
#section scripts
{
#Scripts.Render("~/Areas/Results/VMs/myVM.js")
<script type="text/javascript">
app.myVM.load();
ko.applyBindings(app.myVM, document.getElementById('tabContentParent'));
</script>
}
How can I get the tabs to also reproduce like this when they are in a separate sectional control and not within the same data-binding area?
#section controls
{
<ul class="nav nav-tabs section-controls">
<li class="active">Details</li>
<li class="hidden" id="tab1">Report 1</li>
<li class="hidden" id="tab2">Report 1</li>
<!-- etc., etc. -->
</ul>
}
I am not sure if this is the best way to do it, or if this is the best way to use knockout... but I think I have figured out how to do this. I have bound the ViewModel to multiple sections in separate applyBindings calls. I haven't seen this as a solution or suggestion before so I am not sure if there are side-effects.
A fiddle: Knockout multi-binding showing the functioning solution I propose. I defined the nav tabs like so:
<div>
<ul class="nav nav-tabs section-controls" id="vm1Id2">
<li class="active">Details</li>
<!-- ko foreach: tabInfos -->
<li>
<a data-bind="text: text, attr:{ href: '#' + url }" data-toggle="tab"></a>
</li>
<!-- /ko -->
</ul>
</div>
I defined the tab context like so (and a vm/div as a separator):
<div id="vm2Id">
<p>
<label data-bind="text: message"></label>
</p>
</div>
<div class="panel panel-default">
<div id="vm1Id1" class="tab-content">
<div class="tab-pane active" id="result">
<label>Some data displayed here</label>
</div>
<!-- ko foreach: newTabs -->
<div class="tab-pane" data-bind="attr: {'id': $data}">
<label data-bind="text: $data"></label>
</div>
<!-- /ko -->
</div>
</div>
And finally, I bound everything a little double time.
var ViewModel1 = function() {
var newTabs = ko.observableArray(["report1", "report2"]);
var tabInfos = ko.observableArray([{text: "Report 1", url: "report1"}, {text: "Report 2", url: "report2"}]);
return {
newTabs: newTabs,
tabInfos: tabInfos
};
};
var ViewModel2 = function() {
var message = ko.observable("This is a message as a space holder");
return {
message: message
};
};
var vm1 = new ViewModel1();
var vm2 = new ViewModel2();
ko.applyBindings(vm1, document.getElementById('vm1Id1'));
ko.applyBindings(vm1, document.getElementById('vm1Id2'));
ko.applyBindings(vm2, document.getElementById('vm2Id'));
I think this is the correct way to approach this. It works well enough when the page renders.

Google Custom Search - don't want trunated title

I am trying to do a simple Google Search where I just get back the titles linked to the pages. I have bought the business search and I have everything working (see code below) - I just want to get the full title of the page, not the truncated title. Can anyone help me?
In my head I have:
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// Load the Search API
google.load('search', '1');
// Set a callback to load the Custom Search Element when you page loads
google.setOnLoadCallback(
function(){
var customSearchControl = new google.search.CustomSearchControl('011927268382499158334:cuvurabmo-o');
// Use "mysite_" as a unique ID to override the default rendering.
google.search.Csedr.addOverride("mysite_");
// Draw the Custom Search Control in the div named "CSE"
customSearchControl.draw('cse');
},
true);
</script>
In the body I have:
<div style="display:none">
<!-- Return the unescaped result URL.-->
<div id="mysite_webResult" >
<div class="gs-webResult gs-result"
data-vars="{longUrl:function() {
var i = unescapedUrl.indexOf(visibleUrl);
return i < 1 ? visibleUrl : unescapedUrl.substring(i);}}">
<!-- Build the result data structure.-->
<table width="50%" cellpadding="0" cellspacing="0" >
<tr>
<td valign="top">
<!-- Append results within the table cell.-->
<div class="gs-title">
<a class="gs-title" style="color:#990000;font-family:'Times New Roman',serif;font-size:8.0pt;font-decoration:underline;" data-attr="{href:unescapedUrl,target:target}"
data-body="html(title)"></a>
</div>
<!-- Render results.-->
<div data-if="Vars.richSnippet && Vars.richSnippet.action" class="gs-actions"
data-body="render('action',richSnippet,{url:unescapedUrl,target:target})"></div>
</td>
</tr>
</table>
</div>
</div>
<!-- Div container for the searcher.-->
<div id="cse"></div>

Knockout view not removing item from view after delete

I have this code that successfully deletes an exam from a list of exams displayed on a page, but the page still shows the deleted exam. You have to manually refresh the page for the view to update. We are using a simlar pattern on other pages and it's working correctly. I don't understand why it doesn't work on this page.
// Used to handle the click event for Delete
remove = (exam: Models.Exam) => {
$("#loadingScreen").css("display", "block");
var examService = new Services.ExamService();
examService.remove(exam.examId()).then(() => {
examService.getByFid().then((examinations: Array<Models.Exam>) => {
this.exams(examinations);
this.template("mainTemplate");
});
}).fail((error: any) => {
// Add this error to errors
this.errors([error]);
window.scrollTo(0, 0);
}).fin(() => {
$("#loadingScreen").css("display", "none");
});
}
Here's the UI code that displays the list of exams
<div class="section module">
<!-- ko if: exams().length > 0 -->
<!-- ko foreach: exams.sort(function(a,b){return a.mostRecentDateTaken() > b.mostRecentDateTaken() ? 1:-1}) -->
<div class="addremove_section bubbled">
<a class="button open_review" data-bind="click: $root.edit">Edit</a>
<a class="button open_review" data-bind="click: $root.remove">Delete</a>
<div class="titleblock">
<h4 data-bind="text: 'Exam Name: ' + examTypeLookup().examTypeName()"></h4>
<div data-bind="if:examEntityLookup()!=null">
<div data-bind=" text: 'Reporting Entity: ' + examEntityLookup().description()"></div>
</div>
<div data-bind="text: 'Most recent date taken: ' + $root.formatDate(mostRecentDateTaken())"></div>
<div data-bind="text: 'Number of attempts: ' + numberOfAttempts()"></div>
<div data-bind="text: 'Pass/Fail Status: ' + $root.PassFailEnum(passFailId())"></div>
</div>
<div class="clearfix"></div>
</div>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: exams().length == 0 -->
<div class="addremove_section bubbled">
<div class="titleblock">
<div>No Exams Have Been Entered.</div>
</div>
</div>
<!-- /ko -->
</div>
EDIT: I discovered that if I remove the sort from this line in the view
<!-- ko foreach: exams.sort(function(a,b){return a.mostRecentDateTaken() > b.mostRecentDateTaken() ? 1:-1}) -->
to
<!-- ko foreach: exams -->
it works! The only problem is that I need the data sorted.
I removed the sorting from the view and did the sorting in the service. Not really sure why I can't sort in the view. I assume it's a knockout.js bug.
<!-- ko foreach: exams -->
[HttpGet]
[Route("api/exam")]
public IEnumerable<TDto> GetApplicantExams()
{
var dtos = GetCollection(() => _examService.GetApplicantExams(UserContext.Fid).OrderBy(e => e.DateTaken));
return dtos.ForEach(t => AddItems(t));
}
It's not a bug in Knockout. Since the sort invocation (as you're doing it) is not under the control of a computed/dependent observable, there's nothing to trigger it to resort. You've basically broken the connection between the UI (or more technically, the bindingHandler) and the ko.observable which KO uses for tracking changes.
I've run into this many times where I work, and the general pattern I use is something like this:
var viewmodel = {
listOfObjects:ko.observableArray(),
deleteFromList:deleteFromList,
addToList:addToList,
}
//in your HTML, you'll do a foreach: listOfSortedObjects (instead of listOfObjects)
viewmodel.listOfSortedObjects = ko.computed(function(){
//Since this is *inside* the change tracking ecosystem, this sort will be called as you would expect
return viewmodel.listOfObjects().sort(yourSortingFunction);
});
//Since you cannot edit a (normal) computed, you need to do your work on the original array as below.
function deleteFromList(item){
viewmodel.listOfObjects.remove(item);//Changing this array will trigger the sorted computed to update, which will update your UI
}
function addToList(item){
viewmodel.listOfObjects.push(item);
}

Categories

Resources