Primefaces 4.0, calendar with timeOnly, onchange event not working expectedly? - javascript

I use calendar with timeOnly attribute likes:
<p:calendar pattern="HH:mm" timeOnly="true" value="#{data.currentAbsenceData.ABZTIMF}" id="xabsQuickFromTime" onchange="calculateQuickHour();" timeZone="#{data.timeZone}"/>
<p:calendar pattern="HH:mm" timeOnly="true" value="#{data.currentAbsenceData.ABZTIMT}" id="xabsQuickToTime" onchange="calculateQuickHour();" timeZone="#{data.timeZone}"/>
<p:inputText id="xabsQuickHourInput" value="#{data.currentAbsenceData.ABZDAYI}">
Javascript code:
function calculateQuickHour(){
console.log("hello _ calculateQuickHour");
getHourValue('xabsQuickFromTime', 'xabsQuickToTime', 'xabsQuickHourInput');
}
Well, I use the slider of the calendar to change the value of its input field, the value of the input field changes perfectly but the javascript function is not called by "onchange" event. This works fine in Primefaces 3.5. So, what is the possible event that should be used in this case?

Try this:
<p:ajax event="dateSelect" oncomplete="calculateQuickHour();"/>

Have a look at org.primefaces.component.calendar.Calendar.EVENT_NAMES to see all events valid for calendar. If you don't know wich class implements your component have a look in the corresponding taglib.
If in some case this doesn't help you can set something invalid and a breakpoint on that particular exception at any time. Just before the exception is thrown there will be some code comparing your invalid value against the valid ones.

Related

bootstrap-datepicker does not update AngularJS model when picking date

I am using AngularJS with this bootstrap-datepicker plugin:
Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)
Copyright 2012 Stefan Petre
Improvements by Andrew Rowls
I have it bound like this:
<input type="text" data-provide="datepicker" ng-model="obj.FirstDate" />
I get the values to inputs using ng-model.
When I type the date into this field using keyboard it all works OK, but when I click on a field and select a date from the Datepicker:
the model doesn't get updated,
the field is not treated as dirty (no ng-dirty class).
Is there a way to tell Angular to update value of obj.FirstDate when using the Datepicker? For example to attach it to an event? Or any other way that this would work?
I have a few of these fields so I don't want to write the script which attaches to a field using its id. Any help appreciated.
After much time of struggling with this I was forced to use below code to fix every of my datepicker instances at once:
function fixDatepickerTriggerChange() {
$(document).ready(function () {
$('[data-provide="datepicker"]').datepicker().on('changeDate', function (e) {
angular.element($(this)).triggerHandler('input');
});
});
}
And run it from within the angular.controller.
Based on this answer: https://stackoverflow.com/a/23850753/1813219.

Set focus to a form element using JavaScript / RichFaces

I am using JSF 1.2 and RichFaces. I have a requirement where on click of command button (<h:commandButton>) RichFaces data table will be displayed with 3 set of rows, This is working fine but the problem is I need to set the focus in the text box of data table which is not working. Please find the sample code I am working with.
Command button :
<a4j:commandButton immediate="true"
action="#{bean.addTomethod}"
reRender="myform"
oncomplete= "setFocusOnRichComponenet();"
rendered="true">
</a4j:commandButton>
JavaScript code :
function setFocusOnRichComponenet(){
document.getElementById("myform:richDataTableList:0:richTextBoxID").focus();
}
Here, myform:richDataTableList:0:richTextBoxID is the id of the component where I want to put focus.
When the id is generated dynamically, it can be erroneous at times to try to refer using document.getElementById as you must know the full id.
Simpler way to do this is use the RichFaces method clientId('elementName')
This will basically resolve the exact id so you don't have to refer by tableName[].Element[] format.
So for your scenario, you could replace the javascript function as below:
function setFocusOnRichComponenet(){
document.getElementById("#{rich:clientId('myTextBox')}").focus();
}
where 'myTextBox' is the name of the textbox you are trying to refer
Add a class in input:
<h:inputText id="test" class="testClass"/>
In function set focus by class with jQuery:
function setFocusOnRichComponenet(){
jQuery(".testClass").focus();
}

