Toggle conditions Angularjs with <a> tag - html

I'm working on a code, where in i have icons under an < a > tag. Originally, I had a dropdown so showing a div on that was easy since a dropdown has a value but how do i code the same thing under an < a > tag?

HTML
<div ng-controller="appCtrl">
<div>
X
Y
Z
</div>
<div ng-if="showX">X --> div</div>
<div ng-if="showY">Y --> div</div>
<div ng-if="showZ">Z --> div</div>
</div>
Controller:
var appModule = angular.module('appModule', []);
appModule.controller('appCtrl', function($scope) {
$scope.assignVal = function(val) {
if (val === 'X') {
$scope.showX = true;
$scope.showY = false;
$scope.showZ = false;
} else if (val === 'Y') {
$scope.showX = false;
$scope.showY = true;
$scope.showZ = false;
} else if (val === 'Z'){
$scope.showX = false;
$scope.showY = false;
$scope.showZ = true;
}
}
});

If you want to assign a value to a variable when <a> is clicked, use ng-click, not ng-model.
X
<div ng-if="showX">X</div>

Related

Scroll up drag in web page

I'm looking to scroll up a page when I have a div selected, so the goal is to drag a div and move the page up. The scoll down works strangely.
Is there a problem with angular or html that would be listed?
(I don't want to use Jquery)
<div class="panel panel-default">
<div class="panel-body">
<p class="h4">Commandes</p>
<div class="row">
<div class="col-md-12 col-xs-12 text-right" draggable="true">
<button type="button" (click)="addCommande()" class="btn btn-labeled btn-purple m-l-4">
<span class="btn-label"><i class="fa fa-plus"></i></span><span class="hidden-xs">Ajouter une commande</span>
</button>
</div>
</div>...
editadding solutions based on our discussion in the comments section
im still not sure if I got your end goal, but I hope I did
[first solution] add `scrollPositionRestoration: 'enabled'` to `app-routing.module.ts` 's `RouterModule`:
RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled'})
[second solution] try implementing this logic]
export class ScrollToTopComponent implements OnInit {
windowScrolled: boolean;
constructor(#Inject(DOCUMENT) private document: Document) {}
#HostListener("window:scroll", [])
onWindowScroll() {
if (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop > 100) {
this.windowScrolled = true;
}
else if (this.windowScrolled && window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop < 10) {
this.windowScrolled = false;
}
}
scrollToTop() {
(function smoothscroll() {
var currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
if (currentScroll > 0) {
window.requestAnimationFrame(smoothscroll);
window.scrollTo(0, currentScroll - (currentScroll / 8));
}
})();
}
ngOnInit() {}
[third solution]
If all fails, then create some empty HTML element (eg: div) at the top (or desired scroll to location) with id="top":
<div id="top"></div>
And in component:
ngAfterViewInit() {
// Hack: Scrolls to top of Page after page view initialized
let top = document.getElementById('top');
if (top !== null) {
top.scrollIntoView();
top = null;
}
}
I dont have much to work with regarding how you built your code, but I hope this might solve it (it will make draggable items scroll your screen) :)
var stop = true;
document.quertSelector(".draggable").on("drag", function (e) {
stop = true;
if (e.originalEvent.clientY < 150) {
stop = false;
scroll(-1)
}
if (e.originalEvent.clientY > ($(window).height() - 150)) {
stop = false;
scroll(1)
}
});
document.querySelector(".draggable").on("dragend", function (e) {
stop = true;
});
var scroll = function (step) {
var scrollY = window.pageYOffset;
window.pageYOffset(scrollY + step);
if (!stop) {
setTimeout(function () { scroll(step) }, 20);
}
}

Nesting options under an if binding causes wrong behavior

I want to have a <select> without using the options binding, and nest the <option> element under an if binding.
The following is what I did (here's also a fiddle), which displays a behavior I wasn't expecting: The if seems to fire for each option selection, whereas what I expected is that it would fire only when adding the options elements to DOM.
Thus, when an option is chosen, it doesn't displayed. Only when choosing the same option again, it renders as it should.
What did I do wrong?
var DogHouseViewModel = function() {
var self = this;
self.allowedNames = ["A", "B", "C"];
self.puppies = ko.observableArray([]);
self.createPuppy = function () {
self.puppies.push(new DogViewModel());
}
self.isNameAlreadyTaken = function (puppyName) {
var puppies = self.puppies();
for (var i = 0; i < puppies.length; i++) {
if (puppies[i].dogName() == puppyName) {
return true;
}
}
return false;
}
self.printPuppiesName = function () {
self.puppies().forEach(function (puppy) {
alert(puppy.dogName())
})
}
}
var DogViewModel = function (dogName) {
var self = this;
self.dogName = ko.observable();
}
vm = new DogHouseViewModel()
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.1.0/knockout-min.js"></script>
<div>
<button data-bind="text: 'create a puppy', click: createPuppy"></button>
<button data-bind="text: 'print puppies names', click: printPuppiesName"></button>
<div data-bind="foreach: puppies">
<select data-bind="value: dogName">
<!-- ko foreach: $parent.allowedNames -->
<!-- ko if: !($root.isNameAlreadyTaken($data)) -->
<option data-bind="value: $data, text: $data"></option>
<!-- /ko -->
<!-- /ko -->
</select>
</div>
</div>
I believe this is what you are trying to do. The problem is that your allowedNames are the values of the options do you can't just remove them from the array. But you can clone the parent array and as it changes compute the array by returning a list of not used values.
I also added a check to make sure we don't accidentally add a puppy object to the puppies array when no names are available.
var DogHouseViewModel = function() {
var self = this;
self.allowedNames = ["A", "B", "C"];
self.puppies = ko.observableArray([]);
self.createPuppy = function() {
var newPuppy = new DogViewModel(self);
if(newPuppy.allowedNames().length > 0) { // Check to see if there are any names left.
self.puppies.push(newPuppy);
}
}
self.removePuppy = function(obj) {
self.puppies.remove(obj);
}
self.printPuppiesName = function() {
self.puppies().forEach(function(puppy) {
alert(puppy.dogName())
})
}
}
var DogViewModel = function(parent) {
var self = this;
self.dogName = ko.observable();
self.allowedNames = ko.computed(function() {
var allowedNamesClone = parent.allowedNames.slice(0);
var usedNames = parent.puppies().filter(function(pup) { // get all pups who have a name
return pup.dogName() !== '' && pup.dogName() !== self.dogName();
})
usedNames.forEach(function(pup) {
var index = allowedNamesClone.indexOf(pup.dogName());
if (index > -1) {
allowedNamesClone.splice(index, 1); // remove name from cloned array
}
})
return allowedNamesClone; // return new array
})
}
vm = new DogHouseViewModel()
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
<button data-bind="text: 'create a puppy', click: createPuppy"></button>
<button data-bind="text: 'print puppies names', click: printPuppiesName"></button>
<div data-bind="foreach: puppies">
<!-- ko if: allowedNames().length > 0 -->
<select data-bind="options: allowedNames, value: dogName"></select>
<button data-bind="click: $root.removePuppy">x</button>
<!-- /ko -->
</div>
</div>

Making Div Hide after its been shown

So I have it so far when you click on an image it shows a Div. I just need it so that when you click on the image again and the div is being shown then it will hide.
Here is my code:
Style and script
<style type="text/css">
.show{display:block;}
.hide{display:none;}
</style>
<script type="text/javascript">
function showImg()
{
var obj=document.getElementById('calcShow');
obj.className = 'show';
}
</script>
Here is the HTML
<li data-value="iconchange"><img src="modules/icons/icons/calculator.png" width="65" onclick = "showImg()" class="calculator"></li>
And the Div
<div id="calcShow" class="hide"><br><br><br>
<?php
include("modules/calc/calc.html");
?>
</div>
What you want to do is create a conditional that checks whether the <div> is currently shown or not. Depending on the visibility, change the class that's associated to the <div>:
function toggleImg() {
var obj = document.getElementById('calcShow');
if (obj.className == 'show') {
obj.className = 'hide';
}
else if (obj.className == 'hide') {
obj.className = 'show';
}
}
.show {
display: block;
}
.hide {
display: none;
}
<div id="calcShow" class="hide">Hidden</div>
<br />
<img src="http://placehold.it/100" onclick="toggleImg()">
Note that you don't actually have to use classes for this, as this can be done directly through the .style.display property:
function toggleImg() {
var obj = document.getElementById('calcShow');
if (obj.style.display == 'none') {
obj.style.display = 'block';
}
else if (obj.style.display == 'block') {
obj.style.display = 'none';
}
}
<div id="calcShow" style="display: block">Hidden</div>
<br />
<img src="http://placehold.it/100" onclick="toggleImg()">
Hope this helps! :)
Solution with Jquery:
HTML:
<li data-value="iconchange"><img src="modules/icons/icons/calculator.png" width="65" class="calculator"></li>
The DIV:
<div id="calcShow"><br><br><br>
<?php
include("modules/calc/calc.html");
?>
</div>
The Function:
$('.calculator').click(function{
var isvisible = $('#calcShow').is(":visible");
if(isvisible == true){
$('#calcShow').hide();
}
else{
$('#calcShow').show();
}
})
This is basically one of the easiest way using pure javascript,
function showImage(){
var obj = document.getElementById('calcShow');
if(obj.style.display !== "block"){
obj.style.display = "block";
}else{
obj.style.display = "none";
}
}
Instead of creating separate functions for showing and hiding the image, you could create a function that toggles the value. You can use the ternary operator to decide whether you want to set the className to show or hide.
The ternary operator works like so, condition ? ifTrue : ifFalse.
The condition will be obj.className === "show". If this is true, then it should switch from its current value of "show" to a value of "hide". However, if it's false, then it's current value is "hide" and so its new value should be set to "true".
function showOrHide() {
var obj = document.getElementById('calcShow');
obj.className = (obj.className === "show" ? "hide" : "show");
}
Then you can simply set the onClick attribute to call this function.

cleaning up angularjs controller and function - for drop down list with multi select custom made

how can I clean up this code. here is my function in my controller. I am using this to control 3 different custom made drop down lists in my html. I want when you click out of them, they close. I wish I didn't need to give them each their own variable for ng-show, but I think I do because if ng-show is true for one then they would all show together. Also is it wrong to put all this in a controller rather than a directive or factory or something - besides for cleaning up the function itself.
$scope.toggle = function (option,type) {
if (option == 'subdiv') {
$scope.notMain = true;
if ($scope.notMain) {
if (type == 'item') {
$scope.showItemOptions = true;
$scope.showOptions = false;
$scope.showOrderOptions = false;
}
else if (type == 'style') {
$scope.showOptions = true;
$scope.showItemOptions = false;
$scope.showOrderOptions = false;
}
else if (type == 'order') {
$scope.showOrderOptions = true;
$scope.showItemOptions = false;
$scope.showOptions = false;
}
}
}//end of if subdiv
else if (option == 'maindiv') {
if (!$scope.notMain) {
$scope.showItemOptions = false;
$scope.showOptions = false;
$scope.showOrderOptions = false;
}
$scope.notMain = false;
}//end of if maindiv
};
here is the html for just one of the drop downs (but they are all the same with different variables:
<div class="dropdownlistheader" ng-click="toggle('subdiv','order')">
<input type="text" readonly="readonly" class="dropdownlistinput" value="{{selectedOrderValuesDisplay}}" /> </div>
<div id="ddl123" ng-show="showOrderOptions" class="dropdownlist">
<div ng-show="showOrderOptions" ng-repeat="option in OrdersDDL">
<label> <input type="checkbox" ng-model="selected[$index]" ng-click="toggleOrderSelection(option.Number, option.Details)"> {{option.Details}}</label> </div></div>
I changed the whole thing to one function. was able to do it easily by changing the ng-show variables to contain the text of of the name of the ddl that should show instead of bool like they were.
$scope.toggle = function (option,type) {
if (option == 'subdiv') {
$scope.notMain = true;
if ($scope.notMain) {
$scope.showDDL = type;
}
}
else if (option == 'maindiv') {
if (!$scope.notMain) {
$scope.showDDL = '';
}
$scope.notMain = false;
}
};
in html: ng-show=="type" //type is hardcoded in html

Div content resizing

I have 3 different charts inside 3 different div tags that appear and hide when specified. However, two of the charts randomly resize and i know why.
How do i fix this?
I have wordpress and using visualizer plugin for my charts. have the code in the header.php file and in the text portion of the page specific code.
Code below:
Header.php snippet -
<script>
var divs = ["Daily", "Weekly", "Monthly"];
var visibleDivId = null;
function toggleVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
</script>
HTML page snippet -
<div class="inner_div">
<div id="Daily">[visualizer id="431"]</div>
<div id="Weekly" style="display: none;">[visualizer id="430"]</div>
<div id="Monthly" style="display: none;">[visualizer id="429"]</div>
</div>
<div class="main_div">
<div class="buttons">
Daily | Weekly | Monthly
</div>
A quick fix is to include call visualizer.render(); at the end of your toggleVisibility function:
function toggleVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
visualizer.render();
}
The problem is caused by invalid calculation of available area for divs that aren't visible at the time. Calling this method forces a re-calulcation of the svgs and ensures the right size.