@ -157,7 +157,7 @@ define([
h ( 'span' , Messages . form _textType ) ,
typeSelect [ 0 ]
] ) ;
typeSelect . onChange . reg ( evOnSave . fire () );
typeSelect . onChange . reg ( evOnSave . fire );
}
setCursorGetter ( function ( ) {
@ -1020,7 +1020,7 @@ define([
var itemScale = ( itemCount / max ) ;
rows . push ( h ( 'div.cp-form-results-type-radio-data' , [
h ( 'span.cp-value' , value ) ,
h ( 'span.cp-value' , { 'title' : value } , value ) ,
h ( 'span.cp-count' , itemCount ) ,
showBar ? barGraphic ( itemScale ) : undefined ,
] ) ) ;
@ -2175,10 +2175,18 @@ define([
}
} ;
var addResultsButton = function ( framework , content ) {
var $res = $ ( h ( 'button.cp-toolbar-appmenu.cp-toolbar-form-button' , [
var getAnswersLength = function ( answers ) {
return Object . keys ( answers || { } ) . filter ( function ( key ) {
return key && key . slice ( 0 , 1 ) !== "_" ;
} ) . length ;
} ;
Messages . form _results = "Responses ({0})" ; // XXX update key
var addResultsButton = function ( framework , content , answers ) {
var $container = $ ( '.cp-forms-results-participant' ) ;
var l = getAnswersLength ( answers ) ;
var $res = $ ( h ( 'button.btn.btn-default.cp-toolbar-form-button' , [
h ( 'i.fa.fa-bar-chart' ) ,
h ( 'span.cp-button-name' , Messages . form _results )
h ( 'span.cp-button-name' , Messages . _getKey( ' form_results', [ l ] ) ) ,
] ) ) ;
$res . click ( function ( ) {
$res . attr ( 'disabled' , 'disabled' ) ;
@ -2190,30 +2198,49 @@ define([
$ ( 'body' ) . addClass ( 'cp-app-form-results' ) ;
renderResults ( content , answers ) ;
$res . remove ( ) ;
var $editor = $ ( h ( 'button. cp-toolbar-appmenu ', [
var $editor = $ ( h ( 'button. btn.btn-default ', [
h ( 'i.fa.fa-pencil' ) ,
h ( 'span.cp-button-name' , APP. isEditor ? Messages. form _editor : Messages . form _form )
h ( 'span.cp-button-name' , Messages. form _editor )
] ) ) ;
$editor . click ( function ( ) {
$ ( 'body' ) . removeClass ( 'cp-app-form-results' ) ;
$editor . remove ( ) ;
addResultsButton ( framework , content ) ;
sframeChan . query ( "Q_FORM_FETCH_ANSWERS" , content . answers , function ( err , obj ) {
var answers = obj && obj . results ;
addResultsButton ( framework , content , answers ) ;
} ) ;
} ) ;
framework . _ . toolbar . $bottomL . append ( $editor ) ;
$container. pre pend( $editor ) ;
} ) ;
} ) ;
framework . _ . toolbar . $bottomL . append ( $res ) ;
$container . prepend ( $res ) ;
} ;
var getLogo = function ( ) {
var logo = h ( 'div.cp-form-view-logo' , [
h ( 'img' , {
src : '/customize/CryptPad_logo_grey.svg?' + ApiConfig . requireConf . urlArgs ,
alt : 'CryptPad_logo'
} ) ,
h ( 'span' , 'CryptPad' )
] ) ;
$ ( logo ) . click ( function ( ) {
APP . framework . _ . sfCommon . gotoURL ( '/' ) ;
} ) ;
return logo ;
} ;
Messages . form _alreadyAnswered = "You've responded to this form on {0}" ; // XXX
Messages . form _editAnswer = "Edit my responses" ; // XXX
Messages . form _viewAnswer = "View my responses" ; // XXX
var showAnsweredPage = function ( framework , content , answers ) {
if ( APP . submitPage ) { return ; }
APP . submitPage = true ;
var $formContainer = $ ( 'div.cp-form-creator-content' ) . hide ( ) ;
var $container = $ ( 'div.cp-form-creator-answered' ) . empty ( ) . css ( 'display' , '' ) ;
var viewOnly = content . answers . cantEdit ;
var viewOnly = content . answers . cantEdit || APP . isClosed ;
var action = h ( 'button.btn.btn-primary' , [
viewOnly ? h ( 'i.fa.fa-bar-chart' ) : h ( 'i.fa.fa-pencil' ) ,
h ( 'span' , viewOnly ? Messages . form _viewAnswer : Messages . form _editAnswer )
@ -2238,9 +2265,18 @@ define([
// If responses are public, show button to view them
var responses ;
if ( content . answers . privateKey ) {
responses = h ( 'button.btn.btn-default' , Messages . form _results ) ;
var l = getAnswersLength ( answers ) ;
responses = h ( 'button.btn.btn-default' , [
h ( 'i.fa.fa-bar-chart' ) ,
h ( 'span.cp-button-name' , Messages . _getKey ( 'form_results' , [ l ] ) )
] ) ;
var sframeChan = framework . _ . sfCommon . getSframeChannel ( ) ;
sframeChan . query ( "Q_FORM_FETCH_ANSWERS" , content . answers , function ( err , obj ) {
var answers = obj && obj . results ;
var l = getAnswersLength ( answers ) ;
$ ( responses ) . find ( '.cp-button-name' ) . text ( Messages . _getKey ( 'form_results' , [ l ] ) ) ;
} ) ;
$ ( responses ) . click ( function ( ) {
var sframeChan = framework . _ . sfCommon . getSframeChannel ( ) ;
sframeChan . query ( "Q_FORM_FETCH_ANSWERS" , content . answers , function ( err , obj ) {
var answers = obj && obj . results ;
if ( answers ) { APP . answers = answers ; }
@ -2265,11 +2301,12 @@ define([
var title = framework . _ . title . title || framework . _ . title . defaultTitle ;
$container . append ( h ( 'div.cp-form-submit-success' , [
h ( 'h3.cp-form-view-title' , title ) ,
description ,
h ( 'div.alert.alert-info' , Messages . _getKey ( 'form_alreadyAnswered' , [
new Date ( APP . lastAnswerTime ) . toLocaleString ( ) ] ) ) ,
description ,
actions
] ) ) ;
$container . append ( getLogo ( ) ) ;
} ;
var getFormResults = function ( ) {
@ -2309,6 +2346,7 @@ define([
} else if ( content . answers . anonymous ) {
// Answers aren't anonymous and guests are allowed
// Guests can set a username and logged in users can answer anonymously
var $anon ;
if ( ! loggedIn ) {
anonName = h ( 'div.cp-form-anon-answer-input' , [
Messages . form _answerAs ,
@ -2318,15 +2356,24 @@ define([
} )
] ) ;
$anonName = $ ( anonName ) . hide ( ) ;
$anonBox . on ( 'change' , function ( ) {
if ( Util . isChecked ( $anonBox ) ) { $anonName . hide ( ) ; }
else { $anonName . show ( ) ; }
} ) ;
} else if ( APP . cantAnon ) {
// You've already answered with your credentials
$cbox . hide ( ) ;
$anonBox . attr ( 'disabled' , 'disabled' ) . prop ( 'checked' , false ) ;
}
if ( ! anonName ) {
anonName = h ( 'div.cp-form-anon-answer-input' , [
Messages . form _answerAs ,
h ( 'span.cp-form-anon-answer-registered' , user . name || Messages . anonymous )
] ) ;
}
if ( ! APP . cantAnon ) {
var $anon = $ ( anonName ) . hide ( ) ;
$anonBox . on ( 'change' , function ( ) {
if ( Util . isChecked ( $anonBox ) ) { $anon . hide ( ) ; }
else { $anon . show ( ) ; }
} ) ;
}
} else {
// Answers don't have to be anonymous and only logged in users can answer
// ==> they have to answer with their keys so we know their name too
@ -2337,6 +2384,10 @@ define([
$cbox . after ( h ( 'div.alert.alert-info' , Messages . form _authAnswer ) ) ;
} ) ;
}
if ( update && content . answers . cantEdit || APP . isClosed ) {
$cbox . hide ( ) ;
anonName = undefined ;
}
var send = h ( 'button.cp-open.btn.btn-primary' , update ? Messages . form _update : Messages . form _submit ) ;
var reset = h ( 'button.cp-open.cp-reset-button.btn.btn-danger-alt' , Messages . form _reset ) ;
@ -2383,15 +2434,16 @@ define([
}
evOnChange . fire ( false , true ) ;
window . onbeforeunload = undefined ;
if ( ! update && content . answers . privateKey ) {
// Add results button
addResultsButton ( framework , content ) ;
}
$send . removeAttr ( 'disabled' ) ;
//UI.alert(Messages.form_sent); // XXX not needed anymore?
$send . text ( Messages . form _update ) ;
APP . hasAnswered = true ;
showAnsweredPage ( framework , content , { '_time' : + new Date ( ) } ) ;
if ( content . answers . cantEdit ) {
$cbox . hide ( ) ;
if ( $anonName ) { $anonName . hide ( ) ; }
}
} ) ;
} ) ;
@ -2475,8 +2527,10 @@ define([
} ) ;
var list = h ( 'ul' , lis ) ;
var divContent = [
h ( 'span' , Messages . form _requiredWarning ) ,
list
h ( 'div.alert.alert-danger' , [
Messages . form _requiredWarning ,
list
] )
] ;
$errors . empty ( ) . append ( divContent ) ;
} ) ;
@ -2505,7 +2559,7 @@ define([
var color = content . answers . color || 'nocolor' ;
$container . addClass ( 'cp-form-palette-' + color ) ;
if ( APP . isClosed && content . answers . privateKey && ! APP . isEditor ) {
if ( APP . isClosed && content . answers . privateKey && ! APP . isEditor && ! APP . hasAnswered ) {
var sframeChan = framework . _ . sfCommon . getSframeChannel ( ) ;
sframeChan . query ( "Q_FORM_FETCH_ANSWERS" , content . answers , function ( err , obj ) {
var answers = obj && obj . results ;
@ -2967,6 +3021,7 @@ define([
updateAddInline ( ) ;
if ( editable ) {
if ( APP . mainSortable ) { APP . mainSortable . destroy ( ) ; }
APP . mainSortable = Sortable . create ( $container [ 0 ] , {
direction : "vertical" ,
filter : "input, button, .CodeMirror, .cp-form-type-sort, .cp-form-block-type.editable" ,
@ -2996,6 +3051,13 @@ define([
new Date ( answers . _time || APP . lastAnswerTime ) . toLocaleString ( ) ] ) ) ) ;
}
if ( APP . isClosed ) {
APP . formBlocks . forEach ( function ( b ) {
if ( ! b . setEditable ) { return ; }
b . setEditable ( false ) ;
} ) ;
}
// In view mode, add "Submit" and "reset" buttons
$container . append ( makeFormControls ( framework , content , Boolean ( answers ) , evOnChange ) ) ;
@ -3024,17 +3086,7 @@ define([
// at the bottom
var title = framework . _ . title . title || framework . _ . title . defaultTitle ;
$container . prepend ( h ( 'h1.cp-form-view-title' , title ) ) ;
var logo = h ( 'div.cp-form-view-logo' , [
h ( 'img' , {
src : '/customize/CryptPad_logo_grey.svg?' + ApiConfig . requireConf . urlArgs ,
alt : 'CryptPad_logo'
} ) ,
h ( 'span' , 'CryptPad' )
] ) ;
$ ( logo ) . click ( function ( ) {
framework . _ . sfCommon . gotoURL ( '/drive/' ) ;
} ) ;
$container . append ( logo ) ;
$container . append ( getLogo ( ) ) ;
if ( ! answers ) {
$container . find ( '.cp-reset-button' ) . attr ( 'disabled' , 'disabled' ) ;
@ -3070,10 +3122,11 @@ define([
var $toolbarContainer = $ ( '#cp-toolbar' ) ;
if ( APP . isEditor || priv . form _auditorKey ) {
var helpMenu = framework . _ . sfCommon . createHelpMenu ( [ 'text' , 'pad' ] ) ;
$toolbarContainer . after ( helpMenu . menu ) ;
framework . _ . toolbar . $drawer . append ( helpMenu . button ) ;
var helpMenu = framework . _ . sfCommon . createHelpMenu ( [ 'text' , 'pad' ] ) ;
$toolbarContainer . after ( helpMenu . menu ) ;
framework . _ . toolbar . $drawer . append ( helpMenu . button ) ;
if ( ! APP . isEditor && ! priv . form _auditorKey ) {
$ ( helpMenu . menu ) . hide ( ) ;
}
var offlineEl = h ( 'div.alert.alert-danger.cp-burn-after-reading' , Messages . disconnected ) ;
@ -3123,7 +3176,7 @@ define([
} ) ;
} ) ;
Messages . form _makePublicWarning = "Are you sure you want to make responses to this form public? Past and future responses will be visible by participants. This cannot be undone." // XXX existing key
Messages . form _makePublicWarning = "Are you sure you want to make responses to this form public? Past and future responses will be visible by participants. This cannot be undone." ; // XXX existing key
// Private / public status
var resultsType = h ( 'div.cp-form-results-type-container' ) ;
var $results = $ ( resultsType ) ;
@ -3351,6 +3404,9 @@ define([
} ) ;
var save = h ( 'button.btn.btn-primary' , Messages . settings _save ) ;
$ ( save ) . click ( function ( ) {
if ( dataPicker . value === '' ) {
return void refreshEndDate ( ) ;
}
var d = picker . parseDate ( datePicker . value ) ;
content . answers . endDate = + d ;
framework . localChange ( ) ;
@ -3358,9 +3414,13 @@ define([
refreshEndDate ( ) ;
} ) ;
} ) ;
var cancel = h ( 'button.btn.btn-danger' , h ( 'i.fa.fa-times' ) ) ;
$ ( cancel ) . click ( function ( ) {
refreshEndDate ( ) ;
} ) ;
var confirmContent = h ( 'div' , [
h ( 'div' , Messages . form _setEnd ) ,
h ( 'div.cp-form-input-block' , [ datePicker , save ] ) ,
h ( 'div.cp-form-input-block' , [ datePicker , save , cancel ]) ,
] ) ;
$button . after ( confirmContent ) ;
$button . remove ( ) ;
@ -3593,7 +3653,6 @@ define([
}
if ( APP . isEditor ) {
addResultsButton ( framework , content ) ;
sframeChan . query ( "Q_FORM_FETCH_ANSWERS" , {
channel : content . answers . channel ,
validateKey : content . answers . validateKey ,
@ -3601,6 +3660,7 @@ define([
cantEdit : content . answers . cantEdit
} , function ( err , obj ) {
var answers = obj && obj . results ;
addResultsButton ( framework , content , answers ) ;
if ( answers ) { APP . answers = answers ; }
checkIntegrity ( false ) ;
updateForm ( framework , content , true ) ;
@ -3654,9 +3714,6 @@ define([
// If we have a non-anon answer, we can't answer anonymously later
if ( answers [ curve1 ] ) { APP . cantAnon = true ; }
// Add results button
if ( myAnswers ) { addResultsButton ( framework , content ) ; }
updateForm ( framework , content , false , myAnswers ) ;
} ) ;
return ;
@ -3684,9 +3741,6 @@ define([
APP . hasAnswered = true ;
// If we have a non-anon answer, we can't answer anonymously later
if ( ! obj . _isAnon ) { APP . cantAnon = true ; }
// Add results button
if ( content . answers . privateKey ) { addResultsButton ( framework , content ) ; }
}
checkIntegrity ( false ) ;
updateForm ( framework , content , false , answers ) ;