AngularJS - ng-click buttons not working - angularjs

I am new to AngularJS. I'm trying to toggle a modal into view using ng-if and ng-click.
Essentially, in my controller, I have a scoped variable called "aboutOn". When it is true, the modal is displayed. When it's false, it's not. Simple.
The ng-if part works. But the ng-click part is causing trouble. Sometimes, it just doesn't work.
To open the modal I have this:
<div id="about-link-container" ng-click="aboutOn=true">
<p><i class="far fa-info-circle"></i> About</p>
</div>
This does not work how I want it to work. If I click on the actual text, nothing happens. It only triggers when I click around the border, not directly on the link. If I put the ng-click on the p tag, it doesn't work at all.
Then inside the modal, I have this to close it:
<div class="about-close">
<i class="fas fa-times about-close-icon" ng-click="aboutOn=false"></i>
</div>
This doesn't work at all. What's going on here? Here is my controller, if that's possibly related:
angular.module('myApp', [])
.controller('myController', ['$scope', function myController($scope) {
$scope.female_name = "female name";
$scope.position = "position";
$scope.tedious_task = "tedious task";
$scope.dirty_task = "dirty task";
$scope.female_name = "female name";
$scope.celebrity = "celebrity";
$scope.useless_skill = "useless skill";
$scope.aboutOn = false;
}]);
Here is the entire view:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link href="https://fonts.googleapis.com/css?family=Gamja+Flower|Oswald" rel="stylesheet">
<script data-require="angular.js#1.3.10" data-semver="1.3.10" src="https://code.angularjs.org/1.3.10/angular.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>
<script src="main.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body ng-app="myApp">
<div ng-controller='myController'>
<div class="form">
<div id="about-link-container" ng-click="aboutOn=true">
<p><i class="far fa-info-circle"></i> About</p>
</div>
<h1>M<img src="angular-logo.png" class="logo" />DLIBS</h1>
<div class="form-inner">
<h2>Provide the following words:</h2>
<input ng-model="female_name" />
<input ng-model="position" />
<input ng-model="tedious_task" />
<input ng-model="dirty_task" />
<input ng-model="celebrity" />
<input ng-model="female_name" />
<input ng-model="useless_skill" />
</div>
</div>
<div class="display">
<p>{{ female_name }} was a {{ position }}. Although she loved parts of her job,
she absolutely hated {{tedious_task}} and {{dirty_task}}. So, {{female_name}} met
with her life mentor {{celebrity}} who told her to learn how
to {{useless_skill}} at school. Her school didn't offer a
course on {{useless_skill}} so she studied programming instead.
</p>
</div>
<div ng-if="aboutOn" class="about">
<div class="about-main">
<div class="about-close">
<i class="fas fa-times about-close-icon" ng-click="aboutOn=false"></i>
</div>
<h2 class="about-title"><i class="fas fa-info-circle"></i> About</h2>
<p class="about-p">Madlibs is an AngularJS application. When user fill in the words in
the form above, those words will automatically populate the paragraph below.
Try different combinations!
<br />
<br />
This application was made in 2018 by Jack Seabolt. It was constructed using AngularJS.
</p>
</div>
</div>
</div>
</div>
</body>
</html>

There are two problems that give you this issue.
ng-if creates its own scope.
So if you want to reach controller's scope, you need to have ng-click="$parent.aboutOn=false"
FA icons replace DOM (?). You cannot have ng-click on an icon.
Wrap your icon with <div> (as you already do) and put ng-click on it
The code that you need to change, from this:
<div class="about-close">
<i class="fas fa-times about-close-icon" ng-click="aboutOn=false"></i>
</div>
to this:
<div class="about-close" ng-click="$parent.aboutOn=false">
<i class="fas fa-times about-close-icon"></i>
</div>

Related

Disable field.hide in angular formly

