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
$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>
javascript vue.js
$endgroup$
add a comment |
$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>
javascript vue.js
$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
add a comment |
$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>
javascript vue.js
$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
javascript vue.js
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
add a comment |
$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
add a comment |
1 Answer
1
active
oldest
votes
$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!
$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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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!
$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
add a comment |
$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!
$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
add a comment |
$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!
$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!
answered Mar 5 at 22:40
Simon Forsberg♦Simon 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
add a comment |
$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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$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