Loading a JSON config file when launching an application

I’m currently creating an electron application and what i would like to do is enable/disable and reveal/hide certain buttons when the application is launched.

What I’m struggling with is how i would reference each of the buttons in a JSON configuration file?

some of the html code:

  <div class="notready" style="visibility: hidden;">  
    <div style="display: grid; grid-template-columns: repeat(8,1fr); margin-top:-15px; width:100px; color:#FFFFFF; height:40px; object-position: center; margin-left: 200px;" >
      <div id="btnOverlayReady" class="overlay-state" onclick="" ><img src="" height="100%" width="100%"></div>
      <div id="btnOverlayNotReady" class="overlay-state" onclick="" ><img src="" height="100%" width="100%"></div>
      <div id="btnBreak" class="overlay-state" onclick=""><img src="" height="100%" width="100%"></div>
      <div id="btnEmail" class="overlay-state" onclick=""><img src="" height="100%" width="100%"></div>
      <div id="btnLunch" class="overlay-state" onclick=""><img src="" height="100%" width="100%"></div>
      <div id="btnComfortBreak" class="overlay-state" onclick=""><img src="" height="100%" width="100%"></div>
      <div id="btnMeeting" class="overlay-state" onclick=""><img src="" height="100%" width="100%"></div>
      <div id="btnChat" class="overlay-state" onclick=""><img src="" height="100%" width="100%"></div>
    </div>
  </div>

Could anyone give me some advice on how i could do this?

Thanks

I would want to drop the inline style style="visibility: hidden". This will avoid having to override it in JS with more inline styling or abusing CSS !important rules.

Can class ‘notReady’ have a visibility of hidden instead?

Then depending on the JSON config, could you not simply add a class of ‘enabled’ to the relevant id’d divs and take advantage of css specificity.

.notready {
    visibility: hidden;
}

/* more specific will overide the above rule */
.notready .enabled {
    visibility: visible;
}

I would also remove the inline onclicks ="" and instead use addEventListener. Here is a simple tutorial

You could then select all the elements that have a class of ‘enabled’ and add click listeners to them

// group handlers into an object
// this will enable us to select the handler that corresponds with
// the div/button id name
const handlers = {
    btnOverlayReady:  function(event) {
        // ... do this
    },
    btnOverlayNotReady: function(event) {
        // ... do this
    },
    ...
    btnMeeting: function(event) {
        // ... do this
    }
}

// search the DOM for all enabled buttons
const enabledButtons = document.querySelectorAll('.notready .enabled')

// loop through them adding eventListeners
enabledButtons.forEach(function(button) {
    const handlerMethod = button.id // e.g. "btnMeeting"

    // do we have a handler for that e.g. handlers["btnMeeting"]
    if (handlers[handlerMethod]) {
        // if so add an eventListener that will call the corresponding handler
        button.addEventListener('click', handlers[handlerMethod])
    }
})

That’s how I would approach it. Obviously I have missed out the important first stage of adding the enabled classes. I would need to see an example of your JSON config first.

Edit: I would amend the html (if you can) so that you had some better named hooks e.g.

html

<div id='workRelatedTasks' class="notready" style="visibility: hidden;">
    <div class='taskButtons'>
        <!-- can these be buttons instead of divs? -->
        <button id="btnOverlayReady" class="overlay-state" ><img src=""></button>
        ...

Rely more on CSS for styling
css

.notready {
    visibility: hidden;
}

// avoiding inline styling
.taskButtons {
    display: grid; 
    grid-template-columns: repeat(8,1fr); 
    margin-top:-15px; 
    width:100px; color:#FFFFFF;
    ...
}

.taskButtons .enabled {
    visibility: visible;
}

js

const enabledButtons = document.querySelectorAll('#workRelatedTasks buttons.enabled')

Something like that :slight_smile:

Hi dude, thank you for your response and all of the information you have provided :slight_smile: I have got rid of the style="visibility: hidden"

I haven’t actually put any data within the JSON file yet (config.json), I’m in early stages of creating an application. The purpose of this JSON file is so that users can edit this themselves to hide/show the buttons that they want.

For each of the div elements within the JSON file I Would like to have the attributes “ID”, “hidden” and “enabled” (again early stages I will probably add more attributes down the line). See JSON code below:

[
 {
    "id": "btnOverlayReady",
    "hidden": true,
    "enabled": true
  },
  {
    "id": "btnOverlayNotReady",
    "hidden": true,
    "enabled": true
  },
  {
    "id": "btnBreak",
    "hidden": true,
    "enabled": true
  }
]

The user would then be able to change these attributes, e.g if hidden is set to “false” then this button will be visible when the app is launched, however if this is set to “true” then it wont be visible to the user.

1 Like

That’s great @aaron10500 :slight_smile:

So my understanding is that by default all buttons are hidden. We sort that out with the .notready class. Therefore the JSON object doesn’t need a property of ‘hidden’.

It could instead look like this

// returned JSON object
const buttons = [
 {
    "id": "btnOverlayReady",
    "enabled": true
  },
  {
    "id": "btnOverlayNotReady",
    "enabled": true
  },
  {
    "id": "btnBreak",
    "enabled": false
  }
]

We can then use Array.filter and Array.map to extract the id’s of just the enabled buttons.

const enabledIdSelectors = buttons
    .filter(
        function(button) {
            // wiil return only the objects with enabled set to true
            return button.enabled === true
        }
    )
    .map(
        function(button) {
            // will extract and return the id strings
            return button.id
        {
    )

// output Array
["btnOverlayReady", "btnOverlayNotReady"]

We can add .enabled classes using classLists. Now we have the filtered id’s we can also add the eventListeners at the same time.

const handlers = {
   ... same as before
}

// loop through the filtered selectors adding classes and listeners
enabledIdSelectors.forEach(
    function(idName) {
        const button = document.getElementById(idName)

        // add .enabled class with a rule of 'visibilty: visible'
        button.classList.add('enabled')

        // as before check if the handler has a method with
        // the same name as the id name and if so add it
        if (handlers[idName]) {
            button.addEventListener('click', handlers[idName])
        }
    }
)

I haven’t tested this yet, but it seems like one way to go :slight_smile:

Note that with multiple settings you always have the product of options as the total number of options.

Here that means you have two booleans which both have two settings (true/false) which leads to 2x2 = 4 different settings:

  • hidden and disabled
  • hidden and enabled (huh!?)
  • visible and disabled
  • visible and enabled

I can get “visible and disabled”, but “hidden and enabled” doesn’t make much sense to me. In cases like that really think of what you’re trying to capture and make it impossible for the user to get into a state that doesn’t make sense. So maybe here you could have three options, “hidden”, “disabled”, “visible”.
Not saying that’s what you should do, just as an example.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.