# README

## Quickstart

Hello Softr app developer who just wants to grab some code and get it into your project as quickly as possible! Here's the three-step process that will get you going:

* Visit [the docs](https://scissors-docs.appspan.net)
* Look through the scripts and find the one that does the thing you need
* Do what it says in the "How to Use It" section

## What else should I know?

### Snippets are dynamically loaded by default

When you follow the instructions in the "How to Use It" section, then by default your application will load the snippet from a Cloudflare CDN that always contains the latest version of the snippet. This has the advantage of making sure your site picks up any fixes to the snippet that might have been necessary over time as Softr evolves and changes. But it has the disadvantage that a change to the snippet could possibly break your site at a time not of your choosing.

If you would prefer to avoid both the advantage and disadvantage of loading the snippet dynamically, you can copy and paste the snippet itself. At the bottom of each doc page there is a handy link that will take you to the raw code for the snippet, suitable for easy copying and pasting.

## I found a bug, what should I do?

Thank you for finding a bug! Please head over to the [issues](https://github.com/dcoletta/scissors/issues) page of this repository, create a new issue, and provide the following information:

* Which snippet you are using
* What you expected to happen when you tried to use it
* What actually happened
* Screenshots (if relevant)
* A link to a page of your app where the snippet is not working correctly (if that's feasible)

## How to contribute

See [CONTRIBUTING.md](https://github.com/dcoletta/scissors/blob/main/CONTRIBUTING.md).

## Why does Scissors exist?

I decided to try to get more organized about custom code snippets. For a while I was putting my custom code snippets in [unlock-softr.com](http://unlock-softr.com/), and that was way better than nothing. But I wanted some things that were going to be hard to do there:

* I wanted to make it easier for people to use custom code snippets in their Softr apps
* I wanted to make it easier for multiple people to collaborate on the code snippets
* I wanted to make it optionally possible for changes to a snippet to be able to propagate automatically to Softr sites that are using the snippet

I’m calling it ![:scissors:](https://a.slack-edge.com/production-standard-emoji-assets/14.0/apple-medium/2702-fe0f@2x.png) Scissors since it’s all about code snippets.

In case you’re curious, the tools I used to build this are Github to store the snippets, CloudFlare CDN to publish the code snippets for inclusion into Softr pages, and Gitbook to make the documentation.

## What am I agreeing to by using this code?

Your use of code and documentation in this repository is governed by the [MIT License](https://github.com/dcoletta/scissors/blob/main/LICENSE/README.md).

## Can I depend on this service?

That's a reasonable question, but I can't answer it. Instead, if you want to use this service in the way it's intended to be used, but you're concerned about its long-term existence, then the best thing you can do is make your own. Here's how: [FORKING.md](https://github.com/dcoletta/scissors/blob/main/FORKING.md).


# CONTRIBUTING

## Contributions are welcome!

There are two different ways to contribute a new snippet:

* Preferred: If you are comfortable with Github, JavaScript, and Markdown, then you can create a .js file (the snippet itself) and an .md file (the documentation) and make a pull request to this repository, and I'll review and merge it.
* Alternatively, if you have some JavaScript you want to contribute, but you'd rather hand it off to me and let me do the rest, you can head over to the [issues](https://github.com/dcoletta/scissors/issues) page of this repository, create a new issue, and paste in the code, and I'll take it from there.

Fixes and enhancements to an existing snippet are also welcome! Again, you can contribute a change to a snippet or its documentation using either of the two approaches above.

## What a good pull request looks like

Here's a checklist for what a good pull request (PR) will have:

* a folder at the top level of the repo with the name of your script in PascalCase, such as `DoImportantThing`. (Start the script name with a verb.)
* In the `DoImportantThing` folder, a `DoImportantThing.js` file that contains your snippet code.
* In the JavaScript code in your `DoImportantThing.js` file, any string that a user might need to customize should be overridable. See [SampleSiteBeforeSignup.js](https://github.com/dcoletta/scissors/blob/main/SampleSiteBeforeSignup/SampleSiteBeforeSignup.js) for example conventions.
* At the top of the JavaScript code, please insert a copy of the MIT license inside a comment block.
* In the `DoImportantthing` folder, a `DoImportantThing.md` file that contains the documentation for your snippet. See `SampleSiteBeforeSignup.md` for conventions. If it would be helpful for your documentation to include a screenshot of what visual effect the snippet will have, see [MenuHighlighter.md](/menuhighlighter) for conventions on how to include that in the doc page.
* A new line in [SUMMARY.md](https://github.com/dcoletta/scissors/blob/main/SUMMARY.md) with a link to your snippet.

## CSS and HTML in your snippet

Some code snippets require accompanying CSS and/or HTML. There are many different techniques for loading CSS and HTML by reference, and you are welcome to add CSS and HTML files to your folder to be loaded by reference. The only strong suggestion I will make here is that it should be possible for users of your snippet to be able to automatically pick up the latest version without having to change the Softr project that uses it. This means that it is discouraged for the instructions to include something like "please put this HTML or CSS into your project." Instead, prefer loading CSS with a `<link>` tag or including it as a `style` attribute of HTML, and prefer loading HTML into the DOM with code in your JavaScript, such as `document.createElement()` and `element.appendChild()`.

## What am I agreeing to by contributing to this repository?

By submitting a pull request, issue, or any other content to this repository, you agree that your contributions are governed by the [MIT License](https://github.com/dcoletta/scissors/blob/main/LICENSE/README.md) and represent that there are no claims on your contributions which would conflict with that license.


# FORKING

## Why?

Suppose you like the idea of a repository of Softr code snippets, but you're not sure you want to trust someone else to host that code for you in your live sites. After all, if this service goes down, your sites might break.

Here's the solution: fork it!

## How?

* In Github, fork this repo
* Sign up for a free CloudFlare CDN account
* Connect the CDN to your forked repo
* Sign up for a free Gitbook account
* Connect Gitbook to your forked repo
* (Optionally) create a subdomain such as scissors.example.com and connect it to the CDN
* (Optionally) create a subdomain such as scissors-docs.example.com and connect it to Gitbook

After you do the above, you'll be able to get all the benefits of a snippet code repository, but you'll have full control over how it is hosted, and you can make sure it keeps running. You can even merge some or all the code from the main repo periodically so you stay up to date. Or not, your choice!

## Are those subdomains important?

You don't have to create and use them in order for this approach to serve its main purpose. However, if you do host your snippets from domains that you control, then it will be possible for you to change the hosting services without having to go back into your Softr apps and update them. For example, if some day you you want to use a different CDN instead of CloudFlare, you'll be able to switch it out in a way that is transparent to the sites that are depending on the code snippets.


# MenuHighlighter.js

MenuHighlighter adds a highlight to the link of your header block that corresponds to the page that the user is currently on.

## What It Looks Like

<figure><img src="https://1908298152-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdZ27T2QMmY232w30KoVT%2Fuploads%2FbZCSNfytVsPlIPg3dgtf%2Fimage.png?alt=media&amp;token=c4f1c920-2ab0-4802-a8af-a56afd51a44e" alt=""><figcaption><p>Screenshot of MenuHighlighter.js being used to create a lavender "selected" color to the About page of a Softr site.</p></figcaption></figure>

## How To Use It

In your site settings **Code Inside Footer** section, put the following code:

```
<script src="https://scissors.appspan.net/MenuHighlighter/MenuHighlighter.js">
```

## How to Customize It

Add the following before the `<script src=>` tag:

```
<script>
const MenuHighlighter = {backgroundColor: "#FF0000"};
</script>
```

## What It Does

It looks for an `<nav>` element in the DOM, and then makes a list of all the `<a>` elements underneath the `<nav>` element. For each `<a>`, it checks to see if the slug of the current page starts with the `href` attribute of the link. When it finds one that does, that means it has found the link corresponding to the current page, and it sets the `<a>`'s background color to the specified color. In its search for `<a>` tags, it skips the home page.

## Read the Code

[MenuHighlighter.js](https://scissors.appspan.net/MenuHighlighter/MenuHighlighter.js)


# SampleSiteBeforeSignup.js

SampleSiteBeforeSignup lets you make your site available for "sampling" some number of pages before making the user sign up in order to keep using it.

## How To Use It

In your site settings **Code Inside Header** section, put the following code:

```
<script src="https://scissors.appspan.net/SampleSiteBeforeSignup/SampleSiteBeforeSignup.js">
```

Or, if you want the counter of allowed page views to only be used on certain pages, you can put the above code into just the **Code Inside Header** section of one or more individual pages.

## How to Customize It

Add the following before the `<script src=>` tag:

```
<script>
const SampleSiteBeforeSignup = {
    maxPageViewsBeforeSignUp: 5,    // number of pages the user is allowed to visit before being asked to sign up
    signUpSlug: '/register',        // slug of the page where your user can sign up
    signInSlug: '/signin',          // slug of the page where your user can sign in
    cookieName: 'pageViews'         // name of the cookie that keeps track of the number of visits
};
</script>
```

## What It Does

Every time a non-logged-in user visits your site on a page other than your sign-up or sign-in page, a counter stored in a cookie is incremented. When the counter gets to the limit, then instead of loading the page the user wanted to go to, the page that loads is the sign-up page.

## Read the Code

[SampleSiteBeforeSignup.js](https://scissors.appspan.net/SampleSiteBeforeSignup/SampleSiteBeforeSignup.js)


# LoadDefaultRecord.js

When you have a List Block and a List Details block on the same page, LoadDefaultRecord ensures that the List Details block displays a default record when no record ID is specified on the URL.

## How To Use It

In your the **Code Inside Header** section of your page settings, put the following code:

```
<script src="https://scissors.appspan.net/LoadDefaultRecord/LoadDefaultRecord.js">
```

## How to Customize It

Add the following before the `<script src=>` tag:

```
<script>
const LoadDefaultRecord = {
    defaultRecordId: "abc123"    // Id of the record to display when no record Id is on the URL
};
</script>
```

## What It Does

When the page loads, this script looks to see if there is a record Id specified on the URL, which could either be in the `?recordId=` format or in the `/r/rec` format. If there is no record Id in either of these formats, then it changes the URL to include the value of `defaultRecordId` and reloads the page by calling `history.replaceState()` so that there is not an extra entry in the history.

## Read the Code

[LoadDefaultRecord.js](https://scissors.appspan.net/LoadDefaultRecord/LoadDefaultRecord.js)


# EditThisPage.js

Add an "Edit This Page" button that only you can see, which when clicked takes you to that page in the Softr studio.

## What It Looks Like

<figure><img src="https://1908298152-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdZ27T2QMmY232w30KoVT%2Fuploads%2F44KwcTqGimeFWxwKnEu7%2Ff91410d5c7f08c1f191486cfb68c6c692fc3a9ff.png?alt=media&amp;token=9a6b67d8-85c2-43e4-b337-195becc9f708" alt="A screen shot of a site that uses the &#x22;Edit this page&#x22; script toi add a button that lets you edit the page in the Softr studio."><figcaption><p>A screen shot of a site that uses the "Edit this page" script toi add a button that lets you edit the page in the Softr studio.</p></figcaption></figure>

## How To Use It

In your the **Code Inside Footer** section of your page settings, put the following code:

```
<script src="https://scissors.appspan.net/EditThisPage/EditThisPage.js">
```

## How to Customize It

Add the following before the `<script src=>` tag:

```
<script>
const EditThisPage = {
  superUserEmail: "admin@example.com",  // replace this with your superuser email address
  buttonTitle: "Edit this page",        // default button title, replace with your preference
  buttonStyle: "position: fixed; z-index: 9999999; left: 20px; bottom: 60px"  // default button style
};
</script>
```

{% hint style="info" %}
You don't need to supply all these override values, just the ones you want to change from the default values.
{% endhint %}

## What It Does

When the page loads, this script looks to see if the super user account is logged in. If it is, it creates an "Edit this page' button and adds it to the page. When you click the button, it opens the page editor for this page in the Softr studio, in another browser tab.

## Read the Code

[EditThisPage.js](https://scissors.appspan.net/EditThisPage/EditThisPage.js)

{% embed url="<https://github.com/dcoletta/scissors/blob/main/EditThisPage/EditThisPage.js>" %}


# RedirectAfterFormSubmit.js

After a form submit to Make, redirect your user to another page defined in the Make automation.

## How To Use It

In your the **Code Inside Footer** section of your page settings, put the following code:

```
<script src="https://scissors.appspan.net/RedirectAfterFormSubmit/RedirectAfterFormSubmit.js">
```

Then, in your form's Features section, under Destination choose Send to Make and follow the instructions in the blue box. Fill in the Webhooks response action in Make so that the Body contains `{"redirect": "https://google.com"}`, substituting your destination URL for `https://google.com`.

## How to Customize It

Add the following before the `<script src=>` tag:

```
<script>
const RedirectAfterFormSubmit = {
  formId: "form1",
  redirectPropName: "redirect"
};
</script>
```

{% hint style="info" %}
You don't need to supply all these override values, just the ones you want to change from the default values.
{% endhint %}

## What It Does

After the form is successfully submitted to Make, the script looks at the response body, gets the value for `redirect` (or whatever property name you have specified), and then navigates the browser to that string as a URL.

## Read the Code

{% embed url="<https://github.com/dcoletta/scissors/blob/main/RedirectAfterFormSubmit/RedirectAfterFormSubmit.js>" %}


