Showing events on a multi room schedulerMultiple .on() eventsStructuring Events in JavaScriptRealtime chat...

Grey hair or white hair

What wound would be of little consequence to a biped but terrible for a quadruped?

Should I take out a loan for a friend to invest on my behalf?

Finding algorithms of QGIS commands?

Unreachable code, but reachable with exception

What to do when during a meeting client people start to fight (even physically) with each others?

How to create a hard link to an inode (ext4)?

What Happens when Passenger Refuses to Fly Boeing 737 Max?

How to clip a background including nodes according to an arbitrary shape?

Making a sword in the stone, in a medieval world without magic

How do you like my writing?

How to pass a string to a command that expects a file?

Space in array system equations

Examples of a statistic that is not independent of sample's distribution?

Offered promotion but I'm leaving. Should I tell?

Force user to remove USB token

Is Gradient Descent central to every optimizer?

Why is there a voltage between the mains ground and my radiator?

How to edit the properties of a page programmatically?

Why does Captain Marvel assume the people on this planet know this?

Low budget alien movie about the Earth being cooked

Good for you! in Russian

Do I really need to have a scientific explanation for my premise?

How can The Temple of Elementary Evil reliably protect itself against kinetic bombardment?



Showing events on a multi room scheduler


Multiple .on() eventsStructuring Events in JavaScriptRealtime chat roomConditionally showing some iconsBigBrother - A chat room watcherMultiple jQuery onClick eventsJavaScript table not showingAirport schedulerPopup classes hierarchy designCreating CAPTCHA in ColdFusion then showing image in Vue.js













5












$begingroup$


I write a web app that shows events on a multi room scheduler. I use VueJS for the first time on a real project.



Here, I loop through the events array every room column (two nested v-for). In jQuery I need to loop once through this array to fill all columns at once.



My question: is there any other more efficient way to write this code that fills rooms divs with events in Vue?






var vm = new Vue({
el: '#app',
data: {
rooms: [
{id: 1, title: 'Room 1' },
{id: 2, title: 'Room 2' }
],
events: [
{ id: 1, start: 230, duration: 30, title: 'Event 1', room_id: 2},
{ id: 2, start: 400, duration: 45, title: 'Event 2', room_id: 1}
]
}
})

.agenda-wrapper { max-width: 100%; overflow-x: scroll; }

.agenda { padding-top: 50px; overflow: hidden; }

.room {
width:300px;
height:1170px;
padding: 0 10px;
margin-left: 5px;
background:#ECECEC;
position:relative;
float: left;
}

.room span {
position: absolute;
top: -20px;
height: 10px;
text-align: center;
width: 300px;
font-weight: bold;
}

.event {
display: block;
background:#fff;
color:#4B6EA8;
border:1px solid #ccc;
border-left:4px solid #c4183c;
position:absolute;
padding:0 10px;
font-weight:bold;
font-size:13px;
border-radius: 5px;
width: 280px;
}

<div class="agenda-wrapper" id="app">
<div class="agenda" :style="{ width: (rooms.length * 350) + 'px' }">
<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>












share|improve this question











$endgroup$












  • $begingroup$
    Hi and welcome to Code Review! I'm planning on answering your question later, but just out of curiousity: How would you do it in jQuery?
    $endgroup$
    – Simon Forsberg
    Mar 5 at 8:44










  • $begingroup$
    Hi, thank you for your reply! I think it would be something like that: '$.each(events, function(event){ var el = $("<div></div>").addClass("event").css({ "height": event.duration + "px", "top": event.start + "px" }).text(event.title); $('.room').data('place', event.place_id).append(el); });'
    $endgroup$
    – Alex
    Mar 5 at 9:02












  • $begingroup$
    I also think that maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }
    $endgroup$
    – Alex
    Mar 5 at 9:03












  • $begingroup$
    Yes, backend is Laravel app. It has two models: Room and Event. Event belongsTo Room.
    $endgroup$
    – Alex
    Mar 5 at 13:34
















