Angular UI Bootstrap not working with AngularJS event handling - angularjs

I am new to Angular and have basic problems, getting Angular-UI-Bootstrap to work in combination with AngularJS. Here a simple example, an usual input field that uses ng-change for event handling, and which has a popover. Without the popover attributes, the codes works fine. When the popover attributes are added, the popover is displayed correctly, and looks fine, but the event handler is not called, and also the password model not updated, when the value of the input field changes.
Same problem holds e.g. if I have a button with event handling code and a popover. Same problem also if I do not use popover, but tooltip.
<input type="password" ng-model="password" placeholder="New Password"
ng-change="onPasswordChanged()" popover="I am a popover!"
popover-trigger="mouseenter" />
I am using ui-bootstrap-tpls-0.3.0.js and AngularJS v1.0.7.
Does someone know what the problem is?

Popover directive creates a child scope, so when you bind your model to a primitive, the binding will stay inside that scope (it will not propagate upwards). See "What are the nuances of scope prototypal / prototypical inheritance in AngularJS?" for more info on inheritance.
Workaround is to use a dot notation when referencing your models:
<input type="password" ng-model="data.password" popover="I am a popover!"
popover-trigger="mouseenter" />
DEMO PLUNKER

Related

why ng-change function does not fire in my example

I found some article explaining why ng-change may not fire in a repeat, but I think I tried everything I can do and my ng-change is still not firing.
I made a demo here
<input type="radio" ng-model="select" name="names"
ng-change="$parent.$parent.$parent.noSelected(select)">
I included a model and tried various $parent.$parent but still it wasn't firing.
Can someone tell me what went wrong with my example?
The radio button code you have listed is in a template, that is being consumed by a directive. That directive does not have access to your controller scope, as the scope is isolated deliberately.
You need to look thoroughly at the smart-table documentation to achieve what you are trying to do.

ng-repeat scope and dynamic ng-model

Quick questions. Im generating part of a form dynamically, namely the radio buttons part and I am using an ng-repeat. To do this I have the following code to loop through and list the radio button options:
<div ng-repeat="choice in question.choices">
<input name="{{q.name}}" type="radio" value={{choice.id}} ng-model="choice_[q.answer]" required /> {{choice.choice}}
</div>
I have two issues with this, firstly, im not sure if I am correctly assigning my ng-model dynamically.
Secondly once the model is created it seems to be in its own scope and unusable outside of the repeat due to it being encapsulated within the repeat div.
Is there a way I would be able to access this model? perhaps just passing it through the parent scope using $parent or so?
Any help would be appreciated.
Thanks
I created a plunker to show how to access your model:
Model access demo
<input type="radio" value={{choice.id}} ng-model="$parent.choice" required /> {{choice.choice}}
I used the same model name for every input in the repeat. This way whichever input is selected becomes the active model. That should solve your model naming issue.
Secondly, ng-repeat creates a scope for every template it produces, so you do want to use $parent to access the model on your controllers scope.

NGSwitchery onchange event

I'm working on single-page web app using angularjs.
I'm using NGSwitchery directive for checkbox.
I want to handle an on-change event when user switching the NGSwitchery control.
I tried to attach ng-model and ng-change, but it's not working.
Is there any way?
Following is the code I tried.
Template
<input type="checkbox" id="socialsharing_facebook" class="js-switch" ui-switch ng-model="user.enable_facebook" ng-checked="user.enable_facebook == 1" ng-change="updateUser()" />
updateUser() isn't called, when I change switch.
I haven't used NGSwitchery, but usually you can just watch the model from your controller. The nice thing about that is that if the model changes by some other means, you will be notified of that too. Something like this:
$scope.$watch("user.enable_facebook", $scope.updateUser);

differences between ng-submit and ng-click

In angularjs I'm wondering what the differences are between ng-submit and ng-click? Specifically, pros and cons of each and when should you one or the other? Thanks!
**EDIT**
I've looked in to this a bit more but I'm still wondering what (if any) the benefit is of using ng-submit? Could you use an ng-click in place of all ng-submits? Would this cause any problems? Thanks again!
The ngSubmit directive binds to the submit event in the browser, which is fired when a form is submitted.
From MDN:
Note that submit is fired only on the form element, not the button or submit input. (Forms are submitted, not buttons.)
So you might use it to submit a user sign-up form, or something like that.
On the other hand, the ngClick directive can apply to any kind of element.
From source:
The ngClick directive allows you to specify custom behavior when an
element is clicked.
Use it to allow your user to interact with your page in some way other than submitting a form. Maybe to click on a 'previous' or 'next' pager button, or maybe a map or something.
Angular prevents the default action (form submission to the server) unless the element has action, data-action, or x-action attributes specified.So when using angular with forms without these atributes ng-click and ng-submit can be used to specify which javascript method to call.In either call you can get all input values in a scope because of two-way data binding property of angular.
Could you use an ng-click in place of all ng-submits? Would this cause any problems?
it can be used but when using ng-click it does not take html input attributes (like required,min-max,maxlength) into account and executes method body immediately.
My favorite reason for using ng-submit is that it allows you to press the <Enter> key while focused on a form input etc. and the form will submit. (Assuming of course that you have a button of type="submit" in the form.)
Its more keyboard friendly and accessibility friendly than having ng-click on a button, because with ng-submit, a user can click on the submit button or they can press <Enter>.
If we want the form not to be submitted when it is invalid, then instead of ng-click on the button, we will use ng-submit directive on the form itself
<div class="row">
<form name="adduser" ng-submit="AddUser(adduser.$valid)">
<div id="name-group" class="form-group-lg">
<input type="text"
required
name="name"
ng-model="userfullName"
class="form-control"
placeholder="Full Name">
</div>
In the ng-submit we calling a function AddUser from the controller with a parameter formname.$valid. This submit function will be only called when form is valid or in other words all the user input of the form is valid. Keep in mind that in this case from would not be submitted if form is not valid
When we use ng-click , form will be submitted even if it is invalid. Two observations for ng-click are as follows:
We were able to submit the form even if form was not valid
For the invalid inputs, the value was set to undefined in the controller
ng-submit associated with forms, this event fires when u submit form. Where as ng-click can work without form submit event

AngularJS: How to prevent/delay application of filters to avoid rearrangement of ng-repeat

I've written a directive for a simple sider input.
The fiddle is here: http://plnkr.co/edit/PQXyxfmTbpaQE1ZnkQkq
The problem occurs when you change someone's age enough to change the order. Is there a way to hijack the ng-repeat element's parent scope to not apply filters?
Specifically, can I stop the elements from rearranging while the sliders are being dragged? Like, I would set some flag on the mousedown event which will stop the filtering, and remove that flag on the mouseup event to allow rearranging.
I've looked at the Angular source, and I'm pretty sure this can't be done at the moment, however I also welcome a modification of Angular that might allow this.
Create your own custom filter, and use it instead of orderBy in your view. (However, your custom filter can inject orderByFilter and use it -- see this SO answer for more info on that.)
<li ng-repeat="person in persons | myOrderBy:orderProp:doNotFilter">
Inside your custom filter, check argument doNotFilter, which is a scope property that your directive will set when you mousedown, and clear when you mouseup. If the property is set, don't filter.
You'll have to pass the name of the "don't filter" property to your directives:
<slider min="0" max="100" step="1" ng-model="person.age" do-not-filter="doNotFilter">
An alternative would be to specify one or two controller methods for your directive to call on mousedown and mouseup. Those methods would then affect the doNotFilter scope property.
<slider min="0" max="100" step="1" ng-model="person.age"
filter-stuff="filterStuff(filterState)">

Resources