I am creating a simple rest api in javascript, I want upon initialization, the widget must display a list of all characters.
here is folder structure :
├───book
└───book.js
├───store
│ └───store.js
here is my store.js
window.Store = {
create: function() {
var self = {};
var props = {
name: 'string',
species: 'string',
picture: 'string',
description: 'string'
};
var listProps = ['name', 'species'];
var detailProps = ['name', 'species', 'picture', 'description'];
var characters = [
{
id: makeID(),
name: 'Ndiefi',
species: 'Wookie',
picture: 'store/img/ndiefi.png',
description: 'A legendary Wookiee warrior and Han Solo’s co-pilot aboard the Millennium Falcon, Chewbacca was part of a core group of Rebels who restored freedom to the galaxy. Known for his short temper and accuracy with a bowcaster, Chewie also has a big heart -- and is unwavering in his loyalty to his friends. He has stuck with Han through years of turmoil that have changed both the galaxy and their lives.',
_delay: 500
},
];
}
}
here is index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Character Book</title>
<!-- 3rd party vendor libraries -->
<link rel="stylesheet" href="vendor/font-awesome-4.6.3/css/font-awesome.min.css">
<script src="vendor/jquery-3.1.0.min.js"></script>
<script src="vendor/underscore-1.8.3.min.js"></script>
<!-- 1st party internal libraries -->
<script src="store/store.js"></script>
<script src="tests/start-test.js"></script>
<script src="tests/test-book.js"></script>
<!-- The source of the 'Book' widget -->
<link href="book/book.css" rel="stylesheet">
<script src="book/book.js"></script>
<script>
$(function() {
var frame = $('#test-frame');
var run = $('#test-run');
var results = $('#test-results');
var store = Store.create();
run.click(function() {
run.prop('disabled', true).text('Running Tests');
results.removeClass('test-pass test-fail').text('');
testBook(frame).then(
function success() {
run.prop('disabled', false).text('Run Tests');
results.addClass('test-pass').text('All tests passed');
},
function failure(err) {
run.prop('disabled', false).text('Run Tests');
results.addClass('test-fail').text('Test failed, see console');
}
);
});
Book.init(frame, store);
});
</script>
</head>
<body>
<button id="test-run">Run Tests</button>
<span id="test-results"></span>
<div id="test-frame">
</div>
</body>
</html>
here is what I have tried :
books.js
var data = JSON.parse(characters);
data.forEach(characters => {
console.log(characters.name)
});
so when I run the app in my browser I see the following error :
Uncaught ReferenceError: characters is not defined
what is wrong with my code ? any suggestion or help will be helpfull thanks
Related
I am trying to put Stripe into my web page to accept payments. But whenever I load the page I get an error saying that stripeCheckout is not defined. I know this has to do with the library imported in one of my script tags, but I am not sure why it is showing up as undefined. The library imported I thought was correct. Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- CSS Link -->
<link rel="stylesheet" href="styles.css">
<title>Store</title>
<script src="https://checkout.stripe.com/checkout.js" defer></script>
<script>
var stripePublicKey = '<%= stripePublicKey %>'
</script>
<script src="store.js" defer></script>
</head>
and this in my store.js file
const stripeHandler = stripeCheckout.configure({
key: stripePublicKey,
locale: 'auto',
token: function(token){
}
})
// Removes cart items after they are purchased
const purchaseItems = () => {
// let cartItems = document.getElementsByClassName('cart-items')[0]
// while(cartItems.hasChildNodes()){
// cartItems.removeChild(cartItems.firstChild)
// }
// updateCartTotal()
let priceElement = document.getElementsByClassName('cart-total-price')[0]
let price = parseFloat(priceElement.innerText.replace('$', '')) * 100
stripeHandler.open({
amount: price
})
}
I believe that that particular Stripe checkout API (and script) is now deprecated.
Here's a link to the docs for the new APIs: https://stripe.com/docs/payments/checkout/migration#client-products
Example from docs:
// client.html
<script src="https://js.stripe.com/v3"></script>
<button id="checkout-button">Pay</button>
// client.js
var stripe = Stripe('YOUR_API_KEY');
var checkoutButton = document.querySelector('#checkout-button');
checkoutButton.addEventListener('click', function () {
stripe.redirectToCheckout({
items: [{
// Define the product and SKU in the Dashboard first, and use the SKU
// ID in your client-side code.
sku: 'sku_123',
quantity: 1
}],
successUrl: 'https://www.example.com/success',
cancelUrl: 'https://www.example.com/cancel'
});
});
how are you. I'm implementing a rating at IONIC, although this is basically angular. I want to get the value for each category. if I qualify rubric "animals" I want to get the value I selected. if I qualify "cars" I want to get the value I selected.
My problem is that I always get the same value for both categories. What can I do?. I want to know what is the best solution because then I think creating dynamic code and do not want to repeat code in n categories.
http://plnkr.co/edit/1PomwzklGD2Y8esbsnxT?p=preview
HTML
What do you think about the animals?
<ionic-ratings ratingsobj='ratingsObject'></ionic-ratings>
What do you think about the cars??
<ionic-ratings ratingsobj='ratingsObject'></ionic-ratings>
JAVASCRIPT
$scope.ratingsObject = {
iconOn: 'ion-ios-star', //Optional
iconOff: 'ion-ios-star-outline', //Optional
iconOnColor: 'rgb(200, 200, 100)', //Optional
iconOffColor: 'rgb(200, 100, 100)', //Optional
rating: 4, //Optional
minRating: 1, //Optional
readOnly:false, //Optional
callback: function(rating) { //Mandatory
$scope.ratingsCallback(rating);
}
};
$scope.ratingsCallback = function(rating) {
$scope.cars=rating;
$scope.animals=rating;
console.log('Selected rating is : ', rating);
//is the same value :(
console.log("animals: "+$scope.animals);
console.log("cars: "+$scope.cars);
};
I suggest to use another ionic rating library like this one which enables the use of ng-model. So you can use ng-repeat with an array as a model, and then bind the <rating> directive to a property automatically updated when user set the rating.
Here below is your example adapted to use that lib and made dynamic:
angular.module('ionicApp', ['ionic', 'ionic.rating'])
.controller('MyCtrl', function($scope) {
$scope.myTitle = 'IONIC RATINGS DEMO';
$scope.categories = [{
name: "animals",
question: "What do you think about the animals?",
rating: 0
}, {
name: "cars",
question: "What do you think about the cars?",
rating: 0
}, {
name: "flowers",
question: "What do you think about the flowers?",
rating: 0
}];
$scope.rating = {};
$scope.rating.max = 5;
});
<!DOCTYPE html>
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link href="http://code.ionicframework.com/nightly/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
<script src="https://rawgit.com/fraserxu/ionic-rating/master/ionic-rating.js"></script>
<link rel="stylesheet" href="https://rawgit.com/fraserxu/ionic-rating/master/ionic-rating.css">
<script src="script.js"></script>
</head>
<body ng-controller="MyCtrl">
<ion-view>
<h1 class="text-center">{{myTitle}}</h1>
<div class="list">
<div class="item item-button-right" ng-repeat="category in categories">
{{category.question}}
<rating ng-model="category.rating" max="rating.max"></rating>
</div>
</div>
<pre>categories = {{categories|json}}</pre>
</ion-view>
</body>
</html>
P.S.: in the <pre> tag is shown the model only for debug and demo.
I am having issues finding out why the filter is undefined...
Uncaught ReferenceError: filter is not defined(anonymous function) # mainController.js:46(anonymous function) # mainController.js:76
What am I missing?
Index =
<!DOCTYPE html>
<html ng-app="app" ng-open="main.refreshData()">
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="Content/site.css">
<!--<link data-require="ui-grid#*" data-semver="3.0.0RC18" rel="stylesheet" type="text/css" href="Content/ui-grid.css">-->
<link data-require="ui-grid#*" data-semver="3.0.0RC18" rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" />
<script src="Scripts/jquery-2.1.4.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script src="Application/app.module.js"></script>
<script src="Application/mainController.js"></script>
<script src="Scripts/ui-grid.min.js"></script>
</head>
<body ng-controller="MainController as main">
<input type="text" ng-model="main.food" placeholder="Enter food" />
<p>Sriracha sauce is great with {{main.food}}!</p>
<br />
<br />
<input type="text" ng-model="main.filterText" ng-change="refreshData()" placeholder="Search..." />
<br />
<br />
<h>{{main.title}}</h>
<div class="grid" ui-grid='main.gridOptions' id="grid1"></div>
</body>
</html>
app =
//The app.module.js file houses a single application-level module for your application.
//In this example, your application has an application-level module that loads the
//other modules of the application. The purpose of adding app.module.js as a separate
//file is to introduce the concept that modules, controllers, services, directives,
//views, etc. should be defined in their own files.
//<<Immediately-invoked function expression>>
//Immediately-invoked function expressions can be used to avoid variable hoisting from
//within blocks, protect against polluting the global environment and simultaneously
//allow public access to methods while retaining privacy for variables defined within the function.
(function () {
'use strict';
angular.module('app', []);
})();
Controller =
(function () {
'use strict';
angular
.module('app', ['ui.grid'])
.controller('MainController', main);
function main() {
var self = this;
self.food = 'pizza';
self.myData = [{
name: "Moroni",
age: 50
}, {
name: "Tiancum",
age: 43
}, {
name: "Jacob",
age: 27
}, {
name: "Nephi",
age: 29
}, {
name: "Enos",
age: 34
}];
self.gridOptions = {
data: "main.myData",
enableGridMenu: true
};
self.title = "ng-grid Example";
self.filterText;
self.refreshData = function () {
self.gridOptions.data = self.filter('filter')(self.myData, self.filterText, undefined);
};
}
//Define a custom filter to search only visible columns (used with grid 3)
filter('visibleColumns', function () {
return function (data, grid, query) {
matches = [];
//no filter defined so bail
if (query === undefined || query === '') {
return data;
}
query = query.toLowerCase();
//loop through data items and visible fields searching for match
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < grid.columnDefs.length; j++) {
var dataItem = data[i];
var fieldName = grid.columnDefs[j]['field'];
//as soon as search term is found, add to match and move to next dataItem
if (dataItem[fieldName].toString().toLowerCase().indexOf(query) > -1) {
matches.push(dataItem);
break;
}
}
}
return matches;
}
});
})();
Translate your filter to function and bind it to application.
angular
.module('app', ['ui.grid'])
.controller('MainController', main)
.filter('visibleColumns', visibleColumns);
function visibleColumns () {...}
There is no function filter(), there is method of angular.module Object that called filter('name', function() { ... }).
More about custom filters
I am doing a very simple Backbone app example and I keep getting a JS error message. I basically have two files:
app.js
This file creates a Backbone.js app the appends a span from a template using data from a collection view to an already created div on the html file.
/*Backbone.js Appointments App*/
App = (function($){
//Create Appointment Model
var Appointment = Backbone.Model.extend({});
//Create Appointments Collection
var Appointments = Backbone.Collection.extend({
model: Appointment
});
//Instantiate Appointments Collection
var appointmentList = new Appointments();
appointmentList.reset(
[{startDate: '2013-01-11', title: 'First Appointment', description: 'None', id: 1},
{startDate: '2013-02-21', title: 'Second Appointment', description: 'None', id: 2},
{startDate: '2013-02-26', title: 'Third Appointment', description: 'None', id: 3}
]
);
//Create Appointment View
var AppointmentView = Backbone.View.extend({
template: _.template(
'<span class="appointment" title="<%= description %>">' +
' <span class="title"><%= title %></span>' +
' <span class="delete">X</span>' +
'</span>'
),
initialize: function(options) {
this.container = $('#container');
},
render: function() {
$(this.el).html(this.template(this.model));
this.container.append(this.el);
return this;
}
});
var self = {};
self.start = function(){
new AppointmentView({collection: appointmentList}).render();
};
return self;
});
$(function(){
new App(jQuery).start();
});
index.html
This file just calls the jquery, backbone and other js libraries and also created the div container where the Backbone.js app from the previous file will append the data.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello-backbonejs</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.6/underscore-min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>
<script src="app.js" type="text/javascript"></script>
</head>
<body>
<div id="container"></div>
</body>
</html>
The error I get is the following:
Uncaught TypeError: Object [object Object] has no method 'reset' app.js:14
App app.js:14
(anonymous function) app.js:49
e.resolveWith jquery.min.js:16
e.extend.ready jquery.min.js:16
c.addEventListener.z jquery.min.js:16
You use Backbone 0.3.3 but Collection.reset was introduced in Backbone 0.5. See the changelog for more information.
Either upgrade Backbone (0.9.9 at the moment) (and Underscore and jQuery while you're at it) or use Collection#refresh if you absolutely have to keep Backbone 0.3.3 (but you will probably trip other errors down the road).
I have the following code working with a DataGrid that has two column Column_A and Column_B respectively:
grid.filter({Column_A: '*test*', Column_B: '*'}, true)
This code works fine and finds all rows where Column_A has the word test in it... now, I'd like to do the same but look in either column.... the comma translates to an AND operation but I am looking for an OR operation.
I read the AndOrReadStore specs and based on my understanding I should be able to do something like this:
grid.filter({complexQuery: "Column_A: '*test*' OR Column_B: '*'"}, true)
however this does not work and I don't get any results... I can't even get it to work with one column, like this
grid.filter({complexQuery: "Column_A: '*test*'"}, true)
What am I doing wrong?
Thank you
Here is a working programmatic example (Click the button to invoke the filter: Column_A contains an e OR Column_B is 300):
the JavaScript (script.js):
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.form.Button");
dojo.require("dojox.grid.DataGrid");
dojo.require('dojox.data.AndOrReadStore');
dojo.ready(function(){
var appLayout = new dijit.layout.ContentPane({
id: "appLayout"
}, "appLayout");
var data = {
'items': [
{'Column_A': 'alpha', 'Column_B': '100'},
{'Column_A': 'beta', 'Column_B': '200'},
{'Column_A': 'gamma', 'Column_B': '300'},
{'Column_A': 'delta', 'Column_B': '400'}
]
};
var store = new dojox.data.AndOrReadStore({
data: data
});
var layout = [[
{name : 'A', field : 'Column_A', width : '125px'},
{name : 'B', field : 'Column_B', width : '100%'}
]];
var grid = new dojox.grid.DataGrid({
structure : layout,
store: store,
queryOptions: {ignoreCase: true}
});
var filterButton = new dijit.form.Button({
label: "Filter",
onClick: function () {
grid.filter({complexQuery: "Column_A: '*e*' OR 'Column_B: '300'"});
}
});
filterButton.placeAt(appLayout.domNode);
grid.placeAt(appLayout.domNode);
appLayout.startup();
});
And now the html (index.html)
<html lang="en">
<head>
<meta charset="utf-8">
<title>DataGrid with AndOrReadStore</title>
<link rel="stylesheet" href="style.css" media="screen"/>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/claro.css" />
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/document.css" />
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/layout/resources/ExpandoPane.css" />
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/grid/resources/claroGrid.css">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/grid/enhanced/resources/claro/EnhancedGrid.css">
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js" type="text/javascript"></script>
<script src="script.js" type="text/javascript"></script>
</head>
<body class="claro">
<div id="appLayout"></div>
</body>
</html>
And finally the css (style.css)
html, body {
width: 100%; height: 100%;
margin: 0; padding: 0;
overflow: hidden;
}
#appLayout {
width: 100%; height: 100%;
}
I looked at the link you posted, and I think it's an issue of getting the brackets and parenthesis correct. Also, it looks like the 'complex query' is used for objects, whereas 'query' is used for strings:
grid.filter({query: ("Column_A: '*test*' OR Column_B: '*'")}, true);
Here's the link I looked at: http://dojotoolkit.org/reference-guide/dojox/data/AndOrReadStore.html#dojox-data-andorreadstore