I'm looking to enable users to change the class from incomplete to complete on button click when function(response) returns 1. I have tried using issues, however; It doesn't work well as the HTML elements are loaded with a PHP loop so an ng-class expression doesn't work. This is because an if statement is run checking if it is incomplete or complete while the AngularJS expression wouldn't be able to check the database in this sense.
I added the 'active' variable, but I cant seem to put this into play without ng-class. Is there an alternative to jQuery's class add/remove? Or can someone think of another solution.
HTML:
<div class='task col-md-4 incomplete'>
<button data-ng-click='toggleTask(".$lesson_id.", 0)' class='btn btn-default'>Mark as complete</b></button>
</div>
AngularJS:
var app = angular.module('training-center', []);
app.controller('task-manager', function(\$scope, \$http) {\
$scope.toggleTask = function(id, active) {\
$scope.id = id;\
$http.post('app/modules/Controller.php?action=toggleTask', {
task_id: id,
active: active
}).
then(function(response) {
if (response.data == '1') {
//What do I place here?
}
},
function(response) {
});
};
});
You do not have to use ng-class - you can use regular class and put a parameter in it with {{}}. Then just change the variable in the $scope, and it will automatically adapt its behaviour.
Here is an example:
<div ng-app>
<div ng-controller="testCtrl">
<div id="test" class="{{className}}">
{{className}}
</div>
Click
</div>
</div>
And the controller code (it's ugly, but you'll get the point):
function testCtrl($scope) {
$scope.className = "red";
$scope.increase = function() {
if($scope.className == "red")
$scope.className = "blue";
else if($scope.className == "blue")
$scope.className = "green";
else if($scope.className == "green")
$scope.className = "red";
}
}
(Of course, classes are trivial):
.red { color: #FF0000; }
.blue { color: #0000FF;}
.green { color: #00FF00;}
This works just fine for me. I have not tested it out in an environment where the body of the page is generated by PHP, but should not make a difference.
Related
The below CSS is applied on click of link available at one element:
<a class="vehicleinfo avai-vehicle-info-anc-tag" ng-click="vehicleInfo($event)">Vehicle Info
<span class="s-icon red-down-arrow"> </span>
</a>
$scope.vehicleInfo = function(event) {
var el = jQuery(event.currentTarget),
featuredcarbox = el.closest(".avilablecar.available-car-box");
featuredcarbox.find(".avlcarimagetab img").toggleClass("slide-left");
featuredcarbox.toggleClass("bg-grey");
el.toggleClass("icon-remove");
featuredcarbox.find(".available-car-fac").toggleClass("hidden");
}
I want to remove all the above toggled classes applied at each element (vehicle) on calling one function.
How can I achieve??
too simple.....i think. if you need to remove toggled classes just replace toggleClass to removeClass. as i show in new function/
$scope.vehicleClassRessetInfo = function(event) {
var el = jQuery(event.currentTarget),
featuredcarbox = el.closest(".avilablecar.available-car-box");
featuredcarbox.find(".avlcarimagetab img").removeClass("slide-left");
featuredcarbox.removeClass("bg-grey");
el.removeClass("icon-remove");
featuredcarbox.find(".available-car-fac").removeClass("hidden");
}
You are probably looking for ng-class with a ternary operator. Ng-class works like this:
<div ng-class="(foo == 1) ? 'classes if-true' : 'classifFalse'"
The "(foo == 1)" part can be an expression, an evaluated function, or a variable from the controller.
I don't have enough to work with to put it in a fiddle I don't think, but here is what I would do...
HTML:
<a ng-class="(applyClassses == true) ? 'vehicleinfo avai-vehicle-info-anc-tag' : ''" ng-click="vehicleInfo($event)">Vehicle Info
<span class="s-icon red-down-arrow"></span>
</a>
Controller:
$scope.vehicleInfo = function() {
if () {
$scope.applyClasses = true;
}
else {
$scope.applyClasses = false;
}
}
Before I knew about things like Angular and jQuery, there was plain old Javascript like this:
function toggleClass(e, c) {
var classes = e.className.split(' ');
var match = false;
for(var i=0; i<classes.length; i++) {
if(classes[i] === c) {
match = true;
classes.splice(i,1);
break;
}
}
if(!match) classes.push(c);
e.className = classes.join(' ');
}
I've used this in the past to toggleClass name in an onclick event like so:
<div onclick="toggleClass(this,'foo')"></div>
Here is a working JSFiddle.
How would I implement this as a directive in Angular?
You can use AngularJs' ng-class directive instead of creating another directive.
angular.module('demo', [])
.controller('Ctrl', function($scope) {
$scope.toggleRed = true;
});
.box {
padding: 50px;
display: inline-block;
background-color: #efefef;
}
.box.red-box {
background-color: red;
}
<div ng-app="demo" ng-controller="Ctrl">
<div class="box"
ng-class="{'red-box': toggleRed}"
ng-click="toggleRed = !toggleRed">Click Me</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
Angular is not jQuery, so your thought process should not be about adding removing classes or showing hiding elements or anything to do on these lines.
Please refer to this SO post for some good pointers "Thinking in AngularJS" if I have a jQuery background?
In Angular model drives the view.
What you are doing should be done using the standard ng-class directive.
Let's say you have a grid of users and you want highlight rows when the user click on the row signifying the user has been selected. The way you would go about it would be to define the row html as
<tr ng-repeat='user in users' ng-click='user.selected=!user.selected' ng-class={'active': user.selected}>
</tr>
Now the state of user.selected drives the view and toggles the class on every click.
I am trying to make webpage where there is a div in the center which is being changed, instead of going to different pages.
Ultimately, I would like to have the new div, when clicking on an arrow, to flow from right or left in to the center. But first I would like to make the divs appear and disappear when clicking on the arrows but unfortunately this doesn't work.
This is my javascript:
<script>
function changeToHome() {
document.getElementById("mainmain").style.display="block";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="none";
}
function changeToStudy() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="block";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="none";
}
function changeToJob() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="block";
document.getElementById("mainmain4").style.display="none";
}
function changeToContact() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="block";
}
function changePageRight() {
var displayValue5 = document.getElementById('mainmain').style.display;
var displayValue5 = document.getElementById('mainmain2').style.display;
var displayValue6 = document.getElementById('mainmain3').style.display;
var displayValue7 = document.getElementById('mainmain4').style.display;
if (document.getElementById('mainmain').style.display == "block") {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="block";
}
else if (document.getElementById('mainmain2').style.display == "block") {
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="block";
}
else if (document.getElementById('mainmain3').style.display == "block") {
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="block";
}
else if (displayValue8 == block) {}
}
function changePageLeft() {
var displayValue = document.getElementById('mainmain').style.display;
var displayValue2 = document.getElementById('mainmain2').style.display;
var displayValue3 = document.getElementById('mainmain3').style.display;
var displayValue4 = document.getElementById('mainmain4').style.display;
if (displayValue == "block") { }
else if (displayValue2 == "block") {
document.getElementById("mainmain").style.display="block";
document.getElementById("mainmain2").style.display="none";
}
else if (displayValue3 == "block") {
document.getElementById("mainmain2").style.display="block";
document.getElementById("mainmain3").style.display="none";
}
else if (displayValue4 === "block") {
document.getElementById("mainmain3").style.display="block";
document.getElementById("mainmain4").style.display="none";
}
}
</script>
Now I have a few divs that look like this:
<div id="mainmain4">
<img style="width:400px;height:327px;margin-left:auto;margin-right:auto;display:block;" src="Untitled-22.png" />
<h2> My name </h2>
<p>Hi,</p>
<p>Some text</p>
</div>
With these css atributes:
#mainmain {
float: left;
width: 575px;
display: block;
position: relative;
}
And all other divs with display: none; so I can change this to block and the one that was block to none.
For some reason, after when I click on one button of the menu, which activates a changeToX() function, the arrows work great. But before that, when you first go to the website, it doesn't.
Can someone explain me what I do wrong?
You don't tell the browser which divs shall be displayed on load. You can use theonloadevent for this:
<body onload="changeToHome()">
One additional hint: you maybe don't want to use inline JavaScript and CSS.
jQuery is as this simple:
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
toggle!
<div id="mainmain">test text</div>
<script>
// you need this, only apply javascript when all html (dom) is loaded:
$(document).ready(function() {
$('.toggle-container').on('click', function(e) {
e.preventDefault(); // this prevents the real href to '#'
// .toggle() is like "on / off" switch for hiding and showing a container
$($(this).data('container')).toggle();
});
});
</script>
This function can be reused, because it is based on classes instead of id's.
Check this JSFiddle: http://jsfiddle.net/r8L6xg15/
Maybe this is of some use. I've tried to make a page control-like behaviour. You can select any container div and put elements in there that have the class 'page'. The JavaScript code will let you navigate those with buttons.
You can make it more fancy by adding the buttons through JavaScript. What you then have is basically a list of pages which are normally displayed as regular divs, but when the script kicks in, it changes them to a page control.
You can call this for any parent element, and in that sense it behaves a bit like a jQuery plugin. It is all native JavaScript, though. And not too much code, I hope. Like you said, I think it's good to learn JavaScript at first. It is very powerful by itself, and it's becoming increasingly powerful. jQuery adds a lot of convenience functions and provides fallbacks in case browser don't support certain features, or when implementations differ. But for many tasks, bare JavaScript will do just fine, and it certainly can't hurt to know your way around it.
Press the 'Run this snippet' button at the bottom to see it in action.
function Pages(element)
{
// Some initialization
var activePage;
// Find all pages within this element.
var pages = document.querySelectorAll('.page');
var maxPage = pages.length - 1;
// Function to toggle the active page.
var setPage = function(index)
{
activePage = index;
for (p = 0; p <= maxPage; p++)
{
if (p == activePage)
pages[p].className = 'page active';
else
pages[p].className = 'page inactive';
}
}
// Select the first page by default.
setPage(0);
// Handler for 'previous'
element.querySelector('.prev').onclick = function()
{
if (activePage == 0)
return;
setPage(activePage - 1);
}
// Handler for 'next'
element.querySelector('.next').onclick = function()
{
if (activePage == maxPage)
return;
setPage(activePage + 1);
}
// Add a class to the element itself. This way, you can already change CSS styling
// depending on whether this code is loaded or not. So in case of an error, the
// divs are just all show underneath each other, and the nav buttons are hidden.
element.className = element.className + ' js';
}
Pages(document.querySelector('.pages'));
.pages .page {
display: block;
padding: 40px;
border: 1px solid blue;
}
.pages .page.inactive {
display: none;
}
.pages .nav {
display: none;
}
.pages.js .nav {
display: inline-block;
}
<div class="pages">
<button class="nav prev">Last</button>
<button class="nav next">Next</button>
<div class="page">Page 1 - Introduction and other blah</div>
<div class="page">Page 2 - Who am I? Who are you? Who is Dr Who?</div>
<div class="page">Page 3 - Overview of our products
<ul><li>Foo</li><li>Bar</li><li>Bar Pro</li></ul>
</div>
<div class="page">Page 4 - FAQ</div>
<div class="page">Page 5 - Contact information</div>
</div>
To dos to make this a little more professional:
Add the navigation through JavaScript
Disable the buttons when first/last page has been reached
Support navigation by keys too (or even swipe!)
Some CSS transform (fade or moving) when toggling between pages
Smarter adding and removing of classes. Now I just set className, which sucks if someone would like to add classes themselves. jQuery has addClass and removeClass for this, which is helpful. there are also stand-alone libraries that help you with this.
Visible indication of pages, maybe with tabs at the top?
I struggle thinking "The Angular Way" so this is undoubtedly a simple problem, but I'm trying to have it so when I click a button (which will eventually be colored) the text changes to that color. Here is essentially the code:
JS
var myApp = angular.module('myApp', []);
myApp.controller('ColorCtrl', ['$scope', function($scope){
$scope.changeColor = function(value){
return {"color:" value };
}
$scope.turnGreen = function (){
//what to do here?
}
$scope.turnBlue = function() {
//and here?
}
}]);
HTML
<div ng-app="myApp" ng-controller="ColorCtrl">
<button ng-click="turnBlue()">Make text blue</button>
<button ng-click="turnGreen()">Make text green</button>
<p ng-style="changeColor(value)">I should be either green or blue!</p>
</div>
I know I could easily use jQuery to select the text I want to work with, but I don't want to do that. Do i need to give my paragraph a model? Any push in the right direction is greatly appreciated - thank you.
You could do this way:
Define ng-class directive and value as colorClass which will be set in the scope.
<p ng-class="customStyle.colorClass">I should be either green or blue!</p>
and do:
$scope.customStyle = {};
$scope.turnGreen = function (){
$scope.customStyle.colorClass = "green";
}
$scope.turnBlue = function() {
$scope.customStyle.colorClass = "blue";
}
and some rules:
.green{
color:green;
}
.blue{
color:blue;
}
or with inline style
<p ng-style="customStyle.style">I should be either green or blue!</p>
and
$scope.customStyle = {};
$scope.turnGreen = function (){
//what to do here?
$scope.customStyle.style = {"color":"green"};
}
$scope.turnBlue = function() {
$scope.customStyle.style = {"color":"blue"};
}
im trying to make a switch wich will change two images. I once solved ths, but then i lost some important files, the one containing the final script being one.
The idea is that when the button is clicked, it will change image 1 for image 2 and will change its own image from on to off. Then, when clicked again it will change image 2 for image 1 and its own image from off to on.
I been trying something like this, buts not working, not sure why. I think i got the wrong declaration for the if which determines if the switch is on or off, but again not sure.
Before you read the code and realize its poorly done, consider i dont know a thing about javascript, i only have a vague idea of how it works.
<script type="text/javascript">
var vswitch = false;
if (document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif") {
vswitch = true
}
else {
vswitch = false
}
function change(){
if (vswitch == true){
function changelamp() {
document.getElementById("lamp").src = "http://www.sampleweb.com/image2.png";
}
function changeSwitch() {
document.getElementById("switchh").src = "http://www.sampleweb.com/off.gif";
}
} else {
function changelamp() {
document.getElementById("lamp").src = "http://www.sampleweb.com/image1.gif";
}
function changeSwitch() {
document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif";
}
}
}
<div id="main_img">
<img id="lamp" src = "http://www.sampleweb.com/image1.gif">
</div>
<div id="container">
<img id="switchh" src = "http://www.sampleweb.com/on.gif" onclick='change();'>
</div>
</script>
Thank you
/////////////////////EDIT///////////////////////////
Thanks a lot.
Having those two functions there was a result of the previous code, i dont understand how i didnt realize it until you pointed out, heh. (Sleepyness maybe?)
#renuka, that code worked perfectly. I only changed the calling div, from the div "toggle" you created to the div "container" since the button has to switch the images itself, but other than that was sweet. Thanks.
Thanks for the help!
There are a couple of problems here :)
First:
if (document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif")
^ this assigns a variable
You want to change = to === so that a comparison is done
Second, you're creating functions changelamp and changeSwitch but you're never actually calling them. I think you want to get rid of the function declarations completely:
if (vswitch == true){
document.getElementById("lamp").src = "http://www.sampleweb.com/image2.png";
document.getElementById("switchh").src = "http://www.sampleweb.com/off.gif";
} else {
document.getElementById("lamp").src = "http://www.sampleweb.com/image1.gif";
document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif";
}
Finally, there are some minor syntax errors such as missing semi-colons
vswitch = true; // <- like this
Please check the updated code below:
<script type="text/javascript">
function change(){
var vswitch = false;
if (document.getElementById("switchh").src == "http://www.sampleweb.com/on.gif") {
vswitch = true
}
else {
vswitch = false
}
if (vswitch == true){
document.getElementById("lamp").src = "http://www.sampleweb.com/image2.png";
document.getElementById("switchh").src = "http://www.sampleweb.com/off.gif";
}
else {
document.getElementById("lamp").src = "http://www.sampleweb.com/image1.gif";
document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif";
}
}
</script>
<div id="main_img">
<img id="lamp" src = "http://www.sampleweb.com/image1.gif"/>
</div>
<div id="container">
<img id="switchh" src = "http://www.sampleweb.com/on.gif"/>
</div>
<div id="toggle">
<input type="button" value="On/Off" onclick='change();'/>
</div>
The '=' assigns the value to the "src" of the image. Replace it with '==' for comparison.
Additionally from what jasonscript says, you are never switching the vswitch variable to the opposite state, so you'd need to add
vswitch = !vswitch;
after the if in the change() function, that way, the next time you click in the switch, it takes the "other" path through the if
Another point is that if you have the code layout as you have it in your post (script first and then the HTML code) the first if will actually not find the #switchh img, so you need to either move the if inside the change() function or move your script after the HTML
Major problem is that you are unnecessarily creating functions inside script which are never called.
No need for
changelamp() and changeSwitch()
You can directly post the code after the if condition check.
<script> tags should be closed. = assigns and === does comparison, and you need to change the value of vswitch.
Here is a fiddle that accomplishes what you're after with some random images