Dev for rich edit in studyplan description

This commit is contained in:
PMKuipers 2023-10-18 08:46:44 +02:00
parent 147f218916
commit bcc3cb5a2c
10 changed files with 170 additions and 5 deletions

3
amd/build/util/mform-helper.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
define("local_treestudyplan/util/mform-helper",["exports","core/ajax","core/fragment","core/notification","./string-helper","./debugger"],(function(_exports,_ajax,_fragment,_notification,_stringHelper,_debugger){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_notification=_interopRequireDefault(_notification),_debugger=_interopRequireDefault(_debugger);var _default={install:function(Vue){var debug=new _debugger.default("treestudyplan-mform-helper"),strings=(0,_stringHelper.load_strings)({editmod:{save$core:"save$core",cancel$core:"cancel$core"}});Vue.component("mform",{props:{name:{type:String},params:{type:Object}},data:function(){return{content:"",loading:!0,uuid:void 0!==crypto.randomUUID?crypto.randomUUID():"10000000-1000-4000-8000-100000000000".replace(/[018]/g,(function(c){return(c^crypto.getRandomValues(new Uint8Array(1))[0]&15>>c/4).toString(16)})),text:strings}},computed:{},methods:{openForm:function(){this.$refs.editormodal.show()},onShown:function(){var self=this;debug.info('Loading form "'.concat(self.name,'" with params'),self.params),self.loading=!1,(0,_ajax.call)([{methodname:"local_treestudyplan_get_mform",args:{name:self.name,params:self.params}}])[0].then((function(data){self.content=data.html,self.loading=!1,(0,_fragment.processCollectedJavascript)(data.js)})).catch(_notification.default.exception)},onSave:function(){var self=this,form=this.$refs.content.getElementsByTagName("form")[0];form.dispatchEvent(new Event("save-form-state"));var formdata=new FormData(form),data=new URLSearchParams(formdata).toString();(0,_ajax.call)([{methodname:"local_treestudyplan_submit_mform",args:{name:self.name,params:self.params,data:data}}])[0].then((function(){self.$emit("saved",formdata)})).catch(_notification.default.exception)}},template:'\n <span class=\'s-edit-mod\'><a href=\'#\' @click.prevent="open"><slot><i class="fa fa-cog"></i></slot></a>\n <b-modal\n ref="editormodal"\n scrollable\n centered\n size="xl"\n id="\'modal-\'+uuid"\n @shown="onShown"\n @ok="onSave"\n :title="title"\n :ok-title="text.save$core"\n ><div :class="\'s-edit-mod-form \'+ (genericonly?\'genericonly\':\'\')" ref="content"\n ><div v-if="loading" class="d-flex justify-content-center mb-3"\n ><b-spinner variant="primary"></b-spinner\n ></div\n ><span v-else v-html="content"\n ></div\n ></b-modal>\n </span>\n '})}};return _exports.default=_default,_exports.default}));
//# sourceMappingURL=mform-helper.min.js.map

File diff suppressed because one or more lines are too long

3
amd/build/util/modedit-modal.min.js vendored Normal file
View File

