Implementing CRUD functions in JavaScript with an object - javascript

So I've been trying to implement the CRUD functions into my application (which is a quote generator). Quotes are stored inside of an object:
const citati = [
{
id: 1,
name: "First, solve the problem. Then, write the code. - John Johnson",
},
{
id: 2,
name: "Java is to JavaScript what car is to Carpet. - Chris Heilmann",
},
{
id: 3,
name: "Any fool can write code that a computer can understand. Good programmers write code that humans can understand. - Martin Fowler",
},
{
id: 4,
name: "Code is like humor. When you have to explain it, it's bad. - Cory House",
},
{
id: 5,
name: "Optimism is an occupational hazard of programming: feedback is the treatment. - Kent Beck",
},
{ id: 6, name: "Simplicity is the soul of efficiency. - Austin Freeman" },
{
id: 7,
name: "Before software can be reusable it first has to be usable. - Ralph Johnson",
},
{ id: 8, name: "It's harder to read code than to write it. — Joel Spolsky" },
{ id: 9, name: "Deleted code is debugged code. - Jeff Sickel" },
];
And the HTML code is as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="main.css" />
<title>Quote Generator</title>
</head>
<body>
<div class="container">
<div class="title">- Quote Generator -</div>
<div class="list">
<h4>Search your quote:</h2>
<input
autofocus
placeholder="search"
class="input"
type="text"
autocomplete="off"
name="search"
id="search"
/>
<ul class="list-group" id="list"></ul>
</div>
<div id="quote-generator">
<button id="btn" class="btn randomQuote">Press for a new quote!</button>
<div id="output" class="txt">Press the button to generate a new quote!</div>
<button id="btnCreate">Add</button>
<button id="btnUpdate" class="update">Update</button>
<button class="check">Check</button>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
I've tried implementing the Create function:
btnCreate.addEventListener("click", function () {
citati.push({
name: prompt("Unesite citat i autora u obliku: citat - autor"),
});
});
But I still need to add the id in the function (tips for that are welcome). Now, I think I should be using the id's in the object for other functions but I am kind of lost and don't know how. The main idea is to update/delete the currently displayed quote. How do I get the current quote that is displayed? I tried with findIndex:
const outputTxt = document.querySelector(".txt").textContent;
function objIndex(citat) {
return citat.name === outputTxt;
}
document.querySelector(".check").addEventListener("click", function () {
console.log(citati.findIndex(objIndex));
});
But it doesn't work the right way.
If anyone could help with this matter I would be very grateful :)
Cheers!
P.S. here is the whole code if anyone needs to see it: https://github.com/msostaric-hub/app1
--SOLUTION--
Update: I figured it out! Here is the code that did the trick:
document.querySelector(".check").addEventListener("click", function () {
const outputTxt = document.querySelector(".txt").textContent;
const index = citati.findIndex((x) => x.name === outputTxt);
citati[index] = {
name: prompt("Unesite citat i autora u obliku: citat - autor"),
};
});

Related

