I have the following Javascript that I am using to make a sort of flowchart where the user clicks through a set of questions. For certain responses i want to link to an external site where more info can be found. How do I add these links?
HTML
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="row">
<div class="col-xs-12 text-right">
<button class="btn btn-default btn-corner" type="submit" data-bind="click: startOver, visible: queryData().id > 0">Start over</button>
</div>
</div>
</div>
<div class="container main">
<div class="row">
<div class="c12 text-center">
<h1 data-bind="text: queryData().text"></h1>
<h3 data-bind="text: queryData().subhead"></h3>
<div class="option-group" data-bind="foreach: queryData().answers">
<button class="btn btn-default btn-lg" type="submit" data-bind="click: $parent.goToTarget, text: text"></button>
</div>
<button class="btn btn-default" type="submit" data-bind="click: stepBack, visible: navHistory().length > 1">Previous Step</button>
</div>
</div>
</div>
<div class="push"></div>
</div>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
<script src="app.js?v=0.4.0"></script>
<script>
</script>
</body>
</html>
The Javascript is as follows:
JS
var queries = [{
id: 0,
text: "Where to start?",
answers: [{
text: "Let's Begin!",
target: 1
}]
}, {
id: 1,
text: "Which genre do you want to start in?",
answers: [{
text: "Fantasy",
target: 100
}, {
text: "SciFi",
target: 2
}, {
text: "Neither",
target: 59
}]
}, {
id: 2,
text: "It's huge but it's worth it. The Cryptonomicon by Neal Stephenson",
answers: [{
text: "Amazon.co.uk",
target: "_blank"
}, {
text: "Amazon.com"
}]
}];
function QueryViewModel() {
var self = this;
self.querySet = ko.observable();
self.currentStep = ko.observable();
self.queryData = ko.observable();
self.sfw = ko.observable();
self.navHistory = ko.observableArray();
// Operations
self.goToTarget = function(obj) {
self.navHistory.push(self.currentStep());
self.currentStep(obj.target);
self.queryData(self.querySet()[obj.target]);
}
self.startOver = function() {
self.navHistory.removeAll();
self.goToTarget({target: 0});
}
self.stepBack = function() {
var lastStep = self.navHistory().length > 1 ? self.navHistory.pop() : 0;
self.currentStep(lastStep);
self.queryData(self.querySet()[lastStep]);
}
var paramsString = document.location.hash.substring(1);
var params = new Array();
if (paramsString) {
var paramValues = paramsString.split("&");
for (var i = 0; i < paramValues.length; i++) {
var paramValue = paramValues[i].split("=");
params[paramValue[0]] = paramValue[1];
}
}
params ? paramTarget = params['target'] : params = [];
self.sfw() ? self.querySet(queriesSFW) : self.querySet(queries);
if (paramTarget) {
self.navHistory.push(0);
self.currentStep(0);
self.goToTarget({target: paramTarget})
} else {
self.goToTarget({target: 0});
}
}
ko.applyBindings(new QueryViewModel());
In html you can do something like this:
<button type="button" onclick="window.open('https://google.com/', '_self')">Button</button>
You don't have to use a button, different elements can use onclick like text or images. This can also call js functions, just put the function name where "window.open..." is.
Of course the standard way to do it is
<a href='https://www.google.com/'>Link</a>
You can practice using js here: http://www.w3schools.com/js/tryit.asp?filename=tryjs_intro_inner_html
and learn more about it here: http://www.w3schools.com/js/js_intro.asp
I am not sure why you would show us the JSON for open a link to another page. Unless I misunderstood. This kind of basic information can be found by a quick Google search.
Add your link in the object like:
text: "Fantasy",
link: "http://www.stackoverflow.com",
target: 2
Now when you need to go to that link, use this function:
var link = obj.link;
window.open(link, "_blank");
Related
How can I access and show/hide the exact button in second repeat?
<div class="row" ng-repeat="person in people">
<div class="row" ng-repeat="ticket in tickets">
<button type="button" ng-if="!ticket.added" ng-click="add(ticket)">+</button>
<button type="button" ng-if="ticket.added" ng-click="remove(ticket)">-</button>
</div>
</div>
For example I have 3 persons and 4 different tickets. When someone click on button I want to add clicked ticket for that person.
Now when I click on add button, it's adding clicked ticket for all persons :(
Thanks in advance!
I'm not sure (your question is not too clear) but, maybe you can pass the person to your functions too?
Example:
$scope.people = [{
name: 'Jhon Snow',
tickets: [{
name: 'ticket1',
added: false
}, {
name: 'ticket2',
added: false
}]
}, {
name: 'Peter Parker',
tickets: [{
name: 'ticket3',
added: false
}, {
name: 'ticket4',
added: false
}]
}];
$scope.add = function (ticket) {
ticket.added = true;
}
$scope.remove = function (ticket) {
ticket.added = false;
}
And the html:
<div class="row" ng-repeat="person in people">
{{ person.name}}
<div class="row" ng-repeat="ticket in person.tickets">
- {{ ticket.name }}
<button type="button" ng-if="!ticket.added" ng-click="add(ticket)">+</button>
<button type="button" ng-if="ticket.added" ng-click="remove(ticket)">-</button>
</div>
</div>
You can check a working example here
I am trying to grab the buttons html with .html() and insert into $scope.player. The button is calling the choosePlayer() function with ng-click but it is not working.
Here's the codepen link: http://codepen.io/theMugician/pen/ojJrRp
HTML
<body ng-app="ticTacToe" ng-controller="MainCtrl">
<div class="container">
<div class="row">
<div class="col-xs-12 text-center">
<h1>TIC TAC TOE</h1>
</div>
</div>
</div>
<div id="wrapper" class="container text-center">
<div class="row">
<div ng-click="move(cell)" ng-repeat="cell in cells" class="col-xs-4 square text-center">
{{cell.value}}
</div>
</div>
</div>
<div class="container">
<div class="row text-center">
<h1>CHOOSE A SHAPE</h1>
<button ng-click="choosePlayer()" class="btn btn-red" id="choose-cross">✖</button>
<button ng-click="choosePlayer()" class="btn btn-green" id="choose-circle">◯</button>
</div>
</div>
</body>
JAVASCRIPT
var app = angular.module("ticTacToe", []);
app.controller("MainCtrl", function($scope){
var cell = $(".square");
$scope.player = "";
var cross = "×";
var circle = "◯";
$scope.choosePlayer = function(){
$scope.player = $(this).html();
}
$scope.cells = [ { value: '' }, { value: '' }, { value: '' },
{ value: '' }, { value: '' }, { value: '' } ,
{ value: '' }, { value: '' }, { value: '' }
];
$scope.move = function(cell){
cell.value = $scope.player;
};
});
You could pass the $event object in the ng-click() directive:
<button ng-click="choosePlayer($event)" class="btn btn-red" id="choose-cross">✖</button>
<button ng-click="choosePlayer($event)" class="btn btn-green" id="choose-circle">◯</button>
And then access event.currentTarget to get the element in your controller:
Updated Example
Without jQuery:
$scope.choosePlayer = function(e) {
$scope.player = e.currentTarget.innerText;
}
With jQuery:
$scope.choosePlayer = function(e) {
$scope.player = $(e.currentTarget).text();
}
I have written the following HTML & AngularJS code to update the Tree on HTML Page (View) on the Click of a Button.
When the Button is clicked, the changes appear for a fraction of second and disappear. I am not able to find the reason for this. Could you please let me know how I can overcome this problem?
Below is the HTML and JS Code. This is working in the Snippet Editor, but not in the Browser.
var module = angular.module('myapp', []);
module.controller("TreeCtrl", function($scope) {
$scope.categories = [];
$scope.$apply($scope.addTreeToView = function() {
$scope.categories = [{
title: 'Computers1',
categories: [{
title: 'Laptops1',
categories: [{
title: 'Ultrabooks1'
}, {
title: 'Macbooks1'
}]
}, {
title: 'Desktops1'
}, {
title: 'Tablets1',
categories: [{
title: 'Apple1'
}, {
title: 'Android1'
}]
}]
}, {
title: 'Printers1',
categories: [{
title: 'HP1'
}, {
title: 'IBM1'
}]
}];
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Tree Example</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app="myapp">
<div class="col-sm-10 col-sm-offset-1" ng-controller="TreeCtrl">
<form action="#" method="post" class="form-horizontal" id="commentForm" role="form">
<div class="form-group" id="div_submitComment">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-success btn-circle text-uppercase" type="submit" ng-click="addTreeToView()"><span class="glyphicon glyphicon-send" id="qazwsx"></span> Create Tree</button>
</div>
</div>
</form>
<div class="page-header">
<h3 class="reviews">Tree</h3>
</div>
<script type="text/ng-template" id="categoryTree">
{{ category.title }}
<ul ng-if="category.categories">
<li ng-repeat="category in category.categories" ng-include="'categoryTree'">
</li>
</ul>
</script>
<ul>
<li ng-repeat="category in categories" ng-include="'categoryTree'"></li>
</ul>
</div>
</div>
<script src="self.js"></script>
</body>
try removing type="submit" from the buttom
I was using Form element type of Bootstrap. This has an action attribute. I removed the action attribute. Code works fine after removing it
< form method = "post"
class = "form-horizontal"
id = "commentForm"
role = "form" >
< div class = "form-group"
id = "div_submitComment" >
< div class = "col-sm-offset-2 col-sm-10" >
< button class = "btn btn-success btn-circle text-uppercase"
type = "submit"
ng - click = "addTreeToView()" > < span class = "glyphicon glyphicon-send"
id = "qazwsx" > < /span> Create Tree</button >
< /div>
</div >
< /form>
Because your html will be reloaded after you do "submit" action.So you have to replace "type="submit" by type="button" and disable "auto submit".
im learning angularjs thru an Apress book and I've come across some code that doesnt work, ive tried to debug but my console isnt giving me any errors or anything. Maybe some experts can guide me thru whats wrong, thanks.
customFilters.js file
// Creating a custom filter
// arguments for the filter method is unique and a factory function that returns a filter function that does the actaul work
angular.module('customFilters',[]).filter('unique', function() {
return function(data, propertyname) {
if (angular.isArray(data) && angular.isString(propertyname)) {
var results = [];
var keys = {};
for (var i = 0; i < data.length; i++) {
var val = data[i][propertyname];
if (angular.isUndefined(keys[val])) {
keys[val] = true;
results.push(val);
}
}
return results;
} else {
return data;
}
}
});
sportsStore.js file
//declaring a dependency called customFilters that contains a unqiue filter
angular.module('sportsStore',['customFilters']);
// calling the angular.module method passing in sportsStore located in app.html
angular.module('sportsStore').controller('sportsStoreCtrl', function($scope) {
$scope.data = {
products: [
{name: "Product 1", description:"A product", category:"Category #1", price: 100},
{name: "Product 2", description:"A product", category:"Category #1", price: 110},
{name: "Product 3", description:"A product", category:"Category #2", price: 210},
{name: "Product 4", description:"A product", category:"Category #3", price: 202}
]
};
});
my productListControllers.js file
angular.module('sportsStore').controller('productListCtrl', function($scope,$filter){
var selectedCategory = null;
$scope.selectedCategory = function(newCategory) {
selectedCategory = newCategory;
};
$scope.categoryFilterFn = function(product) {
return selectedCategory == null || product.category == selectedCategory;
};
});
app.html file
<!DOCTYPE html>
<!-- We are defining the sportStore module here in the html tag-->
<html ng-app="sportsStore">
<head>
<title>Sports Store</title>
<link href="bootstrap.min.css" rel="stylesheet" />
<link href="bootstrap-theme.min.css" rel="stylesheet" />
</head>
<!-- Applying ng-controller to the body tagg -->
<body ng-controller="sportsStoreCtrl">
<div class="navbar navbar-inverse">
<a class="navbar-brand" href="#">Sports Store</a>
</div>
<div class="panel panel-default row" ng-controller="productListCtrl">
<div class="col-xs-3">
<a class="btn btn-block btn-default btn-lg" ng-click="selectCategory()">Home</a>
<!-- generating the navigation elements here -->
<a class="btn btn-block btn-default btn-lg" ng-repeat="item in data.products |orderBy:'category'| unique:'category'" ng-click="selectCategory(item)">{{item}}</a>
</div>
<div class="col-xs-8">
<!-- ng-repeat generates elements for each object in an array -->
<!-- we also create a local variable called item -->
<div class="well" ng-repeat="item in data.products | filter:categoryFilterFn">
<h3>
<strong>{{item.name}}</strong>
<span class="pull-right label label-primary">{{item.price | currency}}</span>
</h3>
<span class="lead">{{item.description}}</span>
</div>
</div>
</div>
<script src="angular.js"></script>
<script src="controllers/sportsStore.js"></script>
<script src="filters/customFilters.js"></script>
<script src="controllers/productListControllers.js"></script>
</body>
</html>
You have a typo in your html file. The function is selectedCategory not selectCategory.
There is a typo, the template says selectCategory and the controller says selectedCategory
I tried to use Bootstrap radio button data toggle for tabs, my render of DOM for this happens through Knockout. the tab does not seem to switch between active and inactive tab correctly.
Here is a working example: http://jsfiddle.net/msurguy/x8GvJ/
Here is how to recreate the problem (JSFiddle):
<div id="tabtest" data-bind="foreach: arrayItems">
<div data-bind="attr:{'id':'itemtab' + $index()}" class="btn-group " data-toggle="buttons-radio">
<a data-bind="attr:{href:'#entitysearchitem' + $index()}" class="btn " style="background-color: #f5f5f5" data-toggle="tab">Item</a>
<a data-bind="attr:{href:'#entitymemberssearch' + $index(),'data-index':$index}" style="background-color: #f5f5f5" class="btn " data-toggle="tab">Member</a>
</div>
<div class="tab-content">
<div class="tab-pane fade in " data-bind="attr:{id:'entitysearchitem' + $index()}">
<div class="row padding3centt">
<div class="col-xs-12">
<div class="row">
<div class="col-xs-1"></div>
<div class="col-xs-11">
<ul data-bind="foreach:interests" class="list-styled">
<li>
<span class="fontsize80" data-bind="text:Description">
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" data-bind="attr:{id:'entitymemberssearch' + $index()}">
Hello i am entitymemberssearch
</div>
</div>
<br/>
</div>
JS:
var myObject = [{
"first": "John",
"interests": [ {"Description": "Reading"}, {"Description":"Mountain Biking"}, {"Description":"Hacking"} ]
},
{
"first": "Boy",
"interests": [ {"Description":"Reading"}, {"Description":"Mountain Biking"}, {"Description":"Hacking"} ]
}]
var koData ={
arrayItems :ko.observableArray()
}
ko.mapping.fromJS(myObject, {}, koData.arrayItems);
ko.applyBindings(koData, $("#tabtest").get(0));
I have described the problem in the picture below as well. Any ideas on how to correctly get the bootstrap radio tabs to work?
You need to reconsider the approach you are trying to use : Here's a beautiful solution by Ryan Niemeyer which you can refer to..
http://jsfiddle.net/rniemeyer/cGMTV/
You need to rewrite your code in following format.
var Section = function (name, selected) {
this.name = name;
this.isSelected = ko.computed(function() {
return this === selected();
}, this);
}
var ViewModel = function () {
var self = this;
self.selectedSection = ko.observable();
self.sections = ko.observableArray([
new Section('Section 1', self.selectedSection),
new Section('Section 2', self.selectedSection),
new Section('Section 3', self.selectedSection)
]);
//inialize to the first section
self.selectedSection(self.sections()[0]);
}
ko.applyBindings(new ViewModel());