ckeditor editiable widget content - plugins

I created a plugin and widget, the content is generated dynamically in a dialog, when the dialog is closed, the content is inserted into the CKEditor window, but the content itself cannot be edited.
How can I make it that the widget content can be edited from the main CKEditor input after it has been created via the dialog?
Plugin Code
(function() {
CKEDITOR.plugins.add( 'cc_widget', {
icons: "cc_widget_button",
init: function(editor) {
// Styles
editor.addContentsCss( this.path + 'cc-widget.css' + '?' + new Date());
var str_html = "<div class=\"credit-card credit-card-widget\" data-cke-widget-editable=\"true\"> " +
"<div class=\"h3\"><a id=\"card-title-link\" href=\"/card-details/card-name\">CARD NAME</a></div>" +
"<div class=\"card-info\">" +
"<div class=\"card-image\">" +
"<a id=\"card-image-link\" href=\"/card-details/card-name\">" +
"<img id=\"card-image\" alt=\"CARD NAME\" src=\"\">" +
"</a>" +
"</div>" +
"<div class=\"card-details\">" +
"<div class=\"h4\">Fees and interest</div>" +
"<dl id=\"card-attributes\">" +
"<dt>Annual fee:</dt> " +
"<dd id=\"annual-fee\">$ANNUAL FEE</dd>" +
"<dd id=\"annual-fee-note\" class=\"note\">annual fee note</dd>" +
"<dt>Purchase interest rate:</dt> " +
"<dd id=\"int-purch\">INT RATE%</dd>" +
"<dd id=\"int-purch-note\" class=\"note\">intrest rate note</dd>" +
"<dt>Cash advance rate:</dt> " +
"<dd id=\"cash-adv\">CASH ADV RATE%</dd>" +
"<dd id=\"cash-adv-note\" class=\"note\">cash adv note</dd>" +
"<dt>Balance transfer rate:</dt> " +
"<dd id=\"balance-trans\">BALANCE TRANS RATE%</dd>" +
"<dd id=\"balance-trans-note\" class=\"note\">balance trans note</dd>" +
"<dt>Rewards Rate:</dt> " +
"<dd id=\"reward-rate\">REWARDS RATE</dd>" +
"<dt>Bonus Offer:</dt> " +
"<dd id=\"bonus-offer\">BONUS OFFER</dd>" +
"<dt>Card Type:</dt> " +
"<dd id=\"card-type\">CARD TYPE(S)</dd>" +
"<dt>Credit Needed:</dt> " +
"<dd id=\"credit-needed\">CREDIT SCORE</dd>" +
"</dl>" +
"</div>" +
"</div>" +
"<div class=\"card-description\">" +
"<p>Add a card description here</p>" +
"<div class=\"buttons\" style=\"text-align:center;\">" +
"<a class=\"btn secondary\" id=\"learn-more\" href=\"/card-details/card-name\\\">Learn More</a> </div>" +
"</div>" +
"</div>";
// Dialog
CKEDITOR.dialog.add( 'cc_widget', this.path + 'dialog.js' );
// Widget definition
editor.widgets.add("cc_widget",{
dialog : "cc_widget",
init : function(){
var card_title_link = this.element.findOne('#card-title-link');
this.data.card_title_link_url = card_title_link.getAttribute("href");
this.data.card_title_link_text = card_title_link.getHtml();
var card_image_link = this.element.findOne('#card-image-link');
this.data.card_image_link_url = card_image_link.getAttribute("href");
var card_image = this.element.findOne('#card-image');
this.data.card_image_alt = card_image.getAttribute("alt");
this.data.card_image_src = card_image.getAttribute("src");
var annual_fee = this.element.findOne('#annual-fee');
var annual_fee_note = this.element.findOne('#annual-fee-note');
this.data.annual_fee_text = annual_fee.getHtml();
this.data.annual_fee_note_text = annual_fee_note.getHtml();
var purchase_interest_rate = this.element.findOne('#int-purch');
var interest_info = this.element.findOne('#int-purch-note');
this.data.purchase_interest_rate = purchase_interest_rate.getHtml();
this.data.purchase_interest_rate_note = interest_info.getHtml();
var cash_advance_rate = this.element.findOne('#cash-adv');
var cash_advance_info = this.element.findOne('#cash-adv-note');
this.data.cash_advance_rate = cash_advance_rate.getHtml();
this.data.cash_advance_rate_note = cash_advance_info.getHtml();
var balance_transfer_rate = this.element.findOne('#balance-trans');
var balance_transfer_info = this.element.findOne('#balance-trans-note');
this.data.balance_transfer_rate = balance_transfer_rate.getHtml();
this.data.balance_transfer_rate_note = balance_transfer_info.getHtml();
var reward_rate = this.element.findOne('#reward-rate');
this.data.reward_rate = reward_rate.getHtml();
var bonus_offer = this.element.findOne('#bonus-offer');
this.data.bonus_offer = bonus_offer.getHtml();
var card_type = this.element.findOne('#card-type');
this.data.card_type = card_type.getHtml();
var credit_needed = this.element.findOne('#credit-needed');
this.data.credit_needed = credit_needed.getHtml();
var learn_more = this.element.findOne('#learn-more');
this.data.learn_more = learn_more.getAttribute("href");
var card_data = this.element.findOne('#card_data');
this.data.card_data = (card_data ? card_data : '');
},
upcast : function(element) {
return element.hasClass("credit-card-widget");
},
template : str_html ,
editables : {
card_title_link: {
selector: '#card-title-link'
},
card_image_link: {
selector: '#card-image-link'
},
card_image: {
selector: '#card-image'
},
annual_fee: {
selector: '#annual-fee'
},
annual_fee_note: {
selector: '#annual-fee-note'
},
purchase_interest_rate: {
selector: '#int-purch'
},
interest_info: {
selector: '#int-purch-note'
},
cash_advance_rate: {
selector: '#cash-adv'
},
cash_advance_info: {
selector: '#cash-adv-note'
},
balance_transfer_rate: {
selector: '#balance-trans'
},
balance_transfer_info: {
selector: '#balance-trans-note'
},
reward_rate: {
selector: '#reward-rate'
},
bonus_offer: {
selector: '#bonus-offer'
},
card_type: {
selector: '#card-type'
},
credit_needed: {
selector: '#credit-needed'
},
card_description: {
selector: '#card-description'
},
},
data : function() {
console.log(this);
console.log(this.data);
var card_title_link = this.element.findOne('#card-title-link');
card_title_link.setHtml(this.data.card_data.card_name);
card_title_link.setAttribute('href', '/card-details/' + this.data.card_data.card_slug);
var card_image_link = this.element.findOne('#card-image-link');
card_image_link.setAttribute('href', '/card-details/' + this.data.card_data.card_slug);
var card_image = this.element.findOne('#card-image');
card_image.setAttribute('alt', this.data.card_data.card_name);
card_image.setAttribute('src', this.data.card_data.card_image);
var annual_fee = this.element.findOne('#annual-fee');
var annual_fee_note = this.element.findOne('#annual-fee-note');
annual_fee.setHtml('$' + this.data.card_data.annual_fee);
if(this.data.card_data.annual_fee_info){
annual_fee_note.removeAttribute( 'style' );
annual_fee_note.setHtml(this.data.card_data.annual_fee_info);
}else {
annual_fee_note.setAttribute('style', 'display:none;');
annual_fee_note.setHtml('');
}
var purchase_interest_rate = this.element.findOne('#int-purch');
var purchase_interest_rate_note = this.element.findOne('#int-purch-note');
purchase_interest_rate.setHtml(this.data.card_data.purchase_interest_rate);
if(this.data.card_data.annual_fee_info){
purchase_interest_rate_note.removeAttribute( 'style' );
purchase_interest_rate_note.setHtml(this.data.card_data.interest_info);
}else {
purchase_interest_rate_note.setAttribute('style', 'display:none;');
purchase_interest_rate_note.setHtml('');
}
var cash_advance_rate = this.element.findOne('#cash-adv');
var cash_advance_info = this.element.findOne('#cash-adv-note');
cash_advance_rate.setHtml(this.data.card_data.cash_advance_rate + '%');
if(this.data.card_data.annual_fee_info){
cash_advance_info.removeAttribute( 'style' );
cash_advance_info.setHtml(this.data.card_data.cash_advance_info);
}else {
cash_advance_info.setAttribute('style', 'display:none;');
cash_advance_info.setHtml('');
}
var balance_transfer_rate = this.element.findOne('#balance-trans');
var balance_transfer_info = this.element.findOne('#balance-trans-note');
balance_transfer_rate.setHtml(this.data.card_data.balance_transfer_rate + '%');
if(this.data.card_data.annual_fee_info){
balance_transfer_info.removeAttribute( 'style' );
balance_transfer_info.setHtml(this.data.card_data.balance_transfer_info);
}else {
balance_transfer_info.setAttribute('style', 'display:none;');
balance_transfer_info.setHtml('');
}
var reward_rate = this.element.findOne('#reward-rate');
reward_rate.setHtml(this.data.card_data.rewards_rate);
var bonus_offer = this.element.findOne('#bonus-offer');
bonus_offer.setHtml(this.data.card_data.bonus_offer);
var card_type = this.element.findOne('#card-type');
card_type.setHtml(this.data.card_data.card_type);
var credit_needed = this.element.findOne('#credit-needed');
credit_needed.setHtml(this.data.card_data.credit_needed);
var learn_more = this.element.findOne('#learn-more');
learn_more.setAttribute('href', '/card-details/' + this.data.card_data.card_slug);
}
});
// Button action
editor.addCommand( 'add_cc_widget_box', {
exec : function(editor) {
editor.execCommand("cc_widget");
}
});
// Button definition
editor.ui.addButton( 'cc_widget_button', {
label: 'Add cc-widget link',
command: 'add_cc_widget_box',
icon: this.path + 'cc-widget.png'
});
}
});})();
TIA