Fire change-event manually

Hey I've got a problem with fireing a change-event manually.
So I have a selectOneMenu (i'ts like a dropdown in jsf) with different values.
If I choose a value of this dropdown-list, a datatable should be updated. This works correctly, if i choose this value manually.
Now there is a case, where I need to insert a new value to the selectOneMenu. This new value gets selected automatically, but the change-event to update the datatable doesn't get fired...
So basically I have this button to save a new value to the selectOneMenu which then gets selected correctly, but the datatable doesn't get updated, which is why I tried to write the function fireChange() and gave that to the oncomplete of the button:
<p:commandButton ajax="true" id="seatingPlanSave" actionListener="#{EventAssistentController.createSeatingPlan}" value="#{msg.save}" update=":createEvent:EventSeatingPlan, :createEvent:ticketTypePrices" oncomplete="fireChange()"/>
For the fireChange()-function, i tried a few different things:
function fireChange() {
var element = document.getElementById("createEvent:EventSeatingPlan_input");
element.change();
}
function fireChange() {
var element = document.getElementById("createEvent:EventSeatingPlan_input");
$(element).trigger("change");
}
function fireChange() {
if ("fireEvent" in element)
element.fireEvent("onchange");
else {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
element.dispatchEvent(evt);
}
}
But none of these work :(
Can you please tell me how I can achieve this?
Thanks, Xera
You didn't tell anything about the HTML representation of createEvent:EventSeatingPlan_input while that's mandatory for us (and you!) in order to know how to let JS intercept on that. You didn't tell either if you were using <h:selectOneMenu> or <p:selectOneMenu>, so we can't take a look ourselves in the generated HTML representation. The former generates a <select><option> while the latter generates an <div><ul><li> which interacts with a hidden <select><option>. Both representations of dropdown menus require a different approach in JS. Also, information about how you're registering the change event handler function is mandatory. Is it by hardocing the onchange attribute, or by embedding a <f:ajax> or <p:ajax>?
In any way, based on the information provided so far, I'll guess that you've a
<h:selectOneMenu ...>
<f:ajax render="dataTableId" />
</h:selectOneMenu>
which will generate a <select onchange="..."><option>.
As per your first attempt:
function fireChange() {
var element = document.getElementById("createEvent:EventSeatingPlan_input");
element.change();
}
This will fail on <h:selectOneMenu> because HTMLSelectElement interface doesn't have a change property nor method. Instead, it is onchange property which returns a event handler which can directly be invoked by appending ().
The following will work on <h:selectOneMenu>:
function fireChange() {
var element = document.getElementById("createEvent:EventSeatingPlan_input");
element.onchange();
}
However this will in turn fail in <p:selectOneMenu>, because it returns a HTMLDivElement instead of HtmlSelectElement. The HTMLDivElement doesn't have a onchange property which returns an event handler. As said, the <p:selectOneMenu> generates a <div><ul><li> widget which interacts with a hidden <select><option>. You should be registering this widget in JS context and then use its special triggerChange() method.
So, given a
<p:selectOneMenu widgetVar="w_menu" ...>
<p:ajax update="dateTableId" />
</p:selectOneMenu>
this should do
function fireChange() {
w_menu.triggerChange();
}

html <input type="text" /> onchange event not working

I am trying to do some experiment. What I want to happen is that everytime the user types in something in the textbox, it will be displayed in a dialog box. I used the onchange event property to make it happen but it doesn't work. I still need to press the submit button to make it work. I read about AJAX and I am thinking to learn about this. Do I still need AJAX to make it work or is simple JavaScript enough? Please help.
index.php
<script type="text/javascript" src="javascript.js"> </script>
<form action="index.php" method="get">
Integer 1: <input type="text" id="num1" name="num1" onchange="checkInput('num1');" /> <br />
Integer 2: <input type="text" id="num2" name="num2" onchange="checkInput('num2');" /> <br />
<input type="submit" value="Compute" />
</form>
javascript.js
function checkInput(textbox) {
var textInput = document.getElementById(textbox).value;
alert(textInput);
}
onchange is only triggered when the control is blurred. Try onkeypress instead.
Use .on('input'... to monitor every change to an input (paste, keyup, etc) from jQuery 1.7 and above.
For static and dynamic inputs:
$(document).on('input', '.my-class', function(){
alert('Input changed');
});
For static inputs only:
$('.my-class').on('input', function(){
alert('Input changed');
});
JSFiddle with static/dynamic example: https://jsfiddle.net/op0zqrgy/7/
HTML5 defines an oninput event to catch all direct changes. it works for me.
Checking for keystrokes is only a partial solution, because it's possible to change the contents of an input field using mouse clicks. If you right-click into a text field you'll have cut and paste options that you can use to change the value without making a keystroke. Likewise, if autocomplete is enabled then you can left-click into a field and get a dropdown of previously entered text, and you can select from among your choices using a mouse click. Keystroke trapping will not detect either of these types of changes.
Sadly, there is no "onchange" event that reports changes immediately, at least as far as I know. But there is a solution that works for all cases: set up a timing event using setInterval().
Let's say that your input field has an id and name of "city":
<input type="text" name="city" id="city" />
Have a global variable named "city":
var city = "";
Add this to your page initialization:
setInterval(lookForCityChange, 100);
Then define a lookForCityChange() function:
function lookForCityChange()
{
var newCity = document.getElementById("city").value;
if (newCity != city) {
city = newCity;
doSomething(city); // do whatever you need to do
}
}
In this example, the value of "city" is checked every 100 milliseconds, which you can adjust according to your needs. If you like, use an anonymous function instead of defining lookForCityChange(). Be aware that your code or even the browser might provide an initial value for the input field so you might be notified of a "change" before the user does anything; adjust your code as necessary.
If the idea of a timing event going off every tenth of a second seems ungainly, you can initiate the timer when the input field receives the focus and terminate it (with clearInterval()) upon a blur. I don't think it's possible to change the value of an input field without its receiving the focus, so turning the timer on and off in this fashion should be safe.
onchange only occurs when the change to the input element is committed by the user, most of the time this is when the element loses focus.
if you want your function to fire everytime the element value changes you should use the oninput event - this is better than the key up/down events as the value can be changed with the user's mouse ie pasted in, or auto-fill etc
Read more about the change event here
Read more about the input event here
use following events instead of "onchange"
- onkeyup(event)
- onkeydown(event)
- onkeypress(event)
Firstly, what 'doesn't work'? Do you not see the alert?
Also, Your code could be simplified to this
<input type="text" id="num1" name="num1" onkeydown="checkInput(this);" /> <br />
function checkInput(obj) {
alert(obj.value);
}
I encountered issues where Safari wasn't firing "onchange" events on a text input field. I used a jQuery 1.7.2 "change" event and it didn't work either. I ended up using ZURB's textchange event. It works with mouseevents and can fire without leaving the field:
http://www.zurb.com/playground/jquery-text-change-custom-event
$('.inputClassToBind').bind('textchange', function (event, previousText) {
alert($(this).attr('id'));
});
A couple of comments that IMO are important:
input elements not not emitting 'change' event until USER action ENTER or blur await IS the correct behavior.
The event you want to use is "input" ("oninput"). Here is well demonstrated the different between the two: https://javascript.info/events-change-input
The two events signal two different user gestures/moments ("input" event means user is writing or navigating a select list options, but still didn't confirm the change. "change" means user did changed the value (with an enter or blur our)
Listening for key events like many here recommended is a bad practice in this case. (like people modifying the default behavior of ENTER on inputs)...
jQuery has nothing to do with this. This is all in HTML standard.
If you have problems understanding WHY this is the correct behavior, perhaps is helpful, as experiment, use your text editor or browser without a mouse/pad, just a keyboard.
My two cents.
onkeyup worked for me. onkeypress doesn't trigger when pressing back space.
It is better to use onchange(event) with <select>.
With <input> you can use below event:
- onkeyup(event)
- onkeydown(event)
- onkeypress(event)
when we use onchange while you are typing in input field – there’s no event. But when you move the focus somewhere else, for instance, click on a button – there will be a change event
you can use oninput
The oninput event triggers every time after a value is modified by the user.Unlike keyboard events, it triggers on any value change, even those that does not involve keyboard actions: pasting with a mouse or using speech recognition to dictate the text.
<input type="text" id="input"> oninput: <span id="result"></span>
<script>
input.oninput = function() {
console.log(input.value);
};
</script>
If we want to handle every modification of an <input> then this event is the best choice.
I have been facing the same issue until I figured out how to do it. You can utilize a React hook, useEffect, to write a JS function that will trigger after React rendering.
useEffect(()=>{
document.title='fix onChange with onkeyup';
const box = document.getElementById('changeBox');
box.onkeyup = function () {
console.log(box.value);
}
},[]);
Note onchange is not fired when the value of an input is changed. It is only changed when the input’s value is changed and then the input is blurred. What you’ll need to do is capture the keypress event when fired in the given input and that's why we have used onkeyup menthod.
In the functional component where you have the <Input/> for the <form/>write this
<form onSubmit={handleLogin} method='POST'>
<input
aria-label= 'Enter Email Address'
type='text'
placeholder='Email Address'
className='text-sm text-gray-base w-full mr-3 py-5 px-4 h-2 border border-gray-primary rounded mb-2'
id='changeBox'
/>
</form>
Resulting Image :
Console Image
try onpropertychange.
it only works for IE.

Dojo: dojo onblur events

I have a form setup with dojo 1.5. I am using a dijit.form.ComboBox and a dijit.form.TextBox
The Combobox has values like "car","bike","motorcycle" and the textbox is meant to be an adjective to the Combobox.
So it doesn't matter what is in the Combobox but if the ComboBox does have a value then something MUST be filled in the TextBox. Optionally, if nothing is in the ComboBox, then nothing can be in the TextBox and that is just fine. In fact if something isn't in the Combobox then nothing MUST be in the text box.
In regular coding I would just use an onBlur event on the text box to go to a function that checks to see if the ComboBox has a value. I see in dojo that this doesn't work... Code example is below...
Vehicle:
<input dojoType="dijit.form.ComboBox"
store="xvarStore"
value=""
searchAttr="name"
name="vehicle_1"
id="vehicle_1"
/>
Descriptor:
<input type="text"
dojoType="dijit.form.TextBox"
value=""
class=lighttext
style="width:350px;height:19px"
id="filter_value_1"
name="filter_value_1"
/>
My initial attempt was to add an onBlur within the Descriptor's <input> tag but discovered that that doesn't work.
How does Dojo handle this? Is it via a dojo.connect parameter? Even though in the example above the combobox has an id of "vehicle_1" and the text box has an id of "filter_value_1", there can be numerous comboboxes and textboxes numbering sequentially upward. (vehicle_2, vehicle_3, etc)
Any advice or links to resources would be greatly appreciated.
To add the onBlur event you should use dojo.connect():
dojo.connect(dojo.byId("vehicle_1"), "onBlur", function() { /* do something */ });
If you have multiple inputs that you need to connect this to, consider adding a custom class for those that need to blur and using dojo.query to connect to all of them:
Vehicle:
<input dojoType="dijit.form.ComboBox"
store="xvarStore"
class="blurEvent"
value=""
searchAttr="name"
name="vehicle_1"
id="vehicle_1"
/>
dojo.query(".blurEvent").forEach(function(node, index, arr) {
dojo.connect(node, "onBlur", function() { /* do something */ });
});
In the function that is passed to dojo.connect you could add in some code to strip out the number on the end and use it to reference each filter_value_* input for validation.
dojo.connect()
Combobox documention
onBlur seems to work just fine for me, even in the HTML-declared widgets. Here's a very rudimentary example:
http://jsfiddle.net/kfranqueiro/BWT4U/
(Have firebug/webkit inspector/IE8 dev tools open to see console.log messages.)
However, for a more ideal solution to this, you might also be interested in some other widgets...
http://dojotoolkit.org/reference-guide/dijit/form/ValidationTextbox.html
http://dojotoolkit.org/reference-guide/dijit/form/Form.html
Hopefully this can get you started.

Categories