Custom and predefined action reactable - r

Is it somehow possible to have a custom action and using one of the predefined action, e.g. onClick = "select"?
I would like to use the onClick select and an additional JS function.
Example:
onClick = "select" + JS("function(rowInfo, column) {
// Only handle click events on the 'details' column
if (column.id !== 'details') {
return
}
// Display an alert dialog with details for the row
window.alert('Details for row ' + rowInfo.index + ':\\n' + JSON.stringify(rowInfo.values, null, 2))
// Send the click event to Shiny, which will be available in input$show_details
// Note that the row index starts at 0 in JavaScript, so we add 1
if (window.Shiny) {
Shiny.setInputValue('show_details', { index: rowInfo.index + 1 }, { priority: 'event' })
}
}")

This will do
library(reactable)
reactable(iris[1:5, ], selection = "multiple", onClick = JS(
"function(rowInfo, column){
var rowIdx = rowInfo.index;
document.querySelectorAll('.rt-table .rt-tr')[rowIdx + 1].querySelector('.rt-td-select').click()
// add whatever other JS code you want below
// e.g. alert the clicked
alert(`You clicked row No. ${rowIdx + 1}, column ${column.id}`)
}
"
))

Related

fullcalendar.io removeEventSource on dynamic events

I have event sources added to a fullcalendar object dynamically (addEventSource).
I do not understand how to reference these event sources to remove them with removeEventSource.
I have an example here:
http://jsfiddle.net/64L4npzo/
calendar = jQuery("#calendar").fullCalendar();
event_count = 0;
jQuery(document).on("click", ".add_random_event", function() {
event_count++;
var json_source = [ { title : 'event to remove', start : '2015-11-04' } ];
calendar.fullCalendar('addEventSource', json_source);
jQuery("<div class='remove_event_source' event_count='" + event_count + "'>Remove Event " + event_count + "</div><br>").appendTo("#event_removal");
});
jQuery(document).on("click", ".remove_event_source", function() {
calendar.fullCalendar("removeEventSource", jQuery(this).attr("event_count"));
console.log("Tried to remove event #" + jQuery(this).attr("event_count"));
});
I've read this solution but I'm not sure how to apply it: Problem removing event sources from FullCalendar (jQuery)
If you attach your source object as a data attribute to the 'remove this source' button, you can then use that data attribute later as the source in the removeEventSource method.
During addEventSource:
jQuery("<div class='remove_event_source' event_count='" + event_count + "'>Remove Event " + event_count + "</div><br>").data('source', json_source).appendTo("#event_removal");
When using removeEventSource:
calendar.fullCalendar("removeEventSource", jQuery(this).data('source'));
I've also made a few changes to make sure your source object is unique and updated the jsfiddle: http://jsfiddle.net/64L4npzo/4/
To remove events, you need a source. The source may be an object that provides some data about events.
You can see the list of event source options here
So, in your case, I add a className to events and the events would be referred by that className.
calendar = jQuery("#calendar").fullCalendar();
event_count = 0;
var json_source = [ { title : 'event to remove', start : '2015-11-04', className: 'test' } ];
jQuery(document).on("click", ".add_random_event", function() {
event_count++;
calendar.fullCalendar('addEventSource', json_source);
jQuery("<div class='remove_event_source' event_count='" + event_count + "'>Remove Event " + event_count + "</div><br>").appendTo("#event_removal");
});
jQuery(document).on("click", ".remove_event_source", function() {
calendar.fullCalendar("removeEventSource", json_source);
console.log("Tried to remove event #" + jQuery(this).attr("event_count"));
});
The updated fiddle is here.
http://jsfiddle.net/64L4npzo/1/

Simple adding and subtracting puzzle

