I'm using DNN 9.13 and 2sxc 17. I'm trying to create a custom dropdown field in my Content Type that will use code to dynamically add this year and next year to the text options. So the list will always be updated with options like Fall 2024 Spring 2025 Fall 2025 Spring 2026 and I won't have to add new years all the time.
I've created a custom field following this tutorial
My index.js file looks like
(() => {
const tagName = 'field-string-dropdown-graduation-date';
class StringDropdownGraduationDate extends HTMLElement {
/* Constructor for WebComponents - the first line must always be super() */
constructor() {
super();
console.log('FYI: StringDropdownGraduationDate just constructed!');
this.attachShadow({ mode: 'open' });
this.options = [{value: "1", label: "Option 1"}, {value: "2", label: "Option 2"}];
this.selectedValue = '';
this.render();
}
render() {
this.shadowRoot.innerHTML = `
<style>
select {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
}
</style>
<select>
${this.options.map(option => `
<option value="${option.value}" ${option.value === this.selectedValue ? 'selected' : ''}>
${option.label}
</option>
`).join('')}
</select>
`;
this.shadowRoot.querySelector('select').addEventListener('change', (event) => {
this.selectedValue = event.target.value;
console.log('selected ' + this.selectedValue);
this.dispatchEvent(new CustomEvent('change', { detail: this.selectedValue }));
});
}
/* connectedCallback() is the standard callback when the component has been attached */
connectedCallback() {
console.log('FYI: StringDropdownGraduationDate just got connected!');
if (this.hasAttribute('options')) {
this.options = JSON.parse(this.getAttribute('options'));
}
if (this.hasAttribute('value')) {
this.selectedValue = this.getAttribute('value');
}
this.render();
}
static get observedAttributes() {
return ['options', 'value'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'options') {
this.options = JSON.parse(newValue);
} else if (name === 'value') {
this.selectedValue = newValue;
}
this.render();
}
/** disconnectedCallback() is a standard callback for clean-up */
disconnectedCallback() {
console.log('FYI: StringDropdownGraduationDate getting disconnected - nothing to clean up');
}
}
// Register this web component
customElements.define(tagName, StringDropdownGraduationDate);
})();
This works fine as an html dropdown in the content type form, and I can even confirm that the event listener sees the selected value. screenshot
But I've seen that 2sxc dropdown elements update an input field and that's the value that is saved when the form is saved (i.e., what I select is not saved). Do I need to add an input field and how would I connect it to the dropdown selection? Or is there another way?
I also see that other dropdown elements are constructed as a div, not a select list. I'm new to Web Components, so I'm looking for a way to do something fairly basic and build from there.
Thanks for the help!
There is a this.connector
object which has the API for communicating with the rest of the system. It will be attached by the form automatically.
On that, you'll use this.connector.data.update(newValue)
.
Best check out the tutorials https://2sxc.org/dnn-tutorials/en/razor/tut/ui-fields