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?
}
Related
I am trying to add ng-change to input which runs datetimepicker but it triggers on change function on page load. below is the code
<input datetimepicker ng-model="startDate"
ng-change="testFunction()"
options="cOptions"
placeholder="Select Date"/>
any idea how to prevent this ?
edit:
$scope.testFunction = testFunction;
function testFunction(){
console.log('on change')
}
loadData();
function loadData(){
//this is where startDate is set
}
Hi the change in input field where you're using the directive is triggered by the plugin, it's explicitly setting it to null. So you can have the validation like until input field in filled don't execute logic you written on ng-change function. There're two ways to do that:
<div class="input-group">
<input class="form-control" datetimepicker ng-model="vm.date" options="vm.options"
ng-change="vm.date && vm.changed()"/>
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar">
</span></span>
</div>
Now here ng-change will not trigger until something you inserted in the field. So onload it'll not triggered.
Other way is like instead of anding this scope variable with its ng-change function, you can check in that function if the value is null or not. If it's non-null then only run the implementation written on ng-change.
Here's plunker showing both conditions:
http://plnkr.co/edit/uCf2vpmoYIYzxTjmFVcX?p=preview
Update: If you're editing value onload but still you don't want to execute implementation you written on ng-change then have separate variable, toggle its value on first ng-change, which's triggering automatically because of directive, next change onwards your ng-change function will run.
http://plnkr.co/edit/FogYzmDBd1gIolvjP7yl?p=preview
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()
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/
So I have a modal box that allows the user to edit / save some data.
I just want to add that unlike other Meteor apps, I don't want to save the data straight away - I want the user to fill in all the fields before hitting save where it will save to the database and send to server etc. This is mainly because I want the user to be able to hit the "cancel" button to revert all changes.
I have a drop down box at the start of the form where depending on the value, fields will be shown or hidden
<select class="form-control" id="ddlNewInputType" placeholder="Enter your input type">
<option value="input">Input</option>
<option value="formula">Formula</option>
</select>
And I have a handlebar around a field like this to determine whether I want to show it
{{#if isFormula }}
<div class="row">
<input type="text"
id="txtNewInputFormula" placeholder="Enter formula">
</div>
{{/if}}
With a helper looking like this
isFormula: ->
$('#ddlNewInputType').val() == 'formula'
However, this doesn't work. Aside from when it first loads onto the page, it never hits isFormula, probably because Meteor doesn't consider any of the HTML elements as reactive so it never re-evaluates when the HTML element changes.
What is a suitable way to get around this? Is it possible to make something reactive explicitly in Meteor? I was also considering putting the dropdown list value into a session variable but that just seems messy because I'm going to need to manage this session variable (remember to clear it when the modal box closes etc.)
Your analysis is correct - a reactive variable needs to be involved in order for your helper to reevaluate after changing the select element. The basic strategy looks like:
Initialize a reactive variable when the template is created.
Whenever the select changes, update the reactive variable.
Read the reactive variable in your helper.
Rather than use a session variable, let's use a ReactiveVar scoped to your template. Here's an example set of modifications:
Template.myTemplate.helpers({
isFormula: function() {
return Template.instance().isFormula.get();
}
});
Template.myTemplate.events({
'change #ddlNewInputType': function (e, template) {
var isFormula = $(e.currentTarget).val() === 'formula';
template.isFormula.set(isFormula);
}
});
Template.myTemplate.created = function() {
// in your code, default this to the current value from
// your database rather than false
this.isFormula = new ReactiveVar(false);
};
Remember that you'll need to also do:
$ meteor add reactive-var
See my post on scoped reactivity for a full explanation of this technique.
I have an input file element within an angular view/form. I'm using ng-upload like this:
<input id="img" type="file" name="image" onchange="angular.element(this).scope().setFile(this)">
<input id="imgname" type="hidden" value=""></div>
Since I can't tell angular to listen for changes on input[type="file"] element, I've created the method that updates the hidden input that just holds the current filename. That way I can run my validator on the second field.
Another field I have has some sort of validator, like this:
<input ng-model="other" ng-change="chg()"/>
Now, the trouble is, if I trigger the validator, $scope.chg(), from setFile() method, I think I don't get the same scope - chg() runs, but it's as if the validator is in another scope and doesn't set my actual submit button to enabled. I tried logging from the chg() - it shows different scope then what I actually see on the view.
And if I later trigger the ng-change by changing the regular input field ("other"), it picks up the changes, or actually, it sets the submit button state correctly.
Now, I suspect this has to do with me calling the angular.element(this).scope().setFile(this) from my form instead of direct, $scope-bound method. But I cannot call $scope-bound method because it does not trigger - if I understood correctly, that's due to Angular not (yet) working with input type=file fields.
What can I do here?
I simply want to detect if there is a file or not so I can enable/disable the submit button appropriately.
I used followed flow that works for me:
<input type="file"
ng-model="upFile"
onchange="angular.element(this).scope().setFileEventListener(this)"
/>
From controller:
$scope.setFileEventListener = function(element) {
$scope.uploadedFile = element.files[0];
if ($scope.uploadedFile) {
$scope.$apply(function() {
$scope.upload_button_state = true;
});
}
}
Hope it will help.