skip to Main Content

This took me way to long and I still think my implementation is rather bad and confusing, right now I’m just largely confused why things break if I remove checkedActivities.has(activity) ? "checked" : "unchecked" because I thought my typescript replaces this functionality. Any advice would be greatly appreceated.

<script context="module" lang="ts">
    import userActivities from "../userActivities.json";
    const activityArray: string[] = userActivities.activities.map(
        ([name, icon]) => name
    );
    export let selectedActivities: String[] = activityArray.slice(0, 3);

    let checkedActivities = new Set(activityArray.slice(0, 3));
    function toggleActivitySelection(activity: string) {
        let div = document.getElementById(activity);
        if (checkedActivities.has(activity)) {
            checkedActivities.delete(activity);
            div?.classList.remove("checked");
            div?.classList.add("unchecked");
        } else {
            checkedActivities.add(activity);
            div?.classList.remove("unchecked");
            div?.classList.add("checked");
        }
        console.log(checkedActivities);
    }
</script>

<div>
    <div class="heading-bar">
        <span>Saved activities</span>
        <form action="/activities">
            <button on:click={() => console.log(selectedActivities)}
                >Done</button
            >
        </form>
    </div>
    <div class="bg-container">
        {#each activityArray as activity}
            <div
                class={checkedActivities.has(activity) ? "checked" : "unchecked"}
                id={activity}
            >
                <label>
                    <input
                        class="input_checkbox"
                        id="input_checkbox"
                        type="checkbox"
                        bind:group={selectedActivities}
                        value={activity}
                        on:change={() => {
                            toggleActivitySelection(activity);
                        }}
                    />
                    {activity}
                </label>
            </div>
        {/each}
    </div>
</div>

<style>
    input[type="checkbox"] {
        width: 100%;
        height: 100%;
        display: none;
    }

    label {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    div.checked:hover, div.unchecked:hover {
        border-left: 2px solid var(--color-text) !important;
        border-bottom: 2px solid var(--color-objects) !important;
        border-right: 2px solid var(--color-text) !important;
        border-top: 2px solid var(--color-objects) !important;
    } 

    div.checked {
        padding-top: 0.5em;
        padding-bottom: 0.5em;
        border-radius: 20px;
        margin: 0.5em 0;
        border-left: 2px solid var(--color-text) !important;
        border-bottom: 2px solid var(--color-objects) !important;
        border-right: 2px solid var(--color-text) !important;
        border-top: 2px solid var(--color-objects) !important;
    }

    div.unchecked {
        padding-top: 0.5em;
        padding-bottom: 0.5em;
        border-radius: 20px;
        margin: 0.5em 0;
        border-left: 2px solid var(--color-objects) !important;
        border-bottom: 2px solid var(--color-objects) !important;
        border-right: 2px solid var(--color-objects) !important;
        border-top: 2px solid var(--color-objects) !important;
    }

    .heading-bar {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        margin-top: 1.8em;
        margin-bottom: 0.6em;
    }

    .bg-container {
        border-radius: 12px;
        background-color: var(--color-objects);
        padding: 1em 1.4em;
    }

    #item {
        display: flex;
        align-items: center;
        justify-content: center;
    }

    button {
        background-color: var(--color-objects);
        border: none;
        color: var(--color-text);
        font-size: 1em;
        border-radius: 10px;
        padding: 0.5em 0.5em;
    }
</style>

2

Answers


  1. i am trying to make your example working ts-example

    <script lang="ts">
        const userActivities = {activities:[
          {name:"name1",icon:"icon",checked:false},  
          {name:"name2",icon:"icon",checked:false},
          {name:"name3",icon:"icon",checked:false} 
        ]}
      let selectedActivities:any
    </script>
    
    <div>
        <div class="heading-bar">
            <span>Saved activities</span>
            <form action="/activities">
                <button on:click={() => console.log(selectedActivities)}
                    >Done</button
                >
            </form>
        </div>
        <div class="bg-container">
            {#each  userActivities.activities as i}
                <div
                    class={i.checked ? "checked" : "unchecked"}>
                    <label> {i.name} 
                      <input type="checkbox" bind:checked={i.checked} on:change={_ = >selectedActivities = i} />
                    </label>
                   
                </div>
            {/each}
        </div>
    </div>
    
    <style>
        input[type="checkbox"] {
            width: 100%;
            height: 100%;
            /* display: none; */
        }
    
        label {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    
        div.checked:hover, div.unchecked:hover {
            border-left: 2px solid var(--color-text) !important;
            border-bottom: 2px solid var(--color-objects) !important;
            border-right: 2px solid var(--color-text) !important;
            border-top: 2px solid var(--color-objects) !important;
        } 
    
        div.checked {
          color: green;
        
        }
    
        div.unchecked {
         color:red;
        }
    
       
    
    
    </style>
    
    Login or Signup to reply.
  2. You should not query the DOM or modify it directly like that. All the code adding/removing classes manually should be removed.

    The main issue is that checkedActivities is mutated without assignment, which does not trigger updates of anything that depends on it.

    The toggle function should be reduceable to:

    function toggleActivitySelection(activity: string) {
        checkedActivities.has(activity) ?
            checkedActivities.delete(activity) :
            checkedActivities.add(activity);
    
       checkedActivities = checkedActivities; // triggers updates
    }
    

    Any class changes should happen in markup using the class attribute or a class:... directive.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search