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.
Related
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"),
};
});
Where I am appending my dynamic checkbox items within a loop, I tried adding the additional suffix as seen below:
checkBoxTree.append({ text: plc + " (" + id + ")"}).attr("data-id", id).className = "id-item class";
I get no errors, but the attribute and two classes are not added anywhere. How Is this done?
the attempted above adding this at the end of where I'm writing the new checkbox elems'.attr("data-id", id).className = "id-item class";'
You should not play with Kendo's DOM, it's constantly redrawn. I suggest using template and wrapping the item content's inside a div. Then add any class or data attribute you would need over that div, instead of the item's li. Example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.2.617/styles/kendo.default-v2.min.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.2.617/js/kendo.all.min.js"></script>
</head>
<body>
<div id="treeview"></div>
<script>
let tv = $("#treeview").kendoTreeView({
template: "<div data-id='#= item.id #' class='id-item class'>#= item.text # (#= item.inStock #)</div>",
dataSource: [
{ text: "foo", inStock: 7, items: [
{ text: "bar", inStock: 2 },
{ text: "baz", inStock: 5 }
] }
]
}).data('kendoTreeView');
tv.append({ text: 'abc', id: 10, inStock: 1000 });
</script>
</body>
</html>
Dojo
If you inspect above tree's abc node, you will see...
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
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.
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