Okay so here's the story:
I have two buttons with two different controllers(handlers) - A plus and a minus button:
[ + ] addBtn [ - ] subtractBtn - hidden
The first time you click the addBtn, the subtractBtn should show.
The max amount of clicks for either button is 2.
When you click the addBtn, the count of clicks should increment by 1.
When you click the subtractBtn, the count of clicks should decrement by 1.
When the count reaches 0, the subtractBtn should disappear
The issue here is I need to somehow store this variable(count) into a variable that both controllers can read.
If anyone can answer how this could be done in Ext JS, that would be muy excellente and I will provide tons of upvotes. Thank you!
Use count as a global variable and here is a working example: http://jsfiddle.net/x_window/HVkhy/1/
Ext.onReady(function(){
var count = 0;
var btnAdd = new Ext.Button({
width: 50,
text: '+',
handler: function(){
++count;
if(count > 0 && btnSubs.hidden)
btnSubs.show();
if(count > 1 && !btnAdd.hidden)
btnAdd.hide();
}
});
var btnSubs = new Ext.Button({
width: 50,
hidden: true,
text: '-',
handler: function(){
--count;
if(count < 2 && btnAdd.hidden)
btnAdd.show();
if(count < 1 && !btnSubs.hidden)
btnSubs.hide();
}
});
var panel = new Ext.Panel({
width: 200,
items: [btnAdd, btnSubs],
renderTo: 'content'
});
});
I'm assuming the buttons have a common ancestor (maybe a container, or panel). You could keep the variable there. If you're using button handlers, you can access the parent container by using up()
handler: function(btn, e) {
btn.up('container').count++;
}
You may need to look over http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.ComponentQuery to figure out which selector to use for the up() function.
You can always access controller2 from a controller1 with the getController method of the application instance, which you get in the onLaunch method of controller1.
application.getController("controller2").count++;

fullCalendar adding a class to events

I am trying to select events on fullcalendar, based on user selection.
Example: if user selects class A, then all classes with the same ID should turn green (using applied className).
I am having trouble applying classes to the other events that I can successfully select by ID. I guess my issue is combining the event objects with jQuery objects.
sample code:
eventClick: function(event) {
$(this).addClass("reg_selected"); //this works fine on selected event
var selectedID = event.id
alert(selectedID); //get event.ID, and use it to find similar ones.
var similarEvents = $("#calendar").fullCalendar('clientEvents',selectedID).addClass("reg_selected");
the error I get is:
addClass is not a function
I also tried this method of looping, and got the same error:
for (var i = 0; similarEvents.length > i ; i++){
alert(similarEvents[i].title);
similarEvents[i].className("reg_selected");
}
the alert() worked, but the className() generated the same error as above
This answer for a very similar situation, but when event classes are selected with round-trip to the event source for possible persistence in the db or checks.
Class name can be specified in the event object in the source as follows (start and end given for the context only):
[{
...
"className": "selected-event",
"start": '2017-05-01T08:30:00.0',
"ends": '2017-05-01T09:00:00.0',
...
}, ...]
The idea is that user clicks the event; ajax call to select events goes to backend; onsuccess, frontend javascript does$calendar.fullCalendar('rerenderEvents'); and receives the event source with events' classes. The immediate child of .fc-event-container gets the specified class, in the example above - selected-event.
As a result, the selection can be persisted on the backend.
clientEvents returns an array of matching objects. You need to iterate through the array (in your case similarEvents) and call addClass for each item
Update:
There is also issues using an id to update multiple events, using a filter function instead is a better way to go.
eventClick: function(event) {
var similarEvents = $("#calendar").fullCalendar('clientEvents', function(e) { return e.test === event.test });
for (var i = 0; similarEvents.length > i ; i++){
similarEvents[i].className = 'reg_selected';
$('#calendar').fullCalendar('updateEvent', similarEvents[i]);
}
},
See jsfiddle
For fullcalendar add event class, id and title see this.
if($('#eventTitle').val() == "Avilable") {
eventClass = "avilable";
}else {
eventClass = "unavilable";
}
$myCalendar.fullCalendar('renderEvent', {
id:response,
title: title.val(),
start: start.val(),
end: end.val(),
allDay: true,
className: eventClass,
color: color
}, true
);
I was able to get it working with the following code:
eventRender: function (eventObj, $el) {
$el.addClass(eventObj.ClassName);
},
eventObj.ClassName = "calendar-priority-warning"

how to add a "next fieldset" button to an add/edit form for a Dexterity Plone type

I have a Dexterity type that has multiple fieldsets, and the built-in Javascript that allows showing one fieldset at a time when adding or editing is wonderful.
But I'd like to invite the user to walk through the fieldsets in sequence, so my ideal situation would not present the "Submit" button until the last fieldset was visible, instead presenting NEXT> or <PREV and NEXT> buttons until that last fieldset.
I gather that this is a behavior? But I'm at a bit of a loss as to how to add it and how to control it. I'm currently using the default EditForm, and I'd much prefer to just make a tiny tweak, but if it means dropping down to building the form myself, that's OK. I just need to know whether that's the only way to get this addition, which seems unlikely.
The fieldsets can be rigged up to add 'previous' and 'next' buttons with some extra JavaScript magic. Here's what I use in a current project:
var prevnext = {
formTabs: null,
next: function() { prevnext.formTabs.data('tabs').next(); prevnext._scrollToTop(); },
prev: function() { prevnext.formTabs.data('tabs').prev(); prevnext._scrollToTop(); },
_scrollToTop: function() {
$(window).scrollTop(prevnext.formTabs.closest('form').offset().top);
},
showButtons: function(event, index) {
var tabs = prevnext.formTabs.data('tabs'),
index = typeof(index) === 'undefined' ? tabs.getIndex() : index,
current = tabs.getTabs()[index],
count = tabs.getTabs().length;
$('#prevnext_previous').toggle(index !== 0);
$('#prevnext_next').toggle(index !== (count - 1));
$('.formControls:last :submit[name=form_submit]').toggle(index === )count - 1));
},
init: function() {
var tabs;
prevnext.formTabs = $('.formTabs');
tabs = prevnext.formTabs.data('tabs');
if (tabs.getTabs().length > 0) {
if ($('fieldset#fieldset-distribution').length === 0)
return;
$('.formControls:last :submit:first')
.before($('<input id="prevnext_previous" class="context" ' +
' type="button" value="" />')
.val('< Previous')
.click(prevnext.prev))
.before(document.createTextNode(' '));
$('.formControls:last :submit:first')
.before($('<input id="prevnext_next" class="context" ' +
' type="button" value="" />')
.val('Next >')
.click(prevnext.next))
.before(document.createTextNode(' '));
prevnext.showButtons();
tabs.onClick(prevnext.showButtons);
}
}
};
$(prevnext.init());

