Using javascript to get sum from input title - javascript

Below is a javascript which is able to get the input value & needs external libraries.
I know this seem odd but I have to use javascript to grab the price from the input title and no external libraries is required. Is it possible to work from input title ?
<?php
include_once('database_conn.php');
$sqlCDs = 'SELECT CDID, CDTitle, CDYear, catDesc, CDPrice FROM nmc_cd b inner join nmc_category c on b.catID = c.catID WHERE 1 order by CDTitle';
$rsCDs = mysqli_query($conn, $sqlCDs);
while ($CD = mysqli_fetch_assoc($rsCDs)) {
//have a look at the input field below
echo "\t<div class='item'>
<span class='CDTitle'>{$CD['CDTitle']}</span>
<span class='CDYear'>{$CD['CDYear']}</span>
<span class='catDesc'>{$CD['catDesc']}</span>
<span class='CDPrice'>{$CD['CDPrice']}</span>
<span class='chosen'><input type='checkbox' id="yourId" name='CD[]' value='{$CD['CDID']}' title='{$CD['CDPrice']}' /></span>
</div>\n";
}
?>
JS:
function isChecked(chosen) {
//and here it is called again
var valOfTitle = document.selectElementById("yourId").getAttribute('title');
var number = parseFloat(valOfTitle);
if(chosen.is(':checked')) {
sum = sum + parseFloat(valOfTitle);
} else {
sum = sum - parseFloat(valOfTitle);
}
$('#total').valOfTitle(sum.toFixed(2));
};

Just use getAttribute if you dont want to use any external libraries.
element.getAttribute("title")

i hope i understood you correctly:
you can access the data in your input field via jQuery's attr() method.
// "valOfTitle" is just a name..could also be "george" or "germany"
// "yourInputElementId needs to be the id of your element (written in
// "")
var valOfTitle = $(yourInputElementId).attr('title');
without jQuery:
var valOfTitle = document.selectElementById(yourInputFieldId).getAttribute('title');
if you want it as a number you can just do:
var number = parseFloat(valOfTitle);
if you don't want to add an id to your element you also can use another javascript selector, p.e. getElementsByName- but note: this will return a HTML Collection and not a single element, which means you will have to loop over this collection to access your data.
http://www.w3schools.com/jsref/met_doc_getelementsbyname.asp
maybe this google search may help you too:
https://www.google.de/search?q=javascript+selectors&oq=javascript+selectors&aqs=chrome..69i57.4015j0j7&sourceid=chrome&es_sm=91&ie=UTF-8#q=pure+javascript+selectors
or even
How can I use the jQuery-like selector in pure JavaScript

Related

getElementsByClassName not working when I change to different class name

