Fullcalendar add static events using modal duplicates rendered entries - modal-dialog

I am trying to add static "Training"-events using a button located in a modal.
So what should happen: Clicking on a day or a range of days in fullcalendar opens a modal. In this modal a button is available to "add a training event".
I am using this modal because it shall be possible to add other events in future. Not just trainings.
The modal opens fine and clicking the button adds a new entry in fullcalendar. Clicking on a further day opens the modal again. If now the "add a training button" is clicked again, the new event is rendered twice. One event is rendered on the day i have clicked in the first step, the second is rendered at the day i have clicked now.
Step1:
clicking a day opens the modal
Step2:
clicking the button in the modal adds a new entry
Step3: repeating step1 on another day
Step4:
clicking the button again renders the event twice
Image: Step1-4
This is my js-code. What i am doing wrong?
var calendar = $(calendar).fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: new Date(),
navLinks: true, // can click day/week names to navigate views
selectable: true,
selectHelper: true,
select: function (start, end) {
$('#fc_create').click(); // opens modal
$('.addTraining').on("click", function () { // clicking "add training button"
var eventData;
eventData = {
title: "Training",
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData);
$('.close').click();
})
},
editable: true,
eventLimit: true
});

Every time your "select" callback runs, you are adding another new "click" event handler to the "addTraining" element(s). So if "select" runs 3 times, then the "click" event will be declared 3 times, and when "addTraining" is clicked, 3 versions of the same code will run. Javascript allows multiple handlers for the same event to be attached to an element at once, so you are just building them up each time the "select" callback runs, without ever removing them.
To fix this you can either:
1) Declare the handler once - do it page load, outside your fullCalendar declaration. This will give you a problem in that you won't have direct access to the "start"/"end" values from the select callback. You can get round this by using global variables (yuck) or perhaps putting the values in hidden fields or data- attributes somewhere suitable, and then the click handler can find them each time it runs.
2) Using jQuery's "on" and "off" syntax to first remove the previous handler, and then add a new one, so only one handler is ever active at any one time. See http://api.jquery.com/off/ and http://api.jquery.com/on/ for more details and examples. I can provide a sample if necessary.

Related

How to dynamically create and destroy datepicker in materializecss

I want to initialize and destroy datepicker in materializecss. I know how to initialize but unable to find it how to destroy.
I have one textbox and one dropdown.based on dropdown, the textbox type is changed. so when user select dob, I initialized textbox with materializecss datepicker but after that I am not able to change textbox back to its normal mode, I mean where user can insert text or number.
I am using below code to initialize -
$('#txtDatePicker').pickadate({
selectMonths: true, // Creates a dropdown to control month
selectYears: 100 // Creates a dropdown of 15 years to control year
});
A datepicker usually has 3 buttons, however if these buttons are initialized without values ie. today: "" they will not be shown.
$('.datepicker').pickadate({
today: '',
clear: 'Clear selection',
close: 'Cancel'
});
For more information see: http://amsul.ca/pickadate.js/date/#buttons
From your comment
so lets say you have initialized date picker and now I want to destroy it, so that simple text can be written into it.
I think that if you only need a simple text can be written into it. Just add an option like this
$('.datepicker').pickadate({
editable: true
});

How to Set Initial Focus in a View?

