Stop sj:datepicker from opening Struts2 - struts2

I have following <sj:datepicker> :
<sj:datepicker
id="dateFrom_id%{index}"
name="billingItems[%{index}].dateFrom"
value="%{billingItems[#index].dateFrom}"
displayFormat="dd.mm.yy"
cssClass="customDatePicker"
buttonImage="/images/icons/calendar-blue.png"
parentTheme="css_custom"
firstDay="1"
onBeforeTopics="beforeShow"
/>
and the following beforeShow topic:
$.subscribe('beforeShow', function(event, data) {
if($(event.originalEvent.input).attr('readonly')){
// ned to stop event
}
});
How can I stop the event from propagating. I have tried:
event.stopPropagation();
event.preventDefault();
event.stopImmediatePropagation();
but nothing seems to work.

Do not use event.stopImmediatePropagation(); instead use only stopImmediatePropagation();
Try this
$.subscribe('beforeShow', function(event, data) {
if($(event.originalEvent.input).attr('readonly')=="readonly"){
stopImmediatePropagation();
alert('hi');
}
});
alert line will not execute.
Also do not forget to use readonly="true" in your < sj:datepicker ... /> . For example
<sj:datepicker
id="dateFrom_id"
name="dateFrom"
value="%{'today'}"
displayFormat="dd.mm.yy"
buttonImage="images/icon/Calendar-Blue.png"
cssClass="customDatePicker"
firstDay="1"
onBeforeTopics="beforeShow"
readonly="true"
/>

Related

How do I cancel autocomplete with jqueryui?

