Interactive form for storing user information - javascript

I am learning to use HTML, CSS, JavaScript and JDBC. I want to integrate all the said together and arrive at a webpage that accepts user information that can be used to make a detailed profile of a family that can act as a repository for the family to access that information from anywhere by just logging into the website. I also want to do CURD operations to apply to all the data submitted. Need cascading dropdown menus that populate by themselves when one option is selected by user
I started off by making cascading dropdown menu that when province is selected the next dropdown selects only the corresponding cities in that province only. I was able to populate the first dropdown but could not connect it to subsequent dropdown
below is the JavaScript that I prepared for any number of cascading dropdowns but its not working and now I am unable to identify whats wrong with the code
function makeDropDown(data, filtersAsArray, targetElement) {
const filteredArray = filterArray(data, filtersAsArray);
//const filteredArray = data.filter((r) => r[0] === level1Filter);
//const uniqueOptions = new Set();
// using for each item of the array from the second place and put the valused in the uniqueoptions set
//filteredArray.forEach((r) => uniqueOptions.add(r[1]));
// deconstruting the set to form the array again
//const uniqueList = [...uniqueOptions];
const uniqueList = getUniqueValues(filteredArray, filtersAsArray.length);
populateDropDown(targetElement, uniqueList);
//selectLevel2.innerHTML = "";
//uniqueList.forEach((item) => {
//const option = document.createElement("option");
//option.textContent = item;
//selectLevel2.appendChild(option);
//});
}
function applyDropDown() {
const selectLevel1Value = document.getElementById("level1").value;
const selectLevel2 = document.getElementById("level2");
makeDropDown(myData, [selectLevel1Value], selectLevel2);
applyDropDown2();
}
function applyDropDown2() {
const selectLevel1Value = document.getElementById("level1").value;
const selectLevel2Value = document.getElementById("level2").value;
const selectLevel3 = document.getElementById("level3");
makeDropDown(myData, [selectLevel1Value, selectLevel2Value], selectLevel3);
}
function afterDocumnetLoads() {
populateFirstLevelDropDown();
applyDropDown();
}
function getUniqueValues(data, index) {
const uniqueOptions = new Set();
data.forEach((r) => uniqueOptions.add(r[index]));
return [...uniqueOptions];
}
function populateFirstLevelDropDown() {
const uniqueList = getUniqueValues(myData, 0);
const ele = document.getElementById("level1");
populateDropDown(ele, uniqueList);
}
function populateDropDown(ele, listAsArray) {
ele.innerHTML = "";
listAsArray.forEach((item) => {
const option = document.createElement("option");
option.textContent = item;
ele.appendChild(option);
});
}
function filterArray(data, filtersAsArray) {
return data.filter((r) => filtersAsArray.every((item, i) => item === r[i]));
}
document.getElementById("level1").addEventListener("change", applyDropDown);
document.getElementById("level2").addEventListener("change", applyDropDown2);
document.addEventListener("DOMContentLoaded", afterDocumnetLoads);

Related

mapped button info is out of bounds

