Get the values of All checkboxes using Javascript - javascript

When a button is clicked a new category is added to the database and also displayed on the same page as well.But my problem is that when I click multiple times on button it adds multiple checkboxes for same checkbox value. I made it to insert into database only if it is not already present. My issue is that when i click on button it should add the category if it not present in database. I have two function
add_cat(); javascript function which calls ajax for adding the new category to the database.
is php function which is used for creating new page.
I did that when displaying checkboxes on page i used name= cats[] like array for all checkboxes like
<input type="checkbox" name="cats[]" id="<?php echo $row{'term_id'};?>" value="<?php echo $row{'name'};?>"> <?php echo $row{'name'}; ?> `
In add_cat() function i am using this code
var val = document.getElementById('cat_name').value;
var checkboxes = document.getElementsByName('cats');
var flag = 0;
for (var i = 0, n = checkboxes.length; i < n; i++) {
if (checkboxes[i] == val) {
flag = 1;
}
alert(flag);
} //check the duplicates
if (flag == 1) {
alert(flag);
document.getElementById('error').innerHTML = "Already exists";
setTimeout(function() { // to show the Error
$('#error').fadeIn("fast").delay(500).fadeOut("slow");
}, 1500);
flag = 0;
} else {
var div = document.getElementById('divContainer');
div.innerHTML = div.innerHTML + "<input id='chk_" + idCounter + "' type='checkbox' checked value='" + val + "' /><label for='chk_" + idCounter + "'>" + val + "</label>";
idCounter++;
cat_2_db(val); // call ajax to insert category in database
}
But problem is that flag never get turned into 1 and checkboxes variable is not returning checkbox values

you missed to find the value:
if (checkboxes[i].value === val) {
Refactoring your for loop
for(var i = 0, i < checkboxes.length; i++) {
if (checkboxes[i].value === val) {
flag = 1;
}
}

Related

How to save radio buttons to local storage

i have a quiz with radio buttons ,sow i have to save the answears on my local storge ,but im stuck i don t know what else to do,im learnig sow dont hate me pls,tnx
This is my code sow far
<form id="quiz"> </form>
<script>
let object;
let httpRequest = new XMLHttpRequest();
httpRequest.open("GET", "quiz.json", true);
httpRequest.send();
httpRequest.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
object = JSON.parse(this.response);
console.log(object)
}
let json = object
let quiz = document.getElementById("quiz");
let keyList = Object.keys(json.quiz);
for (let i = 0; i < keyList.length; i++) {
let key = keyList[i];
let questionItem = json.quiz[key];
let html = "<div>";
html += "<div><h2>Question " + (i + 1) + ": " + questionItem.question + "</h2></div>";
html += "<div>";
for (let i = 0; i < questionItem.options.length; i++) {
html += "<div >";
html += "<input type=\"radio\" id=\"q\" checked=\"checked\" name=\"qzz" + key + "_option\" value=\"" + questionItem.options[i] + "\">" + questionItem.options[i] ;
html += "</div>";
}
quiz.innerHTML += html;
}
quiz.innerHTML += "<input type=\"submit\" value=\"submit\">";
function save() {
var g1 = document.querySelector('input[type="radio]');
g1 = (g1) ? g1.value : '';
localStorage.setItem("g1", g1);
}
});
You can simplify your AJAX dialog by using fetch() instead of new XMLHttpRequest();. I straightened out a few things in your code (also see the initial remarks in #brianagulo's answer) and prepared a little set of sample data to demonstrate the whole functionality of the quiz. The jsonplaceholder.typicode.com url only serves as a working json-server endpoint. The received data is actually ignored here.
In your "production version" you will need to un-comment the line:
localStorage.setItem("quiz",JSON.stringify(ans))
The checked answers where collected in an object doing
[...document.querySelectorAll('input[type=radio]:checked')].reduce((a,{name,value}) =>(a[name]=value,a), {});
This
collects all checked radio button inputs with (document.querySelectorAll('input[type=radio]:checked')),
converts the collection of DOM elements into a proper array (with [... ])and eventually
reduce()-s its elements into an object where the element names are the property names and the (input-)element values are the property values.
And also please note that you can only store strings in local storage. Therefore I converted the ans object into a JSON string before using it in the .setItem() method.
const Q = {
quiz: [{
question: "Where was the Boston tea party?",
options: ["New York", "Detroit", "Boston", "Reno"]
}, {
question: "Where would you find Venice Beach?",
options: ["Detroit", "Venice", "Paris", "Los Angeles"]
}, {
question: "Where would you find Queens?",
options: ["London", "Paris", "Stockholm", "New York"]
}, {
question: "Where is Greenwich Village?",
options: ["London", "Paris", "Stockholm", "New York"]
}, {
question: "Where would you find the Gateway Arch?",
options: ["St. Quentin", "St. Louis", "St. Anton", "San Francisco"]
}]
}, quiz = document.getElementById("quiz");
var url = "quiz.json";
// in your productive version: comment out the following line
url = "https://jsonplaceholder.typicode.com/users/7"; // functioning test URL for fetch
function save(ev) {
ev.preventDefault();
const ans=[...document.querySelectorAll('input[type=radio]:checked')].reduce((a,{name,value}) =>(a[name]=value,a), {});
// in Stackoverflow snippets you cannot use local storage, so here is console.log instead:
console.log(ans);
// in your productive version: un-comment the following line
// localStorage.setItem("quiz",JSON.stringify(ans))
}
fetch(url).then(r => r.json()).then(object => {
// remove the following line:
object = Q; // use the static quiz from defined in Q instead ...
let json = object
let keyList = Object.keys(json.quiz);
for (let i = 0; i < keyList.length; i++) {
let key = keyList[i];
let questionItem = json.quiz[key];
let html = "<div>";
html += "<div><h2>Question " + (i + 1) + ": " + questionItem.question + "</h2></div>";
html += "<div>";
for (let i = 0; i < questionItem.options.length; i++) {
html += "<label>";
html += "<input type=\"radio\" id=\"q\" name=\"qzz" + key + "_option\" value=\"" + questionItem.options[i] + "\"> " + questionItem.options[i];
html += "</label><br>";
}
quiz.innerHTML += html;
}
quiz.innerHTML += "<input type=\"submit\" value=\"submit\">";
quiz.onsubmit=save;
});
<form id="quiz"> </form>
There is a typo on your save function. You are missing a quote after radio:
var g1 = document.querySelector('input[type="radio"]');
Also, your question is confusing but if what you are trying to do is get whether the radio is checked or not you must access the checked property and save that to localStorage. And if you want to save the state for all of the buttons then you should use querySelectorAll and save them that way instead. Example below of accessing a single input's checked value:
function save() {
// you can access it directly on this line
var g1 = document.querySelector('input[type="radio]').checked;
localStorage.setItem("g1", g1);
}
For saving them all
Lastly, it seems you are not actually calling the save() function. If your intention is to have the radios checked state saved to localStorage on click you may want to add an event to the submit button. For example:
<form id="quiz"> </form>
<script>
let object;
let httpRequest = new XMLHttpRequest();
httpRequest.open("GET", "quiz.json", true);
httpRequest.send();
httpRequest.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
object = JSON.parse(this.response);
console.log(object)
}
let json = object
let quiz = document.getElementById("quiz");
let keyList = Object.keys(json.quiz);
for (let i = 0; i < keyList.length; i++) {
let key = keyList[i];
let questionItem = json.quiz[key];
let html = "<div>";
html += "<div><h2>Question " + (i + 1) + ": " + questionItem.question + "</h2></div>";
html += "<div>";
for (let i = 0; i < questionItem.options.length; i++) {
html += "<div >";
html += "<input type=\"radio\" id=\"q\" checked=\"checked\" name=\"qzz" + key + "_option\" value=\"" + questionItem.options[i] + "\">" + questionItem.options[i] ;
html += "</div>";
}
quiz.innerHTML += html;
}
quiz.innerHTML += "<input type=\"submit\" value=\"submit\">";
function save() {
// you can access it directly on this line
var g1 = document.querySelector('input[type="radio]').checked;
localStorage.setItem("g1", g1);
}
let submitButton = document.querySelector('input[type="submit"]');
submitButton.onclick = (event) => {
/* this prevents page refresh and submission to the backend which is a form default */
event.preventDefault();
// then we call the save function here
save();
};
});
If this was helpful please consider selecting as the answer

Creating a list of students and assigning a function to each button

I am trying to allow clients to create a list of students then view more info by simply clicking on the button with the students name. I've got it to create the button and display the students name in the button but it only calls the function when I click submit to add the student to the list, the actual student button doesn't seem to function.
function updateStudentList() {
var html = "";
for (var i = 0; i < students.length; i++) {
html += "<li><button type='button' class='studentButton'" + "id=" + students[i].name +">" + students[i].name + "</button></li>";
}
$('#studentList').html(html);
for (var i = 0; i < students.length; i++) {
document.getElementById(students[i].name).addEventListener('click', openStudentInfo(students[i].name));
}
}
function openStudentInfo(studentName) {
console.log("Opening " + studentName + " info.");
var studentInfo = requestStudentByName(studentName);
if (studentInfo != null) {
var studentInfoForm = $("#studentInfoForm");
var html = "";
html += "<h3>Student Name: " + studentInfo.name + "</h3>";
html += "<h3>Student ID: " + studentInfo.studentID + "</h3>";
studentInfoForm.html(html);
$("#studentInfoModal").show();
}
}
HTML:
<ul data-role="listview" id="studentList"> </ul>
Note: I can't use the onclick tag in HTML, it causes security issues. Cordova also blocks this.
The way you binding the event is not ok. Try binding this way:
$(document).ready(function() {
$("#studentList").on("click", ".studentButton", function() {
var studentId = $(this).data("studentid");
openStudentInfo(studentId);
});
});
And in your HTML generation:
html += "<li><button type='button' class='studentButton' data-studentid='" + students[i].studentID +"'>" + students[i].name + "</button></li>";
This kind of event delagation works not metter how you create the elements inside the root element(studentList in this case), because the event was bound in it, and not on the dynamic elements.
no jquery version of DontVoteMeDown's answer
document.getElementById('studentList').addEventListener('click', function(event) {
var clickedEl = event.target;
if(clickedEl.className === 'studentButton') {
var studentId = clickedEl.dataset.studentId;
openStudentInfo(studentId);
}
});

How to fetch the values of a dynamic select list in a global variable?

I'm trying to get the values of my dynamically filled select list in a global variable. This is how I get and fill the select list:
My dropdown.js script:
$(document).ready(function () {
$("#slctTable").change(function()
{
$.getJSON("dropdown_code/get_fields.php?table=" + $(this).val(), success = function(data)
{
var options = "";
for(var i = 0; i < data.length; i++)
{
options += "<option value='" + data[i] + "'>" + data[i] + "</option>";
}
$("#slctField").html("");
$("#slctField").append(options);
$("#slctField").change();
});
});
});
So after this I tryed this code in my main.js scgript to get the values of the select lists:
$('#slctField > option').each(function(){
console.log(this.value); // Use this.value to get the value of the option
});
var options = [];
$('#slctField > option').each(function(){
options.push(this.value);
});
console.log(options);
But when I run my scripts this the result I get back:
But when I copy and paste the code in firebug and run it. I get the result i want.So I think the select lists aren't filled yet when i try to get the values. But I'm stuck on this for a long time and I don't know what to do at the moment.
Because getJSON is asynchronous, to solve your problem you can trigger a custom event when the select is completed (at the end of getJSON success).
In my example I used this slctFieldFilled new event.
This is a different approach. Another possible solution can be based on callbacks: at the end of an asynchronous function execute the callback function, like the getJSON does.
My snippet:
$(function () {
$.getJSON('https://api.github.com/users', success = function (data) {
var options = '';
for (var i = 0; i < data.length; i++) {
options += "<option value='" + data[i].id + "'>" + data[i].id + "</option>";
}
$("#slctTable").append(options);
$("#slctTable").change();
});
$("#slctTable").on('change', function(e) {
var par1 = $(this).val();
$.getJSON("https://api.github.com/users", success = function(data) {
var options = "";
for(var i = 0; i < data.length; i++) {
options += "<option value='" + data[i].id + "'>" + data[i].id + "</option>";
}
$("#slctField").html("");
$("#slctField").append(options);
$("#slctField").change();
//
// Now, the slctField is filled, so trigger your custom event
//
$('#slctField').trigger('slctFieldFilled', options);
});
});
$("#slctField").change(function() {
var par1 = $(slctTable).val();
var par2 = $(slctField).val();
$.getJSON("https://api.github.com/users", success = function(data) {
var options = "";
for(var i = 0; i < data.length; i++) {
options += "<option value='" + data[i].id + "'>" + data[i].id + "</option>";
}
$("#slctAttribute").html("");
$("#slctAttribute").append(options);
$("#slctAttribute").change();
});
});
// listen on custom event...
$('#slctField').on('slctFieldFilled', function(e, optionVariable) {
var options = [];
$(optionVariable).each(function(index, element){
options.push(this.value);
});
$('#log').text(options);
});
});
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<select id="slctTable"></select>
<select id="slctField"></select>
<select id="slctAttribute"></select>
<p id="log"></p>
You're very correct! Your GET is asynchronous and will likely complete long after your main.js code has finished executing. You'll want to make sure your modifications to the global variable is tied to your callbacks in some way so its guaranteed to run afterwards.
var options = [];
$("#slctField").change(function()
{
$.getJSON("dropdown_code/get_attributes.php?table=" + $(slctTable).val() ,"field=" + $(slctField).val() , success = function(data)
{
...
//Option 1: Append the values inside your callback.
//Use window.options because you have another local variable options(window.XX calls any global XX)
for(var i = 0; i < data.length; i++)
{
...
window.options.push(data[i]);
}
//Option 2: Basically the same thing as 1, call a function that does the same thing at the end of your callback
populateOptions();
});
});
function populateOptions(){
$('#slctField > option').each(function(){
options.push(this.value);
});
}
There's plenty of other ways to do it as well as long as you guarantee it executes after your GET. If you have any questions, post a comment. Be careful about the scope of options since you have multiple variables named options(or consider different names so that you can't be confused later on!).

JavaScript & HTML - Modifying dynamically created subclasses within a dynamically created class

Problem:
I have a dynamically created HTML table, that is used for filling out time sheets. It is created programmatically - there is no formal control. The design is a mix of CSS with text boxes being created through JavaScript. Now each 'row' of this table is in a class called 'divRow', and is separated from the others by having 'r' and the number of the row assigned to it as the class (i.e 'divRow r1', 'divRow r2', etc.).
Within each of these 'divRow's, I have cells in a class called 'divCell cc'. These do not have any identifiers in the class name. At the very last cell, I have a 'Total' column, which ideally calculates the total of the row and then adds it into a dynamically created text box.
What I have at the moment:
// Function to create textboxes on each of the table cells.
$(document).on("click", ".cc", function(){
var c = this;
if(($(c).children().length) === 0) {
var cellval = "";
if ($(c).text()) {
cellval = $(this).text();
if(cellval.length === 0) {
cellval = $(this).find('.tbltxt').val();
}
}
var twidth = $(c).width() + 21;
var tid= 't' + c.id;
if(tid.indexOf('x17') >= 0){
var thtml = "<input id='t" + c.id + "' type='text' Class='tbltxt' style='width: " + twidth + "px;' readonly />";
eval(spproc(spcol(t[getx(c.id)],thtml,tid,twidth)));
//var getRow = $(this).parent().attr('class'); - this gets the 'divRow r#' that it is currently on.
var arr = document.getElementsByClassName('cc');
var tot = 0;
for(var i = 0; i<arr.length; i++){
if(parseInt(arr[i].innerHTML) > 0){
tot += parseInt(arr[i].innerHTML);}
}
$('#t' + c.id).focus();
$(this).children().val(tot);
}else{
var thtml = "<input id='t" + c.id + "' type='text' Class='tbltxt' style='width: " + twidth + "px;' />";
eval(spproc(spcol(t[getx(c.id)],thtml,tid,twidth)));
$('#t' + c.id).focus();
$('#t' + c.id).val(cellval);
}}
});
As you can see, when the user clicks on the 'divCell cc', it creates a text box if one is not present. If the user clicks on the 17th column ('x17'), then it runs the for loop, and assigns the value of the total to the text box.
What I need to happen:
So what happens now is that the last cell sums the total of each cell that has a value. However, they are not row-dependent. I need it to calculate based on the row that it is currently 'on'. So if I'm calculating the 2nd row, I don't want the sum of the first, second and third being entered into the total, I just want the 2nd rows' values summed.
What I've tried:
I've tried looping through and using the 'divRow r#' number to try and get the items in the array that end in that number. (cells are given an id of 'x#y#' and the text boxes assigned to those cells are given an id of 'tx#y#').
I've tried getting elements by the cell class name, and then getting their parent class and sorting by that; didn't get far though, keep running into simple errors.
Let me know if you need more explanation.
Cheers,
Dee.
For anyone else that ever runs into this issue. I got it. I put the elements by the row class into an array, and then using that array, I got the childNodes from the row class. The reason the variable 'i' starts at 2 and not 0 is because I have 2 fields that are not counted in the TimeSheet table (Jobcode and description). It's working great now.
Cheers.
$(document).on("click", ".cc", function(){
var c = this;
if(($(c).children().length) === 0) {
var cellval = "";
if ($(c).text()) {
cellval = $(this).text();
if(cellval.length === 0) {
cellval = $(this).find('.tbltxt').val();
}
}
var twidth = $(c).width() + 21;
var tid= 't' + c.id;
if(tid.indexOf('x17') >= 0){
var thtml = "<input id='t" + c.id + "' type='text' Class='tbltxt' style='width: " + twidth + "px;' readonly />";
eval(spproc(spcol(t[getx(c.id)],thtml,tid,twidth)));
// Get current row that has focus
var getRow = $(this).parent().attr('class');
// Get the row number for passing through to the next statement
var rowPos = getRow.split('r', 5)[1];
// Get all the elements of the row class and assign them to the rowClass array
var rowClass = document.getElementsByClassName('r' + rowPos)
// Given the rowClass, get the children of the row class and assign them to the new array.
var arr = rowClass.item(0).childNodes
// Initialize the 'total' variable, and give it a value of 0
var tot = 0;
// Begin for loop, give 'i' the value of 2 so it starts from the 3rd index (avoid the Req Code and Description part of the table).
for(var i = 2; i<arr.length; i++){
if(parseInt(arr[i].innerHTML) > 0){
tot += parseInt(arr[i].innerHTML);}
}
// Assign focus to the 'Total' cell
$('#t' + c.id).focus();
// Assign the 'total' variable to the textbox that is dynamically created on the click.
$(this).children().val(tot);
}else{
var thtml = "<input id='t" + c.id + "' type='text' Class='tbltxt' style='width: " + twidth + "px;' />";
eval(spproc(spcol(t[getx(c.id)],thtml,tid,twidth)));
$('#t' + c.id).focus();
$('#t' + c.id).val(cellval);
}}
});

display my dropdown box in a specific area

Ok here's what I am doing. Based on some dropdown value I am craeting another dropdown value.
Is it possible to display that dropdown in some specific area as I wish based on my existing code.
if (SelectedIndex == 2 || SelectedIndex == 5 || SelectedIndex == 7) {
$("#DomContainer").remove();
var MainContainer = document.createElement("Div");
MainContainer.id = "DomContainer";
$("body").append(MainContainer);
var Options = new Array();
for(var i=1;i<=28;i++){
Options.push(i);
}
AddDropDown(Options);
}
function AddDropDown(Options) {
var selectHTML = "<label>Day:</label> ";
selectHTML += "<select>";
for (i = 0; i < Options.length; i = i + 1) {
selectHTML += "<option value='" + Options[i] + "'>" + Options[i] + "</option>";
}
selectHTML += "</select>";
document.getElementById("DomContainer").innerHTML = selectHTML;
}
For example <div id="new_drop">//Display the drop down here </div>
Simply add a second parameter to AddDropDown for passing the ID of the container to which you want to insert your dropdown list:
function AddDropDown(Options, containerId) {
...
document.getElementById(containerId).innerHTML = selectHTML;
Then call it like this:
AddDropDown(Options, "new_drop");
(if I understand you correctly)
No need to remove and append elements from the DOM, just replace the existing element contents ... here's a simplified version.
// if "SelectedIndex" is one of the values in the array provided
if ($.inArray(SelectedIndex, [2,5,7])) {
$("#DomContainer").html("<label>Day:</label> "+inject_dropdown(28));
}
// Creates and returns a new drop-down based on the "length" provided
function inject_dropdown(length){
var selectHTML = "<select>";
for( i=1; i<=length; i++ ){
selectHTML += "<option value='" + i + "'>" + i + "</option>"
}
selectHTML += "</select>"
return selectHTML;
}
Replace the $('#DomContainer') selector with whatever selector identifies the place you want the new drop-down to appear.

Categories