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.
Related
i have created one submission form by using java script i need to reset the input data by using on reset button.
Help me out of this.
reset: function() {
var oInput1 = sap.ui.getCore().byId("firstname");
oInput1.setValue("");*/
this.getViewById("firstname").setValue("");*/
}
input1.getId("firstname").setValue("");
onExit: function() {
input1.setValue("");
}
the code is not resetting the form data
First of all your provided code-sample is incorrect, please correct it.
Second, onExit is executed when your view is destroyed, setting the input value to empty is rather useless there.
If you want to reset data of your input-field when clicking a button you'll need to have the following elements:
1) an Input- & Button-control (with press-event) in your XML-view.
2) an id assigned to your Input-control to be able to refer to the control when pressing the reset-button.
3) The press-event from the button worked out in your controller.
XML
<Input id="firstname" value=""/>
<Button text="Reset" press="reset"/>
Controller
reset: function() {
var oInput1 = this.getView().byId("firstname");
oInput1.setValue("");
}
i'm trying to update a hidden input with an entered value from a SweetAlert modal (basically a prompt).
The code below does not work, the form submits but the hidden field value is null.
HTML:
<input type="hidden" name="input" v-model="value">
JavaScript:
this.value = websiteId;
event.target.submit();
The below code however does seem to work! But not really much point in using Vue.js if i'm going to just plain old JavaScript.
HTML:
<input type="hidden" class="input-value-web" name="input" value="0">
JavaScript:
document.querySelector('.input-value-web').value = websiteId;
event.target.submit();
When you change the value of a Vue instance's data property, like you're doing with this.value = websiteId, that bound property won't update the value of the <input> until the Vue instance's next update.
However, the next update won't occur until after everything in the method has been executed.
To get around this, use the $nextTick method to wait until the Vue instance has updated before executing event.target.submit().
Here's an example:
methods: {
submitForm() {
this.value = websiteId;
this.$nextTick(() => {
event.target.submit();
});
}
}
Or put in tl;dr code:
form.email.$setValidity('conflict', false);
is too sticky for my simple serverside validation flow.
I'm trying to get the form to show good feedback in the event that the user enters an email address already in use by another customer. I'm running AngularJS v1.2 and have this template:
<form name="form">
<input name="email" type="email" ng-model="..." required>
</form>
<div ng-messages="form.email.$error">
<div ng-message="conflict">Email address already in use.</div>
</div>
In my controller, I'll handle the submit event and trigger the validation in my $http.post().error handler like this:
$http.post('api/form/submit/path/here').error(function(resp) {
if (resp.details === 'conflict')
$scope.form.email.$setValidity('conflict', false);
});
The problem is that when the user goes back and changes the value in the input field, the error message doesn't go away. It sticks around until I manually call $scope.form.setValidity();.
The docs say implement a custom directive with an ng-model dependency, but that seems super overkill for my purposes. I've also tried setting $scope.form.email.$valid = false; and $scope.form.email.$invalid = true; but those don't change the appearance of the textbox.
Nothing in your code modifies the conflict validation key, except for when $setValidity('conflict', false) is explicitly called. Since that is the only code setting the state of the conflict validation key and there is nothing else resetting it to true, it's expected behaviour that editing the textbox wouldn't reset its conflict validation state.
To get the behaviour that you want, you need to code for it. One way is to use ng-change.
<input name="email" type="email" ng-model="..." required ng-change="resetConflictState()">
$scope.resetConflictState = function() {
$scope.form.email.$setValidity('conflict', true);
}
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
};
How can I detect when a user has chosen which file to upload using a html file input. That way I can submit the form automatically.
The file upload element fires an onchange event when its contents have changed. Here's a very terse example:
<input type="file" name="whatever" onchange="alert('Changed!');" />
EDIT: Oh, and if you'd like to submit the form when they select something (although this will probably be a little confusing to your users):
<input type="file" name="whatever" onchange="this.form.submit();" />
A vanilla JavaScript way to detect a change in the file input:
var fileInput = document.getElementById('inputfileID')
fileInput.addEventListener('change', function () {
// Called when files change. You can for example:
// - Access the selected files
var singleFile = fileInput.files[0]
// - Submit the form
var formEl = document.getElementById('formID')
formEl.submit()
}, false);
Just to mention: the attribute false means to not use capture i.e. false means that relevant change listeners in the DOM tree are executed in bottom-up order. It is the default value but you should always give the attribute to maximise compatibility.
See also a SO answer about change event, MDN docs for addEventListener, and a SO answer about form submission.
try
$('#inputfileID').change(function(){
alert(0);
})