Deepstory – jQuery

So the web app is built with bootstrap and jquery(for lazy ppl like me). And I can’t believe I’ve spent over two hours on an auto-resizing textarea. It wasn’t a problem to increase the height as typing, but it is a problem when trying to load the element with height according to the content at loading. Since Chrome wouldn’t calculate the scrollHeight of a tab that is not active, I will have to trigger this calculation only when the tab-pane is clicked, otherwise, the textarea will have 0 size.

Triggered when the GPT-2 part is loaded:

$('textarea').each(function() {
    if($(this).closest(".tab-pane").hasClass('active')){
        this.style.height = (this.scrollHeight) + 'px';
    }
}).on('input', function () {
    this.style.height = (this.scrollHeight) + 'px';
});

Triggered when a tab is clicked:

$("a.nav-link").click(function(){
    $('.tab-pane').each(function(){
        if($(this).hasClass('active')) {
            $(this).find('textarea').each(function() {
                this.style.height = (this.scrollHeight) + 'px';
            });
        }
    });
});

Apart from that, the web app mainly uses jquery load to load content from another page, I’ve decided to design in this way so that I don’t have to refresh the whole page and only load partial content every time an operation is finished.

function refresh(){
    $("#status").load("{{ url_for('status') }}");
    $("#sentences").load("{{ url_for('sentences') }}");
    $("#gpt2").load("{{ url_for('gpt2') }}", function() {
        $('textarea').each(function() {
            if($(this).closest(".tab-pane").hasClass('active')){
                this.style.height = 'auto';
                this.style.height = (this.scrollHeight) + 'px';
            }
        }).on('input', function() {
            this.style.height = 'auto';
            this.style.height = (this.scrollHeight) + 'px';
        });
    });
}

And here is a sample submit/button click ajax request:

$("#createVideo").click(function () {
    $.ajax({
        url: "{{ url_for('create_base') }}",
        success: function (message) {
            alert(message);
            refresh();
        },
        error: function (response) {
            alert(response.responseText);
        }
    });
});

To modify speaker:

$("#modify").click(function () {
    const data = $('tbody tr').map(function() {
        let obj = [];
        $(this).find('select').each(function() {
            obj.push($(this).val());
        });
        return obj;
    }).get();
    $.ajax({
        type: "POST",
        url: "{{ url_for('modify') }}",
        contentType: "application/json",
        data: JSON.stringify(data),
        success: function (message) {
            alert(message);
            refresh();
        },
        error: function (response) {
            alert(response.responseText);
        }
    });
});

the data is get from the mapping of the table tag, tr specifically. I obtain a value from the select tag inside tr and store it as a list/array. In the ajax, I use JSON.stringify(data) to send the data.

And to enrich the app experience, there’s a preview image function for animating an image, and it changes according to the select box value.

$("#animate").find("select").each(function(){
    let img = $('<img />', {src: "image/" + $(this).val()});
    img.insertAfter($(this));
}).on('change', function(){
    $(this).parent().find("img").attr('src', "image/" + $(this).val());
});

This appends an img tag after the select tag and the src of the img tag is the select’s value.

$("#view").click(function () {
    if (!$(this).parent().has('video').length) {
        let video = $('<video />', {
            src: "{{ url_for('video') }}",
            type: 'video/mp4',
            controls: true
        });
        video.insertAfter($(this));
    } else {
        $(this).parent().find("video").attr('src', "{{ url_for('video') }}");
    }
});

Similar concepts for video preview, but it appends once if it didn’t exist, and replace content if the video tag exists.