# MVC Nettbutikk Applikasjon En ren JavaScript-implementering av en nettbutikk som bruker Model-View-Controller (MVC) arkitekturmønsteret. Dette utdanningsprosjektet demonstrerer kjerne webutviklingskonsepter uten eksterne rammeverk. ## 🏗️ Arkitekturoversikt Denne applikasjonen følger MVC-mønsteret med et sentralisert view-renderingssystem: - **Model**: Håndterer databehandling og forretningslogikk - **View**: Administrerer HTML-generering og DOM-manipulering - **Controller**: Koordinerer brukerinteraksjoner og dataflyt ## 📊 UML Diagrammer ### Klassediagram ```mermaid classDiagram class Model { -products: Array~Product~ -cart: Array~CartItem~ +getAllProducts() Array~Product~ +getProductById(id) Product +addToCart(productId, quantity) boolean +removeFromCart(productId) void +updateCartQuantity(productId, quantity) void +getCart() Array~CartItem~ +getCartTotal() number +getCartItemCount() number +clearCart() void +saveCartToStorage() void +loadCartFromStorage() Array~CartItem~ +initializeCart() void } class View { -currentPage: string -cartCount: number +updateView(viewType, data) void +generateNavbar() string +generateProductsPage(products) string +generateProductDetailPage(product) string +generateCartPage(cartItems, total, itemCount) string +createProductCard(product) string +createCartItem(item) string +attachEventListeners() void +updateCartCountInNav() void +showNotification(message) void } class Controller { +loadProducts() void +showProductDetail(productId) void +handleAddToCart(productId) void +handleRemoveFromCart(productId) void +changeQuantity(productId, change) void +handleClearCart() void +navigateToProducts() void +navigateToCart() void +updateCartDisplay() void } class Product { +id: number +name: string +price: number +description: string +image: string +category: string } class CartItem { +productId: number +quantity: number +product: Product } class App { +initialize() void } Controller --> Model : bruker Controller --> View : oppdaterer View --> Controller : sender hendelser Model --> Product : inneholder Model --> CartItem : administrerer CartItem --> Product : refererer til App --> Controller : initialiserer App --> Model : setter opp App --> View : starter ``` ### Sekvensdiagram - Legg til i handlekurv ```mermaid sequenceDiagram participant U as Bruker participant V as View participant C as Controller participant M as Model U->>V: Klikker "Legg i handlekurv" V->>C: handleAddToCart(productId) C->>M: addToCart(productId) M->>M: getProductById(productId) M->>M: Finn eksisterende element eller lag nytt M->>M: saveCartToStorage() M-->>C: return true/false alt Vellykket C->>M: getProductById(productId) M-->>C: return product C->>V: updateView('notification', {message}) C->>C: updateCartDisplay() C->>M: getCart() M-->>C: return cart C->>M: getCartTotal() M-->>C: return total C->>M: getCartItemCount() M-->>C: return itemCount C->>V: updateView('cart', {cartItems, total, itemCount}) C->>V: updateView('cart-count', {count}) V->>V: generateCartPage() eller updateCartCountInNav() V-->>U: Oppdatert UI med notifikasjon else Feilet C->>V: updateView('notification', {message: 'Feil'}) V-->>U: Feilmelding end ``` ## 📁 Prosjektstruktur ``` mvc-emne2/ ├── index.html # Hoved HTML-fil med enkelt app-container ├── styles.css # Applikasjonsstyling ├── js/ │ ├── app.js # Applikasjonsinitialisering │ ├── model.js # Datalag og forretningslogikk │ ├── view.js # UI-rendering og HTML-generering │ └── controller.js # Brukerinteraksjonshåndtering ├── flow-diagram.md # Applikasjonsflytvisualisering ├── README.md # Engelsk dokumentasjon ├── README-NO.md # Norsk dokumentasjon (denne filen) └── ACCESSIBILITY.md # Tilgjengelighetsdokumentasjon ``` ## 🔧 Nøkkelkomponenter ### 1. Model (`model.js`) **Formål**: Administrerer applikasjonsdata og persistering **Nøkkelfunksjoner**: - `getAllProducts()` - Returnerer produktkatalog - `getProductById(id)` - Henter spesifikt produkt - `addToCart(productId, quantity)` - Legger til varer i handlekurv - `removeFromCart(productId)` - Fjerner varer fra handlekurv - `updateCartQuantity(productId, quantity)` - Oppdaterer vareantall - `getCart()` - Returnerer gjeldende handlekurvinnhold - `getCartTotal()` - Beregner total handlekurvpris - `getCartItemCount()` - Returnerer totalt antall varer - `clearCart()` - Tømmer handlekurven - `saveCartToStorage()` / `loadCartFromStorage()` - LocalStorage-persistering **Datastruktur**: ```javascript // Produkt { id: number, name: string, price: number, description: string, image: string (emoji), category: string } // Handlekurvvare { productId: number, quantity: number, product: Product } ``` ### 2. View (`view.js`) **Formål**: Håndterer all UI-rendering gjennom en sentralisert `updateView`-funksjon **Kjernearkitektur**: ```javascript function updateView(viewType, data = {}) { switch (viewType) { case 'products': // Rendrer produktliste case 'product-detail': // Rendrer enkelt produkt case 'cart': // Rendrer handlekurv case 'cart-count': // Oppdater handlekurvmerke case 'notification': // Vis brukermeldinger } } ``` **Nøkkelfunksjoner**: - **Enkelt inngangspunkt**: All rendering går gjennom `updateView()` - **Komplett sidegenerering**: Genererer hele side-HTML inkludert navigasjon - **Event Listener-administrasjon**: Fester automatisk event listeners etter hver rendering - **Mallfunksjoner**: Modulære HTML-genereringsfunksjoner **HTML-genereringsfunksjoner**: - `generateNavbar()` - Lager navigasjonsheader - `generateProductsPage(products)` - Produktlisteside - `generateProductDetailPage(product)` - Produktdetaljside - `generateCartPage(cartItems, total, itemCount)` - Handlekurvside - `createProductCard(product)` - Individuelt produktkort - `createCartItem(item)` - Individuell handlekurvvare ### 3. Controller (`controller.js`) **Formål**: Håndterer brukerinteraksjoner og koordinerer mellom Model og View **Navigasjonsfunksjoner**: - `navigateToProducts()` - Viser produktliste - `navigateToCart()` - Viser handlekurv - `showProductDetail(productId)` - Viser produktdetaljer **Handlekurvadministrasjon**: - `handleAddToCart(productId)` - Legger til produkt i handlekurv - `handleRemoveFromCart(productId)` - Fjerner produkt fra handlekurv - `changeQuantity(productId, change)` - Oppdaterer produktantall - `handleClearCart()` - Tømmer hele handlekurven - `updateCartDisplay()` - Oppdaterer handlekurvvisning og teller **Nøkkeldesignmønstre**: - Alle funksjoner kaller `updateView()` for UI-oppdateringer - Brukernotifikasjoner håndteres konsistent - Handlekurvtilstand persisteres automatisk etter endringer ### 4. Applikasjonsinitialisering (`app.js`) **Formål**: Bootstrapper applikasjonen **Initialiseringsflyt**: 1. Vent på at DOM skal laste 2. Initialiser handlekurv fra localStorage 3. Last produkter fra model 4. Renderer initial produktside 5. Oppdater handlekurvteller ```javascript document.addEventListener('DOMContentLoaded', function() { // Fjern lastingstilstand const loadingElement = document.querySelector('.loading'); if (loadingElement) { loadingElement.remove(); } initializeCart(); const products = getAllProducts(); const itemCount = getCartItemCount(); updateView('products', { products }); updateView('cart-count', { count: itemCount }); console.log('Nettbutikk MVC Demo initialisert!'); }); ``` ## 🔄 Dataflyt ### 1. Applikasjonsoppstart ``` HTML-lasting → DOMContentLoaded → initializeCart() → loadCartFromStorage() → getAllProducts() → updateView('products') → generateProductsPage() → attachEventListeners() ``` ### 2. Brukerinteraksjoner ``` Brukerklikk → Controller-funksjon → Model-operasjon → updateView() → HTML-generering → Event Listener-tilkobling → UI-oppdatering ``` ### 3. Handlekurvoperasjoner ``` Legg til i handlekurv → addToCart() → saveCartToStorage() → updateCartDisplay() → updateView('cart') + updateView('cart-count') → showNotification() ``` ## 🎨 View-renderingssystem ### Sentralisert rendering Alle UI-oppdateringer flyter gjennom den enkelte `updateView()`-funksjonen: ```javascript updateView('products', { products: [...] }); updateView('product-detail', { product: {...} }); updateView('cart', { cartItems: [...], total: 0, itemCount: 0 }); updateView('cart-count', { count: 0 }); updateView('notification', { message: 'Vellykket!' }); ``` ### Komplett sidegenerering I motsetning til tradisjonell DOM-manipulering genererer dette systemet komplett side-HTML: ```javascript function generateProductsPage(products) { return ` ${generateNavbar()}