@ -0,0 +1,3 @@
define("local_treestudyplan/util/modedit-modal",["exports","core/fragment","./util/string-helper","core/ajax","core/notification","core/templates"],(function(_exports,_fragment,_stringHelper,_ajax,_notification,_templates){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_notification=(obj=_notification)&&obj.__esModule?obj:{default:obj};var _default={install:function(Vue){var strings=(0,_stringHelper.load_strings)({editmod:{save$core:"save$core",cancel$core:"cancel$core"}});Vue.component("s-edit-mod",{props:{cmid:{type:Number},coursectxid:{type:Number},title:{type:String,default:""},genericonly:{type:Boolean,default:!1}},data:function(){return{content:"",text:strings.editmod}},computed:{},methods:{openForm:function(){this.$refs.editormodal.show()},onShown:function(){var self=this,params={cmid:this.cmid};console.info("Loading form"),(0,_fragment.loadFragment)("local_treestudyplan","mod_edit_form",this.coursectxid,params).then((function(html,js){(0,_templates.replaceNodeContents)(self.$refs.content,html,js)})).catch(_notification.default.exception)},onSave:function(){var self=this,form=this.$refs.content.getElementsByTagName("form")[0];form.dispatchEvent(new Event("save-form-state"));var formdata=new FormData(form),data=new URLSearchParams(formdata).toString();(0,_ajax.call)([{methodname:"local_treestudyplan_submit_cm_editform",args:{cmid:this.cmid,formdata:data}}])[0].done((function(){self.$emit("saved",formdata)})).fail(_notification.default.exception)}},template:'\n <span class=\'s-edit-mod\'><a href=\'#\' @click.prevent="openForm"><slot><i class="fa fa-cog"></i></slot></a>\n <b-modal\n ref="editormodal"\n scrollable\n centered\n size="xl"\n id="\'modal-cm-\'+cmid"\n @shown="onShown"\n @ok="onSave"\n :title="title"\n :ok-title="text.save$core"\n ><div :class="\'s-edit-mod-form \'+ (genericonly?\'genericonly\':\'\')" ref="content"\n ><div class="d-flex justify-content-center mb-3"><b-spinner variant="primary"></b-spinner></div\n ></div\n ></b-modal>\n </span>\n '})}};return _exports.default=_default,_exports.default}));
//# sourceMappingURL=modedit-modal.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
define("local_treestudyplan/util/string-helper",["exports","core/str"],(function(_exports,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.load_stringkeys=function(string_keys){var _loop2=function(idx){var stringkeys=[];for(var i in string_keys[idx]){var parts=string_keys[idx][i].textkey.split("$"),identifier=parts[0],component=parts.length>1?parts[1]:"local_treestudyplan";stringkeys.push({key:identifier,component:component})}(0,_str.get_strings)(stringkeys).then((function(strings){for(var _i in strings){var s=strings[_i];string_keys[idx][_i].text=s}}))};for(var idx in string_keys)_loop2(idx);return string_keys},_exports.load_strings=function(strings){var _loop=function(idx){var stringkeys=[];for(var handle in strings[idx]){var parts=strings[idx][handle].split(/[$@]/),identifier=parts[0],component=parts.length>1?parts[1]:"local_treestudyplan";stringkeys.push({key:identifier,component:component})}(0,_str.get_strings)(stringkeys).then((function(str){var i=0;for(var _key in strings[idx])strings[idx][_key]=str[i],i++}))};for(var idx in strings)_loop(idx);return strings},_exports.strformat=function(str,values){return str.replace(/\{(\w+)\}/g,(function(m,m1){return m1&&values.hasOwnProperty(m1)?values[m1]:m}))}}));
define("local_treestudyplan/util/string-helper",["exports","core/str"],(function(_exports,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.load_stringkeys=function(string_keys){var _loop2=function(idx){var stringkeys=[];for(var i in string_keys[idx]){var parts=string_keys[idx][i].textkey.split("$"),identifier=parts[0],component=parts.length>1?parts[1]:"local_treestudyplan";stringkeys.push({key:identifier,component:component})}getstr_func(stringkeys).then((function(strings){for(var _i in strings){var s=strings[_i];string_keys[idx][_i].text=s}}))};for(var idx in string_keys)_loop2(idx);return string_keys},_exports.load_strings=function(strings){var _loop=function(idx){var stringkeys=[];for(var handle in strings[idx]){var parts=strings[idx][handle].split(/[$@]/),identifier=parts[0],component=parts.length>1?parts[1]:"local_treestudyplan";stringkeys.push({key:identifier,component:component})}getstr_func(stringkeys).then((function(str){var i=0;for(var _key in strings[idx])strings[idx][_key]=str[i],i++}))};for(var idx in strings)_loop(idx);return strings},_exports.strformat=function(str,values){return str.replace(/\{(\w+)\}/g,(function(m,m1){return m1&&values.hasOwnProperty(m1)?values[m1]:m}))};var getstr_func=void 0!==_str.getStrings?_str.getStrings:_str.get_strings}));
//# sourceMappingURL=string-helper.min.js.map

View File

