From f439fa1cd74a7447a62ace0f30cc8b9091354abd Mon Sep 17 00:00:00 2001 From: Carol Chung Date: Tue, 28 Mar 2017 17:09:06 -0700 Subject: [PATCH] Edit list/#25 (#60) * fix: #25; add viewState, add renderEditQuestions(), add handleViewMenu(), placeholder isChecked() * fix: #25; update renderEditQuestions() and isChecked(); but handling checkbox click events is broken * fix: #25; updated componentDidUpdate() and isChecked() to get question checked status more consistently * fix: #25; update handleSaveButton(e) to use existing key and update indexeddb * fix: #25; add getCategoriesList(), shortCategory(categ) helpers * fix: #25; cleanup and update render() to get latest saved questions more dynamically --- src/components/Child.js | 367 +++++++++++++++++++++++++--------------- src/utilities/index.js | 32 +++- 2 files changed, 258 insertions(+), 141 deletions(-) diff --git a/src/components/Child.js b/src/components/Child.js index 44e4977..5beef15 100644 --- a/src/components/Child.js +++ b/src/components/Child.js @@ -7,6 +7,7 @@ import localforage from 'localforage'; import '../App.css'; import h5bp_interview from '../utilities/h5bp_interview.json'; import { CATEGORIES } from '../utilities/constants'; +import { getCategoriesList, shortCategory } from '../utilities'; class Child extends Component { constructor(props) { @@ -15,6 +16,7 @@ class Child extends Component { this.listId = this.props.match.url.split('/')[2]; this.state = { + viewState: 'read', //read | write GeneralQuestions: [], HTMLQuestions: [], CSSQuestions: [], @@ -24,14 +26,16 @@ class Child extends Component { NetworkQuestions: [] } - // this.handleChange = this.handleChange.bind(this); - // this.handleSaveButton = this.handleSaveButton.bind(this); + this.handleChange = this.handleChange.bind(this); + this.handleSaveButton = this.handleSaveButton.bind(this); //this.handleAllButton = this.handleAllButton.bind(this); - //this.renderRandomQuestions = this.renderRandomQuestions.bind(this); - //this.renderQuestions = this.renderQuestions.bind(this); + this.renderEditQuestions = this.renderEditQuestions.bind(this); + this.renderQuestions = this.renderQuestions.bind(this); //this.getMaxCountObj = this.getMaxCountObj.bind(this); // this.concatCategory = this.concatCategory.bind(this); // this.removeArrayItem = this.removeArrayItem.bind(this); + this.handleViewMenu = this.handleViewMenu.bind(this); + this.isChecked = this.isChecked.bind(this); // var maxQuestionsObj = this.getMaxCountObj(); // maxQuestionsObj.display = 'all'; @@ -41,17 +45,17 @@ class Child extends Component { componentWillMount() { let that = this; - //test - //window.location.reload(); - localforage.getItem(this.listId).then(function(value) { - // This code runs once the value has been loaded - // from the offline store. - console.log(value); - that.setState({ - name: value.name, - questions: value.questions - }); - + localforage.getItem(that.listId).then(function(value) { + let stateObj = {}; + stateObj.key = that.listId; + stateObj.name = value.name; + stateObj.questions = value.questions; + for (let i = 0; i < value.questions.length; i++) { + let categ = Object.keys(value.questions[i])[0]; + stateObj[categ] = value.questions[i][categ] || []; + } + + that.setState(stateObj); }).catch(function(err) { // This code runs if there were any errors console.log(err); @@ -61,40 +65,36 @@ class Child extends Component { render() { var that = this; var category; - var questions = []; - if (this.state.questions) { - var questionsList = this.state.questions.map(function(questionObj, idx) { - for (let key in questionObj) { - category = key; - //console.log('category: ' + category); - questions = questionObj[key]; - //console.log('questions.length: ' + questions.length); - } - - if (questions.length) { - return ( -
-

{category}

