Pushing values into an empty array? - javascript

I'm recently new at programming and JavaScript. I'm not sure why this doesn't work. I'm trying to insert numbers into an empty array. And then have them displayed into the div with the id of "value".
My JavaScript:
var array = new Array();
// var array = [];
$(document).ready(function() {
$('#btn').on('click', function() {
var $input = $('#input').val();
array.push($input);
});
$('#value').text(array);
console.log(array);
});
My HTML:
<div id="number">
<input type="text" id="input">
<button id="btn"> Submit </button>
</div>

You render the empty array once, when the document is ready. Adding more items to the array doesn't rerender the DOM with the new items. You need to update the DOM on each click by moving $('#value').text(array); into the click event handler:
var array = new Array();
// var array = [];
$(document).ready(function() {
var $input = $('#input');
var $value = $('#value');
$('#btn').on('click', function() {
var val = $input.val();
array.push(val);
$value.text(array);
console.log(array);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="input">
<button id="btn">Add</button>
<div id="value"></div>

Just a reminder that Input Fields supply a String not an Integer.
Take a look:
var myArray = [];
$(function() {
$('#btn').on('click', function() {
var $input = $('#input').val();
myArray.push(parseInt($input));
console.log(myArray)
$('#value').text("[" + myArray.join(", ") + "]");
});
});
.input {
padding: 10px;
font-family: Arial, Helvetica, sans-serif;
font-size: 1em;
}
.input input {
width: 60px;
height: 1.25em;
}
.input button {
padding: .25em .6em;
}
.output {
font-family: Arial, Helvetica, sans-serif;
font-size: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input">
<input type="number" id="input" /> <button id="btn">Add</button>
</div>
<div class="output">
<div id="value"></div>
</div>

Related

jQuery: Control CSS with range slider

How is it possible to control CSS with a range slider via jQuery?
Some example code:
$('.font_size').on('input', function() {
var fontsizeval = $(this).attr('value');
var fontsizemin = $(this).attr('min');
var fontsizemax = $(this).attr('max');
$('.text').css("font-size", fontsizeval + "px");
});
* {
font-size: 12px;
}
.text {
font-size: 120px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">Text
<div>
Font Size: <input class="font_size" type="range" value="120" min="30" max="200">
Would be very thankful for help!
use val() instead of attr("value")
$('.font_size').on('input', function() {
var fontsizeval = $(this).val();
var fontsizemin = $(this).attr('min');
var fontsizemax = $(this).attr('max');
$('.text').css("font-size", fontsizeval + "px");
});
* {
font-size: 12px;
}
.text {
font-size: 120px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Font Size: <input class="font_size" type="range" value="120" min="30" max="200">
<div class="text">Text
<div>

Add/Remove item list

I'm practicing with javascript. I built a grocery list in which I would like to add and remove items. Adding elements works fine by typing a name in a input form and pushing the send button. I'd like to remove the element that I just created by clicking on it but I get this error instead:
"Uncaught TypeError: Cannot read property 'removeChild' of undefined at HTMLDocument.removeItem"
here the code:
HTML:-
<div id="paper">
<h3 id="title">Groceries list:</h3>
<ul id="list">
<li></li>
</ul>
</div>
<p class="grocery">
<input type="text" name="grocery" placeholder="ex. Apple" id="blank" />
<label for="grocery">Grocery Name</label>
</p>
<p class="submit">
<input type="submit" value="SEND" id="btn" />
</p>
<script type="text/javascript" src="js/script.js"></script>
CSS:-
#paper {
width: 300px;
height: auto;
margin: 20px auto;
clear: both;
background-color: orange;
}
.grocery, .submit{
text-align: center;
margin: 20px;
}
Javascript:-
var elList = document.getElementById("list");
var elButton = document.getElementById("btn");
function addItem(e) {
var elElement = document.createElement("li");
var whatever = el.value;
var elText = document.createTextNode(whatever);
elElement.appendChild(elText);
elList.appendChild(elElement);
}
function removeItem(e) {
var elElement = document.getElementsByTagName("li");
var elContainer = elElement.parentNode;
elContainer.removeChild(elElement);
}
var el = document.getElementById("blank");
elButton.addEventListener("click", addItem, false);
if ("DOMNodeInserted") {
document.addEventListener("click", removeItem, false);
}
How could I get through this?
Thank you guys for your help
if ("DOMNodeInserted") {
document.addEventListener("click", removeItem, false);
} is wrong. you need to attach this event handler to each list you create.
you can do that in addItem() using elElement.addEventListener("click", removeItem, false);, then in removeItem(e) just use e to get current element using e.currentTarget and remove it.
This seems to work:
var elList = document.getElementById("list");
var elButton = document.getElementById("btn");
function addItem(e) {
var elElement = document.createElement("li");
var whatever = el.value;
var elText = document.createTextNode(whatever);
elElement.appendChild(elText);
elList.appendChild(elElement);
elElement.addEventListener("click", removeItem, false);
}
function removeItem(e) {
var elElement = e.currentTarget;
var elContainer = elElement.parentNode;
elContainer.removeChild(elElement);
}
var el = document.getElementById("blank");
elButton.addEventListener("click", addItem, false);
#paper {
width: 300px;
height: auto;
margin: 20px auto;
clear: both;
background-color: orange;
}
.grocery, .submit{
text-align: center;
margin: 20px;
}
<div id="paper">
<h3 id="title">Groceries list:</h3>
<ul id="list">
<li></li>
</ul>
</div>
<p class="grocery">
<input type="text" name="grocery" placeholder="ex. Apple" id="blank" />
<label for="grocery">Grocery Name</label>
</p>
<p class="submit">
<input type="submit" value="SEND" id="btn" />
</p>
Your problem is here:
function removeItem(e) {
var elElement = document.getElementsByTagName("li");
var elContainer = elElement.parentNode;
elContainer.removeChild(elElement);
}
This document.getElementsByTagName return an HTMLElementCollection which does not have the a property called parentNode. An element from that collection would.
To avoid the undefined error, you need to check if your object is null or undefined before trying to call a method on in such as .removeChild.
In your case, elContainer is null because the elElement is an HTMLElementCollection which doesn't have the .parentNode property.
You can access elements in the collection by index. It also has a length property which you should check to make sure that the collection has elements.
So if you want to remove the first LI, they you can do it like this.
function removeItem(e) {
var elements= document.getElementsByTagName("li");
if (elements.length==0) return;
var elElement = elements[0];
var elContainer = elElement.parentNode;
elContainer.removeChild(elElement);
}
So if you want to remove the that last LI, they you can do it like this.
function removeItem(e) {
var elements= document.getElementsByTagName("li");
if (elements.length==0) return;
var elElement = elements[elements.length-1];
var elContainer = elElement.parentNode;
elContainer.removeChild(elElement);
}

Get the number of dates time later than current datetime

I have a array of objects where i have a property of date_time, and in this array i wish to get the lenght of dates_times objects that are sooner with my current date_time.
Ex:
[data:[{date: "2017-02-24 16:41:51"}, {date: ""2017-02-21 16:41:51"}...],
last_clicked: "2017-02-24 19:41:51"]
I wish to get the length of objecs on "data" array that haves a date_time sooner than "last_clicked".
Maybe you can try something like this:
let length = data.filter(function(d) {
return new Date(d.date) < new Date(last_clicked)
}).length;
You can use Angulars-orderBy-filter. I set up an example for you, just swap out where I have the id key for your data's date key.
function exampleController($scope, exampleFactory, $filter) {
$scope.list = [];
$scope.reverse = false;
$scope.changeSortOrder = function() {
$scope.reverse = !$scope.reverse;
};
function getList() {
exampleFactory
.getList()
.then(function(list) {
// $scope.list = list;
//alternatively you could filter here and change the sort order with the button if needed at all.
$scope.list = $filter('orderBy')(list, '-id'); //where this would be replaced by date(note: the '-' in front of id changes the sort order ASC/DESC)
//$scope.list = $filter('orderBy')(list, 'id', true); //where 3rd argument is wether order should be reversed
});
}
getList();
}
function exampleFactory($http) {
var root = 'http://jsonplaceholder.typicode.com';
function getList() {
return $http.get(root + '/comments')
.then(function(resp) {
return resp.data;
});
}
return {
getList: getList
};
}
angular
.module('app', [])
.controller('exampleController', exampleController)
.factory('exampleFactory', exampleFactory);
.container-fluid {
background-color: #1D1F20;
color: #fff;
font-size: 14px;
font-weight: bold;
button {
margin-top: 20%;
}
}
ul li {
list-style: none;
margin: 10px;
}
.child-padding>div {
padding: 2px;
}
.col-md-2 {
position: fixed;
button {
margin-bottom: 10%;
}
}
.btn-circle {
width: 30px;
height: 30px;
text-align: center;
padding: 6px 0;
font-size: 12px;
line-height: 1.428571429;
border-radius: 50%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div class="container-fluid" ng-app="app">
<div class="container" ng-controller="exampleController">
<div class="row">
<div class="col-md-2 text-center">
<button class="btn btn-primary" type="button" ng-click="changeSortOrder()">Change Sort Order</button>
</div>
<div class="col-md-10 pull-right">
<ul class="ul">
<li ng-repeat="comment in list | orderBy: 'date': reverse track by $index">
<div class="child-padding">
<div>
<span ng-bind="comment.email"></span>
<span class="pull-right btn-info btn-circle" ng-bind="comment.id"></span>
</div>
<div ng-bind="comment.body"></div>
</div>
<div ng-bind="comment.name"></div>
</li>
</ul>
</div>
</div>
</div>
</div>
Use Date.parse to parse your date strings
DEMO JsFiddle
The following code will alert:
Sooner times: 1
var o = {
data:[
{date: "2017-02-24 16:41:51"},
{date: "2017-02-21 16:41:51"}
],
last_clicked: "2017-02-24 12:41:51"
};
function getSoonerLength(data, soonerThan) {
var count = 0;
for (var i = 0 ; i < data.length ; i++) {
var d = Date.parse(data[i].date);
var than = Date.parse(soonerThan);
if (d < than)
count++;
}
return count;
}
alert('Sooner times: ' + getSoonerLength(o.data, o.last_clicked))

Click event not working in Chrome extension options page

In my options page I generate some rows with an input number and a button, related to entries at chrome storage.
The problem is that the event listener i'm creating for the buttons doesn't work at all.
options.html
<html>
<head>
<title>Select the movie's Id</title>
<style>
body: { padding: 10px; }
.style-1 input[type="number"] {
padding: 10px;
border: solid 1px #dcdcdc;
transition: box-shadow 0.3s, border 0.3s;
width: 5em;
}
.style-1 input[type="number"]:focus,
.style-1 input[type="number"].focus {
border: solid 1px #707070;
box-shadow: 0 0 5px 1px #969696;
}
</style>
</head>
<body>
<legend style="border-bottom: solid 1px">Insert</legend>
<input type="number" name="id" id="id" value="">
<button id="save">Insert</button>
<br>
<br>
<legend style="border-bottom: solid 1px">Manage</legend>
<div id="ghost" style="display: none">
<input type="number" name="VAL">
<button name="DEL" id="" >Delete</button>
<br><br>
</div>
<script src="options.js"></script>
</body>
options.js
document.getElementById('save').addEventListener('click', save_options);
chrome.storage.sync.get('movieId', function(result){
for (var i=0; i<result.movieId.length; i++){
createRow(result.movieId[i]);
}
});
function save_options() {
var id = document.getElementById('id').value;
chrome.storage.sync.get('movieId', function(result){
var ids = result.movieId;
ids.push(id);
chrome.storage.sync.set({
'movieId': ids
}, function() {
});
location.reload();
});
}
function createRow(pos){
var newRows= document.getElementById('ghost').cloneNode(true);
newRows.id= '';
newRows.style.display= 'block';
var newRow= newRows.childNodes;
for (var i= 0; i< newRow.length; i++){
var newName= newRow[i].name;
if (newName){
newRow[i].name = newName+pos;
newRow[i].id = pos;
newRow[i].value = pos;
}
}
var insertHere= document.getElementById('ghost');
insertHere.parentNode.insertBefore(newRows,insertHere);
document.getElementById(pos).addEventListener('click', delet());
}
function loop(arrayIds){
console.log('loop');
for (var i=0; i<arrayIds.length; i++){
createRow(i);
}
}
function delet(){
console.log("this.id");
//chrome.storage.sync.remove(id);
}
With this, when I click any of the Delete buttons nothing happens.
I've tried all the combinations I can think for document.getElementById(pos).addEventListener('click', delet()); but none of them work.
document.getElementById(pos).addEventListener('click', delet());
is supposed to be
document.getElementById(pos).addEventListener('click', delet);
In your snippet you are calling delet thus result of that function is added as event listener that is undefined. If you want to bind delet as event handler, pass it to addEventListener without calling it.
EDIT
As I saw your code, you are giving same id to both input and button and when you call document.getElementById it returns input instead of button so, event is binded to input instead of button.
To fix that replace your createRow with this
function createRow(pos) {
var newRow = document.getElementById('ghost').cloneNode(true);
newRow.id= '';
newRow.style.display= 'block';
var value = newRow.querySelector("[name=VAL]");
var button = newRow.querySelector("[name=DEL]");
value.id = "VAL" + pos;
value.value = pos;
button.id = "DEL" + pos;
var insertHere= document.getElementById('ghost');
insertHere.parentNode.insertBefore(newRow, insertHere);
button.addEventListener('click', delet);
}

Apps Script Template HTML Breaks on Success Handler

Searched, but wasn't able to find any similar problems or solutions.
I have some templated HTML which builds a form based on data from a spreadsheet, as I have a variable number of dropdowns and options in those dropdowns.
On click of submit I want to display a spinning gif to the user, so they know it is processing.
If the backend code in code.gs passes the input through all the tests I want to update a div with a success message, if any of the checks fail with an error message.
I've got this to work, before with the create .createHtmlOutputFromFile method, but now with .createTemplateFromFile it just wipes the whole page.
HTML template
<style type="text/css">
#import url(http://fonts.googleapis.com/css?family=Open+Sans:400,600,300);
#container{
padding-left:10px;
font-family: 'Open Sans', Arial, sans-serif;
}
#header{
width: 75%;
margin: 0 auto;
text-align: center;
margin-bottom:10px;
}
form{
text-align: center;
margin-top:10px;
}
#nameField{
width:400px;
margin-bottom:10px;
}
#reqIndic{
color:#FF0000;
}
select{
margin-top: 5px;
width:150px;
}
#submit{
margin-top:20px;
width:125px;
height:40px;
}
#confirmation{
width: 30%;
margin: 0 auto;
min-height:60px;
border-radius: 5px;
}
#padding{
width: 30%;
margin: 0 auto;
min-height:60px;
border-radius: 5px;
}
</style>
<div id="container">
<div id="header">
<h2>Cheltenham Classic</h2>
</div>
<br>
<form name="projectsForm">
<span id="reqIndic">*</span>
<span> Name</span>
<input id="nameField" type="text" name="name" required>
<br>
<? for (var race in races) { ?>
<span><?= race ?></span>
<select>
<? for (var i = 0; i < races[race].length; i++) { ?>
<option value="<?= races[race][i] ?>"><?= races[race][i] ?></option>
<? } ?>
</select>
<br>
<? } ?>
<br>
<input id="submit" type="submit" value="Submit Form" onclick="google.script.run
.withSuccessHandler(updateDiv)
.onEvent(this.parentNode);spinner()">
</form>
</div>
<div id="confirmation" style ="text-align:center"></div>
<div id="padding" style ="text-align:center"></div>
<script type="text/javascript">
function updateDiv(returnValue){
alert('debug');
var div = document.getElementById('confirmation');
if(returnValue == false){
var errStr = '<p>ERROR: Please check your rankings for blank fields or multiple entries of the same project and re-submit your rankings</p>';
div.innerHTML = errStr;
}
else{
div.innerHTML = '<p>Success! Your results were submitted successfully</p>';
}
}
function spinner(){
var div = document.getElementById('confirmation');
div.innerHTML = '<img src="http://loadinggif.com/images/image-selection/32.gif">'
}
</script>
Back end code
I've cut the onEvent function right down to just returning an object with a key value pair without making any checks.
The updateDiv function runs and the alert shows then the entire page is wiped.
function doGet(){
var raceForm = HtmlService.createTemplateFromFile('RaceForm');
raceForm.races = getRaces();
return raceForm.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function onEvent(e){
return {'valid': true};
}
function getRaces(){
var url = //spreadsheet url
var wb = SpreadsheetApp.openByUrl(url);
var ws = wb.getSheetByName('Races Log');
var racesObj = {};
var wsValues = ws.getDataRange().getValues();
for(var i = 0; i <wsValues.length;i++){
var race = wsValues[i][0];
racesObj[race] = [];
racesObj[race].push('0');
for(var j = 1; j<wsValues[i].length;j++){
racesObj[race].push(wsValues[i][j]);
}
}
return racesObj;
}
Any help much appreciated.
If I hard code the racesObj object:
var racesObj = {one:["one","two"], two:["one", "two"], "races":["belmont", "kentucky"]};
The page looks like this: (Using the template)
If I click the submit button, I get this:

Categories