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
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
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;
}
<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])
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.
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.