简体   繁体   中英

JS: Alphabetizing list of radio buttons by label.text() after appending new radio button from text input

Edit Now the new radio button is sorted correctly into the dropdown menu but only the first one. The new button is simply appended to the last node in all other lists.

I have a dynamic table that allows a user to view details on images they've uploaded. This includes the ability to either create a new album (and move upload to that album) or move an upload to another album they've previously created.

I've done this using radio buttons inside dropdown menus (one for each upload) with a text box where each time a new album is created, a corresponding label and input element is appended to each dropdown list.

界面截图

Here is the order of events I desire:

1.Create new album. Upload is moved to new album. 2. Label and input elements for the new album are appended to each dropdown radio list. 3. Radio list is ordered by label text and displayed to viewer in each dropdown menu.

I know this will involve Javascript or Jquery, I don't mind either as I'm new to JS in general and want to learn. I have tried several sort functions I found on StackOverflow but none of them seem to apply to my unique table with dropdown radio list requirements.

Currently, the list is unsorted once I add a new radio button and the new radio button is only appended to the end of the first dropdown menu in the table.

Here is my HTML:

<div class='album-dropdown-content'>
                        <label class='album-select new-album-select'>New Album
                            <input type='radio' name='new_album_radio'  class='new-album-radio'/>

                            <span class='checkmark'></span>

                            <input type='text' name='new_album' class='new-album-text' id='txt-<?= esc($row->viewkey); ?>'/>

                            <button class='new-album-button' data-viewkey='<?= $row->viewkey; ?>'>Create</button>
                        </label>
                        <div id='album-list'>
                            <?php if (! empty($albums)) {
                                foreach ($albums as $album) { ?>
                                    
                                    <label class='album-select'>
                                        <?= esc($album->album_name); ?>

                                        <i class="fa-solid fa-xmark" data-viewkey='<?= esc($row->viewkey); ?>' data-album='<?= esc($row->album_name); ?>'></i>

                                        <input type='radio' name='album_radio' value='<?= $album->album_name; ?>' class='album-radio' data-viewkey='<?= esc($row->viewkey); ?>'/>
                                        
                                        <span class='checkmark'></span>
                                    </label>
                            <?php }} ?>

                            <div class='added-dropdown-select'>
                                <!-- Javascript generates album radio dropdown list -->
                            </div>
                        </div>
                    </div>

And here is my javascript:

function addNewRadioItem(viewkey, albumName) {
            var containers = document.querySelectorAll('.album-list')

            // Create new album radio in dropdown menu
            var label = document.createElement('label');
            var input = document.createElement('input');
            var span = document.createElement('span');

            label.setAttribute('class', 'album-select');
            label.innerHTML += albumName+' <i class="fa-solid fa-xmark" data-viewkey="'+viewkey+'" data-albumName="'+albumName+'"></i>';

            input.setAttribute('type', 'radio');
            input.setAttribute('name', 'album_radio');
            input.setAttribute('class', 'album-radio');
            input.setAttribute('value', albumName);
            input.setAttribute('data-viewkey', viewkey);
            input.setAttribute('checked', 'checked');
            
            span.setAttribute('class', 'checkmark');

            label.appendChild(input);
            label.appendChild(span);

            //container.appendChild(label);
            $(containers).append(label);
    }

    function sortNewRadio() {
        var albumList = $('#album-list');
        var listItems = albumList.children('label').get();

        listItems.sort(function(a, b) {
            var A = $(a).text().toUpperCase();
            var B = $(b).text().toUpperCase();

            return A.localeCompare(B);
        })

        albumList.empty().append(listItems);
    }

In function sortNewRadio() the console.log(arr) output looks funny, the appended radio button is not the same as the other radio buttons. Here is a screenshot of that.

控制台日志输出的屏幕截图。

I have figured it out! I needed to define a class name for the album lists, then use a for loop to iterate through each list's children nodes to sort.

Here is the final javascript:

<script>
    $(document).ready(function() {
        var csrfName = "<?= csrf_token(); ?>"; 
        var csrfHash = "<?= csrf_hash(); ?>";

        $(document).on('change', 'input[name=album_radio]', function() {
            var album = $('.album-radio:checked').val();
            var viewkey = $(this).data('viewkey');

            $.ajax({
                type: "POST",
                url: "<?= base_url(); ?>/users/members/manage_uploads",
                dataType: "JSON",
                data: {
                    [csrfName]: csrfHash,
                    "album_name": album,
                    "viewkey": viewkey,
                },
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                },
                success: function(data) {
                    var res = data;

                    // Update CSRF hash
                    csrfName = res.csrfName;
                    csrfHash = res.csrfHash;

                    // Add new album name 
                    $('#'+viewkey).html(album);

                    viewkey = '';

                    alert(res.message);
                }
            });
        });

        $('.new-album-button').on('click', function () {
            let viewkey = $(this).attr('data-viewkey');
            let newAlbum = $('#txt-'+viewkey).val();

            // Checks if album name is empty
            if (newAlbum === '') {
                alert('Please enter an album name');
                return false;
            } 

            $.ajax({
                type: "POST",
                url: "<?= base_url(); ?>/users/members/manage_uploads",
                dataType: "JSON",
                data: {
                    [csrfName]: csrfHash,
                    "album_name": newAlbum,
                    "viewkey": viewkey,
                },
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                },
                success: function(data) {
                    var res = data;

                    // Update CSRF hash
                    csrfName = res.csrfName;
                    csrfHash = res.csrfHash;

                    // Display new album name in table
                    $('#'+viewkey).html(newAlbum);

                    // Add new album name to all dropdown radio buttons
                    addNewRadioItem(viewkey, newAlbum);

                    alert(res.message);
                }
            });
        });
    });

        function addNewRadioItem(viewkey, albumName) {
            var containers = document.querySelectorAll('.album-list')

            // Create new album radio in dropdown menu
            var label = document.createElement('label');
            var input = document.createElement('input');
            var span = document.createElement('span');

            label.setAttribute('class', 'album-select');
            label.innerHTML += albumName+' <i class="fa-solid fa-xmark" data-viewkey="'+viewkey+'" data-albumName="'+albumName+'"></i>';

            input.setAttribute('type', 'radio');
            input.setAttribute('name', 'album_radio');
            input.setAttribute('class', 'album-radio');
            input.setAttribute('value', albumName);
            input.setAttribute('data-viewkey', viewkey);
            input.setAttribute('checked', 'checked');
            
            span.setAttribute('class', 'checkmark');

            label.appendChild(input);
            label.appendChild(span);

            //container.appendChild(label);
            $(containers).append(label);

             // Sorts radio options with added album
            sortNewRadio();
    }

    function sortNewRadio() {
        var divList = document.querySelectorAll('.album-list');
        var divArray = [...divList];

        for (const elem of divList){
            var listItems = $(elem).children('label').get();

            listItems.sort(function(a, b) {
                var A = $(a).text().toUpperCase();
                var B = $(b).text().toUpperCase();

                return A.localeCompare(B);
            })

            $(elem).empty().append(listItems);    
        }
    }
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM