Save values from dynamic form in ReactJS - javascript

I am a beginner in Reactjs and I am not finding the best way to save data from a dynamic form in ReactJS.
This form can only display 10 questions per page and when I move forward I have to save the answers on the current page.
Can anybody help me?
I was thinking of putting an ID on the form and then getting the component data....I have one form per component (inputs).
This is how I try to code my function that will save the answers and how I render the dynamic inputs
save = (currentIndex, pageNumber) => {
let {text="", id=""} = this.form.model;
let answerText = text;
if(Array.isArray(answerText)){
text = JSON.stringify(text);
answerText = answerText.filter(item=>!!item)
if(!answerText.length) answerText = "";
else answerText = text;
}
saveAnswerAction({
answerId : id,
text: answerText,
}).then(()=>{
return refresh();
}).catch(e=>{
console.log(e);
});
}
render() {
if (this.state.answers) {
var questions = this.state.answers.toJSON();
var questionsToRender = [];
var qInit = (this.state.currentPage * this.state.quantityQuestionsPerPage) - this.state.quantityQuestionsPerPage;
var qEnd = this.state.currentPage * this.state.quantityQuestionsPerPage;
if (qEnd > questions.length) {
qEnd = qInit + 1;
}
for (var i = qInit; i < qEnd; i++) {
var readOnly = false;
let QuestionRender = QuestionRenderFactory(questions[i], i, readOnly);
questionsToRender.push(<QuestionRender ref={form=>this.form=form} />)
}
return (
<div>
{questionsToRender}
</div>
)
}
else {
return (
<div>
NO QUESTIONS
</div>
)
}
}
render() {
return (
<div className={"formId_" + formId}>
<p className="question">{questionAnswer.question.text} {questionAnswer.question.required ? <span className="question-required">* </span>: null }</p>
{ questionAnswer.question.help && <div className="help">{questionAnswer.question.help}</div> }
<Form
ref={form => this.form = form}
value={this.state.model}
onChange={model => this.setState({ model })}>
{fields}
</Form>
<br />
</div>
)
}
I will have the HTML rendered:
<div class="content">
<h3 class="title">Form</h3>
<h3 class="subtitle">Fields * are required</h3>
<br>
<div>
<div class="formId_0">
<p class="question">
Question 1<span class="question-required">* </span>
</p>
<div class="help">help</div>
<form novalidate="">
<div class="input-container undefined undefined">
<div class="input-wrapper"><input name="text" class=" invalid-field" placeholder="" id="id_1" value="800b7e6e-ce0c-44bb-a4d8-60cffaacb509"><span class="inputError"><span class="validation-error">invalid field</span></span></div>
</div>
</form>
<br>
</div>
<div class="formId_1">
<p class="question">
question 2<span class="question-required">* </span>
</p>
<div class="help">help 2</div>
<form novalidate="">
<div class="input-container undefined undefined">
<div class="input-wrapper">
<input type="text" name="text" class=" " placeholder="" id="id_2" value="www.test.com">
<span class="inputError">
</span>
</div>
</div>
</form>
<br>
</div>
</div>
<div class="buttons"><a class="btn skyBlue" href="/">Home</a><button class="btn-previous">Previous</button><button class="btn-next">Next</button></div>
</div>

You could use localStorage but I don't know if its efficient, secure, or the best route to go

Related

I can't get past the js div hiding problem

I want to hide the divi when I click the button and open it when I click it again. But I couldn't run the normally working code, what could be the reason?
The js code works when there is only one div, but it does not work due to this code I wrote, but I can't solve the problem.
Razor Page
#for (int i = 0; i < Model.quest.Count; i++)
{
<div class="row mt-12" >
<div class="col-md-1">
<input type="checkbox" id="questcb" asp-for="#Model.quest[i].check">
<span>#(i + 1) Soru</span>
</div>
<div class="col-md-9">
<textarea class="form-control" asp-for=#Model.quest[i].Question rows="3" id="question" hidden></textarea>
<label>#Model.quest[i].Question</label>
</div>
</div>
<div class="row mt-12">
<div class="col-md-1" hidden>
<button class="btn btn-outline-secondary" type="button" id="A" onclick="clickFunc(this.id)">A</button>
</div>
<div class="col-md-1" >
A)
</div>
<div class="col-md-11" hidden="hidden">
<input type="text" asp-for=#Model.quest[i].Answer1 class="form-control" placeholder="" id="answer"
aria-label="Example text with button addon" aria-describedby="button-addon1">
</div>
<div class="col-md-11" id="Amod_#i" style="display:inline-block">
#Model.quest[i].Answer1
</div>
<div class="col-md-2">
<button class="btn btn-primary" type="button" id="mod_#i" onclick="question(this.id)">Cevapları Görüntüle</button>
</div>
</div>
}
js code
let question = button => {
let element = document.getElementById(`A${button}`);
let buttonDOM = document.getElementById(`${button}`)
let hidden = element.getAttribute("hidden");
if (hidden) {
element.removeAttribute("hidden");
buttonDOM.innerText = "Cevapları Gizle";
}
else {
element.setAttribute("hidden", "hidden");
buttonDOM.innerText = "Cevapları Görüntüle";
}
}
</script>
If the id of div is unique in your code,your js should work.If it still doesn't work,you can try to find the div with the position of the button:
let question = button => {
let element = $("#" + button).parent().siblings(".col-md-11")[1];
let buttonDOM = document.getElementById(`${button}`);
if (element.hidden) {
element.removeAttribute("hidden");
buttonDOM.innerText = "Cevapları Gizle";
}
else {
element.setAttribute("hidden", "hidden");
buttonDOM.innerText = "Cevapları Görüntüle";
}
}
result:

How can I add an element created in Javascript to innerHTML

const totalBill = document.querySelector(".total-bill");
let errorDiv = document.querySelector(".error");
function isValid(e) {
if (totalBill.value.trim().length == 0) {
let para = document.createElement("div");
para.innerText = "Please enter the total amount of bill";
// para.classList.add("bill-para");
para.setAttribute('class', 'bill-error')
console.log(para);
errorDiv.innerHTML = para;
}
e.preventDefault();
}
HTML:
<div class="container">
<div class="error">
</div>
<div class="box-container">
<h1 class="heading">TIP CALCULATOR</h1>
<form action="">
<div class="box">
<label>How much was your bill?</label><br>
<input type="number" placeholder="Total Bill" class="total-bill">
</div>
</form>
</div>
So I am trying to add a div in div.error section and I want to add div named div.bill-error but whenever I am trying to replace the innerHTML and run the code. It shows me '[Object HTMLDivElement]' instead of "Please enter the total amount of bill". But in the console I see that the div is created. But it is not inserted inside
Can anyone tell me where is the problem and solution. Thanks a lot.
Use errorDiv.appendChild(para);, or, if you want to delete existing content in errorDiv first, then errorDiv.textContent = ''; errorDiv.appendChild(para);.
Have you tried, replace
errorDiv.innerHTML = para;
with
errorDiv.append(para);
use appendChild() , I modified your code, here's the snipppet :
const totalBill = document.querySelector(".total-bill");
let errorDiv = document.querySelector(".error");
function isValid(e) {
if (totalBill.value.trim().length == 0) {
let para = document.createElement("div");
para.innerHTML = "Please enter the total amount of bill";
// para.classList.add("bill-para");
para.setAttribute('class', 'bill-error')
errorDiv.appendChild(para);
}
}
<div class="container">
<div class="error">
</div>
<div class="box-container">
<h1 class="heading">TIP CALCULATOR</h1>
<form action="">
<div class="box">
<label>How much was your bill?</label><br>
<input type="number" placeholder="Total Bill" class="total-bill">
</div>
<button type="button" onclick="isValid();">Check</button>
</form>
</div>

Hide filter element

I'm having trouble hiding relevant data with JS.
In my code I have data-type = "power" and data-type = "grill" which are added to the products.
I want the script to check sort filters and hide those that are not present on the page.
Unfortunately, when I have two cases, it doesn't work as it should.
Grill filters do not appear even though they should.
$('.stat').on('click', function() {
var $stats = $('.stat:checked');
var $items = $('.list .product');
$items.show();
if ($stats.length == 0)
return;
var $vstats = $.map($stats, function(o) {
return $(o).data('id');
});
$stats.each(function() {
var $stat = $(this);
$items.filter(function() {
var $currentitem = $(this).data($stat.data('type'));
if ($currentitem.toString().indexOf(",") > -1) {
var $item = $currentitem.split(",");
var hit = 0;
$item.forEach(function(m) {
if ($vstats.indexOf(m) > -1) {
hit++;
}
});
if (hit > 0) {
return false;
} else {
return true;
}
} else {
if ($vstats.indexOf($currentitem) > -1) {
return false;
} else {
return true;
}
}
}).hide();
})
});
var powers = $('[data-power]').map(function() {
return this.dataset.power;
}).get();
var grills = $('[data-grill]').map(function() {
return this.dataset.grill;
}).get();
$('[data-id]').filter(function() {
return !powers.includes(this.dataset.id)
return !grills.includes(this.dataset.id)
}).closest("label").hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="power">
<h2>power</h2>
<div class="checkbox">
<label>
<input data-id="750" data-type="power" class="stat power" type="checkbox">750
</label>
<label>
<input data-id="800" data-type="power" class="stat power" type="checkbox">800
</label>
<label>
<input data-id="1200" data-type="power" class="stat power" type="checkbox">1200
</label>
</div>
</div>
<div class="grill">
<h2>grill</h2>
<div class="checkbox">
<label>
<input data-id="yes" data-type="grill" class="stat grill" type="checkbox">yes
</label>
<label>
<input data-id="no" data-type="grill" class="stat grill" type="checkbox">no
</label>
</div>
</div>
<div class="list">
<div class="col-6 col-lg-3 product" data-power="750" data-grill="yes">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name</span> Product 1</h2>
</div>
</div>
</a>
</div>
<div class="col-6 col-lg-3 product" data-power="800" data-grill="yes">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name 2</span> Product 2</h2>
</div>
</div>
</a>
</div>
</div>
You have to change your filter function. You are returning two values but it stops on first return.
Change
return !powers.includes(this.dataset.id) and return !grills.includes(this.dataset.id)
to
return !powers.includes(this.dataset.id) && !grills.includes(this.dataset.id);
I hope this will solve you problem.

Why does localstorage multi-toggle state code work in jsfiddle but not on my webpage?

In last question I had assistance to create a code to save the state of a fairly complex toggle state. When a radio button is selected a checkbox slides down, when that checkbox is selected another one slides down. The reverse also occurs. Much of the code I do not understand. The problem now is that it works perfectly in jsfiddle.
https://jsfiddle.net/tomik23/ovysmutL/7/
However, it does not function on my webpage. When localstorage restores the state back to the webpage after a page refresh it automatically 'unchecks' the checkboxes about 2 seconds after load when they should have remained checked.
I totally stripped down my page to try to isolate this issue...the problem still exists. I read and tried all the similar stackoverflow problems eg( modified forms, added doc ready function,etc)... but obviously none of them helped.
The code works prior to localstorage insertion. When page is refreshed localstorage restores the state back to the webpage but it automatically 'unchecks' the checkboxes about 2 seconds after load when they should have remained checked. Does ANYBODY know what is going on AND HOW TO FIX THIS? I truly appreciate the help.
**HTML**
<form class="form" id="form-a" method="post" autocomplete="on">
<fieldset>
<div>
<p>
<label class="yes_text">Yes</label>
<span>
<input type="radio" data-show="next-a" id="dog" name="answer_name" value="yes">
</span>
</p>
<p>
<label>No</label>
<span>
<input type="radio" name="answer_name" value="no" checked>
</span>
</p>
</div>
</fieldset>
<fieldset id="next-a" class="hidden">
<div class="red">
<div>
<p>Include Red Dogs:</p>
</div>
<div>
<p>
<label class="yes_text_include">select to include</label>
<span>
<input type="checkbox" data-show="next-b" id="cat" class="red" name="red_name" value="">
</span>
</p>
</div>
</div>
<div id="next-b" class="hidden">
<div>
<p>Include Green Dogs:</p>
</div>
<div>
<p>
<label>select to include</label>
<span>
<input type="checkbox" name="green_name" class="cat" value="">
</span>
</p>
</div>
<div>
<p>
<label>select to include</label>
<span>
<input type="checkbox" name="blue_name" class="cat" value="">
</span>
</p>
</div>
</div>
</fieldset>
</form>
<form class="form" id="form-b" method="post" autocomplete="on">
<fieldset>
<div>
<p>
<label class="yes_text">Yes</label>
<span>
<input type="radio" data-show="next-a" id="dog" name="answer_name" value="yes">
</span>
</p>
<p>
<label>No</label>
<span>
<input type="radio" name="answer_name" value="no" checked>
</span>
</p>
</div>
</fieldset>
<fieldset id="next-a" class="hidden">
<div class="red">
<div>
<p>Include Red Dogs:</p>
</div>
<div>
<p>
<label class="yes_text_include">select to include</label>
<span>
<input type="checkbox" data-show="next-b" id="cat" class="red" name="red_name" value="">
</span>
</p>
</div>
</div>
<div id="next-b" class="hidden">
<div>
<p>Include Green Dogs:</p>
</div>
<div>
<p>
<label>select to include</label>
<span>
<input type="checkbox" name="green_name" class="cat" value="">
</span>
</p>
</div>
</div>
</fieldset>
</form>
**Javascript**
class CheckForm {
constructor(option) {
const forms = document.querySelectorAll(`${option}`);
forms.forEach(form => {
const formname = form.id;
this.formCheck(formname);
this.checkChecked(formname);
});
}
formCheck(formName) {
const form = document.querySelector(`#${formName}`);
form.addEventListener('click', e => {
const { target: { type, value, id, dataset: { show } } } = e;
switch (type) {
case 'radio': {
if (value === 'yes') {
$(`#${formName}`).find(`#${show}`).show(200);
this.saveToLocalstore(formName);
} else {
$(`#${formName} fieldset`).next().hide(200);
document.querySelector(`#${formName}`).reset();
localStorage.removeItem(formName);
this.removeAllChecked(formName);
}
break;
}
case 'checkbox': {
$(`#${formName}`).find(`#${show}`).toggle(200);
this.saveToLocalstore(formName);
if (id) {
this.removeAllChecked(formName, id);
}
break;
}
default:
break;
}
});
}
saveToLocalstore(formName) {
let allInput = document.querySelectorAll(`#${formName} input`);
let object = {};
allInput.forEach(item => {
object[item.name] = item.type === 'radio' ? true : item.checked;
});
localStorage.setItem(formName, JSON.stringify(object));
}
checkChecked(formName) {
const data = JSON.parse(localStorage.getItem(formName));
if (data) {
let i = 1;
for (let [key, value] of Object.entries(data)) {
const item = document.querySelector(`#${formName} input[name='${key}']`);
setTimeout(() => {
if (value) {
item.click();
}
}, i * 1000);
i++;
}
}
}
removeAllChecked(formName, id) {
if (id) {
let allInput = document.querySelectorAll(`#${formName} .${id}`);
allInput.forEach(item => {
item.checked = false;
});
} else {
const allHidden = document.querySelectorAll(`#${formName} .hidden`);
allHidden.forEach(item => {
item.removeAttribute('style', '');
});
}
}
}
new CheckForm('.form');
**CSS**
.hidden {
display: none;
}

How to get value that was passed to a bootstrap modal in AngularJS

I'm trying to implement a Todo list using Angular JS and connecting it with MySQL and PHP. I have a working code where the button used to open a modal passes a php variable to that modal. I have placed that value in a hidden input field (int the modal). Now, I want to get that value so I can use it AngularJS because I will pass it again through AJAX in a separate PHP page. The thing is, it always returns undefined. Where am I going wrong with this?
JQuery code to pass the php variable and value to the modal:
<script>
$(document).ready(function(){
$('#editModal').on('show.bs.modal', function (e) {
var id = $(e.relatedTarget).data('id');
$("#new-taskID").val(id); // e.g. 3
});
});
</script>
'EditModal' (the form inside the Bootstrap Modal)
<form class="cmxform" id="editTask" name="dasd" onsubmit="return false" method="post" action="" role="form">
<div class="col-md-12">
<div ng-app>
<div id="todoapp" ng-controller="TodoCtrl">
<div class="form-group form-animate-text" style="margin-top:15px !important;">
<input type="text" class="form-text" id="new-todo" ng-model="todoText" name="allotted_time_edit" ng-keyup="addTodo()" required>
<span class="bar"></span>
<label>What needs to be done?</label>
<input type="hidden" class="form-text" id="new-taskID" value = "" name="new-taskID" required> //the passed value is placed here
</div>
<section id="main" style="display: block;">
<div ng-show="isTodo()">
<input id="toggle-all" type="checkbox" ng-model="markAll" ng-click="toggleMarkAll()"/>
<label for="toggle-all">Mark all as complete</label>
</div>
<ul id="todo-list" class="unstyled">
<li ng-repeat="todo in todos" ng-dblclick="toggleEditMode()">
<div class="view" ng-keyup="editTodo()">
<input type="checkbox" ng-model="todo.done"/>
<span class="done-{{todo.done}}" >{{todo.text}}</span>
</div>
<input class="edit" type="text" ng-model="todo.text" ng-keyup="editOnEnter(todo)"/>
</li>
</ul>
</section>
<footer style="display: block;">
<div class="todo-count">{{remaining()}} of {{todos.length}} remaining</div>
<a id="clear-completed" ng-click="clear()" ng-show="hasDone()">
Clear <span >{{(todos.length - remaining())}} {{itemText()}}</span>.</a>
</footer>
</div>
</div>
</div>
<center>
<button id="send" type="submit" class="btn btn-primary" name="dasd">Update</button>
<button type="button" class="btn btn-danger"data-dismiss="modal">Cancel</button>
</center>
</form>
AngularJS Code
<script>
function TodoCtrl($scope, $http) {
$scope.todos = [];
$scope.markAll = false;
$scope.addTodo = function(item) {
var name = $scope.todoText;
var id = document.getElementById('new-taskID').val;
alert(id); //return undefined
if(event.keyCode == 13 && name){
$http.post("ajax-search/add_checklist.php?item="+name).success(function(data){ $scope.todos.push({text:$scope.todoText, done:false});
$scope.todoText = '';
});
}
};
$scope.isTodo = function(){
return $scope.todos.length > 0;
}
$scope.toggleEditMode = function(){
$(event.target).closest('li').toggleClass('editing');
};
$scope.editOnEnter = function(todo){
if(event.keyCode == 13 && todo.text){
$scope.toggleEditMode();
}
};
$scope.remaining = function() {
var count = 0;
angular.forEach($scope.todos, function(todo) {
count += todo.done ? 0 : 1;
});
return count;
};
$scope.hasDone = function() {
return ($scope.todos.length != $scope.remaining());
}
$scope.itemText = function() {
return ($scope.todos.length - $scope.remaining() > 1) ? "items" : "item";
};
$scope.toggleMarkAll = function() {
angular.forEach($scope.todos, function(todo) {
todo.done =$scope.markAll;
});
};
$scope.clear = function() {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.done) $scope.todos.push(todo);
});
};
}
</script>
I really need to get the value but it returns undefined. Your help will be much appreciated. Thank you so much!!

Categories

Resources