Move 'var' declarations to the top of the function - Javascript error - javascript

I'm following a tutorial on how to create dynamically updating comments within a form. The guide I'm following keeps presenting errors and the one I have just recently found is not letting me fix it. it's telling me that I need to move 'var' declarations to the top of the function. There is also no definition of '$'
Any help is appreciated!
Here's is my JavaSript
var comment = [
{"name": "name1", "date": "00-00-0000", "body": "comment here1"},
{"name": "name2", "date": "00-00-0000", "body": "comment here2"},
{"name": "name3", "date": "00-00-0000", "body": "comment here3"}
];
for (var i=0;i<comment.length;i++){
var html = "<div class='commentBox'><div class='leftPanelImg'><img src='images/Reviews/Comment%20pic.jpg'></div><div class='rightPanel'><span>"+comment[i].name+"</span><div class='date'>"+comment[i].date+"</div><p>"+comment[i].body+"</p></div><div class='clear'></div></div>"
$('#container').append(html);
}
Here's my HTML
<!DOCTYPE html>
<html>
<head>
<title> Reviews</title>
<link href="css/Review.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class='form'>
<h3>Please write a review about your stay</h3>
Name: <input type="text" id="name"/> <br> <br>
Date: <input type="date" id="date"/> <br> <br>
Comment: <textarea rows="7" col="30" id="bodyText"></textarea><br>
<input type="button" id="addComment" value="Submit">
</div>
<h2>Comments</h2>
<div id='container'>
</div>
Go to Homepage
<script src="https://ajax.googleapis.com/ajax/libs/d3js/5.7.0/d3.min.js"></script>
<script src="Review.jquery.js" type="text/javascript"></script>
</body>
</html>

The linter is telling you that you should declare i and comment at the same point that the interpreter sees the variable is declared, which will either be at the top of the innermost function, or if you're on the top level already, at the very top of the top level. For example, for your code:
var i;
var comment;
var html;
comment = [
{"name": "name1", "date": "00-00-0000", "body": "comment here1"},
{"name": "name2", "date": "00-00-0000", "body": "comment here2"},
{"name": "name3", "date": "00-00-0000", "body": "comment here3"}
];
for (i=0;i<comment.length;i++){
html = "<div class='commentBox'><div class='leftPanelImg'><img src='images/Reviews/Comment%20pic.jpg'></div><div class='rightPanel'><span>"+comment[i].name+"</span><div class='date'>"+comment[i].date+"</div><p>"+comment[i].body+"</p></div><div class='clear'></div></div>"
$('#container').append(html);
}
If you don't do this, you can confuse yourself due to var's unintuitive hoisting problems - that's what the linting rule is for. (It's not a Javascript interpreter error, it's only an error thrown by your linter.)
That said, you might consider using modern syntax instead, with const and let, which are not hoisted, and you can use array methods instead of for loops for more functional and terse code, if you wish:
const comment = [
{"name": "name1", "date": "00-00-0000", "body": "comment here1"},
{"name": "name2", "date": "00-00-0000", "body": "comment here2"},
{"name": "name3", "date": "00-00-0000", "body": "comment here3"}
];
comment.forEach(({ name, date, body }) => {
const html = "<div class='commentBox'><div class='leftPanelImg'><img src='images/Reviews/Comment%20pic.jpg'></div><div class='rightPanel'><span>"+name+"</span><div class='date'>"+.date+"</div><p>"+body+"</p></div><div class='clear'></div></div>"
$('#container').append(html);
});
You also might consider using a modern linter, like ESLint. JSLint is quite old and does not understand much of the nice syntax sugar modern JS allows us.

Related

Tabulator: load data from a JSON file

