appear an html element by clicking on a button with angularjs - html

I have an html form ( ) , I want that it is displayed when I click on a button.
the declaration of the form is the following :
<div id = "formulaire" class="gl" >
and the button is :
Edit
I use angularjs in my code . Please help me.

It better to use a simple variable than a function in this case. I would also recommend using controller scope when setting variables instead of the application scope so you don't run into issues with the variables when your application becomes large.
I also picked data-ng-click over ng-click because it will allow the html to validate correctly (which can be checked using the W3's validator).
Try this...
"use strict";
angular.module('myApp', [])
.controller("myController", function() {
this.edit = false;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<div data-ng-app="myApp" data-ng-controller="myController as ctrl">
Edit
<div id="formulaire" class="gl" data-ng-show="ctrl.edit">
<form>
<fieldset>
<label>Field:</label>
<input type="text" />
</fieldset>
</form>
</div>
</div>

Have you looked into the ngShow directive? It ables you to show or hide a DOM element depending on whether the attribute expression resolves to a truthey or falsey value.

Add model change on click
Edit
And then display the form if model is true
<div id = "formulaire" class="gl" ng-if="show">

Related

.val() returns empry strings when i try to fetch value of input in modal [duplicate]

I have a form in Angular that has two buttons tags in it. One button submits the form on ng-click. The other button is purely for navigation using ng-click. However, when this second button is clicked, AngularJS is causing a page refresh which triggers a 404. I’ve dropped a breakpoint in the function and it is triggering my function. If I do any of the following, it stops:
If I remove the ng-click, the button doesn’t cause a page refresh.
If I comment out the code in the function, it doesn’t cause a page refresh.
If I change the button tag to an anchor tag (<a>) with href="", then it doesn’t cause a refresh.
The latter seems like the simplest workaround, but why is AngularJS even running any code after my function that causes the page to reload? Seems like a bug.
Here is the form:
<form class="form-horizontal" name="myProfile" ng-switch-when="profile">
<fieldset>
<div class="control-group">
<label class="control-label" for="passwordButton">Password</label>
<div class="controls">
<button id="passwordButton" class="secondaryButton" ng-click="showChangePassword()">Change</button>
</div>
</div>
<div class="buttonBar">
<button id="saveProfileButton" class="primaryButton" ng-click="saveUser()">Save</button>
</div>
</fieldset>
</form>
Here is the controller method:
$scope.showChangePassword = function() {
$scope.selectedLink = "changePassword";
};
If you have a look at the W3C specification, it would seem like the obvious thing to try is to mark your button elements with type='button' when you don't want them to submit.
The thing to note in particular is where it says
A button element with no type attribute specified represents the same thing as a button element with its type attribute set to "submit"
You can try to prevent default handler:
html:
<button ng-click="saveUser($event)">
js:
$scope.saveUser = function (event) {
event.preventDefault();
// your code
}
You should declare the attribute ng-submit={expression} in your <form> tag.
From the ngSubmit docs
http://docs.angularjs.org/api/ng.directive:ngSubmit
Enables binding angular expressions to onsubmit events.
Additionally it prevents the default action (which for form means sending the request to the server and reloading the current page).
I use directive to prevent default behaviour:
module.directive('preventDefault', function() {
return function(scope, element, attrs) {
angular.element(element).bind('click', function(event) {
event.preventDefault();
event.stopPropagation();
});
}
});
And then, in html:
<button class="secondaryButton" prevent-default>Secondary action</button>
This directive can also be used with <a> and all other tags
You can keep <button type="submit">, but must remove the attribute action="" of <form>.
I wonder why nobody proposed the possibly simplest solution:
don't use a <form>
A <whatever ng-form> does IMHO a better job and without an HTML form, there's nothing to be submitted by the browser itself. Which is exactly the right behavior when using angular.
Add action to your form.
<form action="#">
This answer may not be directly related to the question. It's just for the case when you submit the form using scripts.
According to ng-submit code
var handleFormSubmission = function(event) {
scope.$apply(function() {
controller.$commitViewValue();
controller.$setSubmitted();
});
event.preventDefault();
};
formElement[0].addEventListener('submit', handleFormSubmission);
It adds submit event listener on the form.
But submit event handler wouldn't be called when submit is initiated by calling form.submit(). In this case, ng-submit will not prevent the default action, you have to call preventDefault yourself in ng-submit handler;
To provide a reasonably definitive answer, the HTML Form Submission Algorithm item 5 states that a form only dispatches a submit event if it was not submitted by calling the submit method (which means it only dispatches a submit event if submitted by a button or other implicit method, e.g. pressing enter while focus is on an input type text element).
See Form submitted using submit() from a link cannot be caught by onsubmit handler
I also had the same problem, but gladelly I fixed this by changing the type like from type="submit" to type="button" and it worked.
First Button submits the form and second does not
<body>
<form ng-app="myApp" ng-controller="myCtrl" ng-submit="Sub()">
<div>
S:<input type="text" ng-model="v"><br>
<br>
<button>Submit</button>
//Dont Submit
<button type='button' ng-click="Dont()">Dont Submit</button>
</div>
</form>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Sub=function()
{
alert('Inside Submit');
}
$scope.Dont=function()
{
$scope.v=0;
}
});
</script>
</body>
Just add the FormsModule in the imports array of app.module.ts file,
and add import { FormsModule } from '#angular/forms'; at the top of this file...this will work.

Event for input type=number

I am a bit new to Angularjs. In Chrome, for number type input fields, pressing on up and down key arrow increases/decreases the entered value. It needs to be disabled. Any ideas or help in how it can be done?
I tried using jQuery: $(":input").bind('keyup mouseup', function () but the ng-model binding is not updating. Might be because the angular js doesn't recognize the change made with jQuery.
Model won't change inside jquery event.Use ng-keypress event in angularjs
If you need to disable it permanently better do it another way, use regular text input but restrict other chars than numbers.
<input type="text" ng-pattern="/^[0-9]*$/" />
Check out ngPattern docs
You can use ng-model directive to access the value of input in controller, and ng-disabled directive to control an input state. Hopefully the following demo may be of some help:
var app = angular.module('demo', []);
app.controller('DemoCtrl', function($scope) {
$scope.myNumber = 0;
$scope.isDisabled = false;
$scope.toggle = function() {
$scope.isDisabled = !$scope.isDisabled;
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="DemoCtrl">
<input type="number" ng-model="myNumber" ng-disabled="isDisabled"/>
<button ng-click="toggle()">Disable/Enable</button>
</div>
</div>

AngularJS ng-modal do not return latest value from form input

I am still new towards AngularJS, I made a simple textarea to handle user input using angular model binding like below code (noted that my ng-app and ng-controller are being injected somewhere else but it is within the entire <div></div>):
HTML:
<div ng-controller="StatusCtrl">
//some other HTML
<div class="sPTabs-holder">
<tabset>
<tab heading="Status">
<div>
<form class="statusPost" enctype="multipart/form-data">
<div class="form-group no-margin">
<div class="col-md-12 col-sm-12 no-pad">
<textarea type="text" ng-model="inputStatus" class="statusPostBox" placeholder="what's new on your mind?"></textarea>
</div>
</div>
<div class="form-group no-margin">
<div class="col-md-12 col-sm-12 no-pad">
<button style="width: 12%;" ng-click="postStatus()" class="btn btn-primary btn-sm" type="button">Share</button>
</div>
</div>
</form>
</div>
</tab>
<tab heading="Image">Image</tab>
</tabset>
</div>
</div>
JS:
'use strict';
var Status = angular.module('Status',['ui.bootstrap','ngResource','ngSanitize'])
Status.controller('StatusCtrl', ['StatusService','$resource','$scope','$http', '$timeout', '$sce',
function StatusCtrl(StatusService, $resource, $scope, $http, $timeout, $sce) {
//Usable models
$scope.inputStatus;
//Html-bind
$scope.makeTrust = function(html){
return $sce.trustAsHtml(html);
}
$scope.postStatus = function(){
if ($scope.inputStatus == null){
console.log('Blank post alert');
alert('You cannot post with blank statuses!');
}else{
console.log($scope.inputStatus);
}
}
}]);
My problem is whenever I click on the submit button angular will always pop me with the empty input error even though I have input in the textarea. At first I thought that I made a mistake in my model binding so I have tried out to echo the value in html using {{inputStatus}}, things appeared as it was typed and also when I try to define a default value in $scope.inputStatus = 'default value', the console does indeed echoed 'default value', but the problem is it doesn't store anything that is being typed in the form. What have i done wrong in my code?
Noted that I am not so familiar on how to setup AngularJS in JSFiddle. I apologize in advance if you would like to see the working demo.
**Update 1 - I have narrow down the problem, apparently the problem only occur when I am using angular tabs by Angular Bootstrap. So what happen is if you revise the HTML code, there is this <tabset> section. When declaring the ng-controller after the <tabset> section and everything works like a charm but if you declare it before the <tabset> section, that is where everything mess up.
You should initialize $scope.inputStatus in your controller, otherwise it will pop out an alert windows if you haven't input anything in the textarea (which will initialize or update $scope.inputStatus).
So you change your controller to
$scope.inputStatus = "";
Then everything will work, here is a working demo.
update
If you are using <tabset>, then you are facing child scope problem. <tabset> will create a child scope inside your controller, which means, the scope bind to tabset is the child of scope bind to StatusCtrl.
There are two ways to fix this problem. The first one is accessing the parent scope directly by changing your ngModel to below
<textarea type="text" ng-model="$parent.inputStatus" class="statusPostBox" placeholder="what's new on your mind?"></textarea>
The second one is easier but may looks like a trick, use Dot notation like #lcycook mentioned. In your controller StatusCtrl, declare a dictionary called data
$scope.data = {
inputStatus: ""
};
Then you can access the inputStatus by data.inputStatus anywhere inside the controller scope and you don't need to care about the child scope.
While there is no direct evidence, I suspect your text area is masked inside a child scope. This is common for new AngularJS developers.
While you are learning which directive creates a child scope (e.g. ng-if, ng-repeat), you can avoid this problem with "Dot notation". Which is, wrapping the model inside an object.
You can do this by initializing your ng-model or at least the wrapper object in your controller.
$scope.data = {};
// OR
$scope.data = {inputStatus=''};
Then in your template
<textarea type="text" ng-model="data.inputStatus" class="statusPostBox" placeholder="what's new on your mind?"></textarea>
Process it in your controller by referring it as $scope.data.inputStatus.
Some people even argue you are doing it wrong if you don't do this for any ng-model, but I find thinking wrapper object name is hard so I still use "dotless" one if I know the there is no child scope.

Empty action attribute on a form with angularJS

I'm trying to submit a form the normal way in a AngularJS application but I encounter an issue : it seems that I must specify the action attribute.
According to the HTML specifications (http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#form-submission-algorithm) :
If action is the empty string, let action be the document's address of
the form document.
But AngularJS refuses to submit the form if the action attribute is not filled.
A work-around I found would be to use action="#" but this is not an acceptable solution since I might use the hash and I don't want it to be rewritten.
Has anyone ever experienced this issue ?
Edit : I don't want to use angular for this form, I just want to submit it the "old" way
I created a small directive to solve this:
.directive('form', ['$location', function($location) {
return {
restrict:'E',
priority: 999,
compile: function() {
return {
pre: function(scope, element, attrs){
if (attrs.noaction === '') return;
if (attrs.action === undefined || attrs.action === ''){
attrs.action = $location.absUrl();
}
}
}
}
}
}]);
Seems to be good for me. It looks for a form where the action is empty, and sets it to the current url.
Actually, it doesn't set the action - it sets the attr value, so the actual form directive thinks it's got one.
Update by #Reimund is good - I have actually had to do the same.
New Update - I have added the option to add a noaction attribute to the form element; this enables you to return to a "normal" angular situation. Otherwise this directive will submit forms twice if using ajax.
In the library, you can see that Angular listens to the event submit of your forms without action : https://github.com/angular/angular.js/blob/b9fa5c5a6781f4e1ec337f27d55c69db491a6555/src/ng/directive/form.js#L331
You can comment this line, it works, but I'm against editing the code of libraries.
Few lines after, you can see that Angular listening to the event $destroy enabling to remove the action on this event.
Therefore, to avoid modifying Angular, you can just trigger this event of your form:
angular.element(document).ready(function(){
angular.element(document.querySelector("#loginForm")).triggerHandler("$destroy")‌​;
});
The reason of this behavior is described few lines above:
we can't use jq events because if a form is destroyed during submission the default action is not prevented.
And the related issue is: https://github.com/angular/angular.js/issues/1238
You can use ng-submit.
Form
<form name="test" action="" ng-submit="submit()">
What's your name? <input ng-model="name" /><br />
<button>Send</button>
</form>
<br />
My name is: {{name}}
JS
var app = angular.module('App', []);
app.controller('AppCtrl', function($scope) {
$scope.submit = function() {
$scope.name = $scope.name + ' Doe';
}
});
Plunker http://plnkr.co/edit/rqAwxWmozrzwwj4oAU5k?p=preview
Normally I simply make button with ng-click handler.
<button ng-click="Generate()">Submit</button><br>

Can div with contenteditable=true be passed through form?

Can <div contenteditable="true">Some Text</div> be used instead of texarea and then passed trough form somehow?
Ideally without JS
Using HTML5, how do I use contenteditable fields in a form submission?
Content Editable does not work as a form element. Only javascript can allow it to work.
EDIT: In response to your comment... This should work.
<script>
function getContent(){
document.getElementById("my-textarea").value = document.getElementById("my-content").innerHTML;
}
</script>
<div id="my-content" contenteditable="true">Some Text</div>
<form action="some-page.php" onsubmit="return getContent()">
<textarea id="my-textarea" style="display:none"></textarea>
<input type="submit" />
</form>
I have tested and verified that this does work in FF and IE9.
You could better use:
<script>
function getContent(){
document.getElementById("my-textarea").value = document.getElementById("my-content").innerText;
}
</script>
NOTE: I changed innerHTML to innerText. This way you don't get HTML elements and text but only text.
Example: I submited "text", innerHTML gives the value: "\r\n text". It filters out "text" but it's longer then 4 characters.
innerText gives the value "text".
This is useful if you want to count the characters.
Try out this
document.getElementById('formtextarea').value=document.getElementById('editable_div').innerHTML;
a full example:-
<script>
function getContent() {
var div_val = document.getElementById("editablediv").innerHTML;
document.getElementById("formtextarea").value = div_val;
if (div_val == '') {
//alert("option alert or show error message")
return false;
//empty form will not be submitted. You can also alert this message like this.
}
}
</script>
`
<div id="editablediv" contenteditable="true">
Some Text</div>
<form id="form" action="action.php" onsubmit="return getContent()">
<textarea id="formtextarea" style="display:none"></textarea>
<input type="submit" />
</form>
`
Instead of this, you can use JQuery (if there is boundation to use JQuery for auto-resizing textarea or any WYSIWYG text editor)
Without JS it doesn't seem possible unfortunately.
If anyone is interested I patched up a solution with VueJS for a similar problem. In my case I have:
<h2 #focusout="updateMainMessage" v-html="mainMessage" contenteditable="true"></h2>
<textarea class="d-none" name="gift[main_message]" :value="mainMessage"></textarea>
In "data" you can set a default value for mainMessage, and in methods I have:
methods: {
updateMainMessage: function(e) {
this.mainMessage = e.target.innerText;
}
}
"d-none" is a Boostrap 4 class for display none.
Simple as that, and then you can get the value of the contenteditable field inside "gift[main_message]" during a normal form submit for example. I'm not interested in formatting, therefore "innerText" works better than "innerHTML" for me.