Squarespace - How to display description/custom text on index thumbnail on hover - javascript

Basically, I want to be able to show title and some text on hover on all my index thumbnail like this website.
http://www.timboelaars.nl/
However, in the current squarespace template that I am using (I believe it's called York), the markup is only grabbing the page title and therefore displaying the page title on hover. (See the below code block, you can see the page title in there, that's the only thing that the template displays on Hover)
<div class="index-item-text-wrapper">
<h2 class="index-item-title">
<a class="index-item-title-link" href="/google-shopping/" data-ajax-loader="ajax-loader-binded"><span class="index-item-title-text">**PAGE TITLE**</span></a>
</h2>
</div>
There's no field for me to put any HTML so I am seeking help to use javascript to manually inject custom HTML markup to every single thumbnail, then show them on hover.
TL;DR I want to be able to display more than just the title on hover (ideally my own HTML markup so I can customize the style) on my thumbnails but that's not supported by the template.
Here is my website http://shensamuel.com/
I am really weak at Javascript and I've searched for a solution for this problem for quite long. Any help will be much appreciated!
Thanks!

The following Javascript can be used to insert text for each tile on the page. The code would be inserted using the footer code injection area (unless you're using Developer Mode in which case you'd insert it with the rest of your scripts).
<script>
(function() {
var tiles = document.getElementsByClassName('index-section');
var thisTile;
var titleText;
var description;
var parent;
var i, I;
for (i=0, I=tiles.length; i<I; i++) {
thisTile = tiles[i];
titleText = thisTile.getElementsByClassName('index-item-title-text')[0];
parent = thisTile.getElementsByClassName('index-item-text-wrapper')[0];
description = document.createElement('span');
description.className = 'index-item-description-text';
switch(titleText.innerHTML.toLowerCase()) {
case "google shopping":
description.innerHTML = "Some custom text.";
break;
case "hana":
description.innerHTML = "More text that's custom.";
break;
case "wali":
description.innerHTML = "Custom text here.";
break;
case "cypress":
description.innerHTML = "Type anything you want.";
break;
case "ryde":
description.innerHTML = "Just another bit of text.";
break;
default:
description.innerHTML = "";
}
parent.appendChild(description);
}
})();
</script>
Observe the pattern in the code in order to add new tiles or edit existing ones. You will see that the script attempts to match (a lower case version of) the 'title' text and then inserts text based on each title. This allows you to add more in the future by repeating this 'case' pattern. Of course if you ever change the title of a tile you'd have to correspondingly change this Javascript code.
You can then style the description by inserting CSS via the Squarespace CSS Editor (or via your base.less file if using Developer Mode). For example:
.index-item-description-text {
display: block;
font-size: 1.2em;
color: #FFFFFF
}
Note that while there is an alternative method that would use each tile's respective URL to do an AJAX query and obtain meta data about each project (and therefore allow you to use the Squarespace content manager to insert this 'description'), that method seems unnecessarily complex for your case.
Update 8/17/2016: Regarding AJAX and how to disable AJAX loader in Squarespace: Jason Barone has suggested adding this snippet to your Code Injection > Footer to disable the "AJAX" pageloader. He noted that it will disable the smooth, AJAX transitions between pages, but will allow custom Javascript like usual.
<script>
//Credit: Jason Barone, http://jasonbarone.com/
window.Template.Constants.AJAXLOADER = false;
</script>
Also, some templates have an option to disable AJAX within the style editor (image credit: SSSUPERS):
Update 9/28/2016:
It has been reported that the code provided above no longer disable AJAX. However, some newer templates have added an 'Enable AJAX Loading' setting that can be toggled off.

Related

Get rendered html as text, including newlines