@ -1 +1 @@
{"version":3,"file":"string-helper.min.js","sources":["../../src/util/string-helper.js"],"sourcesContent":["import {get_strings} from 'core/str';\n\n/**\n * Load the translation of strings from a strings object\n * @param {Object} strings The map of strings\n * @returns {Object} The map with strings loaded in\n */\nexport function load_strings(strings){\n for(let idx in strings){\n let stringkeys = [];\n for(const handle in strings[idx]){\n const key = strings[idx][handle];\n let parts = key.split(/[$@]/);\n let identifier = parts[0];\n let component = (parts.length > 1)?parts[1]:'local_treestudyplan';\n stringkeys.push({ key: identifier, component: component});\n }\n get_strings(stringkeys).then(function(str){\n let i = 0;\n for(const key in strings[idx]){\n strings[idx][key] = str[i];\n i++;\n }\n });\n }\n\n return strings;\n}\n\n/**\n * Load the translation of strings from a strings object based on keys\n * Used for loading values for a drop down menu or the like\n * @param {Object} string_keys The map of stringkeys\n * @returns {Object} The map with strings loaded in\n */\nexport function load_stringkeys(string_keys){\n for(let idx in string_keys){\n // Get text strings for condition settings\n let stringkeys = [];\n for(const i in string_keys[idx]){\n const key = string_keys[idx][i].textkey;\n let parts = key.split(\"$\");\n let identifier = parts[0];\n let component = (parts.length > 1)?parts[1]:'local_treestudyplan';\n stringkeys.push({ key: identifier, component: component});\n }\n get_strings(stringkeys).then(function(strings){\n for(const i in strings) {\n const s = strings[i];\n const l = string_keys[idx][i];\n l.text = s;\n }\n });\n }\n return string_keys;\n}\n\n/**\n * String formatting function - replaces {name} in string by value of same key in values parameter\n * @param {string} str String t\n * @param {object} values Object containing keys to replace {key} strings with\n * @returns Formatted string\n */\nexport function strformat(str,values) {\n return str.replace(/\\{(\\w+)\\}/g, (m, m1) => {\n if (m1 && values.hasOwnProperty(m1)) {\n return values[m1];\n } else {\n return m;\n }\n });\n}"],"names":["string_keys","idx","stringkeys","i","parts","textkey","split","identifier","component","length","push","key","then","strings","s","text","handle","str","values","replace","m","m1","hasOwnProperty"],"mappings":"0LAmCgCA,iCACpBC,SAEAC,WAAa,OACb,IAAMC,KAAMH,YAAYC,KAAK,KAEzBG,MADQJ,YAAYC,KAAKE,GAAGE,QAChBC,MAAM,KAClBC,WAAaH,MAAM,GACnBI,UAAaJ,MAAMK,OAAS,EAAGL,MAAM,GAAG,sBAC5CF,WAAWQ,KAAK,CAAEC,IAAKJ,WAAYC,UAAWA,iCAEtCN,YAAYU,MAAK,SAASC,aAC9B,IAAMV,MAAKU,QAAS,KACdC,EAAID,QAAQV,IACRH,YAAYC,KAAKE,IACzBY,KAAOD,WAdjB,IAAIb,OAAOD,mBAAPC,YAkBDD,4CA/CkBa,4BACjBZ,SACAC,WAAa,OACb,IAAMc,UAAWH,QAAQZ,KAAK,KAE1BG,MADQS,QAAQZ,KAAKe,QACTV,MAAM,QAClBC,WAAaH,MAAM,GACnBI,UAAaJ,MAAMK,OAAS,EAAGL,MAAM,GAAG,sBAC5CF,WAAWQ,KAAK,CAAEC,IAAKJ,WAAYC,UAAWA,iCAEtCN,YAAYU,MAAK,SAASK,SAC9Bd,EAAI,MACJ,IAAMQ,QAAOE,QAAQZ,KACrBY,QAAQZ,KAAKU,MAAOM,IAAId,GACxBA,YAbR,IAAIF,OAAOY,cAAPZ,YAkBDY,qCAqCeI,IAAIC,eACnBD,IAAIE,QAAQ,cAAc,SAACC,EAAGC,WAC7BA,IAAMH,OAAOI,eAAeD,IACrBH,OAAOG,IAEPD"}
{"version":3,"file":"string-helper.min.js","sources":["../../src/util/string-helper.js"],"sourcesContent":["import {get_strings} from 'core/str';\nimport {getStrings} from 'core/str';\n\n/* Determine the proper getstrings function to use (MDL4.3+ recommends use of getStrings, which is jquery independent) */\nconst getstr_func = (getStrings !== undefined)?getStrings:get_strings;\n\n/**\n * Load the translation of strings from a strings object\n * @param {Object} strings The map of strings\n * @returns {Object} The map with strings loaded in\n */\nexport function load_strings(strings){\n for(let idx in strings){\n let stringkeys = [];\n for(const handle in strings[idx]){\n const key = strings[idx][handle];\n let parts = key.split(/[$@]/);\n let identifier = parts[0];\n let component = (parts.length > 1)?parts[1]:'local_treestudyplan';\n stringkeys.push({ key: identifier, component: component});\n }\n getstr_func(stringkeys).then(function(str){\n let i = 0;\n for(const key in strings[idx]){\n strings[idx][key] = str[i];\n i++;\n }\n });\n }\n\n return strings;\n}\n\n/**\n * Load the translation of strings from a strings object based on keys\n * Used for loading values for a drop down menu or the like\n * @param {Object} string_keys The map of stringkeys\n * @returns {Object} The map with strings loaded in\n */\nexport function load_stringkeys(string_keys){\n for(let idx in string_keys){\n // Get text strings for condition settings\n let stringkeys = [];\n for(const i in string_keys[idx]){\n const key = string_keys[idx][i].textkey;\n let parts = key.split(\"$\");\n let identifier = parts[0];\n let component = (parts.length > 1)?parts[1]:'local_treestudyplan';\n stringkeys.push({ key: identifier, component: component});\n }\n getstr_func(stringkeys).then(function(strings){\n for(const i in strings) {\n const s = strings[i];\n const l = string_keys[idx][i];\n l.text = s;\n }\n });\n }\n return string_keys;\n}\n\n/**\n * String formatting function - replaces {name} in string by value of same key in values parameter\n * @param {string} str String t\n * @param {object} values Object containing keys to replace {key} strings with\n * @returns Formatted string\n */\nexport function strformat(str,values) {\n return str.replace(/\\{(\\w+)\\}/g, (m, m1) => {\n if (m1 && values.hasOwnProperty(m1)) {\n return values[m1];\n } else {\n return m;\n }\n });\n}"],"names":["string_keys","idx","stringkeys","i","parts","textkey","split","identifier","component","length","push","key","getstr_func","then","strings","s","text","handle","str","values","replace","m","m1","hasOwnProperty","undefined","getStrings","get_strings"],"mappings":"0LAuCgCA,iCACpBC,SAEAC,WAAa,OACb,IAAMC,KAAMH,YAAYC,KAAK,KAEzBG,MADQJ,YAAYC,KAAKE,GAAGE,QAChBC,MAAM,KAClBC,WAAaH,MAAM,GACnBI,UAAaJ,MAAMK,OAAS,EAAGL,MAAM,GAAG,sBAC5CF,WAAWQ,KAAK,CAAEC,IAAKJ,WAAYC,UAAWA,YAElDI,YAAYV,YAAYW,MAAK,SAASC,aAC9B,IAAMX,MAAKW,QAAS,KACdC,EAAID,QAAQX,IACRH,YAAYC,KAAKE,IACzBa,KAAOD,WAdjB,IAAId,OAAOD,mBAAPC,YAkBDD,4CA/CkBc,4BACjBb,SACAC,WAAa,OACb,IAAMe,UAAWH,QAAQb,KAAK,KAE1BG,MADQU,QAAQb,KAAKgB,QACTX,MAAM,QAClBC,WAAaH,MAAM,GACnBI,UAAaJ,MAAMK,OAAS,EAAGL,MAAM,GAAG,sBAC5CF,WAAWQ,KAAK,CAAEC,IAAKJ,WAAYC,UAAWA,YAElDI,YAAYV,YAAYW,MAAK,SAASK,SAC9Bf,EAAI,MACJ,IAAMQ,QAAOG,QAAQb,KACrBa,QAAQb,KAAKU,MAAOO,IAAIf,GACxBA,YAbR,IAAIF,OAAOa,cAAPb,YAkBDa,qCAqCeI,IAAIC,eACnBD,IAAIE,QAAQ,cAAc,SAACC,EAAGC,WAC7BA,IAAMH,OAAOI,eAAeD,IACrBH,OAAOG,IAEPD,UApEbT,iBAA8BY,IAAfC,gBAA0BA,gBAAWC"}

