knockout textinput modify observeable not updating text - javascript

i´m using textinput data-binding off the latest knockout version.
on an input like:
<input type="text" placeholder="name" data-bind="textinput:vm.found().term">
and it works just like a charme, problem:
when i modify the value with some other script like:
vm.found().term("somecontent")
the input does not change?
i need the value of the textinput to change when i change the observable
the doc says nothing about textInput

You should never have raw, deeply nested bindings like you have there. Assuming the found value has changed, it the text box will still be bound to the previous found object. You probably should be using a with binding somewhere.
<div data-bind="with: vm.found">
<input type="text" placeholder="name" data-bind="textinput: term">
</div>

Related

v-model depending on conditions [duplicate]

I have a vue component that shows a form populated with items from a selected item to edit. Now I don't want to have to use a second form for creating a new item. At the moment I auto populate and update the item with v-model which obviously updates the object. Am I not able to use conditional operators in this like so?
<form #submit.prevent>
<div class="field">
<label class="label">Job Title</label>
<p class="control">
<input type="text" class="input" placeholder="Job title" v-model="experiences[editIndex].title ? experiences[editIndex].title : ''" />
</p>
</div>
</form>
You can use conditional operators with v-model, but you can't give v-model a string like you're attempting in your example.
I wouldn't use the same form for editing and creating (might be preference). I would make the form its own component and then make two additional form components for editing and creating.
However, if you really want to handle the logic in each input's v-model directive, you would need to give it a variable in the last part of the ternary operator. Something like this:
v-model="experiences[i].title ? experiences[i].title : newExperience.title"
If you use eslint-plugin-vue it will complain about ternary in v-model.
ESLint: 'v-model' directives require the attribute value which is
valid as LHS. (vue/valid-v-model)
So I'd rather explicitly use a pair of :value and #input props.
Like that:
<input
type="text"
class="input"
placeholder="Job title"
:value="experiences[editIndex].title ? experiences[editIndex].title : ''"
#input="experiences[editIndex].title = $event.target.value"
/>
Also, you can use some function for #input, which will check property existence and add it if necessary.

How to change one-time binding data in AngularJS?

I have a div which show details like mobilenumber, name etc. like {{::mobilenumber}}, {{::name}}
In that div, there is a button that renders the same values in the new form
By using the button in the form, the user can change the values but in the div where I am showing details, values don't change after clicking on the button
<form ng-submit="form.$valid && saveDetails()">
<input type="text" class="form-control capitalize" placeholder="Full Name" name="fullname"ng-model="address.fullname" maxlength="50" ng-trim="true" autocomplete="off" required >
<span><!-- Mobile Number required --></span>
<input type="text" class="form-control capitalize" placeholder="Mobile Number" name="mobilenumber" id="mobilenumber" ng-model="address.mobilenumber" ng-minlength="10" maxlength="12" ng-trim="true" autocomplete="off" required>
<span><!-- Mobile Number required --></span>
<button ng-click="form.submitted=true><span>Update User Details</span</button>
</form>
Do I want to use one-way binding only?
I tried using $scope.$broadcast('$$rebind:refresh'); but still values don't change.
Any help or guidance would be very helpful for me.
If you really want to keep some sort of one-way-binding...
What you could do, is just use two way binding but with a dataset in between. It gives some overhead but it is a possible solution to your problem. In order to update the view, you just update the copied data. You can control when the data in the view is updated.
When you use interpolation {{mobilenumber}} in your html, angular creates a watcher that watches the property mobilenumber on a scope:
$scope.$watch('mobilenumber', function() {
// update DOM
});
Whenever the value changes, DOM is updated.
However, if you use one time binding {{:mobilenumber}}, as soon as your callback receives truthy value, angular removes the watcher:
var unwatch = $scope.$watch('mobilenumber', function() {
if (value) {
// update DOM
unwatch();
}
);
And since there is no more watcher for mobilenumber, whenever you update values on the scope inside your saveDetails() method, the callback is not triggered and DOM is not updated.
If you're planning on updating values constantly, you should not use one time binding. Use regular bindings:
<div>{{mobilenumber}}</div>

v-model in dynamic component

I have a list of dynamic components that I render with a for loop.
<component
v-for="component in components"
:key="component.componentId"
:is="component.type"
:componentId="component.componentId">
</component>
One of the different component types is an element that contains an input field. I want to attach v-model to that input.
<input type="text" :name="name">
works but when I do
<input type="text" :name="name" v-model="value">
I get no errors but the component is not rendered. However
<input type="text" :name="name" :value="value" #input="setValue">
works, if used with an appropriate method setValue to update the value attribute.
How should I use v-model in the component?
Apparently dynamic type bindings don't work with v-model. Found a commit in the repository that confirms this. For some reason it doesn't give me the warning, even though process.env.NODE_ENV == undefined.
In the original question I stripped a lot of code to make it more readable but seems like I missed the important part.

How to get back input value onblur with Angularjs?

I'm new with Angular and wanted to know how can I handle the following issue :
<input class="form-control" type="text" value="{{add_item.value}}" onfocus="this.value=''" onblur="this.value={{add_item.value}}">
of course this doesn't work.
I would like to get back the first value onblur if the input is empty.
Any advice ?
The short: You need to store the original value somewhere to retrieve when you need it.
Even shorter: Use https://github.com/betsol/angular-input-modified
For those who are interested in , I made an ugly thing but it works. I'm storing the original value in placeholder and using it onblur like this :
<input class="form-control" type="text" placeholder ="{{add_item.value}}" onfocus="this.value=''" onblur="if(this.value=='')this.value=this.placeholder"

Angular.js: update binding after manual modification

I'm only starting to dive into angular.js and have found this issue that I can't seem to get around. Consider this simple code:
<input type="text" ng-model="test">
<input type="text" value="{{test}}">
When I write in the first field, the second one is updated nicely. When I write in the second field and then go back to the first one, the binding is not updated anymore. Interestingly though, the HTML attribute value does get updated - it's just not displayed.
Equivalent (at least roughly) code in vanilla javascript does not suffer from this:
<input type="text" id="model">
<input type="text" id="binding">
<script>
var model = document.getElementById("model");
var binding = document.getElementById("binding");
model.addEventListener("keyup",function() {
binding.value = model.value;
});
</script>
Here's a fiddle for you to test both: http://jsfiddle.net/Q6b5k/
Any idea why this happens when using angular.js and how to fix this?
[EDIT] Judging by the initial replies, it appears I have not made it clear. I do not want the second field to update the first one. The binding is to be one-way only, e.g. to allow filtering or even manual corrections (such as automatic creation of a URL alias in a blog post creation form). http://jsfiddle.net/Q6b5k/1/
The value attribute is only used when rendering the initial HTML. After the page load, everything else happens in the Angular Event Loop and therefore you need to do something that event loop can pick up. You can use ng-change for what you are looking to do:
<input type="text" ng-model="test" ng-change="test2=test.toLowerCase();" />
<input type="text" ng-model="test2"">
This happens because {{value}} does not create a binding, it is used for interpolation.
The simplest solution is to use ng-model in both the fields
<div ng-app>
Angular.js:<br>
<input type="text" ng-model="test">
<input type="text" ng-model="test">
</div>
Demo: Fiddle

Categories