Asset & Assessment Types

Before creating an order you must know the UUIDs of your asset_type and assessment_type that you want to use. Unfortunately, not all types are compatible with each other and we have to change supported types from time to time. So the best practice is to use our many-to-many route for Asset Types and Assessment Types before creating each order. Thankfully we built this guide to make your life easier!

Asset & Assessment Selector

1

Set Up the Form Component

We recommend using a two-step drop down so that the list of available assessment types (e.g. inspections) is determined by the selected asset type.

<div class="dropdown-widget">
    <label for="assetDropdown">Asset Type:</label>
    <select id="assetDropdown">
        <option value="">-- Select Asset Type --</option>
    </select>

    <label for="assessmentDropdown">Inspection Type:</label>
    <select id="assessmentDropdown" disabled>
        <option value="">-- Select Inspection Type --</option>
    </select>
</div>
2

Connect to Our API

The code below calls our API to get a list of all available asset types and associated assessment types. This can be modified to work in Node, but we’re presenting browser-based code in this example.

const ENVIRONMENT = "sandbox.api"; // || 'api' for production
const API_URL = `https://${ENVIRONMENT}.24hourinspections.com/v1/asset-types-to-assessment-types`;

// Fetch data from the API
async function fetchData() {
    try {
        const response = await fetch(API_URL);

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const data = await response.json();
        return data.data.items;
    } catch (error) {
        console.error('Error fetching API data:', error.message);
        return [];
    }
}

// Initialize dropdowns
async function initDropdowns() {
const items = await fetchData();

if (items.length === 0) {
    console.error(
        'No data received from API. Ensure your token and endpoint are valid.'
    );
    return;
}

// Extract unique assets and map assessments to asset IDs
const assets = {};
items.forEach(item => {
    const asset = item.asset_type;
    const assessment = item.assessment_type;
    if (!assets[asset.id]) {
        assets[asset.id] = { name: asset.name, assessments: [] };
    }
    assets[asset.id].assessments.push({
        id: assessment.id,
        name: assessment.name,
    });
});

// Populate the Asset dropdown
const assetDropdown = document.getElementById('assetDropdown');
Object.entries(assets).forEach(([id, asset]) => {
    const option = document.createElement('option');
    option.value = id;
    option.textContent = asset.name;
    assetDropdown.appendChild(option);
});

// Handle Asset dropdown change
assetDropdown.addEventListener('change', event => {
    const selectedAssetId = event.target.value;
    const assessmentDropdown = document.getElementById('assessmentDropdown');

    // Clear and disable the Assessment dropdown if no Asset is selected
    assessmentDropdown.innerHTML =
    '<option value="">-- Select Assessment --</option>';
    if (!selectedAssetId) {
        assessmentDropdown.disabled = true;
        return;
    }

    // Populate the Assessment dropdown
    assets[selectedAssetId].assessments.forEach(assessment => {
        const option = document.createElement('option');
        option.value = assessment.id;
        option.textContent = assessment.name;
        assessmentDropdown.appendChild(option);
    });

    // Enable the Assessment dropdown
    assessmentDropdown.disabled = false;
});
}

// Initialize the dropdowns on page load
initDropdowns();

3

Style the Component

Obviously you can style things however you like, but here’s some sample code for this as well.

Styles
/* General Styling */
body {
    font-family: Arial, sans-serif;
    margin: 0; /* Remove default margin */
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh; /* Full viewport height to prevent scrolling */
    background-color: #f9f9f9;
    overflow: hidden; /* Disable scrolling */
}

/* Widget Container */
.dropdown-widget {
    width: 300px;
    padding: 20px;
    background-color: #ffffff;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    display: flex;
    flex-direction: column;
    gap: 15px;
}

/* Label Styling */
label {
    font-weight: bold;
    margin-bottom: 5px;
    color: #333;
}

/* Dropdown Styling */
select {
    width: 100%;
    padding: 10px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #f9f9f9;
    transition: border-color 0.3s ease;
}

select:focus {
    border-color: #007bff;
    outline: none;
}
4

Place an Order

Finally, POST to /v1/orders with the required body.

Complete Example

View complete example on Playcode.io