How do I append my own function when the clear button is clicked on the Angular Material Auto-complete.
URL: https://material.angularjs.org/latest/demo/autocomplete
For example: I want to run myFunctyion() when the X button in the Auto-complete field is clicked.
The button comes from the following code's ng-click:
<button
type="button"
tabindex="-1"
ng-if="$mdAutocompleteCtrl.scope.searchText && !$mdAutocompleteCtrl.isDisabled"
ng-click="$mdAutocompleteCtrl.clear()">
<md-icon md-svg-icon="md-close"></md-icon>
<span class="md-visually-hidden">Clear</span>
</button>
If you wrote a button element directive or a mdVisuallyHidden class directive with a high priority, you may be able to intercept the event and handle it yourself...
OR submit a pull request to add such an event to https://github.com/angular/material/blob/master/src/components/autocomplete/js/autocompleteDirective.js
Agree with previous answer that "X" button will trigger $mdAutocompleteCtrl.clear().
But my tips will bit different, beside write custom directive you can just put your function to $mdAutocompleteCtrl.clear() at angular-material.js library. Or make a public variable that can passing your function inside $mdAutocompleteCtrl.clear() function.
Actually $mdAutocompleteCtrl.clear() it self is only an alias for public method. The real function name at angular-material.js is clearValue()
Related
I have applied ng-model and ng-change directives on input type text, that shows color in hexa that can be changed from color panel as shown.
<input type="text" ng-model="colors.primary_color"
ng-change="colorChanged()" class="input-control"
placeholder="Primary Color"
color-picker
color-picker-model="primaryColorModel"
color-picker-position="{{colorPickerPosition}}">
<button class="btn-sidebar">
<svg width="20px" height="21px">
<path ng-style="{fill: primaryColorModel}" d="M10.000,3.429 C5.865,3.429 2.500,6.793 2.500,10.928 C2.500,15.063 5.865,18.427 10.000,18.427 C10.000,14.550 10.000,7.089 10.000,3.429 M10.000,0.929 C15.523,0.929 20.000,5.406 20.000,10.928 C20.000,16.450 15.523,20.927 10.000,20.927 C4.477,20.927 -0.000,16.450 -0.000,10.928 C-0.000,5.406 4.477,0.929 10.000,0.929 L10.000,0.929 Z"
/>
</svg>
</button>
Now when I open color panel and change colors, new hexa code shows up in input type text, but colorChanged function doesn't trigger. It only triggers when I click on text box and write some thing.
I want it to be triggerd when I remove any character or value is changed from color panel.
I have tried with $watch like so
$scope.colors = {
primary_color: "#008fff",
secondary_color:"#008fff",
text_color: "#008fff"
}
$scope.$watch('colors', function (nval, oval) {
console.log(nval);
});
$scope.colorChanged = function() {
$rootScope.$broadcast('color-change', {colors: $scope.colors});
}
But it doesn't trigger either.
If I use $apply, it says you are already in digestive cycle.
If you place the relevant markup inside a <form> element and give the <input> a name :
<form name="form">
<input name="primary_color" type="text" ng-model="colors.primary_color"
ng-change="colorChanged()" class="input-control"
placeholder="Primary Color"
color-picker color-picker-model="primaryColorModel"
color-picker-position="{{colorPickerPosition}}">
...
</form>
Then you can programmatically trigger the ng-change directive by using $setViewValue() with no params :
$scope.form.primary_color.$setViewValue()
Will trigger ng-change as the ng-model was changed without actually changing it.
demo -> http://plnkr.co/edit/PmthIfblkPkbKgRInLBc?p=preview
If you are using this plugin, then the variable you specify in color-picker-model attribute is treated as the binding variable for the color picker. So to detect changes to the color picked, you can watch that variable. In your case:
$scope.$watch('primaryColorModel', function(nval, oval) {
//your code here
});
I can't tell which plugin you used for, but regardless unless it was built with angular you'll likely have to wire up a callback that runs a $rootScope.$apply(). The reason being is that the piece of code is happening outside angulars eco-system and it needs to be notified to re-run. See my similar answer here: AngularJS: ng-repeat list is not updated when a model element is spliced from the model array
I am using JSF 1.2 and RichFaces. I have a requirement where on click of command button (<h:commandButton>) RichFaces data table will be displayed with 3 set of rows, This is working fine but the problem is I need to set the focus in the text box of data table which is not working. Please find the sample code I am working with.
Command button :
<a4j:commandButton immediate="true"
action="#{bean.addTomethod}"
reRender="myform"
oncomplete= "setFocusOnRichComponenet();"
rendered="true">
</a4j:commandButton>
JavaScript code :
function setFocusOnRichComponenet(){
document.getElementById("myform:richDataTableList:0:richTextBoxID").focus();
}
Here, myform:richDataTableList:0:richTextBoxID is the id of the component where I want to put focus.
When the id is generated dynamically, it can be erroneous at times to try to refer using document.getElementById as you must know the full id.
Simpler way to do this is use the RichFaces method clientId('elementName')
This will basically resolve the exact id so you don't have to refer by tableName[].Element[] format.
So for your scenario, you could replace the javascript function as below:
function setFocusOnRichComponenet(){
document.getElementById("#{rich:clientId('myTextBox')}").focus();
}
where 'myTextBox' is the name of the textbox you are trying to refer
Add a class in input:
<h:inputText id="test" class="testClass"/>
In function set focus by class with jQuery:
function setFocusOnRichComponenet(){
jQuery(".testClass").focus();
}
I have the following Code that I would like to learn how to refactor out html and place into my Angular controller.
<a class="tab-item ">
<input type="datetime-local" name="schedule-date-time" id='schedule_input'
ng-model="scope.schedule"
ng-change="scope.updateSchedule(scope.schedule)"
class="icon ion-calendar schedule-picker"
ng-class='{highlighted:!scope.PublishingService.getPublishNow()}'
placeholder="yyyy-MM-ddTHH:mm" />
</a>
I would like to add some conditional logic, to trigger a warning modal before the datetime input is opened. In my attempts, when I attach a controller scope function to the above HTML ng-focus or ng-click, the datepicker input is opened first. This is not the functionality I desire. How can I create the datetime-local input dom using angular, and open it from my angularjs controller?
In my design, I would remove the input above, and bind the below function to the using ng-click. I would like that ng-click to warn the user, then call a subsequent function to create the input and open it. I have Something like this in mind:
$scope.DetermineIfIShouldWarnUser = function() {
if($scope.return_path == '/editpost'){
$scope.warnUser(' TRIGGER MODAL POPUP ', $scope.functionToOpenCalandarDOM);
}else{
$scope.functionToOpenCalandarDOM();
}
};
$scope.functionToOpenCalandarDOM() {
// HOW CAN I REFACTOR THE CALENDAR DOM OUT OF THE HTML and load it and open it from here?
}
so I have a form element
<form name='form' novalidate ng-class="{'shake':form.$invalid && submitted}">
<input type='text' name='text' ng-model='text' ng-class="{'has-error':form.text.$error.required && submitted}"/>
<button type='submit' ng-click='submit(form)'>click</button>
</form>
so whenever I click the button it will validate the form and add a class "shake" into form whenever the form is invalid which is in another mean the input type text doesn't take an input..
it works well, the question is.. can I remove the "shake" class after let say 5 second ?
so the flow maybe like this
form invalid -> attach "shake" class -> after 5 second -> remove "shake" class
how can I achieve this in angularjs ?
You can achieve this on your click event..
$scope.submitFunction = function(expression) {
$timeout(function() {
angular.element(#formId).removeClass("shake");
}, 5000);
};
Also do not forget to include dependency on your controller.
function YourCtrl($scope, $timeout){
}
Just an additional info, you can use ng-submit in your form element. It makes your code more readable as angularjs is trying to achieve this.
Why don't you use a timeout? Either javascript's built-in setTimeout or angular's $timeout
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
};