I'm trying to find out if one or both of the 2 colour checkboxes is selected, and depending on which one/pair is selected, objects of that colour will be outputted on the form. So if a user checked the "purple" check box then there will be a bunch of purple objects outputted to the form. If "purple" and "yellow" are both checked both purple and yellow objects will be outputted onto the screen. I've been trying to check if the checkbox is "true" to see if it selected but there is something wrong with my logic. http://codepen.io/MarkBond/pen/pJmrxV?editors=101 Thanks in advance
HTML
<html ng-app="formApp">
<head>
<!-- CSS -->
<!-- load up bootstrap and add some spacing -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style>
body { padding-top:50px; }
form { margin-bottom:50px; }
</style>
<!-- JS -->
<!-- load up angular and our custom script -->
<script src="http://code.angularjs.org/1.3.14/angular.js"></script>
<script src="app.js"></script>
</head>
<!-- apply our angular app and controller -->
<body ng-controller="FormController as formCtrl">
<div class="col-xs-12 col-sm-10 col-sm-offset-1">
<h2>Angular Checkboxes</h2>
<form>
<div class="checkbox">
<label>
<input type="checkbox" name="displayOption" ng-model="formData.displayOption.purple" ng-click="yourFunction()" />purple
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="displayOption" ng-model="formData.displayOption.yellow" ng-click="yourFunction()" />yellow
</label>
</div>
</form>
<h2>Array/Message Output Area</h2>
<pre>
<div ng-repeat="object in formCtrl.objects">
{{ object.name }}
</div>
{{ message }}
</pre>
<!-- SHOW OFF OUR FORMDATA OBJECT -->
<h2>Boolean Test Area</h2>
<pre>
{{ formData }}
</pre>
</div>
</body>
</html>
AngularJS
angular.module('formApp', [])
.controller('FormController', ['$scope' ,function($scope) {
$scope.formData = {};
$scope.yourFuction = function(){
var purple = $scope.purple;
var yellow = $scope.yellow;
if (purple === true && yellow === true) {
this.objects = groupOne
} else if (purple === true) {
this.objects = groupTwo
} else if (yellow === true) {
this.objects = groupOne + groupTwo
}else{
this.message = 'Nothing Selected'
}
};
var groupOne = [
{ name: 'Grape'},
{ name: 'Wine'},
{ name: 'Toy Octipus'}
]
var groupTwo = [
{ name: 'Banana'},
{ name: 'Lemon'},
{ name: 'Yellow Highlighter'}
]
}]);
$scope.yourFuction should be $scope.yourFunction and for your if statements you should be checking for $scope.formData.displayOption.purple instead of $scope.purple
var purple = $scope.formData.displayOption.purple;
var yellow = $scope.formData.displayOption.yellow;
http://codepen.io/anon/pen/LVozZG?editors=101
https://docs.angularjs.org/api/ng/input/input%5Bcheckbox%5D
Related
How can I toggle designs using inputs?
<section id="assignment">
<!-- 1) Fetch the user input and use it as a CSS class -->
<!-- The entered class should be added to the below paragraph -->
<input type="text" v-on:input="setUser" />
<!-- (available classes: "user1", "user2") -->
<p :class="{user}">
Style me!
</p>
<button>Toggle Paragraph</button>
<!-- 2) Use the "visible" and "hidden" classes to show/ hide the above paragraph -->
<!-- Clicking the button should toggle between the two options -->
<!-- 3) Add dynamic inline styling to the below paragraph and let the user enter a background-color -->
<input type="text" />
<p>Style me inline!</p>
</section>
I have already made user1 and user2 classes in css file, but when i try to output user as a class it is showing just user doesnot matter what i write in input field.
Please take a look at following demo:
const app = Vue.createApp({
data() {
return {
user: null,
bgcolor: null,
toggle: false,
users: []
};
},
computed: {
classes() {
return this.users.map(u => 'user' + u.id)
}
},
mounted() {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(json => this.users = json)
}
})
app.mount('#demo')
.user1 {
color: red;
}
.user2 {
color: green;
}
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="demo">
<section id="assignment">
<select v-model="user">
<option v-for="(cls, i) in classes" :key="i">
{{ cls }}
</option>
</select>
<input type="text" v-model="user" />
<p :class="user">
Style me!
</p>
<button #click="toggle = !toggle">Toggle Paragraph</button>
<input v-model="bgcolor" type="color" />
<p v-if="toggle" :style="`background-color: ${bgcolor};`">Style me inline!</p>
</section>
</div>
I'm new to AngularJS, currently I am trying to create a spa for tracking expenses as a simple project but I have some problems with my code.
I managed to do the most of the function but I got stuck at the update function, I want to be able to update the data without creating another button, instead using the same submit button which is used to add new data
Here is the html and js code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Expenses Tracker</title>
<link rel="stylesheet" href="bootstrap.min.css">
<link href="style.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<span class="navbar-brand"><img src="logo.png" class="brand" height="40" />
Simple Expenses App Tracker</span>
</div>
</div>
</nav>
<div class="main" ng-app="myList" ng-controller="myListController">
<img src="logo.png" class="logo">
<form ng-submit="newItem()" class="form">
<input required type="number" placeholder="Amount" ng-model="amount">
<input required type="text" placeholder="Description" ng-model="description">
<input type="submit" value="Submit" class="btn btn-success">
</form>
<ul>
<li ng-repeat="item in items">
<span class="pull-left"> {{item.amount}} den.</span> {{item.description}}
<span class="buttons">
<input type="button" ng-click="editItem($index)" value="Edit" class="btn btn-primary" >
<input type="button" ng-click="deleteItem($index)" value="Delete" class="btn btn-danger">
</span>
</li>
<br>
<li><span class="total">{{totalPrice()}} den.</span> <span class="expense"> Total Expenses</span></li>
</ul>
</div>
<script src="bootstrap.min.js"></script>
<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script src="app.js"></script>
</body>
</html>
var myApp = angular.module("myList", []);
myApp.controller("myListController", function($scope) {
$scope.items = [];
$scope.newItem = function() {
$scope.items.push({description:$scope.description, amount: $scope.amount});
$scope.description = '';
$scope.amount = 0
};
$scope.deleteItem = function(index) {
$scope.items.splice(index, 1);
}
$scope.totalPrice = function() {
var total = 0;
for(count=0; count<$scope.items.length;count++){
total += $scope.items[count].amount;
}
return total;
};
$scope.editItem = function(index) {
$scope.amount = $scope.items[index].amount;
$scope.description = $scope.items[index].description;
};
});
You could have two scope variables to keep track if in edit mode and to keep track of the index that is being edited, and in the newItem() can have an if else statement based on edit mode or not
For example you could do something like
var myApp = angular.module("myList", []);
myApp.controller("myListController", function($scope) {
$scope.items = [];
$scope.isEdit = false; // initialize
$scope.editingIndex = null; //initialize
$scope.newItem = function() {
if(!$scope.isEdit){ //if not in edit mode -> add new
$scope.items.push({description:$scope.description, amount: $scope.amount});
}
else{ //in edit mode -> edit the object
$scope.items[$scope.editingIndex] = { //replace with new values
description:$scope.description, amount: $scope.amount
}
$scope.isEdit = false; //setting back to false
$scope.editingIndex = null;
}
$scope.description = '';
$scope.amount = 0
};
$scope.deleteItem = function(index) {
$scope.items.splice(index, 1);
}
$scope.totalPrice = function() {
var total = 0;
for(count=0; count<$scope.items.length;count++){
total += $scope.items[count].amount;
}
return total;
};
$scope.editItem = function(index) {
$scope.isEdit = true; //setting edit mode true
$scope.editingIndex = index; //setting the index to edit
$scope.amount = $scope.items[index].amount;
$scope.description = $scope.items[index].description;
};
});
demo
I want to split two different section based on page URL. I'm not aware how to do it using knockout.
The below example I have tried so far.
<!-- ko if: attr: { href: https://stackoverflow.com } -->
<p>Div 1</p>
<!-- /ko -->
<!-- ko if: attr: { href: https://getbootstrap.com } -->
<p>Div 2</p>
<!-- /ko -->
Any clarification please drop a comment. Thanks in Advance.
You can use the template system to perform this kind of switch :
ko.applyBindings({
stackoverflowData : {
totalQuestions : 321
},
bootstrapData : {
version : '5.0.2'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.js"></script>
<div data-bind="template: { name: 'stackoverflow-template', data: stackoverflowData }"></div>
<hr />
<div data-bind="template: { name: 'bootstrapData-template', data: bootstrapData }"></div>
<script type="text/html" id="stackoverflow-template">
stackoverflow specific view <br />
Questions: <span data-bind="text: totalQuestions"></span>
</script>
<script type="text/html" id="bootstrapData-template">
bootstrapData specific view <br />
Version <span data-bind="text: version"></span>
</script>
If you want something dynamic you can create a function that returns the template to use based on the viewmodel.
function getTemplate(url) {
// use reg ex
if (url == 'https://stackoverflow.com')
return 'stackoverflow';
if (url == 'https://getbootstrap.com')
return 'bootstrap';
return null;
}
var websites = [{
url: 'https://stackoverflow.com',
specificData: {
totalQuestions: 321
}
},
{
url: 'https://getbootstrap.com',
specificData: {
version: '5.0.2'
}
}
];
websites.map(function(website) {
website.template = ko.computed(function() {
return getTemplate(this.url);
}, website);
return website;
})
ko.applyBindings({
websites: websites
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.js"></script>
<div data-bind="foreach: websites">
<div data-bind="template: { name: (template()+'-template'), data: specificData }">
<hr />
</div>
</div>
<script type="text/html" id="stackoverflow-template">
stackoverflow specific view <br /> Questions: <span data-bind="text: totalQuestions"></span>
</script>
<script type="text/html" id="bootstrap-template">
bootstrapData specific view <br /> Version <span data-bind="text: version"></span>
</script>
To make this work, you'll need to bring the url into your viewmodel. You could do this with a simple custom url bindinghandler. When initialized, it stores the current url in the bound observable (in this case myUrl) and adds an event listener for storing a changed url (in this case I use hash change to be able to make the example work).
Now, in HTML you can show or hide divs based on this observable value. Have a look at the example below.
ko.bindingHandlers.url = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
valueAccessor()(location.href);
window.addEventListener('hashchange', function(ev) {
valueAccessor()(ev.newURL);
});
}
};
ko.applyBindings({
myUrl: ko.observable(),
showDiv1: function() {
window.location.hash = 'div1'
},
showDiv2: function() {
window.location.hash = 'div2'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<p>
Current url: <em data-bind="text: myUrl"></em>
</p>
<button data-bind="click: showDiv1">Show Div 1</button>
<button data-bind="click: showDiv2">Show Div 2</button>
<div data-bind="url: myUrl">
<!-- ko if: myUrl() == "https://stacksnippets.net/js#div1" -->
<p>Div 1</p>
<p data-bind="text: myUrl"></p>
<!-- /ko -->
<!-- ko if: myUrl() == "https://stacksnippets.net/js#div2" -->
<p>Div 2</p>
<p data-bind="text: myUrl"></p>
<!-- /ko -->
</div>
I want a DIV behaving like radio button and fetching its value in angularJS. My div looks like :
<div ng-repeat="address in multipleaddress" class="tileHover widget Text span4">
<div class="radios" for="optionsRadios1{{address.id}}" id="{{address.id}}" ng-model="radiosship.shiphere">
<h3 class="widget-title widget-title" id="shipaddr{{address.id}}">Address #{{$index + 1}}</h3>
<span style="font-size:16px">{{address.firstname}} {{address.lastname}}</span>
<p>{{address.shipping_address}}<br/>{{address.shipping_city}},
<span ngif="{{address.country}} == 'CA'">{{address.shipping_province}}</span>
<span ngif="{{address.country}} == 'US'">{{address.shipping_state}}</span>
<span ngif="{{address.shipping_country}} != 'US' && {{address.shipping_country}} != 'CA'">{{address.otherregion}}</span> - {{address.pincode}},<br/> {{address.country}}</p>
<input type="radio" name="shiphere" id="optionsRadios1{{address.id}}" ng-model="radiosship.shiphere" value="{{address.id}}"/>
</div>
when I click on radios div, the radio button in that div should get selected and I want its value in $scope.radiosship.shiphere in angular.
Any help?
I think the main issue here is that a DIV element can not use ng-model directive --assuming that you do not use a custom directive for that--.
so replace <div class="radios" for="optionsRadios1{{address.id}}" id="{{address.id}}" ng-model="radiosship.shiphere">
with
<div class="radios" for="optionsRadios1{{address.id}}" id="{{address.id}}" ng-click="radiosship.shiphere = address.id; doSomething(address)">
also to bind the model value to the controller $scope rather than the components', you can initialize the radiosship variable in controller like so:
$scope.radiosship = {};
here is a working example
angular.module('App', [])
.controller('MainCtrl', function ($scope) {
$scope.radiosship = {};
$scope.multipleaddress = [
{id: 1, firstname: 'John'},
{id: 2, firstname: 'John'},
{id: 3, firstname: 'John'},
];
});
<!DOCTYPE html>
<html ng-app="App">
<head>
<title>Radio</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<pre>{{radiosship | json}}</pre>
<div ng-repeat="address in multipleaddress" class="tileHover widget Text span4">
<div class="radios" for="optionsRadios1{{address.id}}" id="{{address.id}}" ng-click="radiosship.shiphere = address.id; fetchData(address)">
<h3 class="widget-title widget-title" id="shipaddr{{address.id}}">Address #{{$index + 1}}</h3>
<span style="font-size:16px">{{address.firstname}} {{address.lastname}}</span>
<p>{{address.shipping_address}}<br/>{{address.shipping_city}},
<span ng-if="address.country == 'CA'">{{address.shipping_province}}</span>
<span ng-if="address.country == 'US'">{{address.shipping_state}}</span>
<span ng-if="address.shipping_country != 'US' && address.shipping_country != 'CA'">{{address.otherregion}}</span> - {{address.pincode}},<br/> {{address.country}}</p>
<input type="radio" name="shiphere" id="optionsRadios1{{address.id}}" ng-model="radiosship.shiphere" value="{{address.id}}"/>
</div>
</body>
</html>
I'm just getting started with Angular and running up against some roadblocks in my understanding of certain core concepts. To better familiarize myself with this new framework I'm attempting to build a trivial application: "Would You Rather?". I present the user two questions, they pick one, I highlight their choice, and show how many votes each question has from previous users.
It sounds simple but I'm still stuck in a jQuery frame of mind; I want to select the element based on $(this) or $("#id").
I have a factory with an array of question objects. Each object has a firstQuestion and secondQuestion key that maps to a question, as well as a firstVotes and secondVotes key with the corresponding number of votes. I'm using a QuestionsCtrl to control scope and take action when a user makes a choice.
Here's my index.html file:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Would You Rather?</title>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container" ng-app="wouldYouRatherApp">
<div ng-controller="QuestionsCtrl">
<div class="container">
<div class="row text-center">
<h1 class="col-md-12">Would you rather...</h1>
</div>
<div class="row text-center">
<div class="col-md-12">
<h2 class="btn btn-lg btn-{{buttonClass}}" ng-click="recordAnswer('first')">{{question.firstQuestion}}</h2>
<span class="badge" ng-show="badge.show">{{question.firstVotes}}</span>
</div>
</div>
<div class="row text-center">
<h3 class="col-md-12"><small>or</small></h3>
</div>
<div class="row text-center">
<div class="col-md-12">
<h2 class="btn btn-lg btn-{{buttonClass}}" ng-click="recordAnswer('second')">{{question.secondQuestion}}</h2>
<span class="badge" ng-show="badge.show">{{question.secondVotes}}</span>
</div>
</div>
<br>
<div class="row text-center">
<div class="col-md-12">
<h2 class="btn btn-lg btn-primary" ng-show="showNextQuestion" ng-click="nextQuestion()">Next Question <span class="glyphicon glyphicon-forward"></span></h2>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<script type="text/javascript" src="./main.js"></script>
</body>
</html>
And here's my main.js file:
var app = angular.module("wouldYouRatherApp", []);
app.factory("Badges", function() {
return {show: false}
})
app.factory("Questions", function() {
var Questions = [{
firstQuestion: "Ride a horse?",
firstVotes: 101,
secondQuestion: "Ride a cowboy?",
secondVotes: 212
},
{
firstQuestion: "Kiss a frog?",
firstVotes: 13,
secondQuestion: "Lick a slug?",
secondVotes: 23
},
{
firstQuestion: "Play Monopoly?",
firstVotes: 12,
secondQuestion: "Play Risk?",
secondVotes: 17
}];
return Questions;
})
app.controller("QuestionsCtrl", function($scope, Badges, Questions) {
$scope.question = Questions.shift();
$scope.buttonClass = 'default';
$scope.showNextQuestion = false;
$scope.badge = Badges;
$scope.recordAnswer = function(choice) {
console.log("User chose: " + choice);
$scope.buttonClass = 'success';
// increment votes badge
$scope[choice+'Votes'] += 1;
Badges.show = true;
$scope.showNextQuestion = true;
}
$scope.nextQuestion = function() {
$scope.question = Questions.shift();
Badges.show = false;
$scope.buttonClass = 'default';
$scope.showNextQuestion = false;
}
})
A live example can be found here: http://jsfiddle.net/t99TL/2/
The app's expected behavior is as follows:
Two questions are presented to the user.
The user clicks on one of the buttons.
That question is highlighted. And the votes badge is incremented. Both votes badges are displayed.
A 'Next Question' button is presented to the user.
When he/she clicks on the 'Next Question' button, a new question is loaded.
I feel like I probably need to create a directive for each individual question... but I'm not sure how to start, or if I'm even on the right path. Any advice on obstacles I'm going to face further down the line is much appreciated (i.e. Updating the votes attribute for the question, etc.).
There are a lot to change to make it work the way you want. This code is not perfect, just a demonstration.
HTML:
<div class="container" ng-app="wouldYouRatherApp">
<div ng-controller="QuestionsCtrl">
<div class="container">
<div class="row text-center">
<h1 class="col-md-12">Would you rather...</h1>
</div>
<div class="row text-center">
<div class="col-md-12">
<h2 class="btn btn-lg btn-{{question.firstQuestion.buttonClass}}" ng-click="recordAnswer(question.firstQuestion)">{{question.firstQuestion.text}}</h2>
<span class="badge" ng-show="badge.show">{{question.firstQuestion.votes}}</span>
</div>
</div>
<div class="row text-center">
<h3 class="col-md-12"><small>or</small></h3>
</div>
<div class="row text-center">
<div class="col-md-12">
<h2 class="btn btn-lg btn-{{question.secondQuestion.buttonClass}}" ng-click="recordAnswer(question.secondQuestion)">{{question.secondQuestion.text}}</h2>
<span class="badge" ng-show="badge.show">{{question.secondQuestion.votes}}</span>
</div>
</div>
<br>
<div class="row text-center">
<div class="col-md-12">
<h2 class="btn btn-lg btn-primary" ng-show="showNextQuestion" ng-click="nextQuestion()">Next Question <span class="glyphicon glyphicon-forward"></span></h2>
</div>
</div>
</div>
</div>
JS:
var app = angular.module("wouldYouRatherApp", []);
app.factory("Badges", function() {
return {show: false}
})
app.factory("Questions", function() {
var Questions = [{
firstQuestion: {
text:"Ride a horse?",
votes: 101,
buttonClass : 'default'
},
secondQuestion: {
text:"Ride a cowboy?",
votes: 212,
buttonClass : 'default'
},
},
{
firstQuestion: {
text:"Kiss a frog?",
votes: 13,
buttonClass : 'default'
},
secondQuestion: {
text:"Lick a slug?",
votes: 23,
buttonClass : 'default'
}
},
{
firstQuestion: {
text:"Play Monopoly?",
votes: 12,
buttonClass : 'default'
},
secondQuestion: {
text:"Play Risk?",
votes: 17,
buttonClass : 'default'
}
}];
return Questions;
})
app.controller("QuestionsCtrl", function($scope, Badges, Questions) {
$scope.question = Questions.shift();
$scope.buttonClass = 'default';
$scope.showNextQuestion = false;
$scope.badge = Badges;
$scope.recordAnswer = function(choice) {
choice.buttonClass = 'success';
choice.votes++;
Badges.show = true;
$scope.showNextQuestion = true;
}
$scope.nextQuestion = function() {
$scope.question.firstQuestion.buttonClass = "default";
$scope.question.secondQuestion.buttonClass = "default";
$scope.question = Questions.shift();
Badges.show = false;
$scope.showNextQuestion = false;
}
})
DEMO