Color Selector with Dropdown Pallette

This color changer has dropdowns on the buttons for selecting from a set pallette. The pallette colors can be chosen before installing. I like to use the HTML Color Codes site for help with making color choices.

This code should work as a whole in most themes, where the sidebar loads on all pages even though the sidebar is visible only on the home page. Otherwise the bottom part should go in a script tag at the bottom of the page. This is because that part of the script handles reloading the user's saved color settings so must happen on all pages. That point in the script is marked as such.

To customize the pallette selection, go down to the getColorPairs function. It's pretty easy to set them there.


<div id="color_buttons">
<div id="color_name"></div>
<div class="color_button">
<button>Header</button>
<ul id="header_list"></ul>
</div>
<div class="color_button">
<button>Post Title</button>
<ul id="post_title_list"></ul>
</div>
<div class="color_button">
<button>Sidebar Title</button>
<ul id="sidebar_title_list"></ul>
</div>
<div class="color_button">
<button>Post Date</button>
<ul id="post_date_list"></ul>
</div>
<div class="color_button">
<button>More Link</button>
<ul id="more_link_list"></ul>
</div>
<div class="color_button">
<button>Post Footer</button>
<ul id="post_footer_list"></ul>
</div>
<div class="color_button">
<button>Post Block</button>
<ul id="post_block_list"></ul>
</div>
<div class="color_button">
<button>Post</button>
<ul id="post_list"></ul>
</div>
<div class="color_button">
<button>Post Text</button>
<ul id="post_text_list"></ul>
</div>
<div class="color_button">
<button>Sidebar Block</button>
<ul id="sidebar_block_list"></ul>
</div>
<div class="color_button">
<button>Sidebar Content</button>
<ul id="sidebar_content_list"></ul>
</div>
<div class="color_button">
<button>Sidebar</button>
<ul id="sidebar_list"></ul>
</div>
<div class="color_button">
<button>Main Content</button>
<ul id="main_content_list"></ul>
</div>
<div class="color_button">
<button>Page Background</button>
<ul id="page_background_list"></ul>
</div>
<div class="color_button">
<button>Clear</button>
</div>
<div style="clear: both"></div>
</div>
<script>
const colorsParent = document.getElementById('color_buttons');
colorsParent.addEventListener('click', function(event) {
  if (event.target.tagName === 'BUTTON') {
    const areaKey = event.target.textContent;
    if (areaKey === 'Clear') {
      clearSettings();
    } else {
      makeUL(areaKey);
    }
  }
});

function makeUL(areaKey) {
  const ulData = {
  'Header': ['header_list', 'header_result', 'Header', ''],
  'Post Title': ['post_title_list', 'post_title_result', 'post-title', ''],
  'Sidebar Title': ['sidebar_title_list', 'sidebar_title_result', 'title', ''],
  'Post Date': ['post_date_list', 'post_date_result', 'post-header', ''],
  'More Link': ['more_link_list', 'more_link_result', 'jump-link', 'a'],
  'Post Footer': ['post_footer_list', 'post_footer_result', 'post-footer', ''],
  'Post Block': ['post_block_list', 'post_block_result', 'post-outer', ''],
  'Post': ['post_list', 'post_result', 'post', ''],
  'Post Text': ['post_text_list', 'post_text_result', 'post-body', ''],
  'Sidebar Block': ['sidebar_block_list', 'sidebar_block_result', 'sidebar-container', 'widget'],
  'Sidebar Content': ['sidebar_content_list', 'sidebar_content_result', 'sidebar-container', 'widget-content'],
  'Sidebar': ['sidebar_list', 'sidebar_result', 'sidebar-container', ''],
  'Main Content': ['main_content_list', 'main_content_result', 'page', ''],
  'Page Background': ['page_background_list', 'page_background_result', 'body', '']
  };
  const whichList = ulData[areaKey][0];
  const choicesList = document.getElementById(whichList);
  if (choicesList.innerHTML.trim() === '') {
    const colorPairs = getColorPairs();
    const colors = Object.keys(colorPairs);
    for (let i = 0; i < colors.length; i++) {
      const listItem = document.createElement('li');
      listItem.style.backgroundColor = colors[i];
      choicesList.appendChild(listItem);
    }
    const resetDiv = document.createElement('li');
    resetDiv.style.backgroundColor = 'DarkGray';
    resetDiv.textContent = 'Reset';
    choicesList.appendChild(resetDiv);
    const selectData = ulData[areaKey].slice(1);
    choicesList.addEventListener('click', () => changeSelection(event.target.tagName, event.target.textContent, event.target.style.backgroundColor, ...selectData));
  } else {
    choicesList.textContent = '';
    choicesList.removeEventListener('click', changeSelection);
  }
}

function changeSelection(elementName, buttonText, bgColor, whereToPut, divToChange, nested) {
  if (elementName === 'LI') {
    let color = '';
    let textColor = '';
    if (buttonText !== 'Reset') {
      const colorPairs = getColorPairs();
      color = translateBack(bgColor);
      textColor = colorPairs[color];
    }
    let selector;
    let collection;
    let textString;
    if (nested) {
      if (nested === 'a') {
        selector = `.${divToChange} ${nested}`;
      } else {
        selector = `.${divToChange} .${nested}`;
      }
      collection = document.querySelectorAll(selector);
      textString = `${selector} - ${color}`;
    } else if (divToChange === 'body') {
      collection = [document.body];
      textString = `${divToChange} - ${color}`;
      selector = divToChange;
    } else {
      collection = document.getElementsByClassName(divToChange);
      textString = `.${divToChange} - ${color}`;
      selector = divToChange;
      if (divToChange === 'Header') {
        headerTitle(textColor);
      } else if (divToChange === 'post-title') {
        postTitle(textColor);
      }
    }
    if (!color) {
      textString = '';
    }
    for (let i = 0; i < collection.length; i++) {
      collection[i].style.backgroundColor = color;
      collection[i].style.color = textColor;
    }
    let placeFor = document.getElementById(whereToPut);
    if (!placeFor) {
      placeFor = document.createElement('div');
      placeFor.id = whereToPut;
      const textTarget = document.getElementById('color_name');
      textTarget.appendChild(placeFor);
    }
    placeFor.textContent = textString;
    placeFor.style.backgroundColor = color;
    placeFor.style.color = textColor;
    placeFor.style.padding = '0 3px';
    localStorage.setItem(selector, color);
  }
}

