So I removed a bunch of buttons in the table info dialogs. There are only 5 buttons left, so it feels pretty empty with the default size.
Here are the codes:
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if(dialogName == 'table' || dialogName == 'tableProperties'){
var advTab = dialogDefinition.getContents('advanced');
var infoTab = dialogDefinition.getContents('info');
var advClass = advTab.get('advCSSClasses');
var cmbAlignBut = infoTab.get('cmbAlign');
infoTab.remove('txtSummary');
infoTab.remove('txtCaption');
infoTab.remove('selBorder');
infoTab.remove('txtCellSpace');
infoTab.remove('txtCellPad');
infoTab.remove('selHeaders');
infoTab.remove('cmbAlign');
infoTab.remove('txtBorder');
advClass.type = "select";
advClass.requiredContent = "table(cke-xyz)";
advClass.label = "Table Type";
advClass.default = "normal-table";
advClass.items = [
["Normal", "normal-table"],
["Comparison", "comparison-table"],
["Links", "link-table"]
];
infoTab.add(advClass);
dialogDefinition.removeContents('advanced');
console.log(advClass);
console.log(cmbAlignBut);
}
});
And here's how it looks like:
How do I resize at least the height?
Please see: https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/table/dialogs/table.js#L60
Dialogs usually have minHeight assigned. If you wish to change it, please use :
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if(dialogName == 'table' || dialogName == 'tableProperties'){
ev.data.definition.minHeight = 120; // you can also use ev.data.definition.minHeight = 0;
...
Related
SharePoint Online: I have multiple people picker columns and enter in a number of places people. I get the people OK but it won't update. It says it the entry is undefined. I thought maybe separating each out would work but obviously not. I hope I get some help on this one. What I want to do is to allow users to enter names into where the div entries are and as a people picker. I accomplished that but when you submit the form it says that any entry other than the first is undefined.
<script type = "text/javascript" src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js" > < /script>
<script type="text/javascript" src="/_layouts/15/sp.core.js"></script>
<script type="text/javascript" src="/_layouts/15/clienttemplates.js"></script>
<script type="text/javascript" src="/_layouts/15/clientforms.js"></script>
<script type="text/javascript" src="/_layouts/15/clientpeoplepicker.js"></script>
<script type="text/javascript" src="/_layouts/15/autofill.js"></script>
<script type="text/javascript" src="/_layouts/15/1033/sts_strings.js"></script>
<script type="text/javascript">
var prim5 = 0;var sec4 = 0;var auth5 = 0;
var EorB25 = "";var BorE25 = "";var BorE35 = "";var siteUrl = "https://sp-cloud.kp.org/sites/MedicaidRepository";var cat25 = "";var regimpact = "";var regimpact1 = "";var prim25="";var sec25="";
var auth25="";var s1 = "";var soxD1 = "";var k1 = 'No';var com2 = "";var sDate1 = "";var sSever = "";var kDate1 = "";var finalusersP = [];var finalusers22 = [];var finalusersK = [];var user22 = [];var userK = [];var userP = [];var users22 = [];var usersK = [];var usersP = [];var userPemail = "";var userKemail = "";var user22email = "";
var tDay = new Date();
var dd = tDay.getDate();
var mm = tDay.getMonth()+1;
var yy = tDay.getFullYear();
var sDate = mm+ '/' +dd+ '/' +yy;
$(document).ready(function() {
prim5 = 1;
initializePeoplePickerP('peoplePickerDivP');
registerPPOnChangeEventP($('#peoplePickerDivP'));
});
$(document).ready(function() {
sec5 = 1;
initializePeoplePickerS('peoplePickerDivS');
registerPPOnChangeEventS($('#peoplePickerDivS'));
});
$(document).ready(function() {
auth5 = 1;
initializePeoplePickerK('peoplePickerDivK');
registerPPOnChangeEventK($('#peoplePickerDivK'));
});
function initializePeoplePickerP(peoplePickerElementIdP, UsersP) {
if (typeof(UsersP) == 'undefined') UsersP = null;
console.log('UsersP: ' +UsersP);
// Create a schema to store picker properties, and set the properties.
var schema = {};
schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
schema['SearchPrincipalSource'] = 15;
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = true;
schema['MaximumEntitySuggestions'] = 50;
schema['Width'] = '280px';
this.SPClientPeoplePicker_InitStandaloneControlWrapper(peoplePickerElementIdP, null, schema);
}
function initializePeoplePickerS(peoplePickerElementIdS, Users22) {
if (typeof(Users22) == 'undefined') Users22 = null;
console.log('Users22: ' +Users22);
// Create a schema to store picker properties, and set the properties.
var schema = {};
schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
schema['SearchPrincipalSource'] = 15;
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = true;
schema['MaximumEntitySuggestions'] = 50;
schema['Width'] = '280px';
this.SPClientPeoplePicker_InitStandaloneControlWrapper(peoplePickerElementIdS, null, schema);
}
function initializePeoplePickerK(peoplePickerElementIdK, UsersK) {
if (typeof(UsersK) == 'undefined') UsersK = null;
// Create a schema to store picker properties, and set the properties.
var schema = {};
schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
schema['SearchPrincipalSource'] = 15;
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = true;
schema['MaximumEntitySuggestions'] = 50;
schema['Width'] = '280px';
this.SPClientPeoplePicker_InitStandaloneControlWrapper(peoplePickerElementIdK, null, schema);
}
function registerPPOnChangeEventP(ppElement) {
var ppId = ppElement.attr('id') + "_TopSpan";
console.log('ppID: ' +ppId);
//var addOnChanged = function(ctx) {
if (SPClientPeoplePicker &&
SPClientPeoplePicker.SPClientPeoplePickerDict &&
SPClientPeoplePicker.SPClientPeoplePickerDict[ppId]) {
console.log("In registerPPOnChangeEvent if");
var picker = SPClientPeoplePicker.SPClientPeoplePickerDict[ppId];
picker.oldChanged = picker.OnControlResolvedUserChanged;
//var ppidTest = picker.toString();
console.log("picker: " +picker);
//OnControlResolvedUserChanged
picker.OnControlResolvedUserChanged = function () {
if (picker.TotalUserCount == 0) {
$('#resolvedUsers').html("");
$('#userKeys').html("");
$('#userProfileProperties').html("");
$('#userID').html("");
} else {
setTimeout(function () {
getUserInfoP();
},
100);
}
picker.oldChanged();
}
} else {
// setTimeout(function () { addOnChanged(ctx); }, 100);
console.log("In registerPPOnChangeEvent else");
}
//}
}
function registerPPOnChangeEventS(ppElement) {
var ppId = ppElement.attr('id') + "_TopSpan";
console.log('ppID: ' +ppId);
//var addOnChanged = function(ctx) {
if (SPClientPeoplePicker &&
SPClientPeoplePicker.SPClientPeoplePickerDict &&
SPClientPeoplePicker.SPClientPeoplePickerDict[ppId]) {
console.log("In registerPPOnChangeEvent if");
var picker = SPClientPeoplePicker.SPClientPeoplePickerDict[ppId];
picker.oldChanged = picker.OnControlResolvedUserChanged;
var ppidTest = picker.toString();
console.log("picker: " +ppidTest);
//OnControlResolvedUserChanged
picker.OnControlResolvedUserChanged = function () {
if (picker.TotalUserCount == 0) {
$('#resolvedUsers22').html("");
$('#user22Keys').html("");
$('#user22ProfileProperties').html("");
$('#user22ID').html("");
} else {
setTimeout(function () {
getUserInfoS();
},
100);
}
picker.oldChanged();
}
} else {
//setTimeout(function () { addOnChanged(ctx); }, 100);
console.log("In registerPPOnChangeEvent else");
}
//}
}
function registerPPOnChangeEventK(ppElement) {
var ppId = ppElement.attr('id') + "_TopSpan";
console.log('ppID: ' +ppId);
//var addOnChanged = function(ctx) {
if (SPClientPeoplePicker &&
SPClientPeoplePicker.SPClientPeoplePickerDict &&
SPClientPeoplePicker.SPClientPeoplePickerDict[ppId]) {
console.log("In registerPPOnChangeEvent if");
var picker = SPClientPeoplePicker.SPClientPeoplePickerDict[ppId];
picker.oldChanged = picker.OnControlResolvedUserChanged;
var ppidTest = picker.toString();
console.log("picker: " +ppidTest);
//OnControlResolvedUserChanged
picker.OnControlResolvedUserChanged = function () {
if (picker.TotalUserCount == 0) {
$('#resolvedUsers').html("");
$('#userKeys').html("");
$('#userProfileProperties').html("");
$('#userID').html("");
} else {
setTimeout(function () {
getUserInfoK();
},
100);
}
picker.oldChanged();
}
} else {
// setTimeout(function () { addOnChanged(ctx); }, 100);
console.log("In registerPPOnChangeEvent else");
}
//}
}
// Query the picker for user information.
var userPropertyP = "";
var userPropertyS = "";
var userPropertyK ="";
var userPemail = "";
var i = 0;
var j = 0;
var m = 0;
var keysP = "";
var keysS = "";
var keysK = "";
function getUserInfoP() {
// Get the people picker object from the page.
var peoplePickerP = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDivP_TopSpan;
// Get information about all users.
var usersP = peoplePickerP.GetAllUserInfo();
//var keysP = peoplePickerP.GetAllUserKeys();
//finalusersP = new Array();
console.log('Users: ' +usersP);
var ownerP = usersP[0];
for(i = 0; i < usersP.length; i++){
userPemail = usersP[i];
}
console.log('Owner: ' +ownerP);
$("#siteOwenerEmail").val(ownerP.AutoFillSubDisplayText);
$("#siteOwenerClaim").val(ownerP.Key);
$("#siteOwnerName").val(ownerP.DisplayText);
$("#siteOwnerLogin").val(ownerP.Description);console.log('Get People Picker NameP: ' +ownerP.DisplayText);
var userInfo = '';
if(prim5 > 0){
for (var i = 0; i < usersP.length; i++) {
userP = usersP[i];
if(userP !== null){
//userPemail = userP.EntityData.Email;
userPemail = ownerP.DisplayText;
}
console.log("userPemail: " +userPemail);
return userPemail;
console.log('i= ' +i+ 'User= ' +userP);
for (userPropertyP in userP) {
prim25 += userPropertyP + ': ' + userP[userPropertyP] + '<br>';
}
}
$('#resolvedUsers').html(prim25);
// Get user keys.
keysP = peoplePickerP.GetAllUserKeys();
$('#userKeys').html(keysP);
// Get the first user's ID by using the login name.
getUserIdP(usersP[0].Key);
console.log('Initial: ' +prim25);
}
}
function getUserInfoS() {
// Get the people picker object from the page.
var peoplePickerS = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDivS_TopSpan;
// Get information about all users.
users22 = peoplePickerS.GetAllUserInfo();
//var keysP = peoplePickerP.GetAllUserKeys();
//finalusersS = new Array();
console.log('Users: ' + users22);
var ownerS = users22[0];
/*for(i = 0; i < usersS.length; j++){
userSemail = usersS[i];
}*/
console.log('Owner: ' +ownerS);
$("#siteOwenerEmail").val(ownerS.AutoFillSubDisplayText);
$("#siteOwenerClaim").val(ownerS.Key);
$("#siteOwnerName").val(ownerS.DisplayText);
$("#siteOwnerLogin").val(ownerS.Description);console.log('Get People Picker NameS: ' +ownerS.DisplayText);
var userInfo = '';
if(sec4 > 0){
for (j = 0; j < users22.length; j++) {
user22 = users22[j];
if(user22 !== null){
//userPemail = userP.EntityData.Email;
user22email = ownerS.DisplayText;
}
for (userPropertyS in user22) {
sec25 += userPropertyS + ': ' + user22[userPropertyS] + '<br>';
}
}
$('#resolvedUsers').html(sec25);
// Get user keys.
keysS = peoplePickerS.GetAllUserKeys();
$('#user22Keys').html(keysS);
// Get the first user's ID by using the login name.
getUserIdS( users22[0].Key);
}
}
function getUserInfoK() {
// Get the people picker object from the page.
var peoplePickerK = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDivK_TopSpan;
// Get information about all users.
usersK = peoplePickerK.GetAllUserInfo();
//var keysP = peoplePickerP.GetAllUserKeys();
//finalusersK = new Array();
console.log('Users: ' +usersK);
var ownerK = usersK[0];
/*for(i = 0; i < usersK.length; i++){
userKemail = usersK[i];
}*/
console.log('Owner: ' +ownerK);
$("#siteOwenerEmail").val(ownerK.AutoFillSubDisplayText);
$("#siteOwenerClaim").val(ownerK.Key);
$("#siteOwnerName").val(ownerK.DisplayText);
$("#siteOwnerLogin").val(ownerK.Description);console.log('Get People Picker NameK: ' +ownerK.DisplayText);
var userInfo = '';
if(auth5 > 0){
for (m = 0; m < usersK.length; m++) {
userK = usersK[m];
if(userK !== null){
//userPemail = userP.EntityData.Email;
userKemail = ownerK.DisplayText;
}
for (userPropertyK in userK) {
auth25 += userPropertyK + ': ' + userK[userPropertyK] + '<br>';
}
}
$('#resolvedUsers').html(auth25);
// Get user keys.
keysK = peoplePickerK.GetAllUserKeys();
$('#userKeys').html(keysK);
// Get the first user's ID by using the login name.
getUserIdK(usersK[0].Key);
}
}
// Get the user ID.
function getUserIdP(loginName) {
console.log('Get User ID-P');
var context = new SP.ClientContext.get_current();
this.userP = context.get_web().ensureUser(loginName);
context.load(this.userP);
context.executeQueryAsync(
Function.createDelegate(null, ensureUserSuccessP),
Function.createDelegate(null, onFail)
);
}
function ensureUserSuccessP() {
$('#userId').html(this.userP.get_id());
$("#siteOwenerId").val(this.userP.get_id());
userP = $("#siteOwenerId").val(this.userP.get_id());
}
function getUserIdS(loginName) {
console.log("Get User ID-S");
var context = new SP.ClientContext.get_current();
this.user22 = context.get_web().ensureUser(loginName);
context.load(this.user22);
context.executeQueryAsync(
Function.createDelegate(null, ensureUserSuccessS),
Function.createDelegate(null, onFail)
);
}
function ensureUserSuccessS() {
$('#userId').html(this.user22.get_id());
$("#siteOwenerId").val(this.user22.get_id());
userS = $("#siteOwenerId").val(this.user22.get_id());
}
function getUserIdK(loginName) {
console.log('Get User ID-K');
var context = new SP.ClientContext.get_current();
this.userK = context.get_web().ensureUser(loginName);
context.load(this.userK);
context.executeQueryAsync(
Function.createDelegate(null, ensureUserSuccessK),
Function.createDelegate(null, onFail)
);
}
function ensureUserSuccessK() {
$('#userId').html(this.userK.get_id());
$("#siteOwenerId").val(this.userK.get_id());
userK = $("#siteOwenerId").val(this.userK.get_id());
}
function onFail(sender, args) {
alert('Query failed. Error: ' + args.get_message());
}
function addNewIntake(){
SP.SOD.executeFunc('sp.js', 'SP.ClientContext',updateListItem1);
}
function updateListItem1() {
finalusersP.push(SP.FieldUserValue.fromUser(userP.Key));
finalusers22.push(SP.FieldUserValue.fromUser(user22.Key));
finalusersK.push(SP.FieldUserValue.fromUser(userK.Key));
var clientContext = new SP.ClientContext(siteUrl);
var oList =
clientContext.get_web().get_lists().getByTitle('Issue_Tracker_List');
this.oListItem = oList.addItem();
//console.log('primary person info: ' + finalusersP);
oListItem.set_item('MainContact2',finalusersP);
if(finalusers22 !== ""){
//console.log('secondary person info: ' +finalusers22);
oListItem.set_item('AdditionalContact_x0028_s_x0029_',finalusersS);
}
if(finalusersK !== ""){
oListItem.set_item('ITSupportOwner',finalusersK);
}
oListItem.update();
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySucceeded() {
document.getElementById('main12').style.display="none";
document.getElementById('main22').style.display="block";
setTimeout(CloseDlg, 2000);
}
function CloseDlg() {
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.Cancel);
}
function onQueryFailed(sender, args) {
alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
}
</script>
I'm using the latest Handsontable version 9.0.0 without any framework and I'm trying to follow the Cell editor developer guide, but I'm at a loss.
My requirement is to show a couple of checkboxes and a text box in one cell (not my idea). My thought was to have the data for the cell be a little json string {"Attr1": true, "Attr2": false} and have a custom renderer/editor that would parse the cell value and set the checkboxes appropriately.
I made a fiddle of it here: http://jsfiddle.net/9k1x4z6b/2/
I created a class for the custom attributes column and a renderer function and set the renderer and editor for the column like this
class CustomAttributesEditor extends Handsontable.editors.BaseEditor {
/**
* Initializes editor instance, DOM Element and mount hooks.
*/
// constructor (props) {
// super(props)
// }
prepare(row, col, prop, td, originalValue, cellProperties) {
// Invoke the original method...
super.prepare(row, col, prop, td, originalValue, cellProperties);
td.innerHTML = '';
this.AttributeNames = ['Attr1', 'Attr2'];
this.ctrls = {};
let parsedValue = JSON.parse(Handsontable.helper.stringify(originalValue));
// Create checkbox controls
for (let i = 0; i < this.AttributeNames.length; i++) {
let AttributeName = this.AttributeNames[i];
let span = document.createElement('span');
span.style.whiteSpace = 'nowrap';
let checkbox = document.createElement('input');
this.ctrls[AttributeName] = checkbox;
checkbox.type = 'checkbox';
if (parsedValue[AttributeName] == 'yes') {
checkbox.checked = true;
}
let label = document.createElement('label');
label.innerHTML = AttributeName;
label.htmlFor = checkbox.id;
span.appendChild(checkbox);
span.appendChild(label);
td.appendChild(span);
td.appendChild(document.createElement('br'));
}
// Create a control that is shown/hidden when the "Attr2" checkbox is toggled
let CustomAttributesAttr3SubDiv = document.createElement('div');
var label = document.createElement('label');
label.innerHTML = "Attr3 supplier:";
CustomAttributesAttr3SubDiv.appendChild(label);
var CustomAttributesAttr3 = document.createElement('input');
if (parsedValue.hasOwnProperty('Attr3')) {
CustomAttributesAttr3.value = parsedValue['Attr3'];
}
this.ctrls['Attr3'] = CustomAttributesAttr3;
this.AttributeNames.push('Attr3');
CustomAttributesAttr3.setAttribute('title', 'Attr3');
CustomAttributesAttr3.style.width = '12em';
CustomAttributesAttr3SubDiv.appendChild(CustomAttributesAttr3);
CustomAttributesAttr3SubDiv.appendChild(document.createElement('br'));
td.appendChild(CustomAttributesAttr3SubDiv);
let Attr2Checkbox = this.ctrls['Attr2'];
//CustomAttributes_ShowHideValueCtrl(Attr2Checkbox);
$(Attr2Checkbox).off('change').on('change', function () {
//CustomAttributes_ShowHideValueCtrl(this); // irrelevant to checkbox problem. function shows Attr3 input when Attr2Checkbox is checked, hides otherwise
});
//preventDefault();
}
getValue(){
// This function returns the set value of the controls
let ctrls = this.ctrls;
let resultDict = {};
for (let ctrlID in ctrls){
let ctrl = ctrls[ctrlID];
let FormattedAttributeName = ctrlID.replaceAll(' ', '_');
let val = null;
if (ctrl.type == 'checkbox'){
if (ctrl.checked == true) {
val = 'yes';
} else {
val = null;
}
} else {
val = ctrl.value;
}
resultDict[FormattedAttributeName] = val;
}
return JSON.stringify(resultDict)
}
setValue(value){
// this function sets the value of the controls to match the data value
let parsedValue = {};
try {
parsedValue = JSON.parse(Handsontable.helper.stringify(value));
} catch (exc) {
for (let i = 0; i < this.AttributeNames.length; i++) {
parsedValue[this.AttributeNames[i]] = 'no';
}
}
let ctrls = this.ctrls;
let resultDict = {};
for (let ctrlID in ctrls){
let ctrl = ctrls[ctrlID];
let FormattedAttributeName = ctrlID.replaceAll(' ', '_');
let val = parsedValue[FormattedAttributeName];
if (ctrl.type == 'checkbox'){
if (val == 'yes'){
ctrl.checked = true;
} else {
ctrl.checked = false;
}
} else {
ctrl.value = val;
}
}
}
saveValue(value, ctrlDown){
super.saveValue(value, ctrlDown);
}
open(){}
close(){}
focus(){}
}
function CustomAttributesRenderer(instance, td, row, col, prop, value, cellProperties) {
// This function shows labels for the checked Attr1-3 values
let AttributeNames = ['Attr1', 'Attr2', 'Attr3'];
parsedValue = JSON.parse(Handsontable.helper.stringify(value));
Handsontable.dom.empty(td);
for (let i = 0; i < AttributeNames.length; i++) {
let AttributeName = AttributeNames[i];
let span = document.createElement('span');
span.style.whiteSpace = 'nowrap';
if (parsedValue[AttributeName] == 'yes') {
let label = document.createElement('label');
label.innerHTML = AttributeName;
span.appendChild(label);
td.appendChild(span);
}
td.appendChild(document.createElement('br'));
}
return td;
}
document.addEventListener("DOMContentLoaded", function () {
var container = document.getElementById('divBFEPartMatrix');
var hot = new Handsontable(container, {
data: [
[JSON.stringify({"Attr1": "yes", "Attr2": "yes", "Attr3": ""})],
[JSON.stringify({"Attr1": "yes", "Attr2": "yes", "Attr3": "somevalue"})],
[JSON.stringify({"Attr1": "no", "Attr2": "no", "Attr3": ""})],
],
columns: [
{renderer: CustomAttributesRenderer, editor: CustomAttributesEditor}
],
rowHeaders: true,
colHeaders: true,
filters: true,
dropdownMenu: true
});
})
The result appears properly, with the cell initially not having checkboxes visible due to the renderer not showing them, then when you click the cell the checkboxes appear. The problem is when you click the checkbox it doesn't toggle.
I presume something in handsontable is re-creating the td and blowing away the state change, but I can't figure out how to prevent that from happening. Is there a fully working custom editor fiddle or something I can reference to figure out how to prevent bubbling?
Any help you can offer would be greatly appreciated.
Well, after another couple days of fiddling around I figured out the full set of code I needed to add to make this work. Posted here in case it helps someone else trying to make a custom cell editor/renderer in handsontable.
class SubstitutePartEditor extends Handsontable.editors.BaseEditor {
init(){
// This function creates the edit div
let div = document.createElement('div');
this.div = div;
div.style.display = 'none';
div.style.position = 'absolute';
div.style.width = 'auto';
div.style.backgroundColor = 'white';
this.AttributeNames = ['The waste bin is part of the waste cart', 'This item includes SUPPLIER tapestry'];
this.ctrls = {};
let cbIsSubstitutePart = document.createElement('input');
this.ctrls['IsSubstitutePart'] = cbIsSubstitutePart;
cbIsSubstitutePart.type = 'checkbox';
div.appendChild(cbIsSubstitutePart);
div.appendChild(document.createElement('br'));
let SubstitutePartSubDiv = document.createElement('div');
SubstitutePartSubDiv.style.display = 'inline-block';
div.appendChild(SubstitutePartSubDiv);
let inputSubstitutePart = document.createElement('textarea');
this.ctrls['SubstitutePart'] = inputSubstitutePart;
inputSubstitutePart.style.width = '220px';
inputSubstitutePart.style.height = '88px';
SubstitutePartSubDiv.appendChild(inputSubstitutePart);
this.hot.rootElement.appendChild(div);
}
UpdateDependentControls(){
let RequiredCtrl = this.ctrls['IsSubstitutePart'];
let Ctrl = this.ctrls['SubstitutePart'];
if (RequiredCtrl.checked == true){
Ctrl.style.display = '';
} else {
Ctrl.style.display = 'none';
}
$(RequiredCtrl).off('change').on('change', function(){
if (RequiredCtrl.checked == true){
Ctrl.style.display = '';
} else {
Ctrl.style.display = 'none';
}
});
}
getValue(){
// This function returns the set value of the controls
let ctrls = this.ctrls;
let resultDict = {};
for (let ctrlID in ctrls){
let ctrl = ctrls[ctrlID];
let FormattedAttributeName = ctrlID.replaceAll(' ', '_');
let val = null;
if (ctrl.type == 'checkbox'){
if (ctrl.checked == true) {
val = 'yes';
} else {
val = null;
}
} else {
val = ctrl.value;
}
resultDict[FormattedAttributeName] = val;
}
return JSON.stringify(resultDict)
}
setValue(value){
// this function sets the value of the controls to match the data value
let parsedValue = {};
try {
parsedValue = JSON.parse(Handsontable.helper.stringify(value));
} catch (exc) {
parsedValue = {
IsSubstitutePart: 'no',
SubstitutePart: "This item requires a waiver from the operator's foreign regulatory agency, <FOREIGN REGULATORY AGENCY NAME>."
};
}
let ctrls = this.ctrls;
let resultDict = {};
for (let ctrlID in ctrls){
let ctrl = ctrls[ctrlID];
let FormattedAttributeName = ctrlID.replaceAll(' ', '_');
let val = parsedValue[FormattedAttributeName];
if (ctrl.type == 'checkbox'){
if (val == 'yes'){
ctrl.checked = true;
} else {
ctrl.checked = false;
}
} else {
ctrl.value = val;
}
}
}
saveValue(value, ctrlDown){
super.saveValue(value, ctrlDown);
}
open() {
this._opened = true;
this.refreshDimensions();
this.UpdateDependentControls();
this.div.style.display = '';
}
refreshDimensions() {
this.TD = this.getEditedCell();
// TD is outside of the viewport.
if (!this.TD) {
this.close();
return;
}
const { wtOverlays } = this.hot.view.wt;
const currentOffset = Handsontable.dom.offset(this.TD);
const containerOffset = Handsontable.dom.offset(this.hot.rootElement);
const scrollableContainer = wtOverlays.scrollableElement;
const editorSection = this.checkEditorSection();
let width = Handsontable.dom.outerWidth(this.TD) + 1;
let height = Handsontable.dom.outerHeight(this.TD) + 1;
let editTop = currentOffset.top - containerOffset.top - 1 - (scrollableContainer.scrollTop || 0);
let editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0);
let cssTransformOffset;
switch (editorSection) {
case 'top':
cssTransformOffset = Handsontable.dom.getCssTransform(wtOverlays.topOverlay.clone.wtTable.holder.parentNode);
break;
case 'left':
cssTransformOffset = Handsontable.dom.getCssTransform(wtOverlays.leftOverlay.clone.wtTable.holder.parentNode);
break;
case 'top-left-corner':
cssTransformOffset = Handsontable.dom.getCssTransform(wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode);
break;
case 'bottom-left-corner':
cssTransformOffset = Handsontable.dom.getCssTransform(wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
break;
case 'bottom':
cssTransformOffset = Handsontable.dom.getCssTransform(wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode);
break;
default:
break;
}
if (this.hot.getSelectedLast()[0] === 0) {
editTop += 1;
}
if (this.hot.getSelectedLast()[1] === 0) {
editLeft += 1;
}
const selectStyle = this.div.style;
if (cssTransformOffset && cssTransformOffset !== -1) {
selectStyle[cssTransformOffset[0]] = cssTransformOffset[1];
} else {
Handsontable.dom.resetCssTransform(this.div);
}
const cellComputedStyle = Handsontable.dom.getComputedStyle(this.TD, this.hot.rootWindow);
if (parseInt(cellComputedStyle.borderTopWidth, 10) > 0) {
height -= 1;
}
if (parseInt(cellComputedStyle.borderLeftWidth, 10) > 0) {
width -= 1;
}
selectStyle.height = `${height}px`;
selectStyle.minWidth = `${width}px`;
selectStyle.top = `${editTop}px`;
selectStyle.left = `${editLeft}px`;
selectStyle.margin = '0px';
}
getEditedCell() {
const { wtOverlays } = this.hot.view.wt;
const editorSection = this.checkEditorSection();
let editedCell;
switch (editorSection) {
case 'top':
editedCell = wtOverlays.topOverlay.clone.wtTable.getCell({
row: this.row,
col: this.col
});
this.select.style.zIndex = 101;
break;
case 'corner':
editedCell = wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({
row: this.row,
col: this.col
});
this.select.style.zIndex = 103;
break;
case 'left':
editedCell = wtOverlays.leftOverlay.clone.wtTable.getCell({
row: this.row,
col: this.col
});
this.select.style.zIndex = 102;
break;
default:
editedCell = this.hot.getCell(this.row, this.col);
this.div.style.zIndex = '';
break;
}
return editedCell < 0 ? void 0 : editedCell;
}
focus() {
this.div.focus();
}
close() {
this._opened = false;
this.div.style.display = 'none';
}
}
function SubstitutePartRenderer(instance, td, row, col, prop, value, cellProperties) {
// This function draws the multi checkboxes for the SubstitutePart input field
// Note: if AttributeNames changes you must also update BFEPartMatrix_Edit.ascx line ~240 to match (<- this is where the data is saved)
//Handsontable.renderers.HtmlRenderer.apply(this, arguments);
let parsedValue = {};
try {
parsedValue = JSON.parse(Handsontable.helper.stringify(value));
} catch {
// nothing to do
}
Handsontable.dom.empty(td);
let div = document.createElement('div');
//div.style.whiteSpace = 'nowrap';
div.style.display = 'block';
td.appendChild(div);
if (parsedValue.hasOwnProperty('IsSubstitutePart')) {
if (parsedValue.IsSubstitutePart == 'yes') {
} else {
td.innerHTML = 'N/A';
return;
}
} else {
td.innerHTML = 'N/A';
return;
}
let SubstitutePartSubDiv = document.createElement('div');
SubstitutePartSubDiv.style.display = 'inline-block';
div.appendChild(SubstitutePartSubDiv);
// text area
let inputSubstitutePart = document.createElement('label');
inputSubstitutePart.innerHTML = parsedValue['SubstitutePart'].escape();
inputSubstitutePart.style.width = '220px';
inputSubstitutePart.style.height = '88px';
SubstitutePartSubDiv.appendChild(inputSubstitutePart);
return td;
}
then set the render and editor of the hot column like this
columns: [
{renderer: CustomAttributesRenderer, editor: CustomAttributesEditor}
],
I have set up a rough script (new to this) to automate some data entry that I have to do consistently. I build a UI with checkboxes and have data fill into the sheet based on the responses to the checks. It all works correctly for one product. The problem is that I have duplicated this for other products. When recreated for a second product, I have to rename the function in the second script to "BUILDUI2" in order to see the correct options display (otherwise it displays the options from the previous script). Then, even though I see the correct check boxes, the responses to the check boxes are based off of the first script created. So on the second product, selecting the second checkbox inserts the data specified in the original BuildUI script that is tied to the other product rather than the data shown under BuildUI2.
These are independent scripts activated by separate push buttons on the sheet.
Any insight on how to get the second (and third, and fourth) scripts to read the correct information?
Product 1 Script:
function BuildUI() {
//create the application itself
var app = UiApp.createApplication().setHeight(160).setWidth(250);
app.setTitle("Options");
//create panels and add them to the UI
var panel = app.createVerticalPanel();
//create a text box
var check1 = app.createCheckBox("Safety Aprons");
check1.setName('CheckBox1');
var check2 = app.createCheckBox("Standard Trash Racks (1)");
check2.setName('CheckBox2');
var check3 = app.createCheckBox("Standard Trash Racks (2) ");
check3.setName('CheckBox3');
var check4 = app.createCheckBox("Plate Style Trash Racks (1)");
check4.setName('CheckBox4');
var check5 = app.createCheckBox("Plate Style Trash Racks (2) ");
check5.setName('CheckBox5');
var check6 = app.createCheckBox("6:1 Safety Grates (1)");
check6.setName('CheckBox6');
var check7 = app.createCheckBox("6:1 Safety Grates (2)");
check7.setName('CheckBox7');
//create a submit button
var button = app.createButton('Done');
//add the text box and the button to the panel
panel.add(check1);
panel.add(check2);
panel.add(check3);
panel.add(check4);
panel.add(check5);
panel.add(check6);
panel.add(check7);
panel.add(button);
var handler = app.createServerHandler("submitButton");
button.addClickHandler(handler);
handler.addCallbackElement(panel);
//add the panel to the application
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function submitButton(e){
var app = UiApp.getActiveApplication();
var sheet = SpreadsheetApp.getActiveSheet();
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox1 == 'true') {
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = lastrow-4; i <= numRows - 1; i++) {
var row = values[i];
if (row[2] == 'R012M-BAM' || row[2] == 'R012M-BAF') {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;}
}
var lastrow = sheet.getLastRow();
sheet.getRange(lastrow+1,3).setValue("R012M-BSAF6");
sheet.getRange(lastrow+1,5).setValue("1");
sheet.getRange(lastrow+2,3).setValue("R012M-BSAM6");
sheet.getRange(lastrow+2,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox2 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00092");
sheet.getRange(lastrow+1,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox3 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00092");
sheet.getRange(lastrow+1,5).setValue("2");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox4 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00094");
sheet.getRange(lastrow+1,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox5 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00094");
sheet.getRange(lastrow+1,5).setValue("2");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox6 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00095");
sheet.getRange(lastrow+1,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox7 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00095");
sheet.getRange(lastrow+1,5).setValue("2");
}
return app.close();
}
Product 2 Script:
function BuildUI2() {
//create the application itself
var app = UiApp.createApplication().setHeight(225).setWidth(250);
app.setTitle("Options");
//create panels and add them to the UI
var panel = app.createVerticalPanel();
//create a text box
var check1 = app.createCheckBox("Safety Aprons");
check1.setName('CheckBox1');
var check2 = app.createCheckBox("Pipe Style Trash Racks (1)");
check2.setName('CheckBox2');
var check3 = app.createCheckBox("Pipe Style Trash Racks (2) ");
check3.setName('CheckBox3');
var check4 = app.createCheckBox("Plate Style Trash Racks (1)");
check4.setName('CheckBox4');
var check5 = app.createCheckBox("Plate Style Trash Racks (2) ");
check5.setName('CheckBox5');
var check6 = app.createCheckBox("Bull Nose Style Trash Racks (1)");
check6.setName('CheckBox6');
var check7 = app.createCheckBox("Bull Nose Style Trash Racks (2) ");
check7.setName('CheckBox7');
var check8 = app.createCheckBox("6:1 Safety Grates (1)");
check8.setName('CheckBox8');
var check9 = app.createCheckBox("6:1 Safety Grates (2)");
check9.setName('CheckBox9');
//create a submit button
var button = app.createButton('Done');
//add the text box and the button to the panel
panel.add(check1);
panel.add(check2);
panel.add(check3);
panel.add(check4);
panel.add(check5);
panel.add(check6);
panel.add(check7);
panel.add(check8);
panel.add(check9);
panel.add(button);
var handler = app.createServerHandler("submitButton");
button.addClickHandler(handler);
handler.addCallbackElement(panel);
//add the panel to the application
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function submitButton(e){
var app = UiApp.getActiveApplication();
var sheet = SpreadsheetApp.getActiveSheet();
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox1 == 'true') {
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = lastrow-4; i <= numRows - 1; i++) {
var row = values[i];
if (row[2] == 'R015M-BAM' || row[2] == 'R015M-BAF') {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;}
}
var lastrow = sheet.getLastRow();
sheet.getRange(lastrow+1,3).setValue("R015M-BSAF6");
sheet.getRange(lastrow+1,5).setValue("1");
sheet.getRange(lastrow+2,3).setValue("R015M-BSAM6");
sheet.getRange(lastrow+2,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox2 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00194");
sheet.getRange(lastrow+1,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox3 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00194");
sheet.getRange(lastrow+1,5).setValue("2");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox4 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00097");
sheet.getRange(lastrow+1,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox5 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00097");
sheet.getRange(lastrow+1,5).setValue("2");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox6 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00440");
sheet.getRange(lastrow+1,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox7 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00440");
sheet.getRange(lastrow+1,5).setValue("2");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox8 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00101");
sheet.getRange(lastrow+1,5).setValue("1");
}
var lastrow = sheet.getLastRow();
if(e.parameter.CheckBox9 == 'true')
{sheet.getRange(lastrow+1,3).setValue("85-00101");
sheet.getRange(lastrow+1,5).setValue("2");
}
return app.close();
}
I am learning how to use dc.js to add a count on top of barChart when mouse over a legend.
After some research, I figured out that I have to use .on('renderlet')
var legends = chart.selectAll("g.dc-legend .dc-legend-item");
legends
.on("mouseover.foo", function(d){
var layername = d.name;
var val = '';
if (layername == 'full scat')
val = 's_full';
else if (layername == 'partial scat')
val = 's_partial';
else if (layername == 'empty scat')
val = 's_empty';
else if (layername == 'partial citrate')
val = 'c_partial';
else if (layername == 'empty citrate')
val = 'c_empty';
else if (layername == 'full citrate')
val = 'c_full';
else if (layername == 'N')
val = 'n_pax';
else if (layername == 'Y')
val = 'y_pax';
var div = "";
if (/scat/.test(layername))
div = 'g.sub._0 .stack._2 .barLabel';
else if (/citrate/.test(layername))
div = 'g.sub._1 .stack._2 .barLabel';
else if (/N/.test(layername) ||/Y/.test(layername))
div = 'g.sub._2 .stack._1 .barLabel';
var text = chart.selectAll(div);
text.text(function(d){
return d.data.value[val];
})
text.attr("visibility", "visible");
});
legends
.on("mouseout.foo", function(d){
chart.selectAll('.barLabel').attr("visibility", "hidden");
});
I got the first time mouseover ok, but after I filter the data once, then mouse over. the count would not show up.
Here is a bl.ock
I am creating multiple grids on a page dynamically based on the data returned from server side. Pushing all of the created grids to an arrayOfGrids. However, I am facing issue when I have to add data to a new cell of a new row. Its gets added to last grid.
How can I get this done?
My code is something like this below:-
var index = 0;
for ( var k = 0; k < steps.length; k++) {
var gridId = "#dataGrid_" + index++;
var grid;
var columns = new Array();
for ( var jj = 0; jj < rows[0].cells.length; jj++) {
var key = {
id : rows[0].cells[jj],
name : rows[0].cells[jj],
field : rows[0].cells[jj],
//toolTip : 'Click to sort',
//width : 200,
sortable : true,
editor : Slick.Editors.LongText
};
columns[jj] = key;
}
var data = [];
for ( var i = 1; i < rows.length; i++) {
var tempData = (data[i - 1] = {});
var title = null;
var val = null;
for ( var q = 0; q < rows[i].cells.length; q++) {
title = rows[0].cells[q];
val = rows[i].cells[q];
tempData[title] = val;
}
}
var options = {
enableCellNavigation : true,
editable: true,
asyncEditorLoading: false,
enableColumnReorder: true,
enableAddRow: true,
autoHeight: true,
leaveSpaceForNewRows:false,
explicitInitialization: true
};
var myGrid = $("<div id='"+gridId+"' style='width:400px;'></div>");
grid = new Slick.Grid(myGrid, data, columns, options);
myGrid.appendTo($("#tableData"));
grid.init();
grid.onAddNewRow.subscribe(function(e,args){
// Always adds to last grid ?
});
arrayOfGrids.push(grid);
}
Ok. I got this working based on javascript closure. Best is extract the grid creation code in to a separate function and call the function in for loop. Everything working like charm after that.
function createGrid(gridId, rows) {
var grid;
var colIndex = 0;
var columns = new Array();
for ( var jj = 0; jj < rows[0].cells.length; jj++) {
var key = {
id : rows[0].cells[jj],
name : rows[0].cells[jj],
field : rows[0].cells[jj],
//toolTip : 'Click to sort',
//width : 200,
sortable : true,
editor : Slick.Editors.LongText
};
columns[jj] = key;
}
var data = [];
for ( var i = 1; i < rows.length; i++) {
var tempData = (data[i - 1] = {});
var title = null;
var val = null;
for ( var q = 0; q < rows[i].cells.length; q++) {
title = rows[0].cells[q];
val = rows[i].cells[q];
tempData[title] = val;
}
}
var options = {
enableCellNavigation : true,
editable: true,
asyncEditorLoading: false,
enableColumnReorder: true,
enableAddRow: true,
autoHeight: true,
leaveSpaceForNewRows:false,
explicitInitialization: true
};
var myGrid = $("<div id='"+gridId+"' style='width:400px;'></div>");
grid = new Slick.Grid(myGrid, data, columns, options);
myGrid.appendTo($("#tableData"));
grid.init();
arrayOfGrids.push(grid);
grid.onAddNewRow.subscribe(function (e, args) {
var item = args.item;
grid.invalidateRow(data.length);
data.push(item);
grid.updateRowCount();
grid.render();
});
}
and call that function from the for loop.