Issue
I am using Flask for my website and wanted buttons to render without reloading the url, so I haphazardly copied some JQuery/AJax code and- while it works great for desktop- it is causing me issues on mobile. The buttons will not change value on mobile. I submit which value was clicked to my flask module, and return values to update the button based on what was clicked. Here is my code, starting at the forms I submit until the end of the script:
    <body id="page-top">
        <header class="masthead">
            <div class="text-center">
                <h6 class="text-white-50 mx-auto mb-3">Which song is better?</h6>
                <div class="container mt-5">
                            <form id="songForm" data-sb-form-id="none" autocomplete="off">
                    <div class="row">
                            <div class="col-6 mb-3">
                                <img id="pic1" src="{{images[0]}}" class="img-fluid"/>
                                <input autocomplete="off" id="button1" type="submit" value="{{playlist_tracks[0]}}" class="btn text-wrap btn-primary mt-3 button-smaller" name="song"/>
                            </div>
                            <div class="col-6 mb-3">
                                <img id="pic2" src="{{images[1]}}" class="img-fluid"/>
                                <input autocomplete="off" id="button2" type="submit" value="{{playlist_tracks[1]}}" class="btn text-wrap btn-primary mt-3 button-smaller custom-button" name="song"/>
                            </div>
                    </div>
                </div>
            </div>
            
                        </form>
        </header>
        
        <!-- Include jQuery -->
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
    $(document).ready(function () {
 
        $("#songForm").submit(function (event) {
            console.log("Form submitted!");
            console.log("{{id}}");
            event.preventDefault();  // Prevent the form from submitting in the traditional way
        var selectedSong = $(document.activeElement).val();
        // Get the form data
        var formData = new FormData();
        formData.append('song', selectedSong);
        $.ajax({
            data: formData,
            url: "{{id}}",
            processData: false,
            contentType: false,
            type: 'POST',
            headers: {
                'X-Requested-With': 'XMLHttpRequest'
            },
            success: function (response, status, xhr) {
                console.log("Form Data:", formData);
                console.log("Response:", response);
                if (response.redirect_url) {
                    // Redirect to the specified URL
                    console.log("REDIRECT TRIGGERED");
                    window.location.href = response.redirect_url;
                    return;  // Add a return statement to exit the function after redirection
                }
                // Check if redirect_url exists in the response
                else {
                    // Continue with your existing logic
                    console.log("Updating buttons...");
                    // Check if compare_songs exists and is an array
                    if (Array.isArray(response.compare_songs) && response.compare_songs.length >= 2) {
                        // Assuming you have button IDs 'button1' and 'button2'
                        $('#button1').val(response.compare_songs[0]);
                        $('#button2').val(response.compare_songs[1]);
                        $('#pic1').val(response.images[0]);
                        $('#pic2').val(response.images[1]);
                        console.log("Buttons updated!");
                    } else {
                        console.error("Invalid or missing compare_songs in the response");
                    }
                }
                // Check for a 302 status code
                if (xhr.status === 302) {
                    // Extract the new URL from the headers
                    var newUrl = xhr.getResponseHeader('Location');
                    // Use the following line only if you want to redirect using a GET request
                    window.location.href = newUrl;
                }
            },
        });
    });
});
</script>
I have tried several suggestions from the internet around the on.click method, but must be implementing it wrong. Not sure where to go from here without sitting down and learning a whole new language (which I guess I should do eventually...)
Solution
On a mobile browser (or touchscreen) "clicks" are simulated by the browser based on user touch events. However, sometimes the browser can incorrectly simulates a click and it may not be triggering the submit function. You can try explicitly handling form submission when the user touches the submit button:
$(document).on('click touchstart', '#button1, #button2', function(event) {
    // submit function
});
Also if you want to change the src of an img element, you should use prop instead of val. Val is meant to be used to set the value of a user input field. Prop is meant to be used to set a specific value for a property or attribute on an html element.
$('#pic1').prop('src', response.images[0]);
$('#pic2').prop('src', response.images[1]);
Edit:
To prevent click and touchstart both being called at the same time, you can bind only the applicable event:
var isTouchDevice = 'ontouchstart' in document.documentElement;
$(document).on(isTouchDevice ? 'touchstart' : 'click', '#button1, #button2', function(event) {
    // submit function here
});
or you can introduce a debounce:
var lastEventTime = 0;
$(document).on('click touchstart', '#button1, #button2', function(event) {
    var currentTime = new Date().getTime();
    if (currentTime - lastEventTime < 500) {
        return;
    }
    lastEventTime = currentTime;
    // submit form
});
                            Answered By - Jacob
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.