How to update a Dojo Grid cell value using a TooltipDialog (and DropDownButton)

I have a dojo grid which is using some editable dijit form fields. All is well, until I try ot implement an country (multi) select cell as an Tooltip Dialog; i.e., show a drop down button which opens the tooltip dialog populated with a checkbox array to select one or more country. Once checked and clicked OK, the cell should update with a list of selected countries. Obviously I'll take care of updating the server via the store later on.
I've implemented a country select tooltip dialog which works fine like so:
dojo.provide("CountrySelector");
dojo.declare(
"CountrySelector",
[dijit.form.DropDownButton],
{
label: 'Countries',
dropDown: new dijit.TooltipDialog({ execute: function() {
console.log("EXECUTE : ", arguments[0]);
this.value = arguments[0].country;
}, href:'/cm/ui/countries' }),
postCreate: function() {
this.inherited(arguments);
this.label = this.value;
dojo.connect(this.dropDown, 'onClose', function() { console.log('close'); });
console.log("CountrySelect post create", this);
},
}
);
And the grid cell is typed as:
{ name: 'Countries', field: 'targeting.countries', editable: true, hidden: false, type:dojox.grid.cells._Widget, widgetClass: CountrySelector },
All is working fine but I can't figure out how to update cell's content and store once the widget is executed. As well, I don't seem to have the row id of the updated row.
Any ideas?
Thanks,
Harel
//Layout:
gridLayout: {rows: [{name: 'Coll Name',field: 'colField', type: dojox.grid.cells.ComboBox, editable:'true', width:'8%',options: [], alwaysEditing:false}]}
//Grid Store:
this.gridStore = new dojo.data.ItemFileReadStore({data: {items: data}});
//
var setOptions = function(items, request){
this.gridLayout.rows[0].options.push('Val 1','Val 2');
this.gridLayout.rows[0].values.push('1','2');
dojo.connect(this.gridLayout.rows[0].type.prototype.widgetClass.prototype, "onChange",this, "_onComboChange");
}
this.gridStore.fetch({onComplete: dojo.hitch(this,setOptions)});
_onComboChange: function (selectedOption) {
console.info("_onComboChange: ",selectedOption);
},
// If you need to populate combos with different values you can use onItem
var getArray = function(item, request){
// populate one by one
// attach an event to each combo
}
this.gridStore.fetch({onItem: dojo.hitch(this,getArray)});
This is what i used to update my grid
var idx = yourGrid.getItemIndex(item);
if (idx >- 1) {
yourGrid.updateRow(idx);
}
More detail
every row is identified by its identifier
yourGrid.store.fetchItemByIdentity({
identity: <yourIdentity>,
onItem: function(item){
// Update your attributes in the store depending on the server response
// yourGrid.store.setValue(item, <attribute>,<value>);
var idx = yourGrid.getItemIndex(item);
if (idx >- 1) {
yourGrid.updateRow(idx);
}
}
});
I didn't set up a test with your code but you should be able to do it by just creating a method named getValue in your widget that returns the value.
Take a look at the other examples (like dojox.grid.cells.ComboBox) to get an idea of what getValue should look like.

Resources