Replace keyup event action with click event action - javascript

http://jsfiddle.net/2q8Gn/23/
Rather than have computedPageLinks update via the search input keyup event, can anybody help me amend the above fiddle so computedPageLinks updates via a button click event and doesn't update when the search input loses focus?

Since your search results are based on the value of query changing, even if you remove the valueUpdate: 'keyup' setting, that computed function will still update when the input box is blurred.
You can break that behavior by moving the "searching" out of the computed observable and instead populating a "results" observable array when the click occurs.
So, add a "results" array:
self.results = ko.observableArray([]);
And then add a search function we can trigger on click that populates the results:
self.search = function() {
// Did the user search for anything?
if (!self.query()) {
self.results([]);
return;
}
// Do the "search"
self.results(ko.utils.arrayFilter(self.pageLinks(), function(item) {
return item.title.toLowerCase().indexOf(self.query().toLowerCase()) >= 0;
}) || []);
};
Now you can remove the computed observable, and change your binding to use the results array:
<tbody data-bind="foreach: results">
To link it all up, first remove the valueUpdate setting on your <input> and add a <button> that triggers the search function on your model:
<input placeholder="Search…" type="search" name="q" data-bind="value: query" autocomplete="off" />
<button type="button" data-bind="click: search">Go</button>
Demo

Related

React/Next.js how to get other Element event target value on button click

I have an input element and a button in React:
<li><input type="text" placeholder="Enter new ID"></input>
<button onClick={(e)=>this.saveKonfigElementHandler()}>Save</button></li>
Now, when I enter some value into the input field, I want to save the value into some array when I click on the button.
Is it somehow possible to get a reference to that input field (e.g. the target.value of the input field) to save it when clicking the button?
Or would I simply have to do it with an onChange event that saves the current input value into some Variable, and when I click the button, I will simply retrieve that value to save it into some array? Maybe that would be a lot simpler.
E.g:
<input type="text" value={this.state.inputFieldText.join('')} onChange={(event) => this.textHandler(event)}></input>
in the textHandler Method, I will save the target value from the input field into a Class Component state variable in the textHandler() method. And when I click the button, I retrieve that state value and can do some manipulation with it?
A modern way to do it, with function components, hooks and a controlled form element, is:
import { useState } from 'react'
function MyComponent({ initialId, onSave }) {
const [newId, setNewId] = useState(initialId)
return (
<li>
<input
type="text"
placeholder="Enter new ID"
onChange={(e) => setNewId(e.target.value)}
/>
<button onClick={() => onSave(newId)}>Save</button>
</li>
)
}
I'd also note that it is considered better accessibility practice to use a label element for describing the purpose of your field, rather than a placeholder. Placeholders are more appropriate for example input.
Is it somehow possible to get a reference to that input field (e.g. the target.value of the input field) to save it when clicking the button?
Yes.
Or would I simply have to do it with an onChange event that saves the current input value into some Variable, and when I click the button, I will simply retrieve that value to save it into some array? Maybe that would be a lot simpler.
That would be a slightly more React way to do it.
Your DOM-only approach is more "uncontrolled" (see these docs for what controlled/uncontrolled means). You'd do it like this:
Change your onClick to pass e to the handler:
onClick={(e)=>this.saveKonfigElementHandler(e)}
In saveKonfigElementHandler, use e.target.previousElementSibling to access the input:
saveKonfigElementHandler(e) {
const { value } = e.target.previousElementSibling;
// Use `value` ...
}
That's fragile, of course; if you change your structure so another element is between the button and the input, or the input is within a container element, etc., it'll break — which is one argument for the controlled approach. You could store a link to the input in a data attribute on the button:
<li><input id="id-input" type="text" placeholder="Enter new ID"/>
<button data-input="#id-input" onClick={(e)=>this.saveKonfigElementHandler(e)}>Save</button></li>
and then use querySelector to get it:
saveKonfigElementHandler(e) {
const { value } = document.querySelector(e.target.getAttribute("data-input"));
// Use `value` ...
}
but the you're having to keep selectors unique, etc.
Which you choose, controlled or uncontrolled, is ultimately up to you.
I'm not sure about your question. Do you want something like this ?
<button data-input="#id-input" onClick={this.saveKonfigElementHandler(value)}>Save</button></li>
saveKonfigElementHandler = (value) => (event) => {}

