Home > other >  Make selected item current
Make selected item current

Time:09-30

EDIT: Full code for the 3 most likely files are found here. https://codepen.io/arcticmedia-ryan/project/editor/ZEQwmN

I am not sure how best to explain this so please let me know if you want more. I am building a chat room app. When a person opens up the main vue, they are presented with a "Room List" - from there they can click enter and join the room. The issue is, when they click join, it opens up the tab for the room but doesnt make it active. I feel like I am just banging my head around a simple problem

There is a prop called "SelectedRoomID" that needs to be updated from "undefined" to the room that is selected from the list.

RoomList.vue

<!-- This example requires Tailwind CSS v2.0  -->
<template>
    <TransitionRoot as="template" :show="isOpen">
        <Dialog as="div" class="fixed z-10 inset-0 overflow-y-auto" @close="$emit('onClose')">
            <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
                <TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0"
                                 enter-to="opacity-100" leave="ease-in duration-300" leave-from="opacity-100"
                                 leave-to="opacity-0">
                    <DialogOverlay class="fixed inset-0 bg-gray-700 bg-opacity-75 transition-opacity"/>
                </TransitionChild>

                <!-- This element is to trick the browser into centering the modal contents. -->
                <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
                <TransitionChild as="template" enter="ease-out duration-300"
                                 enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
                                 enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-300"
                                 leave-from="opacity-100 translate-y-0 sm:scale-100"
                                 leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
                    <div class="inline-block align-bottom bg-black bg-opacity-20 rounded-lg px-6 pt-5 pb-4 text-left overflow-hidden shadow-2xl transform transition-all sm:my-8 sm:align-middle sm:p-6">

                        <div class="sm:flex sm:items-start">
                            <div class="flex flex-col">
                                <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
                                    <div class="align-middle inline-block min-w-full sm:px-4 lg:px-5">
                                        <div class="shadow overflow-hidden border-8 border-gray-800 dark:border-gray-900 sm:rounded-lg">
                                            <table class="min-w-full divide-y divide-gray-800">
                                                <thead class="bg-gray-800 dark:bg-gray-900">
                                                <tr>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Room
                                                    </th>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Description
                                                    </th>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Type
                                                    </th>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Users
                                                    </th>
                                                    <th scope="col" class="relative px-6 py-3">
                                                        <button type="button"
                                                                class="bg-white rounded-md text-gray-400 hover:text-gray-500 "
                                                                @click="$emit('onClose')">
                                                            <div class="hidden sm:block absolute top-0 right-0 pt-4 pr-4">
                                                                <span class="sr-only">Close</span>
                                                                <XIcon class="top-1 right-1 absolute h-6 w-6 text-gray-50 " aria-hidden="true"/>
                                                            </div>
                                                        </button>
                                                        
                                                        <span class="sr-only">Enter</span>
                                                        
                                                    </th>
                                                </tr>
                                                </thead>
                                                <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-300 dark:divide-gray-600">
                                                <tr v-for="room in $store.state.rooms.rooms" :key="room.id">
                                                    <td class="px-6 py-4 whitespace-nowrap">
                                                        <div class="flex items-center">
                                                            <div class="flex-shrink-0 h-10 w-10">
                                                                <img class="h-10 w-10 rounded-full" :src="room.image"
                                                                     alt=""/>
                                                            </div>
                                                            <div class="ml-4">
                                                                <div class="text-md font-medium text-gray-900 dark:text-gray-50">
                                                                    {{ room.name }}
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </td>
                                                    <td class="px-6 py-4 whitespace-nowrap">
                                                        <div class="text-md text-gray-900 dark:text-gray-50">{{ room.description }}</div>
                                                    </td>
                                                    <td class="px-2 py-4 whitespace-nowrap">
                                                        <span class="px-2 inline-flex text-s leading-5 font-medium rounded-full">
                                                            <div v-if="room.is_private === true" class="rounded-full py-1 px-2 bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100">
                                                                        <span>Private</span>
                                                                    </div>
                                                                    <div v-else-if="room.is_private === false" class="rounded-full py-1 px-2 bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
                                                                        <span>Public</span>
                                                                    </div>
                                                                    <div v-else-if="room.is_private === 'true'" class="rounded-full py-1 px-2 bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100">
                                                                        <span>Private</span>
                                                                    </div>
                                                                    <div v-else-if="room.is_private === 'false'" class="rounded-full py-1 px-2 bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
                                                                        <span>Public</span>
                                                                </div>
                                                        </span>
                                                    </td>
                                                    <td class="px-6 py-4 whitespace-nowrap text-center">
                                                        <a class="text-md font-medium text-gray-900 dark:text-gray-50">99</a>
                                                      </td>
                                                    <td class="px-6 py-4 whitespace-nowrap text-right text-md font-medium">
                                                        <div class="flex rounded-full py-2 px-4 bg-indigo-700 hover:bg-indigo-900">
                                                        <a href="#" @click="joinRoom(room)"
                                                           class="text-white">Enter</a>
                                                        </div>
                                                    </td>
                                                </tr>
                                                </tbody>
                                            </table>
                                            <div class="bg-gray-800 dark:bg-gray-900">
                                                <div class="flex justify-end px-4 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                    <span class=" px-2 pt-2 text-xs leading-5 font-semibold rounded-full">
                                                    <a href="#">
                                                    <div class="flex rounded-full py-1 px-2 bg-green-700 text-green-100 hover:bg-green-800">
                                                        <PlusIcon class="h-5 w-5"/><span class="text-sm font-bold pl-0.5">Create Room</span>
                                                    </div>
                                                    </a>
                                                    </span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </TransitionChild>
            </div>
        </Dialog>
    </TransitionRoot>