I want Tabulator to automatically load data from a JSON file.
I have made it work with a button.
I have read the q & a here
Load table data from text file
I have also read the documentation here.
http://tabulator.info/docs/4.4/data#array-initial
(By the way, I was expecting the ajaxURL documentation to show a URL ending with a FILE name rather than "/now"... something like $("#div1").load("demo_test.txt"); )
I'm not a professional developer so please be gentle with me.
Here is the content of the JSON file (called "test_Array.txt" and in the same directory as the HTML).
[
{"name": "Oli Bob", "age": "12", "col": "red", "dob": "14/05/1982"},
{"name": "Mary May", "age": "1", "col": "blue", "dob": "14/05/1982"},
{"name": "Christine Lobowski", "age": "42", "col": "green", "dob": "22/05/1982"},
{"name": "Brendon Philips", "age": "125", "col": "orange", "dob": "01/08/1980"},
{"name": "Margret Marmajuke", "age": "16", "col": "yellow", "dob": "31/01/1999"}
]
It passes validation at
https://jsonlint.com/
Here is the HTML
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://unpkg.com/tabulator-tables#5.1.3/dist/css/tabulator_site.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#5.1.3/dist/js/tabulator.min.js"></script>
<meta charset="utf-8" />
<title>tabulator3</title>
</head>
<body>
<div id="example-table"></div>
<script>
//create Tabulator on DOM element with id "example-table"
var table = new Tabulator("#example-table", {
height:205,
// set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
//layout:"fitDataFill",//fit columns to fit data and width of table (optional)
//data:tableData, //set initial table data
columns:[ //Define Table Columns
{title:"Name", field:"name", width:150},
{title:"Age", field:"age", align:"left", formatter:"progress"},
{title:"Favourite Color", field:"col"},
{title:"Date Of Birth", field:"dob", sorter:"date", align:"center"},
]
});
//load sample data into the table
table.setData("test_Array.txt")
</script>
</body>
</html>
What am I doing wrong?
Thank you.
To start off I would say you have posted a link to the v4.4 documentation, but using version 5.1 of Tabulator. It is defo worth reading the correct docs to get started :)
Following on from that the issue that you are experiencing is because as of version 5.0 Tabulator now has an async start up process that means you cant just call setData straight after instantiating the table, you must wait for the tableBuilt event:
table.on("tableBuilt", function(){
table.setData("./test_Array.txt");
});
More importantly if you are just loading data straight from the file then there is no need to set data after the table has been built, you can use the ajaxURL setup option to load the data into the table while it is being built:
var table = new Tabulator("#example-table", {
ajaxURL:"./test_Array.txt",
... other table options
});
As a complete aside if the text file just contains JSON data, then the convention is to end the file with .json instead of .txt
For any other novices/amateurs out there....following Oli's advice I have a working solution as follows:
Create a JSON file called text_Array.json with the following content:
[
{"name": "Oli Bob", "age": "12", "col": "red", "dob": "14/05/1982"},
{"name": "Mary May", "age": "1", "col": "blue", "dob": "14/05/1982"},
{"name": "Christine Lobowski", "age": "42", "col": "green", "dob": "22/05/1982"},
{"name": "Brendon Philips", "age": "125", "col": "orange", "dob": "01/08/1980"},
{"name": "Margret Marmajuke", "age": "16", "col": "yellow", "dob": "31/01/1999"}
]
Create an html file called tabulator3.html with the following content. Put the JSON file in the same folder as the HTML file and it will work :
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://unpkg.com/tabulator-tables#5.1.3/dist/css/tabulator_site.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#5.1.3/dist/js/tabulator.min.js"></script>
<!-- the line below is necessary for the Date sorter to work - it is buried in the v5.1 documentation here
http://tabulator.info/docs/5.1/sort#func-builtin -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.3.1/luxon.min.js"></script>
<meta charset="utf-8" />
<title>tabulator3</title>
</head>
<body>
<div id="example-table"></div>
<script>
//create Tabulator on DOM element with id "example-table"
var table = new Tabulator("#example-table", {
ajaxURL:"test_Array.json", //load sample data into the table
height:205,
columns:[ //Define Table Columns
{title:"Name", field:"name", width:150},
{title:"Age", field:"age", hozAlign:"left", formatter:"progress"},
{title:"Favourite Color", field:"col"},
{title:"Date Of Birth", field:"dob", sorter:"date", hozAlign:"center"},
]
});
</script>
</body>
</html>
Thanks, Oli!

AngularJs appending options to select box