I have a page with some html rendered into it.
I want to get the rendered page as text, but somehow also include the newlines. In addition, if relevant, I'm looking for an extended solution that will also support lists (using spaces and •), tables (using spaces, but with no borders) and similar cases.
I'm looking for Javascript solution, either on client or server side.
Please mind: not every element in the page equals to new line (e.g: some divs can be inline and some can create new lines).
For exapmle, this snippet below will be the html, and the output will be the text itself as you can see below (after running).
#inline{
display:flex;
flex-direction:row;
}
#inline div{
margin-right:5px;
}
#notInline{
display:flex;
flex-direction:column;
}
<div>
<div id='inline'><div>some</div><div>divs</div><div>inline</div></div>
<div id='notInline'><div>some</div><div>divs</div><div>on top of each other</div>
You can try this. First inline text second "on top of each other" text:
var inlineOutput = '';
document.querySelector('#inline').childNodes.forEach(e=>{inlineOutput += e.textContent + ' '}) + "\n";
console.log(inlineOutput);
var noInLineOutput = '';
document.querySelector('#notInline').childNodes.forEach(e=>{noInLineOutput += e.textContent + " \n"});
console.log(noInLineOutput);
There's a js scraper called Cheerio that could extract all the text out for you, I've never used it though. It gives you access to the DOM and you can gather parts of whichever page you need. here's a tutorial that uses it with node.
Not sure if this is what you're looking for, if they're your own pages you can probably make a function that calls everything in the dom and delimits at the open close carats and grabs in the text inbetween, and maybe make a switch if it sees the notInLine class

Live editor that allows for editing of an iframe's HTML and CSS within a textarea (or similar.)