</template>

<script>
import {Dialog, DialogOverlay, DialogTitle, TransitionChild, TransitionRoot} from '@headlessui/vue'
import {ExclamationIcon, XIcon, PlusIcon} from '@heroicons/vue/outline'
import {types as RoomTypes} from "../../../Store/modules/rooms/rooms.types";

export default {
    components: {
        Dialog,
        DialogOverlay,
        DialogTitle,
        TransitionChild,
        TransitionRoot,
        ExclamationIcon,
        XIcon,
        PlusIcon,
    },
    props: ['rooms', 'selectedRoomId'],
    emits: ['onSelectRoom', 'onLeaveRoom', 'onClose'],
    methods: {
        joinRoom(room) {
            this.$store.dispatch(RoomTypes.JOIN_ROOM, room);
            this.selectedRoomId = this.room;
            this.$emit('onClose');
        }
    },
    props: {
        isOpen: Boolean,
        usersCount: Boolean
    },
}
</script>

Main.vue SNIPPET OF CODE

<section aria-labelledby="primary-heading"
                             class="dark:bg-gray-900 min-w-0 flex-1 h-full flex flex-col overflow-hidden lg:order-last">
                        <room-tabs :selectedRoomId="currentRoom.id" :rooms="joinedRooms"
                                   @onSelectRoom="currentRoom = $event" @onLeaveRoom="leaveRoom($event)"/>
                        <message-container :messages="messages"
                                           class="h-full pb-2 mb-2 pt-0 mt-0 shadow-md overflow-y-auto"/>
                        <input-box
                            :room="currentRoom"
                            v-on:messagesent="getMessages"
                            class="dark:bg-gray-800 px-6 pb-6 pt-4 dark:border-t-2 dark:border-gray-600 bottom-0 sticky"
                        />
                    </section>

I know its inside methods: joinRoom that needs to change and I know its wrong where this.selectedRoomId is - I just dont know what I need to change/fix to make it turn the selected room into the active room when you click join.

Any help would be very much appreciated!

CodePudding user response:

Try to emit selected room from joinRoom method:

this.$emit('roomSelected', room);

then in Main.vue listen to event:

<room-tabs @roomSelected="roomSelected"

and update id:

methods: {
  roomSelected(room){
    this.currentRoom.id = room.id
  }
}

CodePudding user response:

I would use mapState to effectively watch the value in the store that is being updated by this.$store.dispatch(RoomTypes.JOIN_ROOM, room);

So in a component that needs to know this value:

 computed: {
    ...mapState(['STORE_NAME', 'STORE_VALUE']),
  },

and then you should be able to use this.STORE_VALUE as a dynamically updated value

  • Related