angularjs scope for ngModel is not working as expected - javascript

I have created custom directive drop down in angularjs and ionic-framework. In my dropdown items will open in modal popup which is working very good.
But I have kept search input box with clear button input box which is tide up with ng-model='search' and on button ng-click if I put ng-click="search=''" than it will work very good but if I put function and try to delete from directive module than it will not work
In template
<input type="search" ng-model="search" placeholder="select city...">
<button ng-show="search.length" ng-click="clearSearch()" class="customIcon button button-icon ion-close-circled input-button"></button>
In directive module
$scope.clearSearch = function() {
$scope.search = '';
}
then it will give me error
$scope.search is undefined
I am just very much confuse with $scope thing I also want to know how can i know scope any tool or something
I have also another issue that I kept two custom directive on the same and when first control change its value I want to clear the selection in second directive for that I am doing $watch also but I don't understand How can I do
My plunkr
http://plnkr.co/edit/GxM78QRwSjTrsX1SCxF7?p=preview

I have no experience with Ionic, but these types of issues are usually related to how prototypal inheritance works in JS and AngularJS.
A great explanation on prototypal inheritance in relation to Angular can be found here.
The issue can usually be solved by moving the property into an object:
$scope.viewModel = {};
$scope.clearSearch = function() {
$scope.viewModel.search = '';
};
And then use viewModel.search in your HTML where you need it:
<input type="search" ng-model="viewModel.search" placeholder="select city...">
Demo: http://plnkr.co/edit/4SLfA1CjRWB1XazIhj9d?p=info

Related

AngularJS - how to add dynamic ng-model

I'm working with a form and would like to add ng-model on dynamic input elements. I have a scope variable defined as:
$scope.formData = {};
On the page there are a couple of drop-down lists that users can choose an option from and based on those options we are appending some input fields to form body.
formBody.append('<input ng-model="formData.'+obj.Title+'" type="number"></input></br>');
This is not working for me because I'm assuming once the controller runs it can't register any new ng-model. Is there way to add dynamic ng-model or there is a different approach to what I'm trying to do (i.e. build predefined views that can be loaded on the page)?
EDIT:
I have created a jsfiddle that outlines what I'm trying to do - http://jsfiddle.net/k5u64yk1/
If you need to dynamically add html with dynamic bindings that cannot be encapsulated into ng-repeat, ng-if, etc, you have to call $compile on the template once it has been modified to alert AngularJS that it has to reparse the template and initiate a new digest cycle. This will pick up any new ng-model bindings and appropriately tie them to your scope.
HTML:
<div ng-app="MyApp" ng-controller="MyCntrl">
<button ng-click="addInput()">Add Input</button>
<div id="form">
input would go here.
</div>
</div>
JS:
By placing your add input inside of a click event, you avoid an infinite compile loop. Note that this currently resets the state of your form, so if you wanted to work around that you'd need to capture your form state and restore it after compile.
$scope.addInput = function () {
var aForm = (angular.element(document.getElementById('form')));
if ($scope.data["Digital Conversation"][0].MetricType.Title === "Number") {
aForm.append(
'<input ng-model="formData.' +
$scope.data["Digital Conversation"][0].Title.Title +
'" type="number"></input>');
}
$compile(aForm)($scope);
}
You can find the working jsfiddle here: http://jsfiddle.net/k5u64yk1/

ng-model inside radio input refresh