- -
- ) - } else { + let categoriesList = getCategoriesList(); + + var questionsList = categoriesList.map((categ) => { + if (this.state[shortCategory(categ)].length) { + return ( +
+

{categ}

+ +
+ ) + } else { return null - } - }); - } + } + }) return (
-

List: {this.state.name}

- {this.state.questions ? questionsList : null} - +

{this.state.name} List

+
+ {this.state.viewState === 'read' ?
Edit | Delete
:
Read | Delete
} + {this.state.viewState === 'edit' ? : null} + {this.state.viewState === 'read' ? questionsList : this.renderEditQuestions()} + {this.state.viewState === 'edit' ? : null} +
); } @@ -106,77 +106,101 @@ class Child extends Component { * Event handler for input field update (number change) * update state which tracks all currently checked questions */ - // handleChange(e) { - // const shortCategory = this.concatCategory(e.target.classList); - // const label = e.target.parentElement; - // const question = label.innerText; - // let questionsAr = []; - // let questionsObj = {}; - // let questionIdx; - - // //console.log('shortCategory: ' + shortCategory); - // //console.log('question: ' + question); - - // if (e.target.checked) { - // //add question to array - // questionsAr = this.state[shortCategory] ? this.state[shortCategory].slice(0) : []; - // questionsAr.push(question); - // questionsObj[shortCategory] = questionsAr; - // this.setState(questionsObj); - // } else { - // //remove question from array - // questionsAr = this.state[shortCategory] ? this.state[shortCategory].slice(0) : []; - // if (questionsAr.indexOf(question) > -1) { - // questionsAr = this.removeArrayItem(questionsAr, questionsAr.indexOf(question)); - // } - // questionsObj[shortCategory] = questionsAr; - // this.setState(questionsObj); - - // } - - // //console.log('this.state[shortCategory]: ' + this.state[shortCategory]); - - // //var inputState = {}; - // //inputState[e.target.id] = e.target.value; - // //this.setState(inputState); - // } + handleViewMenu(e) { + console.log('got to handleViewMenu'); + console.log('e.target.id: ' + e.target.id); + switch(e.target.id) { + case 'edit-link': + this.setState({ + viewState: 'edit' + }) + + console.log('got to edit-link') + break; + case 'delete-link': + console.log('got to delete-link') + break; + case 'read-link': + this.setState({ + viewState: 'read' + }) + console.log('got to read-link') + break; + default: + break; + } + } + + + + /** + * @param {event} + * @return {} + * Event handler for input field update (number change) + * update state which tracks all currently checked questions + */ + handleChange(e) { + const shortCategory = this.concatCategory(e.target.classList); + const label = e.target.parentElement; + const question = label.innerText; + let questionsAr = []; + let questionsObj = {}; + let questionIdx; + + //console.log('shortCategory: ' + shortCategory); + //console.log('question: ' + question); + + if (e.target.checked) { + //add question to array + questionsAr = this.state[shortCategory] ? this.state[shortCategory].slice(0) : []; + questionsAr.push(question); + questionsObj[shortCategory] = questionsAr; + this.setState(questionsObj); + } else { + //remove question from array + questionsAr = this.state[shortCategory] ? this.state[shortCategory].slice(0) : []; + if (questionsAr.indexOf(question) > -1) { + questionsAr = this.removeArrayItem(questionsAr, questionsAr.indexOf(question)); + } + questionsObj[shortCategory] = questionsAr; + this.setState(questionsObj); + + } + } /** * @param {} * @return {} * Event handler for button click (Get Random Questions) */ - // handleSaveButton(e) { - // console.log('clicked Save'); - // const listNameInput = document.getElementById('list-name-inp'); - // var listObj = {}; - // let questionsAr = []; - // let db; - // const key = uuid.v1(); - - // console.log('listNameInput.value: ' + listNameInput.value) - - // CATEGORIES.forEach((categ) => { - // let categObj = {}; - // categObj[categ] = this.state[categ]; - // questionsAr.push(categObj); - // }) - - // listObj.name = listNameInput.value; - // listObj.questions = questionsAr; - - // localforage.setItem(key, listObj).then(function(value) { - // console.log('set new list'); - // }).catch(function(err) { - // // This code runs if there were any errors - // console.log(err); - // }); - + handleSaveButton(e) { + console.log('clicked Save'); + //const listNameInput = document.getElementById('list-name-inp'); + var listObj = {}; + let questionsAr = []; + let db; + const key = this.state.key; + + // console.log('listNameInput.value: ' + listNameInput.value) + + CATEGORIES.forEach((categ) => { + let categObj = {}; + categObj[categ] = this.state[categ]; + questionsAr.push(categObj); + }) + + listObj.name = this.state.name; + listObj.questions = questionsAr; + +//TODO 032717 need to update this to update an existing entry (this is probably creating a new one) + localforage.setItem(key, listObj).then(function(value) { + console.log('update list'); + }).catch(function(err) { + // This code runs if there were any errors + console.log(err); + }); - // // this.setState({ - // // display: 'random' - // // }); - // } + } /** * @param {} @@ -199,25 +223,51 @@ class Child extends Component { * Iterates over the list of list of questions and renders * the question category */ - // renderRandomQuestions() { - // //console.log('renderRandomQuestions'); - // var randomIdxList; - // var questionsList = h5bp_interview.questions.map((questionSet, idx) => { - // randomIdxList = getRandomIndexList(questionSet.id, this.state[questionSet.id]); - // var randomQuestions = this.renderQuestions(idx, randomIdxList); - // //console.log('randomIdxList: ' + randomIdxList); - // return ( - //
- //

{questionSet.category}

- // - //
- // ) - // }); + renderEditQuestions() { + let that = this; - // return questionsList; - // } + var questionsList = h5bp_interview.questions.map(function(questionSet, idx) { + return ( +
+

{questionSet.category}

+
+ {questionSet.question_list.map(function(question, idx2) { + return ( +
+ +
+ ) + })} +
+
+ ) + }); + + + + + + // //console.log('renderRandomQuestions'); + // var randomIdxList; + // var questionsList = h5bp_interview.questions.map((questionSet, idx) => { + // //randomIdxList = getRandomIndexList(questionSet.id, this.state[questionSet.id]); + // var editQuestions = this.renderQuestions(idx); + // //console.log('randomIdxList: ' + randomIdxList); + // return ( + //
+ //