I've looked over numerous Stack Overflow discussions on getElementsByClassName but can't seem to find anything that can help me resolve this particular issue. To explain . . .
I have the following javascript
field_to_update.innerHTML = '';
var elOptNew = document.createElement('option');
elOptNew.text = '---'
elOptNew.value = '';
field_to_update.add(elOptNew);
field_to_update.options[0].selected = true;
var track_names = document.getElementsByClassName('wpaudio');
for (i=0; i<track_names.length; i++) {
var track_name = track_names[i].innerHTML;
var elOptNew = document.createElement('option');
elOptNew.text = track_name.replace("&", "&");
elOptNew.value = track_name;
field_to_update.add(elOptNew); // standards compliant; doesn't work in IE
}
and I am looking to extract the names of a list of audio files using the line var track_names = document.getElementsByClassName('wpaudio') which refers to the following code included in the functions.php file of a wordpress child theme.
<ol id="audioFilesList" class="reactionFormAudio">
<?php
// loop through rows (parent repeater)
while( have_rows('song_upload') ): the_row(); ?>
<li><p class="wpaudio" name="audioFileName"><?php the_sub_field('track_name'); ?></p><br>
The above scenario works fine. BUT i have decided to not use the ordered list of audio files as listed above - but instead us the default audio playlist that can be created within a wordpress post, which produces the following code:
<div class="wp-playlist-tracks">
<div class="wp-playlist-item wp-playlist-playing">
<a class="wp-playlist-caption" href="https://www.futureproofpromotions.com/wp-content/uploads/2020/09/01_WhereToBegin-128.mp3">
1.
<span class="wp-playlist-item-title">
“Where To Begin” </span>
<span class="wp-playlist-item-artist"> — Alice Clayton</span>
</a>
<div class="wp-playlist-item-length">2:57</div>
</div>
<div class="wp-playlist-item">
<a class="wp-playlist-caption" href="https://www.futureproofpromotions.com/wp-content/uploads/2020/09/02_BeingAlone-128.mp3">
2.
<span class="wp-playlist-item-title">
“Being Alone” </span>
<span class="wp-playlist-item-artist"> — Brosnan</span>
</a>
<div class="wp-playlist-item-length">3:15</div>
</div>
</div>
</div>
However, when I swap the javascript line from document.getElementsByClassName('wpaudio'); to document.getElementsByClassName('wp-playlist-caption'); in order to reference the different class name in the the new html, it doesn't display any names!
I am very new indeed to javascript so this may be obvious to someone skilled in that language, but I do have a limited knowlege of php.
Would anybody be able to explain why when i change the class name/reference in the above scenario I get no names displayed?
FYI I have also tried changing document.getElementsByClassName() to document.querySelectorAll() which also works well, when referencing the original class ('.wpaudio') - but again produces no result when referencing ('.wp-playlist-caption') or any other class name nested within it (such as .wp-playlist-item-title or .wp-playlist-item-artist).
Any help with the above would be most appreciated
Since wp-playlist-caption has multiple nested elements, you can either query for each one of them and string them together or take the lazy route and use .innerText. That will extract the rendered plaintext inside the element and its children.
// Wait until the page has loaded
document.addEventListener('DOMContentLoaded', () => {
var field_to_update = document.getElementById('reactionForm_strongestTrack');
field_to_update.innerHTML = '';
var elOptNew = document.createElement('option');
elOptNew.text = '---'
elOptNew.value = '';
field_to_update.add(elOptNew);
field_to_update.options[0].selected = true;
// Search for all playlist-captions inside the playlist-tracks list.
// 'Currently playing' has a playlist-caption too,
// limiting to the tracklist excludes it
document.querySelectorAll('.wp-playlist-tracks .wp-playlist-caption')
.forEach( // The following arrow function will be called for each element
track => {
// There are nested elements but we just want the plaintext
let track_name = track.innerText;
// Create a new element and append to the select as before
let elOptNew = document.createElement('option');
elOptNew.text = track_name.replace("&", "&");
elOptNew.value = track_name;
field_to_update.add(elOptNew);
});
});
Additional reference for arrow functions.

How do I change more than one element?

