> ## Documentation Index
> Fetch the complete documentation index at: https://docs.repdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Behavior Tracking

> Learn how to track respondent behavior

<Steps titleSize="h3">
  <Step title="Implementing a JavaScript Tracker for User Behavior Data">
    <p> Copy the simple **JavaScript tracker code** (attached) into your survey platform’s frontend codebase or UI. This ensures that, whenever respondent complete surveys, it tracks input behavior data for open-ended questions directly from their individual browsers. </p>
  </Step>

  <Step title="Integrate ReDem API into your workflow">
    <p>We are using this script to persist this input\_behavior in the browser until you are ready to call the API</p>

    ```javascript theme={null}
    <script>
      document.addEventListener("DOMContentLoaded", function () {
        const textarea = document.getElementById("input_behavior");
        const submitButton = document.getElementById("submit_button");
      
        // Constants
        const INTERACTION_TYPES = {
            KEYSTROKE: 'KEYSTROKE',
            COPYPASTE: 'COPY_AND_PASTE'
        };
      
        // Question ID - This would typically come from your survey tool, you need to edit this
        const QUESTION_ID = "<BAS_QuestionID>";
        
        // State variables
        let startTime = null;
        let oldText = "";
      
        // Initialize or retrieve interaction data from sessionStorage
        const getInteractionData = () => {
            const storedData = sessionStorage.getItem("interaction_data");
            return storedData ? JSON.parse(storedData) : [];
        };
      
        let interactionData = getInteractionData();
      
        // Function to push interaction data and save to sessionStorage
        const pushInteraction = (value, interactionType) => {
            interactionData.push({
                value: value,
                interactionType: interactionType,
                timestamp: new Date().toISOString()
            });
          
            // Save to sessionStorage
            sessionStorage.setItem("interaction_data", JSON.stringify(interactionData));
        };
      
        // Initialize or retrieve startTime from sessionStorage
        const storedStartTime = sessionStorage.getItem("start_time");
        if (storedStartTime) {
            startTime = parseInt(storedStartTime);
        }
      
        // Handle input changes
        textarea.addEventListener('input', (e) => {
            // Ignore paste events as they're handled separately
            if (e.inputType === 'insertFromPaste') return;
          
            if (!startTime) {
                startTime = Date.now();
                sessionStorage.setItem("start_time", startTime.toString());
            }
          
            const newInteraction = {
                value: e.target.value,
                interactionType: INTERACTION_TYPES.KEYSTROKE
            };
          
            pushInteraction(newInteraction.value, newInteraction.interactionType);
            oldText = e.target.value;
        });
      
        // Handle paste events
        textarea.addEventListener('paste', (e) => {
            if (!startTime) {
                startTime = Date.now();
                sessionStorage.setItem("start_time", startTime.toString());
            }
            
            const cursorPosition = e.target.selectionStart;
            const currentValue = e.target.value;
            const pastedText = e.clipboardData?.getData('text') || '';
            
            // Construct the new complete text by combining existing and pasted content
            const newText = currentValue.slice(0, cursorPosition) + pastedText + currentValue.slice(cursorPosition);
            
            const newInteraction = {
                value: newText,
                interactionType: INTERACTION_TYPES.COPYPASTE
            };
            
            pushInteraction(newInteraction.value, newInteraction.interactionType);
        });
      
        // Handle form submission
        submitButton.addEventListener("click", function () {
            // Get the latest interaction data from sessionStorage
            interactionData = getInteractionData();
          
            // Calculate total time spent
            const totalTimeMs = startTime ? Date.now() - startTime : 0;
          
            // Save final BAS data per each question
            saveBASDataPerQuestion();
        });


        // Function to save data in BAS format
        const saveBASDataPerQuestion = () => {
            const basData = {
                "qualityCheck": "BAS",
                "dataPointId": QUESTION_ID,
                "interactionData": interactionData
            };
          
            sessionStorage.setItem(QUESTION_ID, JSON.stringify(basData));
        };
      });
    </script>
    ```
  </Step>

  <Step title="Use API response to trigger your next step">
    <p>When you are making the API call to ReDem use this structure from the session storage and make sure to connect `QUESTION_ID` during the integration process</p>
  </Step>
</Steps>