Okay, to preface, I am not an overly experience programmer. My area is predominantly in HTML and CSS, so I'm a little stuck here, and I've searched high and low online and can't find what I need; whether that's bad phrasing on my part or lack of information, I'm not sure, haha.
THE LIVE VERSION
HTML
<select ONCHANGE="document.getElementById('display-inner').src = this.options[this.selectedIndex].value">
<option value="http://tessisamess.com/freeedit.html">Free Edit</option>
<option value="http://tessisamess.com/completestyle.html">Complete Style</option>
<option value="http://tessisamess.com/generator.html">Generator</option>
JQUERY
$(function() {
function change() {
var iFrame = document.getElementById('display-inner');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
iFrameBody.innerHTML = document.getElementById('input-inner').value;
}
});
What I'm trying to accomplish:
I'm creating a live editor for the users that I generally create layouts for, and I've got Free Edit mode and the Save function all in working order. I've also got my two base layouts that are often restyled uploaded and displayed in iframes, and you can call either layout or Free Edit from a dropdown to display on the right, next to the editor.
The goal here is for you to be able to click any of the three modes, and then code on the left and see your updates effect what's already in the iframe to the right rather than clearing it and replacing it with your textarea content (which is what it currently does.)
What needs to function, and doesn't:
When you click Complete Style or Generator, the textarea (left) needs to display the base code that people use to style each layout. When you start editing that side, either by using the code generated for you, or replacing it with a premade layout edit, the changes effect the iframe it's connected to on the right. (example: Adding a background image to body will change the page background in the iframe, and so on.)
The purpose:
I'm using this as a tool to give the users who frequently use my free layouts on the site, who have trouble editing them using the site's very out of date resources. I'd like them to be able to throw in my custom CSS and edit it as they please so they can take it back to the site and implement it on their actual journals.
Note that I AM okay with having to change how this already functions if need be. I'd rather it work correctly than stick within what I already have. I'm not really looking to upload TinyMCE, but if options are slim then hey. Nothing for it, right?
$(function() {
function change() {
var iFrame = document.getElementById('display-inner');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
iFrameBody.innerHTML = document.getElementById('input-inner').value;
}
});
$(function() {
function saveTextAsFile()
{
var textToWrite = document.getElementById('input-inner').value;
var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
var fileNameToSaveAs = "mycode_tessisamess.txt";
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null)
{
// Chrome allows the link to be clicked
// without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
}
else
{
// Firefox requires the link to be added to the DOM
// before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
var button = document.getElementById('save');
button.addEventListener('click', saveTextAsFile);
});
#import url(https://fonts.googleapis.com/css?family=Open+Sans);
::selection{background:#EAA2B9;}
::-moz-selection{background:#EAA2B9;}
body,html{height:100%;}
body{margin:0;}
#input, #display{display:inline-block;height:100%;vertical-align:top;overflow:hidden;}
#input{position:relative;background:#ddd url(http://i.imgur.com/wBSwx5F.jpg)center no-repeat fixed;width:35%;-webkit-box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);}
#controls{font-family:Open Sans,Helvetica,arial,sans-serif;font-size:13px;text-align:right;height:24px;background:#fff;padding:7px;border-bottom:1px solid #ccc;-webkit-box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);box-shadow:inset -10px 0 10px -10px rgba(0,0,0,0.6);}
.c-button, select, option{background:#fff;cursor:pointer;border:1px solid rgba(0,0,0,0.3);border-radius:4px;padding:2px 10px;margin:0 2px;font-family:Open Sans,Helvetica,arial,sans-serif;}
#input-inner{position:absolute;bottom:4px;top:38px;width:97%;margin:0;background:transparent;border:none;padding:10px;color:#000;overflow:auto;}
input:focus, textarea:focus, select:focus, option:focus{outline:none;}
#display{width:65%;}
#display-inner{height:100%;overflow:auto;border:none;width:100%;}
#display-inner p{max-width:600px;display:block;margin:0 auto;padding:100px;text-align:justify;font-family:Open Sans,Helvetica,arial,sans-serif;line-height:150%;font-size:115%;color:#444;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<form id="input">
<div id="controls">Options:
<select ONCHANGE="document.getElementById('display-inner').src = this.options[this.selectedIndex].value">
<option value="http://tessisamess.com/freeedit.html">Free Edit</option>
<option value="http://tessisamess.com/completestyle.html">Complete Style</option>
<option value="http://tessisamess.com/generator.html">Generator</option>
</select>
<button type="button" value="save" id="save" class="c-button">save</button>
<input type="reset" class="c-button" value="clear">
</div>
<textarea id="input-inner" onkeyup="change();" placeholder="You are in Free Edit mode! You can paste your code here, or start coding from scratch.
To style a layout instead, select your base from the dropdown above, and start with the base CSS given to create a new layout, or replace it with the free layout coding you wish to edit.
All changes will appear on the righthand side as you make them."></textarea>
</form><!---
---><div id="display">
<iframe id="display-inner" src="http://tessisamess.com/freeedit.html">
</iframe>
</div>
</body>
This would be a very long answer if I were to cover all the aspects of what needs to happen for you to get it working the way you need it, so instead I'll give you some helpful hints.
You can get to the document of the iFrame from your main page with: document.getElementById('MY_IFRAME_ID').contentWindow.document
The Element.outerHTML and Element.innerHTML properties will be your best friend in retrieving and updating page code.
To display HTML, you can do: iframeDocument.getElementsByTagName('html')[0].outerHTML and that will contain the HTML for the entire page, including all the inline css/js. If you need the doctype also, read this. Insert all that into textarea.
To make updates you can grab the html from your textarea and insert it back with Element.innerHTML like so: iframeDocument.getElementsByTagName('html')[0].innerHTML = htmlFromTextarea
For the external css/js, you'll need a proper way to display the code, but I'll leave it to you to figure out the details of that.
To get the external css you just have to iterate over iframeDocument.styleSheets, and use a similar strategy as the one mentioned above, although there are some cross browser considerations you might want to keep in mind.
For external js, you can find them in a similar fashion. Iterate over iframeDocument.getElementsByTagName('script') and get their content with Element.innerHTML
You could implement strategies for updating just sections instead of the entire document each time, but that's a bit more involved. I recommend taking the "update entire document" route until you have a better understanding of the moving parts.
Syntax highlighting would be immensely helpful, so consider putting your code inside a code editor like "Ace".
I hope this helps and good luck! Please don't forget to check this answer as correct if you felt that it addresses your question.

changing cssRules with javascript is not permanent on client, getting wiped out after partial post back

I generated some css from database values on Page_Load and Then wrapped it like-
CssDiv.InnerHtml = "<style id=\"main_styles\" type=\"text/css\">\n" + {Css as string} + "\n</style>"
here CssDiv is like-
<div id="CssDiv" runat="server"></div>
user are allowed to change these css values with color pickers and drop downs. on change of picker or dropdown, I am making ajax call with the selected value to server, saving it into database. Now on success of this request, I have to change the content of $("style#main_styles") according to user's selection.
The problem is
1) When I am changing the Css its being reflected on the page but not under developer tool (that open when you right click to Inspect element). For example assume following css-
#zoneBody .blocktextContent {
background-color: #99daee;
}
now user selected #1066cc from the picker, when my code runs #1066cc is being applied on the element "#zoneBody .blocktextContent" on page but when I am inspecting the element in the developer console its still showing-
#zoneBody .blocktextContent {
background-color: #99daee; // while it should be- "background-color: #1066cc;"
}
2) The changes I made are not permanent on browser, i.e. when any other element on Page is causing partial post-back, although I am not touching CssDiv on server yet its resetting the users selection.
(I have an update panel, that wraps complete page content, even CssDiv... This is causing partial post-backs).
I am using following code to apply the user's selection-
var layoutelement= "#zoneBody .blocktextContent";
var style = "background-color";
var stylevalue= "#1066cc"; // user's selection
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
var sheet = sheets[i];
if (sheet.ownerNode.id == "main_styles") {
var rules = sheet.cssRules;
for (var j = 0; j < rules.length; j++) {
var rule = rules[j];
if (rule.selectorText == layoutelement) {
rule.style.setProperty(style, stylevalue);
// I also tried "rule.style[style] = stylevalue;"
break;
}
}
break;
}
}
I can not use-
$(layoutelement).css(style, stylevalue);
because layoutelement can be more complex like-
layoutelement = "#zoneBody .blockTextContent a,#zoneBody .blockTextContent a:link,#zoneBody .blockTextContent a:visited,#zoneBody .blockTextContent a .yshortcuts";
I hope I am clear enough, but if you need any more description.. let me know in comments.. Thank you
Instead of changing the values of the styles, why not write the styles down in advance, and just toggle the element's classes? You can use jQuery addClass, removeClass and toggleClass if you want. Much more practical than fiddling with the CSS style definitions themselves.
For problem 1, the issue is probably that the developer tool (or view within the developer tool) you are using does not show applied styles, but simply the rules in the style sheet that match that element based on the selector. Or, in other words, it only shows the css rules in the style sheet that apply to the element you are inspecting. To see the styles that are applied at a given time, you will need to examine the styles by inspecting the element in the DOM or use javascript and the CSSStyleDeclaration object returned by getComputedStyle.