I am new to AngularJs. I am having problem in appending options to select boxes created by javascript. Following is my code.
var inputElements = $('<div><label style="float:left;">' + i + '</label><select ng-model="object" class="form-control sel" style="width:300px; float:right; margin-right:75px;"> <option>select</option></select></div></br></br>');
var temp = $compile(inputElements)($scope);
$('#projOrder').append(temp);
$scope.object = object;
//for(var opt=0; opt<selOptLabels.length; opt++) {
$('.sel').append('<option ng-repeat="obj in object" value="'+
{{obj.value}}+'">'+{{obj.value}}+'</option>');
I am getting this error:- SyntaxError: invalid property id
Hi, I am posting json example. This is just a small part of json in my case.
"ProjectOrder": {
"Connect direct required": {
"value": "N",
"id": "STR_15523_62"
},
"Cores": {
"value": ".5",
"id": "NUM_15523_50"
},
"Permanent data in GB": {
"value": "100",
"id": "NUM_15523_56"
},
"Description": {
"value": "AZBNL azbngb",
"id": "STR_15523_2"
},
"Order Id": {
"value": "15523",
"id": "INT_15523_96"
},
"Project cost center": {
"value": "N",
"id": "STR_15523_66"
},
"Project debitor": {
"value": "N",
"id": "STR_15523_64"
},
"Project OE": {
"value": "N",
"id": "STR_15523_57"
},
"Project SITE": {
"value": "N",
"id": "STR_15523_59"
},
"Project Status": {
"value": "RFC",
"id": "STR_15523_54",
"dropdown": [
{
"value": "IW",
"label": "In Work"
},
{
"value": "RFC",
"label": "Ready for Creation"
},
{
"value": "CR",
"label": "Created"
},
{
"value": "FC",
"label": "Failed"
}
]
},
"Project Type (paas, miner)": {
"value": "paas",
"id": "STR_15523_37",
"dropdown": [
{
"value": "paas",
"label": "PaaS Project"
},
{
"value": "miner",
"label": "Miner Project"
}
]
},
"WORK data in GB": {
"value": "100",
"id": "NUM_15523_55"
}
}
Now I have to create input fields and dropdown menus(if there is a dropdown menu) with json data
You really should not be hand-constructing HTML like that. It's best if you use a template and let the template engine handle the heavy lifting.
I also noticed that you're using object as the ng-model. Instead you should have a separate variable which will hold the selected value.
Here's a better way of doing this--in an .html file:
<div ng-repeat="object in listOfObjects"
<label style="float: left">{{ $index }}</label>
<select ng-model="selectedValues[$index]" class="form-control sel"
style="width:300px; float:right; margin-right:75px;"
ng-options="obj.value for obj in object"></select>
</div>
Then in whatever controller you have set up in JavaScript:
// this will be the list of selected values
$scope.selectedValues = new Array(list.length);
// this would be the array that each `object` is part of
$scope.listOfObjects = list;
This isn't the most elegant solution, but basically what I've done is construct an array that is the same length as the list of objects. Angular templates have a special variable $index when you're in an ng-repeat which tracks the current index of the array you're looping through.
So when a user changes the selected value of the 3rd select box (index 2), $scope.selectedValues[2] would be set to the selected option.
EDIT: on transforming the JSON to an array:
var list = Object.keys(json).map(function(jsonKey) {
return {
name: jsonKey,
label: json[jsonKey].label,
value: json[jsonKey].value
};
});`
So.. there are a number of reasons why that won't work. The provided code wouldn't even work because of the template brackets that you are trying to append to your html string...
$('.sel').append('<option ng-repeat="obj in object" value="' +{{obj.value}}+'">'+{{obj.value}}+'</option>');
Is there a reason that you are trying build your markup in js?
It's also advised not to use jquery inside angular controllers. If you have jquery loaded the jQuery object is available through angular.element, otherwise angular uses jQuery light.
Rather than enumerate on the other issues here, I put together this basic example of how a select works in Angular
https://codepen.io/parallaxisjones/pen/BRKebV
Also, you should consult the angular documentation before posting questions to stack overflow. The docs provide a pretty clear example of how to use ng-repeat in a select. https://docs.angularjs.org/api/ng/directive/select
EDIT: I updated my codepen with an example of fetching JSON data with an HTTP GET request
EDIT: updated codepen with provided data example, iterating over object with (key, value) in json syntax in ng-repeat

Output page blank while fetching data from JSON file in AngularJS

I have just started learning angularjs, I'm trying to load data from my json file on view. json file has a list of houses. But does not get showed on my view when I load the index.html file.
Data.json
[
{
"type": "Condo",
"price": 220000,
"address": "213 Grove Street",
"description": "Excellent place! Really nice view!"
},
{
"type": "House",
"price": 410500,
"address": "7823 Winding Way",
"description": "Beautiful home with lots of space for large family."
},
{
"type": "Duplex",
"price": 395000,
"address": "834 River Lane",
"description": "Great neighourhood and lot's of nice green space."
},
]
cribsFactory.js
angular
.module('ngCribs')
.factory('cribsFactory', function($http) {
function getCribs() {
return $http.get('data/data.json');
}
return {
getCribs: getCribs
}
});
cribsController.js
angular
.module('ngCribs')
.controller('cribsController', function($scope, cribsFactory) {
$scope.cribs;
cribsFactory.getCribs().success(function(data) {
$scope.cribs = data;
}).error(function(error) {
console.log(error);
});
});
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ng-cribbs</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body ng-app="ngCribs" ng-controller="cribsController">
<div class="well" ng-repeat="crib in cribs">
<h3>{{ crib.address }}</h3>
<p>
<strong>Type: </strong>{{ crib.type }}</p>
<p>
<strong>Description: </strong>{{ crib.description }}</p>
<p>
<strong>Price: </strong>{{ crib.price | currency }}</p>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"/>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap.min.js"/>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"/>
</script>
<script src="app.js"/>
</script>
<script src="scripts/cribsController.js"/>
</script>
<script src="scripts/cribsFactory.js"/>
</script>
</html>
I'm trying to run the above code in htdocs folder of XAMPP. The folder structure is in the screen shot below.
The json file is inside the data folder and the files cribsFactory.js & cribsController.js are in scripts folder. When i type the URL "http://localhost/ng-cribbs/" in Firefox the output is a completely blank page with no error message of any sort hence the difficulty in debugging.
I was able to load data using an array but facing problem while using JSON file.. Can't understand what I'm doing wrong. Please help!!
Your json data was not valid, validate any json data before and you can use the below corrected json. Hope it helps! validate json here
[{
"type": "Condo",
"price": 220000,
"address": "213 Grove Street",
"description": "Excellent place! Really nice view!"
}, {
"type": "House",
"price": 410500,
"address": "7823 Winding Way",
"description": "Beautiful home with lots of space for large family."
}, {
"type": "Duplex",
"price": 395000,
"address": "834 River Lane",
"description": "Great neighourhood and lot's of nice green space."
}]
Your http call gives you a json string, you should convert it to a javascript array like so: $scope.cribs = JSON.parse(data)

How do I access JSON objects using Handlebars.js?

I'm creating a basic web app using the Echo Nest API to get used to templating and fetching data from APIs. I was just wondering how I would access the 'artist_name' & 'title' objects inside 'song' from the JSON object and use Handlebars.js to insert this data inside my template? When I do the {{#each songs}} as I've written below, it doesn't work.
Thanks in advance!
PS. Jeanie Tracy does not reflect my music taste. It's just the JSON object that came up when I was testing it!
<main>
<section>
<input type="text" id="genre-name" placeholder="Enter the Genre Here." />
<input type="number" id="bpm" placeholder="Enter the BPM here." id="bpm">
Fetch
</section>
<section id="results">
</section>
</main>
<template id="results-template">
<article>
<header>
{{#each songs}}
<h1>{{ this.artist_name }}</h1> {{/each}}
</template>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="handlebars.js"></script>
<script type="text/javascript">
$('#fetch-albums').on('click', function() {
var genre = $('#genre-name').val();
var bpm = $('#bpm').val();
var source = $('#results-template').html();
var template = Handlebars.compile(source);
$.get('http://developer.echonest.com/api/v4/song/search?api_key=[hidden]&style=' + genre + '&min_danceability=0.65&min_tempo=' + bpm + '&results=5', function(data) {
$('#results').append(template(data));
});
});
</script>
JSON OBJECT
{
"response": {
"status": {
"version": "4.2",
"code": 0,
"message": "Success"
},
"songs": [{
"artist_id": "AR8COOH1187B990D7D",
"id": "SOGMVZZ1393A2A9142",
"artist_name": "Jeanie Tracy",
"title": "I'm Gonna Get You"
}, {
"artist_id": "AR8COOH1187B990D7D",
"id": "SOGMIVN14248BD9E88",
"artist_name": "Jeanie Tracy",
"title": "Feel Like Dancing [Joey Negro Dubbed Out]"
}, {
"artist_id": "AR8COOH1187B990D7D",
"id": "SOIMUFZ1315CD4CDEC",
"artist_name": "Jeanie Tracy",
"title": "Do You Believe In Wonder (Stone & Nick Late Nite Diner Mix)"
}, {
"artist_id": "AR8COOH1187B990D7D",
"id": "SOEQTUW1315CD4FAB2",
"artist_name": "Jeanie Tracy",
"title": "Intro"
}, {
"artist_id": "AR8COOH1187B990D7D",
"id": "SOENYBA12A6D4F46C0",
"artist_name": "Jeanie Tracy",
"title": "Rosabel's Disco Diva Mix"
}]
}
}
Your <article> and <header> don't have closing tags. While the HTML specifications may allow some tags to omit closing (like <td>, afaik), and while some browsers are forgiving enough, I don't know if the Handlebars compiler is the same.
Your songs is still under response. I think it should be {{#each response.songs}}. Also, I think you can go with {{ artist_name }} too.

Creating a dynamic toc.json to use with treesaver.js

I've been working for quite some time with a simple backend (based on Spagent - a flat file blogging script) to use with the amazing javascript library treesaver.js. My problem is that I have a lack in my json skill set and can't for the world figure out how to add arrays to my .json...
My file looks like this:
{
"contents": [
{
"url": "index.html",
"hidden": true
},
{
"url": "section1.html",
"title": "Section One",
"thumb": "openroad-thumb.jpg",
"byline": "John Doe"
},
{
"url": "one.html",
"title": "Article One",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "two.html",
"title": "Article Two",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "section2.html",
"title": "Section Two",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "three.html",
"title": "Article Three",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "four.html",
"title": "Article Four",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url":"five.html",
"title":"Article Five",
"thumb":"unknown-thumb.jpeg",
"byline":"John Doe"
}
]
}
And when I use these scripts:
form.php
<!doctype html>
<html class="no-js no-treesaver">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,minimum-scale=1,maximum-scale=1">
<title>Treesaver - Article One</title>
</head>
<body>
<form name="postform" action="post.php" method="post" enctype="multipart/form-data">
<table class="postarea" id="postarea">
<tbody>
<tr> <td class="postblock">URL:</td><td><input type="text" name="url"></td></tr>
<tr> <td class="postblock">Titel:</td><td><input type="text" name="title"></td></tr>
<tr> <td class="postblock">Thumb:</td><td><textarea id="text" rows="5" cols="30" type="text" name="thumb"></textarea> </td> </tr>
<tr> <td class="postblock">Skribent:</td><td><input type="text" name="byline"></td></tr>
<tr> <td class="postblock"></td><td> <input type="submit" value="Submit Entry"> </td> </tr>
</tbody>
</table>
</form>
</form>
</body>
</html>
post.php
<?php
// check if a form was submitted
if( !empty( $_POST ) ){
// convert form data to json format
$postArray = array(
"url" => $_POST['url'],
"title" => $_POST['title'],
"thumb" => $_POST['thumb'],
"byline" => $_POST['byline']
);
//you might need to process any other post fields you have..
$json = json_encode( $postArray);
// make sure there were no problems
//if( json_last_error() != JSON_ERROR_NONE ){
//exit; // do your error handling here instead of exiting
// }
$file = 'entries.json';
// write to file
// note: _server_ path, NOT "web address (url)"!
file_put_contents( $file, $json, FILE_APPEND);
}
My added array is generated like this:
{
"url": "index.html",
"hidden": true
},
{
"url": "section1.html",
"title": "Section One",
"thumb": "openroad-thumb.jpg",
"byline": "John Doe"
},
{
"url": "one.html",
"title": "Article One",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "two.html",
"title": "Article Two",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "section2.html",
"title": "Section Two",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "three.html",
"title": "Article Three",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url": "four.html",
"title": "Article Four",
"thumb": "river-thumb.jpg",
"byline": "Jane Doe"
},
{
"url":"five.html",
"headline":"Article Five",
"thumb":"nagot.jpg",
"byline":"Gustaf"
}{"url":"six.html","title":"Article Six","thumb":"jasas.jpg","byline":"John Doe"}
No comma , is generated after my array and the script is broken. How do I solve this?
You're appending a fresh JSON object into a file already containing one. You might be able to solve it by prepending a comma to the data you are writing, but I'd say that's the wrong way to solve this. You're trying to write in JSON format directly, but you should be getting PHP to do this for you - it does this very well already, and there's no point re-inventing the wheel.
I would therefore read the contents of the file in, convert it to an object or array as appropriate (using json_decode). You can then append things to this structure and re-encode it, before writing the whole thing to a file without the append flag.
If the amount of data in this file is large, you could tackle the problem another way: for every new structure you wish to write, put it in a separate file, and then read them in your blogging script as you need them.
change
file_put_contents( $file, $json, FILE_APPEND);
to
file_put_contents( $file, ",".$json, FILE_APPEND);
You can put the above statement inside some if statement that checks if the file is not empty since you don't need a comma if you are making first insertion.
You would be best advised to read the existing json data and convert it back to its PHP condition which is a Class with the property 'contents' which is an array.
Then you push your new array onto this existing array, and then encode it all as json again and write it all back to your json file.
// check if a form was submitted
if( !empty( $_POST ) ){
$file = 'entries.json';
$json = file_get_contents($file);
// convert json back to a php stdClass
$phpClass = json_decode($json);
$postArray = array(
"url" => $_POST['url'],
"title" => $_POST['title'],
"thumb" => $_POST['thumb'],
"byline" => $_POST['byline']
);
// push the new $postArray onto the bottom of phpClass
array_push($phpClass->contents, $postArray);
// encode php class into json again
$new_json = json_encode($phpClass);
// write it out
file_put_contents( $file, $new_json);
}

Categories