Våre Produkter

${products.map(product => createProductCard(product)).join('')}
`; } ``` ### Event Listener-administrasjon Etter hver rendering festes event listeners på nytt: ```javascript function attachEventListeners() { const productsLink = document.querySelector('[data-page="products"]'); const cartLink = document.querySelector('[data-page="cart"]'); if (productsLink) { productsLink.addEventListener('click', function(e) { e.preventDefault(); navigateToProducts(); }); } // ... flere listeners } ``` ## 💾 Datapersistering ### LocalStorage-integrasjon Handlekurvdata persisteres automatisk: ```javascript function saveCartToStorage() { try { localStorage.setItem('webstore_cart', JSON.stringify(cart)); } catch (error) { console.error('Feil ved lagring av handlekurv til localStorage:', error); } } function loadCartFromStorage() { try { const savedCart = localStorage.getItem('webstore_cart'); if (savedCart) { const parsedCart = JSON.parse(savedCart); return parsedCart.map(item => ({ ...item, product: products.find(p => p.id === item.productId) || { id: item.productId, name: 'Ukjent Produkt', price: 0 } })); } } catch (error) { console.error('Feil ved lasting av handlekurv fra localStorage:', error); } return []; } ``` ## 🚀 Bruk ### Kjøring av applikasjonen 1. Åpne `index.html` i en nettleser 2. Applikasjonen initialiseres automatisk 3. Naviger mellom produkter, produktdetaljer og handlekurv 4. Handlekurvtilstand persisteres på tvers av nettlesersesjoner ### Nøkkelfunksjoner - **Produktbrowsing**: Vis alle produkter i rutenettlayout - **Produktdetaljer**: Klikk på hvilket som helst produkt for detaljert visning - **Handlekurv**: Legg til, fjern og modifiser antall - **Persistent handlekurv**: Handlekurvinnhold lagret i localStorage - **Responsiv design**: Fungerer på desktop og mobil - **Brukernotifikasjoner**: Tilbakemelding for alle brukerhandlinger ## ♿ Tilgjengelighet og semantisk HTML Applikasjonen er bygget med tilgjengelighet i fokus: ### Semantiske HTML-elementer - **`
`**, **`
`**, **`