WooCommerce double load

I have this Wordpress project and I am using WooCommerce Plug-in and WooCommerce Adamas Theme. I have the following problem:
I need to replace the word "Cart" from the top right menu with an icon of a cart as part of my project. What my theme does in its functions.php file is to create two a links to the Cart's contents PoP Up element. The first is the word "Cart" and the second is the cart product counter.
What I have tried is to add the following CSS properties by adding the class cmagnet-cart to the second, in order to include the cart icon.
.cmagnet-cart{
background: url('http://www.athlokinisi.gr/images/shopping-cart.png') no-repeat 10px 6px;
min-width: 45px;
text-align: right;
background-size: auto 17px;
}
I have added the class to the appropriate element at the functions.php cartShow() function where it is originally generated. As you can see, the problem is that when page loads, it shows the icon perfectly on position and then there is a javascript reload of some WooCommerce parameters and hides it again, by returning to its original values. Thus, without my added class.
After contacting the Adamas Theme Support team at PremiumCoding and after several tickets which took place for over 2 weeks, it was pointed out to me that I need to make an alteration at WooCommerce's JS function, perhaps the cart-fragment.js. The problem is that nothing makes sense to me in there and I really cannot find where to make the code alteration in order for the Javascript's second load to include my function or exclude this element from double loading. The Suport team there couldn't assist me further.
I would appreciate endlessly any help as well as an explanation of why this happens. It doesn't make any sense to me why to load some elements two times.
To add two additional information:
- I know that when I fix the issue I will just hide (probably by putting in comments) the first a link which prints the word "Cart"
- The last response I got from support was the following (in case it is of any help):
even if you replace text with icon after loading WooCommerce Ajax,
text will be back. So you will need to change WooCommerce js function
or translate all WooCommerce plugin and theme with WPML plugin and
string translation module.
Extended info:
In general it's not enough for me to just replace the first a link that says "Cart" with the cart's image, because it doesn't solve my bigger problem which includes the following: I am using Greek language for this project and the theme has many uppercase CSS elements. There are some problems with this because Greek words in uppercase cannot be automatically transformed because you have to remove the accents from the vowels. Therefore, I had made a jQuery functions which runs on document ready and corrects this problem, but due to the aforementioned problem of the double load it returns all text back to the previous state.
I solved it by adding this code:
//Uppercase correction for Greek language
String.prototype.replaceArray = function(find, replace){
var replaceString = this;
for (var i = 0; i < find.length; i++){
replaceString = replaceString.replace(find[i], replace[i]);
}
return replaceString;
};
var e = jQuery('a, h2, h3, button, li'), l = e.length, i;
if (typeof getComputedStyle == "undefined"){
getComputedStyle = function(e) {return e.currentStyle;};
}
for (i=0; i<l; i++){
if (getComputedStyle(e[i]).textTransform == "uppercase"){
var find = ['ά', 'έ', 'ί', 'ή', 'ύ', 'ό', 'ώ'];
var replace = ['α', 'ε', 'ι', 'η', 'υ', 'ο', 'ω'];
var replaceTo = e[i].innerHTML;
replaceTo = replaceTo.replaceArray(find, replace);
e[i].innerHTML = replaceTo;
}
}
//Uppercase correction for Greek language
into the file:
wp-content/plugins/woocommerce/assets/js/frontend/cart-fragments.min.js
This JS file was the one responsible for the double load of contents. It may not be the best solution, yet a working one.