Javascript "input" event value is undefined

I have an Electron app that needs to monitor an input text field on a form. The HTML looks like this:
<input type="text" class="cloneProjectName" id="outputProjectName" value="" >
I add an event listener for the element and console log what I think should be the typed data from the input:
projectNameControl.addEventListener("input", function (event) {
console.log(event.value)
})
All I see in the console is "undefined."
I would appreciate any input, I have searched and searched without finding an answer.
Sid
It's not the value of the event that you want (events don't have a value). It's the value of the element that triggered the event that you want and that element can be referenced with this or event.target.
Also, make sure that your JavaScript projectNameControl variable correctly references the input.
let projectNameControl = document.getElementById("outputProjectName");
projectNameControl.addEventListener("input", function (event) {
console.log(this.value, event.target.value);
})
<input type="text" class="cloneProjectName" id="outputProjectName" value="" >

Event listener "change" only works if focus is on object

I'm currently having a little struggle with this. The situation is the following. I have multiple input fields on a page
Input1 and Input2 influence the content of Input3.
Now I wan't an event handler being triggered if content of Input3 changes. I tried:
$('#div-xy').on('change', 'input', function(){console.log('input changed')});
But that only seems to work if the focus is also on Input3 which isn't the case as I'm typing in input2 or input3.
I also tried:
$('#div-xy').bind('DOMSubtreeModified', function(){console.log('CHANGE2')});
which sadly has the same effect. Do you maybe have an idea how to check for changes in Input3? Would appreciate the help.
The change event only triggers on user input, but can be triggered explicitly.
Since you are using jQuery:
$('#input2').change(()=>{
console.log('input 2 is changed');
$('#input3').val('some val');
$('#input3').change()
})
$('#input3').change(()=>{
console.log('input 3 is changed');
})
Try like this:
If you have many of these fields, rather than having a handler be bound to each one, you would get better performance by using a delegated event handler:
HTML:
<div id='parent'>
<input type="text" class="search-field" />
<input type="text" class="search-field" />
<select class="search-field" ><option>1</option><option>2</option></select>
<input type="radio" class="search-field" />
</div>
JS:
$('#parent').on('change', '.search-field', function() {
// validate all search field values
// display search results based on values
// if search results already shown, filter based on $(this).val()
console.log($(this).val());
});
Technically, the change event occurs when the value of an element has been changed BY THE USER. It won't occur on it's own if the value of input3 is changed through jquery or some other code. However you can trigger that in any other jquery function manually and if there is a definition of input.change() then it will be executed.

Dynamic HTML Element Binding Using Kendo