I have a Detail view in an SAPUI5 app which contains a single input field with ID "bestellmenge_tu". Whenever this view is called, the focus should be on that input field. Unfortunately, when setting the focus on the field in the controller's onInit method, the focus will be set but some milliseconds later the UI5 takes it away and transfers it to the "navigation back" button of the detail view.
By putting a log.trace() on the input field's blur event, I found out that the focus is taken away by a method called sap.ui.define.NavContainer._afterTransitionCallback which is called asynchronously (some window.setTimeouts between trigger and execution). The function simply looks for the first focusable element in the view and brutally switches the focus on it.
My workaround was to redefine the method jQuery.fn.firstFocusableDomRef which is used to find this "first focusable element":
// DIESE KANONE FUNKTIONIERT
jQuery.fn.firstFocusableDomRef = (function() {
var _default = jQuery.fn.firstFocusableDomRef;
return function() {
var bestellmenge_tu = document.querySelector("input[id$='bestellmenge_tu-inner']");
if (bestellmenge_tu &&
bestellmenge_tu.style.display !="none" &&
bestellmenge_tu.style.visibility != "hidden") return bestellmenge_tu;
else return _default.apply(this);
}
})();
But this could be a performance issue (querySelector called during DOM transversal at any page load from there on), and it is too much coding for the desired effect.
Is there an easier method to achieve this?
I thought of something like
<mvc:View controllerName="zrt_dispo.view.Detail"...>
<Page id="detailPage" initialFocus="bestellmenge_tu"> <!-- ID of the element to carry the focus -->
</Page>
</mvc:view>
Here is a working example: https://embed.plnkr.co/wp6yes/
<App autoFocus="false" xmlns="sap.m"> <!-- AND/OR -->
<f:FlexibleColumnLayout autoFocus="false" xmlns:f="sap.f" /> <!-- autoFocus in FCL available since 1.76 -->
{ // Controller of the target view:
onInit: function() {
this.attachAfterShow(this.onAfterShow);
},
attachAfterShow: function(onAfterShow) {
this._afterShowDelegate = { onAfterShow };
this.getView().addEventDelegate(this._afterShowDelegate, this);
},
onAfterShow: function() {
this.byId("thatControl").focus();
},
onExit: function() { // detach delegates
this.getView().removeEventDelegate(this._afterShowDelegate);
this._afterShowDelegate = null;
}
}
If you have a sap.m.NavContainer (I.e. sap.m.App or in sap.f.FlexibleColumnLayout), its direct child, aka. NavContainerChild which is usually a View, can react to navigation related events. Add a delegate to the NavContainerChild event afterShow according to the API reference of NavContainer:
The afterShow event can be used to focus another element, only if autoFocus is set to false.
The event handler is fired after the animation is finished. And most importantly:
This event is fired every time (in contrast to onAfterRendering) when the NavContainer has made this child control visible.
Since sap.ui.core.Control extends sap.ui.core.Element, every control can receive the focus via focus().
Known Issues in Older UI5 Versions
SAP Fiori launchpad (FLP) running with older SAPUI5 versions might take the control of the initial focus for the first app launch: FLP: Setting Custom Initial Focus on App Launch Fails
However, it's no longer reproducible (Let me know if otherwise).
In UI5 1.62 and below, calling focus() in onAfterShow alone would still make the app set the focus on the first focusable element when the user navigates back, even with autoFocus="false" (See this GitHub issue #2306). In that case, an additional setTimeout with 0 ms (or requestAnimationFrame) is needed in order to let the browser know that the element should be focused at the end of the call stack.
onAfterShow: function() {
// Only if UI5 version < 1.63:
setTimeout(() => this.byId("thatControl").focus());
},
With commit:6d46cf0, the fix is available as of 1.63.
The NavContainer has a property autoFocus. App is a descendant of NavContainer so it has that property too.
The help (as linked above) states the following:
Determines whether the initial focus is set automatically on first rendering and after navigating to a new page. This is useful when on touch devices the keyboard pops out due to the focus being automatically set on an input field. If necessary the "afterShow" event can be used to focus another element.
Default value is true.

TinyMCE capture click button event

is it possible in TinyMCE to know which button was clicked? so I could place specific action on specific event of a specific button.
the buttons here are default control-buttons like bold/italic/select-font not a custom button one.
probably in the init, but I have no idea what to call. I could capture the editor's events but not the button's.
For example, let's say I want a messagebox popped-up everytime bold button is clicked. How to capture the click event of bold button? is creating custom button the only way?
No, you can define an own command and call this command (+ the defualt action) on buttonklick. I do not know if you want a generic way for all buttons. But it is easy to do it just for one or two buttons.
Example: We want to put an action on the bold button.
First we define an own command in one of our own plugins (in the "init : function(ed, url)" -section):
ed.addCommand('my_bold', this.my_bold, this); //calls the function my_bold
Then we overwrite the default action with an the command:
if (ed.controlManager.get('bold')){
ed.controlManager.get('bold').settings.cmd='my_bold_action';
};
Now, we only need to define the function my bold
my_bold: function() {
// exectution of regular command
this.editor.execCommand('Bold');
// now do whatever you like here
...
},
ed.controlManager must be called in "onInit" methode :
ed.onInit.add(function(editor) {
.......
........
if (editor.controlManager.get('bold')){
editor.controlManager.get('bold').settings.cmd='my_bold_action';
};
});

JQgrid:Get the action from the pager

how can i get the action (what button was clicked) when a button is clicked in the pager?(edit, del, add...)
You probably means button of the navigation bar or navigator (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:navigator).
You can implement what you want with at least three different ways:
You define your custom buttons which look like the original add/edit/del buttons (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:custom_buttons) and use {add:false, edit: false, del: off} parameter of navGrid to switch off standard buttons.
You can use addfunc, editfunc and delfunc if you want replace the default add/edit/del functions.
You can use onclickSubmit or afterSubmit or some another supported events (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:form_editing#events) of add/edit/del button to do some additional action on click the buttont or on submit.
You can chose the way which is the best for your requirements.
You can use the grid onPaging event:
This event fires after click on [page
button] and before populating the
data. Also works when the user enters
a new page number in the page input
box (and presses [Enter]) and when the
number of requested records is changed
via the select box. To this event we
pass only one parameter pgButton
(string) which can be -
first,last,prev,next in case of button
click, records in case when a number
of requested rows is changed and user
when the user change the number of the
requested page.requested page.
Also there are beforeRequest and LoadComplete events. Examples that worked for me are as follows:
beforeRequest: function () {
$.blockUI();
//alert("before request");
},
loadComplete: function () {
//alert("load complete");
$.unblockUI();
}

Dojo: dijit.form.select won't fire "onClick" event the first time clicked

I've been through the Dojo docs as well as the API and tried Google but can't find a solution to my problem, I hope anybody here can help me out.
I'm trying to create a dijit.form.select programmatically (using Dojo 1.4) and connect to the "onClick"-event of the widget.
Here's a part of my code:
var dataSelect = new dijit.form.Select({
id : "myselect",
name : "myselect",
labelAttr: "label",
labelType: "html"
},
"selectid");
dataSelect.addOption({value: "value", label: "first item label"});
dojo.connect(dataSelect, "onClick", function() {
alert("clicked!");
});
What it does: A select-box is created replacing an input-field with the ID "selectid", an option "first item label" is created. Everythings all right until here.
Then I connect to the "onClick"-event of the select, which is supposed to load more options via AJAX (but will just display an alert for testing purposes in this example).
The problem: When I click on the little arrow next to the dropdown, the event is fired (OK). But when I click on the select box itself (the area containing the option), the event is NOT fired the first time I click it (unless I clicked on the arrow before).
When I click the select box a second time (and every time after that), the event will fire!
I've tried to use "onFocus" instead of "onClick" which does work, but then the dropdown will not open when first clicked, even if I use the "openDropDown"-function (which does work when connecting to "onClick"!).
Is it me, did I run into a Dojo bug or is it a strange feature I just don't get?
Any help is appreciated.
Greetings,
Select0r
Here is a cross-browser solution:
var sizeSelect = new dijit.form.Select({
id: "sizeSelect",
name: "state",
options: size,
onChange: function(val) {
dojo.style(dojo.byId("textInput"), {"fontSize":val});
}
}, "sizeSelect");
Try to connect not to the widget itself but to it's dom node:
dojo.connect(dataSelect.domNode, "onclick", function() {
alert("clicked!");
});
Select (which extends _HasDropDown) has fancy code to handle:
mouse down on select widget
mouse move to one of the options
mouse up
Maybe that's canceling the click event.
Maybe you can connect to _loadChildren() instead.
The root cause for this issue is that the _onDropDownMouseDown method of dijit._HasDropDown will manipulate the dom node, which cause the e.target of onmousedown and onmouseup changes for the first initialization.
As we know, the onclick event will be triggered only when the target of onmousedown and onmouseup are the same target.
So in this case, the onclick event is not triggered.
It seems that in Dojo 1.5, the problem still remains.