function AddDocument(Name, TTid) {
auth.onAuthStateChanged(user => {
if(user) {
const colUser = collection(fsinfo, 'User');
// goes to database colelction "user"
const colUser2 = doc(colUser, user.uid);
// goes to the document in colUser named "one"
const colUser3 = collection(colUser2, 'MoviesLiked');
whenSignedIn.hidden = false;
whenSignedOut.hidden = true;
setDoc(doc(colUser3, Name), {
movieliked: TTid,
})
}
else {
whenSignedIn.hidden = true;
whenSignedOut.hidden = false;
//userDetails.innerHTML = '';
console.log( "while logged out" );
console.log("notloggedin");
}
})
};
// query can either be a title or a tt id
function searchMovie(query) {
const url = `https://imdb8.p.rapidapi.com/auto-complete?q=${query}`;
fetch(url, options)
.then(response => response.json())
.then(data => {
var outname = null;
var outdetail = null;
const movieList = document.querySelector('.movielist');
movieList.addEventListener('click', handleClick);
const list = data.d;
//array of list with data from the movie search
//data.d is the specific datas that is outputted from the api
//list is an array that holds that data
console.log(list)
// ^ will output what list holds
const html = list.map(obj => {
const name = obj.l; // holds the name of movie
outname = name;
const poster = obj.i.imageUrl; // holds the poster, i is the image
const detail = obj.id
outdetail = detail;
return `
<section class="movie">
<img src="${poster}"
width = "500"
height = "800"/>
<h2>${name}</h2>
<section class = "details">${detail}</section>
<button type="button">Movie Details</button>
</section>
`;
}).join('');
// Insert that HTML on to the movie list element
function handleClick(e) {
if (e.target.matches('button')) {
const details = e.target.previousElementSibling;
details.classList.toggle('show');
AddDocument(outname, outdetail);
}
}
movieList.insertAdjacentHTML('beforeend', html);
document.getElementById("errorMessage").innerHTML = "";
})
.catch((error) => {
document.getElementById("errorMessage").innerHTML = error;
});
I have a function that will take search to an API call and then load the info from the API to a list.
It should then output said each of said list using list.map(obj) and each item will have a name, poster, and a button attached to it.
Outside the map I have a function that will react when the button is pressed which will toggle and then load the details of the movie to a database in the AddDocument function. My issue is that I am not sure how to make it so that when the button is pressed AddDocument will add whichever obj.name is connected to the button.
Currently, AddDocument will only add the last item in the list and not the item that I pressed the button for.
I know that it is because the function is outside where the mapping is done, and thus the items that are held in outname, and outdetail are the last items that have been mapped. But I just can't figure out a way to make the button press add the correct document to the database.
(I really didn't want to ask this, but I had spent hours thinking and searching and couldn't seem to find a solution. Thank you for any form of feedback that there may be.)

How can I force update?

I'm making a page for posts that can be viewed by newest or most likes.
I manage this with drop-down lists and arrays.
And whenever the dropdown list is clicked, I have to force update this to match its value.
async selectPosts ({...} = {}, forceUpdate = false) {
let goodOrderByDir = 'desc'
let dateOrderByDir = 'desc'
const db = getFirestore()
let constraints = [ //This array determines the viewing order.
orderBy('date', dateOrderByDir), orderBy('good', goodOrderByDir)]
var hw = document.getElementById('dropDowmListID') //It is linked to a drop-down list.
hw.addEventListener('change', function() {
if (hw.value == 1) { //newest
constraints = [
orderBy('date', dateOrderByDir), orderBy('good', goodOrderByDir)]
}
if (hw.value == 2) { //most likes
constraints = [
orderBy('good', goodOrderByDir), orderBy('date', dateOrderByDir)]
}
})
if (forceUpdate) {
this._lastSelectPostsOptions = {}
}
constraints.push(limit(pageSize))
const queryRef = query(collection(db, 'posts'), ...constraints)
return Promise.all((await getDocs(queryRef)).docs.map(async item => {
this._lastSelectPostsDoc = item
const data = item.data()
return {
...data
}
}))
}
When doing a forced update, the default value is false in the current code.
async selectPosts ({...} = {}, forceUpdate = false)
So when I change the dropdown list I was told it must be true to get the next value.
So I changed the code like this
async selectPosts ({...} = {}, forceUpdate = true)
But I couldn't get the value I wanted...
How can I force an update to apply the changed array values?

I'm just starting with JS and I don't really understand how setTimeout works

I am developing a trivia page with a series of questions that I get through an API. When I give to start the game on the main page, I want to redirect me to a second page where the available categories will appear and when I click on them, the questions will appear with multiple answers.
Luckily I have managed to do all this, however, when I switch from one page to another I have not been able to get the categories to appear. They only appear if I am already on that page and I create a button to call the function that displays them.
I had thought of doing this function in this way so that it would switch me to the other page and then load the questions but I have not been able to get it to work.
Does anyone have a solution or know why it is not working?
function get_dataJson() {
let data_json = [];
fetch('https://opentdb.com/api.php?amount=10')
.then(response => response.json())
.then(data => data.results.forEach(element => {
data_json.push(element);
}));
return data_json;
}
let trivial_data = get_dataJson();
function startGame() {
let div_username = document.createElement("div");
let name = document.createElement("h2");
name.innerHTML = document.getElementById("name").value;
div_username.appendChild(name);
let categories = get_categories(trivial_data);
setTimeout("location.href='./game.html'", 1000);
setTimeout(function(){
document.getElementById('nav-game').appendChild(div_username);
show_categories(categories);
},2000);
}
function get_categories(trivial_data) {
let categories = [];
trivial_data.forEach(element => {
categories.push(element.category)
});
console.log(categories);
return categories;
}
function show_categories (categories) {
let div_categories = document.createElement("div");
let count = 0;
categories.forEach ( element => {
let element_category = document.createElement("button");
element_category.innerHTML = element;
element_category.id = count;
element_category.onclick = function() {
get_question(element_category.id);
};
count++;
div_categories.appendChild(element_category);
});
div_categories.className = 'categories';
document.getElementById("categories").appendChild(div_categories);
}
function get_question (pos) {
document.getElementById("categories").style.displays = 'none';
let question = document.createElement("h2");
question.innerHTML = trivial_data[pos].question;
let correct_answer = trivial_data[pos].correct_answer;
let incorrect_answers = trivial_data[pos].incorrect_answers;
let options = incorrect_answers.concat(correct_answer);
options = options.sort();
let div_choices = document.createElement("div");
options.forEach(element => {
let choice = document.createElement('button');
choice.innerHTML = element;
choice.id = 'true' ? element == correct_answer : 'false';
div_choices.appendChild(choice);
});
div_choices.className = 'answers';
document.getElementById("questions").appendChild(question);
document.getElementById("questions").appendChild(div_choices);
}
The first thing you should do is make sure you understand how to use fetch to get data asynchronously
async function get_dataJson() {
const response = await fetch('https://opentdb.com/api.php?amount=10');
const json = await response.json();
return json.results;
}
(async function(){
const trivial_data = await get_dataJson();
console.log(trivial_data);
})()
Then, rather than changing page, just stay on the same page and add/remove/hide elements as necessary - it looks like you have that bit sorted.

My javascript code does not work with the result of work php

I have website on wordpress, and i use Search & Filter Pro plugin for filter my posts.
I need to sort filter fields by posts count.The plugin does not provide the necessary functionality, so I decided to use javascript to sort.
const getFilterFieldDepMeth = () => {
const container = document.querySelector(
".sf-field-taxonomy-deposit_methods ul"
);
const listField = container.querySelectorAll("li");
let arrayList = [];
listField.forEach((item) => {
arrayList.push(item);
});
const sortedListField = arrayList.sort((a, b) => {
const elem1 = parseInt(b.getAttribute("data-sf-count"));
const elem2 = parseInt(a.getAttribute("data-sf-count"));
return elem1 - elem2;
});
sortedListField.map((item) => {
container.appendChild(item);
});
};
getFilterFieldDepMeth();
The code works and can show the result anywhere but I can’t influence the DOM in the filter block. I also cannot delete filter fields.

How to Create Ant Design group of Dynamic fields

I'm using ant design dynamic form. How I suppose to create a group of dynamic forms
Code: https://codesandbox.io/s/vvl2yxqr5l
Scenario
User need to enter the team name and team members name dynamically.
Is it possible add the dynamic fields inside the dynamic field by ant design.
Yes, it is possible to create a nested dynamic form using ant design dynamic form component. I have also asked the same question How to create a questionnaire type form using Ant Design?. You need to add your own logic but here I am providing the basic structure:
To remove team name:
remove = k => {
const { form } = this.props;
const keys = form.getFieldValue("newkeys");
form.setFieldsValue({
newkeys: keys.filter(key => key !== k)
});
};
To add team name:
add = () => {
const { form } = this.props;
const keys = form.getFieldValue("newkeys");
const nextKeys = keys.concat(uuid);
uuid++;
form.setFieldsValue({
newkeys: nextKeys
});
};
To remove team member:
remove1 = (k, l) => {
const { form } = this.props;
const keys = form.getFieldValue("answerkey" + k);
let newkeys = [];
if (keys) {
newkeys = keys;
} else {
newkeys = [];
}
form.setFieldsValue({
["answerkey" + k]: newkeys.filter(key => key !== l)
});
};
To add team member:
add1 = index => {
const { form } = this.props;
const keys = form.getFieldValue("answerkey" + index);
let newkeys = [];
if (keys) {
newkeys = keys;
} else {
newkeys = [];
}
const nextKeys = newkeys.concat(uuid1);
uuid1++;
form.setFieldsValue({
["answerkey" + index]: nextKeys
});
};
I have created a working demo on codesandbox.io.
From above answer, I was trying to remove a team name with remove() function but getting some problem and i found this
Use map instead of loop, as map brings values at line 7 after render()
newkeys.map((i) => {
getFieldDecorator("answerkey" + i, { initialValue: [] });
})
Demo video

Categories

Resources