Create A Real-World Todo Application In Svelte #19 - Custom right-click menus & stores

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
yo yo yo guys and welcome back to the channel hope you guys are doing fantastic as usual and today we're going to be continuing on with the to do application just like usual and I feel like we have actually implemented a lot of the functionality that I had imagined in the first place for a to-do application of course it doesn't look amazing we can always style it into Oblivion also add features into Oblivion but I'm kind of running out of features to add I don't have a lot of ideas of what to add in the upcoming episodes it's all a bit subjective as well on what kind of features you want in your to-do application so if you have some great ideas of what you would like to see if you have some super cool special function that you want to add feel free to comment and let me know we also have some cleaning up to do of course with accessibility and stuff like that and I feel like we should probably you know handle that in the upcoming videos as well but what I'm trying to say is that there is not a lot more functionality to add I feel like you know we could probably you know release this application I feel like this is definitely a minimum viable product but of course not every single application needs to be released you know it can also be used for your own personal use if you don't really have that unique selling point then I mean there are like a million to do applications out there so I'm just trying to be real here that maybe there's not a super large Market but of course if you have some amazing functionalities that no one else has thought of or if you're gonna you know sell it Dirt Cheap or if you're a real entrepreneur perhaps you have some amazing ideas on how to sell your product but what I'm trying to say is that there's not a lot of more functionalities that I'm looking to implement I feel like which also of course Venture a bit into the server side of things perhaps we should have a look at svelt kit and other more full stack Solutions where we can actually Implement stuff on the server as well so we can have a server a web server running so perhaps we can use it for store words but also for other functionalities such as authentication and stuff like that I feel like looking at sveld kit is of course really relevant now since we're doing a lot of swelt and so kit is also quite awesome so everything that is felt is awesome of course there are a lot of other choices out there as well so we can have a look at some other programming languages perhaps something like golang I've been looking at a bit and perhaps PHP we can look at C sharp if you have some really good idea in mind feel free to comment if you have some back-end framework that you would like to see if you comment that as well it's always nice to learn new things learn new technologies because chances are you're gonna find something that you love just like I love a svelte you can also find something for the back end to use that you will love and appreciate working with so so it's important to not get stuck with one back-end language that you feel comfortable with but perhaps not completely happy with so there's a lot of choices out there and they all have their you know advantages and this other advantages so it's always good to have a bit of a check you know keep yourself updated especially if you have been programming for a longer time it's always good to know get out there and see what's new and you know try out new things and perhaps it will make you a better programmer I feel like there's a lot to take from these new Frameworks everyone has some cool idea you can take bits and pieces from different Frameworks and apply it to your own ideas but for this episode I feel like we should look a bit at right clicking stuff so I feel like that's a nice way to make your app stand out a bit more when you have right click it makes your app feel like it's more native like you're actually in an operating system or like a normal you know native application on your computer so if you can handle this right click and actually show a menu that you created yourself I feel like that would be quite nice I feel like would be nice for this Society bar here in particular so you could do some like clicking here you know you have this native Firefox really ugly unuseful context menu currently and wouldn't it be quite nice if we could have a custom menu here so you can do something like delete or perhaps rename if you if you don't want to you know click in and rename it here we can do something cool you know the real problem with this I really wanted to put the rename functionality here as well but we couldn't do that since we need to be able to click you know the text here without it going completely bananas so it would be nice for him to have like a right click here that we can click and we click like rename and then we can actually start renaming it and like automatically focusing on that text or something like that if I feel like that would be quite nice so something like looking at custom context menus I've actually never done this before so why not learn to gather that's what it's all about on this channel but I have some ideas on how perhaps it could be implemented but maybe I'm completely wrong so let's start googling that's how we do it on this practical coding channel so if I search for something like custom context menu JavaScript ability where we can find here so how to create a custom right click menu with JavaScript let's have a look at this one and of course it's premium and that's quite a shame let's find something else on the custom right click context menu in JavaScript let's see here we have some HTML code so this is what I thought you would have some HTML code and perhaps you do something like you know position absolute or position fixed or something like that and then you can now position it at where the user clicked and then you just you know disable the normal context menu that is at least how I thought it was implemented so so let's see if it's somewhere along that way or if I'm completely wrong about that so we have some visibility hidden then we have position fixed and then I guess we can handle context menu so we add an event listener to context menu and touch start all right now we get the mouse position we get some weird menu width and height okay we're doing loads of stuff here really complicated I think we can actually handle this a bit nicer I feel like they have been a bit verbose here perhaps but perhaps it's about being responsive and stuff like that so let's see here yeah so here they set that context menu style top I don't feel like we need to change the Border radius but other than that all they do you know is prevent the default and that's what I'm trying to say here just I will listen to this context menu event this context menu event is called whenever you right click on something in the browser and then we can simply use prevent default to prevent you know the default action the default action here is actually you know to show this native context menu you know this inspect element take screenshot copy whatever it said you know and then we just prevent that from happening and then we just draw and add our own custom context menu with a help of a you know a normal HTML element to have a look at some other Alternatives just to get a better feel for how it's done normally you know so yeah this is exactly what I want we have the menu items I guess this is a library then perhaps CSS script all right then we have a context menu okay this seems quite nice but I don't I don't like this kind of website so let's skip that one custom right click context menu JavaScript your tutorial context menu JavaScript yeah exactly the same code so search for right click menu JavaScript so add customer right click menu to web page um yeah so you try to open it you the same thing here really we're doing prevent default and then we're on our own when it comes to you know creating this actual menu that we are going to show of course that's both a pro and a con because you know we have full control over this but of course it's quite cumbersome to know create our own divider and start styling it and position fixed but of course we also get a bit more control over we can completely style it how we want you know so there's both pros and cons and maybe this is not actually what the browser intends or wants you to do of course the browser kind of wants you to use the default context menu there are of course times when a custom right click menu is nice to have so why not try it out let's also search for svelte if there's some like built-in way I really don't think so but why not have a quick look so there is some nice Ripple yeah exactly what I'm trying to look for you have a nice menu here I really like that one actual menu is here I assume uh felt body on page click so this is where they actually handle that we have the own context menu and then the event attribute or the event modifier prevent default which we can also use of course so we don't need to you know call it immediately in the function Handler or event handler we can just do prevent default and add it like that immediately here that's kind of nice so where I want to add this mainly was the sidebar actually so that you can just right click here and have some nice actions so let's have a look here for that we have Main and we have this sidebar and we have the board list yeah that's exactly right so these things definitely need their own components why not why not make a components for this right away I feel like uh so see if I just create a new directory for this now called sidebar so I'll put all the sidebar good stuff in here let's move that yeah so we have the sidebar here and now we have a board list and now we have like a board list item kind of verbose there but always good to be more clear than you know on here so let's copy this into a component make component for another set we have like a board list item instead and let's move that in there and what do we take in we have current board ID and we have a board and that's about it we also have select board so kind of want to dispatch that we can just do something like this or click and we can just move that over with event forwarding itself so we just forward it on to the parent component if we don't you know write a Handler here so that's quite nice and then we can do this script blank TS write some simple props here so you can do some export let's current board ID which would be a string and now we can export the board here so we'll be a to do board I believe or another to the board the to do board is actually the component so what is this actually called to do to do item to do data board I'm not even sure anymore to task Board of course task board I should have known task board there we go and that's about it other than that it's just accessibility stuff which will cover very soon actually so for these we Loop over the boards array and we create a new board list item for all of them and then we can just pass in the board here you're not going to be mutating it here so we're just gonna be one doing one-way data binding here and let's do some importing here maybe it does not want to import actually okay it's actually imported already she's complaining about something else and it's the current board ID so let's do the same thing here just a quick short on here so that we don't have to write the same thing twice and then we can save that nothing going on here we have board list okay so cannot find module here the board list is actually not working out so so it's actually in the same folder now let's see that there we go all right so now we have the board list and then we also have a nice little board list item that we can manage Now isn't that nice we can also split up these lines a bit more so that I can see what's going on all right then so let's create an event handler for this so we can create something like function on right click which we will handle whenever the user right clicks on this to do board item or this you know sidebar item here now we can do something like on context menu so the vanilla event for right clicking something is called context menu so that's context menu event is called whenever you right click on a Dom element so we can do on context menu then we can do prevent default so we prevent the default here which which is showing that native browser context menu but we don't want that we want to have our own context menu so we do prevent default there and now we can bind this to on right click let's see now then if I add a quick little D back here so on right click let's see if that works boom on right click and we don't see anything native if I just remove this you can see if I start right clicking there nothing happens anymore so we just remove that completely but of course this is only on that element so if I right click somewhere else of course the normal context menu is still available there so that's nice to know so now we actually need to handle rendering the actual context menu which will be the hardest part here I feel like and I'm not really sure how to structure this we could definitely put it in the same you know component here but I feel like we're only going to have one context menu you know shown at one time so we're gonna probably just gonna put it in more like app.sveld and then perhaps we can do something like a store or something Have I shown stores even I don't even think I have shown stores yet that's a bit strange but you haven't actually had a need for a store yet because we haven't really been talking with components in that way we've been using event dispatchers for the most part I kind of don't like using it because I'm more of a more you know object oriented guy I like the orbit oriented way if not know how exposing everything you kind of expose a lot when you're working with stores because you're probably gonna expose it to all the components you know all of them can import that and do whatever they please with it and that's not really something I like that much but you can of course use stores if you have like a really deeply nested which this is not really but it's you know inside bar which is in a to-do board list and then it's in a board list item so it will be quite cumbersome here to use like event dispatchers to dispatch that now I want a context menu let's let's try creating the component first so we're just going to be rendering it like here or something and let's just style it a bit now and get comfortable with that first so if I create a component first we can just do some like context menus and then we can create a new file in here context menu I feel like we're probably not going to have any other context menus in the sidebar so it will be a pretty clear name of where that is coming from so with a sidebar context menu let's just make a divider here for that then and then we can use of course we can use Tailwind CSS here as well so we can do some like fixed which will make you know position fixed so we don't can have it anywhere we want on the page even on top of other elements and then we can also do set here so we can actually have the said index and that is something we want to you know position it and show it on top of other items so let's try doing that set 10 will be set index 10 I believe and let's just write some debug text there and then let's put that in app there so in body we want to show that board the sidebar context menu let's see if that works and yes it does so now if I just do some top here let's try if I use top top 60 yeah and then I can do it left uh left 60 as well so so if you don't know this is more the absolute positioning in CSS where you can now position it based on actual values from top left bottom and right 15 Ram So it's 15 Ram from the right and then 15 Ram from the top as well so we can also do some like BG white here too actually give it a background there there we go and then we can also give it a bit of padding of course padding for perhaps let's add some rounding to it maybe we have like some maybe we have some border for the way maybe it's just border and then we can do border gray 300 I think we used yeah that's about it and let's just change this up a bit if I do left 40 on top 40. so I'm just kind of positioning where I would imagine it to be when I click or no right click on that board item so if I do top 30 left 30 as well okay that did not work that was not a valid one 32 yeah that one works so that's about it so this is when I imagine clicking on it like here or something then I want this to show here and what do I want to show here then well I want to show a rename and delete so let's try adding that so of course we're gonna be using my darling flexbox here to have like a column layout a vertical layout so we can do Flex Flex effects call then we can add some items in here so we can do some like div we're just gonna put some dividers we're gonna turn them into components later on so you can do something like div and then we can write something like rename and rename and delete let's see if that works yeah that looks really bad but we're gonna change it up of course I feel like the padding is a bit too much here actually so let's do padding two yeah I feel like that looks better and perhaps you can also have a gap between these items so Flex call Gap two yeah that's a bit too much actually I feel like Gap one would be nice there we go that's quite nice and then we can do something like hover BG gray hundreds are gonna have some nice hover effects too then let's add that to this one as well loads of code duplication now but okay that looks really bad I think it's due really to that padding there so I feel like we should remove that from the actual or maybe we can do some like py here so we have like a vertical padding but then the components themselves will have the you know horizontal padding so let's see if that looks better yeah there we go that's a bit more like it maybe it still looks a bit weird though I'm not really sure how does this look you know look okay so let's just remove the padding all together they can have their own padding I guess the items themselves I feel like that could be better yeah that looks much better kind of weird to have a top padding if we're gonna have like hover effects and stuff like that so I feel like that looks quite nice maybe we can do something like py1 instead yeah that's a bit more like it uh maybe even more further here let's make it a bit longer here a bit wider that looks pretty nice if you like so we can go with that for sure so I guess we can create a new directory for that as well since we're gonna be adding another component in there so you can structure it a little bit so context menu sidebars and then in here we want to add another component actually which will be the well context menu well this mode actually kind of be a general component actually I think we can actually use this you know reuse this in multiple context menus so why not do that if I do something like a context context menu item I feel like our context menu items will be pretty similar really even the context menu itself you know I don't think I'm gonna have like a million different variations so it kind of depends apparently we only have this context menu so it doesn't really matter almost good to have a general approach in mind if you have ideas about using it multiple places later on but let's just do a context menu item for now so let's copy this in there and then we can just expose that name here as a prop instead so we can do script length yes name and this will be a string and then we can render that there with that prop so in here now we can establish to use that nice context menu item which is much nicer and then we can do something like a name here and use this instead so rename will be the name here let's see if I can import that no I cannot okay let's see context menu item there we go and it's still broke why did it break sidebar context menu okay it's because I moved it into the directory here so let's see it will be context menus sidebar actually so why is it breaking sideboard does the file exist let's see if I can import that again and see why that is breaking so much now it worked out not sure what the difference was really but all right so now we have that rendered it there so let's handle now actually you know clicking on it and showing it let's add that back though so we can have the lead here as well of course uh so there I have a bit more to show there we go nice now let's actually handle the most complicated part of actually positioning it where we click so and also opening it will be a bit of a challenge so where are we gonna handle this we're gonna be starting off in the board list item this is where we have this on right click so we want to trigger something when we right click on this we want to show a context menu and this context menu will be position you know absolutely so it will be Absolute Screen coordinates really so we need to know kind of where the user clicked and I think we can actually get that information from the event so let's see if I log out this event think you can actually get that information from the event so if I log that here you can see here that we have client text and client Y and I'm pretty sure that that is actually the you know you know absolute coordinates it doesn't make sense for this to be like inside of the like relative to the element or anything so it makes sense that this is the really Absolute Screen coordinates or not the Absolute Screen coordinates but more the viewport coordinate so you know in the browser window client x95 would probably be some somewhere here you know if it were the screen coordinates but this is more you know inside of the browser so so you actually have access that we have access to e dot client X and E dot client of Y which will give us screen coordinates and that's all we really need to know so let's see let's now think about how we're going to be opening this so I feel like we should use a store for this uh it makes the most sense so we don't have actually have any stores yet and I'm actually going through this I haven't mentioned it in a couple of videos but we never got a route to implement it really so stores and sveld is really just a way to you know store our data and you know share that data and reactivity specifically the reactivity that is shared between multiple components so whenever a value changes in this store it is reflected in multiple components so you can subscribe to a store and actually you know note notice when something has changed you can have like a variable that is global it's more like a global scope where you have like variables that can change you can change the variables you can reassign the variables and you can know when they have changed in multiple components and is really really cool and it's also really easy to work with of course since it's spelled so we can do something like export let export cons rather it's going to be a constant variable and then we want to do something like you know we're actually naming it so we're going to name it something we can do something like a sidebar context menu so I'm just going to do this kind of you know naively now we're just gonna have one we're probably just gonna switch this out to a more General approach in the future where we can just you know assign to some context menu variable and then it will just magically show different context menus but we're just going to have this for now and then we have a writable so this is actually writable svelt store so now we actually create a store this is where we can actually store a value that we want to be reactive in multiple components and the first parameter here is the default value for this store and I feel like this should be null here actually so we don't want to show this so what will the actual type for this variable be well I think there's actually something called writeable and then this is actually a generic so if I do something like in writable null this is you know what we have currently but we want to have instead of null here we want to have something like the coordinates or something so if I can do something like a number number array so this will be an array which have two well okay it's going to be null or number number so this will be either null or it's gonna be an array that has two elements that both are going to be numbers so that is the kind of the type that I'm thinking in typescript so if you're not using typescript you don't need to think about this at all so so take that how you want but now we have that so number number this will be X and this will be y so board this item we're just gonna set to that so when it comes to stores that there's actually a kind of a special synth so we're actually going to be using the dollar syntax again which we are familiar with we have been using it for the other reactive stuff so it's more of a way to tell the stealth compiler that something is reactive here and specifically we're going to import that constant it's going to be a global constant but it's not going to be constant you know the actual variable is not going to be reassigned but the value inside of the store is so we can do something like dollar and then we write the actual variable name here which will be the sidebar context menu which we now import here normal you know a normal module import here with the help of this dollar sign we tell this felt compiler here that we have a sidewalk context menu that is a store and that we want to now be able to reassign if I reassign it to something now if I just do e dot client X and E dot client y let's try that out actually boom uh so now we actually have reassigned to that and absolutely nothing will happen since we're not handling it anywhere but we can do it now inside of our context minutes if I do name here and if I try using this we can actually use this right away here and this will not actually work so since this has the same name as the component here so that's kind of a shame so this is called sidebar menu for now since we can't really have the same name that's kind of stupid but if I remove context from the name here so we have just sidebar menu instead then we can use that here so sidebar menu perhaps we can import it now let's see import from stores yes so it is usually like a normal variable here if we use the dollar sign so it's important here to use the dollar sign to tell the spell compiler that it's going to be reactive here so sidebar menu and then it will be you know at zero here since this is an array actually so name here it's gonna break now since we have assigned this to be like a string so uh since we have assigned this to be a string so we can do like two string and that should solve it hopefully let's see if that will actually work I'm not sure if that's gonna work being reactive let's see it kind of broke completely now so sidebar context menu yeah of course since it's null so we don't want to show this unless it actually has a value so it's no then we don't want to show it so let's just do that wrap it in an if statement boom let's see if it works now no it doesn't and of course we want to have the dollar sign here so that actually uses the actual value not the constant there so now let's see does it work and yes it does isn't that amazing so now we actually get the screen coordinates and that should be one of course there we go now we actually get the screen coordinates of where I click now it shows that here in numbers so we took values from one component and you know we shoved it over into some Global scope and now the other component knows about it so now we can actually use that but how are we gonna use it then so this is kind of the problem now since we have a store we don't really know what unless you know we can do react we can reactively check that yeah this has changed and then we want to you know do something I feel like that's what we're going to be doing now but I've done this before and it kind of leads to some issues you know especially like multiple levels to it and if you're going to be changing it from multiple components it kind of gets messy but you can actually listen for it so just like we do in other components where we have this normal when we have this magic syntax we can look for changes in the store this way and there's actually also a function for this so that we can use but we can do it this way with this magic syntax and have a function that listens for whenever that changes so let's try that as well so if I do something like on sidebar menu change or something now we can pass in that array so this menu and then we can do something like dollar sign reactive syntax so on side of our menus change so now we pass in that sidebar menu store there we go now we can log that out so we will now know whenever that changes and that's when we want to listen to it of course so now we can see we get some values whenever I right click here you can also see that it will send the first value which will be no so you kind of need to handle that so if venue is no we can do something like a return and we can also type annotate this so it will be null or this nice number number thing we got going so there we go that should be the proper type for that but the question is if we actually need to know this if we actually need to know when it's changed maybe we can just use the class here let's try doing that if I just use the values immediately here let's see if that will work so if I just do something like style then I do top here and then we can do sidebar menu sidebarm menu at zero to string and this will be pixels it's kind of getting a bit tight there I can't see what it says it's style there is sidebar menu there you go and now we want to use the Y value as well so well this will be the actual left value so top one and then the left here will be the x value let's see why that is breaking it's because it's not capitalized properly sidebar menu let's see now if if I remove this reactive syntax here will it work boom let's see now will it work yes it will wow I did not expect it to work that flawlessly holy we're just using the value here we're just assigning this in the style here so we're using the style attribute and we set the CSS values left and top to be X and Y so left here is X and top is a y and it just works it is now where I click the mouse isn't that amazing so really great that was much easier than I actually anticipated it being so we looked at that fat solution with vanilla JavaScript and it had like a hundred lines of code but with weld of course we can just use some beloved syntax that is just amazing with the help of svelt we can implement it so easily and straightforward of course we also need to handle now when we click somewhere else on the page so so that's also kind of important if I click somewhere else on the page I don't want that context menu lingering around but that should hopefully also be pretty easy so I think you can do something like that in app.swelt if I handle this here I think we can do something with this veld body but we actually have a body here already and it's kind of a bad body because we have multiple bodies don't we we have one body here and then we have another body inside of apps like I said this is completely stupid so let's move this into divider instead we have a divider instead of the body it doesn't make sense to have multiple bodies and it didn't seem to break anything really let's see yeah we're not really doing anything stupid anyways so we want we want that to be a divider of course but we want to have we want to be able to have that body and we can actually handle that with well the body I believe so this will give us access to the body and here we can do stuff for like assigning event handlers and that is what we want to do so whenever we click on the body I think we can do it here so all click so on body click let's see here click no I'm not sure if this will trigger whenever we click anywhere on the page that is kind of what I'm are assuming so let's see if I clicks over here here yeah it says body if I click here it will also say body no okay so this is of course whenever you left click this is the normal Dom event it's just a normal click event so of course it's not calling on context menu since I did not assign that so we have on click and that's kind of what I want right really so we want to handle that here perhaps also on right click or does it even matter I don't feel like it does so we have left click and that will hide it actually so yeah so we can handle this here we can actually handle this here by just setting it to null so we have that nice store now that we can access and we just decide about venue is null and now it should hopefully disappear when I whenever click and it did and boom it hides isn't that amazing so but maybe it would be nice to have it for the context menu as well perhaps I'm not really sure about that but perhaps you can solve that if I added multiple times so if I do context menu all context menu and then we do on body click as well I'm assuming this will override it kind of so it won't show anything yeah that's kind of what I thought but perhaps we can solve this here if I do something like e dot stop propagation I'm assuming it will work won't it yes it will so we're actually stopping the propagation from propagating to you know the body we're clicking on something on the body and we're stopping that event from propagating to the actual parent here which is you know eventually going to be the body even though it's like deeply nested in dividers and all kinds of components but the base component here is HTML really but we have a body inside there a body element that receives that event eventually but we stop the propagation here we tell it hey we want it to stop here we want to show the sidebar menu enough of that no more propagating that event so we stop the event there and then we can simply show the context menu if I click somewhere else now boom it disappears if I right click here and I click somewhere else boom boom boom any kind of action really so I'm assuming this yeah as well will also any kind of Click really and the right click will now remove the sidebar menu isn't that amazing so now the thing that we need to handles actually you know passing the state we need to know which board item that we have clicked here so that I can handle it so let's remove that debug information here in the the little nice button that we had so if I rename this to be a rename of course and then I renamed this other to be delete then hopefully I should be able here to handles now we have rename we have delete whenever I click that I want to handle that and actually rename it or delete the actual item that I clicked on and I noticed something also we want this to be cursor pointer of course since this is just a divider it will not have that pointer cursor so there you go much nicer so now now whenever I click that we need to know which board item that I clicked this for and how are we going to handle that well we need to pass that state on to the sidebar to the store actually so it will be null or number number and the number number will be the coordinates and then we want to pass in also the board really the the board that we're going to be deleting or adding so I guess you can do some like board well task board really that's or do we really need to do like sending the whole object that's the question maybe we can just I guess it's nicer to have the access to the whole object so we can do that uh let's do that here then so we have sideworm menu and then here we can actually send in the board since we have access to that already so nice and now we should have access to that in the context the menu as well so if I just show this here in a nice way if I do something like rename plus and then I do sidebar menu this gets a bit problematic now since we have an array it would be nicer here to have an object I feel like we should refactor that later to have an object with x y and the board as properties but now we can see object object does that whatever we want we want this to be name here boom rename default rename default board rename another board we can see now we have access to that isn't that amazing so of course we also here have access to on click since we exposed that I believe well we exposed it through event forwarding so we can do something like on rename and we can also do on delete so now we can remove that little debug information there and then we have the actual function so let's try it out real quick see if it works so rename boom if I click that and rename it will not work actually let's see we're not actually using event forwarding I was just thinking from another case that we had there so I'll click now we have event forwarding hopefully so boom rename now we have some event forwardings and amazing so now we can handle that as well I feel like the rename is gonna be really difficult so let's start with the deletion match and this is also going to become a problem really because we need to have some Global state or something for that as well so where are we actually deleting boards this is in well let's Trace that so we have the board and to do board and now we have the icon here which will be on board delete and we just dispatch board delete this handle over here perhaps yeah we're on current board deleted so it's in app that's about so we're actually kind of lucky here we can just handle that in app that's felt but of course we shouldn't handle everything in app that's out so if it gets like out of hand and we're handling every single thing in app itself then we're not really isolating things properly and that's not something we want to be doing but okay I think it's fine for now we have on current board deleted and we don't want that actually we want to delete a specific board so I guess we can create a more General function for that so on board well more board delete board actually so this will pass in here will be an ID yes so it will be an ID string now we can just copy this code here really yeah so this is just where you want to have instead of current board are you you just want to do ID save the local stores is there something else we do no not really so all that we really do here is delete board current board ID all the other stuff is already General so we can just create an event dispatcher for the deletion here so we can do something like cars dispatch create event dispatcher on the lead you can do dispatch delete and then we can pass in well we can pass in the board here so it will be sidebar menu at well sidebar menu at two and then r dot ID which will give us the ID so delete yeah nothing that's fine so we have app that's felt here we have the Cyber context menu so on on the lead we want to do well we can have an anonymous function of ux that is fine so we have e here then we can do delete board and E dot detail which will give us the detail from the event so let's see if that works if I try to delete another board will it removed itself yes it will isn't that amazing absolutely wonderful so now we have that implemented that was quite straightforward wasn't it but the actual renaming capabilities I feel like will be quite difficult so now we need to have access to actual component of this button so that we can change the text and do stuff like that so it's not as simple as having access to some object with an ID inside of it we actually need to have the the real component that is being rendered on the screen and of course we can solve this problem in multiple ways we could even pass in the component itself I think I've done that like one time but I feel like that is quite of a hacky way to do it and one way that we learned today is with the help of stores if you want to communicate between components we can use a store and perhaps you can do something like that so we assign to some store that says that hey we want this specific board to be we can use the ID again we just do the same thing here shared ID of the item that we are clicking on but we can simply check in the actual button is this you know does this belong to me so for every single component well in every single button component we checked is this the ID that I am handling or the ID that I am rendering or otherwise we don't handle it so I guess we can try that out and this also becomes a big problem so I feel like it would be nice then in the future to isolate these stores into a bit more structured approach so that we have some stores for this kind of functionality so it's not like a big Global store with like a million variables inside I feel like that's a bit a bit nasty so we can do something like export const I'll rename board button or something now we can rename in the future as well so writable here will be null or the string here will be the ID of the board that we are renaming and writable the default value will be null and that should be fine yeah so we have rename and then we can handle that here in this sidebar context menu and we can do something like rename board button import that one and then we can set that to the ID here so sidebar menu at two dot ID and then hopefully now in the actual board list item we can handle that so so we're going to select if rename board button equals border.id so if rename board button that button that we have clicked rename on is the board ID that I am this board list item is it has the same idea that I if it has the same ID that this one is rendering for so then we can do something like yes so yes and imported that as well so if I click that now rename yes it says let's move that into the actual component here so and then of course we want to have another border so that we can tell a difference here so if I now click that it kind of actually broke what is that about all right that's a bit strange actually now I can't switch boards for some reason um okay okay so I'll click here onboard list item or so I kind of removed that we didn't actually Implement that properly so we want to handle that on click here that's the one I was talking about before when I was talking about event forwarding so here we want to use select board and then I'll click we are passing in nothing here okay so if you do something like board.id and then we want this to be an anonymous function as well so select board where you want to handle like this and hopefully it should work now yes it will amazing so now we can handle that context menu if I click rename now it says yes and here it says yes so now we know that this is the button this is the component that we are pressing and of course there are multiple ways to solve this problem but I feel like since we were warmed up with this stores I felt like using some more stores just because they're awesome so I felt like using stores today but if you have another idea or something if you feel like this is a really bad way to do it feel free to comment if you have another better idea to solve this problem but so now we can actually show this but how do we actually want to handle this renaming process well we have this board name wouldn't it be nice to use the Beloved content editable again but we only want it to be content editable whenever you know it is actually being edited so like I said we don't want to have content editable whenever we just click on the text so so maybe we can do something like that if I do content editable we only want to apply that if board is being renamed so if I remove if I move this in here let's see if that works out let's try that real quick so if I do rename now can I rename it yes I can Isn't that cool so I also feel like we want to handle it like actually start focusing on it how do you want to help that though will it start renaming itself no it will not okay so we want to focus on that divider to start editing it I believe so I feel like we should actually use that reactive syntax that I was talking about earlier so there's actually no whenever this value changes if it is the current board ID then we can start focusing on the elements so we can try implementing that real quick so on rename on rename a button or something like that on rename button we can try that and now we pass in the string here so that will be ID string and then we can handle if the ID is not board.id then we can return early we can kind of keep that content editable since it works but now we also want to start focusing on it so we can use our beloved bind this as well so we're using a lot of techniques today behind this we're going to be binding that to like an element here so we can do something like element we can just do something like HTML div element or no bind this and that will be element maybe it will actually not be null I'm not really sure like when it's mounted and I'm assuming it's going to be null but I'm not sure we can also check that here then so our element is null that we can return other than that we can focus on it then and then let's just use the reactive syntax so on rename button and now we can simply pass in rename board button so whenever that value changes this function is called so we yeah that should be fine and let's see if that works if I click that now rename absolutely nothing happened [Music] or did it work let's try again if I start typing now will it work no it won't kind of works but not really okay so let's see if if I cancel log it will it work let's see what happens if I rename yeah so it will work here but I need to add a small little timeout to that since it might not actually have content editable yet so let's try that element Focus one and let's see here now will it work yes it will so that's quite nice now we can start editing it uh well I feel like I should move this now to the end of the word here so maybe I need to find out how to do that so yes content editable move carrot to end I'm going to move cursor to end of content editable entity all right okay we're doing loads of stuff here select all um wow okay there's so much code here I don't feel like doing this today okay let's add and add range Focus select all children this one seems pretty small and straightforward so let's try that out actually we now get selection um well I guess I want to put this all in this timeout here so we can do window set collection uh selection element now we can do element focus of course so element focus and let's try it out now again boom and there we go that is exactly what I wanted then of course we can remove the spell checking as well set that to false boom now I can start renaming it isn't that amazing and just like before you want to handle all the below so whenever we focus out we don't want it to be content editable more anymore we want to remove that rename board button so if I do something like on name blur do we have this already no it's just from a lot of other places that we have it from so we can do something like on blur and assign to on name blur and then I feel like we can do something like a rename border button to null and let's see if that works if I click that now and click somewhere else I don't want to be able to rename it and I cannot do that anymore amazing and I also want to save it here so we actually need to pass it on to the parent component now that I have saved that but this also we need held this in another way we want to bind to text content where we only want to bind it whenever we have content editable and I don't think that is actually possible you can't have I don't think we can have this conditionally it has to be true if I just try binding text contents to board dot name I feel like it's gonna complain yeah content editable actually it cannot be non-dynamic if element uses two-way binding so that's not gonna work out actually I feel like we need to do this the old-fashioned way which is gonna be pretty easy anyways but we need to handle this another way so we have board.name here we need to get the inner text of the element and show it instead so this is definitely not you know two-way data binding at all we're not going to be updating the internal value so if I used to try logging it out I'm pretty sure that this will be static now so if I rename this to like milk and click somewhere else it's gonna still say Asda so we can just set that here from from the inner text so you can do border dot name and that will be element element dot inner text and hopefully that should work now if I rename it again set that to milk boom it says milk and out so we also want to pass this on to the power component that we have changed it so that I can save it to local storage let's see if we can have if we're handling that somewhere here we can just handle it here I believe so always complaining about something I'm not sure what it's complaining about element yeah we don't want this to be a prop I keep doing this so many times just a normal variable element yes then we can do something like this so we can have like an on on rename or something so on well there's more gonna be like on on board renamed so we can handle that here uh well no actually it's gonna be on rename it's just for the broadest item so then we can handle that so and then we can bind to that here so on board rename board list item we want to dispatch here we Note have a event dispatcher so let's create that real quick dispatch rename I believe yeah on rename and that's all onboard renames so now we want to handle now we want to pass that on to parent components again so we can just dispatch board renamed uh we don't need to pass in any information we're just going to be saving the state all like all the state to local storage that's how we're doing it currently so no need to worry about that currently but if we're going to be attaching a server to this of course we're gonna need to do that we don't want to say like all the state that's going to be a lot of bandwidth so if we rename a board or something we only want to send off that to the network but we'll take that when we get there so we have onboard renamed it's complaining about the model again but there's no problem really we are board less than so that's in app.velt I believe or it's going to be in sidebar actually so we just because pass that on I believe so on board renamed then we can handle that in Apple's felt so we're just doing something like on board renamed we save that to local storage save to local storage now let's try renaming it here so we call this milk and rename it and boom there we go milk has been saved isn't that amazing so then we can actually rename it to something like something more appropriate like personal instead of milk we can call this uh homework instead or something like that and boom there we go we have renamed them and it's all being persisted and we can also remove them if we want so if I add some dummy data here that I don't want anymore you can just click that right click that and it amazingly deletes itself but that shouldn't actually be saved really or yeah actually it is going to be saved because we're handling it you know a general approach we have delete board that we're using so it is well it will actually be saved isn't that amazing you have a general approach that we're using and it handles saving for us isn't that beautiful so now we can change it in two ways if you open it up you can change it here but if you're lazy you just want to do it real quick perhaps you're in homework you get really bothered by this this goddess test yeah yeah and then you just rename it here and give it a proper name or if you're really unhappy with it you can just remove it and let it wipe it off the face of the Earth and boom it is gone and you don't have to see it anymore while you're doing your important homework so absolutely amazing functionality that we implemented today I feel like this was a pretty long episode but we got a lot of functionality implemented I mean we got some really nice context menu some really nice and right clicking menus with the help of svelte and it was pretty straightforward with this was some complex scenarios that you can definitely solve in better ways or solve in different ways so I'm really curious about your opinions feel free to comment what you thought of this episode or if you have any you know Improvement suggestions or if you have any questions in general I would love to hear them and feel free to like or dislike depending on what you thought of the video also feel free to subscribe if you want to be part of this community that I'm trying to build and that would be amazing but other than that I'll see you guys in the next episode peace out
Info
Channel: Practical Coder
Views: 376
Rating: undefined out of 5
Keywords:
Id: sRqDJo7dn0E
Channel Id: undefined
Length: 53min 51sec (3231 seconds)
Published: Mon Jun 05 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.