Giter Club home page Giter Club logo

data-target's Introduction

data-target

Basic functionality

This library allows HTML anchors and forms to render the response of the request inside another element.

The element in which the response will be rendered inside must have it's id attribute's value replicated in the data-target attribute of the corresponding anchor or form.

After the response is rendered inside the target element, the library will look for more data-target attributes inside the inner HTML of the target element.

By default, the browser's URL will not be changed after rendering the response inside the target element, but this behavior can be changed. Look at the "Configuration" section below for more information.

Please note that if the rendered response contains javascript code, this code will not be executed by the browser. If you want to execute javascript code according to the rendered response, you could listen to the "data-target:load" event to create your logic to load you modules. To see an example see the "Events" section.

Example using an anchor:

<a href="/path" data-target="the-target-element-id">Click me!</a>
<div id="the-target-element-id">
    The content of this div will be replaced by the response of the HTTP request
</div>

Example using a form:

<form action="/path" method="post" data-target="the-target-element-id">
    <input type="text" name="name" />
    <button>Submit</button>
</form>
<div id="the-target-element-id">
    The content of this div will be replaced by the response of the HTTP request
</div>

Events

After a response is rendered inside the target element, a "data-target:load" event will be dispatched with the following format:

{
    detail: {
        url: string;
        targetElementId: string;
        responseStatusCode: number;
    }
}

Example

window.addEventListener('data-target:load', (event) => {
    console.log(
        `loaded URL ${event.detail.url} inside element with `
        + `ID "${event.detail.targetElementId}, with response `
        + `status code ${event.detail.responseStatusCode}"`
    );
});

Another example is using this event to dynamically load some javascript modules according to which url was loaded:

const modulesMap = {
    'http://localhost/foo': '/modules/foo.js',
    'http://localhost/bar': '/modules/bar.js',
    'http://localhost/baz': '/modules/baz.js',
    'http://localhost/qux': '/modules/qux.js'
};

window.addEventListener('data-target:load', async (event) => {
    const scriptPath = modulesMap[event.detail.url];
    if (scriptPath) {
        await import(scriptPath);
    }
});

Configuration

This library exposes a global object inside window, called dataTargetConfig, that you can use to configure the library's behavior:

export declare type DataTargetConfig = {
    errorHandler: (error: unknown, element: HTMLAnchorElement | HTMLFormElement) => void;
    httpRequestDispatcher: (element: HTMLAnchorElement | HTMLFormElement) => Promise<{
        content: string;
        statusCode: number;
    }>;
};

declare global {
    interface Window {
        dataTargetConfig: DataTargetConfig;
    }
}

errorHandler

Use this function to personalize your error logs capturing logic.

This is the default implementation:

errorHandler: (error: unknown, element: HTMLAnchorElement | HTMLFormElement) => {
    console.error({ error, element });
},

httpRequestDispatcher

Reimplement this function if you need a more strict security control or any other requirement that may affect the http request dispatching logic, like changing the browser's url or using a different fetching library.

This is the default implementation:

httpRequestDispatcher: async (element: HTMLAnchorElement | HTMLFormElement) => {
    if (element instanceof HTMLAnchorElement) {
        return dispatchRequestForAnchor(element);
    }
    
    return dispatchRequestForForm(element);

    async function dispatchRequestForAnchor(anchor: HTMLAnchorElement) {
        const response = await fetch(anchor.href);
        return {
            content: await response.text(),
            statusCode: response.status
        };
    }

    async function dispatchRequestForForm(form: HTMLFormElement) {
        const method = form.method;
        const formData = new FormData(form);
        let response: Response;

        if (method.toLowerCase() === 'get') {
            response = await dispatchGETRequestForForm(form);
        } else {
            response = await fetch(form.action, { method, body: formData });
        }

        return {
            content: await response.text(),
            statusCode: response.status
        };
    }

    async function dispatchGETRequestForForm(form: HTMLFormElement) {
        const formData = new FormData(form);
        const entries = formData.entries();
        const entriesArray = Array.from(entries);
        const entriesArrayWithoutFiles = entriesArray.map(([key, value]) => {
            if (value instanceof File) {
                return null;
            }

            return [key, value];
        }).filter((pair): pair is [string, string] => !!pair);
        const entriesObject: Record<string, string> = Object.fromEntries(entriesArrayWithoutFiles);
        const queryString = new URLSearchParams(entriesObject);
        return fetch(`${form.action}?${queryString}`);
    }
},

data-target's People

Contributors

andremarcondesteixeira avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.