You should try to set contenteditable="false" attribute to root tag of content which you insert into ckeditor

Related

create multi div element in jquery

I want to create a function that creates several boxes for me by capturing the title, text, photo, link and text of the link. That these values ​​change, but the overall shape of the boxes is a model
each div contain with Different values ​​taken by jquery codes:
<div>
<img></img>
<h3></h3>
<p></p>
<a><span></span></a>
</div>
i try it but not complete and not work:
$(document).ready(function () {
var newDiv = document.getElementById("reports-box");
function makenewDivBox(options) {
var div = document.createElement("div");
for (var i = 0; i < options.length; i++) {
var div = document.createElement("div");
var img = document.createElement("img");
var title = document.createElement("h3");
var description = document.createElement("p");
var link = document.createElement("a");
var linkText = document.createElement("span");
img.id = img1;
img.type = "img";
img.src = options[i].src;
title.id = Title1;
title.type = "h3";
title.text = options[i].text;
description.id = des1;
description.type = "p";
description.text = options[i].text;
link.id = link1;
link.type = "hrefa";
link.text = options[i].text;
linkText.id = des1;
linkText.type = "hrefa";
linkText.text = options[i].text;
div.appendChild(img)
div.appendChild(title)
div.appendChild(description)
div.appendChild(link)
div.appendChild(linkText)
}
newDiv.appendChild(div);
}
var options1 = [{
title="t1",
img: "url('image/j1.png')",
description: "content1",
link: "www.link1.com",
linkText: "click here"
}]
var options2 = [{
title="t2",
img: "url('image/j2.png')",
description: "content2",
link: "www.link2.com",
linkText: "more here"
}]
var options3 = [{
title="t3",
img: "url('image/j3.png')",
description: "content3",
link: "www.link3.com",
linkText: "report here"
}]
var options4 = [{
title="t4",
img: "url('image/j4.png')",
description: "content4",
link: "www.link4.com",
linkText: "more details here"
}]
makenewDivBox(options1);
makenewDivBox(options2);
makenewDivBox(options3);
makenewDivBox(options4);
});
I was able to solve it myself.
I'll put the code here, maybe it will be useful for someone:
in html:
<div class="rowReports"></div>
in jquery:
$(document).ready(function () {
var Titels = [
"title1",
"title2",
"title3",
"title4",
"title5",
"title6",
"title7",
"title8"
];
var imgSrces = [
"/FrontEnd/media/image/Nashriyat.png",
"/FrontEnd/media/image/plan.png",
"/FrontEnd/media/image/majameElmi.png",
"/FrontEnd/media/image/kargahAmuzeshi.png",
"/FrontEnd/media/image/targoman.png",
"/FrontEnd/media/image/scoma.png",
"/FrontEnd/media/image/elmsanji.png",
"/FrontEnd/media/image/tablighat.png"
];
var Descriptions = [
"Desc1",
"Desc2 ",
"Desc3",
"Desc4",
"Desc5",
"Desc6",
"Desc7",
"Desc8",
"Desc9"
]
var Links = [
"/Page/frmDefault1.aspx",
"/Page/frmDefault2.aspx",
"/Page/frmDefault3.aspx",
"/Page/frmDefault4.aspx",
"/Page/frmDefault5.aspx",
"/Page/frmDefault6.aspx",
"/Page/frmDefault7.aspx",
"/Page/frmDefault8.aspx"
];
var TextLinks = [
"more report",
"send email",
"more details",
"join group",
"more info",
"add number",
"more",
"continue"
];
for (i = 0; i<Titels.length; i++)
$('.rowReports').append(
$('<div/>')
.attr("id", "newDiv"+i)
.addClass("newDiv reports-box bloated")
.append(' <a href="' + Links[i] + '">' +
'<img class="servicesPic" alt="info" src="' + imgSrces[i] + '"/>' + '<h3>' + Titels[i] + '</h3>' +
'<p>' + Descriptions[i] + '</p>' +
'<span>' + TextLinks[i] + '</span>'+ '</a>'
)
);
});

