I'm trying to make a random quote generator and I want to make the container with the content reload when I click a button in another container. The commented area "what should go here" is where I think the action code should go. I'm not sure if I should go with something like $('quotecontainer').container(function(){}); and go from there, or if something else is needed entirely.
Here's the JS:
$('#newquotebutton').button();
$('#newquotebutton').click(function(){
$(this).button('loading');
// what should go here
$(this).button('reset');
});
Here's the HTML:
<div id="wherebuttonis" class="jumbotron-transparent">
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4 text-center">
<button id="newquotebutton" class="btn btn-default" data-text-loading="loading...">New Quote</button></div></div></div></div>
<div id="quotetron" class="jumbotron-transparent">
<div id = "quotecontainer" class="container text-center">
<script type="text/javascript" src="http://www.brainyquote.com/link/quotefu.js"></script>
<small><i>more Funny Quotes</i></small></div></div>
The remote script you provided seem to provide only one quote per day...
So you'll have to create your own local array of quotes to pick another quotes:
var quotes = ['quote one', 'quote two', 'quote three'];
$('#newquotebutton').button();
$('#newquotebutton').click(function(){
var random_quote = quotes[Math.floor(Math.random()*quotes.length)];
$(this).button('loading');
$('#newquotebutton').text(random_quote);
$(this).button('reset');
});
Related
I have to tweet a quote that I randomly generated using APIs, but my code isn't working. Here is my code, I added comments trying to make it look clearer. I am a novice in coding so it probably has a terrible sintax.
I manage to get my quote by clicking on the "Get another quote" button, but when i want to tweet my quote, clicking on the "Tweet quote" button it wont work and i get the "Uncaught ReferenceError: data is not defined
at pen.js:10" error.
I dont know what i am doing wrong.
(This is a task for FreeCodeCamp). Thanks to everyone who will answer!
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">
<h2 class="title">Random Quote Generator</h2>
<h4 class="subtitle">A project for the FreeCodeCamp challenge</h4>
<div class="container-box">
<div class="container-quote">
<p class="quote" id ="quote"></p>
<div class="container-author" id="author">
<p></p>
</div> <!--closing div for container author-->
<div class="row">
<div class="col-md-6">
<button id="tweetQuote" href="https://twitter.com/intent/tweet?text=data.quoteText">Tweet this quote!</button>
</div>
<div class="col-md-6">
<button id="newQuote">Get another quote</button>
</div>
</div> <!--row-->
</div> <!--closing div for container quote-->
</div> <!--closing div for container-->
And now the javascript
//setting html elements to variables
var $newQuote = $('#newQuote');
var $quote = $('#quote');
var $tweetQuote = $('#tweetQuote');
//execute function by clicking on button
$newQuote.click(getQuote);
$tweetQuote.click(tweetIt);
var text = data.quoteText;
var author = data.quoteAuthor;
//when getQuote is called call the APIs and get the quote by executing
getQuoteFromAPI
function getQuote() {
$quote.empty();
getQuoteFromAPI();
};
function getQuoteFromAPI() {
var url='https://api.forismatic.com/api/1.0/?
method=getQuote&format=jsonp&lang=en&jsonp=?';
//when the APIs are completely called execute the parseQuote function
$.getJSON(url).done(parseQuote);
//log the datas on the console and transform them into real html elements
function parseQuote (response) {
console.log(response);
document.getElementById('quote').innerHTML = response.quoteText;
document.getElementById('author').innerHTML = response.quoteAuthor;
};
};
function tweetIt() {
var url='https://api.forismatic.com/api/1.0/?
method=getQuote&format=jsonp&lang=en&jsonp=?';
$('#tweetQuote').attr('href', 'https://twitter.com/intent/tweet?text=' + text + '-' + author);
};
This is how my page looks like on initial load
<body>
<div class="col-md-12" id="dataPanes">
<div class="row dataPane"> Chunk of html elements </div>
</div>
<div class"col-md-12 text-right">
<input type="button" class="btn btn-primary" value="Add dynamic row" ng-click="addElementChunk()" />
</body>
I am in need to add rows to div#dataPanes on button click
If I was using jQuery,addElementChunk() function would have looked as below
var addElementChunk = function()
{
var html = "<div class='row dataPane'> Chunk of html elements </div>";
$("#dataPanes").append(html);
}
but how do I implement the same in angular??
You need to use $compile
Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.
and $sce
Strict Contextual Escaping (SCE) is a mode in which AngularJS constrains bindings to only render trusted values. Its goal is to assist in writing code in a way that (a) is secure by default, and (b) makes auditing for security vulnerabilities such as XSS, clickjacking, etc. a lot easier.
addElementChunk = function(){
var html = '<div class="row dataPane"> Chunk of html elements </div>';
var trustedHtml = $sce.trustAsHtml(html);
var compiledHtml = $compile(trustedHtml)($scope);
angular.element(document.getElementById('dataPanes')).append(compiledHtml);
}
you can append new div using angular ng-repeat directive
lets say you have an array that contain one element and every time you click the button you add another element to the array, while you are repeating it in your "dataPane" div
so you code could be:
HTML
<div ng-app="myApp" ng-controller="myCtr">
<div class="col-md-12" id="dataPanes">
<div class="row dataPane" ng-repeat="element in added_elements"> Chunk of html elements ( {{element}} ) </div>
</div>
<div class="col-md-12 text-right">
<input type="button" class="btn btn-primary" value="Add dynamic row" ng-click="addMoreElements()" />
</div>
</div>
JS
angular
.module('myApp', [])
.controller('myCtr', ['$scope', function($scope) {
$scope.added_elements = ["elem 1"];
$scope.addMoreElements = function(){
$scope.added_elements.push("elem "+ ($scope.added_elements.length+1));
}
}])
so you can add whatever data you want about your repeated row and bind it in html in simple way without having to repeat the whole html code
Working Demo
You can also append a new html element in this way. I think its very easy to write and also understand. hope it will help you.
angular.element used to access the html element.
Here is the html code:
angular.module('myApp',[]).controller('myCtrl', function($scope){
$scope.addElementChunk = function()
{
var htmlStr = '<div class="row dataPane"> Chunk of html elements </div>';
debugger;
angular.element(document.getElementById('dataPanes')).append(htmlStr);
}
});
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="col-md-12" id="dataPanes">
<div class="row dataPane"> Chunk of html elements </div>
</div>
<div class="col-md-12 text-right">
<input type="button" class="btn btn-primary" value="Add dynamic row" ng-click="addElementChunk()" />
</div>
</div>
Here is the fiddle link
I want to make, that during the ediditing comment action, I have modal window with comment text written inside textarea, and it is editable without deleting all text with clicking. I tried just to put value inside textarea or placing it in placeholder. But both options are wrong and doesnt work.
Can someone take a look on this code and give me an advice, how should I take for it.
editComment.html
<div class="modal-header">
<h3 class="modal-title" id="modal-title">Edytuj komentarz</h3>
</div>
<div class="modal-body" id="modal-body">
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12 form-group">
<label>Treść</label>
<textarea class="form-control input-sm"
name="description"
ng-maxlength="512"
ng-model="$ctrl.selected"
rows="6">{{comment.value()}}</textarea>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-raised btn-primary"
type="button"
ng-disabled="!$ctrl.selected"
ng-click="$ctrl.ok()">Zapisz
</button>
<button class="btn btn-raised btn-warning"
type="button"
ng-click="$ctrl.cancel()">Anuluj
</button>
</div>
editComment.js
(function() {
'use strict';
angular.module('settlerApplication').controller('EditCommentCtrl', function($uibModalInstance) {
var $ctrl = this;
$ctrl.ok = function() {
$uibModalInstance.close($ctrl.selected);
};
$ctrl.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
});
})();
I'm not sure to understand what you are trying to achieve. But anyway : if you want to init your textarea's ng-model with $ctrl.foo (comment.value() in your case, from what I understood), you should either :
In the controller, init your $ctrl.selected variable with this value :
$ctrl.selected = $ctrl.foo;
Or, in your template, use ng-init :
<textarea class="form-control input-sm"
ng-init="$ctrl.selected = $ctrl.foo"
name="description"
ng-maxlength="512"
ng-model="$ctrl.selected"
rows="6"></textarea>
Ok, so I am going to explain that a little.
I have modal window like that:
I want to edit existing comments in this window. And so I want my comment appears instead of text: "Komentarz" (under: "Treść" after clicking in there). And I want that comment text to be editable, so I dont have to write it down again (put the whole text to that area). Is it make it a little better explained about my goal?
a button corresponding to a prompt box,each box is different shells;Although implements the desired function, but my code is too complicated, and that there is no simple way. how can I do? This is my code
<--html button-->
button1
button2
...
button100
<--html pop box-->
<div class="note1" style="display:none;">
<img class="title-css" src="note1.png">
<p class="one">note1</p>
</div>
...
<div class="note100" style="display:none;">
<img class="title-css" src="note100.png">
<p class="one">note100</p>
</div>
<--angular js-->
$scope.showRulePop = function(index) {
for(var i=1;i<=8;i++) {
$('.note'+i).hide();
}
$('.note'+index).show();
};
Well first of all, don't use jQuery, unless your in the directive level of angular jQuery have nothing to do there.
First let's get rid of the links part using a simple ng-repeat :
<--html button-->
<div ng-repeat="button in buttons">
{{button.label[i]}}
</div>
// JS in the controller
$scope.buttons = [{
label:'button1'
},{label:'button2'}];
As you can see i declare in the javascript all your buttons and i just loop over it.
Now the "bombox" or whatever it is let's make it a simple template :
<div class="{{currentnote.class}}" ng-if="currentNote">
<img class="title-css" src="{{currentNote.img}}">
<p class="one">{{currentNote.content}}</p>
</div>
// and use ng-repeat for the eight first when there is no button selected
<!-- show 1 to 8 if note current note selected -->
<div ng-repeat="button in buttons1To8" ng-if="!currentNote">
<div class="{{button.note.class}}">
<img class="title-css" src="{{button.note.img}}">
<p class="one">{{button.note.content}}</p>
</div>
</div>
// JS
$scope.buttons = [{
label:'button1'
note:{class:'note1', img:'note1.png', content:'note1'//assuming no HTML or you' ll need something more
}},{label:'button2', note:{...}}, ...];
$scope.showRulePop = function(index){
$scope.currentNote = $scope.buttons[index].note;
}
$scope.buttons1To8 = $scope.buttons.slice(0, 8);//0 to 7 in fact
That's all, no need of jQuery.
I have two divs - the first contains the second. The contained div has its own controller. When I click an icon button in the container, I change a variable which then affects the visibility of the contained div.
It looks like this:
<div ng-controller="BarController">
<div class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="col-lg-2 page-title">My Page</div>
<div class="col-lg-10">
<span class="actions">
<i class="fa fa-lg fa-download fa-inverse" tooltip="Download"
ng-click="showSecondaryBar=!showSecondaryBar"></i>
</span>
</div>
</div>
</div>
<div class="download navbar download-in download-out"
ng-class="{'myhidden': !showSecondaryBar}"
ng-cloak>
<div class="col-lg-offset-4 col-lg-4 form-inline form-group" ng-controller="TagsController">
<div class="download-label col-lg-6">
<label>Download by tags:</label>
</div>
<div class="download-tags col-lg-6">
<tags-input class="bootstrap" spellcheck="false" min-length="1" ng-model="tags" add-from-autocomplete-only="true">
<auto-complete source="loadTags($query)" min-length="1" load-on-down-arrow="true"
load-on-focus="true" max-results-to-show="5"
highlight-matched-text="false"></auto-complete>
</tags-input>
</div>
</div>
</div>
</div>
The <tags-input> is taken from ng-tags-input and I would like to reset the tags that were already typed to it whenever the icon button is clicked (which changes the visilibyt of the div that contains the ng-tags-input).
Problem is, because I have the TagsController which contains the data (tags) and this data is not visible in the BarController, I'm not sure how I can reset the tags array to become empty.
I thought of using a service but it fills like too much of a coupling. I would prefer to have a function in TagsController which is called upon click. But I can't figure out how to do it from another controller
You are right you have to use a service.
Why don't you use a broadcast as your TagsController is included in BarController?
You can include a scope.broadcast("Event") in BarController
Then a "on" listener on TagsController who will reset the tags array when "Event" Occur.
I would personnaly to this.
https://docs.angularjs.org/api/ng/type/$rootScope.Scope
You can use $broadcast on $rootScope to send an event to TagsController. So TagsController can receive this event by registering an event listener for it. See following example.
Refer to $rootScope API docs
angular.module('app',[])
.controller('ParentController', function($rootScope) {
var parentCtrl = this;
parentCtrl.someFlag = true;
parentCtrl.changeFlag = function() {
parentCtrl.someFlag = !parentCtrl.somFlag;
$rootScope.$broadcast('resettags', {'defaultTags': 'whatever_tag'});
}
})
.controller('ChildController', function($rootScope){
var childCtrl = this;
childCtrl.tags = "Some tags entered by user";
$rootScope.$on('resettags', function(event, args) {
childCtrl.tags = args.defaultTags;
});
});
.myHidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div id="main" ng-controller="ParentController as parentCtrl">
<button type="button" ng-click="parentCtrl.changeFlag()">Toggle</button>
<div ng-class="{'myHidden' : !parentCtrl.someFlag}">
<div ng-controller="ChildController as childCtrl">
<h1>{{childCtrl.tags}}</h1>
</div>
</div>
</div>
</div>