I have an input field which has an ajax data source autocomplete attached to it.
I have a keyup handler for the input field, which looks for someone pressing enter and when they do it triggers a click on the search button, which ajax loads some data in another div.
The problem is that if the person is quick and types and presses enter, the autocomplete still pops up.
I have tried the following:
Adding $('#autocomplete').autocomplete('close'). This doesn't work, presumably because the autocomplete isn't open yet. If I type, wait for the autocomplete to come up, then press enter, it closes it correctly.
Adding $('#autocomplete').autocomplete('destroy'). This works, but then if I go back to the field to try another search, the autocomplete no longer works.
So what I want is a way to cancel any pending requests and close the autocomplete if it's open, but without disabling or destroying it.
EDIT: Code sample (not my real code, just stubs to demonstrate the issue). Filename is scratch.php
<?php
// Stub for search results
if ($_GET['search'])
{
print "Search results for ".$_GET['search']." here";
exit();
}
// Simulated DB search
if ($_GET['term'])
{
print '[{"label":"A 1"},{"label":"A 2"},{"label":"A 3"},{"label":"A 4"}]';
exit();
}
?>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.1/jquery-ui.js"></script>
<link type="text/css" href="http://code.jquery.com/ui/1.10.1/themes/redmond/jquery-ui.css" rel="stylesheet" />
<script language='javascript'>
$(document).ready(function() {
$('#searchfor').on('keyup',function(e) {
if (e.which == 13) $('#search').trigger('click');
});
$('#searchfor').autocomplete({
source: "/scratch.php",
minLength: 2,
select: function( event, ui ) {
$('#searchfor').val(ui.item.value);
$('#search').trigger('click');
}
});
$('#search').on('click',function() {
try
{
// Cancel any pending autocompletes without destroying the autocomplete completely here.
// This currently doesn't work
$('#searchfor').autocomplete("close");
}
catch(e)
{
// Do nothing except prevent an error
}
$('#results').load('scratch?search='+encodeURIComponent($('#searchfor').val()));
});
});
</script>
</head>
<input id='searchfor' /> <input id='search' type='button' value='search' />
<div id='results'></div>
</html>
One way to go about this is to make the input lose focus. You can do this by using .blur(). How about doing something like this:
JAVASCRIPT:
$(document).ready(function() {
$('#searchfor').on('keyup',function(e) {
if (e.which == 13) $('#search').trigger('click');
$('#searchfor').blur();
});
$('#searchfor').autocomplete({
source: "/scratch.php",
minLength: 2,
select: function( event, ui ) {
$('#searchfor').val(ui.item.value);
$('#search').trigger('click');
}
});
$('#search').on('click',function() {
$('#results').load('scratch?search='+encodeURIComponent($('#searchfor').val()));
});
});
DEMO:
http://jsfiddle.net/dirtyd77/dMjRb/3/
In the current verion of jQuery UI you can use the search event to do some checks before the request to the data source is made
https://api.jqueryui.com/autocomplete/#event-search
let autocompleteData = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
333333,
222222,
111111,
123456
];
$('input').autocomplete({
source: autocompleteData,
search:function(e,u){
let value = e.target.value;
// stops the event from continuing if value integer.
if( Number.isInteger(parseInt(value)) ){
e.preventDefault();
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<input type="text">
assuming you have a one page app.
you can wrap the input with
<form onsubmit="return false;">...<form>
this will catch the enter key or any event that will trigger submit.
then, you can bind the submit event yourself and do:
$('input').blur().focus();
do something with $('input').val();

jQueryUI tooltip Widget to show tooltip on Click

How the new jQueryUI's tooltip widget can be modified to open the tooltip on click event on certain element's on document, while the others are still showing their tootip on mouseover event. In click-open case the tooltip should be closed by clicking somewhere else on the document.
Is this possible at all?
Using jqueryui:
HTML:
<div id="tt" >Test</div>
JS:
$('#tt').on({
"click": function() {
$(this).tooltip({ items: "#tt", content: "Displaying on click"});
$(this).tooltip("open");
},
"mouseout": function() {
$(this).tooltip("disable");
}
});
You can check it using
http://jsfiddle.net/adamovic/A44EB/
Thanks Piradian for helping improve the code.
This code creates a tooltip that stays open until you click outside the tooltip. It works even after you dismiss the tooltip. It's an elaboration of Mladen Adamovic's answer.
Fiddle: http://jsfiddle.net/c6wa4un8/57/
Code:
var id = "#tt";
var $elem = $(id);
$elem.on("mouseenter", function (e) {
e.stopImmediatePropagation();
});
$elem.tooltip({ items: id, content: "Displaying on click"});
$elem.on("click", function (e) {
$elem.tooltip("open");
});
$elem.on("mouseleave", function (e) {
e.stopImmediatePropagation();
});
$(document).mouseup(function (e) {
var container = $(".ui-tooltip");
if (! container.is(e.target) &&
container.has(e.target).length === 0)
{
$elem.tooltip("close");
}
});
This answer is based on working with different classes. When the click event takes place on an element with class 'trigger' the class is changed to 'trigger on' and the mouseenter event is triggered in order to pass it on to jquery ui.
The Mouseout is cancelled in this example to make everything based on click events.
HTML
<p>
<input id="input_box1" />
<button id="trigger1" class="trigger" data-tooltip-id="1" title="bla bla 1">
?</button>
</p>
<p>
<input id="input_box2" />
<button id="trigger2" class="trigger" data-tooltip-id="2" title="bla bla 2">
?</button>
</p>
jQuery
$(document).ready(function(){
$(function () {
//show
$(document).on('click', '.trigger', function () {
$(this).addClass("on");
$(this).tooltip({
items: '.trigger.on',
position: {
my: "left+15 center",
at: "right center",
collision: "flip"
}
});
$(this).trigger('mouseenter');
});
//hide
$(document).on('click', '.trigger.on', function () {
$(this).tooltip('close');
$(this).removeClass("on")
});
//prevent mouseout and other related events from firing their handlers
$(".trigger").on('mouseout', function (e) {
e.stopImmediatePropagation();
});
})
})
http://jsfiddle.net/AK7pv/111/
I have been playing with this issue today, I figured I would share my results...
Using the example from jQueryUI tooltip, custom styling and custom content
I wanted to have a hybrid of these two. I wanted to be able to have a popover and not a tooltip, and the content needed to be custom HTML. So no hover state, but instead a click state.
My JS is like this:
$(function() {
$( document ).tooltip({
items: "input",
content: function() {
return $('.myPopover').html();
},
position: {
my: "center bottom-20",
at: "center top",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
}
});
$('.fireTip').click(function () {
if(!$(this).hasClass('open')) {
$('#age').trigger('mouseover');
$(this).addClass('open');
} else {
$('#age').trigger('mouseout');
$(this).removeClass('open');
}
})
});
The first part is more or less a direct copy of the code example from UI site with the addition of items and content in the tooltip block.
My HTML:
<p>
<input class='hidden' id="age" />
Click me ya bastard
</p>
<div class="myPopover hidden">
<h3>Hi Sten this is the div</h3>
</div>
Bacially we trick the hover state when we click the anchor tag (fireTip class), the input tag that holds the tooltip has a mouseover state invoked, thus firing the tooltip and keeping it up as long as we wish... The CSS is on the fiddle...
Anyways, here is a fiddle to see the interaction a bit better:
http://jsfiddle.net/AK7pv/
This version ensures the tooltip stays visible long enough for user to move mouse over tooltip and stays visible until mouseout. Handy for allowing the user to select some text from tooltip.
$(document).on("click", ".tooltip", function() {
$(this).tooltip(
{
items: ".tooltip",
content: function(){
return $(this).data('description');
},
close: function( event, ui ) {
var me = this;
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(400, 1);
},
function () {
$(this).fadeOut("400", function(){
$(this).remove();
});
}
);
ui.tooltip.on("remove", function(){
$(me).tooltip("destroy");
});
},
}
);
$(this).tooltip("open");
});
HTML
Test
Sample: http://jsfiddle.net/A44EB/123/
Update Mladen Adamovic answer has one drawback. It work only once. Then tooltip is disabled. To make it work each time the code should be supplement with enabling tool tip on click.
$('#tt').on({
"click": function() {
$(this).tooltip({ items: "#tt", content: "Displaying on click"});
$(this).tooltip("enable"); // this line added
$(this).tooltip("open");
},
"mouseout": function() {
$(this).tooltip("disable");
}
});
jsfiddle
http://jsfiddle.net/bh4ctmuj/225/
This may help.
<!-- HTML -->
Click me to see Tooltip
<!-- Jquery code-->
$('a').tooltip({
disabled: true,
close: function( event, ui ) { $(this).tooltip('disable'); }
});
$('a').on('click', function () {
$(this).tooltip('enable').tooltip('open');
});

TinyMCE: How to post use key combination Shift Enter?

I'm using the TinyMCE editor in chat and very uncomfortable to send a message by submit-button.
I would like to know, how post message use "onkeypress" in TinyMCE ?
I do this so:
<script type="text/javascript">
tinyMCE.init({
...
setup : function(ed) {
ed.onKeyPress.add(
function (ed, evt) {
if(evt.shiftKey && evt.keyCode == 13) {
AjaxPost();
//alert('shift + enter key');
return;
}
});
}
...
</script>
<script type="text/javascript">
function PostAjax()
{
var Message=document.getElementById('Message').value;
$.ajax({
type: "POST",
url: "PostTinyMCE.php?Message="+Message,
success: function(html)
{
$("#General").html(html);
}
});
}
</script>
<textarea name="content" id="Message" style="width:100%"></textarea>
but it does not give me the desired effect, functions AjaxPost(); does't start, where is my mistake?
Please help me...
Use an alert statement in function AjaxPost to check if the function AjaxPost(); gets executed. If no, try to place your js function before the tinymce init. If yes you need to verify your ajax code.

how to make datetimepicker readonly in struts 2 compatible with ie7

I'm using the Dojo Struts2 datetimepicker, But textfield is editable with the keyboard. I want it in readonly.
I know that this question is answered on another thread, but the solution isn't compatible with ie7, wich is required for me.
The solution in the another thread is:
window.onload = function() {
document.getElementsByName("dojo.test")[0].setAttribute("readOnly","true");
}
But, when I try that on IE7, I get a javascript error:
'document.getElementsByName(...).0' is null or not an object
I read about that, and chage it to:
'document.getElementsBy**Id**(...).0'
But I get another error: The object doesn't support that property.
Any suggestions?
I just wondering if I could change the template of the datetimepicker as I did with a simple Struts2 template... That will solve the problem
<script type="text/javascript">
$(document).ready(function() {
makeReadonly();
});
function makeReadonly() {
setTimeout(function () {
$(".calendar").attr('readonly', 'readonly');
}, 1000);
}
</script>
<td>
<sx:datetimepicker name="up_bod" displayFormat="yyyy-MM-dd" cssClass="rounded calendar" >
</sx:datetimepicker>
</td>
Nice Question.
Use following script. This will work in all browsers.
< % # taglib prefix="sd" uri="/struts-dojo-tags" % >
<head>
<sd:head/>
</head>
< script type="text/javascript">
window.onload = function() {
document.getElementById('fromDate').children[1].setAttribute("readOnly","true");
};
</ script>
<sd:datetimepicker name="fromDate" id="fromDate" label="From Date" />
I hope this will work for you.

jquery close datepicker when input lose focus

I'm using datepicker inside my input , my last field is the datepicker input , after validating it i want to set focus on another input inside my form , but the problem is the datepicker is not closed even taht it does not have the focus..
how can I close the datepicker when i set the focus on another input field?
(I tried .datepicker("hide"); but it did not worked for me).
UPDATE:
this is my code:
$(function()
{ $( "#test_date" ).datepicker({
dateFormat: "dd/mm/yy"
});
});
//when i call my function:
$( "#test_date" ).datepicker("hide"); //---> this does not work!
Thank's In Advance.
Question Edited to work with the latest version of jqueryUI
JqueryUi auto-closes the datepicker when an element loses focus by user interaction, but not when changing focus with JS.
Where you are calling your function which removes focus from the input assigned a datepicker you also need to call:
$("#test_date ~ .ui-datepicker").hide();
This code is hiding the datepicker which is a sibling (~) of #test_date.
To be dynamic, and using the class assigned by jQueryui you can do:
$(".hasDatepicker").on("blur", function(e) { $(this).off("focus").datepicker("hide"); });
;(function() {
function eventOnFocusDP(e, par) {
if (par.ver == $.fn.jquery) {
if (this.tmr) clearTimeout(this.tmr);
par.lbl1.text(par.msgs[1]);
this.tmr = setTimeout(function() { par.inpNP.focus(); }, par.secs*1e3);
}
}
function eventOnFocusNP(e, par) {
if (par.ver == $.fn.jquery) {
par.lbl1.text(par.msgs[0]);
par.lbl2.text(par.msgs[2]);
}
}
function eventOnBlurNP(e, par) {
if (par.ver == $.fn.jquery) par.lbl2.text("");
}
function eventOnBlurHDP(e, par) {
if (par.ver == $.fn.jquery) {
$(this).off("focus").datepicker("hide");
}
}
function test(secs) {
this.ver = $.fn.jquery;
this.secs = (typeof secs)=='number'?secs:2;
this.msgs = [
'This will lose focus to box below '+this.secs+' seconds after it gains focus.',
'Losing focus in '+this.secs+' seconds!',
'Focus now on bottom box.'
];
this.inpDP = $('[name=datePicker]');
this.inpNP = $('[name=nextPicker]');
this.lbl1 = $('#dPMsg').text(this.msgs[0]);
this.lbl2 = $('#dPMsg2');
var par = this;
this.inpDP.datepicker({ dateFormat: "dd/mm/yy" })
.on('focus', function(e) { eventOnFocusDP.apply(this, [e, par]) });
this.inpNP.on('focus', function(e) { eventOnFocusNP.apply(this, [e, par]) });
this.inpNP.on('blur', function(e) { eventOnBlurNP.apply(this, [e, par]) });
$(document).on('blur', '.hasDatepicker', function(e) { eventOnBlurHDP.apply(this, [e, par]) });
return this;
}
function init() {
window.Test = test;
setTimeout(function() {
$(document).on('change', '.switcher, .switcher-ui', function(e) { if (window.Test) new Test(); });
$(jQueryUISwitcher).trigger('change');
}, 1e3);
}
if (document.readyState == "complete") init();
else jQuery(window).on('load', init);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/JDMcKinstry/cfc32292cbbfa548fb9584db05b2b2fc/raw/4f16f7ee441dfb98aa166a2e84193b14574a46d1/jquery.switcher.js"></script>
<form action="javascript: void 0">
<input type="text" name="datePicker" id="dP" placeholder="mm/dd/yyyy" />
<label for="dP" id="dPMsg"></label>
<hr />
<input type="text" name="nextPicker" placeholder="tab to here" />
<label for="dP" id="dPMsg2"></label>
</form>
<hr />
<hr />
<hr />
Here's a modified solution that worked for me:
$(".hasDatepicker").each(function (index, element) {
var context = $(this);
context.on("blur", function (e) {
// The setTimeout is the key here.
setTimeout(function () {
if (!context.is(':focus')) {
$(context).datepicker("hide");
}
}, 250);
});
});
My version of js:
<script type="text/javascript"> $(function () {
$("#dtp1").on("dp.change", function (e) {
$('#dtp1').data("DateTimePicker").hide();
});
});
I hope it's help you
This worked for me:
$("#datepickerTo").datepicker({
onSelect: function () {
$(this).off( "focus" );
}
});

Resources