I am working on lecture validation code. I want to be able to check a line, get content and validate it, if it is what the user should put. I am using "for loop" to iterate the process. JSON to set validation process. The issue is the return error does not match. My question is what is the best way to validate code using Ace editor?
Validation Process (JSON)
{
"course" : "html",
"count" : 2,
"line" : [8, 9],
"check" : ["My name is", ""],
"error" : ["Please type your name. Start with 'My name is'","Write why you want to learn HTML"]
}
HTML & Javascript
var html = ace.edit("html-editor");
html_option = {
mode: "ace/mode/javascript",
theme: "ace/theme/monokai",
fontSize: "10pt",
showPrintMargin : false,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
wrap: true,
scrollPastEnd: true,
displayIndentGuides: true,
};
html.setOptions(html_option);
//Get the JSON validation file
var fond = $(".json").html();
fond = JSON.parse(fond);
//Begin validation on Click "Run"
$("#run").on("click", function(){
$('#run').html('<i class="fa fa-spinner fa-spin"></i> Running');
var fond_course = fond.course;
var fond_count = fond.count;
//Begin error check
for (var i = 0; i < fond_count; i++) {
var line = fond.line[i] - 1;
var error = fond.error[i] ;
var check = fond.check[i];
var fond_check = html.session.getLine(line);
var patt = new RegExp(check);
var res = patt.test(fond_check);
//If a specific line is empty
if(check === null){
html.gotoLine(line);
line = line + 1;
//Error function with parameters
//error_note(true, error, line);
}
//If a line is not equal to the JSON file value
else if(!res){
html.gotoLine(line);
line = line + 1;
//Error function with parameters
//error_note(true, error, line);
}else if(res && check !== null){
//Code is validated, now save the code
}
}
});
#html-editor{
height: 500px;
}
#run{
font-size: 20px;
padding: 10px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.5/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.5/ext-language_tools.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="run">Run</button>
<pre id="html-editor"><!DOCTYPE html>
<html>
<head>
<title>Introduction to HTML</title>
</head>
<body>
<h1>Welcome to Code</h1>
<p>Edit and replace with your name</p>
</body>
</html><pre>
Related
I am making an attempt to create my own chatroom using npm, as it stands everything is working smoothly but my main concern is SQL injection or people entering HTML because it will parse anything entered. There is no form being used and the input button, text field and output are all controlled by JavaScript. below is the part of the HTML I am referring to.
<div id="wrapper">
<div class="bubble-container" ></div>
</div>
<div id="sendCtrls">
<input type="text" placeholder="Your message here" id="text">
<button id="myBtn">Send</button>
</div>
This is my .php file which contains all the JavaScript.
<script>
// -------------------------
//var name = prompt('What is your name?');
var name = "<?php echo $_SESSION['username']; ?>";
var bubbles = 1;
var maxBubbles = 60;
var sock = new WebSocket("ws://localhost:5001");
sock.onopen = function() {
var bubble = $("#wrapper");
bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text">\
<p><b>*** Welcome '+name+' to the chat!</b><br>\
These are the rules, please read & follow them.<br>\
1. Be polite in chat.<br>\
2. Keep personal disputes out of chat.<br>\
3. No advertising.<br>\
4. Do not ask to become a Moderator.\
</p></div></div>');
myChat(bubble);
sock.send(JSON.stringify({
type: "name",
data: name
}));
}
// --------------------------
var maxLength = 200; // chars per bubble
sock.onmessage = function(event){
console.log(event);
var json = JSON.parse(event.data);
var bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text"><p><strong>'+json.name+':</strong> '+json.data+'</p></div></div>');
myChat(bubble);
}
// ---------------------------
document.querySelector('button').onclick = function (){
var text = document.getElementById('text').value;
if(text != "") {
if (text.length < maxLength) {
document.getElementById('text').value='';
sock.send(JSON.stringify({
type: "message",
data: text
}));
var bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text"><p><strong>'+name+':</strong> '+text+'</p></div></div>');
myChat(bubble);
}else{
var bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text"><p>*** Your message exceeds '+maxLength+' characters!</p></div></div>');
myChat(bubble);
};
}
};
// --------------------------
var input = document.getElementById("text");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById("myBtn").click();
}
});
// --------------------------
function myChat(bubble){
$("#msgText").val("");
$(".bubble-container:last").after(bubble);
if (bubbles >= maxBubbles) {
var first = $(".bubble-container:first").remove();
bubbles--;
}
bubbles++;
$('.bubble-container').show(250, function showNext() {
if (!($(this).is(":visible"))) {
bubbles++;
}
$(this).next(".bubble-container").show(250, showNext);
$("#wrapper").scrollTop(9999999);
});
};
</script>
I have not included the server script which is also just JavaScript but can do so if needed. PHP has no interaction with what is being submitted. 2nd question is, will I need to write anything server side to protect against SQL injection or to prevent HTML being entered?
I am quite new to this all, so i am pretty sure this is a simple oversight on my part, but i cant get it to run.
When i deploy the code below and click on the button, it does not do anything. When i inspect the html in my browser, it says "userCodeAppPanel:1 Uncaught ReferenceError: csvHTML is not defined
at HTMLInputElement.onclick"
When i run the function csvHTML from Code.gs, I can see the expected results in my Logger.log, so it seems the problem does not lie in my code.gs
What i am trying to achieve is showing the csv results in html. When all works fine, i will want to work with the data in some other way.
Attached below is my code.
Index.html:
<!DOCTYPE html>
<!-- styles -->
<?!= HtmlService.createHtmlOutputFromFile("styles.css").getContent(); ?>
<div class="content">
<h1>csv representation</h1>
<input class="button" type="submit" onclick="html();" value="Refresh" id="refresh"><br>
<div id="tabel"></div>
<svg class="chart"></svg>
</div>
<!-- javascript -->
<script src="//d3js.org/d3.v3.min.js"></script>
<?!= HtmlService.createHtmlOutputFromFile("chart.js").getContent() ?>
<?!= HtmlService.createHtmlOutputFromFile("main.js").getContent() ?>
<script>
function html()
{
var aContainer = document.createElement('div');
aContainer.classList.add('loader_div');
aContainer.setAttribute('id', 'second');
aContainer.innerHTML = "<div class='loader_mesage'><center>Fetching csv list. Please be patient!<br /> <br /><img src='https://i.ibb.co/yy23DT3/Dual-Ring-1s-200px.gif' height='50px' align='center'></img></center></div>";
document.body.appendChild(aContainer);
google.script.run
.withSuccessHandler(showTable)
.csvHTML();
}
function showTable(tabel)
{
document.getElementById("tabel").innerHTML = tabel;
var element = document.getElementById("second");
element.parentNode.removeChild(element);
}
</script>
and Code.gs:
function doGet(e) {
return HtmlService.createTemplateFromFile("index.html")
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
// Fecth Data and make a csv output.
function csvHTML()
{
var query = "{ 'query': 'SELECT * FROM `<some table>` limit 1000;', 'useLegacySql': false }";
var job = BigQuery.Jobs.query(query, <projectName>);
var json = JSON.parse(job);
var tabel = json2csv(json);
Logger.log(tabel)
return tabel;
}
function json2csv(json, classes) {
var headerRow = '';
var bodyRows = '';
classes = classes || '';
json.schema.fields.forEach(function(col){
headerRow +=col.name+",";
})
json.rows.forEach(function(row){
row.f.forEach(function(cell){
bodyRows +=cell.v+",";
})
})
return headerRow + bodyRows }
So thanks to the suggestions by TheMaster, i rewritten it into the following:
index.html:
<!-- javascript -->
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
function html()
{
var aContainer = document.createElement('div');
aContainer.classList.add('loader_div');
aContainer.setAttribute('id', 'second');
aContainer.innerHTML = "<div class='loader_mesage'><center>Fetching csv list. Please be patient!<br /> <br /><img src='https://i.ibb.co/yy23DT3/Dual-Ring-1s-200px.gif' height='50px' align='center'></img></center></div>";
document.body.appendChild(aContainer);
google.script.run
.withSuccessHandler(showTable)
.csvHTML();
}
function showTable(tabel)
{
document.getElementById("tabel").innerHTML = tabel;
var element = document.getElementById("second");
element.parentNode.removeChild(element);
}
</script>
<!DOCTYPE html>
<div class="content">
<h1>csv representation</h1>
<input class="button" type="submit" onclick="html();" value="Refresh" id="refresh"><br>
<div id="tabel"></div>
<svg class="chart"></svg>
</div>
Code.gs has not been modified.
It appears that the <?!= htmlService.createHtmlOutputFromFile("styles.css").getContent(); ?> and other createHtmlOutputFromFile were getting in the way. Eventually i need these, but I will figure out how to incorporate that at a later stage.
Thanks for all the advice and help!
Disclaimer: I have zero experience with Google Apps Script, so take this with a grain of salt.
Looking at their documentation for BigQuery, it seems you are not querying the database correctly. I am surprised by your claim that Logger.log() shows the correct output. It does not appear that it should work.
In case I am right, here is what I propose you change your Code.gs file to:
function doGet(e) {
return HtmlService.createTemplateFromFile("index.html")
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
// Fetch Data and make a csv output.
function csvHTML() {
var results = runQuery('SELECT * FROM `<some table>` limit 1000;');
var tabel = toCSV(results);
Logger.log(tabel);
return tabel;
}
/**
* Runs a BigQuery query and logs the results in a spreadsheet.
*/
function runQuery(sql) {
// Replace this value with the project ID listed in the Google
// Cloud Platform project.
var projectId = 'XXXXXXXX';
var request = {
query: sql,
useLegacySQL: false
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
var fields = queryResults.schema.fields.map(function(field) {
return field.name;
});
var data = [];
if (rows) {
data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
}
return {
fields: fields,
rows: rows
};
}
function toCSV(results) {
var headerRow = results.fields.join(',');
var bodyRows = results.rows.map(function(rowData) {
return rowData.map(function(value) {
// for proper CSV format, if the value contains a ",
// we need to escape it and surround it with double quotes.
if (typeof value === 'string' && value.indexOf('"') > -1) {
return '"' + value.replace(/"/g, '\\"') + '"';
}
return value;
});
})
.join('\n'); // join the lines together with newline characters
return headerRow + '\n' + bodyRows;
}
Reminder: I have not tested this, I'm purely writing this based on my knowledge of Javascript and their documentation and sample code.
Is it possible to pass a function to the tooltip key in the Zingchart Json?
I tried the following so far:
$scope.applyTooltip = function (timestamp) {
console.log(timestamp);
var tooltip = "<div>";
var data = {
timestamp1: {
param1: "bla",
param2: "foo,
},
...
}
for(var param in data){
console.log(param);
tooltip += param+": "+data[param]+"<br>";
}
tooltop += "</div>;
return tooltip;
}
$scope.graphoptions = {
//...
//just displaying the relevant options
plot: {
"html-mode": true,
tooltip: $scope.applyTooltip("%kt"),
}
}
}
But the function gets the string "%kt" as it is and not the wanted X-Value of the hovered Plot. So how is it possible to pass the X-Value in the Function?
ZingChart does not allow passing in functions through the configuration object.
Instead, there is a property called "jsRule" which allows you to pass the name a function to be evaluated during each tooltip event.
tooltip : {
jsRule : "CustomFn.formatTooltip()"
}
Inside that function, a parameter will be available that will contain information about the node you moused over such as value, scaletext, plotindex, nodeindex, graphid, and more. Simply return an object for the tooltip (including the formatted text) and ZingChart will take care of the rest. Example provided down below.
The one caveat to jsRule is that the function name has to be accessible globally since ZingChart does not accept inline functions. We are aware of this issue and are planning for this to be an option in future versions.
CustomFn = {};
var myConfig = {
type: "line",
tooltip : {
jsRule : "CustomFn.formatTooltip()"
},
series : [
{
values : [1,3,2,3,4,5,4,3,2,1,2,3,4,5,4]
},
{
values : [6,7,8,7,6,7,8,9,8,7,8,7,8,9,8]
}
]
};
CustomFn.formatTooltip = function(p){
var dataset = zingchart.exec('myChart', 'getdata');
var series = dataset.graphset[p.graphindex].series;
var tooltipText = "";
for (var i=0; i < series.length; i++) {
tooltipText += "Series " + i + " : " + series[i].values[p.nodeindex] + "";
if (i !== series.length-1) {
tooltipText += "\n";
}
}
return {
text : tooltipText,
backgroundColor : "#222"
}
}
zingchart.render({
id : 'myChart',
data : myConfig,
height: 400,
width: 600
});
<!DOCTYPE html>
<html>
<head>
<script src= 'https://cdn.zingchart.com/2.3.1/zingchart.min.js'></script>
</head>
<body>
<div id='myChart'></div>
</body>
</html>
On the "share" part of the application, I've got an issue in a specific site dashboard.
This problem occurs randomly when you create a site and apparently with no particular reason.
My issue is concerning the "Site Profile" dashlet. I've developed a custom button which enables the user to send an e-mail to one or multiple members who have subscribed to the site's informations. It relies on a javascript file name "ts-send-mail-to-all-members.js" When you click on it, an pop-up window is open containing checkboxes which enables you to select members, a TinyMCE component, which enables you to write the e-mail and a two buttons, one to send e-mail the other one to close the pop-up.
The subscription button had also been created doesn't generate any error.
The problem occurs when you click on the button which enables you to send e-mails.
There is a javascript error that is throwned accordingly to the site's dashboard configuration.
1) For instance, if the only dashlet present on the page is "Site Profile", I have this following error :
Alfresco.module.SimpleDialog is not a constructor
http://localhost:8080/share/res/modules/ts-send-mail-to-all-members.js
Line 139
The code line is the following :
var sendMailToAllMembersDialog = new Alfresco.module.SimpleDialog(this.id + "-sendMailToAllMembersDialog");
2) I didn't target the specific configuration to obtain this error, but randomly you can also have this error :
tinyMCE is not defined
[Break on this error] tinyMCE.init({
Apparently, tinyMCE is not identified by Alfresco which throws an exception. In the script, "tinyMCE.init" is the first statement where the component is called. I've made researches on this error and usually you just have to add a <script> tag with the src="" argument in order to specify where tiny_mce.js is located. I can be an URL or its location in the Alfresco application.
However, my script is entirely write in JavaScript and I can't write HTML statements.
3) You've got a third case in which the pop-up appears and the functionnality works without any exception being throwned. This case occurs when you add the "Events List" dashlet, on the Site's dashboard.
Here is the "ts-send-mail-to-all-members.js" source code :
/**
* Copyright (C) T&S.
*
*/
/**
* ts-abonnement-site module
*
*
*
* #namespace Alfresco.module
* #class Alfresco.module.TsAbonnementSite
*/
(function()
{
var Dom = YAHOO.util.Dom,
Event = YAHOO.util.Event,
Element = YAHOO.util.Element,
Bubbling = YAHOO.Bubbling,
KeyListener = YAHOO.util.KeyListener
nodeRef = "";
/**
* CreateSite constructor.
*
* #param htmlId {string} A unique id for this component
* #return {Alfresco.CreateSite} The new DocumentList instance
* #constructor
*/
Alfresco.module.TsSendMailToAllMembers = function(containerId)
{
var instance = Alfresco.util.ComponentManager.get(this.id);
if (instance !== null)
{
throw new Error("An instance of Alfresco.module.TsSendMailToAllMembers already exists.");
}
Alfresco.module.TsSendMailToAllMembers.superclass.constructor.call(this, "Alfresco.module.TsSendMailToAllMembers", containerId, ["button", "container", "connection", "selector", "json"]);
return this;
};
YAHOO.extend(Alfresco.module.TsSendMailToAllMembers, Alfresco.component.Base,
{
members:[],
options:{
siteId:""
},
onReady: function TS_onReady()
{
this.widgets.sendMailToAllMembersButton = Alfresco.util.createYUIButton(this, "btn-sendMailToAllMembers", this.showSendMailForm);
this.widgets.sendMailToAllMembersButton.set("className", "mailBtn mailToAllMembersBtn");
Bubbling.on('selectDeselectAllChanged', this.selectDeselectAllChanged);
Bubbling.on('selectDeselectMemberChanged', this.selectDeselectMemberChanged);
},
showSendMailForm: function()
{
// Intercept before dialog show
var doBeforeDialogShow = function TsSendMailToAllMembers_doBeforeDialogShow(
p_form, p_dialog) {
Alfresco.util.populateHTML(
[p_dialog.id + "-dialogTitle", this.msg("label.sendMailToAllMembersForm.title") ],
[p_dialog.id + "-dialogHeader", this.msg("label.sendMailToAllMembersForm.header") ],
[p_dialog.id + "-members-label", this.msg("label.sendMailToAllMembersForm.members") ],
[p_dialog.id + "-subject-label", this.msg("label.sendMailToAllMembersForm.subject") ],
[p_dialog.id + "-body-label", this.msg("label.sendMailToAllMembersForm.body") ],
[p_dialog.id + "-ok-label", this.msg("label.sendMailToAllMembersForm.btn.send.mail") ],
[p_dialog.id + "-cancel-label", this.msg("label.sendMailToAllMembersForm.btn.cancel") ]);
p_dialog.dialog.header.innerHTML = this.msg("label.sendMailToAllMembersForm.dialog.title");
Dom.get(p_dialog.id + "-shortName").value = this.options.siteId;
tinyMCE.init({
mode : "exact",
elements: p_dialog.id + "-body",
convert_fonts_to_spans: false,
theme: 'advanced',
width: "100%",
theme_advanced_buttons1: "bold,italic,underline,|,bullist,numlist,|,forecolor,|,undo,redo,removeformat",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_statusbar_location: "bottom",
theme_advanced_resizing: false,
theme_advanced_buttons2: null,
theme_advanced_buttons3: null,
theme_advanced_path: false,
language: 'fr'
});
Alfresco.util.Ajax.request(
{
url: Alfresco.constants.PROXY_URI + "api/sites/" + this.options.siteId + "/memberships",
dataObj:
{
htmlid : p_dialog.id + "-membersContainer"
},
successCallback:
{
fn: this.onMembersLoaded,
scope: this
}
});
};
var doBeforeFormSubmit = function ()
{
Dom.get(this.id + "-sendMailToAllMembersDialog-mailbody").value = tinyMCE.get(this.id + "-sendMailToAllMembersDialog-body").getContent({format : 'raw'});
var membersIds = "";
var cbs = YAHOO.util.Selector.query("input[id^='cb_']");
for (var i=0; i<cbs.length; i++)
{
var cb = cbs[i];
if (cb.checked)
{
var id = cb.id.replace("cb_", "");
if(cbs.length == 1 || i == cbs.length - 1) {
membersIds += id;
} else {
membersIds += id + ",";
}
}
}
Dom.get(this.id + "-sendMailToAllMembersDialog-membersIds").value = membersIds;
this.widgets.dialog.widgets.okButton.set("disabled", true);
this.widgets.dialog.widgets.cancelButton.set("disabled", true);
};
// Using Forms Service, so always create new
// instance
var sendMailToAllMembersDialog = new Alfresco.module.SimpleDialog(this.id + "-sendMailToAllMembersDialog");
this.widgets.dialog = sendMailToAllMembersDialog;
sendMailToAllMembersDialog.setOptions(
{
width : "60em",
templateUrl : Alfresco.constants.PROXY_URI + "ts/sendMailToAllMembers",
actionUrl : Alfresco.constants.PROXY_URI + "ts/sendHtmlMail",
destroyOnHide : true,
doBeforeFormSubmit:{
fn:doBeforeFormSubmit,
scope: this
},
doBeforeDialogShow : {
fn : doBeforeDialogShow,
scope : this
},
onSuccess : {
fn : function TsSendMailToAllMembers_success(response) {
YAHOO.Bubbling.fire(
"sendMailToAllMembersForm_success",
{
nodeRef : response.json.persistedObject
});
Alfresco.util.PopupManager.displayMessage({
text : this.msg("message.sendMailToAllMembersForm.success")
});
},
scope : this
},
onFailure : {
fn : function TsSendMailToAllMembers_failure(response) {
Alfresco.util.PopupManager.displayMessage({
text : this.msg("message.sendMailToAllMembersForm.failure")
});
},
scope : this
}
}).show();
},
onMembersLoaded: function TS_onMembersLoaded(response)
{
this.members = response.json;
this.updateMembersList(response.config.dataObj.htmlid);
},
updateMembersList : function TS_updateMembersList(containerId)
{
var div = Dom.get(containerId);
div.innerHTML = "<div class=\"memberDiv\">" +
"<input type=\"checkbox\" id=\"selectDeselectAllCb\" checked=\"true\" onclick=\"YAHOO.Bubbling.fire('selectDeselectAllChanged')\" class=\"memberCb\"/>" +
"<label for=\"selectDeselectAllCb\" class=\"memberLabel\">" +
this.msg('label.selectDeselectAll') + "</label>" +
"</div>";
for (var i=0; i<this.members.length; i++)
{
var member = this.members[i];
var avatar = Alfresco.constants.URL_CONTEXT + "/components/images/no-user-photo-64.png";
if (member.authority.avatar && member.avatar != "")
{
// exemple:
// api/node/workspace/SpacesStore/697ec77c-b881-4c16-82b6-4f80fea1514b/content/thumbnails/avatar
avatar = Alfresco.constants.PROXY_URI + member.authority.avatar + "?c=force";
}
div.innerHTML += "<div class=\"memberDiv\">" +
// "<img class=\"memberAvatar\" src=\"" + avatar + "\"/>" +
"<input type=\"checkbox\" id=\"cb_" + member.authority.userName + "\" checked=\"true\" onclick=\"YAHOO.Bubbling.fire('selectDeselectMemberChanged')\" class=\"memberCb\"/>" +
"<label for=\"cb_" + member.authority.userName + "\" class=\"memberLabel\">" +
member.authority.firstName + " " + member.authority.lastName + "</label>" +
"</div>";
}
},
selectDeselectAllChanged: function selectDeselectAllChanged(){
var selectDeselectAllCb = Dom.get('selectDeselectAllCb');
var checked = selectDeselectAllCb.checked;
var cbs = YAHOO.util.Selector.query("input[id^='cb_']");
for (var i=0, j=cbs.length; i<j; i++)
{
var cb = cbs[i];
cb.checked = checked;
}
},
selectDeselectMemberChanged: function selectDeselectMemberChanged(){
var selectDeselectAllCb = Dom.get('selectDeselectAllCb');
var cbs = YAHOO.util.Selector.query("input[id^='cb_']");
var firstChecked = false;
if (cbs[0] != null){
firstChecked = cbs[0].checked;
}
for (var i=0, j=cbs.length; i<j; i++)
{
var cb = cbs[i];
if (cb.checked === firstChecked){
continue;
}
else{
selectDeselectAllCb.checked = false;
return;
}
}
selectDeselectAllCb.checked = firstChecked;
},
/**
* Set messages for this component.
*
* #method setMessages
* #param obj {object} Object literal specifying a set of messages
* #return {Alfresco.SampleComponent} returns 'this' for method chaining
*/
setMessages: function SampleComponent_setMessages(obj)
{
Alfresco.util.addMessages(obj, this.name);
return this;
}
});
})();
Alfresco.module.geTsSendMailToAllMembersInstance = function()
{
var instanceId = "alfresco-TsSendMailToAllMembers-instance";
return Alfresco.util.ComponentManager.get(instanceId) || new Alfresco.module.TsSendMailToAllMembers(instanceId);
};
Here is the "site-profile.get.head.ftl" source code :
<#include "../component.head.inc">
<#link rel="stylesheet" type="text/css" href="${page.url.context}/res/modules/ts/ts.css" />
<#script type="text/javascript" src="${page.url.context}/res/modules/ts-abonnement-site.js"></#script>
<#script type="text/javascript" src="${page.url.context}/res/modules/ts-send-mail-to-all-members.js"></#script>
Here is the "site-profile.get.html.ftl" source code :
<script type="text/javascript">//<![CDATA[
new Alfresco.module.TsAbonnementSite("${args.htmlid}").setOptions(
{
siteId: "${profile.shortName}"
}).setMessages(${messages});
new Alfresco.module.TsSendMailToAllMembers("${args.htmlid}").setOptions(
{
siteId: "${profile.shortName}"
}).setMessages(${messages});
//]]></script>
<div id="${args.htmlid}-sendMailToAllMembersDialog"></div>
<div class="dashlet site-profile">
<div class="title">${msg("header.siteProfile")}</div>
<div class="body">
<div class="msg">
<#if profile.iconurl?exists && profile.iconurl != "">
<img src="/share/proxy/alfresco/api/node/${profile.iconurl}/content/thumbnails/avatar?c=force" height="60px" style="float:left;margin: 5px;"/>
</#if>
<h3><#if (profile.title != "")>${msg("text.welcome", profile.title)?html}<#else>${msg("text.welcome", profile.shortName)?html}</#if></h3>
<#if (profile.description != "")>
<p>${profile.description?html}</p>
</#if>
<#if profile.customProperties??>
<#list profile.customProperties?keys as prop>
<#assign customValue=profile.customProperties[prop].value>
<#if customValue?starts_with('alfresco-php://') == true>
<p>${profile.customProperties[prop].title?html}</p>
<#else>
<p>
<span class="label">${profile.customProperties[prop].title?html}</span>
<span>${customValue?html}</span>
</p>
</#if>
</#list>
</#if>
<#if (sitemanagers?exists && sitemanagers?size > 0)>
<p>
<span class="label">${msg("label.siteAdmin")}</span>
<#list sitemanagers as sitemanager>
<#if sitemanager.authority.authorityType = 'USER'>
${sitemanager.authority.firstName?html}<#if sitemanager.authority.lastName != ""> ${sitemanager.authority.lastName?html}</#if><#if sitemanager_has_next>,</#if>
<#else>
<span>${sitemanager.authority.displayName?html}</span><#if sitemanager_has_next>,</#if>
</#if>
</#list>
</p>
</#if>
<p><span class="label">${msg("label.type")}</span> ${msg("text." + profile.type?lower_case)}</p>
<p><span class="label">${msg("label.visibility")}</span> ${msg("text." + (profile.visibility!"unknown")?lower_case)}</p>
<p><span class="label">${msg("ts-site-profile.siteMembersNbr")}</span> ${profile.siteMembersNbr?html}</p>
<p><span class="label">${msg("ts-site-profile.creationDate")}</span> ${profile.creationDate}</p>
<p>
<button id="${args.htmlid}-btn-sendMailToAllMembers" title='${msg("ts-site-profile.sendMailToAllMembers")}'>
<img class="mailBtn" src="${url.context}/res/modules/ts/images/email-icon.png"/></button>
<div id="${args.htmlid}-div-btn-abo" style="display:none;">
<button id="${args.htmlid}-btn-subscribeDaily" title='${msg("ts-site-profile.subscribeDaily")}'>
<img class="mailBtn" src="${url.context}/res/modules/ts/images/calendar-selection-day-icon.png"/></button>
<button id="${args.htmlid}-btn-subscribeWeekly" title='${msg("ts-site-profile.subscribeWeekly")}'>
<img class="mailBtn" src="${url.context}/res/modules/ts/images/calendar-selection-week-icon.png"/></button>
</div>
<div id="${args.htmlid}-div-btn-delete" style="display:none;">
<button id="${args.htmlid}-btn-delete">
<img class="mailBtn" src="" id="${args.htmlid}-img-btn-delete"/></button>
</div>
</p>
</div>
<div class="clear"></div>
</div>
</div>
So, if you have any specific idea...
Thanks.
I've found the solution.
All I've had to do is add those lines in "site-profile.get.head.ftl" :
<#include "../component.head.inc">
<script type="text/javascript" src="${page.url.context}/res/modules/editors/tiny_mce/tiny_mce.js"></script>
<#script type="text/javascript" src="${page.url.context}/res/modules/editors/tiny_mce.js"></#script>
<#script type="text/javascript" src="${page.url.context}/res/components/form/rich-text.js"></#script>
<#link rel="stylesheet" type="text/css" href="${page.url.context}/res/modules/ts/ts.css" />
<#script type="text/javascript" src="${page.url.context}/res/modules/ts-abonnement-site.js"></#script>
<#script type="text/javascript" src="${page.url.context}/res/modules/ts-send-mail-to-all-members.js"></#script>
<!-- Simple Dialog -->
<#script type="text/javascript" src="${page.url.context}/res/modules/simple-dialog.js"></#script>
Some of those lines were in the "List events" dashlet "head.ftl" file.
Now, the dashlet doesn't need to be included to work and there is no conflict.
First of all you don't really need to incluse tinyMCE again, because it's mostly already done.
take a look at the template file alfresco-template.ftl here you'll see the following;
<#macro templateHtmlEditorAssets>
<!-- HTML Editor Assets -->
<script type="text/javascript" src="${page.url.context}/res/modules/editors/tiny_mce/tiny_mce${DEBUG?string("_src", "")}.js"></script>
<#script type="text/javascript" src="${page.url.context}/res/modules/editors/tiny_mce.js"></#script>
<#script type="text/javascript" src="${page.url.context}/res/modules/editors/yui_editor.js"></#script>
</#macro>
So this could be a clash that it already sees it as an html field and imports tinyMCE double.
Can you check this?
If it's already loaded, then you only need to enable the field correctly.
Second, you need to have a head.html.ftl where you can include specific library files.
Take a look at sample dashlets how they're build.
I am trying to initialize an array with another array. The array contains options for loading an RSS feed reader. The user clicks an option button to selection which RSS category to read. Based on the selection I initalize the feed URL and options arrays like this.
feeds = feedsnews.slice(0, feedsnews.length);
options = optionsnews.slice(0, optionsnews.length);
(The entire javascript for this is at the end of the text).
Then I send these arrays to the code for loading the newsreader. This seems to initialize only the first element in the array.
What is the way to initialize the array with all the elements? Are the arrays declared in the right way for the RSS loader to get them?
Here is the code:
<script language="JavaScript">
var feedsnews = [ {title: 'Reuters Top News', url: 'http://feeds.reuters.com/reuters/topNews' }, {title: 'Reuters International',
url: 'http://feeds.reuters.com/reuters/worldNews' }, {title: 'Reuters US News', url: 'http://feeds.reuters.com/Reuters/domesticNews' }];
var optionsnews = {
stacked : true,
horizontal : false,
title : "News"
}
var feedscat = [ {title: 'Catholic News Agency', url: 'http://www.catholicnewsagency.com/rss/news.xml' }, {title: 'Zenit - English', url: 'http://feeds.feedburner.com/zenit/english' }, {title: 'Zenit - Français', url:
'http://feeds.feedburner.com/zenit/french' }];
var optionscat = {
stacked : true,
horizontal : false,
title : "Catholic"
}
</script>
<SCRIPT LANGUAGE="JavaScript">
var feeds=feedsnews.slice();
var options=optionsnews.slice();
function GetSelectedItem() {
feeds=feedsnews.slice(0, feedsnews.length);
options=optionsnews.slice(0, optionsnews.length);
chosen = "";
len = document.f1.r1.length;
for (i = 0; i <len; i++) {
if (document.f1.r1[i].checked) {
chosen = document.f1.r1[i].value
}
}
if (chosen == "") {
alert("No Location Chosen")
}
else if (chosen =="News") {
feeds = feedsnews.slice(0,feedsnews.length);
options = optionsnews.slice(0,optionsnews.length);
}
else if (chosen =="Catholic") {
feeds = feedscat.slice(0,feedscat.length);
options = optionscat.slice(optionscat.length);
}
else if (chosen =="Community") {
}
else if (chosen =="Personal") {
}
else if (chosen =="Professional") {
}
else {
alert(chosen);
}
$("#snews").load("loadnews.php");
}
</script>
HTML (for #snews div)
<div id="snews" style="position:absolute; top:30px; right: 30px; width: 430px; height: 380px; overflow-y: auto; overflow-x: hidden; background: white;">
<?php require("loadnews.php"); ?>
</div> <!-- End snews -->
PHP (loadnews.php)
<!-- ++Begin Dynamic Feed Wizard Generated Code++ -->
<!--
// Created with a Google AJAX Search and Feed Wizard
// http://code.google.com/apis/ajaxsearch/wizards.html
-->
<!--
// The Following div element will end up holding the actual feed control.
// You can place this anywhere on your page.
-->
<div id="feed-control">
<span style="color:#676767;font-size:11px;margin:10px;padding:4px;">Loading...</span>
</div>
<script type="text/javascript">
function LoadDynamicFeedControl() {
new GFdynamicFeedControl(feeds, 'feed-control', options);
}
// Load the feeds API and set the onload callback.
google.load('feeds', '1');
google.setOnLoadCallback(LoadDynamicFeedControl);
</script>
<!-- ++End Dynamic Feed Control Wizard Generated Code++ -->
var optionsnews = {
stacked : true,
horizontal : false,
title : "News"
}
// snip...
options=optionsnews.slice(0, optionsnews.length);
optionsnews is an Object, not an Array. There is no Object.slice method since objects have neither numerical indexing nor inherent ordering.
What is the point of all this .slice()ing? What are you trying to accomplish?