5












$begingroup$


I write a web app that shows events on a multi room scheduler. I use VueJS for the first time on a real project.



Here, I loop through the events array every room column (two nested v-for). In jQuery I need to loop once through this array to fill all columns at once.



My question: is there any other more efficient way to write this code that fills rooms divs with events in Vue?






var vm = new Vue({
el: '#app',
data: {
rooms: [
{id: 1, title: 'Room 1' },
{id: 2, title: 'Room 2' }
],
events: [
{ id: 1, start: 230, duration: 30, title: 'Event 1', room_id: 2},
{ id: 2, start: 400, duration: 45, title: 'Event 2', room_id: 1}
]
}
})

.agenda-wrapper { max-width: 100%; overflow-x: scroll; }

.agenda { padding-top: 50px; overflow: hidden; }

.room {
width:300px;
height:1170px;
padding: 0 10px;
margin-left: 5px;
background:#ECECEC;
position:relative;
float: left;
}

.room span {
position: absolute;
top: -20px;
height: 10px;
text-align: center;
width: 300px;
font-weight: bold;
}

.event {
display: block;
background:#fff;
color:#4B6EA8;
border:1px solid #ccc;
border-left:4px solid #c4183c;
position:absolute;
padding:0 10px;
font-weight:bold;
font-size:13px;
border-radius: 5px;
width: 280px;
}

<div class="agenda-wrapper" id="app">
<div class="agenda" :style="{ width: (rooms.length * 350) + 'px' }">
<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>












share|improve this question











$endgroup$












  • $begingroup$
    Hi and welcome to Code Review! I'm planning on answering your question later, but just out of curiousity: How would you do it in jQuery?
    $endgroup$
    – Simon Forsberg
    Mar 5 at 8:44










  • $begingroup$
    Hi, thank you for your reply! I think it would be something like that: '$.each(events, function(event){ var el = $("<div></div>").addClass("event").css({ "height": event.duration + "px", "top": event.start + "px" }).text(event.title); $('.room').data('place', event.place_id).append(el); });'
    $endgroup$
    – Alex
    Mar 5 at 9:02












  • $begingroup$
    I also think that maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }
    $endgroup$
    – Alex
    Mar 5 at 9:03












  • $begingroup$
    Yes, backend is Laravel app. It has two models: Room and Event. Event belongsTo Room.
    $endgroup$
    – Alex
    Mar 5 at 13:34














5












5








5





$begingroup$


I write a web app that shows events on a multi room scheduler. I use VueJS for the first time on a real project.



Here, I loop through the events array every room column (two nested v-for). In jQuery I need to loop once through this array to fill all columns at once.



My question: is there any other more efficient way to write this code that fills rooms divs with events in Vue?






var vm = new Vue({
el: '#app',
data: {
rooms: [
{id: 1, title: 'Room 1' },
{id: 2, title: 'Room 2' }
],
events: [
{ id: 1, start: 230, duration: 30, title: 'Event 1', room_id: 2},
{ id: 2, start: 400, duration: 45, title: 'Event 2', room_id: 1}
]
}
})

.agenda-wrapper { max-width: 100%; overflow-x: scroll; }

.agenda { padding-top: 50px; overflow: hidden; }

.room {
width:300px;
height:1170px;
padding: 0 10px;
margin-left: 5px;
background:#ECECEC;
position:relative;
float: left;
}

.room span {
position: absolute;
top: -20px;
height: 10px;
text-align: center;
width: 300px;
font-weight: bold;
}

.event {
display: block;
background:#fff;
color:#4B6EA8;
border:1px solid #ccc;
border-left:4px solid #c4183c;
position:absolute;
padding:0 10px;
font-weight:bold;
font-size:13px;
border-radius: 5px;
width: 280px;
}