{questionSet.category}

+ // + //
+ // ) + // }); + + return questionsList; + } /** * @param {int} index for particular category of questions in h5bp_interview.json @@ -225,21 +275,58 @@ class Child extends Component { * @return {string} HTML list of random questions by index values * */ - // renderQuestions(idxCategory, idxList) { - // var list; - // //console.log('idxList: ' + idxList); - // if (idxList) { - // list = idxList.map((idx) => { - // return ( - //
  • {h5bp_interview.questions[idxCategory].question_list[idx]}
  • - // ) - // }) - // } - - // return list; - // } + renderQuestions(idxCategory) { + var list; + console.log('idxCategory: ' + idxCategory); + //console.log('idxList: ' + idxList); + //if (idxList) { + // list = idxList.map((idx) => { + // return ( + //
  • {h5bp_interview.questions[idxCategory].question_list[idx]}
  • + // ) + // }) + //} + + return list; + } + + //placeholder + // HELPER + /** + * @param {} + * @return {} + * + */ + isChecked(category, question) { + let checked = false; + let categTrimMiddle = category.split(' ').join(''); + + console.log('GeneralQuestions: ' + this.state['GeneralQuestions']); + + console.log('categTrimMiddle: ' + categTrimMiddle); + console.log('this.state[categTrimMiddle]: ' + this.state[categTrimMiddle]); + + if (this.state[categTrimMiddle].indexOf(question) > -1) { + return true; + } + + // for (let i = 0; i < this.state[categTrimMiddle].length; i++) { + // //console.log('Object.keys(this.state.questions[i]): ' + Object.keys(this.state.questions[i])); + // //console.log('category: ' + category); + // if (Object.keys(this.state[categTrimMiddle][i]).indexOf(categTrimMiddle) > -1) { + // if (this.state[categTrimMiddle][i].indexOf(question) > -1) { + // return true; + // } else { + // return checked; + // } + // break; + // } + // } + return checked; + } + /** * @param {} * @return {} diff --git a/src/utilities/index.js b/src/utilities/index.js index 8e79be3..8e51b53 100644 --- a/src/utilities/index.js +++ b/src/utilities/index.js @@ -32,7 +32,7 @@ export function getRandomIndexList(listId, count) { * between (min : max - 1) * src: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#Getting_a_random_integer_between_two_values */ -function getRandomInt(min, max) { +export function getRandomInt(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min)) + min; @@ -55,3 +55,33 @@ function getTotalQuestions(listId) { return total; } + +/** + * @param {} + * @return {[string]} array of concatenated strings for categories + * ['GeneralQuestions', 'HTMLQuestions', ...] + * + */ +export function getCategoriesList() { + let categList = []; + const allQuestionObjList = h5bp_interview.questions; + + allQuestionObjList.forEach((obj) => { + categList.push(obj["category"]); + }) + + return categList; +} + +/** + * @param {string} category string + * @return {string} with space inbetween words trimmed + * ex 'GeneralQuestions' + */ +export function shortCategory(categ) { + let shortCateg; + + shortCateg = categ.split(' ').join(''); + return shortCateg; +} +