Jump to content

jpeter

Member
  • Posts

    182
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by jpeter

  1. @TBrungus You can use the following JS below, which is a slight modification to the JS from this comment

    Here's an example of me targeting the "Message" field that has an id of, textarea-yui_3_17_2_1_1695075633023_1845.

     

    JavaScript

    (function () {
    
      const DELAY = 500; // Delays code execution so other scripts can run
      const SLIDE_UP_SPEED = 200; // Speed in milleseconds
      const SLIDE_DOWN_SPEED = 200; // Speed in milleseconds
    
      setTimeout(() => {
    
        const field = new ToggleFields();
    
        field
          .id('checkbox-f3d6a653-ba34-430b-a76c-97c1f32c8a7e-field')
          .hasValues([
            'Other',
          ])
          .thenShow([
            'textarea-yui_3_17_2_1_1695075633023_1845'
          ]);
    
    
      }, DELAY);
    
    
      /*********************************************************************
       * DO NOT ALTER BELOW THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING
       *********************************************************************/
    
      class ToggleFields {
    
        constructor() {
          this.parentEl = null;
          this.parents = {};
          this.dependenciesFields = [];
          this.values = [];
          this.showFields = [];
          this.valueMapping = null;
        }
    
        id(id) {
          if (typeof id == 'string') {
    
            // Get the parent element 
            const parentFieldId = document.querySelector('[id="' + id + '"]');
            const parentFieldName = document.querySelector('[name="' + id + '"]');
            
            
            if (parentFieldId) { this.parentEl = parentFieldId.closest('.field'); }
            if (parentFieldName) { this.parentEl = parentFieldName.closest('.field'); }
            
            this.parentEl.valueMap = this.parentEl.valueMap || {};
            this.parents[this.parentEl.id || this.parentEl.name] = this.parentEl;
            
            if(!this.parentEl) {
              return this;
            }
            
          }
    
          return this;
        }
    
        hasValues(values) {
          if (!Array.isArray(values)) { return this; }
    
          this.values = values;
    
          if(this.parentEl) {
            values.forEach(value => {
              this.parentEl.valueMap[value] = this.parentEl.valueMap[value] ||  {
                fields: [],
                hidden: true
              };
            })
          }
    
          return this;
        }
    
        thenShow(fields) {
    
          if (!Array.isArray(fields)) { return this; }
          
          if(this.parentEl) {
            fields.forEach(field => {
              this.values.forEach(key => {
                this.parentEl.valueMap[key].fields.push(`#${field}`);
              });
            });
          }
    
          const fieldIds = fields.map(field => '#' + field);
          document.querySelectorAll(fieldIds.join(',')).forEach(el => {
            if(el.closest('.field')) {
              el.closest('.field').style.display = 'none';
            } else {
              el.style.display = 'none'
            }
          });
          
          this.onLoad(() => {
            // Load jQuery if not loaded
            if (!window.jQuery) { return this.loadJquery(this.thenShow(fields)) }
            
            this.showFields = fields;
    
            // Assign jQuery to a variable
            const $ = jQuery;
    
            Object.keys(this.parents).forEach(id => {
    
              const parentEl = this.parents[id];
              
              if (!parentEl || parentEl.toggleFieldInit) { return; }
              
              parentEl.toggleFieldInit = true;
              // Show or hide the dependent field based on the PARENT_VALUE
              $(parentEl).on('change', (evt) => {
    
                const value = evt.target.value;
                
                Object.keys(parentEl.valueMap).forEach(key => {
                  if(parentEl.valueMap[key].hidden == false) {
                    $(parentEl.valueMap[key].fields.join(',')).slideUp(SLIDE_UP_SPEED);
                    parentEl.valueMap[key].hidden = true;
                  } else {
                    $(parentEl.valueMap[value].fields.join(',')).slideDown(SLIDE_DOWN_SPEED);
                    parentEl.valueMap[key].hidden = false;
                  }
                })
              });
    
            });
          })
    
          return this;
        }
    
        loadJquery() {
          var s = document.createElement('script');
          s.src = 'https://code.jquery.com/jquery-3.6.0.min.js';
          s.onload = this.thenShow(this.fields);
          document.body.appendChild(s);
        }
    
        onLoad(callback) {
          // Initialize after the page has been loaded
          if (document.readyState === 'complete') {
            setTimeout(callback, DELAY)
          } else {
            document.addEventListener("DOMContentLoaded", function () {
              setTimeout(callback, DELAY);
            }, false);
          }
        }
    
      }
    
    })();

    Make sure to include the JS between <script> tags like so:

    <script>
      // Add JS here
    </script>

     

  2. @St Lukes 

    The issue is the <main> HTML element has a max-width: 1080px style applied to it. The following CSS below will break the banner outside of it's parent container, but still maintain it's place in the flow of the page:
     

    CSS

    /* Make the banner image the full width of the page */
    #block-yui_3_17_2_1_1705198057319_10582 {
        margin-left: calc(50% - 50vw);
        margin-right: calc(50% - 50vw);
    }
    
    /* Adjust the slide images to be the full width of the page */
    #block-yui_3_17_2_1_1705198057319_10582 .sqs-gallery-design-stacked-slide img {
        object-fit: cover;
        width: 100% !important;
    }
    

     

  3. @joshlee The issue is your code below is relying on jQuery. Instead of relying on jQuery as a dependency, you can replace the following code:

    $(document).ready(function() { 
      $('div#block-yui_3_17_2_1_1707375123858_6165').appendTo('.header-title-logo a');
    });

    With this code:

    (function(){
    
      const headerLogo = document.querySelector('.header-title-logo a');
      const lottiePlayer = document.querySelector('div#block-yui_3_17_2_1_1707375123858_6165 lottie-player');
    
      if(headerLogo && lottiePlayer) {
    
        // Hide existing image 
        const img = headerLogo.querySelector('img');
        if(img) {
          img.style.display = 'none';
        }
        
        // Append lottie image 
        headerLogo.appendChild(lottiePlayer);
      }
    
    })()

    Remember to place the JS code between <script></script> tags. 

  4. @StudioFine 

    Add the following JavaScript code to the Footer using Code Injection. Just update the LINKS array to whatever relative or absolute path(s) you'd like to add the query parameters to. 

    This script loop through all of the links on the page and add the query parameters from the URL to the links that are defined in the LINKS variable. 

    (function () {
    
      const LINKS = [
        '/some/relative/path',
        'https://www.example.com/donate'
      ];
    
      // Function to attach query parameters to a list of links
      function attachQueryParametersToLinks() {
        const selectors = LINKS.map(link => `a[href="${link}"]`);
        const links = document.querySelectorAll(selectors.join(','));
        const urlSearchParams = new URLSearchParams(window.location.search);
    
        // Iterate over the links and update their href attributes
        links.forEach(link => {
          const originalHref = link.getAttribute('href');
          const linkSearchParams = new URLSearchParams(link.search);
          const mergedSearchParams = new URLSearchParams([...urlSearchParams, ...linkSearchParams]);
          link.setAttribute('href', `${originalHref}?${mergedSearchParams.toString()}`);
        });
      }
    
      if (document.readyState == 'complete') {
        attachQueryParametersToLinks()
      } else {
        window.addEventListener('DOMContentLoaded', attachQueryParametersToLinks);
      }
    })()

    Be sure to place the javascript between <script> tags e.g.:

    <script>
      // Add JS here
    </script>

     

  5. @maya_m

    STEP 1: 
    Add the following JavaScript code to the Footer using Code Injection.  This script adds an "active" class on the link that matches whatever filter is defined in the URL. 

    (function () {
      // Get all the links inside the specified container
      const links = document.querySelectorAll("#block-yui_3_17_2_1_1706047640137_2381 a");
    
      // Loop through each link and check if its path matches the path in the URL
      links.forEach((link) => {
          // Add the "active" class if the pathname of in the URL matches 
          if (window.location.pathname === link.pathname) {
              link.classList.add("active");
          }
      });
    })();

    Be sure to add the JavaScript code above between <script> tags like so:

    <script>
      // Add JS here
    </script>

     

    Step 2:
    You can now style the class like so using the following CSS:

    /* Style active filter link */
    #block-yui_3_17_2_1_1706047640137_2381 .active {
        color: blue;
    }

     

  6. @Angelica_Cream You can add the JavaScript below to the Footer using Code Injection to change the text of the pagination label:

    JavaScript

    (function() {
    
     // Define constants for the desired text labels
     const NEXT_LABEL = 'More Work';
     const PREV_LABEL = 'Previous Work';
    
     // --- Pagination Label Updates ---
    
     // Get the pagination element from the page
     const pagination = document.querySelector('.blog-list-pagination');
    
     // Conditionally find the "prev" and "next" label elements within the pagination
     const prevLabel = pagination && pagination.querySelector('.prev-label');
     const nextLabel = pagination && pagination.querySelector('.next-label');
    
     // Update the text content of the labels if they exist
     if (nextLabel) {
       nextLabel.textContent = NEXT_LABEL;
     }
     if (prevLabel) {
       prevLabel.textContent = PREV_LABEL;
     }
    
    })();

    Be sure to place the code in between <script> tags like so:

    <script>
      // Add JS code here
    </script>

     

  7. 11 hours ago, GarySmith said:

    Sorry I can't get the events to show on the website configuration page even with different browsers/incognito/clearing cache. It is working on the public view yes. I meant when logged into the Squarespace account all the published events are removed from the page. If you look at screenshots above the code says display:none is being applied to all of them.

    @GarySmith My previous comment about me replicating the issue was me seeing the issue logged in on the configuration page. When I was trouble shooting, I noticed I was still getting old content while logged in. Perhaps you can follow the steps I took while troubleshooting in the Chrome browser to see if you get fresh content like I did:

    1. Clear Chromes storage. This article has an example of what I did.
    2. Once you've cleared the storage, close the entire Chrome application, including all open windows and tabs.
      1. Keyboard shortcut for Mac, Command (⌘) + Q
      2. Keyboard shortcut for Windows, Ctrl + Shift + Q
    3. Log back into site and check to see that fixed the caching issue

     

  8. If you're using this template then you can leverage the pointer-events: none css rule set to prevent the element from being clicked. Here's the CSS you would add using the CSS editor based on the templates ID and classes being used:

    /* Prevent item from being clicked */
    #mainNavigation .folder-toggle {
        pointer-events: none;
    }

     

  9. @TheSavvyChameleon @colin.irwin Here are some defaults that can be used and should fix the issue with inline CSS and JS as well by leveraging the 'unsafe-inline' and 'unsafe-eval' CSP directives. Also added blob: and data: directives to handle media related to blobs and data attributes.

    <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob: *.squarespace.com *.squarespace-cdn.com *.squarewebsites.com *.google.com *.google-analytics.com *.googleapis.com *.gstatic.com *.googletagmanager.com *.doubleclick.net *.typekit.net *.youtube.com *.jquery.com https://youtu.be">

     

    Tips On Figuring out which websites to allow with Content Security Policy:

    If you're setting up Content Security Policy (CSP) for your website but are unsure which websites to allow access to, here's a tip:

    • Open Google Chrome's developer tools: Click the three dots in the top right corner of your Chrome window, then select "More tools" and then "Developer tools".
    • Find the Console: Look for the tab labeled "Console" within the developer tools window.
    • Add the CSP metatag to your website: This tells your browser which websites are allowed to send resources like images, fonts, and scripts to your page.
    • Reload your website: This triggers the CSP checks.
    • Watch for console errors: Any blocked resources will show up in the console as errors. Look for the website address (URL) mentioned in the error. See screenshot below
    • Whitelist the necessary websites: Based on the console errors (screenshot below for example), add the relevant URLs to your CSP metatag using wildcards if needed (e.g., *.typekit.com instead of https://use.typekit.com). This allows resources from those websites to load on your page.

    Remember: Adding too many websites to your CSP can compromise security, so only allow the ones your website truly needs.

    image.thumb.png.d88e1a4bd7ee63dbd1c77b0696f43d7b.png

  10. @DomDom282 It looks like your website uses Ajax to load new content in without refreshing the page. Because it's using Ajax to refresh the page, you'll want to wrap your code with window.Squarespace.onInitialize(Y, function() {}) . This will cause the code to re-run on every ajax request.  Added new JS code below that should resolve your issue. 

    New JavaScript

    window.Squarespace.onInitialize(Y, function() {
      fetch('https://ipapi.co/json/')
        .then(response => response.json())
        .then(data => {
          if (data.country_code === 'AU') {
            window.location.href = 'https://www.louisedemasi.com/my-art-supplies-au';
          }
        })
        .catch(err => console.log('Error:', err));
    });

    Be sure to keep the JS code wrapped in <script> tags like so:

    <script>
      // Add JS code here
    </script>

     

  11. @sprucerow You can use the following CSS below. You'll need to update the URL of the background-image property to a transparent version of the brushstroke and then play around with the height property as well. 

    CSS

    [data-section-id="6566207a3608ec2faeee84dc"] .slideshow-wrapper:after {
      background-image: url('https://www.onlygfx.com/wp-content/uploads/2019/03/14-white-grunge-brush-stroke-6.png');
      height: 60px;
      content: '';
      width: 100%;
      bottom: 0;
      left: 0;
      display: block;
      z-index: 10;
      background-size: cover;
      position: absolute;
      background-repeat: repeat-x;
      background-position-y: top;
    }
  12. @KeeganMIller It would be easier if I had a URL to preview, however one solution would be to:

    1. Add a hidden field to the RSVP form and label it Event
    2. For the link to the RSVP form, add an event query parameter to the URL and give it some value e.g. /rsvp?event=event-1. In this example, assuming the RSVP form lives at "/rsvp", we add a query parameter whose name is event and the value is event-1. The value of the query parameter should be some unique identifier for that event
    3. When a user clicks the link and lands on /rsvp?event=event-1, the JavaScript code below would then grab the value of the "event" query parameter and update the value of the hidden field
    4. Then, when a user submits the RSVP form, "event-1" will be the value of the hidden field
       

    JavaScript
    You'll want to add the following JavaScript code to the Footer using Code Injection.

    (function () {
      // Check if the document is already in the 'complete' state
      if (document.readyState == 'complete') {
        // If so, invoke the addEventToHiddenField function
        addEventToHiddenField();
      } else {
        // If not, wait for the DOM content to be fully loaded before executing the code
        document.addEventListener('DOMContentLoaded', addEventToHiddenField);
      }
    
      // Function to add an event to the hidden field based on the URL query parameter
      function addEventToHiddenField() {
        // Get URL query parameters
        const urlSearchParams = new URLSearchParams(window.location.search);
    
        // Retrieve the value of the "event" query parameter
        const eventValue = urlSearchParams.get('event');
    
        // Check if the "event" query parameter exists
        if (eventValue) {
          // Get the hidden field by its ID
          const hiddenField = document.querySelector('input[name="SQF_EVENT"]');
    
          // Check if the hidden field exists
          if (hiddenField) {
            // Set the value of the hidden field to the retrieved "event" value
            hiddenField.value = eventValue;
          }
        }
      }
    })();

     Be sure to include the code in between <script> tags like so:

    <script>
      // Add JS code here
    </script>

     

  13. @LemonstrikeCreativeStudios For your site, you can use the following CSS:
     

    /* Ensure fixed header is above everyhting  */
    #header {
        z-index: 20
    }
    
    /* Add image to the top of footer section */
    #footer-sections { position: relative; z-index: 10; }
    #footer-sections:before {
        content: '';
        display: block;
        background-size: cover;
        background-image: url(https://images.squarespace-cdn.com/content/6554f93572c370332e59a9a0/0076b61b-a133-4f36-b2e7-ad8496b62727/peanuts-grass-100px.png?content-type=image%2Fpng);
        width: 100%;
        height: 40px;
        top: -20px;
        left: 0;
        position: absolute;
        z-index: 10;
    }

     

  14. @jcny85 

    STEP 1: 
    Add the following JavaScript code to the Footer using Code Injection.  This script adds an "active" class on the link that matches whatever filter is defined in the query parameter in the URL. 

    (function () {
        // Get all the links inside the specified container
        const links = document.querySelectorAll("#block-yui_3_17_2_1_1705961330405_3743 a");
    
        // Get the query parameter from the URL
        const urlSearchParams = new URLSearchParams(window.location.search);
        const urlTag = urlSearchParams.get("tag");
    
        // Loop through each link and check if its query parameter matches the one in the URL
        links.forEach((link) => {
            const linkSearchParams = new URLSearchParams(link.href.split("?")[1] || "");
            const linkTag = linkSearchParams.get("tag");
    
            // Add the "active" class if the query parameters match
            if (linkTag === urlTag) {
                link.classList.add("active");
            }
        });
    })();

     

    Step 2:
    You can now style the class like so using the following CSS:

    /* Style active blog filter link */
    #block-yui_3_17_2_1_1705961330405_3743 .active {
        color: blue;
    }

     

  15. @Teifi Looking at Chrome's dev tools, it looks like you have CSS on that page that is hiding the dropdown menu. I would update at CSS to the following:

    NEW CSS

    /* Change HEADER nav links on DESKTOP so it goes to home page instead of being anchor links on same page */
    .header-nav-list > div:nth-of-type(1),
    .header-nav-list > div:nth-of-type(2),
    .header-nav-list > div:nth-of-type(3),
    .header-nav-list > div:nth-of-type(4) {
    	display: none;
      	margin-right: 0;
    }

    This will target the <div> tags that are direct children of the .header-nav-list element rather than ALL <div> tags.


    Screenshot of code causing the issue:

    image.thumb.png.de872c64b9ec36c058cf4d681a8bef6f.png

  16. @GarySmith You can achieve the following by the following steps below. It will require you publishing the events and tagging them as well. 

     

    STEP 1:

    Add a "Featured" tag to the events that you would like to be to featured.


    STEP 2:

    Add the following JavaScript code to the Footer using Code Injection. This script will add CSS classes to each event  based on the event's categories and tags set. This will allow us to hide/show events using CSS in a later step.

    JavaScript

    (async function() {
      /**
       * Adds category and tag classes to each event list item so developers can 
       * style them with CSS. 
       */
      try {
        const response = await fetch('https://sidoti.com/events?format=json');
        
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        
        const data = await response.json();
        const { upcoming } = data;
    
        upcoming.forEach(eventData => {
          const { tags, urlId, categories }  = eventData;
          const eventLinkEl = document.querySelector(`.eventlist-event a[href*="${urlId}"]`);
          const parentEl = eventLinkEl && eventLinkEl.closest('.eventlist-event');
    
          if(!parentEl) return;
          
          tags.forEach(tag => parentEl.classList.add(`tag-${stringToCssClass(tag)}`));
          categories.forEach(category => parentEl.classList.add(`category-${stringToCssClass(category)}`));
        });
        
      } catch (error) {
        console.error('Error fetching data:', error.message);
      }
    
      function stringToCssClass(inputString) {
        // Replace spaces with hyphens and remove non-alphanumeric characters
        const cleanedString = inputString.replace(/[^\w\s]/gi, '').replace(/\s+/g, '-');
      
        // Ensure the class starts with a letter and follows CSS naming conventions
        const validCssClass = cleanedString.replace(/^[^a-zA-Z]+/, '').toLowerCase();
      
        return validCssClass;
      }
    })();

    Be sure to add the JavaScript code between <script> tags like so:

    <script>
      // Add JS code here
    </script>

     

    STEP 3: 

    Add the custom CSS below using the CSS Editor. This targets the section under the "Featured Events" heading based on it's data-section-id HTML attribute and then hides all upcoming events EXCEPT for the ones that are tagged as "Featured". 

    CSS

    /* Hide all upcoming events in the "Featured" section that aren't tagged as a featured event  */
    [data-section-id="60352a2206b45a3cc7e308e0"] .eventlist-event:not(.tag-featured) {
        display: none;
    }
  17. @JoshA You can use the following CSS below. This adds CSS variables to the blog-item container and then uses them in the category-* classes that is set on each "card". 

    CSS

    .blog-item {
      --pamphlet: red;
      --report: blue;
      --definition: green;
      --imagination-lab: pink;
      --declaration: black;
      --article: gray;
      --data-study: tomato;
    }
    
    .category-pamphlet { background-color: var(--pamphlet) !important; }
    .category-report { background-color: var(--report) !important; }
    .category-definition { background-color: var(--definition) !important; }
    .category-imagination-lab { background-color: var(--imagination-lab) !important; }
    .category-declaration { background-color: var(--declaration) !important; }
    .category-article { background-color: var(--article) !important; }
    .category-data-study { background-color: var(--data-study) !important; }


    Screenshot

    Here's a screenshot of Chrome dev tools open. You'll notice that each card has a class set based on the category in with the following  format, "category-*" .

    image.thumb.png.9ebf9eb53ff83e4119e5edc2e420e747.png

  18. @mackenzieu The CSS below should do the trick. You can play with the height CSS property with the 30px value to adjust the amount clipped from the bottom.

    CSS

    /* Clip wave image from the bottom */
    #block-yui_3_17_2_1_1706127503146_48723 img {
      object-fit: fill !important;
      object-position: top !important;
      height: calc(100% + 30px);
    }
    
    /* Make wave image span entire width of page */
    #block-yui_3_17_2_1_1706127503146_48723 .fluid-image-container {
        width: 100% !important;
    }

    See article on how to add CSS if you're not sure how. 

    Here's a screenshot of it working:
    image.thumb.png.9b853dc87f0c35d295f1f49393069f47.png

  19. @sian75 The following JS should do the trick as long as you place it in the Header using Code Injection. This will allow the script to run and re-order the elements before the site runs Squarespace's JS code that handles the masonry layout. 

    JavaScript

    (function(){
    
      // Value of the "data-section-id" attribute of the element with a class of "gallery-masonry"
      const SECTION_ID = '65b13fd4e94d515c51c1e3cb';
    
      /*********************************************************************************
       * DO NOT EDIT BELOW UNLESS YOU KNOW WHAT YOU'RE DOING
      *********************************************************************************/
      if(document.readyState == 'complete') {
        reverseOrderOfGalleryItems();
      } else {
        window.addEventListener('DOMContentLoaded', reverseOrderOfGalleryItems);
      }
    
      function reverseOrderOfGalleryItems() {
        // Get the parent element that contains the <figure> elements
        const gallery = document.querySelector(`.gallery-masonry[data-section-id="${SECTION_ID}"] .gallery-masonry-wrapper`);
    
        // Get a NodeList of all <figure> elements within the parent element
        const figureElements = gallery.querySelectorAll('figure');
    
        // Convert the NodeList to an array and reverse it
        const reversedFigures = Array.from(figureElements).reverse();
    
        // Remove existing <figure> elements from the parent
        figureElements.forEach(figure => figure.remove());
    
        // Append the reversed <figure> elements back to the parent
        reversedFigures.forEach(figure => gallery.appendChild(figure));
      }
      
    })()

    Remember to place the JavaScript code in between <script> tags, e.g.

    <script>
      // Add JS code here
    </script>

     

×
×
  • Create New...

Squarespace Webinars

Free online sessions where you’ll learn the basics and refine your Squarespace skills.

Hire a Designer

Stand out online with the help of an experienced designer or developer.