How to link to highlighted text on another page

I have a static HTML page where I am using span tags and javascript to highlight selected portions of text. On a separate page, I would like to link back to this HTML page and have specified highlighting active. See provided code below.
The issue is the required style="background: transparent" tag. It has to be there so that the highlight is only active when clicked upon, but this also means that when I attempt to link to this page as specified below, the highlight is not active.
Any help would be much appreciated. Thanks.
Clicking this link highlights specified portions of text in the document.
<span title="Warscape"><a title="Warscape" onclick="highlightSpan(this.getAttribute('title'))" href="">Warscape</a></span>
This is the text that is highlighted when clicked.
<span title="Warscape" class="highlight" style="background: transparent">During this month while we have been building Fort No 1 Spring field Missouri, quite a No of Regiments have arrived from the north & now the Army of the Frontier [is?] formed</span>
Code to link to page with highlighting.
<a href="j_62sept.html?highlight=Warscape">
CSS re. highlighting
.highlight {background:#bcdbda;}
Javascript re. highlighting
function highlightSpan(spanTitle)
{
var spans = document.getElementsByTagName("span");
// take away color
for (var i = 0; i < spans.length; ++i)
{
spans[i].style.backgroundColor = "transparent";
}
// add color
for (var i = 0; i < spans.length; ++i)
{
if (spans[i].getAttribute('title') == spanTitle)
{
spans[i].style.backgroundColor = "#bcdbda";
}
}
}
I recognise that this is an old thread, but this problem can now be addressed for Chrome using the Scroll to Text Fragment feature described here:
https://chromestatus.com/feature/4733392803332096
In short, it allows you to provide a link which jumps to a specific string of text and (in Chrome's implementation) highlights that section. A basic version of the link would look like this:
https://en.wikipedia.org/wiki/Cat#:~:text=Felis%20catus
when your clicking the links to the page where the highlighting takes action (<a href="j_62sept.html?highlight=Warscape">
) you need to somehow read querystring value on that page to highlight the right span. You can use javascript for this. See this example: http://www.bloggingdeveloper.com/post/JavaScript-QueryString-ParseGet-QueryString-with-Client-Side-JavaScript.aspx
This is an interesting question. If you'd like to have the javascript pick up on parameters in the url, you can use the window.location.href parameter to pull it out. So, quite simply the following function:
function CheckForHighlight(){
href = window.location.href;
values = href.split('?')[1] // Remove the url
highlight = values.split('=')[1]; // Grab the second parmeter
highlightSpan(highlight); // Highlight it!
}
Please Note that this is a very basic example. I encourage learning through simplicity, and this function can be expanded to dynamically parse all url varaibles. Brain Exersise for you!

Categories

Resources