Google Form to Slack threaded message

In Google Form, on submit, I want to send a new message as one of the fields from the form and want to include the rest of the form fields as threaded messages in to the parent message.
I manually captured one of my thread_ts and successfully sent threaded messages. But I do not know what is the [best] way to get thread_ts id as I submit the form.
var channel = 'xxxx';
function onSubmit(e) {
var response = e.response.getItemResponses();
var Parent = response[0].getResponse();
var Thread = response[1].getResponse();
var Thread2 = response[2].getResponse();
var message = '#Test - ' + Parent;
var payload = {
"payload": '{"text": "' + message + '"}'
//"payload": '{"channel": "xxx","thread_ts": "1571950486.000500","text": "' + Thread + '--' + Thread2 + '"}'
}
var options = {
"method": "post",
"payload": payload
};
UrlFetchApp.fetch(webhookUrl, options);
};
I do not get any errors.
Here is how I was able to do it:
var webhookUrl = 'https://hooks.slack.com/services/***/***/***';
function SendtoSlack(e) {
var formResponse = e.response;
var itemResponses = formResponse.getItemResponses();
for (var i = 0; i < itemResponses.length; i++) {
switch (itemResponses[i].getItem().getTitle()) {
case "Client":
var Client = itemResponses[i].getResponse() || '';
break;
case "Day":
var date = itemResponses[i].getResponse() || '';
break;
case "Time":
var time = itemResponses[i].getResponse() || '';
break;
case "Device":
var Device = itemResponses[i].getResponse() || '';
break;
case "Browser":
var Browser = itemResponses[i].getResponse() || '';
break;
case "Geo":
var GEO = itemResponses[i].getResponse() || '';
break;
}
}
var redirectAlert = '#***'+' - ' + Client;
var payload = {
"payload": '{"text": "' + redirectAlert + '"}',
}
var options = {
"method": "post",
"payload": payload
};
UrlFetchApp.fetch(webhookUrl, options);
var webhookUrl1 = 'https://slack.com/api/conversations.history?token=xoxp-***-***-***-***&channel=***&pretty=1';
var slackJSON = UrlFetchApp.fetch(webhookUrl1);
var slackJSONObject = JSON.parse(slackJSON);
var ts = slackJSONObject.messages[0].ts;
var threadedMessagePayload = {
"payload": '{"thread_ts": "' + ts + '","text": "' + '`\nDevice: ' + Device + '\nBrowser: ' + Browser + '\nGeo: ' + GEO + '\nReported Date & Time: ' + date + ' ' + time + '"}',
}
var optionsForThreadedMessage = {
"method": "post",
"payload": threadedMessagePayload
};
UrlFetchApp.fetch(webhookUrl, optionsForThreadedMessage);
}