View File

@ -0,0 +1,133 @@
/*eslint no-var: "error"*/
/*eslint no-console: "off"*/
/*eslint no-bitwise: "off"*/
/*eslint-disable no-trailing-spaces*/
/*eslint-env es6*/
// Put this file in path/to/plugin/amd/src
import {call} from 'core/ajax';
import {processCollectedJavascript} from 'core/fragment';
//import {replaceNodeContents} from 'core/templates';
import notification from 'core/notification';
import {load_strings} from './string-helper';
import Debugger from './debugger';
//import {markFormSubmitted} from 'core_form/changechecker'; // Moodle 4.00+ only
//import {notifyFormSubmittedByJavascript} from 'core_form/events'; // Moodle 4.00+ only
/**
* Create a random UUID in both secure and insecure contexts
* @returns UUID
*/
function create_uuid() {
if (crypto.randomUUID !== undefined ) {
return crypto.randomUUID();
} else {
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}
}
export default {
install(Vue/*,options*/){
let debug = new Debugger("treestudyplan-mform-helper");
let strings = load_strings({
editmod: {
save$core: "save$core",
cancel$core: "cancel$core",
}
});
Vue.component('mform', {
props: {
name: {
type: String,
},
params: {
type: Object,
}
},
data() {
return {
content: "",
loading: true,
uuid: create_uuid(),
text: strings,
};
},
computed: {
},
methods: {
openForm(){
const self = this;
self.$refs["editormodal"].show();
},
onShown(){
const self = this;
debug.info(`Loading form "${self.name}" with params`,self.params);
self.loading = false;
call([{
methodname: 'local_treestudyplan_get_mform',
args: {name: self.name, params: self.params}
}])[0].then((data)=>{
self.content = data.html;
self.loading = false;
// Process the collected javascript;
processCollectedJavascript(data.js);
}).catch(notification.exception);
//loadFragment('local_treestudyplan', 'mod_edit_form', this.coursectxid, params).then((html,js) =>{
// replaceNodeContents(self.$refs["content"], html, js);
//}).catch(notification.exception);
},
onSave(){
const self = this;
let form = this.$refs["content"].getElementsByTagName("form")[0];
// markFormSubmitted(form); // Moodle 4.00+ only
// We call this, so other modules can update the form with the latest state.
form.dispatchEvent(new Event("save-form-state"));
// Tell all form fields we are about to submit the form.
// notifyFormSubmittedByJavascript(form); // Moodle 4.00+ only
const formdata = new FormData(form);
const data =new URLSearchParams(formdata).toString();
//const formdata = new FormData(form);
//const data = {};
//formdata.forEach((value, key) => (data[key] = value));
call([{
methodname: 'local_treestudyplan_submit_mform',
args: {name: self.name, params: self.params, data: data}
}])[0].then(()=>{
self.$emit("saved",formdata);
}).catch(notification.exception);
}
},
template: `
<span class='s-edit-mod'><a href='#' @click.prevent="open"><slot><i class="fa fa-cog"></i></slot></a>
<b-modal
ref="editormodal"
scrollable
centered
size="xl"
id="'modal-'+uuid"
@shown="onShown"
@ok="onSave"
:title="title"
:ok-title="text.save$core"
><div :class="'s-edit-mod-form '+ (genericonly?'genericonly':'')" ref="content"
><div v-if="loading" class="d-flex justify-content-center mb-3"
><b-spinner variant="primary"></b-spinner
></div
><span v-else v-html="content"
></div
></b-modal>
</span>
`,
});
}
};