<div class="agenda-wrapper" id="app">
<div class="agenda" :style="{ width: (rooms.length * 350) + 'px' }">
<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>












share|improve this question











$endgroup$




I write a web app that shows events on a multi room scheduler. I use VueJS for the first time on a real project.



Here, I loop through the events array every room column (two nested v-for). In jQuery I need to loop once through this array to fill all columns at once.



My question: is there any other more efficient way to write this code that fills rooms divs with events in Vue?






var vm = new Vue({
el: '#app',
data: {
rooms: [
{id: 1, title: 'Room 1' },
{id: 2, title: 'Room 2' }
],
events: [
{ id: 1, start: 230, duration: 30, title: 'Event 1', room_id: 2},
{ id: 2, start: 400, duration: 45, title: 'Event 2', room_id: 1}
]
}
})

.agenda-wrapper { max-width: 100%; overflow-x: scroll; }

.agenda { padding-top: 50px; overflow: hidden; }

.room {
width:300px;
height:1170px;
padding: 0 10px;
margin-left: 5px;
background:#ECECEC;
position:relative;
float: left;
}

.room span {
position: absolute;
top: -20px;
height: 10px;
text-align: center;
width: 300px;
font-weight: bold;
}

.event {
display: block;
background:#fff;
color:#4B6EA8;
border:1px solid #ccc;
border-left:4px solid #c4183c;
position:absolute;
padding:0 10px;
font-weight:bold;
font-size:13px;
border-radius: 5px;
width: 280px;
}

<div class="agenda-wrapper" id="app">
<div class="agenda" :style="{ width: (rooms.length * 350) + 'px' }">
<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>








var vm = new Vue({
el: '#app',
data: {
rooms: [
{id: 1, title: 'Room 1' },
{id: 2, title: 'Room 2' }
],
events: [
{ id: 1, start: 230, duration: 30, title: 'Event 1', room_id: 2},
{ id: 2, start: 400, duration: 45, title: 'Event 2', room_id: 1}
]
}
})

.agenda-wrapper { max-width: 100%; overflow-x: scroll; }

.agenda { padding-top: 50px; overflow: hidden; }

.room {
width:300px;
height:1170px;
padding: 0 10px;
margin-left: 5px;
background:#ECECEC;
position:relative;
float: left;
}

.room span {
position: absolute;
top: -20px;
height: 10px;
text-align: center;
width: 300px;
font-weight: bold;
}

.event {
display: block;
background:#fff;
color:#4B6EA8;
border:1px solid #ccc;
border-left:4px solid #c4183c;
position:absolute;
padding:0 10px;
font-weight:bold;
font-size:13px;
border-radius: 5px;
width: 280px;
}

<div class="agenda-wrapper" id="app">
<div class="agenda" :style="{ width: (rooms.length * 350) + 'px' }">
<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>





var vm = new Vue({
el: '#app',
data: {
rooms: [
{id: 1, title: 'Room 1' },
{id: 2, title: 'Room 2' }
],
events: [
{ id: 1, start: 230, duration: 30, title: 'Event 1', room_id: 2},
{ id: 2, start: 400, duration: 45, title: 'Event 2', room_id: 1}
]
}
})

.agenda-wrapper { max-width: 100%; overflow-x: scroll; }

.agenda { padding-top: 50px; overflow: hidden; }

.room {
width:300px;
height:1170px;
padding: 0 10px;
margin-left: 5px;
background:#ECECEC;
position:relative;
float: left;
}

.room span {
position: absolute;
top: -20px;
height: 10px;
text-align: center;
width: 300px;
font-weight: bold;
}

.event {
display: block;
background:#fff;
color:#4B6EA8;
border:1px solid #ccc;
border-left:4px solid #c4183c;
position:absolute;
padding:0 10px;
font-weight:bold;
font-size:13px;
border-radius: 5px;
width: 280px;
}

