npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@adamjkb/netlify-cms-widget-select-async

v1.1.0

Published

NetlifyCMS select widget from external resources

Downloads

10

Readme

Async Select Widget for NetlifyCMS

A select widget for NetlifyCMS widget that allows you to select a string value or an array of strings. The options are populated through asynchronous fetch requests.

Checkout the demo or try it out in a sandbox

Table of contents

Features

  • Support for custom fetch() request parameters like headers, method, and body
  • Supports GraphQL and REST APIs
  • Nested data structures
  • Grouped options
  • Fuzzy searching fetched options

Install

Via NPM:

npm install @adamjkb/netlify-cms-widget-async

You may install it through native JavaScript import through CDNs such as Skypack

import { Widget as AsyncSelectWidget } from '@adamjkb/netlify-cms-widget-async'
CMS.registerWidget(AsyncSelectWidget)

Via script tag:

<script src='https://unpkg.com/@adamjkb/netlify-cms-widget-select-async/dist/index.umd.js'></script>
<script>
    CMS.registerWidget(AsyncSelectWidget.Widget)
</script>

How to use

Simple usage

Add to your NetlifyCMS collection:

fields:
  - name: simple_usage
    label: Simple usage
    widget: select-async
    # widget options:
    url: https://fakestoreapi.com/products
    value_field: id
    display_field: title

Advanced usage

Add to your NetlifyCMS collection:

fields:
  - name: advanced_usage
    label: Advanced usage
    widget: select-async
    # widget options:
    url: https://graphql.myshopify.com/api/graphql
    value_field: node.value
    display_field: node.label
    data_path: data.products.edges
    grouped_options:
        data_path: node.options.edges
        value_field: node.id
        display_field: node.title
    multiple: true
    min: 1
    max: 4
    refetch_url: false
    fuzzy_search: true
    fetch_options:
        headers:
            Content-Type: application/json
            X-Shopify-Storefront-Access-Token: dd4d4dc146542ba7763305d71d1b3d38
        method: POST
        body: '{"query": "query allProducts{ products(first:10) { edges { node { label: title value: id options: variants(first:3) { edges { node { id title } } } } } } }"}'

Options

url string

Endpoint URL

Example: https://fakestoreapi.com/products

display_field string | default: "label"

Object key or path to object to be displayed.

Example: node.label or title

value_field string | default: "value"

Object key or path to object to be saved.

Example: node.value or id

data_path string?

Object key or path to object to the array of objects to be used as options.

If fetch() request does not return an array of object but an object this value can be used to access the array.

Example: data.products.edges or data

multiple boolean | default: false

Allows multiple options to be selected. Widget's output value is going to change to an string[]

min and max integer?

Minimum and maximum number of items allowed to be selected

ignored if multiple is false

fetch_options object?

The properties of this field are mapping to the main values of native fetch() request parameters. fetch() documentation on MDN

If you need to set parameters outside of the built-in method,headers, and body you can do so with by extending the passed in parameters using the fethc_options.params_function

fetch_options.method string | default: "GET"

Request method.

fetch_options.headers object | default: {}

Request headers.

Example:

fetch_options:
    headers:
        Content-Type: application/json
        X-Access-Token: <PUBLIC-API-KEY>
fetch_options.body string | default: undefined

Request body.

Note that GET methods does not have a body. Change request method if you are specifying this field.

fetch_options.params_function function?

⚠️ Only works if you are using a JavaScript config file to initialize NetlifyCMS. Refer to documentation how to set that up.

A JavaScript function that receives all all the other fetch_options values, the url, and the search input term. Must return a valid object with at least a url property.

function({term, url, method, headers, body}) {
    // ...
    return {
        url, // required
        options: {method, headers, body} // optional
    }
}
fetch_options: {
    // ...
    params_function: ({ term, url, ...rest }) => ({
        url,
        options: {
            ...rest,
            body: JSON.stringify({
                query: `
                    query allProducts(
                        $myCustomQuery: String
                    ) {
                        products(
                            first: 15
                            query: $myCustomQuery
                        ) {
                            edges {
                                node {
                                    label: title
                                    value: id
                                }
                            }
                        }
                    }
                `,
                variables: {
                    'myCustomQuery': `title:${term}*`
                }
            })
        }
    })    
}

grouped_options object?

If you have data structure where there is a second level of option you have the option to group them together. A sample data structure:

const data = [
    {
        label: 'Colors',
        options: [
            {
                label: 'Red',
                value: 'red'
            },
            // ...
        ]
    },
    {
        label: 'Flavors',
        options: [
            {
                label: 'Salted Caramel',
                value: 'salted-caramel'
            }
            // ...
        ]
    },
    // ...
]
grouped_options.display_field string | default: "label"

Object key or path to object to be displayed.

grouped_options.value_field string | default: "value"

Object key or path to object to be saved.

grouped_options.data_path string

Object key or path to object to the array of objects to be used as options.

grouped_options.flatten_singles boolean | default: true

If true, grouped options that contain only one option will be transformed into a top level options. Its label will be formatted as such {parent.label}: {child.label}.

refetch_url boolean | default: true

By default react-select will send a try to load new options through a new request whenever the search input changes, setting this field's value to false will prevent that and retain the options after the initial request.

Note that the fetched options are filtered with fuzzy search by default so the search input will affect the displayed options.

fuzzy_search boolean | default: true

The widget uses fuse.js to search the provided options. But if you are using filtering the data on the API level you might not want to filter the result on client side too. See fetch_options.params_function

Setting both fuzzy_search and refetch_url off will turn off input field search function.

Authors

Acknowledgments

The project was heavily inspired by @chrisboustead's asynchronous implementation of the original NetlifyCMS Select widget, netlify-cms-widget-select-async