Here is the scenario I'm currently in:
I have three HTML elements. A textbox called shipToAddress, another textbox called deliverToAddress and a checkbox called sameAsShipToAddress.
I then have a kendo view model behind the scenes that contains a variable called address which will hold a string of an address ex: "123 Main Street".
When the page first loads, the shipToAddress element data-binds to the kendo view model's address variable ex: "123 Main Street". The deliverToAddress has no data-bind what so ever when the page initially loads. However once the sameAsShipToAddress checked box gets checked, I want to add a data-bind attribute to the deliverToAddress so it too will look at the kendo view model's address variable.
Here is the HTML:
<input id="shipToAddress"
data-bind="value: address" />
<input type="checkbox"
id="deliverSameAsShipTo"
value="deliverSameAsShipTo"
data-bind="checked: sameAsShipToAddress,
events: { click: differentDeliveryAddress }" />
<input id="deliverToAddress" />
And here is the backend Kendo View Model:
var _vm = kendo.observable({
address: "",
sameAsShipToAddress: false,
differentDeliveryAddress() {
if (!this.sameAsShipToAddress)
$("#deliverToAddress").attr("data-bind", "value: address");
else
$("#deliverToAddress").removeAttr("data-bind");
}
});
Can this be done? I feel like I'm close with the following code but currently the deliverToAddress' value property is not getting set. Do I need to some how refresh the deliverToAddress element's attributes?
Your code works correctly and you are very close to the final solution. Instead of setting the value of the bound field, set the "binding definition" as the property value:
$("#deliverToAddress").attr("data-bind", "value: address");
The ViewModel is already bidirectionally bound, so rebind the model and the binding will work in both directions.
After adding the property (and thus binding to the address field of the ViewModel) you need to set also the value of the deliverToAddress field. After that the binding resp. unbinding (set the value to empty string here) works correctly - you can see using the browser DOM explorer, that the attribute is added - change the address text and click the test button - deliverToAddress changes too.
I have created an example in the Telerik Dojo.
The view model code looks like this (I have added a button to test the behaviour):
$(document).ready(function(){
var vm = kendo.observable({
address: "",
sameAsShipToAddress: false
});
kendo.bind(document.body, vm);
//
$("#setDeliverAddressButton").kendoButton({
click: function(e) {
console.log(vm.sameAsShipToAddress);
if (vm.sameAsShipToAddress) {
$("#deliverToAddress").attr("data-bind", "value: address");
$("#deliverToAddress").val(vm.address);
}
else {
$("#deliverToAddress").removeAttr("data-bind");
$("#deliverToAddress").val("");
}
}
});
$("#triggerChangeButton").kendoButton({
click: function(e) {
kendo.bind(document.body, vm);
}
});
});
The HTML:
<input id="shipToAddress" data-bind="value: address" />
<input type="checkbox"
id="deliverSameAsShipTo"
value="deliverSameAsShipTo"
data-bind="checked: sameAsShipToAddress" />
<input id="deliverToAddress" />
<button role="button" id="setDeliverAddressButton">set deliver address</button>
bidirectional update
Another option (or even you need to do this always) is to trigger the change programatically as described in this discussion: How to update the ViewModel after programatic changes.

AngularJs Ng-Keypress event working wrongly?

I am developing an application in Angularjs. I am using ng-keypress event in input type=text. While typing value in text I'm getting wrong values in the keypress function. For example, the first time if I type "1" I am getting undefined. Second time, typing any other value gives the first value
<input ng-model="NodeId_1" type="text" ng-keypress="getValue()"/>
var angularapp = angular.module('nameapp', []);
angularapp.controller('NameCtrl', function ($scope) {
$scope.getValue = function () {
alert($scope.NodeId_1);//Here first time undefined is coming and second what ever we enter first value will come
}
}
)
You'll want to use ng-keyup instead.
ng-keypress happens as the key is pressed, and BEFORE the value populates the input. This is why you're not getting any value on the first keypress, but on subsequent presses you will.
Use ng-keyup and your problem is solved, as it happens once the value has already populated the input.
<input ng-model="NodeId_1" type="text" ng-keyup="getValue()" />
ng-keypress is working as intended, but it is not the directive applicable to your requirements.
Working plunkr: http://plnkr.co/edit/OHWDZo68siDlcrXnLyzJ?p=preview
The keypress event is fired when a key is pressed down and that key
normally produces a character value (use input instead).
https://developer.mozilla.org/en-US/docs/Web/Events/keypress
So neither the input field value nor the scope value(apply/digest loop etc.) will reflect the expected input value.
Solution is depending on your requirements. Here are some:
1) Use another event on the inputfield: change, keyup, ...
2) Use the $event object in your listener method:
<input ng-model="NodeId_1" type="text" ng-keypress="getValue($event)"/>
$scope.getValue = function (event) {
console.log(event)
}
3) Create a watcher for your NodeId_1 value within your scope:
$scope.$watch('NodeId_1', function(newVal) {
...
});
The watcher function work for me, I attached my example
$scope.$watch('itemm.montoAmodificar', function (newValue) {
$scope.fnActualizarNuevoSaldoDependencia(parseFloat(newValue));
});
The html code is the following
<input ng-model="itemm.montoAmodificar" my-focus class="form-control" type="text" placeholder="Ingrese el monto" ng-keypress="fnActualizarNuevoSaldoDependencia($event);" />

Categories