<div class="agenda-wrapper" id="app">
<div class="agenda" :style="{ width: (rooms.length * 350) + 'px' }">
<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>






javascript vue.js






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 9 mins ago









Simon Forsberg

48.7k7130286




48.7k7130286










asked Mar 5 at 8:26









AlexAlex

261




261












  • $begingroup$
    Hi and welcome to Code Review! I'm planning on answering your question later, but just out of curiousity: How would you do it in jQuery?
    $endgroup$
    – Simon Forsberg
    Mar 5 at 8:44










  • $begingroup$
    Hi, thank you for your reply! I think it would be something like that: '$.each(events, function(event){ var el = $("<div></div>").addClass("event").css({ "height": event.duration + "px", "top": event.start + "px" }).text(event.title); $('.room').data('place', event.place_id).append(el); });'
    $endgroup$
    – Alex
    Mar 5 at 9:02












  • $begingroup$
    I also think that maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }
    $endgroup$
    – Alex
    Mar 5 at 9:03












  • $begingroup$
    Yes, backend is Laravel app. It has two models: Room and Event. Event belongsTo Room.
    $endgroup$
    – Alex
    Mar 5 at 13:34


















  • $begingroup$
    Hi and welcome to Code Review! I'm planning on answering your question later, but just out of curiousity: How would you do it in jQuery?
    $endgroup$
    – Simon Forsberg
    Mar 5 at 8:44










  • $begingroup$
    Hi, thank you for your reply! I think it would be something like that: '$.each(events, function(event){ var el = $("<div></div>").addClass("event").css({ "height": event.duration + "px", "top": event.start + "px" }).text(event.title); $('.room').data('place', event.place_id).append(el); });'
    $endgroup$
    – Alex
    Mar 5 at 9:02












  • $begingroup$
    I also think that maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }
    $endgroup$
    – Alex
    Mar 5 at 9:03












  • $begingroup$
    Yes, backend is Laravel app. It has two models: Room and Event. Event belongsTo Room.
    $endgroup$
    – Alex
    Mar 5 at 13:34
















$begingroup$
Hi and welcome to Code Review! I'm planning on answering your question later, but just out of curiousity: How would you do it in jQuery?
$endgroup$
– Simon Forsberg
Mar 5 at 8:44




$begingroup$
Hi and welcome to Code Review! I'm planning on answering your question later, but just out of curiousity: How would you do it in jQuery?
$endgroup$
– Simon Forsberg
Mar 5 at 8:44












$begingroup$
Hi, thank you for your reply! I think it would be something like that: '$.each(events, function(event){ var el = $("<div></div>").addClass("event").css({ "height": event.duration + "px", "top": event.start + "px" }).text(event.title); $('.room').data('place', event.place_id).append(el); });'
$endgroup$
– Alex
Mar 5 at 9:02






$begingroup$
Hi, thank you for your reply! I think it would be something like that: '$.each(events, function(event){ var el = $("<div></div>").addClass("event").css({ "height": event.duration + "px", "top": event.start + "px" }).text(event.title); $('.room').data('place', event.place_id).append(el); });'
$endgroup$
– Alex
Mar 5 at 9:02














$begingroup$
I also think that maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }
$endgroup$
– Alex
Mar 5 at 9:03






$begingroup$
I also think that maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }
$endgroup$
– Alex
Mar 5 at 9:03














$begingroup$
Yes, backend is Laravel app. It has two models: Room and Event. Event belongsTo Room.
$endgroup$
– Alex
Mar 5 at 13:34




$begingroup$
Yes, backend is Laravel app. It has two models: Room and Event. Event belongsTo Room.
$endgroup$
– Alex
Mar 5 at 13:34










1 Answer
1






active

oldest

votes


















3












$begingroup$

I asked you how you would do it in jQuery and you said that you would do something like:




$.each(events, function(event){
var el = $("<div></div>")
.addClass("event")
.css({ "height": event.duration + "px", "top": event.start + "px" })
.text(event.title);
$('.room').data('place', event.place_id).append(el);
});



And sure, this would only loop through the events array once. But what happens in every iteration? It does a jQuery search for $('.room').data('place', event.place_id), which is not a constant-time lookup operation, so this approach might be slower than what you think it is.





Now, for your Vue approach. You said:




maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }




And yes, I agree with this. Putting the events inside your rooms makes much more sense.



As for your Vue template, overall the code looks fine. I'm not a CSS expert so I don't know if there's something you can improve there, but there probably is. Maybe consider using CSS Grids, where each room could be one column, and time-slots could be rows? The current approach of having 1px = 1 minute seems a bit unnatural to me.



As for this part:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>


The only thing I would change is to put v-for and v-if before your :style-binding, as they are more important to be aware about, this is mostly my personal opinion though.



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in events"
v-if="event.room_id === room.id"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


It would be nicer if your events would be inside the rooms, as then you could write:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in room.events"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


I would recommend in the future to use a Room component and a RoomEvent component so that you could write:



<Room v-for="room in rooms" :key="room.id" />


And the room-component:



<div class="room">
<span>{{ room.title }}</span>
<RoomEvent v-for="event in room.events" />
</div>


I think that the <h5>{{ event.title }}</h5> belongs inside the RoomEvent





Overall a nice job!






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you so much for such a great review! I rewrote backend as I mentioned. Now the code is a bit faster. As for CSS, I will look at CSS Grids one more time, but I'm afraid it's more complicated and less supportive by old browsers way. Anyway, thanks for your advice!
    $endgroup$
    – Alex
    Mar 7 at 7:22










  • $begingroup$
    Another small question: I have some plugins that need jQuery. Is it a good idea to use both jQuery (UI components like Select2) and Vue in same code?
    $endgroup$
    – Alex
    Mar 7 at 7:24










  • $begingroup$
    @Alex Yes unfortunately CSS Grids are not supported by older browsers. Regarding jQuery: I have never used it together with Vue myself but I would recommend to try to get rid of jQuery. There is probably Vue alternatives that you can use instead, if you are looking for UI-components then I can recommend Vuetify for example.
    $endgroup$
    – Simon Forsberg
    Mar 7 at 12:05










  • $begingroup$
    Thank you so much!
    $endgroup$
    – Alex
    Mar 7 at 15:02











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214749%2fshowing-events-on-a-multi-room-scheduler%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3












$begingroup$

I asked you how you would do it in jQuery and you said that you would do something like:




$.each(events, function(event){
var el = $("<div></div>")
.addClass("event")
.css({ "height": event.duration + "px", "top": event.start + "px" })
.text(event.title);
$('.room').data('place', event.place_id).append(el);
});



And sure, this would only loop through the events array once. But what happens in every iteration? It does a jQuery search for $('.room').data('place', event.place_id), which is not a constant-time lookup operation, so this approach might be slower than what you think it is.





Now, for your Vue approach. You said:




maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }




And yes, I agree with this. Putting the events inside your rooms makes much more sense.



As for your Vue template, overall the code looks fine. I'm not a CSS expert so I don't know if there's something you can improve there, but there probably is. Maybe consider using CSS Grids, where each room could be one column, and time-slots could be rows? The current approach of having 1px = 1 minute seems a bit unnatural to me.



As for this part:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>


The only thing I would change is to put v-for and v-if before your :style-binding, as they are more important to be aware about, this is mostly my personal opinion though.



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in events"
v-if="event.room_id === room.id"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


It would be nicer if your events would be inside the rooms, as then you could write:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in room.events"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


I would recommend in the future to use a Room component and a RoomEvent component so that you could write:



<Room v-for="room in rooms" :key="room.id" />


And the room-component:



<div class="room">
<span>{{ room.title }}</span>
<RoomEvent v-for="event in room.events" />
</div>