EDIT: I changed the var to class but I might have some error in here.
Here it goes, I want to have this paragraph in which the user can change the name on the following paragraph. The code I'm using only changes one name but the rest remains the same.
<script type="text/javascript">
function changey(){
var userInput = document.getElementById('userInput').value;
var list = document.getElementByClassName('kiddo');
for (let item of list) {
item.innerHTML = userInput;
}
}
</script>
<input id="userInput" type="text" value="Name of kid" />
<input onclick="changey()" type="button" value="Change Name" /><br>
Welcome to the site <b class="kiddo">dude</b> This is how you create a document that changes the name of the <b class="kiddo">dude</b>. If you want to say <b class="kiddo">dude</b> more times, you can!
No error messages, the code only changes one name instead of all three.
Use class="kiddo" instead of id in the html.
You can then use var kiddos = document.getElementsByClassName('kiddo') which will return an array of all the elements of that class name stored in kiddos.
Then you just need to loop through the values and change what you want.
Example of loop below:
for (var i = 0; i < kiddos.length; i++) {
kiddos[i].innerHTML = userInput;
}
id should be unique on the page. Javascript assumes that there is only one element with any given id. Instead, you should use a class. Then you can use getElementsByClassName() which returns an entire array of elements that you can iterate over and change. See Select ALL getElementsByClassName on a page without specifying [0] etc for an example.
Hello You should not use id, instead use class.
Welcome to the site <b class="kiddo">dude</b> This is how you create a document that changes the name of the <b class="kiddo">dude</b>. If you want to say <b class="kiddo">dude</b> more times, you can!
After That on Js part :
<script type="text/javascript">
function changey(){
var userInput = document.getElementById('userInput').value;
var list = document.getElementByClassName('kiddo');
for (let item of list) {
item.innerHTML = userInput;
}
}
</script>
you should use class instated of id. if you use id then the id [kiddo] must be unique
In short, document.querySelectorAll('.kiddo') OR
document.getElementsByClassName('kiddo') will get you a list of elements to loop through. Take note of querySelectorAll, though - it uses a CSS selector (note the dot) and doesn't technically return an array (you can still loop through it, though).
See the code below for some full working examples (const and arrow functions are similar to var and function, so I'll put up a version using old JavaScript, too):
const formEl = document.querySelector('.js-name-change-form')
const getNameEls = () => document.querySelectorAll('.js-name')
const useNameFromForm = (formEl) => {
const formData = new FormData(formEl)
const nameValue = formData.get('name')
const nameEls = getNameEls()
// Set the text of each name element
// NOTE: use .textContent instead of .innerHTML - it doesn't get parsed, so it's faster and less work
nameEls.forEach(el => el.textContent = nameValue)
}
// Handle form submit
formEl.addEventListener('submit', (e) => {
useNameFromForm(e.target)
e.preventDefault() // Prevent the default HTTP request
})
// Run at the start, too
useNameFromForm(formEl)
.name {
font-weight: bold;
}
<!-- Using a <form> + <button> (submit) here instead -->
<form class="js-name-change-form">
<input name="name" value="dude" placeholder="Name of kid" />
<button>Change Name</button>
<form>
<!-- NOTE: Updated to use js- for js hooks -->
<!-- NOTE: Changed kiddo/js-name to spans + name class to remove design details from the HTML -->
<p>
Welcome to the site, <span class="js-name name"></span>! This is how you create a document that changes the name of the <span class="js-name name"></span>. If you want to say <span class="js-name name"></span> more times, you can!
</p>
var formEl = document.querySelector('.js-name-change-form');
var getNameEls = function getNameEls() {
return document.querySelectorAll('.js-name');
};
var useNameFromForm = function useNameFromForm(formEl) {
var formData = new FormData(formEl);
var nameValue = formData.get('name');
var nameEls = getNameEls(); // Set the text of each name element
// NOTE: use .textContent instead of .innerHTML - it doesn't get parsed, so it's faster and less work
nameEls.forEach(function (el) {
return el.textContent = nameValue;
});
};
// Handle form submit
formEl.addEventListener('submit', function (e) {
useNameFromForm(e.target);
e.preventDefault(); // Prevent the default HTTP request
});
// Run at the start, too
useNameFromForm(formEl);
<button class="js-get-quote-btn">Get Quote</button>
<div class="js-selected-quote"><!-- Initially Empty --></div>
<!-- Template to clone -->
<template class="js-quote-template">
<div class="js-quote-root quote">
<h2 class="js-quote"></h2>
<h3 class="js-author"></h3>
</div>
</template>
You have done almost everything right except you caught only first tag with class="kiddo".Looking at your question, as you need to update all the values inside tags which have class="kiddo" you need to catch all those tags which have class="kiddo" using document.getElementsByClassName("kiddo") and looping over the list while setting the innerHTML of each loop element to the userInput.
See this link for examples:https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp
try:
document.querySelectorAll('.kiddo')
with
<b class="kiddo">dude</b>

I want to rename the index of my array using javascript

Hi I'm having my personal experiment with arrays what I was trying to do is to rename the index of the array from the result of my text field that dynamically adds using Javascript(I dont want to use jquery or other libraries like angular js). See image below for the UI
the problem is that the output looks like this
I want to be able to rename the index of the array generated(THIS IS WHAT I WANT FYI)
btw PHP handles my data and Javascript obviously handles my textfield manipulation
see my code
Javascript
var countBox =1;
var boxName = 0;
var boxName2 = 0;
function addInput()
{
var boxName="index"+countBox;
var boxName2="value"+countBox;
document.getElementById('response').innerHTML+='<input type="text" name="aindex" id="'+boxName+'" value="'+boxName+'" " /><input type="text" name="avalue[]" id="'+boxName2+'" value="'+boxName2+'" " /><br/>';
countBox += 1;
}
PHP
if(isset($_POST['save'])){
$b = $_POST['avalue'];
$results = print_r( $b, true);
file_put_contents( $filepath, print_r($b, true));
}
From your HTML, it appears you want to have pairs of form fields to hold keys and values? If so, just set the name of your all of your key fields to "keys[]" and all the value fields to "values[]" which when submitted will provide two arrays to your backend service.

Filter Table with JQuery using the “each” element

OK everybody, I hope you can help me. I have a problem with JQuery or better with the each selector of JQuery.
I have an example table, where I want to filter for special values which I entered before. Those values I got from my input field , store them in a variable, split the data an create an JQuery Object.
Well and then I think I have a problem with the selection, marked in the code section.
<p>
<input id="testyear" size="4" type="text">
<input value="Werte" onclick="getvalue()" type="button">
</p>
<script>
function getvalue() {
var wert = $('#testyear').val();
$("#years").find("tr").hide();
var data = this.value.split(" ");
// create jQuery Object
var jQueryObject = $("#years").find("tr");
// i think here is my error, i want to display only the object which are equal or better stored in my variable “wert”.
$.each(data, function (){
//jQueryObject = jQueryObject.filter(wert);
jQueryObject == wert;
});
jQueryObject.show();
};
<!--Example Table-->
<table id="years">
<tbody>
<tr>
<td>1997</td>
<td class="century">20</td>
</tr>
<tr>
<td>2001</td>
<td class="century">21</td>
</tr>
</tbody>
</table>
I expect, that when I enter 1997 in the inpt field, the whole tr which contains 1997 will be displayed. I know it is simple but I have no idea so thanks for your help.
Use a filter on the TR's after initially hiding them all.
e.g.
getvalue = function() {
var wert = $('#testyear').val();
// create jQuery Object
$("#years tr").hide().filter(function() {
return ~~$("td", this).first().text() >= wert;
}).show();
};
JSFiddle: https://jsfiddle.net/TrueBlueAussie/h8Lejfac/
Notes:
The ~~ is a little conversion to integer trick
You seem to have extra code you do not need in the example
Just get filter to return true for each item you want to keep and false for the rest
When using jQuery, avoid using inline event handlers (like onclick=). Use jQuery event handlers instead. See below:
e.g.
$('#wert').click(function() {
var wert = $('#testyear').val();
// create jQuery Object
$("#years tr").hide().filter(function() {
return ~~$("td", this).first().text() >= wert;
}).show();
});
JSFiddle: https://jsfiddle.net/TrueBlueAussie/h8Lejfac/1/
I think your problem is not in each() method (not selector). Your problem is here:
var data = this.value.split(" ");
this is not defined (you are not in an object scope). I think you need this:
var data = wert.split(" ");
-----------^^^^
You've obtain the value of wert in the last line.

How can I create dynamic controls and put their data into an object?

I created a div and a button. when the button clicked, there will be a group of element(included 1 select box and 2 text inputs) inserted into the div. User can add as many group as they can, when they finished type in data of all the group they added, he can hit save button, which will take the value from each group one by one into the JSON object array. But I am stuck in the part how to get the value from each group, so please help, thank you.
The code for the div and the add group button function -- AddExtra() are listed below:
<div id="roomextra">
</div>
function AddExtra() {
$('#roomextra').append('<div class=extra>' +
'<select id="isInset">' +
'<option value="Inset">Inset</option>' +
'<option value="Offset">OffSet</option>' +
'</select>' +
'Length(m): <input type="text" id="insetLength">' +
'Width(m): <input type="text" id="insetWidth">' +
'Height(m): <input type="text" id="insetHeight">' +
'</div>');
}
function GetInsetOffSetArray (callBack) {
var roomIFSDetail = [{
"IsInset": '' ,
"Length": '' ,
"Width": '' ,
"Height": ''
}];
//should get all the value from each group element and write into the array.
callBack(roomIFSDetail);
}
This should just about do it. However, if you're dynamically creating these groups, you'll need to use something other than id. You may want to add a class to them or a data-* attribute. I used a class, in this case. Add those classes to your controls so we know which is which.
var roomIFSDetail = [];
var obj;
// grab all of the divs (groups) and look for my controls in them
$(.extra).each(function(){
// create object out of select and inputs values
// the 'this' in the selector is the context. It basically says to use the object
// from the .each loop to search in.
obj = {
IsInset: $('.isInset', this).find(':selected').val() ,
Length: $('.insetLength', this).val() ,
Width: $('.insetWidth', this).val() ,
Height: $('.insetHeight', this).val()
};
// add object to array of objects
roomIFSDetail.push(obj);
});
you'd better not to use id attribute to identity the select and input, name attribute instead. for example
$('#roomextra').append('<div class=extra>' +
'<select name="isInset">' +
'<option value="Inset">Inset</option>' +
'<option value="Offset">OffSet</option>' +
'</select>' +
'Length(m): <input type="text" name="insetLength">' +
'Width(m): <input type="text" name="insetWidth">' +
'Height(m): <input type="text" name="insetHeight">' +
'</div>');
}
and then, usr foreach to iterate
$(".extra").each(function() {
var $this = $(this);
var isInset = $this.find("select[name='isInset']").val();
var insetLength = $this.find("input[name='insetLength']").val();
// ... and go on
});
A common problem. A couple things:
You can't use IDs in the section you're going to be repeating, because IDs in the DOM are supposed to be unique.
I prefer to use markup where I'm writing a lot of it, and modify it in code rather than generate it there.
http://jsfiddle.net/b9chris/PZ8sf/
HTML:
<div id=form>
... non-repeating elements go here...
<div id=roomextra>
<div class=extra>
<select name=isInset>
<option>Inset</option>
<option>OffSet</option>
</select>
Length(m): <input id=insetLength>
Width(m): <input id=insetWidth>
Height(m): <input id=insetHeight>
</div>
</div>
</div>
JS:
(function() {
// Get the template
var container = $('#roomextra');
var T = $('div.extra', container);
$('#addGroup').click(function() {
container.append(T.clone());
});
$('#submit').click(function() {
var d = {};
// Fill d with data from the rest of the form
d.groups = $.map($('div.extra', container), function(tag) {
var g = {};
$.each(['isInset', 'insetLength', 'insetWidth', 'insetHeight'], function(i, name) {
g[name] = $('[name=' + name + ']', tag).val();
});
return g;
});
// Inspect the data to ensure it's what you wanted
debugger;
});
})();
So the template that keeps repeating is written in plain old HTML rather than a bunch of JS strings appended to each other. Using name attributes instead of ids keeps with the way these elements typically work without violating any DOM constraints.
You might notice I didn't quote my attributes, took the value attributes out of the options, and took the type attributes out of the inputs, to keep the code a bit DRYer. HTML5 specs don't require quoting your attributes, the option tag's value is whatever the text is if you don't specify a value attribute explicitly, and input tags default to type=text if none is specified, all of which adds up to a quicker read and slimmer HTML.
Use $(".extra").each(function() {
//Pull info out of ctrls here
});
That will iterate through all of your extra divs and allow you to add all values to an array.

Categories

Resources