View File

@ -1,4 +1,8 @@
import {get_strings} from 'core/str';
import {getStrings} from 'core/str';
/* Determine the proper getstrings function to use (MDL4.3+ recommends use of getStrings, which is jquery independent) */
const getstr_func = (getStrings !== undefined)?getStrings:get_strings;
/**
* Load the translation of strings from a strings object
@ -15,7 +19,7 @@ export function load_strings(strings){
let component = (parts.length > 1)?parts[1]:'local_treestudyplan';
stringkeys.push({ key: identifier, component: component});
}
get_strings(stringkeys).then(function(str){
getstr_func(stringkeys).then(function(str){
let i = 0;
for(const key in strings[idx]){
strings[idx][key] = str[i];
@ -44,7 +48,7 @@ export function load_stringkeys(string_keys){
let component = (parts.length > 1)?parts[1]:'local_treestudyplan';
stringkeys.push({ key: identifier, component: component});
}
get_strings(stringkeys).then(function(strings){
getstr_func(stringkeys).then(function(strings){
for(const i in strings) {
const s = strings[i];
const l = string_keys[idx][i];

View File

@ -0,0 +1,20 @@
<?php
namespace local_treestudyplan\local\forms;
use moodleform;
class studyplan_editform extends moodleform {
public function definition() {
global $CFG, $COURSE, $DB, $PAGE;
$mform = $this->_form;
// Activity.
$mform->addElement('editor', 'activityeditor',
get_string('activityeditor', 'assign'), array('rows' => 10), array('maxfiles' => EDITOR_UNLIMITED_FILES,
'noclean' => true, 'context' => $this->context, 'subdirs' => true));
$mform->addHelpButton('activityeditor', 'activityeditor', 'assign');
$mform->setType('activityeditor', PARAM_RAW);
}
}

View File

@ -25,7 +25,7 @@ $plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-260
$plugin->version = 2023090701; // YYYYMMDDHH (year, month, day, iteration).
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
$plugin->release = "1.0.0";
$plugin->release = "1.1.0-RC1";
$plugin->maturity = MATURITY_STABLE;
// Supported from Moodle 3.11 to 4.1 (4.2 not yet tested).