I think that the <h5>{{ event.title }}</h5> belongs inside the RoomEvent





Overall a nice job!






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you so much for such a great review! I rewrote backend as I mentioned. Now the code is a bit faster. As for CSS, I will look at CSS Grids one more time, but I'm afraid it's more complicated and less supportive by old browsers way. Anyway, thanks for your advice!
    $endgroup$
    – Alex
    Mar 7 at 7:22










  • $begingroup$
    Another small question: I have some plugins that need jQuery. Is it a good idea to use both jQuery (UI components like Select2) and Vue in same code?
    $endgroup$
    – Alex
    Mar 7 at 7:24










  • $begingroup$
    @Alex Yes unfortunately CSS Grids are not supported by older browsers. Regarding jQuery: I have never used it together with Vue myself but I would recommend to try to get rid of jQuery. There is probably Vue alternatives that you can use instead, if you are looking for UI-components then I can recommend Vuetify for example.
    $endgroup$
    – Simon Forsberg
    Mar 7 at 12:05










  • $begingroup$
    Thank you so much!
    $endgroup$
    – Alex
    Mar 7 at 15:02
















3












$begingroup$

I asked you how you would do it in jQuery and you said that you would do something like:




$.each(events, function(event){
var el = $("<div></div>")
.addClass("event")
.css({ "height": event.duration + "px", "top": event.start + "px" })
.text(event.title);
$('.room').data('place', event.place_id).append(el);
});



And sure, this would only loop through the events array once. But what happens in every iteration? It does a jQuery search for $('.room').data('place', event.place_id), which is not a constant-time lookup operation, so this approach might be slower than what you think it is.





Now, for your Vue approach. You said:




maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }




And yes, I agree with this. Putting the events inside your rooms makes much more sense.



As for your Vue template, overall the code looks fine. I'm not a CSS expert so I don't know if there's something you can improve there, but there probably is. Maybe consider using CSS Grids, where each room could be one column, and time-slots could be rows? The current approach of having 1px = 1 minute seems a bit unnatural to me.



As for this part:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>


The only thing I would change is to put v-for and v-if before your :style-binding, as they are more important to be aware about, this is mostly my personal opinion though.



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in events"
v-if="event.room_id === room.id"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


It would be nicer if your events would be inside the rooms, as then you could write:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in room.events"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


I would recommend in the future to use a Room component and a RoomEvent component so that you could write:



<Room v-for="room in rooms" :key="room.id" />


And the room-component:



<div class="room">
<span>{{ room.title }}</span>
<RoomEvent v-for="event in room.events" />
</div>


I think that the <h5>{{ event.title }}</h5> belongs inside the RoomEvent





Overall a nice job!






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you so much for such a great review! I rewrote backend as I mentioned. Now the code is a bit faster. As for CSS, I will look at CSS Grids one more time, but I'm afraid it's more complicated and less supportive by old browsers way. Anyway, thanks for your advice!
    $endgroup$
    – Alex
    Mar 7 at 7:22










  • $begingroup$
    Another small question: I have some plugins that need jQuery. Is it a good idea to use both jQuery (UI components like Select2) and Vue in same code?
    $endgroup$
    – Alex
    Mar 7 at 7:24










  • $begingroup$
    @Alex Yes unfortunately CSS Grids are not supported by older browsers. Regarding jQuery: I have never used it together with Vue myself but I would recommend to try to get rid of jQuery. There is probably Vue alternatives that you can use instead, if you are looking for UI-components then I can recommend Vuetify for example.
    $endgroup$
    – Simon Forsberg
    Mar 7 at 12:05










  • $begingroup$
    Thank you so much!
    $endgroup$
    – Alex
    Mar 7 at 15:02














3












3








3





$begingroup$

I asked you how you would do it in jQuery and you said that you would do something like:




$.each(events, function(event){
var el = $("<div></div>")
.addClass("event")
.css({ "height": event.duration + "px", "top": event.start + "px" })
.text(event.title);
$('.room').data('place', event.place_id).append(el);
});



And sure, this would only loop through the events array once. But what happens in every iteration? It does a jQuery search for $('.room').data('place', event.place_id), which is not a constant-time lookup operation, so this approach might be slower than what you think it is.





Now, for your Vue approach. You said:




maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }




And yes, I agree with this. Putting the events inside your rooms makes much more sense.



As for your Vue template, overall the code looks fine. I'm not a CSS expert so I don't know if there's something you can improve there, but there probably is. Maybe consider using CSS Grids, where each room could be one column, and time-slots could be rows? The current approach of having 1px = 1 minute seems a bit unnatural to me.



As for this part:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>


The only thing I would change is to put v-for and v-if before your :style-binding, as they are more important to be aware about, this is mostly my personal opinion though.



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in events"
v-if="event.room_id === room.id"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


It would be nicer if your events would be inside the rooms, as then you could write:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in room.events"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


I would recommend in the future to use a Room component and a RoomEvent component so that you could write:



<Room v-for="room in rooms" :key="room.id" />


And the room-component:



<div class="room">
<span>{{ room.title }}</span>
<RoomEvent v-for="event in room.events" />
</div>


I think that the <h5>{{ event.title }}</h5> belongs inside the RoomEvent





Overall a nice job!






share|improve this answer









$endgroup$



I asked you how you would do it in jQuery and you said that you would do something like:




$.each(events, function(event){
var el = $("<div></div>")
.addClass("event")
.css({ "height": event.duration + "px", "top": event.start + "px" })
.text(event.title);
$('.room').data('place', event.place_id).append(el);
});



And sure, this would only loop through the events array once. But what happens in every iteration? It does a jQuery search for $('.room').data('place', event.place_id), which is not a constant-time lookup operation, so this approach might be slower than what you think it is.





Now, for your Vue approach. You said:




maybe I need to do it on backend to make a rooms array look like that: { id: 1, title: 'Room 1', events: [{ id: 1, title: 'Event 1', start: 90, duration: 30 }] }




And yes, I agree with this. Putting the events inside your rooms makes much more sense.



As for your Vue template, overall the code looks fine. I'm not a CSS expert so I don't know if there's something you can improve there, but there probably is. Maybe consider using CSS Grids, where each room could be one column, and time-slots could be rows? The current approach of having 1px = 1 minute seems a bit unnatural to me.



As for this part:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
v-for="event in events"
v-if="event.room_id === room.id">
<h5>{{ event.title }}</h5>
</div>


The only thing I would change is to put v-for and v-if before your :style-binding, as they are more important to be aware about, this is mostly my personal opinion though.



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in events"
v-if="event.room_id === room.id"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


It would be nicer if your events would be inside the rooms, as then you could write:



<div class="room" v-for="room in rooms" :key="room.id">
<span>{{ room.title }}</span>
<div class="event"
v-for="event in room.events"
:style="{ top: event.start + 'px', height: event.duration + 'px'}"
>
<h5>{{ event.title }}</h5>
</div>


I would recommend in the future to use a Room component and a RoomEvent component so that you could write:



<Room v-for="room in rooms" :key="room.id" />


And the room-component:



<div class="room">
<span>{{ room.title }}</span>
<RoomEvent v-for="event in room.events" />
</div>


I think that the <h5>{{ event.title }}</h5> belongs inside the RoomEvent





Overall a nice job!







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 5 at 22:40









Simon ForsbergSimon Forsberg

48.7k7130286