function translateBack(selKey) {
  let properKey;
  if (selKey.startsWith('rgb')) {
    let componentToHex = (val) => {
      a = Number(val).toString(16);
      return a.padStart(2, '0');
    };
    let rgbtohex = (rgb) => {
      hex = rgb.slice(4, -1).split(',');
      return hex.reduce((a, b) => a + componentToHex(b), '#');
    };
    properKey = rgbtohex(selKey);
  } else {
    const colorPairs = getColorPairs();
    properKey = Object.keys(colorPairs).find(key => key.toLowerCase() === selKey);
  }
  return properKey;
}

function clearSettings() {
  localStorage.clear();
  window.location.reload();
}

// These are for the color picker.
// They can go in sidebar widget when it loads on all pages.
function getColorPairs() {
  const colorPairs = {
    '#dbee68': 'Black',
    '#4682b4': 'White',
    '#4bb446': 'White',
    '#b0c4de': 'Black',
    '#ff8c00': 'White',
    '#f0f3f4': 'Black',
    '#ee6898': 'White',
    'Gainsboro': 'Black',
    'MediumSlateBlue': 'White',
    '#bdcd5a': 'White',
    '#e6e6fa': 'Black',
    'WhiteSmoke': 'Black',
    'White': 'Black',
    'DarkOrange': 'White',
    'Gold': 'Black'
  };
  return colorPairs;
}
// for text color of nested elements set in CSS
function headerTitle(titleColor) {
  const h1AAndPseudo = ['.Header h1','.Header h1 a','.Header h1 a:hover','.Header h1 a:visited'];
  for (const eachOne of h1AAndPseudo) {
    const titleText = document.querySelector(eachOne);
    if (titleText) {
      titleText.style.color = titleColor;
    }
  }
  const menuIcon = document.querySelector('button.hamburger-menu svg');
  if (menuIcon) {
    menuIcon.style.fill = titleColor;
  }
  const homeIcon = document.querySelector('.return_link svg');
  if (homeIcon) {
    homeIcon.style.fill = titleColor;
  }
}
function postTitle(titleColor) {
  const titleText = document.querySelectorAll('.post-title a');
  for (let i = 0; i < titleText.length; i++) {
    titleText[i].style.color = titleColor;
  }
}
// to set colors from local storage
document.addEventListener('DOMContentLoaded', function(){
  if (localStorage.length > 0) {
    const colorPairs = getColorPairs();
    let storedColor;
    storedColor = localStorage.getItem('Header');
    if (storedColor) {
      const textColor = colorPairs[storedColor];
      const collection = document.getElementsByClassName('Header');
      assignColor(collection, storedColor, textColor);
      headerTitle(textColor);
    }
    storedColor = localStorage.getItem('post-title');
    if (storedColor) {
      const textColor = colorPairs[storedColor];
      const collection = document.getElementsByClassName('post-title');
      assignColor(collection, storedColor, textColor);
      postTitle(textColor);
    }
    const areas = ['title', 'post-outer', 'post', 'post-header', 'post-body', 'post-footer', 'sidebar-container', 'page'];
    for (const area of areas) {
      storedColor = localStorage.getItem(area);
      if (storedColor) {
        const textColor = colorPairs[storedColor];
        const collection = document.getElementsByClassName(area);
        assignColor(collection, storedColor, textColor);
      }
    }
    const nestedAreas = ['.jump-link a', '.sidebar-container .widget', '.sidebar-container .widget-content'];
    for (const area of nestedAreas) {
      storedColor = localStorage.getItem(area);
      if (storedColor) {
        const textColor = colorPairs[storedColor];
        const collection = document.querySelectorAll(area);
        assignColor(collection, storedColor, textColor);
      }
    }
    storedColor = localStorage.getItem('body');
    if (storedColor) {
      document.body.style.backgroundColor = storedColor;
      document.body.style.color = colorPairs[storedColor];
    }
  }
});
function assignColor(collection, selectedColor, textColor) {
  for (let i = 0; i < collection.length; i++) {
    collection[i].style.backgroundColor = selectedColor;
    collection[i].style.color = textColor;
  }
}

</script>


The CSS:


#color_buttons {
background: AliceBlue;
background-image: linear-gradient(to right, MistyRose, Moccasin, LightYellow, HoneyDew, AliceBlue, Lavender, LavenderBlush);
}
.color_button {
float:left;
position: relative;
margin: 5px;
}
.color_button button {
padding: 3px;
}
.color_button ul {
position: absolute;
top: 1.5em;
list-style:none;
margin: 0;
padding: 0;
z-index: 100;
}
.color_button li {
width: 40px;
height: 30px;
font-size: 0.85rem;
}
#color_name {
font-size: 0.9rem;
}

 

Comments