Populate Fields via Drop-down selection
-
Hi
I’m not sure how to best describe what I am after so I will give it to you belts and braces and hopefully you will see through the trees for the wood!
I have a list of 30/40 venues and each venue, upon selection, will offer 5/6 bits of information, that I would like to display below (somewhere is good!). I’m seeing this done via a drop-down list that, once a branch has been selected, will display the details
These bits of info are Branch, Contact Name, Position, Number, Email, Website.
I would like to present these so they look styled info possible, but just there if nothing else. And the email will ideally be a mailTo: link and the website a href.
The reason for this is to reduce the amount of space required to list all 30/40 branches upon a single page and speed up the location of individual info.
I am not great with code but know enough to get by – I’m imagining it might be a MySQL database job but just not sure how. If there is a plugin that handles the very same requirements – please share.
Many thanks
Simon
-
I don’t know of a plugin but if you want to accomplish this, the simplest way is to use Javascript for everything.
I will give you some details below:
- You can save all the venues along with their respective branch information inside JSON data.
- Set an event listener on the drop-down control. The function will identify the selected venue and then lookup its details from the JSON data.
- Display the found informations in a placeholder. (It will be a DIV html tag for example)
- All necessary formatting of the information will also be done through Javascript.
I hope this will help.
I agree that JavaScript can manage this, but the question arises, where does the JSON come from? The answer may be obvious for some, but it’s less clear with custom data. JSON data can be had from the REST API. This could work for custom field data like post meta, but if the source data resides in a custom table or something you’d need either a custom API endpoint or you’d get the data via Ajax or a similar request.
Alternately, information could be output from PHP, either as direct output or as inline script declarations.
@nomisrenrut > Please can you tell us :
- If the venues are static or dynamic
- If they are dynamic, who will be in charge of updating them ? Is it the administrator or your users.
Depending on that, we can propose you the best solution.
Thank you both … the data will be input once and will only ever change if I or someone who will edit the website changes it due to staff changes (which isnt usually that often), it will not need to change on the fly.
I would need to learn how to sort this function out – any good website you can point me to or youtube channels I would be very grateful. I know some but as always, spread thin across my solo endeavours.
Im guess the info is stored alongside the wordpress installation? How is the data called to the page? All that good stuff.
Many thanks for taking the time to answer thus far. Most appreciated
@nomisrenrut > As the data changes very rarely, you don’t need any user interface to change it. The best way to handle your problem is then to use Javascript.
However, note that extracting the data and populating the drop down field may not be enough as you may need to process the selected venue in the back end.
Here, I will give you a Javascript code to solve your problem. You can slightly modify it to suit your needs. That script will read the data and then according to the selected venue, it will display the formatted info for the corresponding branch.
=====
JSON
=====[ { "name": "Red Rocks Amphitheatre", "contact_name": "Amanda Johnson", "position": "General Manager", "number": "(303) 697-4939", "email": "amanda.johnson@redrocksonline.com", "website": "https://www.redrocksonline.com/" }, { "name": "Madison Square Garden", "contact_name": "Michael Rodriguez", "position": "Events Coordinator", "number": "(212) 465-MSG1 (6741)", "email": "michael.rodriguez@msg.com", "website": "https://www.msg.com/madison-square-garden" } ]First, you will need to create the JSON data. You will for example store it in your WordPress upload folder :
/wp-content/uploads/venues.jsonThis JSON data will contain all the venues and their respective branch. If one day, you need to update the venues, just change this file.
========
HTML / CSS
========Here is the HTML code for the drop down and the placeholder for the branch. The solution you will have to choose for applying that code will depend on the way you implement your form. (Form plugin ? Direct change on WordPress templates ? etc.)
<style> .hidden { display: none; } </style> <form> <select id="venue-ctrl"></select> <div id="venue-info" class="hidden"> <div id="venue__name"></div> <div id="venue__contact_name"></div> <div id="venue__position"></div> <div id="venue__number"></div> <div id="venue__email"></div> <div id="venue__website"></div> </div> </form>=========
JAVASCRIPT
=========(() => { /* ****************************************** */ /* change the following constants as needed */ /* ****************************************** */ const venueFilename = "/wp-content/uploads/venues.json"; // JSON file name const venueCtrlId = 'venue-ctrl'; // ID of the drop-down const venueInfoId = 'venue-info'; // ID of the DIV placholder to display the branch info const buildLinkElement = (value, link = value) => { const el = document.createElement('a'); el.setAttribute('href', link); el.appendChild(new Text(value)); return el; }; const fieldProcessor = { "name": v => new Text(v), "contact_name": v => new Text(v), "position": v => new Text(v), "number": v => new Text(v), "email": v => buildLinkElement(v, 'mailto:' + v), "website": v => buildLinkElement(v) }; function loadVenue() { fetch(venueFilename) .then(response => { if (!response.ok) { throw new Error('Unable to load the venue file'); } return response.json(); }) .then(data => { initVenue(data); }) .catch(error => { alert(error); }); } function initVenue(venues) { const venueCtrl = document.getElementById(venueCtrlId); const venueInfoEl = document.getElementById(venueInfoId); /* Populating the drop-down field */ venueCtrl.innerHTML = '<option value="0">Select a venue</option>'; venues.forEach((venue, i) => { const name = venue.name; const venueItemObj = document.createElement('option'); venueItemObj.setAttribute('value', i + 1); venueItemObj.appendChild(new Text(name)); venueCtrl.appendChild(venueItemObj); }); /* Set event listener on drop-down when selection changes */ venueCtrl.addEventListener('change', () => { const selectedId = venueCtrl.value - 1; if (selectedId < 0) { venueInfoEl.classList.add('hidden'); return; } venueInfoEl.classList.remove('hidden'); const venue = venues[selectedId]; const fieldList = [ 'name', 'contact_name', 'position', 'number', 'email', 'website' ]; fieldList.forEach(fieldName => { const el = document.getElementById("venue__" + fieldName); if (el) { el.textContent = ''; if (venue[fieldName]) { const fieldValue = venue[fieldName]; el.appendChild(fieldProcessor[fieldName](fieldValue)); } } }); }); } document.addEventListener('DOMContentLoaded', () => { loadVenue(); }); })();I hope this will help.
Mandresi …. blown away with your generosity! Many thanks for this – I shall give it a whirl and update you on what should be a favourable outcome.
Kudos to you π
You’re welcome. Have fun π
@imandresi – code works a treat thank you … however, now i need to change it to cope with how i want to display the info. I have used tabs within divi theme and places the code within each tab – national, regional and recreational … and my attempt works to a point, ive made 3 js files reflecting each section, and the same for the html and json – the issue is that even though I have the different lists showing under the different tabs – when i select a branch in tab 2 , it displays the region, but the info appears under the drop down under tab 1. i will paste my attempt at changing the code, would you have any ideas where I have gone wrong please? Im sure im close, just missing something that denotes the different tab!?
(() => { /* ****************************************** */ /* change the following constants as needed */ /* ****************************************** */ const nationalVenueFilename = "/wp-content/uploads/nationalVenues.json"; // JSON file name const nationalVenueCtrlId = 'nationalVenue-ctrl'; // ID of the drop-down const nationalVenueInfoId = 'nationalVenue-info'; // ID of the DIV placholder to display the branch info const buildLinkElement = (value, link = value) => { const el = document.createElement('a'); el.setAttribute('href', link); el.appendChild(new Text(value)); return el; }; const fieldProcessor = { "name": v => new Text(v), "contact_name": v => new Text(v), "position": v => new Text(v), "number": v => new Text(v), "email": v => buildLinkElement(v, 'mailto:' + v), "website": v => buildLinkElement(v) }; function loadVenue() { fetch(nationalVenueFilename) .then(response => { if (!response.ok) { throw new Error('Unable to load the venue file'); } return response.json(); }) .then(data => { initVenue(data); }) .catch(error => { alert(error); }); } function initVenue(venues) { const nationalVenueCtrl = document.getElementById(nationalVenueCtrlId); const nationalVenueInfoEl = document.getElementById(nationalVenueInfoId); /* Populating the drop-down field */ nationalVenueCtrl.innerHTML = '<option value="0">Select a National Branch </option>'; venues.forEach((venue, i) => { const name = venue.name; const nationalVenueItemObj = document.createElement('option'); nationalVenueItemObj.setAttribute('value', i + 1); nationalVenueItemObj.appendChild(new Text(name)); nationalVenueCtrl.appendChild(nationalVenueItemObj); }); /* Set event listener on drop-down when selection changes */ nationalVenueCtrl.addEventListener('change', () => { const selectedId = nationalVenueCtrl.value - 1; if (selectedId < 0) { nationalVenueInfoEl.classList.add('hidden'); return; } nationalVenueInfoEl.classList.remove('hidden'); const venue = venues[selectedId]; const fieldList = [ 'name', 'contact_name', 'position', 'number', 'email', 'website' ]; fieldList.forEach(fieldName => { const el = document.getElementById("venue__" + fieldName); if (el) { el.textContent = ''; if (venue[fieldName]) { const fieldValue = venue[fieldName]; el.appendChild(fieldProcessor[fieldName](fieldValue)); } } }); }); } document.addEventListener('DOMContentLoaded', () => { loadVenue(); }); })();js^^^
<style> .hidden { display: none; } .space { margin-bottom: 25px; } </style> <form> <select id="nationalVenue-ctrl" class="space"></select> <div id="nationalVenue-info" class="hidden"> <div id="nationalVenue__name">Name: </div> <div id="nationalVenue__contact_name"></div> <div id="nationalVenue__position"></div> <div id="nationalVenue__number"></div> <div id="nationalVenue__email"></div> <div id="nationalVenue__website"></div> <div id="nationalVenue__introduction"></div> </div> </form>html^^
Also – tried to style from within divi and it didnt work – nor does the styling i added to the html (is just gets dropped when pasted in) – what is the best practise for trying to make the details look as the rest of the page?
Maybe it cannot be changed – anyway – ill keep trying meantime.
Many thanks in advance
Si
@nomisrenrut – Here, I have modified the code to handle the tabs you said.
I also saw that in your code you tried to use an additional field named “introduction”, so I had taken that into account when doing the code update. Now the code can handle any tab you want. You just have to create the HTML for the each tab and initialize the javascript code. No need to duplicate that latter.
Concerning the styling, I would suggest that you put your styles in the style.css of you child theme. Don’t forget to load that file in your functions.php otherwise it would not be applied.
You can have a look at below site for more info:
https://www.elegantthemes.com/blog/divi-resources/divi-child-theme#what-you-will-need-to-create-a-divi-child-theme=========================== JSON: national-venues.json =========================== [ { "name": "Red Rocks Amphitheatre", "contact_name": "Amanda Johnson", "position": "General Manager", "number": "(303) 697-4939", "email": "amanda.johnson@redrocksonline.com", "website": "https://www.redrocksonline.com/", "introduction": "<p><b>Amanda Johnson</b> orchestrates seamless events that blend the magic of music with the breathtaking surroundings, creating unforgettable experiences for concert-goers.</p>" }, { "name": "Madison Square Garden", "contact_name": "Michael Rodriguez", "position": "Events Coordinator", "number": "(212) 465-MSG1 (6741)", "email": "michael.rodriguez@msg.com", "website": "https://www.msg.com/madison-square-garden", "introduction": "<p><b>Michael Rodriguez</b> seamlessly orchestrates events as the dedicated <i>Events Coordinator</i> at the iconic <b>Madison Square Garden</b>, ensuring unforgettable experiences for audiences in the heart of New York City.</p>" } ]The CSS file has to be put inside style.css of your child theme. Feel free to modify it as needed.
===== CSS ===== .space { margin-bottom: 25px; } /* CSS formatting for the branch info */ .venue__name {} .venue__contact_name {} .venue__position {} .venue__number {} .venue__email {} .venue__website {} .venue__introduction {}====== HTML ====== <!-- HTML code for National venues --> <form> <select id="nationalVenue-ctrl" class="space"></select> <div id="nationalVenue-info"></div> </form> <!-- HTML code for regional venues --> <form> <select id="regionalVenue-ctrl" class="space"></select> <div id="regionalVenue-info"></div> </form>============ Javascript ============ function processJSONVenue({venueFilename, venueCtrlId, venueInfoId, dropDownLabel}) { /** * This function creates an HTML link from a value. * It can be used to generate website, email or tel link */ const buildLink = (value, link = value) => { return<a href="${link}">${value}</a>; }; /** * The following object comprises properties, each housing * a function that produces HTML code responsible for formatting * the branch item associated with the property's name. */ const fieldFormat = { "name": v => 'Name: ' + v, "email": v => buildLink(v, 'mailto:' + v), "website": v => buildLink(v), }; let fieldList = []; function loadVenue() { fetch(venueFilename) .then(response => { if (!response.ok) { throw new Error('Unable to load the venue file'); } return response.json(); }) .then(data => { fieldList = data[0] ? Object.keys(data[0]) : []; initVenue(data); }) .catch(error => { alert(error); }); } function initVenue(venues) { const venueCtrl = document.getElementById(venueCtrlId); const venueInfoEl = document.getElementById(venueInfoId); /* Populating the drop-down field */ venueCtrl.innerHTML =<option value="0">${dropDownLabel}</option>; venues.forEach((venue, i) => { const name = venue.name; const venueItemObj = document.createElement('option'); venueItemObj.setAttribute('value', i + 1); venueItemObj.appendChild(new Text(name)); venueCtrl.appendChild(venueItemObj); }); /* Set event listener on drop-down when selection changes */ venueCtrl.addEventListener('change', () => { const selectedId = venueCtrl.value - 1; venueInfoEl.textContent = ''; if (selectedId < 0) { return; } const venue = venues[selectedId]; fieldList.forEach(fieldName => { if (venue[fieldName]) { const fieldValue = venue[fieldName]; /* formats the field if a formatting function exists */ const fieldContent = fieldFormat[fieldName] ? fieldFormat[fieldName](fieldValue) : fieldValue; const el = document.createElement('div'); el.className = "venue__" + fieldName; el.innerHTML = fieldContent; venueInfoEl.appendChild(el); } }); }); } document.addEventListener('DOMContentLoaded', () => { loadVenue(); }); } /* ****************************************** */ /* update the following parameters as needed */ /* ****************************************** */ processJSONVenue( { venueFilename: '/wp-content/uploads/national-venues.json', // JSON file name venueCtrlId: 'nationalVenue-ctrl', // ID of the drop-down venueInfoId: 'nationalVenue-info', // ID of the DIV placeholder to display the branch info dropDownLabel: 'Select a National Branch' } ); processJSONVenue( { venueFilename: '/wp-content/uploads/regional-venues.json', // JSON file name venueCtrlId: 'regionalVenue-ctrl', // ID of the drop-down venueInfoId: 'regionalVenue-info', // ID of the DIV placeholder to display the branch info dropDownLabel: 'Select a Regional Branch' } );I hope this help.
You’re so very kind – many thanks for the help. I love to learn new things, just figure my pea brain has limited space these days and if I don’t use the code often I tend to forget. but this stuff is an awesome reference,
Sorry re the ‘introduction’. i thought about adding this but then changed my mind. But I’m sure I can take that out. or leave it if it isn’t doing any harm.
Now to check over your code and see where i wetn wrong!
Thanks again
You’re welcome! Happy to help. Enjoy π
Sorry to ask again but it doesn’t seem to work this time around ….
Ive got a book with the drop down icon but nothing is loading, Ive check the link address and they are all correct (and I did it the exact same way as i did before which worked).
This is the slighly changed Java
============ Javascript ============ function processJSONVenue({venueFilename, venueCtrlId, venueInfoId, dropDownLabel}) { /** * This function creates an HTML link from a value. * It can be used to generate website, email or tel link */ const buildLink = (value, link = value) => { return <a href="${link}">${value}</a>; }; /** * The following object comprises properties, each housing * a function that produces HTML code responsible for formatting * the branch item associated with the property's name. */ const fieldFormat = { "name": v => 'Name: ' + v, "email": v => buildLink(v, 'mailto:' + v), "website": v => buildLink(v), }; let fieldList = []; function loadVenue() { fetch(venueFilename) .then(response => { if (!response.ok) { throw new Error('Unable to load the venue file'); } return response.json(); }) .then(data => { fieldList = data[0] ? Object.keys(data[0]) : []; initVenue(data); }) .catch(error => { alert(error); }); } function initVenue(venues) { const venueCtrl = document.getElementById(venueCtrlId); const venueInfoEl = document.getElementById(venueInfoId); /* Populating the drop-down field */ venueCtrl.innerHTML = <option value="0">${dropDownLabel}</option>; venues.forEach((venue, i) => { const name = venue.name; const venueItemObj = document.createElement('option'); venueItemObj.setAttribute('value', i + 1); venueItemObj.appendChild(new Text(name)); venueCtrl.appendChild(venueItemObj); }); /* Set event listener on drop-down when selection changes */ venueCtrl.addEventListener('change', () => { const selectedId = venueCtrl.value - 1; venueInfoEl.textContent = ''; if (selectedId < 0) { return; } const venue = venues[selectedId]; fieldList.forEach(fieldName => { if (venue[fieldName]) { const fieldValue = venue[fieldName]; /* formats the field if a formatting function exists */ const fieldContent = fieldFormat[fieldName] ? fieldFormat[fieldName](fieldValue) : fieldValue; const el = document.createElement('div'); el.className = "venue__" + fieldName; el.innerHTML = fieldContent; venueInfoEl.appendChild(el); } }); }); } document.addEventListener('DOMContentLoaded', () => { loadVenue(); }); } /* ****************************************** */ /* update the following parameters as needed */ /* ****************************************** */ processJSONVenue( { venueFilename: '/wp-content/uploads/national-venues.json', // JSON file name venueCtrlId: 'nationalVenue-ctrl', // ID of the drop-down venueInfoId: 'nationalVenue-info', // ID of the DIV placeholder to display the branch info dropDownLabel: 'Select a National Branch' } ); processJSONVenue( { venueFilename: '/wp-content/uploads/regional-venues.json', // JSON file name venueCtrlId: 'regionalVenue-ctrl', // ID of the drop-down venueInfoId: 'regionalVenue-info', // ID of the DIV placeholder to display the branch info dropDownLabel: 'Select a Regional Branch' } ); processJSONVenue( { venueFilename: '/wp-content/uploads/recreational-venues.json', // JSON file name venueCtrlId: 'recreationalVenue-ctrl', // ID of the drop-down venueInfoId: 'recreationalVenue-info', // ID of the DIV placeholder to display the branch info dropDownLabel: 'Select a Recreational Branch' } );and this is the screen grab of the what I am seeing.
It just doesn’t seem to want to find the ‘info’
-
This reply was modified 2 years, 1 month ago by
nomisrenrut.
book = box !! sry
I guess it must be a Javascript error. When I look at the code you modified there is something missing. The correct code is:
const buildLink = (value, link = value) => { return '<a href="${link}">${value}</a>'; };There should be a backtick
( ` )symbol surrounding the<a href ></a>HTML tag.Please, when you copy the code, replace the quote with a backtick as it seems that there is a bug in the forum editor and the backtick is not displayed.
The topic ‘Populate Fields via Drop-down selection’ is closed to new replies.