The default hide directive with angular-formly is ng-if which can be configured via e.g. the formlyConfigProvider.
Currently all my fields should always be shown and I don't want to have unneccesary ng-if="!field.hide" checks rendered that can inpact the performance.
How can I tell formly not to use this check per field/form or globally?
ng-if add and remove elements from the DOM, when you want to show and hide large number of elements it can be slow, insted you can use ng-show.
ng-show will only change the visibility of the element.
<html lang="en" itemscope="" itemtype="http://schema.org/Article">
<head>
<script>
var oModelesDep = [];
</script>
<!-- Angular Material requires Angular.js Libraries -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="https://s3.amazonaws.com/gowpres/resources/js/utils/jquery-1.10.2.js"></script>
<!-- Angular Material Library -->
<script src="https://www.weldpad.com/starterkit.js?containerId=60515"></script>
<script data-meta="61021" src="https://www.weldpad.com/sogettopanswerers.html?containerId=61021"></script>
</head>
<body ng-controller="AppCtrl" ng-app="MyApp">
<h4 ng-init="showchat = true">Your - Starter Kit</h4>
<button ng-click="showchat = false">hide</button>
<button ng-click="showchat = true">show</button>
{{showchat}}
<sogettopanswerers ng-show="showchat" tag="html">
<div ng-repeat="qdata in listqdata.items track by $index" style="background-color: white;">
<div class="well" style="overflow: auto;">
<h2>
<a href="{{qdata.link}}" class="question-hyperlink">
{{qdata.title}}
</a>
<small>{{qdata.view_count}} Views</small></h2>
<contentashtml ng-init="load()" content="qdata.body">
</contentashtml>
<div style="padding:15px;display: inline-block;vertical-align: top;">
<p>Name: {{qdata.owner.display_name}}</p>
<a href="{{qdata.owner.link}}">
<img ng-src="{{qdata.owner.profile_image}}" alt="Description"/>
</a>
</div>
<div style="display: inline-block;">
<p>Created: <span am-time-ago="qdata.creation_date * 1000"></span></p>
<p>
Last Update:<span am-time-ago="qdata.last_activity_date * 1000"></span>
</p>
<p>
Answered:{{qdata.is_answered}}
</p>
</div>
<p>
Answers:{{qdata.answer_count}}
</p>
</div>
</div>
</sogettopanswerers>
</body>
</html>
Look at the line:
<sogettopanswerers ng-show="showchat" tag="html">
and see how fast the response is.
you set hide-directive="ng-show" in the formly-form
<formly-form hide-directive="ng-show"></formly-form>
"hide-directive
Allows you to control the directive used to hide fields. Common value for this might be ng-show. It will be passed !field.hide. You can also specify this on a global level using formlyConfig.extras.defaultHideDirective = 'ng-show'"
http://docs.angular-formly.com/docs/formly-form
So you can either set it as I instructed or you can choose to edit it in the config on startup for all fields

Angular Material Contact Chips validation ng-minlength/maxlength/required

