Update $scope from external javascript plugin - angularjs

I have a javascript plugin that convert persian date . everything works well except one thing .
I've added a default value for input like : $scope.myDate='13930101' ;
But i'd like to update it when user click on new date . How can i update the $scope ? should i create a directive for that ?
Thanks
Plunker

This is the really nice thing about Angular, you don't have to watch simple variables to update them in the $scope. Take out ng-change="newDate()" on your date field. When you use ng-model on an input field, any changes made to that input field will be reflected in the variable you set it to.
The other thing you can do is move your onClick function into the angular ng-click function you created:
$scope.showDate = function() {
// alert($scope.myDate);
PersianDatePicker.Show('thisDate', $scope.myDate);
};
That will grab the current value of $scope.myDate and pass it into the plugin:
Plunker

Related

Angular form to pristine when for is in original state

I have a form with preset values from an object in scope. When I modify a form field for instance the name field and change it from Bob to Bobby the form is now dirty but if I delete the "y" and the "b" from the end of the name the form is now in its original state but it is still dirty. How do I get it to return to pristine when the form is the same as when it started out? I have the original state saved in scope so they can be compared but I am not connecting the dots on how to achieve this.
Here is an example that shows the same behavior I was describing above:
http://www.angularjshub.com/examples/forms/formreset/
Try something like the below in your controller, and then use the ng-change to call the function.
$scope.resetWhenUnchanged = function()
{
if (original === $scope.modifiedValue) {
$scope.personForm.field.$setPristine();
}
};

django-autocomplete-light and angular: how can angular get the value selected

Using django-automcomplete-light V3 and angular on a non admin page.
Using the widget autocomplete.ModelSelect2
Where is the selected value stored? Using firebug, it's not in a new hidden html element and if i attempt to watch the original (now hidden) select element, it's value never changes if I change the selected value in the autocomplete widget.
How can angular watch/read this value?
Update:
As #visegan below points out you can use jquery syntax to get the value but for some reason you can't watch it.
i.e. this watch never gets triggered:
$scope.$watch(function(){
return $('#id_field').val();
},
function(newVal, oldVal){
console.log('current %r', newVal);
$scope.models.foo=parseInt(newVal);
});
Well I have just tried with my project and it was pretty straight forward:
$('#id_field').val()
To be honest, I am also not sure where exactly does the value come from.
As for the change watcher: autocomplete light now uses select2 component, which is apparently a bit problematic with angular.
There are two approaches that works: first one is to add more jquery:
$('#id_field').change(function() {alert('changed')});
This I have tested. The other approach is to do it somehow natively. Look at Select2 event handling with Angular js

Angularjs form.$dirty

I'm able to find form data is changed or not using $dirty.
ex: I changed text box or drop down and then $dirty become true. If I reverted to old data still it is true. I need to know if my changes are reverted or not. Do we have any property in Angularjs? If property is true I want to enable save button otherwise it should be disable.
https://docs.angularjs.org/api/ng/type/form.FormController
I need to implement around 10 pages and each page has 10 text boxes and a couple of drop downs. So I don't want track each control manually in my pages.
You can try using this module: https://github.com/betsol/angular-input-modified
From the README file:
This Angular.js module adds additional properties and methods to the
ngModel and ngForm controllers, as well as CSS classes to the
underlying form elements to provide end-user with facilities to detect
and indicate changes in form data.
This extra functionality allows you to provide better usability with
forms. For example, you can add decorations to the form elements that
are actually changed. That way, user will see what values has changed
since last edit.
Also, you can reset an entire form or just a single field to it's
initial state (cancel all user edits) with just a single call to the
reset() method or lock new values (preserve new state) just by calling
overloaded $setPristine() method.
DISCLAIMER: I haven't tried it myself and I notice the author overwrites the ngModel directive instead of adding a decorator, which could be dangerous...but at the very least, you can look at the source and get an idea of how to write your own service or directive with similar functionality.
Even though it does not follow the usage of $dirty, but an implementation similar to this might be helpful for you in the case of a Save button on update.
Inside your html:
<form name="testForm" ng-controller="ExampleController" ng-submit=" save()">
<input ng-model="val" ng-change="change()"/>
<button ng-disabled="disableSave">Save</button>
</form>
Inside your controller:
.controller('ExampleController', ['$scope', function($scope) {
$scope.disableSave = true; // Keep save button disabled initially
$scope.val = 'Initial'; // Initial value of the variable
var copyVal = $scope.val; // Copy Initial value into a temp variable
$scope.change = function() {
$scope.disableSave = $scope.val === copyVal;
};
$scope.save = function() {
// Save the updated value (inside $scope.val)
console.log($scope.val);
// Re-disable the input box (on successful updation)
copyVal = $scope.val;
$scope.disableSave = true;
};
}]);
Here is a working plunkr for the same.

ng-repeat how to handle a button element separately

I am using ng-repeat to populate data in a table so far so good. What i am trying to accomplish is to use a button and change it's text according to the userId (cust.id). I am trying to understand how to use a $scope inside a repeat method and modify it separately from the other elements.
On the following demo when i click to button with (userid value = 1) then i would like to change the specific button text and NOT every button in my ng-repeat
<button ng-click="perLineText(cust.id)">{{buttonText}}</button>
Live Demo
I am trying to figure out how to handle specific elements in my ng-repeat. Any help much appreciated.
You can do that by just using the this in you controller function instead of $scope.
$scope.perLineText = function(customerId){
if (customerId === 1) {
this.buttonText = 'Stop';
};
See the updated fiddle http://jsfiddle.net/u5swjwv1/
On a click callback this points to the scope of nested repeat element. If you use $scope you are actually referring to the parent scope object.
Look at this explanation too 'this' vs $scope in AngularJS controllers
A good way to handle this problem is using $index. Just pass it when calling your perLineText($index) function so you know which row you are in. Now you can simply work with the appropriate index object in your array which might my $scope.customers[index]
You can also use the ng-bind="perLineText(cust.id)" instead of the {{buttonText}} so the ng-click will toogle something and the perLineText will return Start or Stop.

Angular - Form validation issues when using form input directive

I have been trying to build a form input directive which will generate a form input based on the model and the model attributes .
For example,
if the field is name and type is text, the directive will return a input html control,
if the field is a list, then it will return a select box
and so on
These inputs are generated using ng-repeat in the view. The inputs are bound to the model in the scope. This is working fine. However, the form validation fails; i.e if the input controls are invalid, the main form still shows the form is valid.
I have put up a simple plunkr to illustrate the issue - http://plnkr.co/edit/R3NTJK?p=preview
NOTE : I have actually nested the form, as the input name field is also dynamically generated from the scope model.
I have been trying to a get hold on this from the past 2 days and this is really driving me nuts.
I m not sure if I m missing something.
I would really appreciate if some one could help me out with this.
Update:
Use the following link function:
link: function linkFn(scope,elem,attr){
var jqLiteWrappedElement =
angular.element('<input type="url" name="socialUrl" ng-model="social.url">');
elem.replaceWith(jqLiteWrappedElement);
$compile(jqLiteWrappedElement)(scope);
}
Plunker.
For reasons I don't understand, the replaceWith() must be executed before the call to $compile. If someone can explain why this is so, we'd appreciate it!
Update2: in the comments below, Artem mentioned that the DOM must be modified before the linking function is called, so this also works:
var myElem = angular.element('some html');
var linkFn = $compile(myElem);
element.replaceWith(myElem);
linkFn(scope);
Original answer:
Instead of the link function, just use a template in your directive:
template: '<input type="url" name="socialUrl" ng-model="social.url">'

Resources