Is there an Aurelia way to accomplish what I am trying to do? After I click add, I want the input to be set back to zero. Here is the app.js file
export class App {
constructor() {
this.message = 'Hello World!';
this.array = [];
this.array.push("Hello");
}
addToArray()
{
this.array.push(this.hello);
hello = "";
}
}
I tried setting the var hello back to an empty string, thinking Aurelia had them two way bounded. But then I thought that was silly, because you might want to mutate/manipulate the variable while in the function, and you wouldn't want the user to see it, so I guess setting hello back to an empty string wouldn't work. Here is the html.
<form submit.trigger="addToArray()">
<input type='text' value.bind="hello">
<input type='submit' value="add">
</form>
<ul>
<li repeat.for="a of array">${a}</li>
</ul>
It turns out they are bounded! Simple answer here, i needed to use this.hello = ""
Potentially, the model wouldn't update until the function has finished running, my guess is this is how it works. So as long as the bounded variable is set to something user friendly at the end of the function you should be fine making any changes to the value during execution
Related
I have a simple view;
<form ng-submit="ctrl.check()">
<input type="text" ng-model="ctrl.input">
</form>
<div>
<span ng-repeat="input in ctrl.log">{{input}}<br></span>
</div>
Connected to the controller;
app.controller('verify', [..., function(...) {
var ctrl = this;
// some variables omitted here
ctrl.input = '';
ctrl.log = [];
ctrl.check = function()
{
ctrl.log.unshift(ctrl.input);
// some logic omitted here
};
}]);
But when the user scans a barcode containing the string "123456789." repeatedly, the log object contains randomly cropped values.
From a screenshot, this is what I see:
12345678
1234567
123
Scanning the barcode in notepad works perfectly.
I am struggling to see what is happening here, but my only suspicion at this point is that the ng-model binding is being slower at updating the model than the form is to respond to the enter key, thus causing the submit to happen before the model has been updated.
Is this a known issue with angular/Does anyone know how to prevent this from happening?
I'm creating a module that allows users to see the status of a set of IP addresses by creating a custom field that holds the address (and validates it when it's first entered). On the Field view there's a glyphicon that changes based on the result of a ping attempt.
How it should look
However, I'm having difficulty in getting the Javascript for pinging the address and each individual field to pass arguments correctly. For some reason, only the address from the first field is passed to the Javascript, instead of using the addresses from each individual field.
How it looks when only one address gets passed
I've checked the page with Firebug and found that the onload arguments are collected and sent correctly, but the Javascript is only receiving the first field's contents. Since the Javascript uses the arguments to determine which DOM to change, only the first DOM is ever altered.
I've also confirmed that the values are passed incorrectly by making the spanIDHolder and addressHolder spans visible and having the Javascript alert with the contents of those two spans. The HTML displays the correct value, but the alert only shows the first.
Here's the code for the view:
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
#{
string ipaddress = Model.ContentField.Value;
string spanID = ipaddress + "span";
bool showPingResult = Model.ContentField.ShowPing;
}
<body>
#{
if (!string.IsNullOrEmpty(ipaddress)) {
if (showPingResult) {
<span id="addressHolder" style="display:none">#ipaddress</span>
<span id="spanIDHolder" style="display:none">#spanID</span>
<span id="#spanID">
<span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span>
</span>
}
<span class="text-field">#ipaddress</span>
}
}
<script src="http://code.jquery.com/jquery.min.js"></script>
<script>
var address = document.getElementById("addressHolder").innerText;
var id = document.getElementById("spanIDHolder").innerText;
function setPingResult() {
var elem = document.getElementById(id);
elem.innerHTML = '<div class="glyphicon glyphicon-ok-sign" aria-hidden="true"></div>';
}
$(document).ready(function () {
setPingResult();
});
</script>
</body>
The Javascript is temporarily simplified until I can get the parameters passing correctly, so 'address' is unused.
Things I've tried so far:
Other methods of including the Javascript code such as inlining or including it in the HTML as discussed here
Doing the ping through a C# function and using if statements on the view to display the correct symbol
This works, but means that it runs the ping script before the page loads. If there's a way to call the C# function in the onload block (or equivalent), that would be a solution
Running the code through an onload call on the body and storing the Javascript in a separate file
Moving things around randomly hoping it decides to work
Let me know if I need to provide code from elsewhere in the project.
Edit: Some things I've found so far...
The block at the beginning which designates the variables is only executed once, no matter how many individual fields are on the page. I found this by replacing spanID with the output of a random number generator. All four fields received the same random number.
I've tried encasing the field in a part, but can't figure out how to get the variables to the part view instead of the field view. A viewmodel may be the key?
The variables can be passed to the Javascript section just by using # in front of the needed variable name. This results in the last field's data being passed.
Solution:
For some reason, the pass works correctly if I collect the variable in the document.ready block instead of directly in the JS function. Therefore, instead of
function setPingResult() {
var elem = document.getElementById('#spanID');
elem.innerHTML = '<div class="glyphicon glyphicon-ok-sign" aria-hidden="true"></div>';
}
$(document).ready(function () {
setPingResult();
});
I use
function setPingResult(spanID) {
var elem = document.getElementById(spanID);
elem.innerHTML = '<div class="glyphicon glyphicon-ok-sign" aria-hidden="true"></div>';
}
$(document).ready(function () {
setPingResult('#spanID');
});
If someone could explain why this works, that would be lovely.
I basically have a very complicated set of tabs with various input controls but lets not worry about this for now. For now let consider simple input wtching issue I am baffled by.
For example:
<input type="text" placeholder="Associate some tags please" data-ng-model="tag" data-ng-maxlength="250">
I am try to detect if user has typed something into my input:
$scope.$watch('tag', function () {
//$scope.$watchCollection('tag', function () {
console.log('tag changed');
});
But I seem to get zero response. However, when I perform my save operation I always seem to get the value user typed in.
Is a case of ng-model not binding correctly or is it that I am not $watching it correctly?
Also after I've performed my save operation I try to clear what user typed in for the tag with:
$scope.tag = '';
But that doesn't seem to work for some reason as though $scope.tag doesn't exist.
PS: When I say save operation I am actually performing a array.push() into an object which later gets saved by a service.
For example:
$scope.checkSaveTag = function (tag) {
...
// checked for duplicate tag beforehand
$scope.myForm.Tags.push(tagObj); // complicated form object
$scope.tag = ''; // tag input control
...
};
Any chance that the tag is an object or an array? If that is the case, you'll need to do a deep $watch, e.g:
$scope.$watch('tag', function () {
console.log('tag changed');
}, true);
Try like this
Controller
$scope.form={
tag:''
}
$scope.$watch("form.tag",function(newVal,oldVal){
console.log(newVal);
})
Html
<input type="text" placeholder="Associate some tags please" data-ng-model="form.tag" data-ng-maxlength="250">
I cannot understand why this small code is not working properly.Please help!
All i try is to push textbox values into an array and then then display it back using a binding.
HTML code is :
<div>
Add Task:<input type="text" placeholder="abcd" data-bind="value:viewModel.newTask"/>
<input type="button" value="add" data-bind="click:viewModel.addTask" />
</div>
<div data-bind="foreach:viewModel.tasks" ></div>
js script is:
var viewModel = function (items) {
var self = this;
self.newTask = ko.observable();
self.tasks = ko.observableArray(items);
self.addTask = function () {
self.tasks().push(self.newTask());
self.newTask(" ");
}
ko.applyBindings(viewModel(["alpha","beta","gamma"]));
}
i tried it in JSFiddle also:
http://jsfiddle.net/Rakz_1221/m3rwupmz/1/
First off, you haven't included KnockoutJS in your JSFiddle demo, so your demo will not work anyway.
The problem you have is that you're calling tasks.push. tasks itself isn't an array. tasks is a function - a Knockout Observable. In order to push values into it, we need to execute this function by calling tasks().push() instead.
As James Thrope has commented, you can in fact call tasks.push, sorry about that!
Finally, your ko.applyBindings(...) is never being called as it's contained within your viewModel function - which you're not calling at any point.
I strongly advise you to go through KnockoutJS's very own interactive tutorial available at http://learn.knockoutjs.com.
I'm trying to bind an input (one-way), whoever if I change its value its no longer binding properly
//controller => on row click => change input
$scope.getNote = function (note)
{
$scope.currentNote = note;
};
//view
<input type="text" value="{{currentNote.Title}}" >
This is the scenario, getNote is being called and the input is being filled properly. However, when I change the value of the input and call getNote again the input doesn't show the new value even tho its value attribute contains the correct value. So somehow its not showing the correct value to the end user.
eg:
1- First Value from GetNote = "Hello World"
2- I change the value of the input to "Foo" as a normal user
3- Call GetNote again and the I get value="Hello World" but on the screen it displays "Foo"
Hack Solution:
//controller object value copy using jquery
$scope.currentNote = jQuery.extend({}, note);
//view
<input type="text" ng-model="currentNote.Title" >
Am hoping for an Elegant solution
I think you should try with ngValue directive, as sbaaaang said. But without curly braces (documentation here: https://docs.angularjs.org/api/ng/directive/ngValue).
Edit:
And maybe if you just want to use one-way data binding a div will be enough for your purposes, and not an input. Then you can style it as you want.
use ng-value="" instead of value="" should fix
i would do:
$scope.getNote = function (note)
{
$scope.currentNote = note;
};
//view
<input type="text" ng-model="currentNote.Title" ng-value="currentNote.Title" />
If you still getting problems try also:
$scope.getNote = function (note)
{
$scope.$on(function () {
$scope.currentNote = note;
});
};