48.7k7130286












  • $begingroup$
    Thank you so much for such a great review! I rewrote backend as I mentioned. Now the code is a bit faster. As for CSS, I will look at CSS Grids one more time, but I'm afraid it's more complicated and less supportive by old browsers way. Anyway, thanks for your advice!
    $endgroup$
    – Alex
    Mar 7 at 7:22










  • $begingroup$
    Another small question: I have some plugins that need jQuery. Is it a good idea to use both jQuery (UI components like Select2) and Vue in same code?
    $endgroup$
    – Alex
    Mar 7 at 7:24










  • $begingroup$
    @Alex Yes unfortunately CSS Grids are not supported by older browsers. Regarding jQuery: I have never used it together with Vue myself but I would recommend to try to get rid of jQuery. There is probably Vue alternatives that you can use instead, if you are looking for UI-components then I can recommend Vuetify for example.
    $endgroup$
    – Simon Forsberg
    Mar 7 at 12:05










  • $begingroup$
    Thank you so much!
    $endgroup$
    – Alex
    Mar 7 at 15:02


















  • $begingroup$
    Thank you so much for such a great review! I rewrote backend as I mentioned. Now the code is a bit faster. As for CSS, I will look at CSS Grids one more time, but I'm afraid it's more complicated and less supportive by old browsers way. Anyway, thanks for your advice!
    $endgroup$
    – Alex
    Mar 7 at 7:22










  • $begingroup$
    Another small question: I have some plugins that need jQuery. Is it a good idea to use both jQuery (UI components like Select2) and Vue in same code?
    $endgroup$
    – Alex
    Mar 7 at 7:24










  • $begingroup$
    @Alex Yes unfortunately CSS Grids are not supported by older browsers. Regarding jQuery: I have never used it together with Vue myself but I would recommend to try to get rid of jQuery. There is probably Vue alternatives that you can use instead, if you are looking for UI-components then I can recommend Vuetify for example.
    $endgroup$
    – Simon Forsberg
    Mar 7 at 12:05










  • $begingroup$
    Thank you so much!
    $endgroup$
    – Alex
    Mar 7 at 15:02
















$begingroup$
Thank you so much for such a great review! I rewrote backend as I mentioned. Now the code is a bit faster. As for CSS, I will look at CSS Grids one more time, but I'm afraid it's more complicated and less supportive by old browsers way. Anyway, thanks for your advice!
$endgroup$
– Alex
Mar 7 at 7:22




$begingroup$
Thank you so much for such a great review! I rewrote backend as I mentioned. Now the code is a bit faster. As for CSS, I will look at CSS Grids one more time, but I'm afraid it's more complicated and less supportive by old browsers way. Anyway, thanks for your advice!
$endgroup$
– Alex
Mar 7 at 7:22












$begingroup$
Another small question: I have some plugins that need jQuery. Is it a good idea to use both jQuery (UI components like Select2) and Vue in same code?
$endgroup$
– Alex
Mar 7 at 7:24




$begingroup$
Another small question: I have some plugins that need jQuery. Is it a good idea to use both jQuery (UI components like Select2) and Vue in same code?
$endgroup$
– Alex
Mar 7 at 7:24












$begingroup$
@Alex Yes unfortunately CSS Grids are not supported by older browsers. Regarding jQuery: I have never used it together with Vue myself but I would recommend to try to get rid of jQuery. There is probably Vue alternatives that you can use instead, if you are looking for UI-components then I can recommend Vuetify for example.
$endgroup$
– Simon Forsberg
Mar 7 at 12:05




$begingroup$
@Alex Yes unfortunately CSS Grids are not supported by older browsers. Regarding jQuery: I have never used it together with Vue myself but I would recommend to try to get rid of jQuery. There is probably Vue alternatives that you can use instead, if you are looking for UI-components then I can recommend Vuetify for example.
$endgroup$
– Simon Forsberg
Mar 7 at 12:05












$begingroup$
Thank you so much!
$endgroup$
– Alex
Mar 7 at 15:02




$begingroup$
Thank you so much!
$endgroup$
– Alex
Mar 7 at 15:02


















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214749%2fshowing-events-on-a-multi-room-scheduler%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...