How can I display the results of a users' search/query in HTML/UI? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
I want to return the results of the users’ search in HTML. The results will vary depending on what value they type in. How can I get my code to display the data from whatever the value of {NameOfData} is?
Myscript.js
function GetData(e){
const nameOfData = e.target.value;
const url = `http://container:8004/v1/data/${nameOfData}`;
//http request
fetch(url,)
.then(res => res.json())
.then (json => console.log(JSON.stringify(json)))
const input = document.getElementById("input");
input.addEventListener("change", GetData);
Index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<form id="form" role="search">
<input type="search" id="input" name="q" placeholder="Search Entities...">
<button>Search</button>
</form>
<script src="myScript.js">
</script>
</body>
</html>
There are only two options for them to input/search for: site and country.
This is what the returned value will look like if {NameOfData} is site:
[
{
"id": "4833e18248616a04ee29b4dd08dd68abfa049ad720489677533c8507a95e7335",
"url": "http://container:8004/v1/data/site/4833e18248616a04ee29b4dd08dd68abfa049ad720489677533c8507a95e7335",
"type": "site",
"name": "Head-Smashed-In Buffalo Jump",
"legal": [
{
"type": "attribution",
"text": "Data is supplied by Wikipedia",
"link": "https://en.wikipedia.org/"
}
]
},
This is what the returned value will look like if the {NameOfData} is Country:
[
{
"id": "5c02434187bc31589f270ae33efb56cbcc43ac0ffcc80d03b42990a0eb61a168",
"url":http://container:8004/v1/data/country/5c02434187bc31589f270ae33efb56cbcc43ac0ffcc80d03b42990a0eb61a168",
"type": "country",
"name": "Afghanistan",
"legal": [
{
"type": "attribution",
"text": "Data is supplied by Wikipedia",
"link": "https://en.wikipedia.org/"
}
]
},
index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
</head>
<body>
<form id="form" role="search">
<input
type="search"
id="input"
name="q"
placeholder="Search Entities..."
/>
<!-- button>Search</button -->
</form>
<div>
<ul style="list-style: none" id="results"></ul>
</div>
<script src="yourScript.js"></script>
</body>
</html>
yourScript.js
const createAndAppendDOM = (DOMChild, objDOMParameters, parent) => {
// argument -> objDOMParameters must be object with parameters of HTML tag -> example { id: 'myId', textContent: 'example' }
const DOMCreated = document.createElement(DOMChild);
if(Object.keys(objDOMParameters).length === 0 ) {
return {
created: false,
error: "Object is empty"
};
}else {
for(let parameter in objDOMParameters) {
DOMCreated[parameter] = objDOMParameters[parameter];
}
}
parent.appendChild(DOMCreated);
}
function GetData(e) {
e.preventDefault();
const nameOfData = e.target.value;
//const url = `http://container:8004/v1/data/${nameOfData}`;
const url = "https://my-json-server.typicode.com/typicode/demo/posts";
//http request
fetch(URL)
.then(res => res.json())
.then(
json => {
//console.log(json);
json.forEach(element => {
createAndAppendDOM('li', { textContent: ` ${element['title']} ` }, results);
});
})
}
// I don't know what for you have button tag and what for if you have listener - change - to input
// its not make sense
// so what do you want to do when you append listener to button - click - for submit?
// If you want to use listener like - change - so you maybe delete button in you HTML code, because your code will execute when you escape from input tag
const results = document.querySelector("ul");
console.log(results);
const input = document.querySelector("input");
input.addEventListener("change", GetData);

Uncaught ReferenceError: characters is not defined

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

Angular: How to use ng-options to make four separate selections?

JS:
angular
.module('app', [])
function MainCtrl() {
var ctrl = this;
ctrl.selectionList = [
{ id: 1, name: 'apple'},
{ id: 2, name: 'banana'},
{ id: 3, name: 'grapes'},
{ id: 4, name: 'carrot'}
];
ctrl.selectedThing = ctrl.selectionList[0].name;
}
angular
.module('app', [])
.controller('MainCtrl', MainCtrl);
HTML:
<div class="row">
<div class="col-sm-3 col-xs-12 unit">
<select
ng-model="ctrl.selectedThing"
ng-options="selections.name as selections.name for selections in ctrl.selectionList">
</select>
</div>
</div><!--end of first row-->
So this code creates four different selections.
The problem is that when I choose an option, let's say for example "apples" on one selection, all the other selections become apples too. Is there any way to solve this with ng-options or should I just write the select in HTML?
You definitely want to use ng-options, as that isn't the issue here. The problem you are seeing is most likely because the ng-model on all of your select elements is the same ctrl variable. So when you update one of them, it changes a single variable that is bound to all four dropdowns. You either need to setup up an array for your selected items, or four different instances of a selected variable.
ctrl.selectedThings = [ctrl.selectedList[0].name, '', '', ''];
Then in your view you can do this...
<select
ng-model="ctrl.selectedThings[rowIndex]"
ng-options="selections.name as selections.name for selections in ctrl.selectionList">
</select>
Not the most robust solution if you are going past 4 items, but you should be able to adapt it to be dynamic.
Your code is working fine, can you check and confirm?!
(function ()
{
var app = angular.module("app", []);
function HomeController()
{
var vm = this;
vm.selectionList = [
{ id: 1, name: 'apple'},
{ id: 2, name: 'banana'},
{ id: 3, name: 'grapes'},
{ id: 4, name: 'carrot'}
];
}
app.controller("HomeController", [HomeController]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<title>Angular JS App</title>
</head>
<body>
<div class="container" ng-controller="HomeController as homeCtrl">
<div class="row">
<div class="col-sm-3 col-xs-12 unit">
<select
ng-model="homeCtrl.selectedThing"
ng-options="selections.name as selections.name for selections in homeCtrl.selectionList">
</select>
<pre>{{homeCtrl.selectedThing}}</pre>
</div>
</div><!--end of first row-->
</div>
</body>
</html>
If you have ng-model="ctrl.selectedThing" for all of your <select> tags, they will all change to the same selection because they're using the same scope property. Think of it like having 4 variables referencing the same data: if you change one, access any of the variables will retrieve the same result.
You need to bind all of your selects to a different property on scope, so ctrl.selectedThing1,2,...n. That's not very scalable, but that would fix your problem.

obtain different values in star rating

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.

Searchable Angular Tree for large tree possibly with KendoUI's TreeView

I'm building a website using Angular JS as the presentation framework talking to a WebApi backend and need to render and tree control with a large amount of data (slightly under 1 MB). The tree needs to support check boxes and provide events when leafs or branches are selected. It is essential for the users that they can search for nodes in the tree by either the name of the node or a know ID associated with the node.
I've been looking at Telerik's Kendo UI however I have the following problems that I've not been able to resolve:
When the tree has loadOnDemand set to false (which it has to be because of the data size) the find methods of the control do not work
findByText only supports exact matching as far as I can tell (not an essential feature but certainly desirable)
No obvious was to find the node based on the second Id
I'd be happy to offload some of the work to our WebApi backend but can't see how the Telerik control would support this. I'd appreciate help in resolving these issues or a recommendation for a performant alternative to Telerik's tree control
I attempted to create a sample snippet on Telerik's dojo however the registration process is not working for me. I've created a small sample to demonstrate the problem but it appears to be runnable here too.
angular.module("KendoDemos", ["kendo.directives"]);
function MyCtrl($scope) {
$scope.treeData = new kendo.data.HierarchicalDataSource({
data: [{
id: 1,
extenalId: "AA",
text: "Item 1"
}, {
id: 2,
extenalId: "BA",
text: "Item 2",
items: [{
id: 21,
extenalId: "BB",
text: "SubItem 2.1"
}, {
id: 22,
extenalId: "BC",
text: "SubItem 2.2"
}]
}, {
id: 3,
extenalId: "CC",
text: "Item 3"
}]
});
$scope.itemTemplate = "<span title='{{dataItem.extenalId}}'>{{dataItem.text}}</span>";
$scope.findNode = findNode;
$scope.findById = findById;
$scope.findByExternalId = findByExternalId;
function findNode(item) {
var treeView = $("#sTree").data("kendoTreeView");
// TODO: How do we find SubItem 2.1 if the tree has not been expanded
// TODO: How do we do a contains search
var node = treeView.findByText($scope.search);
if (node.length) {
console.log("found");
treeView.expandTo(treeView.dataItem(node));
if (node[0].textContent === $scope.search)
treeView.select(node);
}
}
function findById() {
var treeView = $("#sTree").data("kendoTreeView");
//TODO: How do we find 22 if the tree has not been expanded
var dataItem = treeView.dataSource.get($scope.searchId);
var node = treeView.findByUid(dataItem.uid);
if (node.length) {
console.log("found by id");
treeView.expandTo(treeView.dataItem(node));
treeView.select(node);
} else
console.log("Not found by id");
}
function findByExternalId() {
var treeView = $("#sTree").data("kendoTreeView");
//TODO: How do we find BB
var dataItem = treeView.dataSource.get($scope.searchId2);
var node = treeView.findByUid(dataItem.uid);
if (node.length) {
console.log("found by id");
treeView.expandTo(treeView.dataItem(node));
treeView.select(node);
} else
console.log("Not found by id");
}
window.$scope = $scope;
}
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/treeview/angular">
<style>
html {
font-size: 12px;
font-family: Arial, Helvetica, sans-serif;
}
</style>
<title></title>
<link href="http://cdn.kendostatic.com/2014.2.903/styles/kendo.common.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.2.903/styles/kendo.default.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.2.903/styles/kendo.dataviz.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.2.903/styles/kendo.dataviz.default.min.css" rel="stylesheet" />
<script src="http://cdn.kendostatic.com/2014.2.903/js/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.2.903/js/angular.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.2.903/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example" ng-app="KendoDemos">
<div class="demo-section k-content" ng-controller="MyCtrl">
<div class="box-col">
<h4>Searchable TreeView</h4>
<input data-ng-model="search" placeholder="Locate node" data-ng-change="findNode()" />
<div id="sTree" kendo-tree-view="tree" k-data-source="treeData" k-template="itemTemplate" k-on-change="selectedItem = dataItem"></div>
</div>
<div class="box-col" ng-show="selectedItem">
<h4>Selected: {{selectedItem.text}}</h4>
</div>
<div class="box-col">
<h4><input data-ng-model="searchId" placeholder="ID" /><button ng-click="findById()">Find </h4>
<h4><input data-ng-model="searchId2" placeholder="Extenal ID" /><button ng-click="findByExternalId()">Find </h4>
</div>
</div>
<style scoped>
.k-treeview .k-in {
padding: 5px;
}
</style>
</div>
</body>
</html>

Categories

Resources