import { SelectComponent, pageCss } from "https://fhnw-ramonamarti.github.io/Kolibri/src/examples/select-new/selectComponent.js";
import * as Service from "./dataService.js";
// load styles for new component
const style = document.createElement("style");
style.textContent = pageCss;
document.querySelector("head").append(style);
/**
* helper to replace elements to form
* @param {*} id - id of the html element to place the projected elements in
* @param {*} labelElement - new label to relape in the form
* @param {*} inputElement - new input element to relape in the form
* @example
addSelectViewToUi("task1", lunchLabelElement, lunchInputElement);
*/
const addSelectViewToUi = (id, labelElement, inputElement) => {
const inputContainer = document.getElementById(id);
const labelContainer = document.getElementById(id + "-label");
labelContainer.replaceWith(labelElement);
inputContainer.replaceWith(inputElement);
}
// NOTE: You can read about our project in README.md file.
// Please follow the TODO's for the five tasks.
// The tasks are structured in the UI as follows:
// 1. Demo container with the usage of an existing way to create a selection input.
// 2. Task container with TODO's placeholder is positioned in the form
// where the new componenent should be fit in.
// ----- TASK 1 ----------
/*
TODO: Create a selection input using our new component.
The label should be 'Lunch' and the name 'lunch'.
The resulting component should provide 1 column with the data.
The data is provided by the function `Service.getLunchTypes()`
and can be used to fulfill the task.
To add the created view elements to the form you can use
the function `addSelectViewToUi` from the top.
The id of the container to fill the view elements in is 'task1-lunch'.
*/
// TODO: SOLUTION TASK 1 HERE
// ----- TASK 2 ----------
// ----- TASK 2.1 --------
/*
TODO: Create a selection input using our new component.
The label should be 'Home region' and the name 'home-region'.
The resulting component should provide 2 column with the value data and categories.
The value data is provided by the function `Service.getRegionsByCountryChDeAt()`,
the categories are provided by the function `Service.getCountriesChDeAt()`
and they can be used to fulfill the task.
To add the created view elements to the form you can use
the function `addSelectViewToUi` from the top.
The id of the container to fill the data view elements is 'task2-home-region'.
*/
// TODO: SOLUTION TASK 2.1 HERE
// ----- TASK 2.2 --------
/*
TODO: Create a selection input using our new component.
The label should be 'Birth region' and the name 'birth-region'.
The resulting component should provide 2 column with the value data and categories.
The value data is provided by the function `Service.getRegionsByCountry()`,
the categories are provided by the function `Service.getCountries()`
and they can be used to fulfill the task.
To add the created view elements to the form you can use
the function `addSelectViewToUi` from the top.
The id of the container to fill the data view elements is 'task2-birth-region'.
*/
// TODO: SOLUTION TASK 2.2 HERE
// ----- TASK 2.3 --------
/*
TODO: Create a selection input using our new component.
The label should be 'Birth year' and the name 'birth-year'.
The resulting component should provide 2 column with the value data and categories.
The value data is provided by the function `Service.getYearsByDecade()`,
the categories are provided by the function `Service.getDecades()`
and they can be used to fulfill the task.
To add the created view elements to the form you can use
the function `addSelectViewToUi` from the top.
The id of the container to fill the data view elements is 'task2-birth-year'.
*/
// TODO: SOLUTION TASK 2.3 HERE
// ------------------------
// Please fill out the question form to give us feedback about how the tasks worked.
// Please send your solution as a zip back to Ramona Marti on MS Teams.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Auswahlkomponente User Test</title>
<link
rel="shortcut icon"
type="image/png"
href="https://fhnw-ramonamarti.github.io/Kolibri/img/logo/logo-60x54.png"
/>
<link
rel="stylesheet"
href="https://fhnw-ramonamarti.github.io/Kolibri/css/kolibri-base.css"
/>
<style>
.newComponent {
color: red;
font-weight: bold;
}
label {
display: flex;
align-items: center;
}
select,
input {
border: #ccc solid 1px;
font-size: 1rem;
height: 2rem;
border-radius: 4px;
}
.task .select-input-component {
width: 320px;
}
</style>
</head>
<body>
<div class="demo" id="demo1"></div>
<div class="task" id="task1"></div>
<div class="demo" id="demo2"></div>
<div class="task" id="task2"></div>
<div class="demo" id="demo3"></div>
<div class="task" id="task3"></div>
<script type="module" src="starter.js"></script>
<script type="module" src="userTesting.js"></script>
</body>
</html>
import { projectForm, FORM_CSS } from "https://fhnw-ramonamarti.github.io/Kolibri/src/kolibri/projector/simpleForm/simpleFormProjector.js"
import { SimpleFormController } from "https://fhnw-ramonamarti.github.io/Kolibri/src/kolibri/projector/simpleForm/simpleFormController.js"
import { TEXT, CHOICE, COMBOBOX } from "https://fhnw-ramonamarti.github.io/Kolibri/src/kolibri/util/dom.js";
import * as Service from "./dataService.js";
// load style
const style = document.createElement("style");
style.textContent = FORM_CSS;
document.querySelector("head").append(style);
// prepare filling container
const fillContainer = (id, title, buildForm) => {
const formHolder = document.getElementById(id);
if (null != formHolder) {
const [fieldset] = buildForm();
formHolder.innerHTML = `<h3>${title}</h3>`;
formHolder.append(fieldset);
}
};
// prepare containes to do the tasks in
const replaceField = (id, name) => {
const inputElement = document.getElementById(id).querySelector(`[name=${name}]`);
const inputId = inputElement.id;
const fieldset = inputElement.closest("fieldset")
const labelElement = fieldset.querySelector(`[for="${inputId}"]`);
const spanElement = fieldset.querySelector(`span[data-id="${inputId}"]`);
const containerLabel = document.createElement("span");
containerLabel.id = id + "-" + name + "-label";
const container = document.createElement("span");
container.id = id + "-" + name;
container.textContent = "TODO";
container.classList.add("newComponent");
spanElement.replaceWith(container);
labelElement.replaceWith(containerLabel);
return [containerLabel, container];
};
// ----- DEMO 1 --------
const demo1 = () => {
/** @type { Array<OptionType> } */
const types = Service.getLunchTypes().map((types) => ({ value: types }));
const formStructure = [
{ value: "", label: "Name", name: "name", type: TEXT },
{ value: "", label: "Lunch", name: "lunch", type: COMBOBOX, list: types },
];
const controller = SimpleFormController(formStructure);
return projectForm(controller);
};
fillContainer("demo1", "Demo 1 - Short datalist", demo1);
// ----- TASK 1 --------
const task1 = () => {
const formStructure = [
{ value: "", label: "Name", name: "name", type: TEXT },
{ value: "", label: "Lunch", name: "lunch", type: "hidden" },
];
const controller = SimpleFormController(formStructure);
return projectForm(controller);
};
fillContainer("task1", "Task 1 - 1 column layout", task1);
replaceField("task1", "lunch");
// ----- DEMO --------
const demo2 = () => {
/** @type { Array<OptionType> } */
const years = Service.getYearsByDecade().map((year) => ({ value: year }));
/** @type { Array<OptionType> } */
const filterRegionsChDeAt = (...countryCode) =>
Service.getRegionsByCountryChDeAt(...countryCode).map((region) => ({ value: region }));
/** @type { Array<OptionType> } */
const filterRegions = (...countryCode) =>
Service.getRegionsByCountry(...countryCode).map((region) => ({ value: region }));
const formStructure = [
{ value: "", label: "Name", name: "name", type: TEXT },
{
value: "Aargau",
label: "Home region",
name: "home-region",
type: CHOICE,
list: filterRegionsChDeAt(),
},
{
value: "",
label: "Birth region",
name: "birth-region",
type: CHOICE,
list: filterRegions(),
},
{ value: "", label: "Birth year", name: "birth-year", type: CHOICE, list: years },
];
const controller = SimpleFormController(formStructure);
return projectForm(controller);
};
fillContainer("demo2", "Demo 2 - Long selects", demo2);
// ----- TASK 2 --------
const task2 = () => {
const formStructure = [
{ value: "", label: "Name", name: "name", type: TEXT },
{ value: "", label: "Home region", name: "home-region", type: "hidden" },
{ value: "", label: "Birth region", name: "birth-region", type: "hidden" },
{ value: "", label: "Birth year", name: "birth-year", type: "hidden" },
];
const controller = SimpleFormController(formStructure);
return projectForm(controller);
};
fillContainer("task2", "Task 2 - 2 column layout", task2);
replaceField("task2", "home-region");
replaceField("task2", "birth-region");
replaceField("task2", "birth-year");
export {
getAllContinents,
getCountries,
getCountriesChDeAt,
getRegionsByCountry,
getRegionsByCountryChDeAt,
getYearsByDecade,
getDecades,
getLunchTypes,
};
/** @type { () => String } */
const getAllContinents = () => {allCountriesWithContinent.map((country) => country.continent);return [
...new Set(allCountriesWithContinent.map((country) => country.continent)),
]};
/** @type { (...String) => String } */
const getCountries = (...continents) =>
allCountriesWithContinent
.filter((e) => allRegionsWithCountry.map((c) => c.country).includes(e.country))
.filter((e) => continents.length === 0 || continents.includes(e.continent))
.map((country) => country.country);
/** @type { (...String) => String } */
const getRegionsByCountry = (...countries) =>
allRegionsWithCountry
.filter((e) => countries.length === 0 || countries.includes(e.country))
.map((region) => region.region).sort();
/** @type { () => String } */
const getCountriesChDeAt = () => ["Switzerland", "Germany", "Austria"];
/** @type { (...String) => String } */
const getRegionsByCountryChDeAt = (...countries) =>
allRegionsWithCountry
.filter(
(e) => countries.length === 0 && ["CH", "DE", "AT"].includes(e.code) || countries.includes(e.country)
)
.map((region) => region.region).sort();
/** @type { (...String) => String } */
const getYearsByDecade = (...decades) => {
const decadeStarts = decades.map(decade => decade.slice(0, 3));
const data = [...Array(90).keys()].map((e) => e + 1930 + "");
return data.filter((e) => (e) => decadeStarts.length === 0 || decadeStarts.includes(e.slice(0, 3)));
};
/** @type { () => String } */
const getDecades = () => [...Array(9).keys()].map((e) => e * 10 + 1930 + "'s");
/** @type { () => String } */
const getLunchTypes = () => ["all", "vegetarian", "vegan", "flexetarian", "gluten-free", "lactose-free"];
/* data tables for 'allCountriesWithContinent' and 'allRegionsWithCountry' */
/* Link: https://github.com/fhnw-ramonamarti/fhnw-ramonamarti.github.io/blob/main/ip6/userTest/dataService_old.js */