Not able to view more than 4 dimensions in QlikSense

I have included Sankey JS as external plugin to Qlik sense. I have added total of 5 dimensions and 1 measure to my chart. But when I view the chart, I'm able to see only 4 dimensions and the last dimension replaces the previous dimensions. For Ex:
Dim1, Dim2, Dim3, Dim4 - It looks fine when I include only 4 dimensions.
Dim1, Dim2, Dim3, Dim5 - If I add 5th dimension to the chart.
The problem is when I view QDataPages[0] size object, I'm able to see only values for 4 dimensions under the qMatrix object. How do I crease the size or see more dimensions. Your help is really appreciated.
requirejs.config({
shim : {
"extensions/SenseSankey/sankeymore" : {
"deps" : ["extensions/SenseSankey/d3.min"]
}
}
});
//define(["jquery", "text!./style.css","extensions/SenseSankey/sankeymore"], function($, cssContent) {
define(["jquery", "text!./style.css","core.utils/theme","extensions/SenseSankey/md5.min","extensions/SenseSankey/sankeymore"], function($, cssContent, Theme, md5) {
'use strict';
$( "<style>" ).html( cssContent ).appendTo( "head" );
return {
initialProperties: {
version: 1.3,
qHyperCubeDef: {
qDimensions: [],
qMeasures: [],
qInitialDataFetch: [{
qWidth: 5,
qHeight: 2000
}]
},
selectionMode: "QUICK"
},
definition: {
type: "items",
component: "accordion",
items: {
dimensions: {
uses: "dimensions",
min: 2,
max: 7
},
measures: {
uses: "measures",
min: 1,
max: 1
},
//sorting: {
// uses: "sorting"
//},
settings: {
uses: "settings",
type: "items",
items : {
SankeyGroup:{
label : "Sankey Settings",
type:"items",
items : {
flowMax:{
type: "integer",
label: "Flow max (10 to 2000)",
ref: "flowMax (max is 2000)",
defaultValue: 500,
min : 10,
max : 2000
},
flowChoice:{
ref:"flowChoice",
type:"integer",
component:"dropdown",
label:"Color Flow",
options:
[
{
value:1,
label:"Qlik Color"
},
{
value:2,
label:"Custom Color"
}
],
defaultValue: 1
},
flowColor:{
type: "string",
component: "color-picker",
//component: "ColorsPickerComponent",
expression: "optional",
label: "Color Flow if no Hex Color",
ref: "flowColor",
defaultValue: 2,
show: function(layout) { return layout.flowChoice == 1 }
},
flowColorCustom:{
type: "string",
label: "Custom Hex Color for Flow",
ref: "flowColorCustom",
defaultValue: "#999999",
show: function(layout) { return layout.flowChoice == 2 }
},
Separateur:{
ref: "displaySeparateur",
type: "string",
component: "dropdown",
label: "Pop-up Separator",
options:
[
{
value:" - ",
label:"-"
},
{
value:" <-> ",
label:"<->"
},
{
value: " → ",
label: " → "
},
],
defaultValue: " - "
},
Format:{
ref: "displayFormat",
type: "string",
component: "dropdown",
label: "Pop-up Format",
options:
[
{
value: "Number2",
label: "1000.12"
},
{
value: "Number1",
label: "1000.1"
},
{
value: "Number",
label: "1000"
},
{
value: "Money2",
label: "1000.12 €"
},
{
value: "Money1",
label: "1000.1 €"
},
{
value: "Money",
label: "1000 €"
},
],
defaultValue: "Number"
},
Palette:{
ref:"displayPalette",
type:"string",
component: "dropdown",
label : "Palette",
options:
[
{
value: "D3-20",
label: "Ordinal Palette 20 colors"
},
{
value: "D3-20c",
label: "Blue-Grey Palette 20 colors"
},
{
value: "D3-20b",
label: "Blue-Purple Palette 20 colors"
},
{
value: "20",
label: "Palette 20 colors"
},
{
value: "20a",
label: "Other Palette 20 colors"
},
{
value: "20b",
label: "Spectral 14 color Palette" // Added by Anand.V.N for Spectral Color Palette
},
],
defaultValue: "D3-20"
},
colorPersistence:{
ref: "colorPersistence",
component: "switch",
type: "boolean",
translation: "Persistence",
defaultValue: false,
trueOption: {
value: true,
translation: "properties.on"
},
falseOption: {
value: false,
translation: "properties.off"
},
show: true
}
}
}
}
}
}
},
snapshot: {
canTakeSnapshot: true
},
paint: function ( $element, layout ) {
// Fonction format pop-up
function formatMoney(n, c, d, t, m, l){
var c = isNaN(c = Math.abs(c)) ? 2 : c,
d = d == undefined ? "." : d,
t = t == undefined ? "," : t,
s = n < 0 ? "-" : "",
i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
j = (j = i.length) > 3 ? j % 3 : 0;
return l + ' \n ' + s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "")+ m;
};
// Persistent color function
var hashScale = d3.scale.linear().domain([1, 4294967295]).range([ 0, 19.9999 ]);
function hashL(str) {
var hashL = 5381,
i = str.length
while(i)
hashL = (hashL * 33) ^ str.charCodeAt(--i)
//hash = md5(str)
return hashL >>> 0;
}
function getColorForNode(strValue) {
if (colorPersistence===true) {
return colours[parseInt(Math.floor(hashScale(hashL(md5(strValue)))))];
} else
{
return colours[Math.floor(Math.random() * (19))];
}
}
var _this = this;
var maxHeight = layout.flowMax;
var displayFormat = layout.displayFormat;
var displaySeparateur = layout.displaySeparateur;
var displayPalette = layout.displayPalette;
var colorPersistence = layout.colorPersistence;
if (displayPalette === "D3-20") {
var colours = ['#1f77b4','#aec7e8','#ff7f0e','#ffbb78','#2ca02c','#98df8a','#d62728','#ff9896','#9467bd','#c5b0d5','#8c564b',
'#c49c94','#e377c2','#f7b6d2','#7f7f7f','#c7c7c7','#bcbd22','#dbdb8d','#17becf','#9edae5' ];
}
else if (displayPalette === "D3-20b") {
var colours = ['#393b79','#5254a3','#6b6ecf','#9c9ede','#637939','#8ca252','#b5cf6b','#cedb9c','#8c6d31','#bd9e39',
'#e7ba52','#e7cb94','#843c39','#ad494a','#d6616b','#e7969c','#7b4173','#a55194','#ce6dbd','#de9ed6'];
}
else if (displayPalette === "D3-20c") {
var colours = ['#3182bd','#6baed6', '#9ecae1','#c6dbef','#e6550d','#fd8d3c','#fdae6b','#fdd0a2','#31a354',
'#74c476','#a1d99b','#c7e9c0','#756bb1','#9e9ac8','#bcbddc','#dadaeb','#636363','#969696','#bdbdbd','#d9d9d9' ];
}
else if (displayPalette === "20") {
var colours = [ '#1abc9c','#7f8c8d','#2ecc71','#bdc3c7','#3498db','#c0392b','#9b59b6','#d35400','#34495e','#f39c12',
'#16a085','#95a5a6','#27ae60','#ecf0f1','#2980b9','#e74c3c','#8e44ad','#e67e22','#2c3e50','#f1c40f' ];
}
else if (displayPalette === "20a") {
var colours = [ '#023FA5','#7D87B9','#BEC1D4','#D6BCC0','#BB7784','#FFFFFF','#4A6FE3','#8595E1','#B5BBE3','#E6AFB9',
'#E07B91','#D33F6A','#11C638','#8DD593','#C6DEC7','#EAD3C6','#F0B98D','#EF9708','#0FCFC0','#9CDED6'];
}
else if (displayPalette === "20b") { // Added by Anand.V.N for Spectral Color Palette
var colours = [ '#F46D43','#E78162','#FDAE61','#F0B880','#FEE08B','#F1CA5F','#E6F598','#D4E86D','#ABDDA4','#85D07B',
'#66C2A5','#44B591','#3288BD','#5E4FA2','#D9D9D9','#BFBFBF','#A6A6A6','#7F7F7F','#595959','#9CDED6'];
}
var flowColor = (layout.flowChoice == 2) ? layout.flowColorCustom : Theme.palette[layout.flowColor];
var qData = layout.qHyperCube.qDataPages[0];
// create a new array that contains the dimension labels
var qDim = layout.qHyperCube.qDimensionInfo.map(function(d) {
return d.qFallbackTitle;
});
console.log(layout.qHyperCube);
var divName = layout.qInfo.qId;
var qMatrix = qData.qMatrix.sort();
var source = qMatrix.map(function(d) {
var path = "";
var sep = "";
for (var i = 0; i < d.length - 1; i++) {
path += sep + (d[i].qText.replace('|', ' ')) + '|' + (d[i].qElemNumber);
sep = ",";
}
return {
//"Path":d[0].qText,
"Path": path,
"Frequency": d[d.length - 1].qNum
}
});
var id = "sk_"+ layout.qInfo.qId;
if (document.getElementById(id)) {
$("#" + id).empty();
}
else {
$element.append($('<div />').attr("id", id));
}
$("#" + id).width($element.width()).height($element.height());
var sLinks = [];
var endArr = [];
var catArray = [];
//********Creates Duplicate IDs*************
// $element.attr("id",id)
//******************************************
//var td = _this.Data;
var sNodes = [];
var jNodes = [];
var rev = 0; //permet de pivoter les dimensions
source=source.slice(0,maxHeight);
//source foreach
source.forEach(function(d) {
//var row = d;
var path = d.Path;
var val = parseFloat(d.Frequency);
if(val > 0) {
var tArr = path.split(",",4);
//tArr.sort();
if (rev == "1") {
tArr.reverse();
}
if (tArr.length > 1) {
$.each(tArr, function(i) {
if(tArr.length === (i + 1)){
tArr[i] = this.toString().trim() + "~end";
}else{
tArr[i] = this.toString().trim() + "~" + i;
}
});
$.each(tArr, function(i) {
if ($.inArray(this.toString().trim(), sNodes) === -1) {
sNodes.push(this.toString().trim());
}
});
}
}
});
sNodes.forEach(function(d) {
jNodes.push({
name: d.toString()
})
});
//source foreach
source.forEach(function(d) {
//var row = d;
var path = d.Path
var val = parseFloat(d.Frequency);
if(val > 0) {
var tArr = path.split(",");
if (rev == "1") {
tArr.reverse();
}
if (tArr.length > 1) {
$.each(tArr, function(i) {
if(tArr.length === (i + 1)){
tArr[i] = this.toString().trim() + "~end";
}else{
tArr[i] = this.toString().trim() + "~" + i;
}
});
$.each(tArr, function(i) {
var tFlag = "no";
if ((i + 1) != tArr.length) {
var cS = $.inArray(this.toString().trim(), sNodes);
var cT = $.inArray(tArr[i + 1].toString().trim(), sNodes);
$.each(sLinks, function(i, v) {
if ((v.source === cS) && (v.target === cT)) {
tFlag = "yes";
v.value = v.value + val;
}
});
if (tFlag == "no") {
sLinks.push({
"source" : cS,
"target" : cT,
"value" : val
});
}
}
});
}
}
});
var margin = {
top : 1,
right : 1,
bottom : 0,
left : 1
}, width = $element.width(), height = $element.height();
// Added svgHeader class for Scrollbars by Anand.V.N
var svg = d3.select("#sk_" + divName).attr("class","svgHeader").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var sankey = d3.sankey().nodeWidth(15).nodePadding(10).size([width -10 , height-10]);
var path = sankey.link();
sankey.nodes(jNodes).links(sLinks).layout(32);
var link = svg.append("g").selectAll(".link").data(sLinks).enter().append("path").attr("class", "link").attr("d", path).style("stroke-width",function(d) {
return Math.max(1, d.dy);
}).sort(function(a, b) {
return b.dy - a.dy;
});
//Color of Flow
link.style('stroke', flowColor);
// affiche la valeur sur le flux en popup
link.append("title").text(function(d) {
//Je supprime les tildes et les pipes
var start = d.source.name.split('|')[0];
//var start = d.source.name.substr(0, d.source.name.length - 2).split('|')[0];
var end = d.target.name.split('|')[0];
if (displayFormat === "Number"){
return formatMoney(d.value, 0, '.', ' ','' , start + displaySeparateur + end);
}
if (displayFormat === "Number1"){
return formatMoney(d.value, 1, '.', ' ','' , start + displaySeparateur + end);
}
if (displayFormat === "Number2"){
return formatMoney(d.value, 2, '.', ' ','' , start + displaySeparateur + end);
}
if (displayFormat === "Money"){
return formatMoney(d.value, 0, '.', ' ',' €' , start + displaySeparateur + end);
}
if (displayFormat === "Money1"){
return formatMoney(d.value, 1, '.', ' ',' €' , start + displaySeparateur + end);
}
if (displayFormat === "Money2"){
return formatMoney(d.value, 2, '.', ' ',' €' , start + displaySeparateur + end);
}
});
var node = svg
.append("g").selectAll(".node").data(jNodes).enter().append("g").attr("class", "node").attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
node.on("click",function(d, i) {
//on passe a la fonction l'identifiant qElement precedemment stocké dans le nom et le nom de la dimension sous forme d'un tableau
_this.backendApi.selectValues(
parseInt(d.name.split('~')[1].replace('end', qDim.length - 1)),
[ parseInt(d.name.split('~')[0].split('|')[1]) ],
true
);
})
// Start of Node and Path/Link Color. Declared variables for the arrays to store unique colors for specific nodes Added by Anand.V.N
var nodeLinkColor='';
var nodeName='';
var colorArray= new Array();
var objColor={};
var tempArr=new Array();
// End of Node and Path/Link Color Added by Anand.V.N
// AVEC POPUP sur le carré de couleur
node.append("rect").attr("height", function(d) {
return d.dy;
}).attr("width", sankey.nodeWidth()).style("fill", function(d) {
// Implemented Logic for the arrays to store unique colors for specific nodes Added by Anand.V.N
nodeName= d.name.split('|')[0];
if (!tempArr.contains(nodeName)) {
d.color = getColorForNode(d.name);
nodeLinkColor=d.color;
objColor[nodeName]=nodeLinkColor
colorArray.push(objColor);
}
else
{
colorArray.forEach(function(i){
d.color=i[nodeName];
});
}
tempArr.push(nodeName);
// End of Node and Path/Link Color Added by Anand.V.N
return d.color;
}).style("stroke", function(d) {
return d3.rgb(d.color).darker(2);
}).append("title").text(function(d) {
var level = d.name.substr(d.name.indexOf("~")+1,1);
if (level === "e" ){level = qDim.length -1;}
var entete = qDim[level] + ' : ' + d.name.split('|')[0];
if (displayFormat === "Number"){
return formatMoney(d.value, 0, '.', ' ','', entete);
}
if (displayFormat === "Number1"){
return formatMoney(d.value, 1, '.', ' ','',entete);
}
if (displayFormat === "Number2"){
return formatMoney(d.value, 2, '.', ' ','',entete);
}
if (displayFormat === "Money"){
return formatMoney(d.value, 0, '.', ' ',' €',entete);
}
if (displayFormat === "Money1"){
return formatMoney(d.value, 1, '.', ' ',' €',entete);
}
if (displayFormat === "Money2"){
return formatMoney(d.value, 2, '.', ' ',' €',entete);
}
});
var link = svg.append("g").selectAll(".link").data(sLinks).enter().append("path").attr("class", "link").attr("d", path).style("stroke-width",function(d) {
return Math.max(1, d.dy);
}).sort(function(a, b) {
return b.dy - a.dy;
});
link.style('stroke', function(d) {
// Implemented Logic to compare node arrays for specific colors and assign to the link/path. Added by Anand.V.N
var start = d.source.name.split('|')[0];
var end = d.target.name.split('|')[0];
colorArray.forEach(function(i){
// console.log(i);
if(colorArray.indexOf(start)==-1)
d.color=i[start];
});
// End of Node and Path/Link Color Added by Anand.V.N
return d.color;
});
link.append("title").text(function(d) {
var start = d.source.name.split('|')[0];
//var start = d.source.name.substr(0, d.source.name.length - 2).split('|')[0];
var end = d.target.name.split('|')[0];
if (displayFormat === "Number"){
return formatMoney(d.value, 0, '.', ' ','' , start + displaySeparateur + end);
}
if (displayFormat === "Number1"){
return formatMoney(d.value, 1, '.', ' ','' , start + displaySeparateur + end);
}
if (displayFormat === "Number2"){
return formatMoney(d.value, 2, '.', ' ','' , start + displaySeparateur + end);
}
if (displayFormat === "Money"){
return formatMoney(d.value, 0, '.', ' ',' €' , start + displaySeparateur + end);
}
if (displayFormat === "Money1"){
return formatMoney(d.value, 1, '.', ' ',' €' , start + displaySeparateur + end);
}
if (displayFormat === "Money2"){
return formatMoney(d.value, 2, '.', ' ',' €' , start + displaySeparateur + end);
}
});
// Changes the 'x' attribute size for the <text> to include text within <rect> nodes. Also have updated <text> tag by appending it next to <rect> tag. Added by Anand.V.N
node.append("text").attr("class", "nodeTitle").attr("x", 5).attr("y", function(d) {
return d.dy / 2;
}).attr("dy", ".35em").attr("text-anchor", "middle").attr("alignment-baseline", "middle").attr("transform", null).text(function(d) {
var str = d.name.substring(0, d.name.indexOf("~")).split('|')[0];
return str
}).filter(function(d) {
return d.x < width / 2;
}).attr("text-anchor", "start");
// End of <text> tag. Added by Anand.V.N
/*
function dragmove(d) {
d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")");
sankey.relayout();
link.attr("d", path);
}
*/
}
};
} );
Regards,
Just an assumption: Did you change this code from qWidth=4 to qWidth=5?
qInitialDataFetch: [{
qWidth: 5,
qHeight: 2000
}
If this is the case, then remove the extension from your sheet, refresh the browser and re-add the extension again!
I think you just have to recreate the app, qwidth and max/min dimensions has been set correctly.
Just recreate the app or re-add the extension.
I faced the same problem, after recreating the app, the problem has been solved.

Add a user to a group programatically

Is it possible to add a user to a group via REST/sdk?
Scenario: We want to add all our users to a mandatory group on a regularly basis.
Thanks!Max
you can get group ids from share point list like this
function GetMandatoryGroups() {
var context;
var factory;
var appContextSite;
var oList;
var collListItem;
context = new SP.ClientContext(appweburl);
factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostweburl);
this.web = appContextSite.get_web();
oList = this.web.get_lists().getByTitle('MandatoryGroups');
context.load(oList);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View><RowLimit>100</RowLimit></View>');
collListItem = oList.getItems(camlQuery);
context.load(collListItem, 'Include(Title,Id)');
context.executeQueryAsync(
Function.createDelegate(this, successHandler),
Function.createDelegate(this, errorHandler)
);
function successHandler() {
MandatoryGroups = new Array();
var listItemInfo = '';
var listitemenumerator = collListItem.getEnumerator();
while (listitemenumerator.moveNext()) {
var olistitem = listitemenumerator.get_current();
//listItemInfo += '<li>ID:' + olistitem.get_id().toString() + ' GroupID: ' + olistitem.get_item('Title') + '</li>';
MandatoryGroups.push(olistitem.get_item('Title'));
}
AutoJoinGroups();
// document.getElementById("message").innerHTML = 'Lists found' + oList.get_title() + ':<ul>' + listItemInfo + '</ul>';
}
function errorHandler(sender, args) {
document.getElementById("message").innerText =
"Could not complete cross-domain call: " + args.get_message();
}
}
you can join users to the mendatory groups like this (after user logs in )
function AutoJoinGroups() {
yam.platform.request({
// yam.request({
url: "groups.json?mine=1",
method: "GET",
data: {},
success: function (group) {
//for ($i = 0; $i < MandatoryGroups.length; $i++) {
// if (!ArrayContains(MandatoryGroups[$i].toString(), group)) {
// joinGroupAsync(MandatoryGroups[$i].toString());
// setTimeout('', 10000);
// // setTimeout(joinGroupAsync(MandatoryGroups[$i].toString()),5000);
// }
//}
var i = 0;
function AsyncAutoJoinLoop() {
if (i < MandatoryGroups.length) {
if (!ArrayContains(MandatoryGroups[i].toString(), group)) {
setTimeout(function () {
joinGroupAsync(MandatoryGroups[i].toString());
i++;
if (i < MandatoryGroups.length) {
AsyncAutoJoinLoop();
}
}, 3000)
}
}
}
AsyncAutoJoinLoop();
// getMyGroups();
},
error: function (group) {
console.error("There was an error with the request.");
}
});
}
function joinGroupAsync(id) {
yam.platform.request({
// yam.request({
url: "group_memberships.json?group_id=" + id,
method: "POST",
data: {},
success: function (group) {
},
error: function (group) {
console.error("There was an error with the request.");
}
});
}
you can add group to the sharepoint list like this.
function InsertMandatoryItem() {
var context;
var factory;
var appContextSite;
var oListItem;
context = new SP.ClientContext(appweburl);
factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostweburl);
this.web = appContextSite.get_web();
var oList = this.web.get_lists().getByTitle('MandatoryGroups');
var itemCreateInfo = new SP.ListItemCreationInformation();
oListItem = oList.addItem(itemCreateInfo);
oListItem.set_item('Title', InsertGroupId);
oListItem.update();
context.load(oListItem);
context.executeQueryAsync(
Function.createDelegate(this, onQuerySucceeded),
Function.createDelegate(this, onQueryFailed)
);
function onQuerySucceeded() {
//alert('Item created: ' + oListItem.get_id());
// getMyGroups();
// AutoJoinGroups();
$.getScript(scriptbase + 'SP.RequestExecutor.js', GetMandatoryGroups);
}
function onQueryFailed(sender, args) {
$.getScript(scriptbase + 'SP.RequestExecutor.js', GetMandatoryGroups);
alert('Request failed. ' + args.get_message() +
'\n' + args.get_stackTrace());
}
}
You can remove remove group from sharepoint list like this
function RemoveMandatoryGroup() {
var context;
var factory;
var appContextSite;
var collListItem;
var itemId;
context = new SP.ClientContext(appweburl);
factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostweburl);
this.web = appContextSite.get_web();
var oList = this.web.get_lists().getByTitle('MandatoryGroups');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + RemoveGroupId.toString() + "</Value></Eq></Where></Query></View>");
collListItem = oList.getItems(camlQuery);
context.load(collListItem, 'Include(Title,Id)');
// this.oListItem.deleteObject();
context.executeQueryAsync(
Function.createDelegate(this, onQuerySucceeded),
Function.createDelegate(this, onQueryFailed)
);
function onQuerySucceeded() {
var oListItem;
var listitemenumerator = collListItem.getEnumerator();
while (listitemenumerator.moveNext()) {
var itemtoDelete = listitemenumerator.get_current();
////listItemInfo += '<li>ID:' + olistitem.get_id().toString() + ' GroupID: ' + olistitem.get_item('Title') + '</li>';
//MandatoryGroups.push(olistitem.get_item('Title'));
itemId = itemtoDelete.get_id();
}
oListItem = oList.getItemById(itemId);
oListItem.deleteObject();
context.executeQueryAsync(Function.createDelegate(this, onQueryDeleteSucceeded), Function.createDelegate(this, onQueryDeleteFailed));
//alert('Item created: ' + oListItem.get_id());
function onQueryDeleteSucceeded() {
//alert('Request failed. ' + args.get_message() +
// '\n' + args.get_stackTrace());
getMyGroups();
$.getScript(scriptbase + 'SP.RequestExecutor.js', GetMandatoryGroups);
}
function onQueryDeleteFailed() {
alert('Request failed. ' + args.get_message() +
'\n' + args.get_stackTrace());
}
}
function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() +
'\n' + args.get_stackTrace());
}
}
No, there isn't. This is by design. Yammer likes to entice with the carrot, not by the stick. What we've done is create communications to ask people to join a specific group.
The api does allow the ability for the currently logged to be joined to a specific group. E.g. Put a link on a SharePoint site that says "Join the Yammer group", and have the action join that user to the group. You can see the details for how to do that here:
https://developer.yammer.com/restapi/#rest-groups
ya, in costume app yo can autojoin that user when he logs in..Same thing i ma doing.

