An article on creating a color picker from a specific palette using an input field of a radio type.
Why?
At the time of print, this feature is not provided out-of-the-box and getting our users to learn about hexadecimal color references and Red Green Blue (RGB) values is somewhat difficult. What would be nice-to-have is if they could be presented with a bunch of colors and they click on one to select it.
When are colors used? Well in this use-case, we are using it to color events in a calendar associated with specific staff. Probably not the most essential part of a system but important to some staff...
How?
In an earlier article, I've shown how to change a radio type field in ZohoCreator into a Carousel type of interface. This time, we're going to repurpose and restyle a radio type field into a color picker.
Pre-amble: Create a Zoho Creator form
- Create a form, I'm calling mine "Color Picker"
- Add a note field, I've given it the field link name "Note_ColorPicker_Css"
- Add a radio field type, I've called it "Color Picker"
- Add a single line text field, I'm calling it "Hexadecimal" [Key field that will be used by the application later - so perhaps rename this to 'Staff Color']
- Add another single line field, I'm calling it "RGB Value" [Optional: not required for the functionality of this demo but used in later application when including CSS opacity]
Step 1: Code to complete the radio options
This is the code when loading the form: Created or Edited > Load of the Form
// // I like defaulting variables v_DefaultColor = "#000000"; // // a color palette l_ColorPalette = List(); l_ColorPalette.add({"#FFFFFF","#EF1616","#EF8216","#EFB116","#5DC35A","#38D7BB","#16D0EF","#398EF3","#C516EF","#EF166F"}); l_ColorPalette.add({"#F3F3F3","#FDF4F4","#FDF6F4","#FDF9F4","#F5FAF5","#F4FBF9","#F4FBFD","#F4F7FE","#FAF4FD","#FDF4F5"}); l_ColorPalette.add({"#E7E7E7","#FCE7E7","#FCEDE7","#FCF2E7","#EAF5EA","#E8F8F3","#E7F7FC","#E8EEFD","#F5E7FC","#FCE7EB"}); l_ColorPalette.add({"#CBCBCB","#F9CCCC","#F9D8CC","#F9E4CC","#D2E9D1","#CEF0E7","#CCEEF9","#CEDBFA","#EACCF9","#F9CCD5"}); l_ColorPalette.add({"#AAAAAA","#F6ABAB","#F6C1AB","#F6D5AB","#B6DEB5","#AEE8DA","#ABE4F6","#AEC6F8","#DFABF6","#F6ABBB"}); l_ColorPalette.add({"#7C7C7C","#F27D7D","#F2A57D","#F2C47D","#92D191","#84E0CB","#7DDAF2","#85ADF5","#D27DF2","#F27D9B"}); l_ColorPalette.add({"#595959","#CC1111","#CC6E11","#CC9711","#4EA64C","#2EB79F","#11B1CC","#2F78D0","#A811CC","#CC115E"}); l_ColorPalette.add({"#000000","#8B0808","#8B4908","#8B6608","#337131","#1C7D6C","#08788B","#1D508E","#72088B","#8B083E"}); // // reset and set radio group options clear input.Color_Picker; for each l_ColorRow in l_ColorPalette { for each v_ThisColor in l_ColorRow { input.Color_Picker:ui.add(v_ThisColor); } }
- //
- // I like defaulting variables
- v_DefaultColor = "#000000";
- //
- // a color palette
- l_ColorPalette = List();
- l_ColorPalette.add({"#FFFFFF","#EF1616","#EF8216","#EFB116","#5DC35A","#38D7BB","#16D0EF","#398EF3","#C516EF","#EF166F"});
- l_ColorPalette.add({"#F3F3F3","#FDF4F4","#FDF6F4","#FDF9F4","#F5FAF5","#F4FBF9","#F4FBFD","#F4F7FE","#FAF4FD","#FDF4F5"});
- l_ColorPalette.add({"#E7E7E7","#FCE7E7","#FCEDE7","#FCF2E7","#EAF5EA","#E8F8F3","#E7F7FC","#E8EEFD","#F5E7FC","#FCE7EB"});
- l_ColorPalette.add({"#CBCBCB","#F9CCCC","#F9D8CC","#F9E4CC","#D2E9D1","#CEF0E7","#CCEEF9","#CEDBFA","#EACCF9","#F9CCD5"});
- l_ColorPalette.add({"#AAAAAA","#F6ABAB","#F6C1AB","#F6D5AB","#B6DEB5","#AEE8DA","#ABE4F6","#AEC6F8","#DFABF6","#F6ABBB"});
- l_ColorPalette.add({"#7C7C7C","#F27D7D","#F2A57D","#F2C47D","#92D191","#84E0CB","#7DDAF2","#85ADF5","#D27DF2","#F27D9B"});
- l_ColorPalette.add({"#595959","#CC1111","#CC6E11","#CC9711","#4EA64C","#2EB79F","#11B1CC","#2F78D0","#A811CC","#CC115E"});
- l_ColorPalette.add({"#000000","#8B0808","#8B4908","#8B6608","#337131","#1C7D6C","#08788B","#1D508E","#72088B","#8B083E"});
- //
- // reset and set radio group options
- clear input.Color_Picker;
- for each l_ColorRow in l_ColorPalette
- {
- for each v_ThisColor in l_ColorRow
- {
- input.Color_Picker:ui.add(v_ThisColor);
- }
- }
Step 2: Replace the text with colored boxes
// ... // // reset and set radio group options clear input.Color_Picker; for each l_ColorRow in l_ColorPalette { for each v_ThisColor in l_ColorRow { input.Color_Picker:ui.add("<span style='display:inline-block;width:20px;height:20px;background-color:"+v_ThisColor+"'> </span>"); } }
- // ...
- //
- // reset and set radio group options
- clear input.Color_Picker;
- for each l_ColorRow in l_ColorPalette
- {
- for each v_ThisColor in l_ColorRow
- {
- input.Color_Picker:ui.add("<span style='display:inline-block;width:20px;height:20px;background-color:"+v_ThisColor+"'> </span>");
- }
- }
Step 3: Inject some CSS in a notes field
// ... // // reset and set radio group options clear input.Color_Picker; for each l_ColorRow in l_ColorPalette { for each v_ThisColor in l_ColorRow { input.Color_Picker:ui.add("<span class='my-color-picker' style='background-color:"+v_ThisColor+";'> </span>"); } } // // inject some CSS v_CssStyle = "<style>"; v_CssStyle = v_CssStyle + ".zc-Color_Picker .my-color-picker{width:17px;height:17px;border:0 !important;margin-right:1px;}"; v_CssStyle = v_CssStyle + ".zc-Color_Picker .choice-table-cell span{padding:0 !important;}"; // get rid of circular inputs v_CssStyle = v_CssStyle + ".zc-Color_Picker .customRadio+label{display:none !important;}"; // float the radio options to the left to be horizontal rather than vertical v_CssStyle = v_CssStyle + ".zc-Color_Picker .choice-table-cell{float:left;padding:0 !important;line-height:0 !important;margin:-4px 0 0 0 !important;}"; v_CssStyle = v_CssStyle + ".zc-Color_Picker .choice-table-row{float:left;display:none;}"; // first row is slightly different v_CssStyle = v_CssStyle + ".zc-Color_Picker div:nth-child(-n+30) span label span{width:16px;height:16px;margin-right:0;border:1px solid #fff !important;}"; // first cell (white) needs a grey border v_CssStyle = v_CssStyle + ".zc-Color_Picker div:nth-child(-n+3) span label span{width:14px;height:14px;margin-right:2px;border:1px solid #eee !important;}"; // create a new row after every 10 boxes (1 box = choice-table-row + choice-table-cell + choice-table-row = 3 divs) v_CssStyle = v_CssStyle + ".zc-Color_Picker div:nth-child(30n+1){clear:both;}"; v_CssStyle = v_CssStyle + "</style>"; input.Note_ColorPicker_Css = v_CssStyle;
- // ...
- //
- // reset and set radio group options
- clear input.Color_Picker;
- for each l_ColorRow in l_ColorPalette
- {
- for each v_ThisColor in l_ColorRow
- {
- input.Color_Picker:ui.add("<span class='my-color-picker' style='background-color:"+v_ThisColor+";'> </span>");
- }
- }
- //
- // inject some CSS
- v_CssStyle = "<style>";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker .my-color-picker{width:17px;height:17px;border:0 !important;margin-right:1px;}";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker .choice-table-cell span{padding:0 !important;}";
- // get rid of circular inputs
- v_CssStyle = v_CssStyle + ".zc-Color_Picker .customRadio+label{display:none !important;}";
- // float the radio options to the left to be horizontal rather than vertical
- v_CssStyle = v_CssStyle + ".zc-Color_Picker .choice-table-cell{float:left;padding:0 !important;line-height:0 !important;margin:-4px 0 0 0 !important;}";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker .choice-table-row{float:left;display:none;}";
- // first row is slightly different
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div:nth-child(-n+30) span label span{width:16px;height:16px;margin-right:0;border:1px solid #fff !important;}";
- // first cell (white) needs a grey border
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div:nth-child(-n+3) span label span{width:14px;height:14px;margin-right:2px;border:1px solid #eee !important;}";
- // create a new row after every 10 boxes (1 box = choice-table-row + choice-table-cell + choice-table-row = 3 divs)
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div:nth-child(30n+1){clear:both;}";
- v_CssStyle = v_CssStyle + "</style>";
- input.Note_ColorPicker_Css = v_CssStyle;
Step 4: Popup and Dismiss Color Picker
To do this, we add one more option on the radio options which includes a button. When this input is clicked it displays the color palette and hides itself; when the color palette is clicked, it hides itself and shows the button.
Code for Onload of form:
// // default to black on blank form, if loading an existing record, the value stored will be used. v_DefaultColor = if(isBlank(input.Hexadecimal), "#000000", input.Hexadecimal); // // a color palette l_ColorPalette = List(); l_ColorPalette.add({"#FFFFFF","#EF1616","#EF8216","#EFB116","#5DC35A","#38D7BB","#16D0EF","#398EF3","#C516EF","#EF166F"}); l_ColorPalette.add({"#F3F3F3","#FDF4F4","#FDF6F4","#FDF9F4","#F5FAF5","#F4FBF9","#F4FBFD","#F4F7FE","#FAF4FD","#FDF4F5"}); l_ColorPalette.add({"#E7E7E7","#FCE7E7","#FCEDE7","#FCF2E7","#EAF5EA","#E8F8F3","#E7F7FC","#E8EEFD","#F5E7FC","#FCE7EB"}); l_ColorPalette.add({"#CBCBCB","#F9CCCC","#F9D8CC","#F9E4CC","#D2E9D1","#CEF0E7","#CCEEF9","#CEDBFA","#EACCF9","#F9CCD5"}); l_ColorPalette.add({"#AAAAAA","#F6ABAB","#F6C1AB","#F6D5AB","#B6DEB5","#AEE8DA","#ABE4F6","#AEC6F8","#DFABF6","#F6ABBB"}); l_ColorPalette.add({"#7C7C7C","#F27D7D","#F2A57D","#F2C47D","#92D191","#84E0CB","#7DDAF2","#85ADF5","#D27DF2","#F27D9B"}); l_ColorPalette.add({"#595959","#CC1111","#CC6E11","#CC9711","#4EA64C","#2EB79F","#11B1CC","#2F78D0","#A811CC","#CC115E"}); l_ColorPalette.add({"#000000","#8B0808","#8B4908","#8B6608","#337131","#1C7D6C","#08788B","#1D508E","#72088B","#8B083E"}); // // reset and set radio group options clear Color_Picker; for each l_ColorRow in l_ColorPalette { for each v_ThisColor in l_ColorRow { input.Color_Picker:ui.add("<span class='my-color-picker' style='background-color:" + v_ThisColor + ";'> </span>"); } } input.Color_Picker:ui.add("<div class='my-color-picker-button'><span class='my-color-picker'> </span></div>"); // // inject some CSS v_CssStyle = "<style>"; // when hiding the color palette, need to move the button higher to align it to the field label v_CssStyle = v_CssStyle + ".zc-Color_Picker{margin-top:-7px !important;}"; v_CssStyle = v_CssStyle + ".zc-Color_Picker div{display:none !important;}"; v_CssStyle = v_CssStyle + ".zc-Color_Picker div:last-child{display:block !important;}"; v_CssStyle = v_CssStyle + ".zc-Color_Picker .customRadio+label{display:none !important;}"; // make button match other inputs on the form v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button{width:30px;height:20px;border:1px solid #A9B7C3;padding: 3px 5px 0;transition: background 0.2s cubic-bezier(0.86, 0, 0.07, 1);border-radius: 2px !important;background: linear-gradient(to bottom, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%);}"; v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button span{width:100%;height:6px;border-radius:2px;background-color: " + v_DefaultColor + ";}"; v_CssStyle = v_CssStyle + "</style>"; input.Note_ColorPicker_Css = v_CssStyle;
- //
- // default to black on blank form, if loading an existing record, the value stored will be used.
- v_DefaultColor = if(isBlank(input.Hexadecimal), "#000000", input.Hexadecimal);
- //
- // a color palette
- l_ColorPalette = List();
- l_ColorPalette.add({"#FFFFFF","#EF1616","#EF8216","#EFB116","#5DC35A","#38D7BB","#16D0EF","#398EF3","#C516EF","#EF166F"});
- l_ColorPalette.add({"#F3F3F3","#FDF4F4","#FDF6F4","#FDF9F4","#F5FAF5","#F4FBF9","#F4FBFD","#F4F7FE","#FAF4FD","#FDF4F5"});
- l_ColorPalette.add({"#E7E7E7","#FCE7E7","#FCEDE7","#FCF2E7","#EAF5EA","#E8F8F3","#E7F7FC","#E8EEFD","#F5E7FC","#FCE7EB"});
- l_ColorPalette.add({"#CBCBCB","#F9CCCC","#F9D8CC","#F9E4CC","#D2E9D1","#CEF0E7","#CCEEF9","#CEDBFA","#EACCF9","#F9CCD5"});
- l_ColorPalette.add({"#AAAAAA","#F6ABAB","#F6C1AB","#F6D5AB","#B6DEB5","#AEE8DA","#ABE4F6","#AEC6F8","#DFABF6","#F6ABBB"});
- l_ColorPalette.add({"#7C7C7C","#F27D7D","#F2A57D","#F2C47D","#92D191","#84E0CB","#7DDAF2","#85ADF5","#D27DF2","#F27D9B"});
- l_ColorPalette.add({"#595959","#CC1111","#CC6E11","#CC9711","#4EA64C","#2EB79F","#11B1CC","#2F78D0","#A811CC","#CC115E"});
- l_ColorPalette.add({"#000000","#8B0808","#8B4908","#8B6608","#337131","#1C7D6C","#08788B","#1D508E","#72088B","#8B083E"});
- //
- // reset and set radio group options
- clear Color_Picker;
- for each l_ColorRow in l_ColorPalette
- {
- for each v_ThisColor in l_ColorRow
- {
- input.Color_Picker:ui.add("<span class='my-color-picker' style='background-color:" + v_ThisColor + ";'> </span>");
- }
- }
- input.Color_Picker:ui.add("<div class='my-color-picker-button'><span class='my-color-picker'> </span></div>");
- //
- // inject some CSS
- v_CssStyle = "<style>";
- // when hiding the color palette, need to move the button higher to align it to the field label
- v_CssStyle = v_CssStyle + ".zc-Color_Picker{margin-top:-7px !important;}";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div{display:none !important;}";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div:last-child{display:block !important;}";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker .customRadio+label{display:none !important;}";
- // make button match other inputs on the form
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button{width:30px;height:20px;border:1px solid #A9B7C3;padding: 3px 5px 0;transition: background 0.2s cubic-bezier(0.86, 0, 0.07, 1);border-radius: 2px !important;background: linear-gradient(to bottom, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%);}";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button span{width:100%;height:6px;border-radius:2px;background-color: " + v_DefaultColor + ";}";
- v_CssStyle = v_CssStyle + "</style>";
- input.Note_ColorPicker_Css = v_CssStyle;
if(!isNull(input.Color_Picker) && !input.Color_Picker.contains("button")) { v_HeximalRef = input.Color_Picker.getsuffix("background-color:").getprefix(";"); input.Hexadecimal = v_HeximalRef; // optional function here but used in my real-world case input.RGB_Value = thisapp.ColorPicker.fn_HexToRGB(v_HeximalRef); // // inject some CSS v_CssStyle = "<style>"; // when hiding the color palette, need to move the button higher to align it to the field label v_CssStyle = v_CssStyle + ".zc-Color_Picker{margin-top:-7px !important;}"; // hide all the divs under the color palette v_CssStyle = v_CssStyle + ".zc-Color_Picker div{display:none !important;}"; // show the last div (the button) under the color palette v_CssStyle = v_CssStyle + ".zc-Color_Picker div:last-child{display:block !important;}"; // hide the circular inputs v_CssStyle = v_CssStyle + ".zc-Color_Picker .customRadio+label{display:none !important;}"; // make button match other inputs on the form v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button{width:30px;height:20px;border:1px solid #A9B7C3;padding: 3px 5px 0;transition: background 0.2s cubic-bezier(0.86, 0, 0.07, 1);border-radius: 2px !important;background: linear-gradient(to bottom, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%);}"; v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button span{width:100%;height:6px;border-radius:2px;background-color: " + input.Hexadecimal + ";}"; v_CssStyle = v_CssStyle + "</style>"; input.Note_ColorPicker_Css = v_CssStyle; } else if(!isNull(input.Color_Picker) && input.Color_Picker.contains("button")) { // // inject some CSS v_CssStyle_Popup = "<style>"; v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .my-color-picker{width:17px;height:17px;border:0 !important;margin-right:1px;}"; v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .choice-table-cell span{padding:0 !important;}"; // get rid of circular inputs v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .customRadio+label{display:none !important;}"; // align to left v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .choice-table-cell{float:left;padding:0 !important;line-height:0 !important;margin:-4px 0 0 0 !important;}"; v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .choice-table-row{float:left;display:none;}"; // first row is slightly different v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:nth-child(-n+30) span label span{width:16px;height:16px;margin-right:0;border:1px solid #fff !important;}"; // first cell (white) needs a grey border v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:nth-child(-n+3) span label span{width:14px;height:14px;margin-right:2px;border:1px solid #eee !important;}"; // create a new row after every 10 boxes (1 box = choice-table-row + choice-table-cell + choice-table-row = 3 divs) v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:nth-child(30n+1){clear:both;}"; // hide the button v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:last-child{display:none !important;}"; v_CssStyle_Popup = v_CssStyle_Popup + "</style>"; input.Note_ColorPicker_Css = v_CssStyle_Popup; }
- if(!isNull(input.Color_Picker) && !input.Color_Picker.contains("button"))
- {
- v_HeximalRef = input.Color_Picker.getsuffix("background-color:").getprefix(";");
- input.Hexadecimal = v_HeximalRef;
- // optional function here but used in my real-world case
- input.RGB_Value = thisapp.ColorPicker.fn_HexToRGB(v_HeximalRef);
- //
- // inject some CSS
- v_CssStyle = "<style>";
- // when hiding the color palette, need to move the button higher to align it to the field label
- v_CssStyle = v_CssStyle + ".zc-Color_Picker{margin-top:-7px !important;}";
- // hide all the divs under the color palette
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div{display:none !important;}";
- // show the last div (the button) under the color palette
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div:last-child{display:block !important;}";
- // hide the circular inputs
- v_CssStyle = v_CssStyle + ".zc-Color_Picker .customRadio+label{display:none !important;}";
- // make button match other inputs on the form
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button{width:30px;height:20px;border:1px solid #A9B7C3;padding: 3px 5px 0;transition: background 0.2s cubic-bezier(0.86, 0, 0.07, 1);border-radius: 2px !important;background: linear-gradient(to bottom, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%);}";
- v_CssStyle = v_CssStyle + ".zc-Color_Picker div.my-color-picker-button span{width:100%;height:6px;border-radius:2px;background-color: " + input.Hexadecimal + ";}";
- v_CssStyle = v_CssStyle + "</style>";
- input.Note_ColorPicker_Css = v_CssStyle;
- }
- else if(!isNull(input.Color_Picker) && input.Color_Picker.contains("button"))
- {
- //
- // inject some CSS
- v_CssStyle_Popup = "<style>";
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .my-color-picker{width:17px;height:17px;border:0 !important;margin-right:1px;}";
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .choice-table-cell span{padding:0 !important;}";
- // get rid of circular inputs
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .customRadio+label{display:none !important;}";
- // align to left
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .choice-table-cell{float:left;padding:0 !important;line-height:0 !important;margin:-4px 0 0 0 !important;}";
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker .choice-table-row{float:left;display:none;}";
- // first row is slightly different
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:nth-child(-n+30) span label span{width:16px;height:16px;margin-right:0;border:1px solid #fff !important;}";
- // first cell (white) needs a grey border
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:nth-child(-n+3) span label span{width:14px;height:14px;margin-right:2px;border:1px solid #eee !important;}";
- // create a new row after every 10 boxes (1 box = choice-table-row + choice-table-cell + choice-table-row = 3 divs)
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:nth-child(30n+1){clear:both;}";
- // hide the button
- v_CssStyle_Popup = v_CssStyle_Popup + ".zc-Color_Picker div:last-child{display:none !important;}";
- v_CssStyle_Popup = v_CssStyle_Popup + "</style>";
- input.Note_ColorPicker_Css = v_CssStyle_Popup;
- }
Source(s):
- Joel Lipman - Zoho Creator: Radio group into Calendar Carousel
- Joel Lipman - Zoho Deluge: Convert Hex to RGB