I've been trying to trigger a validation error on <md-contact-chips> for ng-minlength/maxlength/required but haven't been able to implement this effectively.
Is there a straight forward way to implement this myself? -- it seems for some reason that the contact chips directive in Angular Material does not support these validations.
See codepen here:
http://codepen.io/anon/pen/YqdRNw
<form name='myForm'>
<div ng-controller="ContactChipDemoCtrl as ctrl" layout="column" ng-cloak="" class="chipsdemoContactChips" ng-app="MyApp">
<md-content class="md-padding autocomplete" layout="column">
<md-contact-chips ng-model="ctrl.contacts" ng-minlength='1' ng-required='true' ng-maxlenght='3' name='contacts' md-contacts="ctrl.querySearch($query)" md-contact-name="name" md-contact-image="image" md-contact-email="email" md-require-match="true" md-highlight-flags="i" filter-selected="ctrl.filterSelected" placeholder="To" >
</md-contact-chips>
<p ng-show="myForm.contacts.$error.required" class="text-danger">You did not enter a contact</p>
<p ng-show="myForm.contacts.$error.minlength" class="text-danger">Your contact list is too short</p>
<p ng-show="myForm.contacts.$error.maxlength" class="text-danger">Your contact list is too long</p>
</md-content>
</div>
</form>
You cannot use this attribute directly. you have to use custom validation for it.
<md-contact-chips ng-model="ctrl.contacts" md-transform-chip="customvalidation($chip)"> </md-contact-chips>
<p ng-show="ctrl.contacts.length == 0 && ctrl.contacts.$touched"> Required </p>
<p ng-show="ctrl.contacts.length < 3 && ctrl.contacts.$touched"> Minimum 2 Contacts are required </p>
<p ng-show="ctrl.contacts.length > 5 && ctrl.contacts.$touched"> Maximum 5 Contacts can be added </p>
Inside controller you can define customvalidation function and add extra condition if you want.
function customvalidation(chip){
if(satisifedCondition(chip)){
return null //It will add chip
} else { return undefined } // It will not add chip
}
For the time being, you will need to write your own validation. Currently, md-chips only supports md-max-chips validation. Other forms of validation are currently pending. md-chips api
You can use the chips length property to get the number of chips in the array. With this you can use ng-show on your error messages to perform the necessary validation checks.
Ex: ng-show="myForm.contacts.length == 0"
Additionally, you can use md-on-add or md-on-remove to write your own validation.
Thats the how can I handle required validation with md-chips and md-contact-chips
I don't test code completely but I wrote that for give you an idea. I hope it helps you !
angular.module('MyApp', ['ngMaterial'])
.controller("ContactChipDemoCtrl", ['$scope', function ContactChipDemoCtrl($scope) {
$scope.formRequiredError = {};
$scope.sendButton = function(form) {
$scope.formRequiredError = {
"required": $scope.contacts.length <= 0;
};
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.js"></script>
<html lang="en" ng-app="MyApp">
<head>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
</head>
<body layout="column" ng-controller="ContactChipDemoCtrl as ctrl">
<form name='myForm'>
<div layout="column" ng-cloak="" class="chipsdemoContactChips">
<md-content class="md-padding autocomplete" layout="column">
<md-contact-chips ng-model="ctrl.contacts" ng-minlength='1' ng-required='true' ng-maxlenght='3' name='contacts' md-contacts="ctrl.querySearch($query)" md-contact-name="name" md-contact-image="image" md-contact-email="email" md-require-match="true" md-highlight-flags="i"
filter-selected="ctrl.filterSelected" placeholder="To">
</md-contact-chips>
<p ng-show="myForm.contacts.$error.minlength" class="text-danger">Your contact list is too short</p>
<p ng-show="myForm.contacts.$error.maxlength" class="text-danger">Your contact list is too long</p>
</md-content>
</div>
<div class="custom-error" ng-if="ctrl.contacts.length <= 0">
<div ng-messages="formRequiredError">
<div ng-message="required" translate='form_user_empty'></div>
</div>
</div>
</form>
</body>
</html>
Simple workaround:
<md-contact-chips
ng-class="{'myError': object.fieldName !== undefined && object.fieldName.length == 0}"
ng-model="object.fieldName"
otherStuff></md-contact-chips>
In CSS
.myError input::placeholder {
color: rgb(221,44,0) !important;
}

ng-repeat just doesnt work

<div ng-init="offers = [
{state:'Zabiorę', from:'Warszawa', to:'Wrocław', date:'30/04/16', size:'S:8 M:4 L:2 XL:0'},
{state:'Wyśle', from:'Wrocław', to:'Warszawa', date:'31/04/16', size:'S:0 M:1 L:0 XL:0'}]">
<div ng-repeat="offer in offers">
<hr class="featurette-divider">
<div class="announcement row">
<div class="col-md-1"><strong>{{offer.state}}</strong></div>
<div class="col-md-2">
<img class="img-circle"
src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
alt="Generic placeholder image" width="70" height="70">
</div>
<div class="col-md-1">{{offer.from}}</div>
<div class="col-md-1"><span class="glyphicon glyphicon-arrow-right" aria-hidden="true"></span></div>
<div class="col-md-1">{{offer.to}}</div>
<div class="col-md-2">{{offer.date}}</div>
<div class="col-md-2">{{offer.size}}</div>
<div class="col-md-2">
<button type="button" class="btn btn-primary">Szczegóły</button>
</div>
</div>
</div>
</div> // </div ng-cloak>
Hello, i just wrote some code in my jhipster project, i wrote that in one of my project template and it just doesnt work, it shows nothing. When on jsfiddle.net it works.
#edit
Entire code, controller and state:
- http://pastebin.com/2tkvbiwG - template.html
- http://pastebin.com/kV4E7x0G - state.js
- http://pastebin.com/XF5rBmK7 - controller.js
Your code should work just fine. Please check that you have included angular.js and that you have defined your ng-app and ng-controller
Here is a plunker:
https://plnkr.co/edit/JLIQJQoEM9q4iAztY7KQ?p=preview
EDIT
In controller.js you need to define ui-router like this.
angular
.module('deliveritApp', ['ui.router'])
.controller('SearchOfferController', SearchOfferController);
Also name your function SearchController to function SearchOfferController.
In state.js you need to add the $stateProvider in the config like this:
angular
.module('deliveritApp')
.config(['$stateProvider', stateConfig])

how to add active class in ionic + angular?

could you please tell me how to add active class in selected button .when use select any button from toolbar it become green and show data .Actually I have four button and four div contend .I need to show div contend when I select the button .In other words when I click "A button" it show "A contend ".When I click "B button " it show "b contend " now b button is active rest are inactive .can we do this angular .I tried to do using ng-if but succeed till now
here is my code
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Tabs Example</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body>
</body>
<ion-view ng-controller="showhidecntr">
<ion-header-bar align-title="center" class="bar-balanced">
<div class="buttons">
<a class="button icon-left ion-chevron-left button-clear">Back</a>
<!--i style="font-size:30px;" class='icon ion-chevron-left'></i-->
</div>
<h1 class="title">Title</h1>
</ion-header-bar>
<ion-content>
<div class="button-bar">
<a class="button button-small" ng-click="AbuttonClick">a </a>
<a class="button button-small" ng-click="BbuttonClick">b </a>
<a class="button button-small" ng-click="CbuttonClick">c</a>
<a class="button button-small" ng-click="DbuttonClick">d</a>
</div>
<div class="a_content" ng-if='isShowAcontend'>
a contend
</div>
<div class="b_content" ng-if='isShowBcontend'>
b contend
</div>
<div class="c_content" ng-if='isShowCcontend'>
c contend
</div>
<div class="d_content" ng-if='isShowDcontend'>
d contend
</div>
</ion-content>
</ion-view>
</html>
http://codepen.io/anon/pen/JdErVM
Updated codepen with working example, tweak styles as necessary
http://codepen.io/anon/pen/PqWJrv
This can be done entirely in the html, no controller code necessary (unless you want a default tab, then add $scope.activeButton = 'a'; in controller).
You need to can keep track of a $scope variable and use ng-class
<a ng-click="activeButton = 'a'" ng-class="{ 'active': activeButton === 'a' }>A</a>
<a ng-click="activeButton = 'b'" ng-class="{ 'active': activeButton === 'b' }>B</a>
set that up with each button and ng-class will take care of the rest. The good thing with directives is you can get a lot done just in your html without ever writing code in the controller.
You can do the same with your content areas with the same variable to keep it simple:
<div ng-show="activeButton === 'a'">Content A</div>
<div ng-show="activeButton === 'b'">Content B</div>
One issue is that with ng-click I believe you need to have parens to execute the a controller function. eg:
<a class="button button-small" ng-click="aButtonClick()"> a </a>
Regarding the use of ng-if vs ng-show:
"The ngIf directive removes or recreates a portion of the DOM tree based on an expression."
"The ngShow directive shows or hides the given HTML element based on the expression provided to the ngShow attribute."
<div class="a_content" ng-if='isShowAcontend'>
a contend
</div>
then in your controller:
$scope.aButtonClick = function(){
$scope.isShowAcontend = true;
// you may have to do this as well but I'm sure there is a cleaner way to do it:
$scope.isShowBcontend = false;
$scope.isShowCcontend = false;
}
a better approach would be something like:
<a class="button button-small" ng-click="handleButtonClick('a')"> a </a>
<a class="button button-small" ng-click="handleButtonClick('b')"> b </a>
in your controller:
$scope.handleClick = function(section){
$scope.active_content_area = section;
}
and
<div class="a_content" ng-show='active_content_area == "a"'> a contend </div>
<div class="a_content" ng-show='active_content_area == "b"'> b contend </div>
...
This way you won't have to manage setting the separate variables to false to hide your other divs.

How can I call an angular controller function from my custom polymer web component?

I've seen this question and seen it answered but not in any way I can use or understand. The question is very specific and simple but somehow the answers are a bit over my head.
All I want to do is have a very simple menu work. when i menu item is clicked, I need it to of course use my angular controller function to handle it. I want all of that on the angular side. It actually does work when I simply use the elements directly without declaratively making my own.
So this works just fine and my ng-click is successfuly calling my acceptedSelect() in my controller:
<core-menu>
<div ng-repeat="order in acceptedOrders" ng-click="acceptedSelect(order)">
<paper-item class="my-paper-item" >
<div class="order-list-item">
<div class="order-number">{{order.Order}}</div>
<div class="order-date"> {{order.Date}} </div>
<div style="clear: both"></div>
<div class="order-address">
{{order.Property}}
</div>
</div>
</paper-item>
</div>
</core-menu>
But i do the same thing by wrapping the paper element in a polymer-element, it doesn't work. So this will not work:
<polymer-element name="my-app" attributes="refresh">
<template>
<style>
...
</style>
<core-menu>
<div ng-repeat="order in acceptedOrders" ng-click="acceptedSelect(order)">
<paper-item class="my-paper-item" >
<div class="order-list-item">
<div class="order-number">{{order.Order}}</div>
<div class="order-date"> {{order.Date}} </div>
<div style="clear: both"></div>
<div class="order-address">
{{order.Property}}
</div>
</div>
</paper-item>
</div>
</core-menu>
</template>
<script>
Polymer('my-app', {
});
<my-app></my-app>
I'm just not sure what I can do to make this work. Any help is greatly appreciated.

Resources