I am working on an application and before getting too deep I wanted to do a test. I have a button created using Bootstrap. I have the Bootstrap angular directives installed. I wanted to change the text of the button based upon the selection the user makes on that button. Here is my code:
the Index.html file:
<!doctype html>
<html ng-app="SchedgMeApp">
<head>
<!--<script src="js/angular.min.js"></script>-->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script src="js/ui-bootstrap-custom-tpls-0.12.0.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="js/app.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="DropdownCtrl">
<!-- Single button -->
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle ng-disabled="disabled">
<span class="selection">{{ selectedAction.name }}</selection> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="action in actions">
<a ng-click="setAction(action)">{{ action.name }}</a>
</li>
</ul>
</div>
</div>
</body>
</html>
The app.js file:
var app = angular.module('SchedgMeApp',['ui.bootstrap']);
angular.module('SchedgMeApp').controller('DropdownCtrl', function($scope, $log){
$scope.status = {
isopen: false
};
$scope.toggled = function(open) {
$log.log('Dropdown is now: ', open);
};
$scope.toggleDropdown = function($event) {
$event.preventDefault();
$event.stopProagation();
$scope.status.isopen = !$scope.status.isopen;
};
$scope.actions = [
{id: 'calbert', name: 'Chris Albert'},
{id: 'mmahony', name: 'Mike Mahony'},
{id: 'ctfletcher', name: 'CT Fletcher'},
{id: 'rjohnson', name: 'Rob Johnson'}
];
$scope.setAction = function(action) {
$scope.selectedAction = action;
};
});
This works, but the code to change the text on the button is in the controller and I would prefer it in a directive because I would like to be able to populate the data for every dropdown button in my site this way and have every dropdown button in my site respond in the same manner. So here are my questions:
How do I do this through an angular directive?
How can I set a default value on initial load? <-- solved...see comment
How can I make this so that I have data for all the buttons in my JS, but can pick which data to use on a particular button? I assume a model? <--solved...see comment
Related
I'm new to AngularJS and trying to make a web app.
I was studying for directives from CodeAcademy and for my application decided to make a directive navbar, so every time I need it, I can call it.
But the problem is, it doesn't show in the index.html. I'm using grid in my index.html
Also I would like to know, if there is a better way in navbarCtrl.js to make it like
rest: {'About','Contact','Resources'} instead of writing them one by one.
Many thanks
navInfo.html
<link rel="stylesheet" type="text/css" href="/css/navbar.css" />
<header>
<div class="nav-placeholder">
<img src="/img/letter-y.png" ng-src="{{info.icon}}" />
<i class="menu-toggle-btn"></i>
<nav class="navigation-menu">
<a class="title" href="#">{{info.title}}</a>
<a class="rest" href="#">{{info.rest}}</a>
<a class="rest" href="#">{{info.rest}}</a>
<a class="rest" href="#">{{info.rest}}</a>
</nav>
</div>
</header>
navbarCtrl.js
var app = angular.module('nav', []);
app.controller('navbarCtrl', ['$scope', function($scope) {
$scope.navs = [
{
icon: '/img/letter-y.png',
title: 'Yedy',
rest: 'About',
rest: 'Contact',
rest: 'Resources'
}
];
}]);
navbarDirective.js
app.directive('navInfo', function(){
return{
restrict: 'E',
scope:{
info:'='
},
templateUrl: 'src/js/directives/navInfo.html'
};
})
index.html
<body ng-app="AppYedy">
<!-- Navbar -->
<div class="header" ng-controller="navbarCtrl">
<div ng-repeat="nav in navs">
<nav-info info="nav"></nav-info>
</div>
</div>
The below code loads a json file into my app in order to to populate some table data. It gets the job done.
function init_main () {
$('html').hide().fadeIn('slow');
// popuate from index.json
var json = $.getJSON(chrome.extension.getURL('js/index.json'), function(json) {
// CREATE SETTINGS TABLE WITH GIVEN INDEX
for (var property in json) {
var table = $('<table></table>').addClass('table');
var header = $('<thead></thead>').addClass('thead-inverse');
var head_r = $('<tr></tr>');
var h1 = $('<th></th>').text(property);
var h2 = $('<th></th>').text('check to remove: ');
head_r.append(h1);
head_r.append(h2);
header.append(head_r);
table.append(header);
var body = $('<tbody></tbody>');
table.append(body);
for (var tag in json[property]) {
var body_r = $('<tr></tr>');
var d1 = $('<td></td>').text(tag);
var d2 = $('<td></td>') // maybe change to class?
$('<input />', { type: 'checkbox', id: tag}).appendTo(d2);
body_r.append(d1);
body_r.append(d2);
body.append(body_r);
}
$('#tableWrap').append(table);
}
});
}
//bind events to dom elements
document.addEventListener('DOMContentLoaded', init_main);
However, unlike the rest of my html markup, only these elements will not use the bootstrap library to alter my CSS. All other html markup successfully uses the bootstrap library.
I have tried moving the code outside of the callback with no luck. No errors in console.
Does anyone have any idea why bootstrap wont come into effect during the above code snippet? I think it has something to do with page load but so far I have not seen any success with window.onPageLoad()
Here are my script imports in my html for reference:
<html>
<head>
<!-- load stylesheets: Bootstrap v2.3.0 - http://twitter.github.com/bootstrap/index.html -->
<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css"></link>
<!-- load javascript: jQuery 1.9.1 - http://jquery.com/ -->
<script type="text/javascript" src="../js/jquery-1.9.1.min.js"></script>
<!-- load javascript: Bootstrap v2.3.0 - http://twitter.github.com/bootstrap/ -->
<script type="text/javascript" src="../js/bootstrap.min.js"></script>
<!-- load stylesheets: internal -->
<link rel="stylesheet" type="text/css" href="../css/global.css"></link>
<link rel="stylesheet" type="text/css" href="../css/main.css"></link>
</head>
<body>
<div class="navbar">
<div class="navbar-inner">
<a id="home" id="active" class="brand" href="#">
<!-- UNCOMMENT THE CSS VALUES TO TEST OTHER DIMENTIONS -->
<img src="../images/icon.png" alt="">
<span class="icon-bar"></span>
Fluff 1.0
</a>
<a id="settings" class ="brand" href="#" >
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
Settings</a>
<a id="run" class ="brand" href="#" >
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
Run</a>
</div>
</div>
<div id="outer">
<!-- Main Page -->
<div id="main-inner">
<div id="main-title"> Fluff 1.0 </div>
<div id="textblock">Donate or contact block here</div>
</div>
<!-- Settings Page -->
<div id="settings-inner">
<h5 id="directions"> <span></span> Select Tags to Remove from Automated Browser Queries </h5>
<div id="tableWrap">
</div>
</div>
<!-- Run Page -->
<div id="run-inner">
<table class='table'>
<thead>
<tr>
<td> 1 </td>
<td> 2</td>
</tr>
</thead>
</table>
</div>
</div>
<!-- load javascript: unique html page javascript file -->
<script type="text/javascript" src="../js/main.js"></script>
</body>
edit: sample.json - 'num' key is not relevant in any of the question or code
{
"sex": {
"M":{
"num":13,
},
"F": {
"num":13,
},
"T": {
"num":0
}
},
"politics": {
"L": {
"num":10,
},
"R": {
"num":10,
}
},
"race": {
"AMI":{
"num":6,
},
"ASI":{
"num":7,
},
"AFA":{
"num":7,
},
"PCI":{
"num":0
},
"WHT":{
"num":2,
"3":"-"
},
"HSP":{
"num":5,
"6":"-"
},
"MDE":{
"num":6,
}
},
"orientation": {
"STR": {
"num":0
},
"GAY": {
"num":0
},
"OTH": {
"num":0
}
},
"interests": {
"GARD":{
"num":4,
},
"NHL":{
"num":1,
},
"NBA":{
"num":1,
},
"TECH":{
"num":0
}
}
}
I don't understand your problem exactly, but I put your sample in jsfiddle by removing some unuseful html file to make it simple to read and this works. Only code which is wrong is var json = $.getJSON. Why you do it? however you have not any returned value at all and if it was it never works in async functions like get.
The second problem is that you never call your function!!
See this code and share your idea with me:
jsfiddle
Solved by changing div id='tableWrap' to table id='tableWrap' in html
Tables inside of tables ...
I am writing something in Vue.js and it requires iterating over a list of tags. When clicked, each of those tags should show the 5 most recent stories with said tag.
I am using vue resources rather than ajax and that is all working fine.
So far I have one component which generates the list of tags and a child component to generate a list of stories. The child should take the tag id from the clicked tag and make a get request. I am struggling to make vue pass the tag id from parent to child.
I am using v-bind so it looks like this (p.s. ignore the #, using Laravel's blade and that is to tell blade not to act on the moustache tags)
<child v-bind:tag="#{{tags.id}}"></child>
Though tags.id works perfectly well elsewhere, it does not appear to here.
If I try to pass through a string literal it is quite happy, ie:
<child tag="1"></child>
but I am having no luck with vue's dynamic syntax :tag
Here is my full code:
<!DOCTYPE html>
<html>
<head>
<title>Laravel</title>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<style type="text/css">
.toggled { display: none; }
</style>
</head>
<body>
<div class="container">
<h1>My tags</h1>
<tags></tags>
</div>
<template id="tags-template">
<ul class="list-group"
>
<li class="list-group-item"
v-for="tags in list"
#click=" tags.open =! tags.open"
>
<span>#{{ tags.name }}</span>
<div v-bind:class="{'toggled': tags.open}">
See all recent stories #{{tags.id}}
<child v-bind:tag="#{{tags.id}}"></child>
</div>
</li>
</ul>
</template>
<template id="stories-template">
<p>Stories dropdown goes here #{{ tag }}</p>
</template>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.7.0/vue-resource.js"></script>
<script>
Vue.component('tags', {
//
template: '#tags-template',
data: function() {
return {
list: [],
url: '/tags/',
};
},
created: function() {
this.fetchTagsList();
},
methods: {
fetchTagsList: function() {
var resource = this.$resource('/api/tags/{id}');
resource.get( {}, function(tags)
{
this.list = tags;
}.bind(this));
},
// toggle: function() {
// var resource = this.$resource('/api/storyFromTag/{id}');
// resource.get( {id: 1}, function(stories)
// {
// this.list = stories;
// }.bind(this));
// alert(stories);
// }
}
}),
Vue.component('child', {
props: ['tag'],
template: '#stories-template'
})
new Vue ({
el: 'body'
})
</script>
</body>
</html>
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".
I am using BackgridJs which uses Backbonejs to fill up a grid with data.
This is how my code looks like now:
<!DOCTYPE html>
<html>
<head>
<title>Terminal</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="../js/backgrid/lib/backgrid.css" />
<script src="../js/backgrid/assets/js/jquery.js"></script>
<script src="../js/backgrid/assets/js/underscore.js"></script>
<script src="../js/backgrid/assets/js/backbone.js"></script>
<script src="../js/backgrid/lib/backgrid.js"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>Hello, world!</h1>
<div class="btn-group">
<a class="btn btn-ledger dropdown-toggle" data-toggle="dropdown" href="#">
Ledger
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">With Margin</a></li>
<li><a tabindex="-1" href="#">Without Margin</a></li>
</ul>
</div>
<div class="btn-group">
<a class="btn btn-company-code dropdown-toggle" id = "company_code" data-toggle="dropdown" href="#">
Company Code
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">DHA</a></li>
<li><a tabindex="-1" href="#">HAC</a></li>
<li><a tabindex="-1" href="#">DHA</a></li>
</ul>
</div>
<div class="btn-group">
<a class="btn btn-cost-centre dropdown-toggle" data-toggle="dropdown" href="#">
Cost centre
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">ALL</a></li>
<li><a tabindex="-1" href="#">NSE-EQ</a></li>
</ul>
</div>
<div class="btn-group">
<a class="btn btn-type dropdown-toggle" data-toggle="dropdown" href="#">
Type
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">CLNT</a></li>
<li><a tabindex="-1" href="#">GENL</a></li>
<li><a tabindex="-1" href="#">MARG</a></li>
</ul>
</div>
<button type="submit" id = "submit" class="btn btn-success">
<i class="icon-circle-arrow-right icon-large"></i> Submit
</button>
<div id="example-1-result" class="backgrid-container"></div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://code.jquery.com/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="../static/js/bootstrap.min.js"></script>
<script>
var Territory = Backbone.Model.extend({});
var Territories = Backbone.Collection.extend({
model: Territory
//url: "examples/territories.json"
});
//var territories = new Territories();
var territory1 = new Territory({ name: "How Bizarre", pop: 20 });
var territory2 = new Territory({ name: "How ", pop: 21 });
var territories = new Territories([territory1,territory2]);
var columns = [{
name: "id", // The key of the model attribute
label: "ID", // The name to display in the header
editable: false, // By default every cell in a column is editable, but *ID* shouldn't be
// Defines a cell type, and ID is displayed as an integer without the ',' separating 1000s.
cell: Backgrid.IntegerCell.extend({
orderSeparator: ''
})
}, {
name: "name",
label: "Name",
// The cell type can be a reference of a Backgrid.Cell subclass, any Backgrid.Cell subclass instances like *id* above, or a string
cell: "string" // This is converted to "StringCell" and a corresponding class in the Backgrid package namespace is looked up
}, {
name: "pop",
label: "Population",
cell: "integer" // An integer cell is a number cell that displays humanized integers
}, {
name: "percentage",
label: "% of World Population",
cell: "number" // A cell type for floating point value, defaults to have a precision 2 decimal numbers
}, {
name: "date",
label: "Date",
cell: "date",
}, {
name: "url",
label: "URL",
cell: "uri" // Renders the value in an HTML anchor element
}];
// Initialize a new Grid instance
var refreshgrid = function(){
var grid = new Backgrid.Grid({
columns: columns,
collection: territories
});
// Render the grid and attach the root to your HTML document
$("#example-1-result").append(grid.render().$el);
}
// Fetch some countries from the url
//territories.fetch({reset: true});
$(".dropdown-menu li").click(function(){
$(this).closest('.btn-group').children('a').text($(this).text())
});
$('#submit').on('click', function(event) {
url = '/ledger/data'
company_code = $("#company_code").text();
// event.preventDefault(); // To prevent following the link (optional)
$.post( url, { name: "John", time: "2pm" },function(data){
ledgerData = JSON.parse(data);
refreshgrid();
});
//$.post(url,function(response){
// alert(response);
//});
});
</script>
</body>
</html>
When I get the JSON data in the Post request, I am not able to figure out how to feed it to the grid during the refreshgrid() call.
In most Backbonejs examples, the url is in the Model itself, but for me, the url keeps changing after every submit. So, how do I get the data and feed it to the grid?
By default, Backbone.js makes RESTful requests with an Accept header for application/json.
If you set a url property on a Collection, fetching the data is a simple as calling fetch
Read more about the Collection.url property here.
var CandiesCollection = Backbone.Collection.extend({url: "/candies"});
var c = new CandiesCollection;
c.fetch();
// GET /candies (Accept: application/json, text/javascript, */*; q=0.01)
Some more examples of Backbone doing magical work for you!
Backbone.js will automatically make a POST request when you save a new model (or use collection.create())
Likewise, it will automatically make a PUT request when you call model.save() on an existing model.
model.destroy() will make a DELETE request.
Aside from that, updating/refreshing is done exactly the same.