Why does my webpage submit the form when it loads, but no submit button has been clicked?

The windows.pageload event handler submits the page on page load. My intention is for this to wire the event handler to the submit event when the form submit button is clicked. What did I do wrong? Thanks!
function submit_data () {
var parent1Phone = $("parent1Phone").value;
var areaCode = parent1Phone.substring(0,3);
var prefix = parent1Phone.substring(4,7);
var suffix = parent1Phone.substring(8,12);
var firstName = $("firstName").value;
var lastName = $("lastName").value;
var sportID = $("sportID").value;
var entryFrom = $("entryFrom").value;
var linkSource = codeSource;
var primaryEmail = $("primaryEmail").value;
var graduationYear = $("graduationYear").value;
var postalCode = $("postalCode").value;
var parent1FirstName = $("parent1FirstName").value;
var parent1LastName = $("parent1LastName").value;
var parent1Relationship = $("parent1Relationship").value;
var parent1Phone1= areaCode;
var parent1Phone2 = prefix;
var parent1Phone3 = suffix;
var parent1PhoneType = $("parent1PhoneType").value; //No validation required. No non-choice allowed.
var parent1Email = $("parent1Email").value;
var parent1EmailConfirm = $("parent1Email").value;
var successDestination = success;
var errorDestination = failure;
var url = "http://recruit- match.ncsasports.org/fasttrack/saefentry/submitFullFormRemote.go?";
window.location.href = url + "firstName="+ firstName + "&lastName=" + "&lastName=" + lastName +"&sportID=" + sportID + "&entryFrom=" + entryFrom + "&linkSource=" + linkSource + "&primaryEmail=" + primaryEmail +"&graduationYear=" + graduationYear + "&postalCode=" + postalCode + "&parent1FirstName=" + parent1FirstName + "&parent1LastName=" + parent1LastName + "&parent1Relationship=" + parent1Relationship + "&parent1Phone1=" + parent1Phone1 + "&parent1Phone2=" + parent1Phone2 + "&parent1Phone3=" + parent1Phone3 + "&parent1PhoneType=" + parent1PhoneType + "&parent1Email=" + parent1Email + "&parent1EmailConfirm=" + parent1Email + "&successDestination=" + successDestination + "&errorDestination=" + errorDestination;
}
function prepareEventHandlers() {
$("frmNcsa").onclick = submit_data();
}
window.onload = function() {
prepareEventHandlers();
}
You are calling submit_data in the assignment $("frmNcsa").onclick = submit_data();, it should be $("#frmNcsa").click(submit_data);
assuming all the strings passed to the jQuery function are the ids of elements, they shold be prepended with #.