I m beginner in Angular. I m working on a angular project. I have a input checkbox in my partial source. When it checked a popup should appear, not checked state have a popup.
I found the below code on google and it works separately. But when i put it my partial source it doesn't work.
<div>
<div >
<input type="checkbox" ng-true-value="A" ng-false-value="B" ng-model="check"/>
</div>
<div ng-show="check == 'A'">
Checked
</div>
<div ng-show="check == 'B'">
Unchecked
</div>
Can you anyone help me
Assuming You want to access the parent controller value inside partial which has been loaded using ng-controller directive, In that you need to follow dot rule in your code, As a ng-controller create a new child scope whenever it adds the specified template.
For solving issue you should have your data in object structure in-order to follow prototypal inheritance
Code
$scope.model = {};
Markup
<div>
<div >
<input type="checkbox" ng-true-value="A" ng-false-value="B" ng-model="model.check"/>
</div>
<div ng-show="model.check == 'A'">
Checked
</div>
<div ng-show="model.check == 'B'">
Unchecked
</div>
Other way to do it would be is you can simply use $parent before the check scope variable, that will refer to the parent scope of the controller.
Just replace check with $parent.check everywhere in the view, This will work but the first approach is most preferable.
Add single quotes to 'A' and 'B'
<div >
<input type="checkbox" ng-true-value="'A'" ng-false-value="'B'" ng-model="check"/>
</div>
Related
With Kendo UI component in Angularjs, for example:
<input kendo-date-picker="myDatePicker"
ng-model="dateString"
k-ng-model="dateObject"
style="width: 100%;" />
I am able to access the date picker in javascript with the variable $scope.myDatePicker
Now, the problem is, this date-picker comes with a wrapper with the tag ng-switch-when.
<div ng-switch="userSelection.code">
<div ng-switch-when="JUST_DEMO">
<input kendo-date-picker="myDatePicker"
ng-model="dateString"
k-ng-model="dateObject"
style="width: 100%;" />
</div>
</div>
With this, in the javascript, the variable $scope.myDatePicker becomes 'undefined', even though after the flag JUST_DEMO is turned on subsequently.
So my question is, how to fix this? I need to access $scope.myDatePicker in javascript to manually open the datepicker in the code.
P.S.:
I think I found a working approach: using $compile in the databound event.
i don't see any code for ng-switch , not sure if it's there in your tag :
<div ng-switch="myVar">
ng-switch is evaluated against myVar variable in abve code snippet.
I suggest you use ng-switch as follows :
declare a scope variable with some sort of flag to base your ng-switch on
$scope.datePickerParent = {};// some object
datePickerParent .JUST_DEMO = true/false;
datePickerParent.myDatePicker = ''; //assign some value
<td ng-switch on="datePickerParent.showNgSwitch">
<div ng-switch-when="datePickerParent.JUST_DEMO">
<input kendo-date-picker="datePickerParent.myDatePicker"
ng-model="dateString"
k-ng-model="dateObject"
style="width: 100%;" />
</div>
</td>
Also have a look at this SO post
Also try to use $parent to access scope variable, ng-switch creates it's own scope
I found the solution:
<div ng-switch="userSelection.code">
<div ng-switch-when="JUST_DEMO">
<input kendo-date-picker="myKendo.myDatePicker"
ng-model="dateString"
k-ng-model="dateObject"
style="width: 100%;" />
</div>
</div>
instead of using the normal "myDatePicker" variable, wrap it in another object, such as myKendo.
So, in javascript, this can be accessed with $scope.myKendo.myDatePicker.
JSFiddle here: http://jsfiddle.net/c6tzj6Lf/4/
I am dynamically creating forms and buttons and want to disable the buttons if the required form inputs are not completed.
HTML:
<div ng-app="choicesApp">
<ng-form name="choicesForm" ng-controller="ChoicesCtrl">
<div ng-bind-html="trustCustom()"></div>
<button ng-repeat="button in buttons" ng-disabled="choicesForm.$invalid">
{{button.text}}
</button>
</ng-form>
</div>
JavaScript:
angular.module('choicesApp', ['ngSanitize'])
.controller('ChoicesCtrl', ['$scope', '$sce', function($scope, $sce) {
$scope.custom = "Required Input: <input required type='text'>";
$scope.trustCustom = function() {
return $sce.trustAsHtml($scope.custom);
};
$scope.buttons = [
{text:'Submit 1'},
{text:'Submit 2'}];
}]);
choicesForm.$invalid is false and does not change when entering text into the input field.
Solution:
I ended up using the angular-bind-html-compile directive from here: https://github.com/incuna/angular-bind-html-compile
Here is the relevant bit of working code:
<ng-form name="choicesForm">
<div ng-if="choices" bind-html-compile="choices"></div>
<button ng-click="submitForm()" ng-disabled="choicesForm.$invalid">
Submit
</button>
</ng-form>
And choices might be a snippit of HTML like this:
<div><strong>What is your sex?</strong></div>
<div>
<input type="radio" name="gender" ng-model="gender" value="female" required>
<label for="female"> Female</label><br>
<input type="radio" name="gender" ng-model="gender" value="male" required>
<label for="male"> Male</label>
</div>
The main problem is that ngBindHtml doesn't compile the html - it inserts the html as it is. You can even inspect the dynamic input and see that it doesn't have the ngModel's CSS classes (ng-pristine, ng-untouched, etc) which is a major red flag.
In your case, the form simply doesn't know that you've added another input or anything has changed for that matter. Its state ($pristine, $valid, etc) isn't determined by its HTML but by the registered NgModelControllers. These controllers are added automatically when an ngModel is linked.
For example this <input required type='text'> won't affect the form's validity, even if it's required, since it doesn't have ngModel assigned to it.
But this <div ng-model="myDiv" required></div> will affect it since it's required and has ngModel assigned to it.
The ngDisabled directive on your buttons works as expected since it depends on the form's $invalid property.
See this fiddle which showcases how ngModel registers its controller. Note that the html containing the dynamic input gets compiled after 750ms just to show how NgModelControllers can be added after FormController has been instantiated.
There are a few solutions in your case:
use a custom directive to bind and compile html - like this one
use ngInclude which does compile the html
use $compile to compile the newly added HTML but this is a bit tricky as you won't know exactly when to perform this action
This is an answer yet imcomplete because i cannot do the code at the moment.
I think your html will be included, not compiled. So the inputs are not bind to angular and are not part of the angular form object.
The only way i see is to use a directive that will compile the passed html and add it to your form. This may be quite tricky though, if you want to go on this way i suggest to edit your question to ask for the said directive.
However i'm not really familiar with $compile so i don't know if it'll work to just add $compile around $sce.trustAsHtml()
You can write a method as ng-disabled does not work with booleans, it works with 'checked' string instead:
So on your controller place a method :
$scope.buttonDisabled = function(invalid){
return invalid ? "checked" : "";
};
And on your view use it on angular expression :
<button ng-repeat="button in buttons" ng-disabled="buttonDisabled(choicesForm.$invalid)">
Here is a working fiddle
Working DEMO
This is the solution you are looking for. You need a custom directive. In my example I have used a directive named compile-template and incorporated it in div element.
<div ng-bind-html="trustCustom()" compile-template></div>
Directive Code:
.directive('compileTemplate', function($compile, $parse){
return {
link: function(scope, element, attr){
var parsed = $parse(attr.ngBindHtml);
function getStringValue() { return (parsed(scope) || '').toString(); }
//Recompile if the template changes
scope.$watch(getStringValue, function() {
$compile(element, null, -9999)(scope); //The -9999 makes it skip directives so that we do not recompile ourselves
});
}
}
});
I found the directive in this fiddle.
I believe what is really happening though due to jsfiddle I'm unable to dissect the actual scopes being created here.
<div ng-app="choicesApp">
<ng-form name="choicesForm" ng-controller="ChoicesCtrl">
<div ng-bind-html="trustCustom()"></div>
<button ng-repeat="button in buttons" ng-disabled="choicesForm.$invalid">
{{button.text}}
</button>
</ng-form>
</div>
The first div is your top level scope, your form is the first child scope. Adding the div using a function creates the dynamically added input field as a child of the first child, a grandchild of the top level scope. Therefore your form is not aware of the elements you're adding dynamically causing only the static field to be required for valid form entry.
A better solution would be to use ng-inclue for additional form fields or if your form isn't to large then simply put them on the page or template you're using.
I have an Angular form that is parsing some JSON data.
I'm rendering using ng-repeat. However, I'm having an issue in that the form never becomes valid when a radio button in each group is selected.
I suspect the issue lies with the ng-model in each input, but I can't seem to figure out the correct way to dynamically create an ng-model inside an ng-repeat.
Form block code:
<form name="posttestForm">
<alert ng-repeat="alert in alerts"
type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</alert>
<div class="well question-well" ng-repeat="question in questions">
<p>
<strong>{{question.question}}</strong>
</p>
<ul>
<li ng-repeat="answers in question.answers">
<input ng-model="Q[question.id]"
type="radio" name="Q{{question.id}}" value="{{answers.id}}"
required="" data-key="{{answers.isCorrect}}" />{{answers.answer}}
</li>
</ul>
</div>
<button type="submit" class="btn btn-primary" ng-click="EvaluatePosttest(3)"
ng-show="!TestPassed">
Submit Questions</button>
</form>
Here's a Plunkr that shows the dynamic code and demonstrates the form never turning valid when a radio button in each group is selected.
http://plnkr.co/edit/HQGPIOCdn3TGlE96CpK5?p=preview
And here's a Plunkr using static content displaying it working.
http://plnkr.co/edit/ZFt2VnBfaQjuu73kaNQJ?p=preview
Just add this in your javascript controller
$scope.Q = [undefined,undefined,undefined,undefined,undefined,undefined];
Explanation : you set ng-model as Q[question.id] but Q is undefined so the ng-model won't ever work. You always must initialize variable in the controller. The only case it works not initialize is when you do :
ng-model="test"
if you do
ng-model="test.test"
ng-model="test[0]"
It won't ever work if it's not initialized properly.
You can do a custom form validation inside your controller. In your case:
$scope.Q = [];
$scope.$watch('Q', function (Q) {
$scope.posttestForm.$setValidity('count', Q.length >= $scope.questions.length);
}, true);
Inside that, you can do whatever validation you want.
Here's the working plunkr: http://plnkr.co/edit/7Ww4fjJzkDjifPaZ2QtG?p=preview
In my application I have a custom directive with select tag.
<div class="row pv10" ng-if="item.visible">
<div class="col-xs-4 text-danger"><span ng-if="item.label_visible"> {{item.label}}</span></div>
<div class="col-xs-8">
<div class="row">
<div class="col-xs-1">
<select ng-options="oneItem for oneItem in item.options" ng-model="selectedItem" ng-change="changeEvent()">
{{selectedItem | json}}
</select>
</div>
</div>
</div>
</div>
I would like to perform an action on every change event. I thought of using ng-change, which btw. worked just fine with radioBtn/checkBox. I tried two approaches here.
Firstly I tried to pass "changeEvent" function to the directive's isolated scope.
<custom-select item='item' change-event="change()" ng-if="item.component == 'select'" />
changeEvent() function exists in current controller (attached to the view holding custom-select)
scope: {
item: "=",
changeEvent: "&"
}
Sadly expression does not evaluate on change.
Secondly I tried to attach the function directly to directive
link: function ($scope, elems, attrs) {
$scope.changeEvent = function () {
alert("Change Event!");
}
}
but it didn't work either.
I read somewhere that ng-change even used within a custom directive operates on a controllers scope, not isolated scope of directive. However am not quite sure about that.
I'd really appreciate your help.
EDIT!
This is a JSFiddle to the directive I use. If I should provide more details, just let me know, this is the first time I've ever used jsfiddle.
This is how the directive is invoked:
<div class="row" ng-repeat="item in jsonData">
<div class="col-xs-12">
<cbp-select item='item' change="change()" ng-if="item.component == 'select'" />
</div>
</div>
https://jsfiddle.net/60nsfg0L/
EDIT2
When I have uploaded my solution to our local server it started to work properly.(Yes, I cleaned browser's cash, and my locals wamp/iss cache too).
But now I have a different problem.
I have a form built from different directives(like the one above), all have ng-click/change/blur. Everything seems to work fine until I change one of the options in my "select" directive. After selecting one of the values, ng-change expression is triggered (for not its just a simple alert) and from that moment onwards am not able to focus on any other elements. Weirdly enough, if I cause ng-change to trigger on any other element be it radiobtn or checkbox this problem does not occur.
I can not get value of input wrapped by ng-if
this is html code
<div ng-controller="Home">
<form ng-submit="startChat(visitor)" >
<div class="lkv_getting">
<div ng-if="formsetting.name == true">
<input required ng-class="lkv_name_class" ng-model="visitor.name" id="lkv_name" name="lkv_name" type="text" class="lkv_input" placeholder="Nhập họ tên" />
</div>
<textarea required maxlength="100" placeholder="Gõ tin nhắn!!" ng-model="visitor.msg" id="message_input" name="lkv_message_input"></textarea>
<button class="lkv_button" type="submit" id="lkv_start" title="Message">Bắt đầu</button>
</div>
</form>
</div>
and controller
$scope.startChat = function (visitor) {
var user = visitor.name; // the value is undefine
var msg = visitor.msg; // but this one has value
};
Any one can help me? Thanks in advance
When using ng-if the DOM elements won't get rendered if formsetting.name ever equals false. That means you won't be able to get your input values back since they won't be rendered to the DOM. Check to see that formsetting.name is indeed true or initialized to true in your controller if that makes sense for you. If formsetting.name can change values you probably want to use ng-show instead. Using ng-show draws the elements to the DOM but hides them so you can still access them.