I'm using a jQuery library of radio/checkbox components (yeah, I know using jQuery is bad with angular, but that was not my choice to use that library and I cannot change that) and I got a problem with refreshing ng-model data (radio component in library does a simple click trigger event when radio value change).
I noticed, that while one click trigger does nothing to model, triggering it twice solves the problem (but that is not the way I would like to solve this problem). I prepared a simple fiddle- a little example of what is my problem. First click (executing changeInput(1, 1) in the code below) on a button does a change in DOM, but does nothing to angular model - while clicking just on the radio button is doing just fine. Executing changeInput(1,2) does exacly the same as clicking the radio element.
function changeInput(obj, num){
for(var i = 0; i < num; i++){
$('input').eq(obj).click();
}
}
What else can I do? While reading stackoverflow I have noticed that people say that triggering 'input' solves the problem - but not in that case (JSFiddle). Is triggering click twice is the only way to solve this problem?
In Angular things don't work the way you might be used to. Once you get used to it, you will enjoy the much more straightforward and declarative nature of you code.
You said:
"in this question I would like only to know how to make model changes"
Nevertheless, in your attempts your are trying to make model changes by changing the view (programmatically). This is both unintuitive and a nightmare in terms of maintainability.
In Angular you should worry about your data (model) and watch the views adapt automagically.
So, if you want to make model changes, then all you need to do is to...well, change the model:
<input type="radio" name='test' ng-model="value" value="0" />
<input type="radio" name='test' ng-model="value" value="1" />
<button ng-click="changeInput(0)">Change value to 0</button><br/>
<button ng-click="changeInput(1)">Change value to 1</button><br/>
function Ctrl($scope) {
$scope.value = 0;
$scope.changeInput = function (newValue) {
$scope.value = newValue;
}
}
In order for Angular to do its magic and update the view you need to perform the action within the Angular context (ng-click instead of onclick takes care of that). If for whatever reason you can't use ng-click, you need to let Angular know something changed by wrapping your code in the changeInput() function in $scope.apply().
See, also, this short demo.
I had a similar issue once using only angular. The ng-binding of your input must be a property of an object defined in your controller. I think that otherwise, the input value is binded to a variable defined in the input own scope.
That wouldn't work :
<input type="checkbox" ng-model="selected"></input>
But that would :
<input type="checkbox" ng-model="someObject.selected"></input>
with for example in you controller :
$scope.someObject = {
selected: false
};

inline editing in angularjs save item

I try to avoid any directive as I want to learn more, but I can't get it working on the save part.
partially working code here : http://jsfiddle.net/U3pVM/3789/
is it good to avoid using $index? because I use a lots of this
$scope.saveEditedTask = function(i){
this.editable = false;
}
change text field to
<input ng-show="editable" type="text" ng-model="task.name"/>
Plunker
You were not using the angular directive ng-model which bi-directionally binds the field to object.

How to create an AngularJS directive that binds to a variable?

I want to build a directive for showing datepicker textboxes, i.e regular textboxes which have JQuery UI's datepicker used on them, so when the user clicks them, a datepicker box opens to let them pick the date, etc.
I want to bind this directive somehow to a property on my scope. E.g if it were a normal textbox and I did ng-model='myDate' then $scope.myDate would be updated if the user typed in a new date. In the same way, I want to bind this field from the directive so when the user picks a date, it updates the scope property its bound to.
The problem is, I want to display the directive using something like this:
<datepicker name='something' value='2013-07-20' model='myProperty' />
And have the directive replace it with the <input type="text" /> etc. So I can't use ng-model.
How else can I bind the model property to the directive so that it updates whenever the user changes it?
See if this is what you want:
HTML
<div ng-app="app" ng-controller="Ctrl">
<foo model="property"></foo>
<input type="text" ng-model="property">
</div>
Javascript
angular.module('app', [])
.directive('foo', function() {
return {
restrict: 'E',
replace: true,
scope: { model: '=' },
template: '<input type="text" ng-model="model">'
};
})
.controller('Ctrl', function($scope) {
$scope.property = 'Foobar';
});
jsFiddle
In order to use ng-model instead of model, you'll need to wrap the input in a container tag. Here's another jsFiddle script that illustrates it.
Finally, there's a date picker control in Angular UI Bootstrap. Perhaps it already does what you need.

Angular ng-model bound from nested ng-repeat

This must have been already done, and I am missing something about how Angular works on that point.
In short, I have <select ng-model><option ng-repeat/></select> and I don't know how to give it a default value at page load.
View:
<div ng-ctrl="MyCtrl">
<form ng-submit="submitChoice()">
<select ng-model='choice'>
<option ng-repeat='choice in choices' value='{{choice.id}}'>{{choice.id}}</option>
</select>
</form>
</div>
Way 1: When user updates the view (select the 'choice' he wants), the $scope used in MyCtrl gets it and I can perform whatever I want with it:
Way 2: But if, the other way round, I want to programmatically set the default value for the choices from the controller (at start), it can't change the value displayed:
function MyCtrl ($scope) {
$scope.submitChoice = function() {return;}; // Way1: OK!
$scope.choice = choice4; // Way2: Doesn't change the view!!
}
I guess it's because each element in ng-repeat has its own scope (fyi if I hardcode options in view instead of a ng-repeat, it works well).
In way 1 the inner scope selected by the use emits choice to the upper scope, if I understand well. But I have no idea how to do way 2.
Is it doable in a simple way? Is a directive necessary?
You would be better off using the ng-options directive with the select directive. Using select + ngRepeat has all sort of limitations and is better avoided. Is there any particular reason for generating options with ngRepeat?
If you could share more code (especially the structure of your data model) I might be able to provide more info.

Categories