<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/310/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Abgreeve</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/310/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Abgreeve"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/Special:Contributions/Abgreeve"/>
	<updated>2026-04-18T19:31:12Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Assignment_settings&amp;diff=139718</id>
		<title>Assignment settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Assignment_settings&amp;diff=139718"/>
		<updated>2021-02-25T01:39:13Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Submission settings */ Clarification of the attempts reopened setting.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
This page explores in more detail the settings for the [[Assignment activity]] once you have added it to your course and also covers the Site administration settings.&lt;br /&gt;
&lt;br /&gt;
Note that if you want to edit an existing assignment, click the Edit link to its right and choose the action you wish to take, eg &#039;Edit settings&#039;.&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
#In the Description, provide instructions for students. Check the box if you want these instructions to display on the course page.&lt;br /&gt;
#In Additional files, you can add files which may be of help to the students as they do their assignment, such as example submissions or answer templates.&lt;br /&gt;
&lt;br /&gt;
==Availability==&lt;br /&gt;
&lt;br /&gt;
;Allow submissions from&lt;br /&gt;
:This stops students from submitting before the shown date but it doesn&#039;t hide the assignment and any included instructions or materials.&lt;br /&gt;
;Due date&lt;br /&gt;
:Submissions are still allowed after this date but will be marked as late. Disable it by unticking the checkbox. Assignments without a due date will appear on the dashboard with &#039;No Due Date&#039; displayed.&lt;br /&gt;
;Cut-off date&lt;br /&gt;
:After this date, students will not be able to submit and the submit button will disappear.&lt;br /&gt;
;Remind me to grade by..&lt;br /&gt;
:A date needs to be entered here in order for the assignment to display on the teacher&#039;s [[Course overview block]] and in the [[Calendar]]. It will display when at least one student has submitted.&lt;br /&gt;
&lt;br /&gt;
==Submission types==&lt;br /&gt;
&lt;br /&gt;
Here you can decide how you wish students to submit their work to you.&lt;br /&gt;
&lt;br /&gt;
Note: If Submission comments are enabled in &#039;&#039;Administration&amp;gt;Plugins&amp;gt;Activity modules&amp;gt;Assignment&amp;gt;Submission plugins&#039;&#039;, students will be able to add a note to their teacher on submitting work. If Anonymous submissions are enabled, student comments display in the gradebook as from &amp;quot;Participant 01 etc&amp;quot; to avoid revealing identities.&lt;br /&gt;
&lt;br /&gt;
;Online text&lt;br /&gt;
:Students type their responses directly in Moodle using a text editor (such as the [[Atto editor]] which automatically saves text at regular intervals.)&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to set a word limit on an online text assignment. Students get a warning if they try to exceed the word limit. Numbers are counted as words and abbreviations such as &#039;&#039;I&#039;m&#039;&#039; or &#039;&#039;they&#039;re&#039;&#039; are counted as single words.&lt;br /&gt;
&lt;br /&gt;
;File submissions&lt;br /&gt;
:Students can upload one or more files of any type the teacher can open. The teacher can annotate uploaded PDFs, docx and odt files within the browser, and on saving, the annotated file is made available to the student. (Check with your admin that [https://en.wikipedia.org/wiki/Ghostscript Ghostscript] and a [[Document converters| document converter]] are enabled, if you can&#039;t annotate uploaded files.) In the screenshot below, a docx file has been uploaded and converted so that the teacher may use the annotation tools to comment directly on the student&#039;s assignment.&lt;br /&gt;
&lt;br /&gt;
[[File:assignmentgrading3.png|thumb|500px|center|Annotating uploaded files]]&lt;br /&gt;
&lt;br /&gt;
Comments may be collapsed to make it easier to read the original text:&lt;br /&gt;
&lt;br /&gt;
[[File:collapsedcommentexample.png]]&lt;br /&gt;
&lt;br /&gt;
;Maximum submission size&lt;br /&gt;
:The maximum upload size refers to each file a student uploads. It cannot be larger than the limit in the Course settings.&lt;br /&gt;
;Accepted file types&lt;br /&gt;
:The teacher can specify the types of file the students may upload to the assignment. A file type selector appears upon clicking &#039;Choose&#039;, offering a choice of different file types. (See the video [https://youtu.be/vN1DlHeZkw4 File type selection] for more information.) Leaving the field blank will allow all file types.&lt;br /&gt;
&lt;br /&gt;
If the file types have been restricted, then when students attempt to submit the assignment, they will see a message telling them which files are accepted:&lt;br /&gt;
[[File:studentfiletyperestrictions.png|thumb|500px|center|Student view of specified files]]&lt;br /&gt;
&lt;br /&gt;
==Feedback types==&lt;br /&gt;
;Feedback comments&lt;br /&gt;
:With this enabled, markers can leave comments for each submission (which appear on the assignment grading screen.)&lt;br /&gt;
&lt;br /&gt;
The [[Atto editor]] now allows for recording audio and video when grading, along with the option to upload supporting files such as images.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Annotate PDF&#039;&#039;&#039; appears if this setting is enabled by the Site administrator in the &#039;&#039;Manage assignment feedback plugins&#039;&#039; section of Site admin and will allow the teacher to annotate using comments, stamps and other features.&lt;br /&gt;
&lt;br /&gt;
;Offline grading worksheet&lt;br /&gt;
:This is useful if you wish to download the grading list and edit it in a program such as MS Excel.&lt;br /&gt;
{|&lt;br /&gt;
|[[File:emptygradebook.png|thumb|The empty gradebook on Moodle]]&lt;br /&gt;
|[[File:downloadgradingworksheet.png|thumb|The dropdown to download the list]]&lt;br /&gt;
|[[File:excelgrades.png|thumb|Editing the grades offline]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When the teacher has completed their grading offline, they can then upload the spreadsheet, confirm the changes and the grades and comments will be transferred over into Moodle&#039;s gradebook:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|[[File:uploadgradingworksheet.png|thumb|Uploading the grading worksheet]]&lt;br /&gt;
|[[File:confirmchanges.png|thumb|Confirming the changes]]&lt;br /&gt;
|[[File:fullgradebook.png|thumb|Grades and feedback transferred into Moodle]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See also [http://www.somerandomthoughts.com/blog/2012/11/19/offline-grading-worksheet-in-moodle-2-4-assignment/ Offline grading worksheet] blog post by Gavin Henrick.&lt;br /&gt;
&lt;br /&gt;
;Feedback files&lt;br /&gt;
:This allows markers to upload files with feedback when marking. These files may be the marked up student assignments, documents with comments, a completed marking guide, or spoken audio feedback. It enables the Feedback Files column in the assignment grading screen (accessed from &#039;View/Grade all submissions&#039;.) To upload feedback files, click on the green tick in the grade column on the grading table and then upload either with drag and drop or using the [[File picker]].&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|[[File:feedback files.jpg|thumb|The Feedback files column]]&lt;br /&gt;
|[[File:feedback files 2.jpg|thumb|Upload files here]]&lt;br /&gt;
|[[File:feedback view for students.jpg|thumb|Student view with comments and file feedback both enabled]]&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Uploading multiple feedback files&#039;&#039;&#039; is also possible:&lt;br /&gt;
#Download the students&#039; assignments using the &amp;quot;Download all submissions&amp;quot; link from the same dropdown menu;&lt;br /&gt;
#Extract the folder offline and add your comments to the student&#039;s submissions. Keep the names the same.&lt;br /&gt;
#Select the students&#039; submissions and zip them into a new folder. Important: Don&#039;t just edit them inside their original folder and re-zip this; it will not work. The folder name does not matter as long as the feedback files have the same names as before.&lt;br /&gt;
#Upload this newly zipped folder.&lt;br /&gt;
#You will be presented with a confirmation screen displaying your feedback files. (If you zip files from a Mac, make sure to remove the folder _MACOSX)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|[[File:mutiplefeedbackzip.png|thumb|Choose from the dropdown menu]]&lt;br /&gt;
|[[File:multiplezip1.png|thumb|Confirmation screen displaying the feedback files to be uploaded]]&lt;br /&gt;
|[[File:multiplezip2.png|thumb|Screen confirming uploaded feedback]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
;Comment inline&lt;br /&gt;
:This usefully allows you to comment directly on an &#039;online text&#039; type submission.&lt;br /&gt;
&lt;br /&gt;
==Submission settings==&lt;br /&gt;
;Require students click submit button&lt;br /&gt;
:If this is set to &#039;No&#039; students can make changes to their submission at any time. (If you want to stop them changing work once you are ready to grade, click &#039;View/Grade all submissions&#039;; locate the student and From the Edit column, click the action icon and select &#039;Prevent submission changes&#039;.)&lt;br /&gt;
:If set to &#039;Yes&#039;, students can upload draft versions of the assignment until such time as they are ready to submit. Clicking the submit button tells the teacher they have finished drafting and want the work to be graded. They can no longer edit it and must ask the teacher to revert to draft status if they need to change it again. To do that, click &#039;View/Grade all submissions; locate the student and from the Edit column, click the action icon and select &#039;Revert the submission to draft&#039;.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|[[File:revert to draft.jpg|thumb|Reverting to draft]]&lt;br /&gt;
|[[File:prevent submission changes.jpg|thumb|Prevent submission changes]]&lt;br /&gt;
|[[File:with selected.jpg|thumb|&amp;quot;With selected&amp;quot; to choose several students.]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
;Require that students accept the Submission statement&lt;br /&gt;
:An administrator can define a &amp;quot;Submission statement&amp;quot; (see below) i.e. a statement where students promise the work is their own and which they must agree to before submitting their work. If the administrator has given teachers the option of using a submission statement or not, then it will be available in the assignment settings screen. If the administrator has forced the statement throughout the site, a teacher will not have this option in the settings but a student will see the statement when accessing their assignment.&lt;br /&gt;
&lt;br /&gt;
;Attempts reopened&lt;br /&gt;
: Here you can allow the teacher to reopen a students submission attempt. Changing this setting to &#039;Manually&#039; allows the teacher to go into the grader and in the &amp;quot;Attempt settings&amp;quot; section set &amp;quot;Allow another attempt&amp;quot; to either &amp;quot;yes&amp;quot; or &amp;quot;no&amp;quot;. Changing the setting to &amp;quot;Automatically until pass&amp;quot; requires that &amp;quot;Grade to pass&amp;quot; in the Grade section be set. If the student does not receive a passing grade then the submission will automatically be reopened and another attempt can be made.&lt;br /&gt;
;Maximum attempts&lt;br /&gt;
: Here you can decide how many attempts to allow if students can resubmit. If a student has to keep trying until they get a pass grade, you might decide to limit the attempts even though they have not yet passed - or they might be trying for ever!&lt;br /&gt;
&lt;br /&gt;
==Groups submission settings==&lt;br /&gt;
These settings allow students to collaborate on a single assignment, eg. working in the same online area or uploading, editing and reuploading an MS Powerpoint in the common assignment area.&lt;br /&gt;
&lt;br /&gt;
When grading, the teacher may choose to give a common grade and feedback to all students in the group or to give individual grades and feedback to each member.&lt;br /&gt;
&lt;br /&gt;
;Require group to make submission&lt;br /&gt;
:Students not in a group can still submit assignments unless this is forced in &#039;&#039;Site administration &amp;gt; Plugins &amp;gt; Assignment &amp;gt; Assignment settings&#039;&#039;. Moodle will then display a message &#039;&#039;You&#039;re not a member of any group; please contact your teacher&#039;&#039; , and the student will not be able to submit the assignment.&lt;br /&gt;
;Require all group members submit&lt;br /&gt;
:This setting will only appear if the teacher has ticked the &amp;quot;Require students click submit button&amp;quot; earlier. The assignment will not be classed as &amp;quot;submitted&amp;quot; until all members of the group have made a contribution. When one student has submitted, the other members of the group will be able to see who still has to submit.&lt;br /&gt;
;Grouping for student groups&lt;br /&gt;
:If a particular grouping is selected here, then the gradebook will display any other groups and non-grouped students in the &amp;quot;default group&amp;quot;, while naming the group(s) that are in the chosen grouping. If &amp;quot;none&amp;quot; is selected, then the gradebook will display the names of all groups and put any non-grouped students in the &amp;quot;default group&amp;quot;. See this [https://moodle.org/mod/forum/discuss.php?d=216399#p942913 forum post on grouping for student groups] for examples of how this might be used.&lt;br /&gt;
&lt;br /&gt;
==Notifications==&lt;br /&gt;
Please note that if you are using group mode then course teachers need to be members of the group in order to receive submission and late submission notifications.&lt;br /&gt;
&lt;br /&gt;
==Grade==&lt;br /&gt;
*See [[Grade points]] and [[Advanced grading methods]] for more information on the settings here.&lt;br /&gt;
*Setting a passing grade may be connected with [[Activity completion]] and [[Restrict access]] such that a student will not be able to access a follow up activity until they have passed this assignment.&lt;br /&gt;
*;Anonymous submissions&lt;br /&gt;
:This hides students&#039; names when grading and instead shows randomly generated Participant numbers.&lt;br /&gt;
&lt;br /&gt;
With Anonymous submissions, students cannot see the final grade until all of the students&#039; names have been revealed. Rubrics will also be hidden from students&#039; view until the names are revealed. To reveal student names after you are finished grading, look under &#039;&#039;Assignment settings &amp;gt; Reveal student identities&#039;&#039;. Feedback comments will appear whether or not student names are hidden or revealed. Note that this level of anonymity might not suit the privacy requirements of your organisation. See MDL-35390 for more details.&lt;br /&gt;
&lt;br /&gt;
Users with the capability [[Capabilities/mod/assign:viewblinddetails|View student identities when Anonymous submissions are enabled]] (by default managers only) can view student identities and participant numbers.&lt;br /&gt;
&lt;br /&gt;
Users with the capability [[Capabilities/moodle/site:viewanonymousevents|View anonymous events in reports]] (by default managers only) can view student submissions to assignments with Anonymous submissions (in Moodle 3.9 onwards).&lt;br /&gt;
&lt;br /&gt;
*;Marking (grading) workflow&lt;br /&gt;
:This lets you keep grades and feedback hidden until you are ready to release them to students. It is also useful if you want to show your progress in grading, or co-ordinate multiple markers/graders.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|[[File:26markingworkflow.png|thumb|Marking workflow state in the individual grading screen]]&lt;br /&gt;
|[[File:26quickgradingworkflow.png|thumb|Dropdown to select marking workflow state when quick grading]]&lt;br /&gt;
|}&lt;br /&gt;
The phases are:&lt;br /&gt;
&lt;br /&gt;
* Not marked (the marker has not yet started)&lt;br /&gt;
* In marking (the marker has started but not yet finished)&lt;br /&gt;
* Marking completed (the marker has finished but might need to go back for checking/corrections)&lt;br /&gt;
* In review (the marking is now with the teacher in charge for quality checking)&lt;br /&gt;
* Ready for release (the teacher in charge is satisfied with the marking but wait before giving students access to the marking)&lt;br /&gt;
* Released (the student can access the grades/feedback)&lt;br /&gt;
&lt;br /&gt;
;Marking allocation&lt;br /&gt;
:Marking allocation can be used if marking workflow is set to Yes. Teachers can then be selected to grade or review submitted work of specific students.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|[[File:26markingworkflowallocatedmarkers.png|thumb|Allocated markers on the grading screen]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Other settings==&lt;br /&gt;
Depending on what is enabled for your site and course, you may also need to explore [[Common module settings]], [[Restrict access| Restrict access]], [[Activity completion]], [[Tags]] and [[Competencies]]&lt;br /&gt;
==Assignment capabilities==&lt;br /&gt;
&lt;br /&gt;
* [[Capabilities/mod/assign:exportownsubmission|Export own submission]]&lt;br /&gt;
* [[Capabilities/mod/assign:grade|Grade assignment]]&lt;br /&gt;
* [[Capabilities/mod/assign:submit|Submit assignment]]&lt;br /&gt;
* [[Capabilities/mod/assign:view|View assignment]]&lt;br /&gt;
&lt;br /&gt;
Role permissions for the activity can be changed from the gear icon Actions menu.&lt;br /&gt;
&lt;br /&gt;
==Site administration settings==&lt;br /&gt;
Administrators can access assignment configuration options by expanding &#039;&#039;Administration &amp;gt; Site administration &amp;gt; Plugins &amp;gt; Activity modules &amp;gt; Assignment&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Assignment settings===&lt;br /&gt;
Here, the administrator can set defaults for certain settings. They may also make certain settings &#039;Advanced&#039; which means a course teacher has to click the &#039;Show more&#039; link to see them, or they may &#039;lock&#039; settings which means a course teacher cannot alter that setting.&lt;br /&gt;
&lt;br /&gt;
If the site contains courses with over 100 participants, the number of assignments listed on the assignment grading page may be limited using the Maximum assignments per page (assign | maxperpage) setting. This removes &#039;All&#039; from the &#039;Assignments per page&#039; setting.&lt;br /&gt;
&lt;br /&gt;
;Submission statement&lt;br /&gt;
:Here is where the administrator can enter text into a box which will appear when students are about to submit an assignment:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|[[File:newsubmissionstatement.png|thumb|Admin view of Submission statement set up screen - click to enlarge]]&lt;br /&gt;
|[[File:submissionstatement1.png|thumb|Student view when about to submit - click to enlarge]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If it is left as the default &amp;quot;No&amp;quot;, then teachers will have the choice within their own assignments to force this or not.&lt;br /&gt;
&lt;br /&gt;
The submission statement may be shown in different languages. See [[Multi-language content filter]] for how to do this.&lt;br /&gt;
&lt;br /&gt;
Note for sites using languages other than English: There is currently a bug affecting the default assignment submission statement - it doesn&#039;t display in a user&#039;s language (MDL-54731). A workaround is to enter the submission statement in the required language (using the multi-lang filter if multiple languages are are required) in the &#039;Submission statement&#039; (submissionstatement) field then save changes.&lt;br /&gt;
&lt;br /&gt;
===Submission plugins===&lt;br /&gt;
Here the administrator can enable, disable or change the order and default settings for any submission plugins.&lt;br /&gt;
;Submission comments&lt;br /&gt;
:Note that if submission comments are enabled here AND comments enabled globally in &#039;&#039;Site Administration &amp;gt; Advanced features&#039;&#039;) then students will be able to send a message to their teacher when submitting their assignment. If either of those settings is disabled, then the submission comments link will not appear.&lt;br /&gt;
&lt;br /&gt;
===Feedback plugins===&lt;br /&gt;
====Manage assignment feedback plugins====&lt;br /&gt;
Here the administrator can enable, disable or change the order and default settings for any feedback plugins.&lt;br /&gt;
;Annotate PDF&lt;br /&gt;
:This is the place to upload stamps for teachers to use when annotating student PDFs.&lt;br /&gt;
&lt;br /&gt;
=====Check Ghostscript=====&lt;br /&gt;
You can also check the ghostscript path from here:&lt;br /&gt;
{|&lt;br /&gt;
|[[File:Selection_116.png|thumb|Ghostscript not installed or incorrectly installed]]&lt;br /&gt;
|[[File:Selection_115.png|thumb|Ghostscript correctly installed]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the default stamps are deleted by accident, they can be found in mod/assign/feedback/editpdf/pix and re-uploaded.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[de:Aufgabe konfigurieren]]&lt;br /&gt;
[[fr:Ajouter/modifier un devoir]]&lt;br /&gt;
[[ja:課題を追加/編集する]]&lt;br /&gt;
[[es:Configuraciones de tarea]]&lt;br /&gt;
[[it:Impostazioni Compito]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Block_layout&amp;diff=132639</id>
		<title>Block layout</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Block_layout&amp;diff=132639"/>
		<updated>2018-12-04T14:10:58Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Update explaining that the navigation and administration blocks can not be updated with the defaultblocks settings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Blocks}}&lt;br /&gt;
==Default block layout for new courses==&lt;br /&gt;
&lt;br /&gt;
To amend the default block layout for new courses, one or more of the following lines (omitting the forward slashes) from &#039;&#039;config-dist.php&#039;&#039; may be added to &#039;&#039;[[Configuration_file|config.php]]&#039;&#039;, amending the block names as required.&lt;br /&gt;
&lt;br /&gt;
 // These variables define DEFAULT block variables for new courses&lt;br /&gt;
 // If this one is set it overrides all others and is the only one used.&lt;br /&gt;
 //      $CFG-&amp;gt;defaultblocks_override =    &#039;participants,activity_modules,search_forums,course_list:news_items,calendar_upcoming,recent_activity&#039;;&lt;br /&gt;
 //&lt;br /&gt;
 // These variables define the specific settings for defined course formats.&lt;br /&gt;
 // They override any settings defined in the formats own config file.&lt;br /&gt;
 //      $CFG-&amp;gt;defaultblocks_site = &#039;site_main_menu,course_list:course_summary,calendar_month&#039;;&lt;br /&gt;
 //      $CFG-&amp;gt;defaultblocks_social =  &#039;participants,search_forums,calendar_month,calendar_upcoming,social_activities,recent_activity,course_list&#039;;&lt;br /&gt;
 //      $CFG-&amp;gt;defaultblocks_topics =  &#039;participants,activity_modules,search_forums,course_list:news_items,calendar_upcoming,recent_activity&#039;;&lt;br /&gt;
 //      $CFG-&amp;gt;defaultblocks_weeks =  &#039;participants,activity_modules,search_forums,course_list:news_items,calendar_upcoming,recent_activity&#039;;&lt;br /&gt;
 // These blocks are used when no other default setting is found.&lt;br /&gt;
 //      $CFG-&amp;gt;defaultblocks = &#039;participants,activity_modules,search_forums,course_list:news_items,calendar_upcoming,recent_activity&#039;;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, to set the default block layout for topics format courses to People, and Tags on the left, and Messages, Online users and Recent activity on the right, simply add the following line to your &#039;&#039;config.php&#039;&#039; file:&lt;br /&gt;
&lt;br /&gt;
 $CFG-&amp;gt;defaultblocks_topics =  &#039;participants,tags:messages,online_users,recent_activity&#039;;&lt;br /&gt;
&lt;br /&gt;
Note how the colon is used to separate those blocks appearing on the left, from those appearing on the right.&lt;br /&gt;
Additional Note: The Navigation and Administration blocks are not customisable using these settings.&lt;br /&gt;
&lt;br /&gt;
==Resetting the block layout for existing courses==&lt;br /&gt;
&lt;br /&gt;
The block layout for existing courses may be reset by copying the following script into a text file, saving it as &#039;&#039;resetblocks.php&#039;&#039;, copying it into the Moodle root directory, then visiting &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://yourmoodlesite.org/resetblocks.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: This script may change the layout of your course pages and also remove blocks from those pages if they have not been specified in the config.php line. Check which of your courses has blocks which are not in the config.php line and be prepared to spend time adding blocks to your course pages again. &#039;&#039;Please note that a database backup is recommended before using the script&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 //moodle 2.x&lt;br /&gt;
 require_once(&#039;config.php&#039;);&lt;br /&gt;
 require_once($CFG-&amp;gt;libdir.&#039;/blocklib.php&#039;);&lt;br /&gt;
 $courses = get_courses();//can be feed categoryid to just effect one category&lt;br /&gt;
 foreach($courses as $course) {&lt;br /&gt;
    $context = get_context_instance(CONTEXT_COURSE,$course-&amp;gt;id);&lt;br /&gt;
    blocks_delete_all_for_context($context-&amp;gt;id);&lt;br /&gt;
    blocks_add_default_course_blocks($course);&lt;br /&gt;
 } &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[es:Diseño de bloque]]&lt;br /&gt;
[[ja:ブロックレイアウト]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Lesson_settings&amp;diff=130320</id>
		<title>Lesson settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Lesson_settings&amp;diff=130320"/>
		<updated>2018-03-14T07:47:22Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Provide option to try a question again - update to try to explain how this setting works. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Lesson}}&lt;br /&gt;
=Lesson administration settings=&lt;br /&gt;
&lt;br /&gt;
This page explains the settings involved when first creating a lesson.&lt;br /&gt;
To add a lesson to your Moodle course page:&lt;br /&gt;
*With the editing turned on, in the section you wish to add your lesson, click the &amp;quot;Add an activity or resource&amp;quot; link (or, if not present, the &amp;quot;Add an activity&amp;quot; drop down menu) and choose &#039;&#039;Lesson&#039;&#039; All settings may expanded by clicking the &amp;quot;Expand all&amp;quot; link top right.&lt;br /&gt;
*In the &#039;&#039;&#039;General&#039;&#039;&#039; section, give your lesson a name, a description if needed, and tick the box if you wish that description displayed on the course page.&lt;br /&gt;
&lt;br /&gt;
==Appearance==&lt;br /&gt;
===Progress bar===&lt;br /&gt;
Choose this to show a bar at the bottom of the page showing how far into the lesson the student has got.&lt;br /&gt;
* For lessons containing &#039;&#039;&#039;only&#039;&#039;&#039; &#039;&#039;Content pages&#039;&#039;, once a lesson has been taken to the end, if that same lesson is re-taken, the progress bar will not be &amp;quot;reset&amp;quot;, i.e. it will show a 100% progress from page 1! &lt;br /&gt;
&lt;br /&gt;
* For lessons containing &#039;&#039;Question pages&#039;&#039; and set to &amp;quot;Re-take&amp;quot; &#039;&#039;&#039;Yes&#039;&#039;&#039;, the progress bar is always &amp;quot;reset&amp;quot; at 0% upon re-take.&lt;br /&gt;
&lt;br /&gt;
* Note that the Lesson Progress bar only works correctly for lessons with a &amp;quot;straightforward&amp;quot; navigation, such as page 1 -&amp;gt; page  2 -&amp;gt; page n -&amp;gt; end of lesson. It is not guaranteed to work with pages &amp;quot;jumping all over the place&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Display menu=== &lt;br /&gt;
Choose this when you want to show a list of the content page titles in the Lesson to the student.  Only those pages which have &amp;quot;Display in menu?&amp;quot; checked will display. The  menu will not display question pages.&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
&lt;br /&gt;
====Linked media====&lt;br /&gt;
[[File:pop-up file link.png|thumb|Link to pop-up]]&lt;br /&gt;
If you want to include a link to a media file for students to refer to, upload it here. A &#039;Click here to view&#039; link will be displayed in a block called &#039;Linked media&#039; on each page of the lesson.&lt;br /&gt;
&lt;br /&gt;
The width and height of the pop-up window may be set by an admin in &#039;&#039;Site administration &amp;gt; Plugins &amp;gt; Activity modules &amp;gt; Lesson&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====Display ongoing score====&lt;br /&gt;
Choose this to let students see their score as they work through the lesson.&lt;br /&gt;
&lt;br /&gt;
===Minimum grade to display menu===&lt;br /&gt;
Choose this if you want the student to go through the lesson once and get a grade before they can (on review) see and navigate through all the different pages.&lt;br /&gt;
====Slideshow====&lt;br /&gt;
&lt;br /&gt;
Slideshow height, width and background colour are set for the whole site by an administrator in  Site administration &amp;gt; Plugins &amp;gt; Activity modules &amp;gt; Lesson&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====Maximum Number of Answers====&lt;br /&gt;
Here you can set the default number of selection boxes available when you add or edit a question or content page. For instance, if you are only going to use Multiple Choice questions with 3 answers in your lesson, you might select 3. You can change the default here at any time to display more or less question answers or content choices.&lt;br /&gt;
:&#039;&#039;Note:&#039;&#039; This only impacts the editing screen. Changing from 4 to 2 will not remove or hide any answers previously entered from the student.&lt;br /&gt;
&lt;br /&gt;
====Use default feedback====&lt;br /&gt;
Every Moodle site has a standard response (feedback) when a student selects a correct or wrong answer in a lesson. Select &amp;quot;No&amp;quot; if you only what you put as a response for a specific question&#039;s answer to display. In this case, when you leave the response to a question blank, the student will not see any comment about their answer.  The typical Moodle standard responses are: &amp;quot;That&#039;s the correct answer&amp;quot; or &amp;quot;That&#039;s the wrong answer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
====Link to next activity====&lt;br /&gt;
Choose this to give students a link to another activity when they reach the end of the lesson.&lt;br /&gt;
&lt;br /&gt;
==Availability==&lt;br /&gt;
&lt;br /&gt;
===Available from/Deadline===&lt;br /&gt;
Here you can set a start and end date and time for your Lesson.&lt;br /&gt;
&lt;br /&gt;
===Time limit=== &lt;br /&gt;
&lt;br /&gt;
This allows you to set a time limit on the lesson which can now be seconds, minutes, hours, days or weeks. Students will see a countdown counter in a block as they work.(Note that this does not work if the lesson is downloaded for offline use via the mobile app.)&lt;br /&gt;
&lt;br /&gt;
[[File:lessontimeremaining.png]]&lt;br /&gt;
&lt;br /&gt;
The timer does not stop them doing the lesson when the time is up, but  correct answers are no longer scored.&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
&lt;br /&gt;
====Password protected lesson====&lt;br /&gt;
*Change to &amp;quot;Yes&amp;quot;  and enter the password if you want students only to access it when they know the password.&lt;br /&gt;
&lt;br /&gt;
====Allow lesson to be attempted offline====&lt;br /&gt;
&lt;br /&gt;
Enabling this setting means the lesson can be downloaded and done offline by a mobile app user.Lessons which are timed may not be attempted offline.&lt;br /&gt;
&lt;br /&gt;
==Flow control==&lt;br /&gt;
&lt;br /&gt;
===Allow Student Review===&lt;br /&gt;
This puts a &amp;quot;Review Lesson&amp;quot; button on the last screen of the lesson to encourage the students to navigate through the lesson again. If the lesson contains questions then the review will start from the first question, otherwise the review will start from the first content page.&lt;br /&gt;
:Note that the students will not be able to &#039;&#039;change&#039;&#039; their answers, only &#039;&#039;view&#039;&#039; them.&lt;br /&gt;
&lt;br /&gt;
===Provide option to try a question again===&lt;br /&gt;
*This displays a button after an incorrectly answered question so that the student can try again (but not get credit for it). If the student clicks to move on to another question then the selected (wrong) answer jump will be followed. By default wrong answer jumps are set to &amp;quot;this page&amp;quot;, so it is recommended that you set the wrong answer jump to a different page to avoid confusion with your students.&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; Leave this off if you are using essay questions. &lt;br /&gt;
&lt;br /&gt;
===Maximum Number of Attempts===&lt;br /&gt;
*Decide here how many times you want students to be able to attempt each question. When they reach the maximum, they will be taken automatically to the next page.&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039;&#039;&#039; this setting works in combination with the above setting, or independently. &lt;br /&gt;
&lt;br /&gt;
*When &#039;provide an option to try again&#039; is set to No, students will be able to retake the question as many times as it is set here, with a score penalty.&lt;br /&gt;
&lt;br /&gt;
*When &#039;provide an option to try again&#039; is set to Yes, then students will be able to retake the question as many times as it set here without a score penalty. In this case an extra dialogue appears.&lt;br /&gt;
&lt;br /&gt;
Consequently when the relevant jump &#039;this page&#039; is used in wrong answer while the &#039;provide an option to try again&#039; is set to No and &#039;maximum number of attempts&#039; is set to 1, a student that will answer wrongly will be moved into the next page, since he/she has the change to try the question just once. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Tip:&#039;&#039;&#039;&#039;&#039; Ensure you check lesson using a real student account, as the teacher preview or the &#039;switch role to student&#039; may not give you the exact picture.&lt;br /&gt;
&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
&lt;br /&gt;
====Action after a Correct Answer====&lt;br /&gt;
Choose here where you want a student to be sent to if they get a question right. See [[Using Lesson]] for more details on this setting. The options are:&lt;br /&gt;
**the next part of the Lesson (default setting)&lt;br /&gt;
**a random, unexpected page&lt;br /&gt;
**a random page which they have not yet answered.&lt;br /&gt;
====Number of pages to show====&lt;br /&gt;
You only need this if you have set &amp;quot;Action after a correct answer&amp;quot; to show an unseen or unanswered page. Otherwise, all pages will be seen&lt;br /&gt;
&lt;br /&gt;
==Grade==&lt;br /&gt;
&lt;br /&gt;
Set a grade and grade category here, along with a &amp;quot;Grade to pass&amp;quot; which may be connected with [[Activity completion]] and [[Restrict access]] such that a student will not be able to access a follow up activity until they have obtained the required grade in the lesson.&lt;br /&gt;
&lt;br /&gt;
===Practice lesson===&lt;br /&gt;
&lt;br /&gt;
Practice lessons are now saved; this means they will appear in the reports .You must enable the &amp;quot;Retakes allowed&amp;quot; setting if you want students to be able to attempt a practice lesson several times.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: If you are upgrading from an earlier version, be aware that all practice lessons will have &amp;quot; Re-takes allowed&amp;quot;  set to &amp;quot;Yes&amp;quot; . If you are restoring  a practice lesson made before this change, you may need to  modify the &amp;quot;Re-takes allowed&amp;quot; setting if needed.&lt;br /&gt;
&lt;br /&gt;
===Custom Scoring===&lt;br /&gt;
Use this to give a particular number score (negative or positive) to each answer&lt;br /&gt;
===Re-takes allowed===&lt;br /&gt;
Choose this if you want your students to be able to do the lesson more than once.&lt;br /&gt;
:Note that this setting only applies to lessons containing &#039;&#039;Question pages&#039;&#039;. Lessons consisting &#039;&#039;&#039;only&#039;&#039;&#039; of &#039;&#039;Content pages&#039;&#039; can be re-taken even if &#039;Re-takes allowed&#039; is set to &#039;&#039;No&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
====Handling of re-takes====&lt;br /&gt;
If you allow your students to re-take the lesson, then decide here if the grade for all lesson attempts is the mean or the maximum.&lt;br /&gt;
&lt;br /&gt;
:Note that the Question Analysis always uses the answers from the first tries of the lesson. Re-takes by students are ignored.&lt;br /&gt;
&lt;br /&gt;
====Minimum Number of Questions====&lt;br /&gt;
Set the minimum number of questions that will be used to calculate a student&#039;s score. Students will be told how many they have answered and how many more they need to answer.&lt;br /&gt;
*If you are using Content pages, then set this to 0.&lt;br /&gt;
*If you use this setting, then add some explanatory text at the start of the lesson so the student knows the minimum number of questions they must answer to receive a grade.&lt;br /&gt;
&lt;br /&gt;
==Common module settings==&lt;br /&gt;
See [[Common module settings]]&lt;br /&gt;
&lt;br /&gt;
==Access restrictions==&lt;br /&gt;
[[Restrict access]] must be turned on in the site settings for this to appear.&lt;br /&gt;
(These settings are collapsed by default)&lt;br /&gt;
&lt;br /&gt;
*Grade - limit to overall grade or specific grade on another activity&lt;br /&gt;
*Group - limit to specific group&lt;br /&gt;
*Groupings - limit to specific groupings&lt;br /&gt;
*User profile - limit based upon user profile fields&lt;br /&gt;
*Restriction set - nest restrictions&lt;br /&gt;
&lt;br /&gt;
==Activity completion==&lt;br /&gt;
[[Activity completion]] must be turned on in the site settings for this to appear.&lt;br /&gt;
(These settings are collapsed by default)&lt;br /&gt;
*Completion tracking - 3 options&lt;br /&gt;
*Required view&lt;br /&gt;
*Required grade&lt;br /&gt;
*Required end reached&lt;br /&gt;
*Required time spent&lt;br /&gt;
*Expected completion on&lt;br /&gt;
&lt;br /&gt;
==User and group overrides==&lt;br /&gt;
&lt;br /&gt;
When a lesson has been created, it is possible to overrride certain settings for individuals and groups from Lesson administration. In situations where two group overrides may apply to a single user, the most lenient date is used. For &amp;quot;Available from&amp;quot; dates, this means the earliest possible date is used, for &amp;quot;Deadline&amp;quot; dates, this means that the latest possible date is used. Note also that if there exists a user override for a student, it will always take precedence over any group overrides.&lt;br /&gt;
&lt;br /&gt;
It is possible to override passwords, availability/deadline, time limits and question retries and lesson retakes.&lt;br /&gt;
&lt;br /&gt;
Selecting one of the options, for example &#039;User&#039; will display a button to click. From the next screen you can choose the user or group to override and the settings you wish to override:&lt;br /&gt;
&lt;br /&gt;
[[File:lessonoverrideuser.png]]&lt;br /&gt;
&lt;br /&gt;
When the override is saved, it is displayed on a screen along with any other overrides previously set:&lt;br /&gt;
&lt;br /&gt;
[[File:lessonoverrideexamples.png]]&lt;br /&gt;
&lt;br /&gt;
==Site administration settings==&lt;br /&gt;
&lt;br /&gt;
*The administrator can change the lesson&#039;s default settings and decide which lesson features to display to teachers in courses, and which features are &#039;Advanced&#039;.&lt;br /&gt;
*Features which have the &#039;Advanced&#039; box ticked only display when teachers click a &#039;Show more&#039; link.&lt;br /&gt;
*This is useful for simplifying the lesson for teachers when it is first set up.&lt;br /&gt;
*The lesson settings can be reviewed from &#039;&#039;Site administration &amp;gt; Plugins &amp;gt; Activity modules &amp;gt; Lesson.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[de:Lektion konfigurieren]]&lt;br /&gt;
[[fr:Ajouter/modifier une leçon]]&lt;br /&gt;
[[ja:レッスンの設定]]&lt;br /&gt;
[[es:Configuraciones de lección]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=MySQL_full_unicode_support&amp;diff=128335</id>
		<title>MySQL full unicode support</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=MySQL_full_unicode_support&amp;diff=128335"/>
		<updated>2017-07-26T01:49:03Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: sql commands addition&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Environment}}&lt;br /&gt;
==UTF-8==&lt;br /&gt;
&lt;br /&gt;
UTF-8 is a character encoding that most websites use. It encodes each of the 1,112,064 valid code points. To store all of this information, four bytes is required. The most popular values are in the three byte region. MySQL by default only uses a three byte encoding and so values in the four byte range (eg. Asian characters and Emojis) can not be stored. Any attempt to enter a text that contains four byte characters will result in a Moodle database error.&lt;br /&gt;
&lt;br /&gt;
MySQL does provide full four byte UTF-8 support, but it requires certain database settings to be configured. From version 3.3 on Moodle uses full UTF-8 for both MySQL and MariaDB by default. Existing databases will still run with partial support, but it is recommended to move over to full support.&lt;br /&gt;
&lt;br /&gt;
Moodle comes with a Command Line Interface (CLI) script for converting to full UTF-8 for MySQL (and MariaDB). Before Moodle versions 3.1.5 and 3.2.2 this conversion tool would only change the Collation to some variant of &#039;utf8_bin&#039;. &#039;utf8_unicode_ci&#039; was the recommended Collation. We now recommend using &#039;utf8mb4_unicode_ci&#039; which supports four byte characters (utf8_unicode_ci only supports three).&lt;br /&gt;
&lt;br /&gt;
This script will attempt to change the database Collation, Character set, default table settings and column definitions.&lt;br /&gt;
&lt;br /&gt;
To summarise:&lt;br /&gt;
&lt;br /&gt;
* Fresh installs of Moodle 3.1.5 and 3.2.2 onwards will use utf8mb4 by default, if the database server is configured appropriately (see below).&lt;br /&gt;
* Sites upgrading to Moodle 3.1.5 or 3.2.2 can use the script to update to utf8mb4. In Moodle 3.3 a warning will show that the database isn&#039;t using full UTF-8 support and suggest moving to &#039;utf8mb4_unicode_ci&#039;, but you may choose to keep using &#039;utf8_*&#039;.&lt;br /&gt;
&lt;br /&gt;
===File format===&lt;br /&gt;
&lt;br /&gt;
To allow for large indexes on columns that are a varchar, a combination of settings needs to be set. The file format for the system needs to be using &amp;quot;Barracuda&amp;quot;. This allows for the row format to be set to &amp;quot;Compressed&amp;quot; or &amp;quot;Dynamic&amp;quot;. To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
===File per table===&lt;br /&gt;
&lt;br /&gt;
To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
===Large prefix===&lt;br /&gt;
&lt;br /&gt;
This in conjunction with the row format being either &amp;quot;Compressed&amp;quot; or &amp;quot;Dynamic&amp;quot; allows for large varchar indexes above 191 characters.&lt;br /&gt;
To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
==Steps to upgrade==&lt;br /&gt;
&lt;br /&gt;
Most important: Please backup your database before making any changes or running the CLI script.&lt;br /&gt;
&lt;br /&gt;
* Change configuration settings for MySQL (exactly the same for MariaDB). This step is optional. You can run the script and it will try and make these changes itself. If errors occur then try manually changing these settings as listed below.&lt;br /&gt;
** On Linux based systems you will want to alter my.cnf. This may be located in &#039;/etc/mysql/&#039;.&lt;br /&gt;
** Make the following alterations to my.cnf:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[client]&lt;br /&gt;
default-character-set = utf8mb4&lt;br /&gt;
&lt;br /&gt;
[mysqld]&lt;br /&gt;
innodb_file_format = Barracuda&lt;br /&gt;
innodb_file_per_table = 1&lt;br /&gt;
innodb_large_prefix&lt;br /&gt;
&lt;br /&gt;
character-set-server = utf8mb4&lt;br /&gt;
collation-server = utf8mb4_unicode_ci&lt;br /&gt;
skip-character-set-client-handshake&lt;br /&gt;
&lt;br /&gt;
[mysql]&lt;br /&gt;
default-character-set = utf8mb4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Restart your MySQL server.&lt;br /&gt;
* Run the CLI script to convert to the new Character set and Collation (requires Moodle 3.1.5, 3.2.2 or newer): &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ php admin/cli/mysql_collation.php --collation=utf8mb4_unicode_ci&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: For large sites, this script will be slow. It is recommended to dump and reimport your data according to https://docs.moodle.org/310/en/Converting_your_MySQL_database_to_UTF8#Default_Mysql_character_set&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Adjust the $CFG-&amp;gt;dboptions Array in your &#039;&#039;&#039;config.php&#039;&#039;&#039; to make sure that Moodle uses the right Collation when connecting to the MySQL Server: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dboptions = array(&lt;br /&gt;
  &amp;amp;hellip;&lt;br /&gt;
  &#039;dbcollation&#039; =&amp;gt; &#039;utf8mb4_unicode_ci&#039;,&lt;br /&gt;
  &amp;amp;hellip;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you only have access to the database command line (or something like phpmyadmin) you can try the following sql commands:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
SET GLOBAL innodb_file_format = barracuda&lt;br /&gt;
&lt;br /&gt;
SET GLOBAL innodb_file_per_table = 1&lt;br /&gt;
&lt;br /&gt;
SET GLOBAL innodb_large_prefix = &#039;on&#039;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Try adding some Emojis (e.g. 😂💩) to your Moodle site to verify that the upgrade was successful.&lt;br /&gt;
&lt;br /&gt;
[[Category:Environment|UTF-8]]&lt;br /&gt;
[[Category:UTF-8]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[es:MySQL soporte unicode completo]]&lt;br /&gt;
[[fr:Support unicode complet pour MySQL]]&lt;br /&gt;
[[de:MySQL Unicode Unterstützung]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Lesson_settings&amp;diff=128118</id>
		<title>Lesson settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Lesson_settings&amp;diff=128118"/>
		<updated>2017-06-06T06:04:06Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Allow Student Review  - Clarification of student review. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Lesson}}&lt;br /&gt;
=Lesson administration settings=&lt;br /&gt;
&lt;br /&gt;
This page explains the settings involved when first creating a lesson.&lt;br /&gt;
To add a lesson to your Moodle course page:&lt;br /&gt;
*With the editing turned on, in the section you wish to add your lesson, click the &amp;quot;Add an activity or resource&amp;quot; link (or, if not present, the &amp;quot;Add an activity&amp;quot; drop down menu) and choose &#039;&#039;Lesson&#039;&#039; All settings may expanded by clicking the &amp;quot;Expand all&amp;quot; link top right.&lt;br /&gt;
*In the &#039;&#039;&#039;General&#039;&#039;&#039; section, give your lesson a name, a description if needed, and tick the box if you wish that description displayed on the course page.&lt;br /&gt;
&lt;br /&gt;
==Appearance==&lt;br /&gt;
===Progress bar===&lt;br /&gt;
Choose this to show a bar at the bottom of the page showing how far into the lesson the student has got.&lt;br /&gt;
* For lessons containing &#039;&#039;&#039;only&#039;&#039;&#039; &#039;&#039;Content pages&#039;&#039;, once a lesson has been taken to the end, if that same lesson is re-taken, the progress bar will not be &amp;quot;reset&amp;quot;, i.e. it will show a 100% progress from page 1! &lt;br /&gt;
&lt;br /&gt;
* For lessons containing &#039;&#039;Question pages&#039;&#039; and set to &amp;quot;Re-take&amp;quot; &#039;&#039;&#039;Yes&#039;&#039;&#039;, the progress bar is always &amp;quot;reset&amp;quot; at 0% upon re-take.&lt;br /&gt;
&lt;br /&gt;
* Note that the Lesson Progress bar only works correctly for lessons with a &amp;quot;straightforward&amp;quot; navigation, such as page 1 -&amp;gt; page  2 -&amp;gt; page n -&amp;gt; end of lesson. It is not guaranteed to work with pages &amp;quot;jumping all over the place&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Display menu=== &lt;br /&gt;
Choose this when you want to show a list of the content page titles in the Lesson to the student.  Only those pages which have &amp;quot;Display in menu?&amp;quot; checked will display. The  menu will not display question pages.&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
&lt;br /&gt;
====Linked media====&lt;br /&gt;
[[File:pop-up file link.png|thumb|Link to pop-up]]&lt;br /&gt;
If you want to include a link to a media file for students to refer to, upload it here. A &#039;Click here to view&#039; link will be displayed in a block called &#039;Linked media&#039; on each page of the lesson.&lt;br /&gt;
&lt;br /&gt;
The width and height of the pop-up window may be set by an admin in &#039;&#039;Site administration &amp;gt; Plugins &amp;gt; Activity modules &amp;gt; Lesson&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====Display ongoing score====&lt;br /&gt;
Choose this to let students see their score as they work through the lesson.&lt;br /&gt;
&lt;br /&gt;
===Minimum grade to display menu===&lt;br /&gt;
Choose this if you want the student to go through the lesson once and get a grade before they can (on review) see and navigate through all the different pages.&lt;br /&gt;
====Slideshow====&lt;br /&gt;
&lt;br /&gt;
Slideshow height, width and background colour are set for the whole site by an administrator in  Site administration &amp;gt; Plugins &amp;gt; Activity modules &amp;gt; Lesson&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====Maximum Number of Answers====&lt;br /&gt;
Here you can set the default number of selection boxes available when you add or edit a question or content page. For instance, if you are only going to use Multiple Choice questions with 3 answers in your lesson, you might select 3. You can change the default here at any time to display more or less question answers or content choices.&lt;br /&gt;
:&#039;&#039;Note:&#039;&#039; This only impacts the editing screen. Changing from 4 to 2 will not remove or hide any answers previously entered from the student.&lt;br /&gt;
&lt;br /&gt;
====Use default feedback====&lt;br /&gt;
Every Moodle site has a standard response (feedback) when a student selects a correct or wrong answer in a lesson. Select &amp;quot;No&amp;quot; if you only what you put as a response for a specific question&#039;s answer to display. In this case, when you leave the response to a question blank, the student will not see any comment about their answer.  The typical Moodle standard responses are: &amp;quot;That&#039;s the correct answer&amp;quot; or &amp;quot;That&#039;s the wrong answer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
====Link to next activity====&lt;br /&gt;
Choose this to give students a link to another activity when they reach the end of the lesson. &#039;&#039;(Note: this can also be achieved using [[Conditional activities]])&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Availability==&lt;br /&gt;
&lt;br /&gt;
===Available from/Deadline===&lt;br /&gt;
Here you can set a start and end date and time for your Lesson.&lt;br /&gt;
&lt;br /&gt;
===Time limit=== &lt;br /&gt;
&lt;br /&gt;
This allows you to set a time limit on the lesson which can now be seconds, minutes, hours, days or weeks. Students will see a countdown counter in a block as they work.&lt;br /&gt;
&lt;br /&gt;
[[File:lessontimeremaining.png]]&lt;br /&gt;
&lt;br /&gt;
The timer does not stop them doing the lesson when the time is up, but  correct answers are no longer scored.&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
&lt;br /&gt;
====Password protected lesson====&lt;br /&gt;
*Change to &amp;quot;Yes&amp;quot;  and enter the password if you want students only to access it when they know the password.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Flow control==&lt;br /&gt;
&lt;br /&gt;
===Allow Student Review===&lt;br /&gt;
This puts a &amp;quot;Review Lesson&amp;quot; button on the last screen of the lesson to encourage the students to navigate through the lesson again. If the lesson contains questions then the review will start from the first question, otherwise the review will start from the first content page.&lt;br /&gt;
:Note that the students will not be able to &#039;&#039;change&#039;&#039; their answers, only &#039;&#039;view&#039;&#039; them.&lt;br /&gt;
&lt;br /&gt;
===Provide option to try a question again===&lt;br /&gt;
*This displays a button after an incorrectly answered question so that the student can try again (but not get credit for it)&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; Leave this off if you are using essay questions. &lt;br /&gt;
===Maximum Number of Attempts===&lt;br /&gt;
*Decide here how many times you want students to be able to attempt each question. When they reach the maximum, they will be taken automatically to the next page.&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039;&#039;&#039; this setting works in combination with the above setting, or independently. &lt;br /&gt;
&lt;br /&gt;
*When &#039;provide an option to try again&#039; is set to No, students will be able to retake the question as many times as it is set here, with a score penalty.&lt;br /&gt;
&lt;br /&gt;
*When &#039;provide an option to try again&#039; is set to Yes, then students will be able to retake the question as many times as it set here without a score penalty. In this case an extra dialogue appears.&lt;br /&gt;
&lt;br /&gt;
Consequently when the relevant jump &#039;this page&#039; is used in wrong answer while the &#039;provide an option to try again&#039; is set to No and &#039;maximum number of attempts&#039; is set to 1, a student that will answer wrongly will be moved into the next page, since he/she has the change to try the question just once. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Tip:&#039;&#039;&#039;&#039;&#039; Ensure you check lesson using a real student account, as the teacher preview or the &#039;switch role to student&#039; may not give you the exact picture.&lt;br /&gt;
&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
&lt;br /&gt;
====Action after a Correct Answer====&lt;br /&gt;
Choose here where you want a student to be sent to if they get a question right. See [[Using Lesson]] for more details on this setting. The options are:&lt;br /&gt;
**the next part of the Lesson (default setting)&lt;br /&gt;
**a random, unexpected page&lt;br /&gt;
**a random page which they have not yet answered.&lt;br /&gt;
====Number of pages to show====&lt;br /&gt;
You only need this if you have set &amp;quot;Action after a correct answer&amp;quot; to show an unseen or unanswered page. Otherwise, all pages will be seen&lt;br /&gt;
&lt;br /&gt;
==Grade==&lt;br /&gt;
&lt;br /&gt;
Set a grade and grade category here, along with a &amp;quot;Grade to pass&amp;quot; which may be connected with [[Activity completion]] and [[Restrict access]] such that a student will not be able to access a follow up activity until they have obtained the required grade in the lesson.&lt;br /&gt;
&lt;br /&gt;
===Practice lesson===&lt;br /&gt;
&lt;br /&gt;
Practice lessons are now saved; this means they will appear in the reports .You must enable the &amp;quot;Retakes allowed&amp;quot; setting if you want students to be able to attempt a practice lesson several times.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: If you are upgrading from an earlier version, be aware that all practice lessons will have &amp;quot; Re-takes allowed&amp;quot;  set to &amp;quot;Yes&amp;quot; . If you are restoring  a practice lesson made before this change, you may need to  modify the &amp;quot;Re-takes allowed&amp;quot; setting if needed.&lt;br /&gt;
&lt;br /&gt;
===Custom Scoring===&lt;br /&gt;
Use this to give a particular number score (negative or positive) to each answer&lt;br /&gt;
===Re-takes allowed===&lt;br /&gt;
Choose this if you want your students to be able to do the lesson more than once.&lt;br /&gt;
:Note that this setting only applies to lessons containing &#039;&#039;Question pages&#039;&#039;. Lessons consisting &#039;&#039;&#039;only&#039;&#039;&#039; of &#039;&#039;Content pages&#039;&#039; can be re-taken even if &#039;Re-takes allowed&#039; is set to &#039;&#039;No&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Show more===&lt;br /&gt;
Depending on the what the administrator has specified as &#039;Advanced&#039;, other settings will be displayed by clicking a &#039;Show more&#039; link:&lt;br /&gt;
====Handling of re-takes====&lt;br /&gt;
If you allow your students to re-take the lesson, then decide here if the grade for all lesson attempts is the mean or the maximum.&lt;br /&gt;
&lt;br /&gt;
:Note that the Question Analysis always uses the answers from the first tries of the lesson. Re-takes by students are ignored.&lt;br /&gt;
&lt;br /&gt;
====Minimum Number of Questions====&lt;br /&gt;
Set the minimum number of questions that will be used to calculate a student&#039;s score. Students will be told how many they have answered and how many more they need to answer.&lt;br /&gt;
*If you are using Content pages, then set this to 0.&lt;br /&gt;
*If you use this setting, then add some explanatory text at the start of the lesson so the student knows the minimum number of questions they must answer to receive a grade.&lt;br /&gt;
&lt;br /&gt;
==Common module settings==&lt;br /&gt;
See [[Common module settings]]&lt;br /&gt;
&lt;br /&gt;
==Access restrictions==&lt;br /&gt;
[[Restrict access]] must be turned on in the site settings for this to appear.&lt;br /&gt;
(These settings are collapsed by default)&lt;br /&gt;
&lt;br /&gt;
*Grade - limit to overall grade or specific grade on another activity&lt;br /&gt;
*Group - limit to specific group&lt;br /&gt;
*Groupings - limit to specific groupings&lt;br /&gt;
*User profile - limit based upon user profile fields&lt;br /&gt;
*Restriction set - nest restrictions&lt;br /&gt;
&lt;br /&gt;
==Activity completion==&lt;br /&gt;
[[Activity completion]] must be turned on in the site settings for this to appear.&lt;br /&gt;
(These settings are collapsed by default)&lt;br /&gt;
*Completion tracking - 3 options&lt;br /&gt;
*Required view&lt;br /&gt;
*Required grade&lt;br /&gt;
*Required end reached&lt;br /&gt;
*Required time spent&lt;br /&gt;
*Expected completion on&lt;br /&gt;
&lt;br /&gt;
==User and group overrides==&lt;br /&gt;
&lt;br /&gt;
When a lesson has been created, it is possible to overrride certain settings for individuals and groups from Lesson administration. In situations where two group overrides may apply to a single user, the most lenient date is used. For &amp;quot;Available from&amp;quot; dates, this means the earliest possible date is used, for &amp;quot;Deadline&amp;quot; dates, this means that the latest possible date is used. Note also that if there exists a user override for a student, it will always take precedence over any group overrides.&lt;br /&gt;
&lt;br /&gt;
It is possible to override passwords, availability/deadline, time limits and question retries and lesson retakes.&lt;br /&gt;
&lt;br /&gt;
Selecting one of the options, for example &#039;User&#039; will display a button to click. From the next screen you can choose the user or group to override and the settings you wish to override:&lt;br /&gt;
&lt;br /&gt;
[[File:lessonoverrideuser.png]]&lt;br /&gt;
&lt;br /&gt;
When the override is saved, it is displayed on a screen along with any other overrides previously set:&lt;br /&gt;
&lt;br /&gt;
[[File:lessonoverrideexamples.png]]&lt;br /&gt;
&lt;br /&gt;
==Site administration settings==&lt;br /&gt;
&lt;br /&gt;
*The administrator can change the lesson&#039;s default settings and decide which lesson features to display to teachers in courses, and which features are &#039;Advanced&#039;.&lt;br /&gt;
*Features which have the &#039;Advanced&#039; box ticked only display when teachers click a &#039;Show more&#039; link.&lt;br /&gt;
*This is useful for simplifying the lesson for teachers when it is first set up.&lt;br /&gt;
*The lesson settings can be reviewed from &#039;&#039;Site administration &amp;gt; Plugins &amp;gt; Activity modules &amp;gt; Lesson.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://youtu.be/cUDV0WE5ZYY Moodle 2.x Lesson (part 1)]  MoodleBites video on YouTube &lt;br /&gt;
*[http://youtu.be/Mfj-8w-Ze0A Moodle 2.x Lesson (part 2)]  MoodleBites video on YouTube &lt;br /&gt;
*[http://youtu.be/jXjqHtgC9c0 Moodle 2.x Lesson (part 3)]  MoodleBites video on YouTube &lt;br /&gt;
&lt;br /&gt;
[[de:Lektion konfigurieren]]&lt;br /&gt;
[[fr:Ajouter/modifier une leçon]]&lt;br /&gt;
[[ja:レッスンの設定]]&lt;br /&gt;
[[es:Configuraciones de lección]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Installation_quick_guide&amp;diff=127666</id>
		<title>Installation quick guide</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Installation_quick_guide&amp;diff=127666"/>
		<updated>2017-05-08T01:36:55Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Create a database UTF-8 update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Installing Moodle}}&lt;br /&gt;
&#039;&#039;This page is intended for administrators who are experienced with installing web server applications and are in a hurry to get up and running. Otherwise please see [[Installing Moodle]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Basic Requirements==&lt;br /&gt;
&lt;br /&gt;
* You will need a working web server (e.g. [[Apache]]), a database (e.g. [[MySQL]], [[MariaDB]] or [[PostgreSQL]]) and have [[PHP]] configured. See the [{{Release notes}} release notes] in the dev docs for software requirements.&lt;br /&gt;
* Moodle requires a number of [[PHP]] extensions. However, Moodle checks early in the installation process and you can fix the problem and re-start the install script if any are missing.&lt;br /&gt;
* If you want Moodle to send email (you probably do) you need a working Sendmail (Unix/Linux) on your server or access to an SMTP mail server.&lt;br /&gt;
&lt;br /&gt;
==Getting Moodle==&lt;br /&gt;
&lt;br /&gt;
You have two basic options:&lt;br /&gt;
* Download your required version from http://moodle.org/downloads ... OR&lt;br /&gt;
* Pull the code from the Git repository (recommended for developers and also makes upgrading very simple):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone -b MOODLE_{{Version2}}_STABLE git://git.moodle.org/moodle.git &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
...this fetches a complete copy of the Moodle repository and then switches to the {{Version}} Stable branch. &lt;br /&gt;
&lt;br /&gt;
See [[Git_for_Administrators|Git for Administrators ]] for details on using Git to install Moodle code.&lt;br /&gt;
&lt;br /&gt;
Note: Only download Moodle from one of the moodle.org sources. Other versions (e.g. control panel based installers, Linux distribution repositories) cannot be guaranteed to work properly, be upgradable or be supportable.&lt;br /&gt;
&lt;br /&gt;
==Create a database==&lt;br /&gt;
&lt;br /&gt;
* Using your chosen database server, create a new empty database. The default encoding must be UTF8. For example, using MySQL:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create a user/password combination with appropriate permissions for the database. For example (MySQL again):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql&amp;gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,CREATE TEMPORARY TABLES,DROP,INDEX,ALTER ON moodle.* TO &#039;moodleuser&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;yourpassword&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes: It is important to GRANT ON moodle.* as the database name including the &#039;.*&#039; and not just the bare database name. Save this password you use for the Moodle user, since you will need it later in the install.&lt;br /&gt;
&lt;br /&gt;
==Create data directory==&lt;br /&gt;
&lt;br /&gt;
* Create an empty directory to hold Moodle files. It &#039;&#039;&#039;must not&#039;&#039;&#039; be in the area served by the web server and must have permissions so that the web server user can write to it. Typically, either make it owned by the web server user or give it write permissions for &#039;everyone&#039;.&lt;br /&gt;
&lt;br /&gt;
==Install Moodle code==&lt;br /&gt;
&lt;br /&gt;
* If you downloaded the zip or tgz file earlier, then unzip / untar / move / copy the Moodle code (obtained above) so that it will be served by your web server (e.g. on Debian based Linux, move to /var/www/moodle)&lt;br /&gt;
* Check the permissions and make sure that the web server does &#039;&#039;&#039;not&#039;&#039;&#039; have permissions to write to any of the files in the Moodle code directories (a very common root cause of sites being hacked).&lt;br /&gt;
* If you need to, configure your web server to serve the Moodle site with your chosen URL.&lt;br /&gt;
&lt;br /&gt;
==Configure Moodle==&lt;br /&gt;
&lt;br /&gt;
* In the Moodle code directory, find the file &#039;&#039;config-dist.php&#039;&#039; and copy it to a new file called &#039;&#039;config.php&#039;&#039; (but read next step, &#039;Install Moodle&#039;, first).&lt;br /&gt;
* Edit config.php with your favourite editor and change the appropriate settings to point to your site, directories and database. &#039;&#039;Note: the Moodle install script will create config.php for you if it does not exist but make sure you (re-)set permissions appropriately afterwards&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Install Moodle==&lt;br /&gt;
&lt;br /&gt;
* Go to the URL for your moodle site in a browser (installation will complete automatically) or run the command line version at (requires cli version of PHP):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/usr/bin/php /path/to/moodle/admin/cli/install.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The CLI creates the config.php for you and will not run if you created one in the previous step.&lt;br /&gt;
* After completing the install make sure your file permissions are ok for the Moodle program files (not writeable by web server) and the Moodle data files (writeable by web server).&lt;br /&gt;
&lt;br /&gt;
==Set up cron==&lt;br /&gt;
&lt;br /&gt;
You will need a cron job to run periodically. It is recommended that &#039;&#039;the cron is run every minute&#039;&#039;, as required for asynchronous activity deletion when using the [[Recycle bin|recycle bin]]. A typical Unix cron entry will be as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* * * * *    /usr/bin/php /path/to/moodle/admin/cli/cron.php &amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You do not set up Cron inside Moodle but on your server.  Your site &#039;&#039;&#039;will not work properly&#039;&#039;&#039; unless cron is running regularly. It is very important you do not skip this step.&lt;br /&gt;
&lt;br /&gt;
See [[Cron]] for details.&lt;br /&gt;
&lt;br /&gt;
==Congratulations!==&lt;br /&gt;
&lt;br /&gt;
You are now ready to use your Moodle site.&lt;br /&gt;
&lt;br /&gt;
If you run into problems, check the [[Installation FAQ]] and visit the [http://moodle.org/mod/forum/view.php?id=28 Installation help forum].&lt;br /&gt;
&lt;br /&gt;
[[Category:Quick guide]]&lt;br /&gt;
&lt;br /&gt;
[[ja:インストールクイックスタート]]&lt;br /&gt;
[[de:Installation in Kürze]]&lt;br /&gt;
[[fr:Installation_rapide]]&lt;br /&gt;
[[es:Inicio_Rápido_de_Instalación]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=RedHat_Linux_installation&amp;diff=127665</id>
		<title>RedHat Linux installation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=RedHat_Linux_installation&amp;diff=127665"/>
		<updated>2017-05-08T01:25:38Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Setup MySQL - UTF-8 update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note : These instructions apply to RedHat version 8. They have also been found to work for RedHat 9.0 and for Fedora Core 1 and 2. &#039;&#039;&#039;Fedora Core 3 requires the php-gd package in addition to php.&#039;&#039;&#039; I see no reason why they should not work for later versions. In addition, later distributions of Fedora (after 7) contain a moodle yum package. Installation is as easy as &#039;&#039;&#039;yum install moodle&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Redhat installation considerations: There are many installation options available when installing Redhat. I assume that you are installing on a server and will have selected a Server type install. There is however no reason why this should not work on a desktop or Workstation installation.&lt;br /&gt;
&lt;br /&gt;
== Make sure you have installed the following packages ==&lt;br /&gt;
(You will need to select the option to customize the default set of packages on installation OR bring up the package manager by putting disk 1 back in the drive for an existing system):&lt;br /&gt;
&lt;br /&gt;
* X Windows System (not vital but easier)&lt;br /&gt;
* Gnome or KDE desktop environment (as above)&lt;br /&gt;
* Server Configuration Tools&lt;br /&gt;
* Web Server&lt;br /&gt;
** Click &amp;quot;Details&amp;quot; and make sure all PHP modules are ticked (except ODBC and PGSQL, they&#039;re not neccesary)&lt;br /&gt;
** make sure not to miss the MYSQL-PHP module (not installed by default)&lt;br /&gt;
* SQL Database&lt;br /&gt;
** Click &amp;quot;Details&amp;quot; and tick MySQL server box&lt;br /&gt;
* Also make sure you set up the firewall. You probably only need to enable HTTP (and perhaps FTP and SSH) access to your server machine, unless you know different.&lt;br /&gt;
&lt;br /&gt;
If you want a minimal system, startging with RHEL6 (and clones) there is the possiblity of installing a minimal system.&lt;br /&gt;
&lt;br /&gt;
== Configure hostname and domain name==&lt;br /&gt;
&lt;br /&gt;
Type system-config-network to open the GUI editor.  Click on the DNS tab. In the &amp;quot;DNS Search Path&amp;quot; fill in your domain name for example myuniversity.edu. Now ensure the &amp;quot;Hostname&amp;quot; contains the computer name you will use and click activate to make changes&lt;br /&gt;
&lt;br /&gt;
== A word about SELinux ==&lt;br /&gt;
Default RedHat Enterprise Linux comes with SELinux set to enforcing. If you are not used to SELinux and setting permissions it&#039;s (maybe less secure but) often easier to lower the SELinux level to permissive, see the CentOS [https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Security-Enhanced_Linux/sect-Security-Enhanced_Linux-Working_with_SELinux-Changing_SELinux_Modes.html]&lt;br /&gt;
&lt;br /&gt;
== A word about the PHP packages in RHEL ==&lt;br /&gt;
RedHat EL - or &#039;the upstream vendor&#039; if you are using a clone - will not introduce newer PHP packages unless there is an exception (php53 in EL5.6+). Moodle has quite a some PHP dependencies which cannot be fullfilled solely by installing all RHEL-provided packages.&lt;br /&gt;
&lt;br /&gt;
You have therefore to make a choice:&lt;br /&gt;
* Use RH and pay attention your Moodle version supports it + PHP modules from and maintain them on your own&lt;br /&gt;
* Install the whole (latest) PHP from source on your own (and maintain it)&lt;br /&gt;
* Install PHP packages from a third party repo (but you won&#039;t get support from Redhat if you run into problems):&lt;br /&gt;
** [rpms.famillecollet.com] Maintains recent MySQL and PHP packages for supported EL version (a EPEL contributor)&lt;br /&gt;
** RPMFusion and others also have newer PHP packages&lt;br /&gt;
&lt;br /&gt;
== Download Moodle==&lt;br /&gt;
(I will install under /usr/moodle, data in /usr/moodle_data)&lt;br /&gt;
&lt;br /&gt;
* Download your favourite version of Moodle from moodle.org (.zip archive is easiest)&lt;br /&gt;
* as Root create folder under /usr and copy zip&lt;br /&gt;
** su&lt;br /&gt;
** mkdir /usr/moodle&lt;br /&gt;
** mkdir /usr/moodle_data&lt;br /&gt;
** cp moodle_111.zip /usr/moodle&lt;br /&gt;
* If you prefer you can install the GIT version directly for all the latest features. Instead of downloading and copying the zip file..&lt;br /&gt;
** cd /usr/moodle&lt;br /&gt;
** git clone git://git.moodle.org/moodle.git&lt;br /&gt;
* Or if you prefer you can install the CVS version directly for all the latest features. Instead of downloading and copying the zip file..&lt;br /&gt;
** cd /usr/moodle&lt;br /&gt;
** cvs -d:pserver:anonymous@uk.cvs.moodle.org:/cvsroot/moodle login&lt;br /&gt;
** cvs -z3 -d:pserver:anonymous@uk.cvs.moodle.org:/cvsroot/moodle co moodle&lt;br /&gt;
&lt;br /&gt;
== Unpack and set file permission etc ==&lt;br /&gt;
&lt;br /&gt;
* Still as root we unpack moodle and rename to something appropiate (I have multiple moodle installs, hence this setup). I will call this install mymoodle.&lt;br /&gt;
** cd /usr/moodle&lt;br /&gt;
** unzip moodle_xxx.zip&lt;br /&gt;
** mv moodle mymoodle&lt;br /&gt;
*** (optional step - I have more than one install under /usr/moodle)&lt;br /&gt;
** mkdir /usr/moodle_data/mymoodle&lt;br /&gt;
*** (same name as the moodle install above)&lt;br /&gt;
** chown -R apache:apache /usr/moodle&lt;br /&gt;
*** (! Giving Apache full rights to your Moodle programs is not secure. Check out the forums for recomendations on how to secure a production environment.)&lt;br /&gt;
** chown -R apache:apache /usr/moodle_data&lt;br /&gt;
&lt;br /&gt;
== Setup config.php ==&lt;br /&gt;
&lt;br /&gt;
* Still as root copy and edit the config file, you should know the host/domain name for your server&lt;br /&gt;
** cd /usr/moodle/mymoodle&lt;br /&gt;
** cp config-dist.php config.php&lt;br /&gt;
** vi config.php (or whatever your favourite editor is!)&lt;br /&gt;
* Your config.php settings should be something like...&lt;br /&gt;
** dbtype = &amp;quot;mysqli&amp;quot;&lt;br /&gt;
** dbhost = &amp;quot;localhost&amp;quot;&lt;br /&gt;
** dbname = &amp;quot;mymoodle&amp;quot;&lt;br /&gt;
** dbuser = &amp;quot;moodleuser&amp;quot;&lt;br /&gt;
** dbpass = &amp;quot;moodlepass&amp;quot; (&amp;lt;-- better make this something of your own)&lt;br /&gt;
** prefix = &amp;quot;&amp;quot;&lt;br /&gt;
*** (keep the default &#039;mdl_&#039; prefix if you plan on sharing the database with other applications)&lt;br /&gt;
** wwwroot = &amp;quot;http://myhost.mydomain/mymoodle&amp;quot;&lt;br /&gt;
*** (If you only want to try moodle out and will not be accessing it from other machines you can use &amp;quot;http://localhost/mymoodle&amp;quot;)&lt;br /&gt;
** dirroot = &#039;/usr/moodle/mymoodle&#039;&lt;br /&gt;
** dataroot = &#039;/usr/moodle_data/mymoodle&#039;&lt;br /&gt;
* Save your changes and exit from the editor&lt;br /&gt;
&lt;br /&gt;
== Setup MySQL ==&lt;br /&gt;
&lt;br /&gt;
* First you need to get the MySQL daemon running, it is not running by default.&lt;br /&gt;
** On the Desktop find and launch &amp;quot;Services&amp;quot; (on KDE and Gnome it&#039;s under System Settings=&amp;gt;Server Settings=&amp;gt;Services, but you might have to hunt around).&lt;br /&gt;
** Tick the box for MySQL and (with it selected) press the Start icon - ensure it starts up&lt;br /&gt;
** Choose &amp;quot;Save Changes&amp;quot; from the menu, and exit the program.&lt;br /&gt;
* If you haven&#039;t yet, as root, change the MySQL root password&lt;br /&gt;
** mysqladmin -u root password mysqlpass (&amp;lt;-- should change this to something of your own)&lt;br /&gt;
* Next, set up the MySQL database (see http://moodle.org/doc/?file=install.html#Database for more details)&lt;br /&gt;
* Launch MySQL as root&lt;br /&gt;
** mysql -u root -p&lt;br /&gt;
*** (at the password prompt, enter the password from above)&lt;br /&gt;
* At the &#039;&amp;gt;&#039; MySQL prompt, enter the following commands (MySQL commands are ended with a &#039;;&#039;)&lt;br /&gt;
** CREATE DATABASE mymoodle CHARSET &#039;utf8mb4&#039;;&lt;br /&gt;
*** (the name &#039;mymoodle&#039; is the same name as the database from Step 4)&lt;br /&gt;
** GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER ON mymoodle.*&lt;br /&gt;
*** (as above, &#039;mymoodle&#039; is from Step 4)&lt;br /&gt;
** TO moodleuser@localhost IDENTIFIED BY &#039;moodlepass&#039;;&lt;br /&gt;
*** (&#039;moodleuser&#039; and &#039;moodlepass&#039; are from Step 4)&lt;br /&gt;
** flush privileges;&lt;br /&gt;
** quit&lt;br /&gt;
* (! Consider MySQL security - not covered here. If you run a firewall, you don&#039;t have too much to worry about.)&lt;br /&gt;
&lt;br /&gt;
== Setup Apache ==&lt;br /&gt;
&lt;br /&gt;
* Edit the Apache configuration file at /etc/httpd/conf/httpd.conf&lt;br /&gt;
* Right at the end of the file add the following lines: (once again &#039;mymoodle&#039; as from Step 3)&lt;br /&gt;
** &amp;lt;Directory &amp;quot;/usr/moodle/mymoodle&amp;quot;&amp;gt;&lt;br /&gt;
** DirectoryIndex index.php&lt;br /&gt;
** AcceptPathInfo on&lt;br /&gt;
** AllowOverride None&lt;br /&gt;
** Options None&lt;br /&gt;
** Order allow,deny&lt;br /&gt;
** Allow from all&lt;br /&gt;
** &amp;lt;/Directory&amp;gt;&lt;br /&gt;
** Alias /mymoodle &amp;quot;/usr/moodle/mymoodle&amp;quot;&lt;br /&gt;
* Don&#039;t insert a space in &amp;quot;allow,deny&amp;quot; (common mistake!)&lt;br /&gt;
* You might also want to run through the rest of the config file and make some other (obvious) changes - administrator email and suchlike. Not vital though.&lt;br /&gt;
* Run the Services application (same as for Mysql) - tick and start &amp;quot;httpd&amp;quot;, then save changes and exit.&lt;br /&gt;
&lt;br /&gt;
== Set up the cron job ==&lt;br /&gt;
&lt;br /&gt;
As root user edit the /etc/crontab file using vi (or another editor) OR you can add a line to the root user&#039;s &amp;quot;personal&amp;quot; crontab (don&#039;t do both!).&lt;br /&gt;
&lt;br /&gt;
* If you wish to place an entry in your root user&#039;s crontab use:&lt;br /&gt;
** crontab -e&lt;br /&gt;
** Add the following line:&lt;br /&gt;
*** */5 * * * * /usr/bin/wget -O /dev/null http://localhost/mymoodle/admin/cron.php&lt;br /&gt;
**** (change the URL as appropriate for your site)&lt;br /&gt;
---&lt;br /&gt;
* If you wish to add an entry in /etc/crontab:&lt;br /&gt;
* Open the /etc/crontab file in an editor (vi).&lt;br /&gt;
* Add the following line:&lt;br /&gt;
** */5 * * * * root /usr/bin/wget -O /dev/null http://localhost/mymoodle/admin/cron.php&lt;br /&gt;
*** (change the URL as appropriate for your site)&lt;br /&gt;
---&lt;br /&gt;
* In either case, don&#039;t forget to save the file and exit (in vi that is &amp;lt;Esc&amp;gt;, then &#039;:wq&#039;)&lt;br /&gt;
&lt;br /&gt;
== Try your new installation ==&lt;br /&gt;
&lt;br /&gt;
http://myhost.mydomain/mymoodle/admin&lt;br /&gt;
&lt;br /&gt;
or, if you are running the browser on the same machine&lt;br /&gt;
&lt;br /&gt;
http://localhost/mymoodle/admin&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[pl:Instalacja_w_RedHat]]&lt;br /&gt;
&lt;br /&gt;
== Reference ==&lt;br /&gt;
Please also see these discussion for GD:&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=MySQL&amp;diff=127632</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=MySQL&amp;diff=127632"/>
		<updated>2017-05-05T02:19:52Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Installing MySQL - minor UTF-8 update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Installing Moodle}}&lt;br /&gt;
MySQL is one of the supported databases that underpins a Moodle installation. &lt;br /&gt;
&lt;br /&gt;
== Installing MySQL ==&lt;br /&gt;
&lt;br /&gt;
* If you are running Linux your preference should be to install using your distributions package manager. This ensures you will get any available updates.  However, you can also use apt-get or yum depending on the distribution that you are running.&lt;br /&gt;
* There are installers available for most popular operating systems at http://www.mysql.com/downloads/mysql/.&lt;br /&gt;
* It is possible and reasonably straightforward to build mysql from source but it is not recommended (the pre-built binaries are supposedly better optimised).&lt;br /&gt;
* Make sure you set a password for the &#039;root&#039; user (see http://dev.mysql.com/doc/refman/5.0/en/default-privileges.html).&lt;br /&gt;
* Consider installing and configuring my.cnf (the MySQL settings file) to suit your needs. The default configuration is usually very conservative in respect of memory usage versus performance. Increase the &#039;max_allowed_packet&#039; setting to at least 4 megabytes. Also make sure that your collation and character set is using full UTF-8 support. Please view [[MySQL_full_unicode_support#Steps_to_upgrade]].&lt;br /&gt;
* If you are going to use Master/Slave replication, you must add binlog_format = &#039;ROW&#039; into your my.cnf within [mysqld]. Otherwise, Moodle will not be able to write to the database.&lt;br /&gt;
&lt;br /&gt;
== Creating Moodle database ==&lt;br /&gt;
&lt;br /&gt;
These are the steps to create an empty Moodle database. Substitute your own database name, user name and password as appropriate.&lt;br /&gt;
&lt;br /&gt;
The instructions assume that the web server and MySQL server are on the same machine. In this case the &#039;dbhost&#039; is &#039;localhost&#039;. If they are on different machines substitute the name of the web server for &#039;localhost&#039; in the following instructions and the &#039;dbhost&#039; setting will be the name of the database server. &lt;br /&gt;
Databases have a &amp;quot;Character set&amp;quot; and a &amp;quot;Collation&amp;quot;. For Moodle the Character set should be &#039;&#039;&#039;utf8&#039;&#039;&#039; and the Collation &#039;&#039;&#039;utf8_unicode_ci&#039;&#039;&#039;. You may get the option to set these values when you create the database. If you are not given a choice, the default options are probably good. An install on an old server may have the wrong settings.&lt;br /&gt;
&lt;br /&gt;
=== Command line === &lt;br /&gt;
&lt;br /&gt;
* To create a database using the &#039;mysql&#039; command line client, first log into MySQL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p&lt;br /&gt;
Enter password: &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Enter the password you previously set - or been given - for the MySQL &#039;root&#039; user). After some pre-amble this should take you to the &#039;&#039;mysql&amp;gt;&#039;&#039; prompt.&lt;br /&gt;
* Create a new database (called &#039;moodle&#039; - substitute your own name if required).  We recommend you use &#039;&#039;&#039;utf8mb4_unicode_ci&#039;&#039;&#039; for Collation.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql&amp;gt; CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Add a user/password with the minimum needed permissions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql&amp;gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,CREATE TEMPORARY TABLES,DROP,INDEX,ALTER ON moodle.* TO moodleuser@localhost IDENTIFIED BY &#039;yourpassword&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
...which creates a user called &#039;moodleuser&#039; with a password &#039;yourpassword&#039;. Make sure you invent a strong password and resist the temptation to &#039;GRANT ALL&#039;.&lt;br /&gt;
&lt;br /&gt;
=== phpMyAdmin ===&lt;br /&gt;
&lt;br /&gt;
[http://www.phpmyadmin.net/ phpMyAdmin] is a web based administration tool for MySQL. If this is available you can use it to create a new database. Make sure that you select &#039;UTF8&#039; as the default character set.&lt;br /&gt;
&lt;br /&gt;
==Which database belongs to which Moodle==&lt;br /&gt;
If you have installed several Moodle installations on the same server, there will be several databases in your MySQL server. The names might be quite poor reflections of the content like  _mdl1 _mdl2 _mdl3 . So how do I see which database goes with which Moodle installation? You can go in with phpMyAdmin and in the various databases check for the table &amp;quot;mdl_course&amp;quot;. There you will easily see the name of that Moodle Installation. In table mdl_config you can see the Moodle version. The main URL for the site is not in the database except where there are absolute links.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[MariaDB]]&lt;br /&gt;
* [[MySQL full unicode support]]&lt;br /&gt;
* [http://www.mysql.com/ The MySQL homepage]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/MySQL Wikipedia article about &#039;&#039;MySQL&#039;&#039;]&lt;br /&gt;
* [http://forums.mysql.com/read.php?24,92131,92131 List of articles on MySQL performance tuning]&lt;br /&gt;
&lt;br /&gt;
[[Category:SQL databases]]&lt;br /&gt;
&lt;br /&gt;
[[ja:MySQL]]&lt;br /&gt;
[[de:MySQL]]&lt;br /&gt;
[[es:MySQL]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=MySQL&amp;diff=127631</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=MySQL&amp;diff=127631"/>
		<updated>2017-05-05T02:07:52Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: utf8mb4 update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Installing Moodle}}&lt;br /&gt;
MySQL is one of the supported databases that underpins a Moodle installation. &lt;br /&gt;
&lt;br /&gt;
== Installing MySQL ==&lt;br /&gt;
&lt;br /&gt;
* If you are running Linux your preference should be to install using your distributions package manager. This ensures you will get any available updates.  However, you can also use apt-get or yum depending on the distribution that you are running.&lt;br /&gt;
* There are installers available for most popular operating systems at http://www.mysql.com/downloads/mysql/.&lt;br /&gt;
* It is possible and reasonably straightforward to build mysql from source but it is not recommended (the pre-built binaries are supposedly better optimised).&lt;br /&gt;
* Make sure you set a password for the &#039;root&#039; user (see http://dev.mysql.com/doc/refman/5.0/en/default-privileges.html).&lt;br /&gt;
* Consider installing and configuring my.cnf (the MySQL settings file) to suit your needs. The default configuration is usually very conservative in respect of memory usage versus performance. Increase the &#039;max_allowed_packet&#039; setting to at least 4 megabytes. Also make sure that your collation is using full UTF-8 support. Please view [[MySQL_full_unicode_support#Steps_to_upgrade]].&lt;br /&gt;
* If you are going to use Master/Slave replication, you must add binlog_format = &#039;ROW&#039; into your my.cnf within [mysqld]. Otherwise, Moodle will not be able to write to the database.&lt;br /&gt;
&lt;br /&gt;
== Creating Moodle database ==&lt;br /&gt;
&lt;br /&gt;
These are the steps to create an empty Moodle database. Substitute your own database name, user name and password as appropriate.&lt;br /&gt;
&lt;br /&gt;
The instructions assume that the web server and MySQL server are on the same machine. In this case the &#039;dbhost&#039; is &#039;localhost&#039;. If they are on different machines substitute the name of the web server for &#039;localhost&#039; in the following instructions and the &#039;dbhost&#039; setting will be the name of the database server. &lt;br /&gt;
Databases have a &amp;quot;Character set&amp;quot; and a &amp;quot;Collation&amp;quot;. For Moodle the Character set should be &#039;&#039;&#039;utf8&#039;&#039;&#039; and the Collation &#039;&#039;&#039;utf8_unicode_ci&#039;&#039;&#039;. You may get the option to set these values when you create the database. If you are not given a choice, the default options are probably good. An install on an old server may have the wrong settings.&lt;br /&gt;
&lt;br /&gt;
=== Command line === &lt;br /&gt;
&lt;br /&gt;
* To create a database using the &#039;mysql&#039; command line client, first log into MySQL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p&lt;br /&gt;
Enter password: &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Enter the password you previously set - or been given - for the MySQL &#039;root&#039; user). After some pre-amble this should take you to the &#039;&#039;mysql&amp;gt;&#039;&#039; prompt.&lt;br /&gt;
* Create a new database (called &#039;moodle&#039; - substitute your own name if required).  We recommend you use &#039;&#039;&#039;utf8mb4_unicode_ci&#039;&#039;&#039; for Collation.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql&amp;gt; CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Add a user/password with the minimum needed permissions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql&amp;gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,CREATE TEMPORARY TABLES,DROP,INDEX,ALTER ON moodle.* TO moodleuser@localhost IDENTIFIED BY &#039;yourpassword&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
...which creates a user called &#039;moodleuser&#039; with a password &#039;yourpassword&#039;. Make sure you invent a strong password and resist the temptation to &#039;GRANT ALL&#039;.&lt;br /&gt;
&lt;br /&gt;
=== phpMyAdmin ===&lt;br /&gt;
&lt;br /&gt;
[http://www.phpmyadmin.net/ phpMyAdmin] is a web based administration tool for MySQL. If this is available you can use it to create a new database. Make sure that you select &#039;UTF8&#039; as the default character set.&lt;br /&gt;
&lt;br /&gt;
==Which database belongs to which Moodle==&lt;br /&gt;
If you have installed several Moodle installations on the same server, there will be several databases in your MySQL server. The names might be quite poor reflections of the content like  _mdl1 _mdl2 _mdl3 . So how do I see which database goes with which Moodle installation? You can go in with phpMyAdmin and in the various databases check for the table &amp;quot;mdl_course&amp;quot;. There you will easily see the name of that Moodle Installation. In table mdl_config you can see the Moodle version. The main URL for the site is not in the database except where there are absolute links.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[MariaDB]]&lt;br /&gt;
* [[MySQL full unicode support]]&lt;br /&gt;
* [http://www.mysql.com/ The MySQL homepage]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/MySQL Wikipedia article about &#039;&#039;MySQL&#039;&#039;]&lt;br /&gt;
* [http://forums.mysql.com/read.php?24,92131,92131 List of articles on MySQL performance tuning]&lt;br /&gt;
&lt;br /&gt;
[[Category:SQL databases]]&lt;br /&gt;
&lt;br /&gt;
[[ja:MySQL]]&lt;br /&gt;
[[de:MySQL]]&lt;br /&gt;
[[es:MySQL]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=MySQL_full_unicode_support&amp;diff=126930</id>
		<title>MySQL full unicode support</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=MySQL_full_unicode_support&amp;diff=126930"/>
		<updated>2017-02-24T06:43:30Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* File Format - minor heading change*/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==MySQL full unicode support==&lt;br /&gt;
&lt;br /&gt;
==UTF-8==&lt;br /&gt;
&lt;br /&gt;
UTF-8 is a character encoding that most websites use. It encodes each of the 1,112,064 valid code points. To store all of this information, four bytes is required. The most popular values are in the three byte region. MySQL by default only uses a three byte encoding and so values in the four byte range can not be stored. Any record that contains a four byte character will not be saved.&lt;br /&gt;
&lt;br /&gt;
MySQL does support full UTF-8 support. It requires certain settings to be configured. From Moodle 3.3 the default will be to use full UTF-8 for MySQL and MariaDB. Existing databases will still run with partial support, but it is recommended to move over to full support.&lt;br /&gt;
&lt;br /&gt;
Moodle does come with a Command Line Interface (CLI) script for converting to full UTF-8 for MySQL (and MariaDB). Before Moodle 3.3 this conversion tool would only change the collation to some variant of &#039;utf8_bin&#039;. &#039;utf8_unicode_ci&#039; was the recommended collation. We now recommend &#039;utf8mb4_unicode_ci&#039;. &#039;utf8mb4_unicode_ci&#039; supports 4 byte characters (utf8_unicode_ci only supports 3 byte characters) so four byte characters such as Asian characters and emoji should now be fully supported.&lt;br /&gt;
&lt;br /&gt;
This script will attempt to change the database collation, character set, and default table settings.&lt;br /&gt;
&lt;br /&gt;
===File format===&lt;br /&gt;
&lt;br /&gt;
To allow for large indexes on columns that are a varchar, a combination of settings needs to be set. The file format for the system needs to be using &amp;quot;Barracuda&amp;quot;. This allows for the row format to be set to &amp;quot;Compressed&amp;quot; or &amp;quot;Dynamic&amp;quot;. To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
===File per table===&lt;br /&gt;
&lt;br /&gt;
To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
===Large prefix===&lt;br /&gt;
&lt;br /&gt;
This in conjunction with the row format being either &amp;quot;Compressed&amp;quot; or &amp;quot;Dynamic&amp;quot; allows for large varchar indexes above 191 characters.&lt;br /&gt;
To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
==Steps to upgrade==&lt;br /&gt;
&lt;br /&gt;
* Most important. Please backup your database before making any changes or running the CLI script.&lt;br /&gt;
* Change configuration settings for MySQL (exactly the same for MariaDB). This step is optional. You can run the script and it will try and make these changes itself. If errors occur then try manually changing these settings as listed below.&lt;br /&gt;
** On Linux based systems you will want to alter my.cnf. This may be located in &#039;/etc/mysql/&#039;.&lt;br /&gt;
** Make the following alterations to my.cnf:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[client]&lt;br /&gt;
default-character-set = utf8mb4&lt;br /&gt;
&lt;br /&gt;
[mysqld]&lt;br /&gt;
innodb_file_format = Barracuda&lt;br /&gt;
innodb_file_per_table = 1&lt;br /&gt;
innodb_large_prefix&lt;br /&gt;
&lt;br /&gt;
character-set-client-handshake = FALSE&lt;br /&gt;
character-set-server = utf8mb4&lt;br /&gt;
collation-server = utf8mb4_unicode_ci&lt;br /&gt;
&lt;br /&gt;
[mysql]&lt;br /&gt;
default-character-set = utf8mb4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Restart your mysql server.&lt;br /&gt;
* Run the CLI script to convert to the new character set and collation: &#039;&#039;&#039;php admin/cli/mysql_collation --collation=utf8mb4_unicode_ci&#039;&#039;&#039;&lt;br /&gt;
* The upgrade is now complete.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=MySQL_full_unicode_support&amp;diff=126929</id>
		<title>MySQL full unicode support</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=MySQL_full_unicode_support&amp;diff=126929"/>
		<updated>2017-02-24T06:40:58Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: MySQL full UTF-8 support&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==MySQL full unicode support==&lt;br /&gt;
&lt;br /&gt;
==UTF-8==&lt;br /&gt;
&lt;br /&gt;
UTF-8 is a character encoding that most websites use. It encodes each of the 1,112,064 valid code points. To store all of this information, four bytes is required. The most popular values are in the three byte region. MySQL by default only uses a three byte encoding and so values in the four byte range can not be stored. Any record that contains a four byte character will not be saved.&lt;br /&gt;
&lt;br /&gt;
MySQL does support full UTF-8 support. It requires certain settings to be configured. From Moodle 3.3 the default will be to use full UTF-8 for MySQL and MariaDB. Existing databases will still run with partial support, but it is recommended to move over to full support.&lt;br /&gt;
&lt;br /&gt;
Moodle does come with a Command Line Interface (CLI) script for converting to full UTF-8 for MySQL (and MariaDB). Before Moodle 3.3 this conversion tool would only change the collation to some variant of &#039;utf8_bin&#039;. &#039;utf8_unicode_ci&#039; was the recommended collation. We now recommend &#039;utf8mb4_unicode_ci&#039;. &#039;utf8mb4_unicode_ci&#039; supports 4 byte characters (utf8_unicode_ci only supports 3 byte characters) so four byte characters such as Asian characters and emoji should now be fully supported.&lt;br /&gt;
&lt;br /&gt;
This script will attempt to change the database collation, character set, and default table settings.&lt;br /&gt;
&lt;br /&gt;
===File Format===&lt;br /&gt;
&lt;br /&gt;
To allow for large indexes on columns that are a varchar, a combination of settings needs to be set. The file format for the system needs to be using &amp;quot;Barracuda&amp;quot;. This allows for the row format to be set to &amp;quot;Compressed&amp;quot; or &amp;quot;Dynamic&amp;quot;. To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
===File per table===&lt;br /&gt;
&lt;br /&gt;
To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
===Large prefix===&lt;br /&gt;
&lt;br /&gt;
This in conjunction with the row format being either &amp;quot;Compressed&amp;quot; or &amp;quot;Dynamic&amp;quot; allows for large varchar indexes above 191 characters.&lt;br /&gt;
To enable this setting see the upgrade steps listed below.&lt;br /&gt;
&lt;br /&gt;
==Steps to upgrade==&lt;br /&gt;
&lt;br /&gt;
* Most important. Please backup your database before making any changes or running the CLI script.&lt;br /&gt;
* Change configuration settings for MySQL (exactly the same for MariaDB). This step is optional. You can run the script and it will try and make these changes itself. If errors occur then try manually changing these settings as listed below.&lt;br /&gt;
** On Linux based systems you will want to alter my.cnf. This may be located in &#039;/etc/mysql/&#039;.&lt;br /&gt;
** Make the following alterations to my.cnf:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[client]&lt;br /&gt;
default-character-set = utf8mb4&lt;br /&gt;
&lt;br /&gt;
[mysqld]&lt;br /&gt;
innodb_file_format = Barracuda&lt;br /&gt;
innodb_file_per_table = 1&lt;br /&gt;
innodb_large_prefix&lt;br /&gt;
&lt;br /&gt;
character-set-client-handshake = FALSE&lt;br /&gt;
character-set-server = utf8mb4&lt;br /&gt;
collation-server = utf8mb4_unicode_ci&lt;br /&gt;
&lt;br /&gt;
[mysql]&lt;br /&gt;
default-character-set = utf8mb4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Restart your mysql server.&lt;br /&gt;
* Run the CLI script to convert to the new character set and collation: &#039;&#039;&#039;php admin/cli/mysql_collation --collation=utf8mb4_unicode_ci&#039;&#039;&#039;&lt;br /&gt;
* The upgrade is now complete.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Database_activity_FAQ&amp;diff=126479</id>
		<title>Database activity FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Database_activity_FAQ&amp;diff=126479"/>
		<updated>2016-12-21T08:55:20Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Remove how to make an email address clickable - please do not do, it causes problems with search highlighting.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Database}}&lt;br /&gt;
==Where can I download additional database presets?==&lt;br /&gt;
&lt;br /&gt;
See the Presets and See also sections in [[Building Database]] for various places with presets for download.&lt;br /&gt;
&lt;br /&gt;
==How can I add to the list of database presets available for users to choose from?==&lt;br /&gt;
&lt;br /&gt;
[[File:databasepresetsnew.png|thumb|Database presets]]&lt;br /&gt;
&lt;br /&gt;
There is one default preset, Image Gallery. It is possible to create your own presets. &lt;br /&gt;
&lt;br /&gt;
When you have created your database that you desire to set as a preset; go to the &amp;quot;Presets&amp;quot; tab of the database and choose &amp;quot;Save as preset&amp;quot;. Give the preset a name and the database fields and templates will now be available as a preset for the rest of the site. You will need site admin rights to do this.&lt;br /&gt;
&lt;br /&gt;
Please see the [[Database presets]] for other available presets you can import into your system.&lt;br /&gt;
&lt;br /&gt;
==How can I create a database in which students can only view their own entries?==&lt;br /&gt;
&lt;br /&gt;
Either:&lt;br /&gt;
*Set up the database so that entries require approval. If the entries are never approved, then only the student that added a particular entry and the teachers can view it.&lt;br /&gt;
&lt;br /&gt;
Or:&lt;br /&gt;
*Set the group mode of the database to &amp;quot;Separate groups&amp;quot; and assign each student to a separate group.&lt;br /&gt;
&lt;br /&gt;
==How can I enable a sort function by clicking on the field headings?==&lt;br /&gt;
&lt;br /&gt;
For sorting, you need to manually create the link in the template around that heading.  To find the URL you need, you can do a sort using the menus and then look in the URLs. Take out everything but the d, sort and order parameters. For example,&lt;br /&gt;
&lt;br /&gt;
http://moodle.org/mod/data/view.php?d=13&amp;amp;sort=44&amp;amp;order=ASC&lt;br /&gt;
&lt;br /&gt;
http://moodle.org/mod/data/view.php?d=13&amp;amp;sort=44&amp;amp;order=DESC&lt;br /&gt;
&lt;br /&gt;
==How can I list database information horizontally instead of vertically?==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=74243 How can I list database information horizontally instead of vertically? Forum discussion]&lt;br /&gt;
&lt;br /&gt;
==Can&#039;t get columns to line up in list view==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=84050 Can&#039;t get columns to line up in list view forum discussion] including moodle.org presets for download&lt;br /&gt;
&lt;br /&gt;
==How can I make an Encyclopedia database preset?==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=87560 Encyclopedia database preset forum discussion] including encyclopedia-style preset for download&lt;br /&gt;
&lt;br /&gt;
==Is there a Time stamp for database entries?==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;##timeadded##&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==How can I make the title of an entry into a link?==&lt;br /&gt;
&lt;br /&gt;
To make the title of an entry in list view link to the single view, add the following code to the list template:&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a href=&amp;quot;##moreurl##&amp;quot;&amp;gt;[[Title]]&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==How can I hide a database entry which was previously approved?==&lt;br /&gt;
&lt;br /&gt;
Edit the list and or single template and add the undo approval tag (##disapprove##).&lt;br /&gt;
&lt;br /&gt;
==How can I add a default sort order of entries?==&lt;br /&gt;
&lt;br /&gt;
In the Fields tab, select a default sort field, choose ascending or descending then click the Save button.&lt;br /&gt;
&lt;br /&gt;
==Why is my database so slow to show each page?==&lt;br /&gt;
&lt;br /&gt;
Try to go to &amp;quot;Administration &amp;gt; Miscellaneous &amp;gt; XMLDB editor&amp;quot; and choose &amp;quot;Check Indexes&amp;quot;. If you have any missing indexes found; upgrade your Moodle to the latest weekly build of your version; re-run the test; backup your site database and then run the suggested SQL from the test on your site database. This should speed up your database activity load times.&lt;br /&gt;
&lt;br /&gt;
==How can I prevent students from adding entries?==&lt;br /&gt;
&lt;br /&gt;
An override may be used to close/archive a database activity, or have a database in which only teachers can add entries, but students can view the entries.&lt;br /&gt;
&lt;br /&gt;
# Follow the Permissions link in the settings block under Database activity administration&lt;br /&gt;
# Remove Student from the capability [[Capabilities/mod/data:writeentry|mod/data:writeentry]] by clicking the &#039;X&#039; next to it.&lt;br /&gt;
# Click the continue button to confirm.&lt;br /&gt;
&lt;br /&gt;
==How can I empty a database / remove records from a database en masse?==&lt;br /&gt;
In List view, there is a checkbox next to each entry. Click to select the ones you wish to delete and then click the &#039;Delete selected&#039; button. Alternatively, click the &#039;Select all&#039; and &#039;Delete all&#039; buttons. A warning message will appear asking you to confirm what you wish to delete.&lt;br /&gt;
&lt;br /&gt;
==I get an error message when importing a csv of entries==&lt;br /&gt;
One thing to try is to open up the csv file in Excel and save it again as a csv file - with another name - and then try importing it agin. Sometimes this just works :)&lt;br /&gt;
&lt;br /&gt;
==How do I export/import picture fields from a database activity from one course to another?==&lt;br /&gt;
You cannot export/import database entries with picture fields using the csv option, you will need to use Moodle&#039;s backup and restore functionality. Please note that you will need to backup and restore the database activity with user data in order for the entries to be carried over.&lt;br /&gt;
&lt;br /&gt;
==How can I show recently added entries in a block on the course page?==&lt;br /&gt;
&lt;br /&gt;
# Enable an RSS feed of recently added entries as described in [[Using Database]]&lt;br /&gt;
# Add a [[Remote RSS feeds block]] to the course page&lt;br /&gt;
# Add the database activity RSS feed to it&lt;br /&gt;
&lt;br /&gt;
==How can I have entries waiting for approval highlighted?==&lt;br /&gt;
&lt;br /&gt;
In Moodle 3.0 onwards, any newly created database activities show entries waiting for approval as highlighted for the teacher and the user who added the entry. &lt;br /&gt;
&lt;br /&gt;
For existing database activities, the highlighting can be added by editing the list and/or single template and resetting it, or adding some inline css:&lt;br /&gt;
&lt;br /&gt;
 class=&amp;quot;mod-data-default-template ##approvalstatus##&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Any further questions?==&lt;br /&gt;
&lt;br /&gt;
Please post in the [https://moodle.org/mod/forum/view.php?id=3505 Database forum] on moodle.org&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
Forum discussions:&lt;br /&gt;
&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=87005 New preset, please review, and make suggestions!] including FAQ preset for download&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=88727 Design a Database Preset for Document Sharing] including preset for download&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=55338 Look of the database module]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=61179 For those who want the display of Moodle Site&#039;s Modules and plugins]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=94854#p457252 Looking for some stellar examples of Moodle courses] including book reviews preset for download&lt;br /&gt;
*[https://moodle.org/mod/forum/discuss.php?d=268206 Database 2.7 List and Single View: Possible to view only entered fields?]&lt;br /&gt;
*[https://moodle.org/mod/forum/discuss.php?d=324452 Glossary autolink within a database activity]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[de:Datenbank FAQ]]&lt;br /&gt;
[[es:Actividad BasedeDatos FAQ]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Parent_role&amp;diff=126331</id>
		<title>Parent role</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Parent_role&amp;diff=126331"/>
		<updated>2016-12-07T05:27:48Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Assigning the parent to the student - Added step for clarification */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Roles}}&lt;br /&gt;
The role of &#039;&#039;&#039;Parent&#039;&#039;&#039; may be used to provide parents/mentors/tutors with permission to view certain information, such as activity reports, grades, blog entries and forum posts, about their children/mentees/tutees.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Creating a new role===&lt;br /&gt;
&lt;br /&gt;
#As an administrator, go to &#039;&#039;Administration &amp;gt; Site administration &amp;gt; Users &amp;gt; Permissions &amp;gt; Define roles&#039;&#039; and click the &amp;quot;Add a new role&amp;quot; button.&lt;br /&gt;
#For archtype  role choose &amp;quot;No role.&amp;quot;&lt;br /&gt;
#Give the role a short name (such as &amp;quot;Parent&amp;quot;, but it can be anything appropriate, such as tutor/mentor)&lt;br /&gt;
#Give the role a custom full name (such as &amp;quot;Parent&amp;quot;, but it can be anything appropriate, such as tutor/mentor)&lt;br /&gt;
#Under Context types where this role may be assigned check the &#039;&#039;&#039;user&#039;&#039;&#039; context.&lt;br /&gt;
#Under the heading of &#039;&#039;&#039;Course&#039;&#039;&#039;&lt;br /&gt;
#Change [[Capabilities/moodle/user:viewdetails|moodle/user:viewdetails]] to &#039;&#039;allow&#039;&#039; - to access the student&#039;s profile&lt;br /&gt;
#Under the heading of &#039;&#039;&#039;Users&#039;&#039;&#039;&lt;br /&gt;
#Change [[Capabilities/moodle/user:viewdetails|moodle/user:viewalldetails]] to &#039;&#039;allow&#039;&#039; - to view all aspects of the student&#039;s profile&lt;br /&gt;
#Change any/all of the following capabilities to &#039;&#039;allow&#039;&#039;&lt;br /&gt;
#*[[Capabilities/moodle/user:readuserblogs|moodle/user:readuserblogs]] - to read the student&#039;s blog entries&lt;br /&gt;
#*[[Capabilities/moodle/user:readuserposts|moodle/user:readuserposts]] - to read the student&#039;s forum posts&lt;br /&gt;
#*[[Capabilities/moodle/user:viewuseractivitiesreport|moodle/user:viewuseractivitiesreport]] - to view the student&#039;s activity reports and grades&lt;br /&gt;
#*[[Capabilities/moodle/user:editprofile|moodle/user:editprofile]] - to edit the student&#039;s profile&lt;br /&gt;
#Click the &amp;quot;Create this role&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:CustomRole05.png|thumb|Setting up the parent role]]&lt;br /&gt;
| [[File:CustomRole06.png|thumb|Assigning capabilities to the parent role]]&lt;br /&gt;
| [[File:CustomRole07.png|thumb|Saving changes to the parent role]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some permissions may already be set to &amp;quot;Allow&amp;quot;, or the permissions granted here may not be the ones required for that Role. This set of Permissions mean that this Role allows anyone assigned to a Parent Role, then linked to the Student Role, to edit the profile or read the blogs of that Student - not everyone&#039;s profile or blogs.&lt;br /&gt;
&lt;br /&gt;
==Assigning the parent to the student==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Access the child&#039;s full  profile page, via &#039;&#039;&#039;Site administration ► Users ► Accounts ► Browse list of users&#039;&#039;&#039;&lt;br /&gt;
*Click the child&#039;s name to view the profile.&lt;br /&gt;
*In the Administration section, click Preferences&lt;br /&gt;
*In the Roles section, click Assign roles relative to this user&lt;br /&gt;
*Choose the role to assign i.e. Parent by clicking on the word.&lt;br /&gt;
*Select the parent in the potential users list and use the Add button to add it to the existing users list. &lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:Parentroleassignroles.png|thumb|500px|&amp;quot;Assign roles relative to this user&amp;quot;]]&lt;br /&gt;
| [[File:choosingparent.png|thumb|500px|Assigning the parent to the student]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
At this point you can return to the &amp;quot;Assign roles in user:&amp;quot; page and you should see that the parent name is now in the &amp;quot;Users with Role&amp;quot; column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;NOTE:&#039;&#039;&#039;The same parent may be assigned to several students, siblings or otherwise.&lt;br /&gt;
&lt;br /&gt;
===Adding multiple parents/mentors at once===&lt;br /&gt;
If you are interested in assigning several parent roles &#039;&#039;en masse&#039;&#039; there is a contributed plugin (use at your own risk) here CONTRIB-3938  which allows you to configure automatic role assignment between users from a database (ex: mentor/mentee or parent/child). You can also read the discussion at http://moodle.org/mod/forum/discuss.php?d=70539#p345127)&lt;br /&gt;
&lt;br /&gt;
===Adding the Mentees Block===&lt;br /&gt;
This block needs to be added so parents can see links to their child&#039;s profile.&lt;br /&gt;
&lt;br /&gt;
* On the Front Page, turn editing on.&lt;br /&gt;
*Go to the &#039;&#039;&#039;Add Blocks&#039;&#039;&#039; block and select the [[Mentees block]] and when it appears, click on the Configuration icon.&lt;br /&gt;
*Edit the configuration settings to suit the needs of the site. When complete, save the changes and return to the Front Page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
| [[File:addmenteesblock.png|thumb|Accessing the Add Blocks]]&lt;br /&gt;
| [[File:configuringmenteesblock.png|thumb|Setting the configuration values]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===How a parent sees their child&#039;s activities===&lt;br /&gt;
&lt;br /&gt;
*Once the mentees block has been added, a parent/mentor sees the link to any children/mentees they are responsible for.&lt;br /&gt;
*They click on a name and will be taken to the profile page of that user.&lt;br /&gt;
*They then select from &amp;quot;Course profiles&amp;quot; - the name of a course the user is enrolled in.&lt;br /&gt;
*Grades may then be viewed by clicking in the Reports section&lt;br /&gt;
*Forum posts or similar may also be viewed from the user&#039;s profile in the Miscellaneous section.&lt;br /&gt;
{|&lt;br /&gt;
| [[File:MOParentRole01a.png|thumb|Click the name of a course in the profile]]&lt;br /&gt;
| [[File:MOParentRole02.png|thumb|Only &#039;&#039;&#039;then&#039;&#039;&#039; choose an item, for example grades]]&lt;br /&gt;
| [[File:MOParentRole03.png|thumb|The course grades are now visible]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*To view activity in another course, the parent needs to click back to the user&#039;s main profile and then select another course link.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://www.youtube.com/watch?v=Gk_TRi_N00o The Parent role in Moodle 2.0 video]&lt;br /&gt;
*[[Create_custom_roles|Create a custom role]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=57812 Create a Parent of a student role]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=199269 Parent Role Report: Who belongs to whom?]&lt;br /&gt;
&lt;br /&gt;
*Improving navigation:&lt;br /&gt;
&lt;br /&gt;
One small hack that can make the course list a bit more readable, especially for long course lists, is to change the format to a vertical list:&lt;br /&gt;
&lt;br /&gt;
* Edit the moodle/user/view.php file and look for these lines (around line 302-304 in my 2.3.2 installation):&lt;br /&gt;
&amp;lt;code php&amp;gt;. $cfullname . &amp;quot;&amp;lt;/a&amp;gt;, &amp;quot;;&lt;br /&gt;
                } else {&lt;br /&gt;
                    $courselisting .= $cfullname . &amp;quot;, &amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* and change that to :&lt;br /&gt;
&amp;lt;code php&amp;gt;. $cfullname . &amp;quot;&amp;lt;/a&amp;gt;,&amp;lt;br /&amp;gt;&amp;quot;;&lt;br /&gt;
                } else {&lt;br /&gt;
                    $courselisting .= $cfullname . &amp;quot;&amp;lt;br /&amp;gt;&amp;quot;;;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Then save&lt;br /&gt;
This will affect the profile view in a course.&lt;br /&gt;
&lt;br /&gt;
* Edit the moodle/user/profile.php file and look for these lines (around line 3332 in my 2.3.2 installation):&lt;br /&gt;
&amp;lt;code php&amp;gt; $courselisting .= &amp;quot;&amp;lt;a href=\&amp;quot;{$CFG-&amp;gt;wwwroot}/user/view.php?id={$user-&amp;gt;id}&amp;amp;amp;course={$mycourse-&amp;gt;id}\&amp;quot; $class &amp;gt;&amp;quot; . format_string($mycourse-&amp;gt;fullname) . &amp;quot;&amp;lt;/a&amp;gt;, &amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* and change that to :&lt;br /&gt;
&amp;lt;code php&amp;gt;$courselisting .= &amp;quot;&amp;lt;a href=\&amp;quot;{$CFG-&amp;gt;wwwroot}/user/view.php?id={$user-&amp;gt;id}&amp;amp;amp;course={$mycourse-&amp;gt;id}\&amp;quot; $class &amp;gt;&amp;quot; . format_string($mycourse-&amp;gt;fullname) . &amp;quot;&amp;lt;/a&amp;gt;,&amp;lt;br /&amp;gt;&amp;quot;;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Then save&lt;br /&gt;
This will affect the profile view from the main page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[eu:Guraso_rola]]&lt;br /&gt;
[[fr:Rôle Parent]]&lt;br /&gt;
[[ja:親ロール]]&lt;br /&gt;
[[de:Eltern-Rolle]]&lt;br /&gt;
[[es:Rol paterno]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=125158</id>
		<title>Stash block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=125158"/>
		<updated>2016-09-01T08:01:22Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Added Fred as a maintainer because he does a lot of the work on this project.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox plugin&lt;br /&gt;
|type = Block, Stash&lt;br /&gt;
|set = https://moodle.org/plugins/browse.php?list=set&amp;amp;id=79 &lt;br /&gt;
|entry = https://moodle.org/plugins/block_stash&lt;br /&gt;
|tracker = https://github.com/FMCorz/moodle-block_stash/issues&lt;br /&gt;
|discussion = https://moodle.org/plugins/block_stash&lt;br /&gt;
|maintainer = [[User:Adrian Greeve|Adrian Greeve]], Frédéric Massart&lt;br /&gt;
|float = right&lt;br /&gt;
}}&lt;br /&gt;
=Stash=&lt;br /&gt;
[https://moodle.org/plugins/block_stash Stash] is a block that allows a teacher to create and then show items around a course. Students can then go and collect these items which will then appear in their stash block. The stash block is a good way to encourage more interaction with activities and is invaluable for teachers looking to gamify their course.&lt;br /&gt;
&lt;br /&gt;
==Adding an item==&lt;br /&gt;
* A teacher can click on the settings link in the stash block.&lt;br /&gt;
* This will lead them to a page that lists all the current items. &lt;br /&gt;
* Click on the &amp;quot;Add an item&amp;quot; button to add an item.&lt;br /&gt;
* Both a name and an image must be supplied.&lt;br /&gt;
&lt;br /&gt;
[[File:block stash add an item.png|400px]]&lt;br /&gt;
&lt;br /&gt;
* Clicking &amp;quot;Save and next&amp;quot; will progress to a location page.&lt;br /&gt;
&lt;br /&gt;
[[File:block stash item location.png|400px]]&lt;br /&gt;
&lt;br /&gt;
==Item location==&lt;br /&gt;
The location page contains details about a specific item location. One item has the ability to be located in many different places. Each location determines how many times a student can collect an item from that area.&lt;br /&gt;
&lt;br /&gt;
==The hard part: embedding objects==&lt;br /&gt;
Please see [https://www.youtube.com/watch?v=J9fvJmUdUFg this video on YouTube] about what and how to insert.&lt;br /&gt;
===Click on the link to the item location===&lt;br /&gt;
* Click on the link to the location of the item (red rectangle in the image below) :&lt;br /&gt;
&lt;br /&gt;
[[File:block stash link to the item location.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===Find the Snippet and copy that code===&lt;br /&gt;
* A window will pop with appearance dropdown menu, button text, snippet (this is the very important JavaScript code that will do the actual work), and location summary:&lt;br /&gt;
&lt;br /&gt;
[[File:block stash link item location inside Smaug&#039;s castle.png|400px]]&lt;br /&gt;
&lt;br /&gt;
* Notice that the &#039;Snippet&#039; rectangle can be scrolled and resized. You can enlarge it by dragging the triangle in the lower right corner (red circle in the image below):&lt;br /&gt;
&lt;br /&gt;
[[File:block stash snippet enlarged rectangle.png|400px]]&lt;br /&gt;
&lt;br /&gt;
* Now you can select all the content of the Snippet box, which you will later paste into the [[Atto]] editor inside an activity:&lt;br /&gt;
&lt;br /&gt;
[[File:block stash snippet selected for copying.png|500px]]&lt;br /&gt;
&lt;br /&gt;
* Close the window.&lt;br /&gt;
&lt;br /&gt;
=== Now select an activity or resource to harbour the item===&lt;br /&gt;
* Let us create a [[Page|page]] named &#039;The Hobbit, book reading&#039;&lt;br /&gt;
* In that page, instruct the students to read the famous Tolkien book:&lt;br /&gt;
&lt;br /&gt;
[[File:block stash required activity (page).png|400px]]&lt;br /&gt;
&lt;br /&gt;
* Let us now create another [[Page|page]] named &#039;After reading The Hobbit&#039;&lt;br /&gt;
* In that page, congratulate your students for having read a long book and... now it is time to insert the item (the ring) that will reward them for their reading activity:&lt;br /&gt;
&lt;br /&gt;
[[File:block stash page where we will embedd the item.png|400px]]&lt;br /&gt;
&lt;br /&gt;
* Notice the very first button (red rectangle) in the Atto toolbar that will expand the toolbar. You must click on that first button:&lt;br /&gt;
&lt;br /&gt;
* Now you must click on the button with the &amp;lt;&amp;gt; symbols  to show the HTML code (green rectangle):&lt;br /&gt;
&lt;br /&gt;
[[File:block stash page where we will embedd the item expanded Atto toolbar.png|400px]]&lt;br /&gt;
&lt;br /&gt;
* And finally, you can now paste the snippet code into the page:&lt;br /&gt;
[[File:block stash page where we have embedded the item Snippet code.png|400px]]&lt;br /&gt;
&lt;br /&gt;
* You can click on the &amp;lt;&amp;gt; button again and save your page with the embedded item.&lt;br /&gt;
&lt;br /&gt;
=See it in action in your own Moodle server=&lt;br /&gt;
The authors of the plugins have crafted a sample course for you to try. It is the best way to see what this plugin has to offer. Please accurately follow these steps:&lt;br /&gt;
&lt;br /&gt;
* Get your hands on a Moodle installation (3.0 or newer preferred)&lt;br /&gt;
* Install the three following plugins (without exception):&lt;br /&gt;
**  The [https://moodle.org/plugins/block_stash block stash plugin] (block_stash)&lt;br /&gt;
** The [https://moodle.org/plugins/availability_stash stash availability plugin] (availability_stash)&lt;br /&gt;
** The [https://moodle.org/plugins/filter_stash stash snippet filter plugin] (filter_stash)&lt;br /&gt;
&lt;br /&gt;
* Enable the filter &amp;quot;Stash snippets&amp;quot; you just installed through &amp;quot;Site administration &amp;gt; Filters&amp;quot;&lt;br /&gt;
* Enable [[Using_restrict_access#Gamification|conditional access]], named enableavailability under &amp;quot;Site administration &amp;gt; Advanced features&amp;quot;&lt;br /&gt;
* [[Course restore|Restore]] now [https://moodle.org/pluginfile.php/50/local_plugins/plugin_description/1665/stash-demo.mbz this backup file] as a new course&lt;br /&gt;
* Enrol a student in the new course&lt;br /&gt;
*  Now, login as that student and try the course&lt;br /&gt;
* You will see some very easy to follow instructions:&lt;br /&gt;
[[File:block stash course just started.png|400px]]&lt;br /&gt;
&lt;br /&gt;
* You need to collect 3 coins, one sword and one crown in order to complete the course:&lt;br /&gt;
[[File:block stash 5 object collected.png|200px]]&lt;br /&gt;
&lt;br /&gt;
* When your stash has all the needed items, you will have completed the course!&lt;br /&gt;
[[File:block stash course completed.png|400px]]&lt;br /&gt;
&lt;br /&gt;
= Frequently asked questions =&lt;br /&gt;
== Why isn&#039;t my item working properly? ==&lt;br /&gt;
There are a couple of possibilities that your item may not be working properly.&lt;br /&gt;
&lt;br /&gt;
* The code snippet will only work when inserted into an [[Atto]] editor that only a teacher can see. Placing code into a forum post or database entry will not work. Items for these activities should be placed in the description of the activity.&lt;br /&gt;
* Using the [[TinyMCE editor]] causes the JavaScript to be saved in an invalid form. Please use the [[Atto]] editor instead.&lt;br /&gt;
&lt;br /&gt;
== How do I restrict access to an activity to rely on an item in the stash? ==&lt;br /&gt;
Restricting access to an activity through an item in the stash is possible, but requires the inclusion of [https://moodle.org/plugins/availability_stash the availability_stash plugin].&lt;br /&gt;
&lt;br /&gt;
==Isn&#039;t there an easier way to use the Stash?==&lt;br /&gt;
Yes. Install and enable the [https://moodle.org/plugins/filter_stash Stash snippet filter] in order to provide shortcodes to place items.&lt;br /&gt;
&lt;br /&gt;
[[Category:Game]]&lt;br /&gt;
&lt;br /&gt;
[[es:blocks/stash]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124956</id>
		<title>Stash block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124956"/>
		<updated>2016-08-19T08:45:34Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Why isn&amp;#039;t my item working properly? */ TinyMCE problem.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stash=&lt;br /&gt;
Stash is a block that allows a teacher to create and then show items around a course. Students can then go and collect these items which will then appear in their stash block. The stash block is a good way to encourage more interaction with activities and is invaluable for teachers looking to gamify their course.&lt;br /&gt;
&lt;br /&gt;
==Adding an item==&lt;br /&gt;
A teacher can click on the settings link in the stash block. This will lead them to a page that lists all the current items. Click on the &amp;quot;Add an item&amp;quot; button to add an item.&lt;br /&gt;
Both a name and an image must be supplied.&lt;br /&gt;
Clicking &amp;quot;Save and next&amp;quot; will progress to a location page.&lt;br /&gt;
==Item location==&lt;br /&gt;
The location page contains details about a specific item location. One item has the ability to be located in many different places. Each location determines how many times a student can collect an item from that area.&lt;br /&gt;
&lt;br /&gt;
= Frequently asked questions =&lt;br /&gt;
== Why isn&#039;t my item working properly? ==&lt;br /&gt;
There are a couple of possibilities that your item may not be working properly.&lt;br /&gt;
&lt;br /&gt;
* The code snippet will only work when inserted into an editor that only a teacher can see. Placing code into a forum post or database entry will not work. Items for these activities should be placed in the description of the activity.&lt;br /&gt;
* Using the editor TinyMCE causes the JavaScript to be saved in an invalid form. Please use the atto editor instead.&lt;br /&gt;
&lt;br /&gt;
== How do I restrict access to an activity to rely on an item in the stash? ==&lt;br /&gt;
Restricting access to an activity through an item in the stash is possible, but requires the inclusion of the availability_stash plugin.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124641</id>
		<title>Gradebook calculation changes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124641"/>
		<updated>2016-08-04T02:40:27Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* 20160518 - letter grade boundary issue */ - Information about a script for the 57 letter grade problem.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: The following information only applies if you see a message displayed in the gradebook following a site upgrade, or after restoring a course backup from a different version of Moodle.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occasionally there are error fixes which can affect gradebook calculations in certain courses. As part of the upgrade process, such courses are identified and a message is displayed in the gradebook informing teachers that error fixes may result in some grades being changed. Details of these changes are provided below. The 8-digit version number is the date of the fix.&lt;br /&gt;
&lt;br /&gt;
It is recommended that the errors are fixed by clicking the button &#039;Accept grade changes and fix calculation errors&#039;. Until this is done, the message will continue to be displayed in the gradebook (only for teachers; students can&#039;t see it). The old gradebook calculations will still be used (ensuring grades remain unchanged), however they are likely to result in more errors if grades are updated in the future.&lt;br /&gt;
&lt;br /&gt;
=== 20150619 - Calculation of extra credit item weights when using natural aggregation ===&lt;br /&gt;
&lt;br /&gt;
Two errors were fixed:&lt;br /&gt;
# Overriding the weight of the extra credit item can lead to changes in other items&#039; weights and random final grades&lt;br /&gt;
# The automatic weight of an extra credit item was dependent on the overrides of the normal item&#039;s weights&lt;br /&gt;
&lt;br /&gt;
The second error was especially noticeable for students with excluded grade items (for example, when they are hidden or empty). &lt;br /&gt;
&lt;br /&gt;
For example, a category has two normal grade items and one extra credit item. If the maximum grades for each item are the same, the weights of the three items will be: 50%, 50% and 50%. However if the weights of the normal items are overridden to be 50% and 50%, then the weight of the extra credit item would become 0%. If the teacher overrode the weight of the first item to 80%, the second item would automatically become 20% (correct) and the extra credit would also become 20% (incorrect). &lt;br /&gt;
&lt;br /&gt;
The correct behaviour (after the fix): If the weight of extra credit item is not overridden, it should be itemmaxgrade / totalmaxgrade , where totalmaxgrade does not include the extra credit item. In the example, the weight of the extra credit item should always be 50%.&lt;br /&gt;
&lt;br /&gt;
See MDL-49257 for further details including screenshots.&lt;br /&gt;
&lt;br /&gt;
=== 20150627 - Calculated grade items ===&lt;br /&gt;
&lt;br /&gt;
Two errors affecting grades were fixed:&lt;br /&gt;
# Changing the maxgrade for a category item with a calculation that has existing grades results in grades displayed out of the old maximum grade, not the updated one. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
# Values for grade items with a calculation are always displayed from 0 to 100 regardless of the minimum and maximum grades for the grade item. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
&lt;br /&gt;
These fixes will impact existing grades by correcting the maximum grade for existing grade items.&lt;br /&gt;
&lt;br /&gt;
See MDL-48239 for further details.&lt;br /&gt;
&lt;br /&gt;
=== 20160518 - letter grade boundary issue ===&lt;br /&gt;
&lt;br /&gt;
Some letter boundaries, when achieved by a student, would not give the student the associated grade.&lt;br /&gt;
For example. If the letter grades were updated so that the letter boundary for a C was  57 and a D was 50, a student that received 57 for a grade would get a D instead of a C.&lt;br /&gt;
This problem only affects sites that have edited the letter grades, and not all letter boundaries have this problem. The default settings do not produce this error.&lt;br /&gt;
This has now been fixed, but the course gradebook will be frozen if the system has detected that the course has been affected by an altered letter grade boundary. There is a possibility that student&#039;s letter grades will change after the gradebook freeze has been accepted.&lt;br /&gt;
see MDL-45390 for further details.&lt;br /&gt;
&lt;br /&gt;
The upgrade step that freezes the gradebook above for the letter grade boundary is not 100% accurate. The upgrade step was optimised for speed and will freeze any course that has the potential to be a problem. The script may freeze more courses than it needs to. To determine if a course is definitely affected requires a lot of processing. We have created a script that will go through each of the courses and analyse the grades to see if the grade displayed will actually change. Due to the complex nature of the gradebook, this requires checking how the grade will displayed from a teachers perspective as well as the student perspective and is consequently very slow.&lt;br /&gt;
&lt;br /&gt;
If you wish to check your site and see which courses are definitely affected then you can find the script on issue MDL-55066.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;&lt;br /&gt;
* The script can only be run &#039;&#039;&#039;after&#039;&#039;&#039; the upgrade has been done. The upgrade step is cautious with the courses it freezes and so the script uses the frozen courses as a base to do its calculations.&lt;br /&gt;
* The script is a Command Line Interface (CLI) and is to be run from the command line.&lt;br /&gt;
* The script has two settings.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
php 57script.php&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Running the script with no options will only produce a report of which courses should be frozen and which should not. No alterations to the freeze will be made.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
php 57script.php --update&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Running the script with the &amp;quot;update&amp;quot; option will unfreeze courses that it deems do not actually require freezing.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124265</id>
		<title>Stash block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124265"/>
		<updated>2016-07-02T04:53:19Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Stash */ - More detail&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stash=&lt;br /&gt;
Stash is a block that allows a teacher to create and then show items around a course. Students can then go and collect these items which will then appear in their stash block. The stash block is a good way to encourage more interaction with activities and is invaluable for teachers looking to gamify their course.&lt;br /&gt;
&lt;br /&gt;
==Adding an item==&lt;br /&gt;
A teacher can click on the settings link in the stash block. This will lead them to a page that lists all the current items. Click on the &amp;quot;Add an item&amp;quot; button to add an item.&lt;br /&gt;
Both a name and an image must be supplied.&lt;br /&gt;
Clicking &amp;quot;Save and next&amp;quot; will progress to a location page.&lt;br /&gt;
==Item location==&lt;br /&gt;
The location page contains details about a specific item location. One item has the ability to be located in many different places. Each location determines how many times a student can collect an item from that area.&lt;br /&gt;
&lt;br /&gt;
= Frequently asked questions =&lt;br /&gt;
== Why isn&#039;t my item working properly? ==&lt;br /&gt;
The code snippet will only work when inserted into an editor that only a teacher can see. Placing code into a forum post or database entry will not work. Items for these activities should be placed in the description of the activity.&lt;br /&gt;
== How do I restrict access to an activity to rely on an item in the stash? ==&lt;br /&gt;
Restricting access to an activity through an item in the stash is possible, but requires the inclusion of the availability_stash plugin.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124264</id>
		<title>Stash block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124264"/>
		<updated>2016-07-02T04:40:46Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: FAQ&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stash=&lt;br /&gt;
Stash is a block that allows a teacher to create and then show items around a course. Students can then go and collect these items which will then appear in their stash block.&lt;br /&gt;
&lt;br /&gt;
==Adding an item==&lt;br /&gt;
A teacher can click on the settings link in the stash block. This will lead them to a page that lists all the current items. Click on the &amp;quot;Add an item&amp;quot; button to add an item.&lt;br /&gt;
Both a name and an image must be supplied.&lt;br /&gt;
Clicking &amp;quot;Save and next&amp;quot; will progress to a location page.&lt;br /&gt;
==Item location==&lt;br /&gt;
The location page contains details about a specific item location. One item has the ability to be located in many different places. Each location determines how many times a student can collect an item from that area.&lt;br /&gt;
= Frequently asked questions =&lt;br /&gt;
== Why isn&#039;t my item working properly? ==&lt;br /&gt;
The code snippet will only work when inserted into an editor that only a teacher can see. Placing code into a forum post or database entry will not work. Items for these activities should be placed in the description of the activity.&lt;br /&gt;
== How do I restrict access to an activity to rely on an item in the stash? ==&lt;br /&gt;
Restricting access to an activity through an item in the stash is possible, but requires the inclusion of the availability_stash plugin.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124242</id>
		<title>Stash block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124242"/>
		<updated>2016-06-29T07:52:51Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Items and locations&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stash=&lt;br /&gt;
Stash is a block that allows a teacher to create and then show items around a course. Students can then go and collect these items which will then appear in their stash block.&lt;br /&gt;
&lt;br /&gt;
==Adding an item==&lt;br /&gt;
A teacher can click on the settings link in the stash block. This will lead them to a page that lists all the current items. Click on the &amp;quot;Add an item&amp;quot; button to add an item.&lt;br /&gt;
Both a name and an image must be supplied.&lt;br /&gt;
Clicking &amp;quot;Save and next&amp;quot; will progress to a location page.&lt;br /&gt;
==Item location==&lt;br /&gt;
The location page contains details about a specific item location. One item has the ability to be located in many different places. Each location determines how many times a student can collect an item from that area.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124241</id>
		<title>Stash block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Stash_block&amp;diff=124241"/>
		<updated>2016-06-29T07:35:37Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Very basic introduction to the stash&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stash=&lt;br /&gt;
Stash is a block that allows a teacher to create and then show items around a course. Students can then go and collect these items which will then appear in their stash block.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124240</id>
		<title>Gradebook calculation changes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124240"/>
		<updated>2016-06-29T02:17:13Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* 20160518 - letter grade boundary issue */ more alterations&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: The following information only applies if you see a message displayed in the gradebook following a site upgrade, or after restoring a course backup from a different version of Moodle.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occasionally there are error fixes which can affect gradebook calculations in certain courses. As part of the upgrade process, such courses are identified and a message is displayed in the gradebook informing teachers that error fixes may result in some grades being changed. Details of these changes are provided below. The 8-digit version number is the date of the fix.&lt;br /&gt;
&lt;br /&gt;
It is recommended that the errors are fixed by clicking the button &#039;Accept grade changes and fix calculation errors&#039;. Until this is done, the message will continue to be displayed in the gradebook (only for teachers; students can&#039;t see it). The old gradebook calculations will still be used (ensuring grades remain unchanged), however they are likely to result in more errors if grades are updated in the future.&lt;br /&gt;
&lt;br /&gt;
=== 20150619 - Calculation of extra credit item weights when using natural aggregation ===&lt;br /&gt;
&lt;br /&gt;
Two errors were fixed:&lt;br /&gt;
# Overriding the weight of the extra credit item can lead to changes in other items&#039; weights and random final grades&lt;br /&gt;
# The automatic weight of an extra credit item was dependent on the overrides of the normal item&#039;s weights&lt;br /&gt;
&lt;br /&gt;
The second error was especially noticeable for students with excluded grade items (for example, when they are hidden or empty). &lt;br /&gt;
&lt;br /&gt;
For example, a category has two normal grade items and one extra credit item. If the maximum grades for each item are the same, the weights of the three items will be: 50%, 50% and 50%. However if the weights of the normal items are overridden to be 50% and 50%, then the weight of the extra credit item would become 0%. If the teacher overrode the weight of the first item to 80%, the second item would automatically become 20% (correct) and the extra credit would also become 20% (incorrect). &lt;br /&gt;
&lt;br /&gt;
The correct behaviour (after the fix): If the weight of extra credit item is not overridden, it should be itemmaxgrade / totalmaxgrade , where totalmaxgrade does not include the extra credit item. In the example, the weight of the extra credit item should always be 50%.&lt;br /&gt;
&lt;br /&gt;
See MDL-49257 for further details including screenshots.&lt;br /&gt;
&lt;br /&gt;
=== 20150627 - Calculated grade items ===&lt;br /&gt;
&lt;br /&gt;
Two errors affecting grades were fixed:&lt;br /&gt;
# Changing the maxgrade for a category item with a calculation that has existing grades results in grades displayed out of the old maximum grade, not the updated one. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
# Values for grade items with a calculation are always displayed from 0 to 100 regardless of the minimum and maximum grades for the grade item. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
&lt;br /&gt;
These fixes will impact existing grades by correcting the maximum grade for existing grade items.&lt;br /&gt;
&lt;br /&gt;
See MDL-48239 for further details.&lt;br /&gt;
&lt;br /&gt;
=== 20160518 - letter grade boundary issue ===&lt;br /&gt;
&lt;br /&gt;
Some letter boundaries, when achieved by a student, would not give the student the associated grade.&lt;br /&gt;
For example. If the letter grades were updated so that the letter boundary for a C was  57 and a D was 50, a student that received 57 for a grade would get a D instead of a C.&lt;br /&gt;
This problem only affects sites that have edited the letter grades, and not all letter boundaries have this problem. The default settings do not produce this error.&lt;br /&gt;
This has now been fixed, but the course gradebook will be frozen if the system has detected that the course has been affected by an altered letter grade boundary. There is a possibility that student&#039;s letter grades will change after the gradebook freeze has been accepted.&lt;br /&gt;
see MDL-45390 for further details.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124239</id>
		<title>Gradebook calculation changes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124239"/>
		<updated>2016-06-29T02:13:01Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* 20160518 - letter grade boundary issue */ - small clarification&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: The following information only applies if you see a message displayed in the gradebook following a site upgrade, or after restoring a course backup from a different version of Moodle.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occasionally there are error fixes which can affect gradebook calculations in certain courses. As part of the upgrade process, such courses are identified and a message is displayed in the gradebook informing teachers that error fixes may result in some grades being changed. Details of these changes are provided below. The 8-digit version number is the date of the fix.&lt;br /&gt;
&lt;br /&gt;
It is recommended that the errors are fixed by clicking the button &#039;Accept grade changes and fix calculation errors&#039;. Until this is done, the message will continue to be displayed in the gradebook (only for teachers; students can&#039;t see it). The old gradebook calculations will still be used (ensuring grades remain unchanged), however they are likely to result in more errors if grades are updated in the future.&lt;br /&gt;
&lt;br /&gt;
=== 20150619 - Calculation of extra credit item weights when using natural aggregation ===&lt;br /&gt;
&lt;br /&gt;
Two errors were fixed:&lt;br /&gt;
# Overriding the weight of the extra credit item can lead to changes in other items&#039; weights and random final grades&lt;br /&gt;
# The automatic weight of an extra credit item was dependent on the overrides of the normal item&#039;s weights&lt;br /&gt;
&lt;br /&gt;
The second error was especially noticeable for students with excluded grade items (for example, when they are hidden or empty). &lt;br /&gt;
&lt;br /&gt;
For example, a category has two normal grade items and one extra credit item. If the maximum grades for each item are the same, the weights of the three items will be: 50%, 50% and 50%. However if the weights of the normal items are overridden to be 50% and 50%, then the weight of the extra credit item would become 0%. If the teacher overrode the weight of the first item to 80%, the second item would automatically become 20% (correct) and the extra credit would also become 20% (incorrect). &lt;br /&gt;
&lt;br /&gt;
The correct behaviour (after the fix): If the weight of extra credit item is not overridden, it should be itemmaxgrade / totalmaxgrade , where totalmaxgrade does not include the extra credit item. In the example, the weight of the extra credit item should always be 50%.&lt;br /&gt;
&lt;br /&gt;
See MDL-49257 for further details including screenshots.&lt;br /&gt;
&lt;br /&gt;
=== 20150627 - Calculated grade items ===&lt;br /&gt;
&lt;br /&gt;
Two errors affecting grades were fixed:&lt;br /&gt;
# Changing the maxgrade for a category item with a calculation that has existing grades results in grades displayed out of the old maximum grade, not the updated one. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
# Values for grade items with a calculation are always displayed from 0 to 100 regardless of the minimum and maximum grades for the grade item. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
&lt;br /&gt;
These fixes will impact existing grades by correcting the maximum grade for existing grade items.&lt;br /&gt;
&lt;br /&gt;
See MDL-48239 for further details.&lt;br /&gt;
&lt;br /&gt;
=== 20160518 - letter grade boundary issue ===&lt;br /&gt;
&lt;br /&gt;
Some letter boundaries, when achieved by a student, would not give the student the associated grade.&lt;br /&gt;
For example. If the letter grades were updated so that the letter boundary for a C was  57 and a D was 50, a student that received 57 for a grade would get a D instead of a C.&lt;br /&gt;
This problem only affects sites that have edited the letter grades, and not all letter boundaries have this problem. The default settings do not produce this error.&lt;br /&gt;
see MDL-45390 for further details.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124238</id>
		<title>Gradebook calculation changes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=124238"/>
		<updated>2016-06-29T02:11:52Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* 20160518 - letter grade boundary issue */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: The following information only applies if you see a message displayed in the gradebook following a site upgrade, or after restoring a course backup from a different version of Moodle.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occasionally there are error fixes which can affect gradebook calculations in certain courses. As part of the upgrade process, such courses are identified and a message is displayed in the gradebook informing teachers that error fixes may result in some grades being changed. Details of these changes are provided below. The 8-digit version number is the date of the fix.&lt;br /&gt;
&lt;br /&gt;
It is recommended that the errors are fixed by clicking the button &#039;Accept grade changes and fix calculation errors&#039;. Until this is done, the message will continue to be displayed in the gradebook (only for teachers; students can&#039;t see it). The old gradebook calculations will still be used (ensuring grades remain unchanged), however they are likely to result in more errors if grades are updated in the future.&lt;br /&gt;
&lt;br /&gt;
=== 20150619 - Calculation of extra credit item weights when using natural aggregation ===&lt;br /&gt;
&lt;br /&gt;
Two errors were fixed:&lt;br /&gt;
# Overriding the weight of the extra credit item can lead to changes in other items&#039; weights and random final grades&lt;br /&gt;
# The automatic weight of an extra credit item was dependent on the overrides of the normal item&#039;s weights&lt;br /&gt;
&lt;br /&gt;
The second error was especially noticeable for students with excluded grade items (for example, when they are hidden or empty). &lt;br /&gt;
&lt;br /&gt;
For example, a category has two normal grade items and one extra credit item. If the maximum grades for each item are the same, the weights of the three items will be: 50%, 50% and 50%. However if the weights of the normal items are overridden to be 50% and 50%, then the weight of the extra credit item would become 0%. If the teacher overrode the weight of the first item to 80%, the second item would automatically become 20% (correct) and the extra credit would also become 20% (incorrect). &lt;br /&gt;
&lt;br /&gt;
The correct behaviour (after the fix): If the weight of extra credit item is not overridden, it should be itemmaxgrade / totalmaxgrade , where totalmaxgrade does not include the extra credit item. In the example, the weight of the extra credit item should always be 50%.&lt;br /&gt;
&lt;br /&gt;
See MDL-49257 for further details including screenshots.&lt;br /&gt;
&lt;br /&gt;
=== 20150627 - Calculated grade items ===&lt;br /&gt;
&lt;br /&gt;
Two errors affecting grades were fixed:&lt;br /&gt;
# Changing the maxgrade for a category item with a calculation that has existing grades results in grades displayed out of the old maximum grade, not the updated one. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
# Values for grade items with a calculation are always displayed from 0 to 100 regardless of the minimum and maximum grades for the grade item. This can cause flow on affects for automatic weights with Natural Aggregation.&lt;br /&gt;
&lt;br /&gt;
These fixes will impact existing grades by correcting the maximum grade for existing grade items.&lt;br /&gt;
&lt;br /&gt;
See MDL-48239 for further details.&lt;br /&gt;
&lt;br /&gt;
=== 20160518 - letter grade boundary issue ===&lt;br /&gt;
&lt;br /&gt;
Some letter boundaries, when achieved by a student, would not give the student the associated grade.&lt;br /&gt;
For example. If the letter grades were updated so that the letter boundary for a C was  57 and a D was 50, a student that received 57 for a grade would get a D instead of a C.&lt;br /&gt;
This problem only affects sites that have edited the letter grades. The default settings do not produce this error.&lt;br /&gt;
see MDL-45390 for further details.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Legacy_course_files&amp;diff=121825</id>
		<title>Legacy course files</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Legacy_course_files&amp;diff=121825"/>
		<updated>2015-12-14T03:59:17Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Where are legacy files stored? -Uploading legacy course files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Repositories}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: This page only applies to sites which have been upgraded from Moodle 1.9.&amp;lt;/p&amp;gt;&lt;br /&gt;
In Moodle 2.0 onwards, files are stored in separate areas, rather than together in the course files area. See [[Course files]] for a detailed explanation. When a site is upgraded from 1.9, the course files area is renamed &#039;Legacy course files&#039;. By default, this area is not available in new courses.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;It is recommended that teachers make use of the new [[Repositories|repositories]] in Moodle 2.0 for storing course files, rather than saving them in the legacy course files area&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Enabling legacy course files areas==&lt;br /&gt;
&lt;br /&gt;
To enable a legacy course files area in a new course&lt;br /&gt;
&lt;br /&gt;
# Enable the legacy course files repository plugin in &#039;&#039;Administration &amp;gt; Site administration &amp;gt; Plugins &amp;gt; Repositories &amp;gt; Common repository settings&#039;&#039;.&lt;br /&gt;
# Check the legacyfilesinnewcourses box in the Manage repositories common settings (Settings &amp;gt; Site administration &amp;gt; Plugins &amp;gt; Repositories &amp;gt; Common repository settings) then click the &#039;Save changes&#039; button.&lt;br /&gt;
# Set &#039;Legacy course files&#039; to Yes in the course settings.&lt;br /&gt;
&lt;br /&gt;
A legacy course files link will then appear in the &#039;&#039;Administration &amp;gt; Course administration&#039;&#039; area.&lt;br /&gt;
&lt;br /&gt;
==Repository capabilities==&lt;br /&gt;
&lt;br /&gt;
The capabilities [[Capabilities/repository/coursefiles:view|Use course files repository plugin]] and [[Capabilities/moodle/course:managefiles|Manage files]] are both required for users to access the legacy course files area.&lt;br /&gt;
&lt;br /&gt;
==FAQs==&lt;br /&gt;
===Can you find out disk volume of legacy files?===&lt;br /&gt;
No.  You will need a custom report of some kind.  See http://moodle.org/mod/forum/discuss.php?d=201601&lt;br /&gt;
&lt;br /&gt;
===Where are legacy files stored?===&lt;br /&gt;
For one explanation, see http://moodle.org/mod/forum/discuss.php?d=164544&lt;br /&gt;
&lt;br /&gt;
If you are looking to add files to the course (such as for testing). Go to &#039;Administration &amp;gt; Course administration &amp;gt; Legacy course files&#039; in your course (with all the appropriate settings set as mentioned above). You can upload and delete files here.&lt;br /&gt;
&lt;br /&gt;
===Is there a way to delete legacy files en masse?===&lt;br /&gt;
Not at the moment.  Tracker item: http://tracker.moodle.org/browse/MDL-36008 and discussion: https://moodle.org/mod/forum/discuss.php?d=209353&lt;br /&gt;
&lt;br /&gt;
See also a comment here: https://moodle.org/mod/forum/discuss.php?d=234922#p1020379&lt;br /&gt;
&lt;br /&gt;
===Is there a way to prevent new additions to legacy files?===&lt;br /&gt;
Yes. Unchecking [[Managing_repositories#Allow adding to legacy course files|Allow adding to legacy course files]] in &#039;&#039;Site Administration &amp;gt; Plugins &amp;gt; Repositories &amp;gt; Common repository settings&#039;&#039; will prevent users from adding new files and directories to legacy course files, but they will still be able to delete files.&lt;br /&gt;
&lt;br /&gt;
===What happens if you switch legacy files off in a site that has been upgraded and has a lot of legacy files?===&lt;br /&gt;
Unsure.&lt;br /&gt;
&lt;br /&gt;
===Can you migrate a course from 1.9 to 2+ and NOT end up with a legacy files repository?===&lt;br /&gt;
Yes, you can. If you restore as a Teacher into the course you&#039;re currently present in (best if it&#039;s empty) and don&#039;t override any settings then the Legacy Files will not be added as a Repository.&lt;br /&gt;
&lt;br /&gt;
===What happens to the Legacy files in a course imported from 1.9 to 2.x that is re-imported into another 2.x?===&lt;br /&gt;
&lt;br /&gt;
===In backups, are legacy files included with a course?===&lt;br /&gt;
Seems to be the case: http://moodle.org/mod/forum/discuss.php?d=194981&lt;br /&gt;
&lt;br /&gt;
Also check out https://moodle.org/mod/forum/discuss.php?d=251415&lt;br /&gt;
&lt;br /&gt;
===Long term, will there be any problem keeping a large number of Legacy files?===&lt;br /&gt;
Possibly if you want to import (as opposed to restore) you may lose legacy files.  See &lt;br /&gt;
*http://tracker.moodle.org/browse/MDL-25631&lt;br /&gt;
*http://tracker.moodle.org/browse/MDL-32598&lt;br /&gt;
&lt;br /&gt;
===What happens if legacy files were previously enabled and then the legacy course files repository is disabled?===&lt;br /&gt;
&lt;br /&gt;
Legacy course files are displayed if they have ever been enabled on the course, but can be disabled at the course level in the course settings. Any new courses created will not have a legacy course files area.&lt;br /&gt;
&lt;br /&gt;
==Also see==&lt;br /&gt;
*http://moodle.org/mod/forum/discuss.php?d=172559&lt;br /&gt;
*http://moodle.org/mod/forum/discuss.php?d=197746&lt;br /&gt;
*https://moodle.org/mod/forum/discuss.php?d=234922&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[ja: レガシーコースファイル]]&lt;br /&gt;
[[de:Legacy-Kursdateien]]&lt;br /&gt;
[[es:Archivos de curso heredados]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Legacy_course_files&amp;diff=121824</id>
		<title>Legacy course files</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Legacy_course_files&amp;diff=121824"/>
		<updated>2015-12-14T02:42:18Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Enabling legacy course files areas - clarification of point two */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Repositories}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: This page only applies to sites which have been upgraded from Moodle 1.9.&amp;lt;/p&amp;gt;&lt;br /&gt;
In Moodle 2.0 onwards, files are stored in separate areas, rather than together in the course files area. See [[Course files]] for a detailed explanation. When a site is upgraded from 1.9, the course files area is renamed &#039;Legacy course files&#039;. By default, this area is not available in new courses.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;It is recommended that teachers make use of the new [[Repositories|repositories]] in Moodle 2.0 for storing course files, rather than saving them in the legacy course files area&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Enabling legacy course files areas==&lt;br /&gt;
&lt;br /&gt;
To enable a legacy course files area in a new course&lt;br /&gt;
&lt;br /&gt;
# Enable the legacy course files repository plugin in &#039;&#039;Administration &amp;gt; Site administration &amp;gt; Plugins &amp;gt; Repositories &amp;gt; Common repository settings&#039;&#039;.&lt;br /&gt;
# Check the legacyfilesinnewcourses box in the Manage repositories common settings (Settings &amp;gt; Site administration &amp;gt; Plugins &amp;gt; Repositories &amp;gt; Common repository settings) then click the &#039;Save changes&#039; button.&lt;br /&gt;
# Set &#039;Legacy course files&#039; to Yes in the course settings.&lt;br /&gt;
&lt;br /&gt;
A legacy course files link will then appear in the &#039;&#039;Administration &amp;gt; Course administration&#039;&#039; area.&lt;br /&gt;
&lt;br /&gt;
==Repository capabilities==&lt;br /&gt;
&lt;br /&gt;
The capabilities [[Capabilities/repository/coursefiles:view|Use course files repository plugin]] and [[Capabilities/moodle/course:managefiles|Manage files]] are both required for users to access the legacy course files area.&lt;br /&gt;
&lt;br /&gt;
==FAQs==&lt;br /&gt;
===Can you find out disk volume of legacy files?===&lt;br /&gt;
No.  You will need a custom report of some kind.  See http://moodle.org/mod/forum/discuss.php?d=201601&lt;br /&gt;
&lt;br /&gt;
===Where are legacy files stored?===&lt;br /&gt;
For one explanation, see http://moodle.org/mod/forum/discuss.php?d=164544&lt;br /&gt;
&lt;br /&gt;
===Is there a way to delete legacy files en masse?===&lt;br /&gt;
Not at the moment.  Tracker item: http://tracker.moodle.org/browse/MDL-36008 and discussion: https://moodle.org/mod/forum/discuss.php?d=209353&lt;br /&gt;
&lt;br /&gt;
See also a comment here: https://moodle.org/mod/forum/discuss.php?d=234922#p1020379&lt;br /&gt;
&lt;br /&gt;
===Is there a way to prevent new additions to legacy files?===&lt;br /&gt;
Yes. Unchecking [[Managing_repositories#Allow adding to legacy course files|Allow adding to legacy course files]] in &#039;&#039;Site Administration &amp;gt; Plugins &amp;gt; Repositories &amp;gt; Common repository settings&#039;&#039; will prevent users from adding new files and directories to legacy course files, but they will still be able to delete files.&lt;br /&gt;
&lt;br /&gt;
===What happens if you switch legacy files off in a site that has been upgraded and has a lot of legacy files?===&lt;br /&gt;
Unsure.&lt;br /&gt;
&lt;br /&gt;
===Can you migrate a course from 1.9 to 2+ and NOT end up with a legacy files repository?===&lt;br /&gt;
Yes, you can. If you restore as a Teacher into the course you&#039;re currently present in (best if it&#039;s empty) and don&#039;t override any settings then the Legacy Files will not be added as a Repository.&lt;br /&gt;
&lt;br /&gt;
===What happens to the Legacy files in a course imported from 1.9 to 2.x that is re-imported into another 2.x?===&lt;br /&gt;
&lt;br /&gt;
===In backups, are legacy files included with a course?===&lt;br /&gt;
Seems to be the case: http://moodle.org/mod/forum/discuss.php?d=194981&lt;br /&gt;
&lt;br /&gt;
Also check out https://moodle.org/mod/forum/discuss.php?d=251415&lt;br /&gt;
&lt;br /&gt;
===Long term, will there be any problem keeping a large number of Legacy files?===&lt;br /&gt;
Possibly if you want to import (as opposed to restore) you may lose legacy files.  See &lt;br /&gt;
*http://tracker.moodle.org/browse/MDL-25631&lt;br /&gt;
*http://tracker.moodle.org/browse/MDL-32598&lt;br /&gt;
&lt;br /&gt;
===What happens if legacy files were previously enabled and then the legacy course files repository is disabled?===&lt;br /&gt;
&lt;br /&gt;
Legacy course files are displayed if they have ever been enabled on the course, but can be disabled at the course level in the course settings. Any new courses created will not have a legacy course files area.&lt;br /&gt;
&lt;br /&gt;
==Also see==&lt;br /&gt;
*http://moodle.org/mod/forum/discuss.php?d=172559&lt;br /&gt;
*http://moodle.org/mod/forum/discuss.php?d=197746&lt;br /&gt;
*https://moodle.org/mod/forum/discuss.php?d=234922&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[ja: レガシーコースファイル]]&lt;br /&gt;
[[de:Legacy-Kursdateien]]&lt;br /&gt;
[[es:Archivos de curso heredados]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121601</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121601"/>
		<updated>2015-11-26T02:40:00Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Form library and helper functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Edit form template==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form template&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| &amp;lt;code xml&amp;gt;&lt;br /&gt;
{{!&lt;br /&gt;
    @template mod_lesson/page_editor&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Edit this {{lessonpagetype}} &amp;lt;/h3&amp;gt;&lt;br /&gt;
    {{#title}}&lt;br /&gt;
        {{&amp;gt;core/form-element-text}}&lt;br /&gt;
    {{/title}}&lt;br /&gt;
    &amp;lt;div&amp;gt;Page Content&amp;lt;/div&amp;gt;&lt;br /&gt;
    {{#select}}    &lt;br /&gt;
        {{&amp;gt;core/form-element-select}}&lt;br /&gt;
    {{/select}}    &lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Form data compilation for displaying==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form data compilation for display&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var frm = new form();&lt;br /&gt;
            frm.addFieldset(&#039;general&#039;, &#039;General&#039;);&lt;br /&gt;
            textfield = new text();&lt;br /&gt;
            textfield.set_name(&#039;title&#039;);&lt;br /&gt;
            textfield.set_id(&#039;mod_lesson_title_&#039; + pageid);&lt;br /&gt;
            textfield.set_label(&#039;Page Title&#039;);&lt;br /&gt;
            textfield.set_required();&lt;br /&gt;
            textfield.set_text(lesson.pages[pageid].title);&lt;br /&gt;
            frm.addElement(textfield);&lt;br /&gt;
            selectfield = new selectElement();&lt;br /&gt;
            selectfield.set_name(&#039;Jump_1&#039;);&lt;br /&gt;
            selectfield.set_label(&#039;Jumps&#039;);&lt;br /&gt;
            selectfield.set_id(&amp;quot;mod_lesson_jump_1_&amp;quot; + pageid);&lt;br /&gt;
            selectfield.set_options(joptions);&lt;br /&gt;
            frm.addElement(selectfield);&lt;br /&gt;
            $.when(frm.printForm()).then(function(tempformstuff) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(tempformstuff); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Could do client side validation here.&lt;br /&gt;
                    if ($(&amp;quot;#mod_lesson_title_&amp;quot; + pageid).val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var textelement = $(&amp;quot;#fitem_mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                        frm.handleError(&#039;title&#039;, textelement, &#039;text&#039;, &#039;Title should not be empty&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(frm);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var formdata = {&lt;br /&gt;
                lessonpagetype: lesson.pages[pageid].qtypestring,&lt;br /&gt;
                pageid: pageid,&lt;br /&gt;
                title: {&lt;br /&gt;
                    id: &amp;quot;mod_lesson_title_&amp;quot; + pageid,&lt;br /&gt;
                    label: &amp;quot;Page Title&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                    text: lesson.pages[pageid].title,&lt;br /&gt;
                    required: 1&lt;br /&gt;
                },&lt;br /&gt;
                contents: lesson.pages[pageid].contents,&lt;br /&gt;
                select: {&lt;br /&gt;
                    id: pageid,&lt;br /&gt;
                    label: &amp;quot;Jumps&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;Jump_1&amp;quot;,&lt;br /&gt;
                    options: formfactory.formatOptions(joptions),&lt;br /&gt;
                    helpButton: &amp;quot;&amp;lt;button type=\&amp;quot;button\&amp;quot;&amp;gt;Help is here&amp;lt;/button&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
                }&lt;br /&gt;
            };&lt;br /&gt;
            $.when(templates.render(&#039;mod_lesson/page_editor&#039;, formdata)).done(function(pageeditor) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(pageeditor); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Do client side validation.&lt;br /&gt;
                    var titleelement = $(&amp;quot;#mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                    if (titleelement.val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var errors = {&lt;br /&gt;
                            errors: {&lt;br /&gt;
                                name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                                message: &amp;quot;The lesson page title should not be empty&amp;quot;&lt;br /&gt;
                            }&lt;br /&gt;
                        };&lt;br /&gt;
                        formfactory.handleErrors(errors, formdata);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(formdata);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Saving a form==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form saving&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formobject.handleErrors(response.warnings);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formfactory.handleErrors(response.warnings, formobject);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==New form elements==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ New form elements&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/form-element&#039;], function($, formElement) {&lt;br /&gt;
&lt;br /&gt;
    var Select = function() {&lt;br /&gt;
        formElement.call(this);&lt;br /&gt;
        this.type = &#039;select&#039;;&lt;br /&gt;
        this.options = &#039;&#039;;&lt;br /&gt;
        this.template = &amp;quot;core/form-element-select&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Format a normal array into an object for a select form element.&lt;br /&gt;
     *&lt;br /&gt;
     * @param {array} options An array of options.&lt;br /&gt;
     * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
     * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
     */&lt;br /&gt;
    this.formatOptions = function(options, selected) {&lt;br /&gt;
        var returnoptions = [];&lt;br /&gt;
        var select = 0;&lt;br /&gt;
        if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
            select = selected&lt;br /&gt;
        }&lt;br /&gt;
        for (index in options) {&lt;br /&gt;
            if (index == selected) {&lt;br /&gt;
                returnoptions.push({&lt;br /&gt;
                    value: index,&lt;br /&gt;
                    text: options[index],&lt;br /&gt;
                    selected: select&lt;br /&gt;
                });&lt;br /&gt;
            } else {&lt;br /&gt;
                returnoptions.push({&lt;br /&gt;
                    value: index,&lt;br /&gt;
                    text: options[index],&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return returnoptions;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_name = function(name) {&lt;br /&gt;
        formElement.prototype.set_name.call(this, name);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_id = function(id) {&lt;br /&gt;
        formElement.prototype.set_id.call(this, id);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_label = function(label) {&lt;br /&gt;
        formElement.prototype.set_label.call(this, label);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_error = function(error) {&lt;br /&gt;
        formElement.prototype.set_error.call(this, error);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_required = function() {&lt;br /&gt;
        formElement.prototype.set_required.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_options = function(options, selected) {&lt;br /&gt;
        this.options = formatOptions(options, selected);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.get_name = function() {&lt;br /&gt;
        return formElement.prototype.get_name.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.show = function() {&lt;br /&gt;
        return formElement.prototype.show.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return Select;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Template for a select element==&lt;br /&gt;
Same for both.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;fitem_{{id}}&amp;quot; class=&amp;quot;fitem fitem_select {{#required}}required{{/required}} {{#advanced}}advanced{{/advanced}}&amp;quot; data-field-type=&amp;quot;select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;fitemtitle&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;label {{#hiddenLabel}}class=&amp;quot;accesshide&amp;quot;{{/hiddenLabel}} for=&amp;quot;{{id}}&amp;quot;&amp;gt;&lt;br /&gt;
            {{label}}&lt;br /&gt;
            {{#required}}{{&amp;gt;core/form-required}}{{/required}}&lt;br /&gt;
            {{#advanced}}{{&amp;gt;core/form-advanced}}{{/advanced}}&lt;br /&gt;
        &amp;lt;/label&amp;gt;&lt;br /&gt;
        {{{helpButton}}}&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;felement fselect {{#error}}error{{/error}}&amp;quot;&amp;gt;&lt;br /&gt;
        {{#error}}&lt;br /&gt;
        &amp;lt;span class=&amp;quot;error&amp;quot; tabindex=&amp;quot;0&amp;quot;&amp;gt;{{{error}}}&amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;br/&amp;gt;&lt;br /&gt;
        {{/error}}&lt;br /&gt;
        &amp;lt;select name=&amp;quot;{{name}}&amp;quot; id=&amp;quot;{{id}}&amp;quot; {{#required}}required{{/required}} {{#size}}size=&amp;quot;{{size}}&amp;quot;{{/size}}&amp;gt;&lt;br /&gt;
            {{#options}}&lt;br /&gt;
                &amp;lt;option value=&amp;quot;{{value}}&amp;quot; {{#selected}}selected{{/selected}}&amp;gt;{{text}}&amp;lt;/option&amp;gt;&lt;br /&gt;
            {{/options}}&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Form library and helper functions==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Simple web service==&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class mod_lesson_external extends external_api {&lt;br /&gt;
&lt;br /&gt;
    public static function add_page_parameters() {&lt;br /&gt;
        return new external_function_parameters(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;lessonid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;lesson module ID&#039;),&lt;br /&gt;
                &#039;pageid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;lesson page ID&#039;),&lt;br /&gt;
                &#039;title&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;lesson page title&#039;, VALUE_OPTIONAL)&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static function add_page($lessonid, $pageid, $title) {&lt;br /&gt;
        $params = self::validate_parameters(self::add_page_parameters(),&lt;br /&gt;
                array($lessonid, $pageid, $title));&lt;br /&gt;
        $errors = array();&lt;br /&gt;
        if (empty($title)) {&lt;br /&gt;
            $errors[&amp;quot;code&amp;quot;] = &amp;quot;formvalidationfailed&amp;quot;;&lt;br /&gt;
            $errors[&amp;quot;message&amp;quot;] = &amp;quot;Validation Failed&amp;quot;;&lt;br /&gt;
            $errors[&amp;quot;errors&amp;quot;] = array(&#039;code&#039; =&amp;gt; &#039;notitlefound&#039;, &#039;name&#039; =&amp;gt; &#039;title&#039;, &#039;message&#039; =&amp;gt; &#039;Title must not be empty&#039;);&lt;br /&gt;
            return array(&#039;status&#039; =&amp;gt; false, &#039;warnings&#039; =&amp;gt; $errors);&lt;br /&gt;
        }&lt;br /&gt;
        return array(&#039;status&#039; =&amp;gt; true, &#039;warnings&#039; =&amp;gt; $errors);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static function add_page_returns() {&lt;br /&gt;
        return new external_single_structure(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;status&#039; =&amp;gt; new external_value(PARAM_BOOL, &#039;status: true if success&#039;),&lt;br /&gt;
                &#039;warnings&#039; =&amp;gt; new external_warnings()&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121600</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121600"/>
		<updated>2015-11-26T01:39:05Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Titles&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Edit form template==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form template&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| &amp;lt;code xml&amp;gt;&lt;br /&gt;
{{!&lt;br /&gt;
    @template mod_lesson/page_editor&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Edit this {{lessonpagetype}} &amp;lt;/h3&amp;gt;&lt;br /&gt;
    {{#title}}&lt;br /&gt;
        {{&amp;gt;core/form-element-text}}&lt;br /&gt;
    {{/title}}&lt;br /&gt;
    &amp;lt;div&amp;gt;Page Content&amp;lt;/div&amp;gt;&lt;br /&gt;
    {{#select}}    &lt;br /&gt;
        {{&amp;gt;core/form-element-select}}&lt;br /&gt;
    {{/select}}    &lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Form data compilation for displaying==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form data compilation for display&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var frm = new form();&lt;br /&gt;
            frm.addFieldset(&#039;general&#039;, &#039;General&#039;);&lt;br /&gt;
            textfield = new text();&lt;br /&gt;
            textfield.set_name(&#039;title&#039;);&lt;br /&gt;
            textfield.set_id(&#039;mod_lesson_title_&#039; + pageid);&lt;br /&gt;
            textfield.set_label(&#039;Page Title&#039;);&lt;br /&gt;
            textfield.set_required();&lt;br /&gt;
            textfield.set_text(lesson.pages[pageid].title);&lt;br /&gt;
            frm.addElement(textfield);&lt;br /&gt;
            selectfield = new selectElement();&lt;br /&gt;
            selectfield.set_name(&#039;Jump_1&#039;);&lt;br /&gt;
            selectfield.set_label(&#039;Jumps&#039;);&lt;br /&gt;
            selectfield.set_id(&amp;quot;mod_lesson_jump_1_&amp;quot; + pageid);&lt;br /&gt;
            selectfield.set_options(joptions);&lt;br /&gt;
            frm.addElement(selectfield);&lt;br /&gt;
            $.when(frm.printForm()).then(function(tempformstuff) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(tempformstuff); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Could do client side validation here.&lt;br /&gt;
                    if ($(&amp;quot;#mod_lesson_title_&amp;quot; + pageid).val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var textelement = $(&amp;quot;#fitem_mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                        frm.handleError(&#039;title&#039;, textelement, &#039;text&#039;, &#039;Title should not be empty&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(frm);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var formdata = {&lt;br /&gt;
                lessonpagetype: lesson.pages[pageid].qtypestring,&lt;br /&gt;
                pageid: pageid,&lt;br /&gt;
                title: {&lt;br /&gt;
                    id: &amp;quot;mod_lesson_title_&amp;quot; + pageid,&lt;br /&gt;
                    label: &amp;quot;Page Title&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                    text: lesson.pages[pageid].title,&lt;br /&gt;
                    required: 1&lt;br /&gt;
                },&lt;br /&gt;
                contents: lesson.pages[pageid].contents,&lt;br /&gt;
                select: {&lt;br /&gt;
                    id: pageid,&lt;br /&gt;
                    label: &amp;quot;Jumps&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;Jump_1&amp;quot;,&lt;br /&gt;
                    options: formfactory.formatOptions(joptions),&lt;br /&gt;
                    helpButton: &amp;quot;&amp;lt;button type=\&amp;quot;button\&amp;quot;&amp;gt;Help is here&amp;lt;/button&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
                }&lt;br /&gt;
            };&lt;br /&gt;
            $.when(templates.render(&#039;mod_lesson/page_editor&#039;, formdata)).done(function(pageeditor) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(pageeditor); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Do client side validation.&lt;br /&gt;
                    var titleelement = $(&amp;quot;#mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                    if (titleelement.val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var errors = {&lt;br /&gt;
                            errors: {&lt;br /&gt;
                                name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                                message: &amp;quot;The lesson page title should not be empty&amp;quot;&lt;br /&gt;
                            }&lt;br /&gt;
                        };&lt;br /&gt;
                        formfactory.handleErrors(errors, formdata);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(formdata);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Saving a form==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form saving&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formobject.handleErrors(response.warnings);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formfactory.handleErrors(response.warnings, formobject);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==New form elements==&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ New form elements&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/form-element&#039;], function($, formElement) {&lt;br /&gt;
&lt;br /&gt;
    var Select = function() {&lt;br /&gt;
        formElement.call(this);&lt;br /&gt;
        this.type = &#039;select&#039;;&lt;br /&gt;
        this.options = &#039;&#039;;&lt;br /&gt;
        this.template = &amp;quot;core/form-element-select&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Format a normal array into an object for a select form element.&lt;br /&gt;
     *&lt;br /&gt;
     * @param {array} options An array of options.&lt;br /&gt;
     * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
     * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
     */&lt;br /&gt;
    this.formatOptions = function(options, selected) {&lt;br /&gt;
        var returnoptions = [];&lt;br /&gt;
        var select = 0;&lt;br /&gt;
        if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
            select = selected&lt;br /&gt;
        }&lt;br /&gt;
        for (index in options) {&lt;br /&gt;
            if (index == selected) {&lt;br /&gt;
                returnoptions.push({&lt;br /&gt;
                    value: index,&lt;br /&gt;
                    text: options[index],&lt;br /&gt;
                    selected: select&lt;br /&gt;
                });&lt;br /&gt;
            } else {&lt;br /&gt;
                returnoptions.push({&lt;br /&gt;
                    value: index,&lt;br /&gt;
                    text: options[index],&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return returnoptions;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_name = function(name) {&lt;br /&gt;
        formElement.prototype.set_name.call(this, name);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_id = function(id) {&lt;br /&gt;
        formElement.prototype.set_id.call(this, id);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_label = function(label) {&lt;br /&gt;
        formElement.prototype.set_label.call(this, label);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_error = function(error) {&lt;br /&gt;
        formElement.prototype.set_error.call(this, error);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_required = function() {&lt;br /&gt;
        formElement.prototype.set_required.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_options = function(options, selected) {&lt;br /&gt;
        this.options = formatOptions(options, selected);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.get_name = function() {&lt;br /&gt;
        return formElement.prototype.get_name.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.show = function() {&lt;br /&gt;
        return formElement.prototype.show.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return Select;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Template for a select element==&lt;br /&gt;
Same for both.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;fitem_{{id}}&amp;quot; class=&amp;quot;fitem fitem_select {{#required}}required{{/required}} {{#advanced}}advanced{{/advanced}}&amp;quot; data-field-type=&amp;quot;select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;fitemtitle&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;label {{#hiddenLabel}}class=&amp;quot;accesshide&amp;quot;{{/hiddenLabel}} for=&amp;quot;{{id}}&amp;quot;&amp;gt;&lt;br /&gt;
            {{label}}&lt;br /&gt;
            {{#required}}{{&amp;gt;core/form-required}}{{/required}}&lt;br /&gt;
            {{#advanced}}{{&amp;gt;core/form-advanced}}{{/advanced}}&lt;br /&gt;
        &amp;lt;/label&amp;gt;&lt;br /&gt;
        {{{helpButton}}}&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;felement fselect {{#error}}error{{/error}}&amp;quot;&amp;gt;&lt;br /&gt;
        {{#error}}&lt;br /&gt;
        &amp;lt;span class=&amp;quot;error&amp;quot; tabindex=&amp;quot;0&amp;quot;&amp;gt;{{{error}}}&amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;br/&amp;gt;&lt;br /&gt;
        {{/error}}&lt;br /&gt;
        &amp;lt;select name=&amp;quot;{{name}}&amp;quot; id=&amp;quot;{{id}}&amp;quot; {{#required}}required{{/required}} {{#size}}size=&amp;quot;{{size}}&amp;quot;{{/size}}&amp;gt;&lt;br /&gt;
            {{#options}}&lt;br /&gt;
                &amp;lt;option value=&amp;quot;{{value}}&amp;quot; {{#selected}}selected{{/selected}}&amp;gt;{{text}}&amp;lt;/option&amp;gt;&lt;br /&gt;
            {{/options}}&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Form library and helper functions==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121599</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121599"/>
		<updated>2015-11-26T01:33:17Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: New form element&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form saving&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formobject.handleErrors(response.warnings);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formfactory.handleErrors(response.warnings, formobject);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form data compilation for display&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var frm = new form();&lt;br /&gt;
            frm.addFieldset(&#039;general&#039;, &#039;General&#039;);&lt;br /&gt;
            textfield = new text();&lt;br /&gt;
            textfield.set_name(&#039;title&#039;);&lt;br /&gt;
            textfield.set_id(&#039;mod_lesson_title_&#039; + pageid);&lt;br /&gt;
            textfield.set_label(&#039;Page Title&#039;);&lt;br /&gt;
            textfield.set_required();&lt;br /&gt;
            textfield.set_text(lesson.pages[pageid].title);&lt;br /&gt;
            frm.addElement(textfield);&lt;br /&gt;
            selectfield = new selectElement();&lt;br /&gt;
            selectfield.set_name(&#039;Jump_1&#039;);&lt;br /&gt;
            selectfield.set_label(&#039;Jumps&#039;);&lt;br /&gt;
            selectfield.set_id(&amp;quot;mod_lesson_jump_1_&amp;quot; + pageid);&lt;br /&gt;
            selectfield.set_options(joptions);&lt;br /&gt;
            frm.addElement(selectfield);&lt;br /&gt;
            $.when(frm.printForm()).then(function(tempformstuff) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(tempformstuff); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Could do client side validation here.&lt;br /&gt;
                    if ($(&amp;quot;#mod_lesson_title_&amp;quot; + pageid).val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var textelement = $(&amp;quot;#fitem_mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                        frm.handleError(&#039;title&#039;, textelement, &#039;text&#039;, &#039;Title should not be empty&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(frm);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var formdata = {&lt;br /&gt;
                lessonpagetype: lesson.pages[pageid].qtypestring,&lt;br /&gt;
                pageid: pageid,&lt;br /&gt;
                title: {&lt;br /&gt;
                    id: &amp;quot;mod_lesson_title_&amp;quot; + pageid,&lt;br /&gt;
                    label: &amp;quot;Page Title&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                    text: lesson.pages[pageid].title,&lt;br /&gt;
                    required: 1&lt;br /&gt;
                },&lt;br /&gt;
                contents: lesson.pages[pageid].contents,&lt;br /&gt;
                select: {&lt;br /&gt;
                    id: pageid,&lt;br /&gt;
                    label: &amp;quot;Jumps&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;Jump_1&amp;quot;,&lt;br /&gt;
                    options: formfactory.formatOptions(joptions),&lt;br /&gt;
                    helpButton: &amp;quot;&amp;lt;button type=\&amp;quot;button\&amp;quot;&amp;gt;Help is here&amp;lt;/button&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
                }&lt;br /&gt;
            };&lt;br /&gt;
            $.when(templates.render(&#039;mod_lesson/page_editor&#039;, formdata)).done(function(pageeditor) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(pageeditor); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Do client side validation.&lt;br /&gt;
                    var titleelement = $(&amp;quot;#mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                    if (titleelement.val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var errors = {&lt;br /&gt;
                            errors: {&lt;br /&gt;
                                name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                                message: &amp;quot;The lesson page title should not be empty&amp;quot;&lt;br /&gt;
                            }&lt;br /&gt;
                        };&lt;br /&gt;
                        formfactory.handleErrors(errors, formdata);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(formdata);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ New form elements&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/form-element&#039;], function($, formElement) {&lt;br /&gt;
&lt;br /&gt;
    var Select = function() {&lt;br /&gt;
        formElement.call(this);&lt;br /&gt;
        this.type = &#039;select&#039;;&lt;br /&gt;
        this.options = &#039;&#039;;&lt;br /&gt;
        this.template = &amp;quot;core/form-element-select&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Format a normal array into an object for a select form element.&lt;br /&gt;
     *&lt;br /&gt;
     * @param {array} options An array of options.&lt;br /&gt;
     * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
     * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
     */&lt;br /&gt;
    this.formatOptions = function(options, selected) {&lt;br /&gt;
        var returnoptions = [];&lt;br /&gt;
        var select = 0;&lt;br /&gt;
        if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
            select = selected&lt;br /&gt;
        }&lt;br /&gt;
        for (index in options) {&lt;br /&gt;
            if (index == selected) {&lt;br /&gt;
                returnoptions.push({&lt;br /&gt;
                    value: index,&lt;br /&gt;
                    text: options[index],&lt;br /&gt;
                    selected: select&lt;br /&gt;
                });&lt;br /&gt;
            } else {&lt;br /&gt;
                returnoptions.push({&lt;br /&gt;
                    value: index,&lt;br /&gt;
                    text: options[index],&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return returnoptions;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_name = function(name) {&lt;br /&gt;
        formElement.prototype.set_name.call(this, name);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_id = function(id) {&lt;br /&gt;
        formElement.prototype.set_id.call(this, id);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_label = function(label) {&lt;br /&gt;
        formElement.prototype.set_label.call(this, label);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_error = function(error) {&lt;br /&gt;
        formElement.prototype.set_error.call(this, error);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_required = function() {&lt;br /&gt;
        formElement.prototype.set_required.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.set_options = function(options, selected) {&lt;br /&gt;
        this.options = formatOptions(options, selected);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.get_name = function() {&lt;br /&gt;
        return formElement.prototype.get_name.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Select.prototype.show = function() {&lt;br /&gt;
        return formElement.prototype.show.call(this);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return Select;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Template for a select element==&lt;br /&gt;
Same for both.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;fitem_{{id}}&amp;quot; class=&amp;quot;fitem fitem_select {{#required}}required{{/required}} {{#advanced}}advanced{{/advanced}}&amp;quot; data-field-type=&amp;quot;select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;fitemtitle&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;label {{#hiddenLabel}}class=&amp;quot;accesshide&amp;quot;{{/hiddenLabel}} for=&amp;quot;{{id}}&amp;quot;&amp;gt;&lt;br /&gt;
            {{label}}&lt;br /&gt;
            {{#required}}{{&amp;gt;core/form-required}}{{/required}}&lt;br /&gt;
            {{#advanced}}{{&amp;gt;core/form-advanced}}{{/advanced}}&lt;br /&gt;
        &amp;lt;/label&amp;gt;&lt;br /&gt;
        {{{helpButton}}}&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;felement fselect {{#error}}error{{/error}}&amp;quot;&amp;gt;&lt;br /&gt;
        {{#error}}&lt;br /&gt;
        &amp;lt;span class=&amp;quot;error&amp;quot; tabindex=&amp;quot;0&amp;quot;&amp;gt;{{{error}}}&amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;br/&amp;gt;&lt;br /&gt;
        {{/error}}&lt;br /&gt;
        &amp;lt;select name=&amp;quot;{{name}}&amp;quot; id=&amp;quot;{{id}}&amp;quot; {{#required}}required{{/required}} {{#size}}size=&amp;quot;{{size}}&amp;quot;{{/size}}&amp;gt;&lt;br /&gt;
            {{#options}}&lt;br /&gt;
                &amp;lt;option value=&amp;quot;{{value}}&amp;quot; {{#selected}}selected{{/selected}}&amp;gt;{{text}}&amp;lt;/option&amp;gt;&lt;br /&gt;
            {{/options}}&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form template&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| &amp;lt;code xml&amp;gt;&lt;br /&gt;
{{!&lt;br /&gt;
    @template mod_lesson/page_editor&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Edit this {{lessonpagetype}} &amp;lt;/h3&amp;gt;&lt;br /&gt;
    {{#title}}&lt;br /&gt;
        {{&amp;gt;core/form-element-text}}&lt;br /&gt;
    {{/title}}&lt;br /&gt;
    &amp;lt;div&amp;gt;Page Content&amp;lt;/div&amp;gt;&lt;br /&gt;
    {{#select}}    &lt;br /&gt;
        {{&amp;gt;core/form-element-select}}&lt;br /&gt;
    {{/select}}    &lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121598</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121598"/>
		<updated>2015-11-26T01:27:43Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Form saving&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form saving&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formobject.handleErrors(response.warnings);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
save_edit_form: function(formobject) {&lt;br /&gt;
&lt;br /&gt;
            // Perhaps this could all be included in a save method for the form.&lt;br /&gt;
            var formdata = formfactory.getFormData();&lt;br /&gt;
            formdata[&amp;quot;lessonid&amp;quot;] = lesson.id;&lt;br /&gt;
            formdata[&amp;quot;pageid&amp;quot;] = this.id;&lt;br /&gt;
            delete formdata[&amp;quot;Jump_1&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
            var promises = ajax.call([{&lt;br /&gt;
                methodname: &#039;mod_lesson_add_page&#039;,&lt;br /&gt;
                args: formdata&lt;br /&gt;
            }]);&lt;br /&gt;
&lt;br /&gt;
            $.when.apply($.when, promises).then(function(response) {&lt;br /&gt;
                if (response.warnings.length != &amp;quot;0&amp;quot;) {&lt;br /&gt;
                    formfactory.handleErrors(response.warnings, formobject);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form data compilation for display&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var frm = new form();&lt;br /&gt;
            frm.addFieldset(&#039;general&#039;, &#039;General&#039;);&lt;br /&gt;
            textfield = new text();&lt;br /&gt;
            textfield.set_name(&#039;title&#039;);&lt;br /&gt;
            textfield.set_id(&#039;mod_lesson_title_&#039; + pageid);&lt;br /&gt;
            textfield.set_label(&#039;Page Title&#039;);&lt;br /&gt;
            textfield.set_required();&lt;br /&gt;
            textfield.set_text(lesson.pages[pageid].title);&lt;br /&gt;
            frm.addElement(textfield);&lt;br /&gt;
            selectfield = new selectElement();&lt;br /&gt;
            selectfield.set_name(&#039;Jump_1&#039;);&lt;br /&gt;
            selectfield.set_label(&#039;Jumps&#039;);&lt;br /&gt;
            selectfield.set_id(&amp;quot;mod_lesson_jump_1_&amp;quot; + pageid);&lt;br /&gt;
            selectfield.set_options(joptions);&lt;br /&gt;
            frm.addElement(selectfield);&lt;br /&gt;
            $.when(frm.printForm()).then(function(tempformstuff) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(tempformstuff); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Could do client side validation here.&lt;br /&gt;
                    if ($(&amp;quot;#mod_lesson_title_&amp;quot; + pageid).val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var textelement = $(&amp;quot;#fitem_mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                        frm.handleError(&#039;title&#039;, textelement, &#039;text&#039;, &#039;Title should not be empty&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(frm);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var formdata = {&lt;br /&gt;
                lessonpagetype: lesson.pages[pageid].qtypestring,&lt;br /&gt;
                pageid: pageid,&lt;br /&gt;
                title: {&lt;br /&gt;
                    id: &amp;quot;mod_lesson_title_&amp;quot; + pageid,&lt;br /&gt;
                    label: &amp;quot;Page Title&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                    text: lesson.pages[pageid].title,&lt;br /&gt;
                    required: 1&lt;br /&gt;
                },&lt;br /&gt;
                contents: lesson.pages[pageid].contents,&lt;br /&gt;
                select: {&lt;br /&gt;
                    id: pageid,&lt;br /&gt;
                    label: &amp;quot;Jumps&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;Jump_1&amp;quot;,&lt;br /&gt;
                    options: formfactory.formatOptions(joptions),&lt;br /&gt;
                    helpButton: &amp;quot;&amp;lt;button type=\&amp;quot;button\&amp;quot;&amp;gt;Help is here&amp;lt;/button&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
                }&lt;br /&gt;
            };&lt;br /&gt;
            $.when(templates.render(&#039;mod_lesson/page_editor&#039;, formdata)).done(function(pageeditor) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(pageeditor); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Do client side validation.&lt;br /&gt;
                    var titleelement = $(&amp;quot;#mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                    if (titleelement.val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var errors = {&lt;br /&gt;
                            errors: {&lt;br /&gt;
                                name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                                message: &amp;quot;The lesson page title should not be empty&amp;quot;&lt;br /&gt;
                            }&lt;br /&gt;
                        };&lt;br /&gt;
                        formfactory.handleErrors(errors, formdata);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(formdata);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Template for a select element==&lt;br /&gt;
Same for both.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;fitem_{{id}}&amp;quot; class=&amp;quot;fitem fitem_select {{#required}}required{{/required}} {{#advanced}}advanced{{/advanced}}&amp;quot; data-field-type=&amp;quot;select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;fitemtitle&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;label {{#hiddenLabel}}class=&amp;quot;accesshide&amp;quot;{{/hiddenLabel}} for=&amp;quot;{{id}}&amp;quot;&amp;gt;&lt;br /&gt;
            {{label}}&lt;br /&gt;
            {{#required}}{{&amp;gt;core/form-required}}{{/required}}&lt;br /&gt;
            {{#advanced}}{{&amp;gt;core/form-advanced}}{{/advanced}}&lt;br /&gt;
        &amp;lt;/label&amp;gt;&lt;br /&gt;
        {{{helpButton}}}&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;felement fselect {{#error}}error{{/error}}&amp;quot;&amp;gt;&lt;br /&gt;
        {{#error}}&lt;br /&gt;
        &amp;lt;span class=&amp;quot;error&amp;quot; tabindex=&amp;quot;0&amp;quot;&amp;gt;{{{error}}}&amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;br/&amp;gt;&lt;br /&gt;
        {{/error}}&lt;br /&gt;
        &amp;lt;select name=&amp;quot;{{name}}&amp;quot; id=&amp;quot;{{id}}&amp;quot; {{#required}}required{{/required}} {{#size}}size=&amp;quot;{{size}}&amp;quot;{{/size}}&amp;gt;&lt;br /&gt;
            {{#options}}&lt;br /&gt;
                &amp;lt;option value=&amp;quot;{{value}}&amp;quot; {{#selected}}selected{{/selected}}&amp;gt;{{text}}&amp;lt;/option&amp;gt;&lt;br /&gt;
            {{/options}}&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form template&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| &amp;lt;code xml&amp;gt;&lt;br /&gt;
{{!&lt;br /&gt;
    @template mod_lesson/page_editor&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Edit this {{lessonpagetype}} &amp;lt;/h3&amp;gt;&lt;br /&gt;
    {{#title}}&lt;br /&gt;
        {{&amp;gt;core/form-element-text}}&lt;br /&gt;
    {{/title}}&lt;br /&gt;
    &amp;lt;div&amp;gt;Page Content&amp;lt;/div&amp;gt;&lt;br /&gt;
    {{#select}}    &lt;br /&gt;
        {{&amp;gt;core/form-element-select}}&lt;br /&gt;
    {{/select}}    &lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121597</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121597"/>
		<updated>2015-11-26T01:24:14Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: form data definition&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form data compilation for display&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var frm = new form();&lt;br /&gt;
            frm.addFieldset(&#039;general&#039;, &#039;General&#039;);&lt;br /&gt;
            textfield = new text();&lt;br /&gt;
            textfield.set_name(&#039;title&#039;);&lt;br /&gt;
            textfield.set_id(&#039;mod_lesson_title_&#039; + pageid);&lt;br /&gt;
            textfield.set_label(&#039;Page Title&#039;);&lt;br /&gt;
            textfield.set_required();&lt;br /&gt;
            textfield.set_text(lesson.pages[pageid].title);&lt;br /&gt;
            frm.addElement(textfield);&lt;br /&gt;
            selectfield = new selectElement();&lt;br /&gt;
            selectfield.set_name(&#039;Jump_1&#039;);&lt;br /&gt;
            selectfield.set_label(&#039;Jumps&#039;);&lt;br /&gt;
            selectfield.set_id(&amp;quot;mod_lesson_jump_1_&amp;quot; + pageid);&lt;br /&gt;
            selectfield.set_options(joptions);&lt;br /&gt;
            frm.addElement(selectfield);&lt;br /&gt;
            $.when(frm.printForm()).then(function(tempformstuff) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(tempformstuff); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Could do client side validation here.&lt;br /&gt;
                    if ($(&amp;quot;#mod_lesson_title_&amp;quot; + pageid).val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var textelement = $(&amp;quot;#fitem_mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                        frm.handleError(&#039;title&#039;, textelement, &#039;text&#039;, &#039;Title should not be empty&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(frm);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
var formdata = {&lt;br /&gt;
                lessonpagetype: lesson.pages[pageid].qtypestring,&lt;br /&gt;
                pageid: pageid,&lt;br /&gt;
                title: {&lt;br /&gt;
                    id: &amp;quot;mod_lesson_title_&amp;quot; + pageid,&lt;br /&gt;
                    label: &amp;quot;Page Title&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                    text: lesson.pages[pageid].title,&lt;br /&gt;
                    required: 1&lt;br /&gt;
                },&lt;br /&gt;
                contents: lesson.pages[pageid].contents,&lt;br /&gt;
                select: {&lt;br /&gt;
                    id: pageid,&lt;br /&gt;
                    label: &amp;quot;Jumps&amp;quot;,&lt;br /&gt;
                    name: &amp;quot;Jump_1&amp;quot;,&lt;br /&gt;
                    options: formfactory.formatOptions(joptions),&lt;br /&gt;
                    helpButton: &amp;quot;&amp;lt;button type=\&amp;quot;button\&amp;quot;&amp;gt;Help is here&amp;lt;/button&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
                }&lt;br /&gt;
            };&lt;br /&gt;
            $.when(templates.render(&#039;mod_lesson/page_editor&#039;, formdata)).done(function(pageeditor) {&lt;br /&gt;
                $(&#039;.mod_lesson_pages&#039;).append(pageeditor); &lt;br /&gt;
                $(&#039;#mod_lesson_editor_save_btn&#039;).click(function() {&lt;br /&gt;
                    // Do client side validation.&lt;br /&gt;
                    var titleelement = $(&amp;quot;#mod_lesson_title_&amp;quot; + pageid);&lt;br /&gt;
                    if (titleelement.val() == &amp;quot;&amp;quot;) {&lt;br /&gt;
                        var errors = {&lt;br /&gt;
                            errors: {&lt;br /&gt;
                                name: &amp;quot;title&amp;quot;,&lt;br /&gt;
                                message: &amp;quot;The lesson page title should not be empty&amp;quot;&lt;br /&gt;
                            }&lt;br /&gt;
                        };&lt;br /&gt;
                        formfactory.handleErrors(errors, formdata);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        lesson.pages[pageid].save_edit_form(formdata);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                $(&#039;#mod_lesson_editor_cancel_btn&#039;).click(function() {&lt;br /&gt;
                    $(&#039;.mod_lesson_page_editor&#039;).remove();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Template for a select element==&lt;br /&gt;
Same for both.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;fitem_{{id}}&amp;quot; class=&amp;quot;fitem fitem_select {{#required}}required{{/required}} {{#advanced}}advanced{{/advanced}}&amp;quot; data-field-type=&amp;quot;select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;fitemtitle&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;label {{#hiddenLabel}}class=&amp;quot;accesshide&amp;quot;{{/hiddenLabel}} for=&amp;quot;{{id}}&amp;quot;&amp;gt;&lt;br /&gt;
            {{label}}&lt;br /&gt;
            {{#required}}{{&amp;gt;core/form-required}}{{/required}}&lt;br /&gt;
            {{#advanced}}{{&amp;gt;core/form-advanced}}{{/advanced}}&lt;br /&gt;
        &amp;lt;/label&amp;gt;&lt;br /&gt;
        {{{helpButton}}}&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;felement fselect {{#error}}error{{/error}}&amp;quot;&amp;gt;&lt;br /&gt;
        {{#error}}&lt;br /&gt;
        &amp;lt;span class=&amp;quot;error&amp;quot; tabindex=&amp;quot;0&amp;quot;&amp;gt;{{{error}}}&amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;br/&amp;gt;&lt;br /&gt;
        {{/error}}&lt;br /&gt;
        &amp;lt;select name=&amp;quot;{{name}}&amp;quot; id=&amp;quot;{{id}}&amp;quot; {{#required}}required{{/required}} {{#size}}size=&amp;quot;{{size}}&amp;quot;{{/size}}&amp;gt;&lt;br /&gt;
            {{#options}}&lt;br /&gt;
                &amp;lt;option value=&amp;quot;{{value}}&amp;quot; {{#selected}}selected{{/selected}}&amp;gt;{{text}}&amp;lt;/option&amp;gt;&lt;br /&gt;
            {{/options}}&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form template&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| &amp;lt;code xml&amp;gt;&lt;br /&gt;
{{!&lt;br /&gt;
    @template mod_lesson/page_editor&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Edit this {{lessonpagetype}} &amp;lt;/h3&amp;gt;&lt;br /&gt;
    {{#title}}&lt;br /&gt;
        {{&amp;gt;core/form-element-text}}&lt;br /&gt;
    {{/title}}&lt;br /&gt;
    &amp;lt;div&amp;gt;Page Content&amp;lt;/div&amp;gt;&lt;br /&gt;
    {{#select}}    &lt;br /&gt;
        {{&amp;gt;core/form-element-select}}&lt;br /&gt;
    {{/select}}    &lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121596</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121596"/>
		<updated>2015-11-26T01:17:25Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Select template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Template for a select element==&lt;br /&gt;
Same for both.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;fitem_{{id}}&amp;quot; class=&amp;quot;fitem fitem_select {{#required}}required{{/required}} {{#advanced}}advanced{{/advanced}}&amp;quot; data-field-type=&amp;quot;select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;fitemtitle&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;label {{#hiddenLabel}}class=&amp;quot;accesshide&amp;quot;{{/hiddenLabel}} for=&amp;quot;{{id}}&amp;quot;&amp;gt;&lt;br /&gt;
            {{label}}&lt;br /&gt;
            {{#required}}{{&amp;gt;core/form-required}}{{/required}}&lt;br /&gt;
            {{#advanced}}{{&amp;gt;core/form-advanced}}{{/advanced}}&lt;br /&gt;
        &amp;lt;/label&amp;gt;&lt;br /&gt;
        {{{helpButton}}}&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;felement fselect {{#error}}error{{/error}}&amp;quot;&amp;gt;&lt;br /&gt;
        {{#error}}&lt;br /&gt;
        &amp;lt;span class=&amp;quot;error&amp;quot; tabindex=&amp;quot;0&amp;quot;&amp;gt;{{{error}}}&amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;br/&amp;gt;&lt;br /&gt;
        {{/error}}&lt;br /&gt;
        &amp;lt;select name=&amp;quot;{{name}}&amp;quot; id=&amp;quot;{{id}}&amp;quot; {{#required}}required{{/required}} {{#size}}size=&amp;quot;{{size}}&amp;quot;{{/size}}&amp;gt;&lt;br /&gt;
            {{#options}}&lt;br /&gt;
                &amp;lt;option value=&amp;quot;{{value}}&amp;quot; {{#selected}}selected{{/selected}}&amp;gt;{{text}}&amp;lt;/option&amp;gt;&lt;br /&gt;
            {{/options}}&lt;br /&gt;
        &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form template&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| &amp;lt;code xml&amp;gt;&lt;br /&gt;
{{!&lt;br /&gt;
    @template mod_lesson/page_editor&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Edit this {{lessonpagetype}} &amp;lt;/h3&amp;gt;&lt;br /&gt;
    {{#title}}&lt;br /&gt;
        {{&amp;gt;core/form-element-text}}&lt;br /&gt;
    {{/title}}&lt;br /&gt;
    &amp;lt;div&amp;gt;Page Content&amp;lt;/div&amp;gt;&lt;br /&gt;
    {{#select}}    &lt;br /&gt;
        {{&amp;gt;core/form-element-select}}&lt;br /&gt;
    {{/select}}    &lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121595</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121595"/>
		<updated>2015-11-26T01:14:49Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Form template&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| &amp;lt;code xml&amp;gt;&lt;br /&gt;
{{!&lt;br /&gt;
    @template mod_lesson/page_editor&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Edit this {{lessonpagetype}} &amp;lt;/h3&amp;gt;&lt;br /&gt;
    {{#title}}&lt;br /&gt;
        {{&amp;gt;core/form-element-text}}&lt;br /&gt;
    {{/title}}&lt;br /&gt;
    &amp;lt;div&amp;gt;Page Content&amp;lt;/div&amp;gt;&lt;br /&gt;
    {{#select}}    &lt;br /&gt;
        {{&amp;gt;core/form-element-select}}&lt;br /&gt;
    {{/select}}    &lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121594</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121594"/>
		<updated>2015-11-26T01:10:39Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Set width&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type A&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121593</id>
		<title>User:Adrian Greeve/form comparison</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/form_comparison&amp;diff=121593"/>
		<updated>2015-11-26T01:08:18Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Library for both types&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|+ Library&lt;br /&gt;
|-&lt;br /&gt;
! Type A&lt;br /&gt;
! Type B&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var Form = function() {&lt;br /&gt;
        this._fieldsets = {};&lt;br /&gt;
        this.elements = {};&lt;br /&gt;
        this.formPage = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // These two methods would actually be using classes for the form.&lt;br /&gt;
    Form.prototype.add_top = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div class=&amp;quot;mod_lesson_page_editor&amp;quot;&amp;gt;&amp;lt;form action=&amp;quot;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.add_bottom = function() {&lt;br /&gt;
        this.formPage += &#039;&amp;lt;div&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_save_btn&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
        this.formPage += &#039;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;mod_lesson_editor_cancel_btn&amp;quot;&amp;gt;Cancel&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addFieldset = function(key, title) {&lt;br /&gt;
        this._fieldsets[key] = title;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleError = function(errorname, errorelement, elementtype, errormessage) {&lt;br /&gt;
        var index = elementtype + &amp;quot;-&amp;quot; + errorname;&lt;br /&gt;
        this.elements[index].set_error(errormessage);&lt;br /&gt;
        var htmlpromise = templates.render(this.elements[index].template, this.elements[index]);&lt;br /&gt;
        $.when(htmlpromise).then(function(newhtml) {&lt;br /&gt;
            templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.handleErrors = function(errors) {&lt;br /&gt;
&lt;br /&gt;
        // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
        var errorname = errors.errors.name;&lt;br /&gt;
        var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
        // console.log(errorelementid);&lt;br /&gt;
        var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
        // console.log(errorelement);&lt;br /&gt;
        // Get the form element type.&lt;br /&gt;
        var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
        Form.prototype.handleError.call(this, errorname, errorelement, elementtype, errors.errors.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.addElement = function(element) {&lt;br /&gt;
        var index = element.type + &amp;quot;-&amp;quot; + element.name;&lt;br /&gt;
        this.elements[index] = element;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.showElements = function() {&lt;br /&gt;
        console.log(this.elements);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    Form.prototype.printForm = function() {&lt;br /&gt;
&lt;br /&gt;
        var allpromises = [];&lt;br /&gt;
        for (index in this.elements) {&lt;br /&gt;
            allpromises.push(this.elements[index].show());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $.when.apply($.when, allpromises).then(function() {&lt;br /&gt;
            Form.prototype.add_top.call(this);&lt;br /&gt;
            var schema = arguments;&lt;br /&gt;
            for (index in schema) {&lt;br /&gt;
                this.formPage += schema[index][0];&lt;br /&gt;
            }&lt;br /&gt;
            Form.prototype.add_bottom.call(this);&lt;br /&gt;
            return this.formPage;&lt;br /&gt;
        }, function() {&lt;br /&gt;
           return &#039;default html&#039;; &lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return Form;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code javascript&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;core/templates&#039;], function($, templates) {&lt;br /&gt;
&lt;br /&gt;
    var formData;&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
&lt;br /&gt;
        handleErrors: function(errors, formdata) {&lt;br /&gt;
            // name attribute of the error.&lt;br /&gt;
            var errorname = errors.errors.name;&lt;br /&gt;
            var templatedata;&lt;br /&gt;
            for (index in formdata) {&lt;br /&gt;
                if (typeof formdata[index] == &amp;quot;object&amp;quot;) {&lt;br /&gt;
                    if (formdata[index].name == errorname) {&lt;br /&gt;
                        formdata[index].error = errors.errors.message;&lt;br /&gt;
                        templatedata = formdata[index];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // for (index in errors.errors) {&lt;br /&gt;
&lt;br /&gt;
            //     console.log(errors.errors[&amp;quot;name&amp;quot;]);&lt;br /&gt;
            // }&lt;br /&gt;
&lt;br /&gt;
            // Need to loop through all potential errors.&lt;br /&gt;
&lt;br /&gt;
            var errorelementid = $(&amp;quot;:input[name=&amp;quot; + errorname + &amp;quot;]&amp;quot;).attr(&amp;quot;id&amp;quot;);&lt;br /&gt;
            // console.log(errorelementid);&lt;br /&gt;
            var errorelement = $(&amp;quot;#fitem_&amp;quot; + errorelementid);&lt;br /&gt;
            // console.log(errorelement);&lt;br /&gt;
            // Get the form element type.&lt;br /&gt;
            var elementtype = errorelement.attr(&amp;quot;data-field-type&amp;quot;);&lt;br /&gt;
            // console.log(elementtype);&lt;br /&gt;
            var template = &#039;core/form-element-&#039; + elementtype;&lt;br /&gt;
            var templatepromise = templates.render(template, templatedata);&lt;br /&gt;
            $.when(templatepromise).then(function(newhtml) {&lt;br /&gt;
                templates.replaceNode(errorelement, newhtml);&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        getFormData: function() {&lt;br /&gt;
            formData = $(&#039;form&#039;).serializeArray();&lt;br /&gt;
            var tempstorage = {};&lt;br /&gt;
            for (index in formData) {&lt;br /&gt;
                var name = formData[index].name;&lt;br /&gt;
                if (name !== &#039;query&#039;) {&lt;br /&gt;
                    tempstorage[name] = formData[index].value;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return tempstorage;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Format a normal array into an object for a select form element.&lt;br /&gt;
         *&lt;br /&gt;
         * @param {array} options An array of options.&lt;br /&gt;
         * @param {string} selected The selected option. Needs to match the array index.&lt;br /&gt;
         * @return {object} An options object that can be used with a select form element.&lt;br /&gt;
         */&lt;br /&gt;
        formatOptions: function(options, selected) {&lt;br /&gt;
            var returnoptions = [];&lt;br /&gt;
            var select = 0;&lt;br /&gt;
            if (selected !== &#039;undefined&#039;) {&lt;br /&gt;
                select = selected&lt;br /&gt;
            }&lt;br /&gt;
            for (index in options) {&lt;br /&gt;
                if (index == selected) {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                        selected: select&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    returnoptions.push({&lt;br /&gt;
                        value: index,&lt;br /&gt;
                        text: options[index],&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return returnoptions;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=119390</id>
		<title>Grade import</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=119390"/>
		<updated>2015-07-27T06:09:01Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Importing grades */ - Inclusion of note 3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
==Importing grades==&lt;br /&gt;
Grades may be imported as a CSV or XML file, or by pasting from a spreadsheet. &lt;br /&gt;
&lt;br /&gt;
The import file format is the same as the corresponding export format. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1:&#039;&#039;&#039; Grade import is equivalent to manual grading in the [[Grader report|grader report]]. Thus, if grades for a particular  Moodle activity such as an assignment are imported, they can no longer be edited via the assignment submission page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2:&#039;&#039;&#039;  To import grades above 100% you need to check the  &#039;unlimitedgrades&#039; and &#039;gradepointmax&#039; settings in &#039;&#039;Site administration&amp;gt;Administration&amp;gt;Grades&amp;gt;General settings&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 3:&#039;&#039;&#039; Importing feedback will also overwrite any grades that are linked to that assessment. Please include both feedback and grades for the activity when mapping and importing grades via CSV. If both columns are not included then all grades for that activity will be lost.&lt;br /&gt;
&lt;br /&gt;
[[Image:Csv grade import.png|thumb|CSV grade import]]&lt;br /&gt;
To import grades into the gradebook:&lt;br /&gt;
&lt;br /&gt;
# Decide on an import format - CSV or XML file, or paste from spreadsheet (see below) - then [[Grade export|export some grades]] using the corresponding export format.&lt;br /&gt;
# Edit the export file as appropriate and save it.&lt;br /&gt;
# Tip:  If you opened your exported file in Excel, don&#039;t add columns there because Moodle will reject the import if there are new columns that didn&#039;t exist in the exported file. If you need to add columns, do that in Moodle BEFORE you export your gradebook.&lt;br /&gt;
# Select your chosen import format from the gradebook dropdown menu.&lt;br /&gt;
# Browse and upload your previously saved file.&lt;br /&gt;
# Set options as required.&lt;br /&gt;
# Click the &amp;quot;Upload grades&amp;quot; button.&lt;br /&gt;
# CSV import only: Preview the grade import and choose the column mapping then click the &amp;quot;Upload grades&amp;quot; button to complete the grade import.&lt;br /&gt;
## Tip: By default &amp;quot;Map from&amp;quot; is set to First Name, and &amp;quot;Map to&amp;quot; to userid. Change both dropdowns to: &amp;quot;Email Address&amp;quot; to &amp;quot;useremail&amp;quot;, or to &amp;quot;Id Number&amp;quot; to &amp;quot;useridnumber&amp;quot; (assuming that your users have ID number fields filled in in their profiles).&lt;br /&gt;
## Tip: Unlike in most email programs, email addresses are case sensitive in grade import files.  (This should eventually be fixed as per MDL-29315.)&lt;br /&gt;
&lt;br /&gt;
You need two permissions to import grades: (1) general permission to import grades and (2) permission to import grades in a particular format. For example, to import CSV grades you need moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow and gradeimport/csv:view (&amp;quot;Import grades from CSV&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==CSV import==&lt;br /&gt;
&lt;br /&gt;
CSV import is more flexible than XML import, as you may choose the column mapping.&lt;br /&gt;
&lt;br /&gt;
===Grade Mapping===&lt;br /&gt;
&lt;br /&gt;
After selecting your CSV for import you&#039;ll be prompted to map user fields and grade items to the new column headers to ensure that there is a match. More than one item can be mapped to the same grade item in your destination course so be mindful of the mapping to ensure that grade data is imported properly, any collisions (i.e. if two or more fields are mapped to the same but duplicate data exists) will cause an error. User grade data for users not yet enrolled to the destination course will be noted (and once enrolled their grade data will display).&lt;br /&gt;
&lt;br /&gt;
===Encoding===&lt;br /&gt;
&lt;br /&gt;
If you are unsure of the encoding of your CSV file, try selecting the second option in the encoding dropdown menu. If you&#039;ve used Excel to produce the CSV file the second option WINDOWS-xxx encoding is probably the correct one. The grade import preview will tell you if you guessed the encoding correctly.&lt;br /&gt;
&lt;br /&gt;
===Verbose scales===&lt;br /&gt;
&lt;br /&gt;
Scales can be either specified as a raw id - eg. 0, 1, 2, 3, etc. or as a string, eg. &amp;quot;good&amp;quot;, &amp;quot;bad&amp;quot;, &amp;quot;not very bad&amp;quot;. The later format is called &amp;quot;verbose&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Force import===&lt;br /&gt;
&lt;br /&gt;
This prevents grade overriding during the grade importing in a scenario where more than one teacher exports the course grades and then re-imports them. If a second teacher exports the grades and tries to import them,  the following error message will be displayed and the grade importing procedure will be aborted:&lt;br /&gt;
&amp;lt;pre&amp;gt;(&#039;&#039;Student name&#039;&#039;) grades have not been imported because the grades in the import file are older than in the grader report. To proceed with the grade import anyway, use the force import option.&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
It will not be possible to  import a file that had been  exported file longer than a year ago,  one with dates in the future. However, in cases where a teacher needs to import the grades regardless, they should use the  &#039;&#039;&#039;Force import&#039;&#039;&#039;. option. This will then import the grades irrespective of the dates.&lt;br /&gt;
&lt;br /&gt;
==Paste from spreadsheet==&lt;br /&gt;
&lt;br /&gt;
Grades may be pasted directly from a spreadsheet such as Excel or Libre Office:&lt;br /&gt;
&lt;br /&gt;
1) Ensure you have the correct column names for your grades (eg the assignment title or manual grade) It might help to  download and edit the relevant students and graded information by using the [[Grade export]] feature.&lt;br /&gt;
&lt;br /&gt;
2) For the students you need either their username, their ID or their email address. Add the grades you need and copy the relevant section:&lt;br /&gt;
[[File:pastegrades1.png|thumb|center|400px]]&lt;br /&gt;
3) In your course, go to &#039;&#039;Grade administration&amp;gt;Import&amp;gt;Paste from spreadsheet&#039;&#039; and paste:&lt;br /&gt;
[[File:pastegrades2.png|thumb|center|400px]]&lt;br /&gt;
4) In the preview, ensure you match up the identifier you used for the students -so if you used &#039;username&#039;, ensure it maps to &#039;username&#039;. Do the same for your graded activities:&lt;br /&gt;
[[File:pastegrades3.png|thumb|400px|center]]&lt;br /&gt;
5) If everything has been correctly mapped (See grade mapping above), you should get a success message and the grades will have been added, displaying in a different colour to show they were imported directly into the gradebook:&lt;br /&gt;
{|&lt;br /&gt;
| [[File:pastegrades4.png|thumb|400px]]&lt;br /&gt;
| [[File:pastegrades5.png|thumb|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Paste from a spreadsheet requires similar permissions to a csv file import: (1) general permission to import grades and (2) permission to import grades in a particular format i.e. moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow and gradeimport/direct:view (&amp;quot;Import grades from spreadsheet&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==XML import==&lt;br /&gt;
&lt;br /&gt;
Before importing an XML file you will need to ensure that all of the students that you want to alter grades for have their ID number field filled out. This is located in the &amp;quot;Optional&amp;quot; section of the user edit profile page.&lt;br /&gt;
You will also need to set the ID number of the activity as well. You can find this under &amp;quot;Common module settings&amp;quot; when editing the activity.&lt;br /&gt;
&lt;br /&gt;
The format for the XML should be as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;results&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;activityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;53.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;differentactivityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;73.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;lt;/results&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a working example try exporting the gradebook as an xml file and view the format.&lt;br /&gt;
&lt;br /&gt;
===Remote file URL===&lt;br /&gt;
&lt;br /&gt;
The remote file URL field is for fetching data from a remote server, such as a student information system.&lt;br /&gt;
&lt;br /&gt;
==Grade import capabilities==&lt;br /&gt;
&lt;br /&gt;
* [[Capabilities/gradeimport/csv:view|Import grades from CSV]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:publish|Publish import grades from XML]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:view|Import grades from XML]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=85944 Gradebook confusion]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=92081 Can external software insert data into the gradebook?]&lt;br /&gt;
&lt;br /&gt;
[[ja:評定のインポート]]&lt;br /&gt;
[[de:Bewertungen importieren]]&lt;br /&gt;
[[es:Importar calificaciones]]&lt;br /&gt;
[[fr:Importation des notes]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=119389</id>
		<title>Grade import</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=119389"/>
		<updated>2015-07-27T06:07:53Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Grade Mapping */ moving content&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
==Importing grades==&lt;br /&gt;
Grades may be imported as a CSV or XML file, or by pasting from a spreadsheet. &lt;br /&gt;
&lt;br /&gt;
The import file format is the same as the corresponding export format. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1:&#039;&#039;&#039; Grade import is equivalent to manual grading in the [[Grader report|grader report]]. Thus, if grades for a particular  Moodle activity such as an assignment are imported, they can no longer be edited via the assignment submission page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2:&#039;&#039;&#039;  To import grades above 100% you need to check the  &#039;unlimitedgrades&#039; and &#039;gradepointmax&#039; settings in &#039;&#039;Site administration&amp;gt;Administration&amp;gt;Grades&amp;gt;General settings&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Csv grade import.png|thumb|CSV grade import]]&lt;br /&gt;
To import grades into the gradebook:&lt;br /&gt;
&lt;br /&gt;
# Decide on an import format - CSV or XML file, or paste from spreadsheet (see below) - then [[Grade export|export some grades]] using the corresponding export format.&lt;br /&gt;
# Edit the export file as appropriate and save it.&lt;br /&gt;
# Tip:  If you opened your exported file in Excel, don&#039;t add columns there because Moodle will reject the import if there are new columns that didn&#039;t exist in the exported file. If you need to add columns, do that in Moodle BEFORE you export your gradebook.&lt;br /&gt;
# Select your chosen import format from the gradebook dropdown menu.&lt;br /&gt;
# Browse and upload your previously saved file.&lt;br /&gt;
# Set options as required.&lt;br /&gt;
# Click the &amp;quot;Upload grades&amp;quot; button.&lt;br /&gt;
# CSV import only: Preview the grade import and choose the column mapping then click the &amp;quot;Upload grades&amp;quot; button to complete the grade import.&lt;br /&gt;
## Tip: By default &amp;quot;Map from&amp;quot; is set to First Name, and &amp;quot;Map to&amp;quot; to userid. Change both dropdowns to: &amp;quot;Email Address&amp;quot; to &amp;quot;useremail&amp;quot;, or to &amp;quot;Id Number&amp;quot; to &amp;quot;useridnumber&amp;quot; (assuming that your users have ID number fields filled in in their profiles).&lt;br /&gt;
## Tip: Unlike in most email programs, email addresses are case sensitive in grade import files.  (This should eventually be fixed as per MDL-29315.)&lt;br /&gt;
&lt;br /&gt;
You need two permissions to import grades: (1) general permission to import grades and (2) permission to import grades in a particular format. For example, to import CSV grades you need moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow and gradeimport/csv:view (&amp;quot;Import grades from CSV&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==CSV import==&lt;br /&gt;
&lt;br /&gt;
CSV import is more flexible than XML import, as you may choose the column mapping.&lt;br /&gt;
&lt;br /&gt;
===Grade Mapping===&lt;br /&gt;
&lt;br /&gt;
After selecting your CSV for import you&#039;ll be prompted to map user fields and grade items to the new column headers to ensure that there is a match. More than one item can be mapped to the same grade item in your destination course so be mindful of the mapping to ensure that grade data is imported properly, any collisions (i.e. if two or more fields are mapped to the same but duplicate data exists) will cause an error. User grade data for users not yet enrolled to the destination course will be noted (and once enrolled their grade data will display).&lt;br /&gt;
&lt;br /&gt;
===Encoding===&lt;br /&gt;
&lt;br /&gt;
If you are unsure of the encoding of your CSV file, try selecting the second option in the encoding dropdown menu. If you&#039;ve used Excel to produce the CSV file the second option WINDOWS-xxx encoding is probably the correct one. The grade import preview will tell you if you guessed the encoding correctly.&lt;br /&gt;
&lt;br /&gt;
===Verbose scales===&lt;br /&gt;
&lt;br /&gt;
Scales can be either specified as a raw id - eg. 0, 1, 2, 3, etc. or as a string, eg. &amp;quot;good&amp;quot;, &amp;quot;bad&amp;quot;, &amp;quot;not very bad&amp;quot;. The later format is called &amp;quot;verbose&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Force import===&lt;br /&gt;
&lt;br /&gt;
This prevents grade overriding during the grade importing in a scenario where more than one teacher exports the course grades and then re-imports them. If a second teacher exports the grades and tries to import them,  the following error message will be displayed and the grade importing procedure will be aborted:&lt;br /&gt;
&amp;lt;pre&amp;gt;(&#039;&#039;Student name&#039;&#039;) grades have not been imported because the grades in the import file are older than in the grader report. To proceed with the grade import anyway, use the force import option.&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
It will not be possible to  import a file that had been  exported file longer than a year ago,  one with dates in the future. However, in cases where a teacher needs to import the grades regardless, they should use the  &#039;&#039;&#039;Force import&#039;&#039;&#039;. option. This will then import the grades irrespective of the dates.&lt;br /&gt;
&lt;br /&gt;
==Paste from spreadsheet==&lt;br /&gt;
&lt;br /&gt;
Grades may be pasted directly from a spreadsheet such as Excel or Libre Office:&lt;br /&gt;
&lt;br /&gt;
1) Ensure you have the correct column names for your grades (eg the assignment title or manual grade) It might help to  download and edit the relevant students and graded information by using the [[Grade export]] feature.&lt;br /&gt;
&lt;br /&gt;
2) For the students you need either their username, their ID or their email address. Add the grades you need and copy the relevant section:&lt;br /&gt;
[[File:pastegrades1.png|thumb|center|400px]]&lt;br /&gt;
3) In your course, go to &#039;&#039;Grade administration&amp;gt;Import&amp;gt;Paste from spreadsheet&#039;&#039; and paste:&lt;br /&gt;
[[File:pastegrades2.png|thumb|center|400px]]&lt;br /&gt;
4) In the preview, ensure you match up the identifier you used for the students -so if you used &#039;username&#039;, ensure it maps to &#039;username&#039;. Do the same for your graded activities:&lt;br /&gt;
[[File:pastegrades3.png|thumb|400px|center]]&lt;br /&gt;
5) If everything has been correctly mapped (See grade mapping above), you should get a success message and the grades will have been added, displaying in a different colour to show they were imported directly into the gradebook:&lt;br /&gt;
{|&lt;br /&gt;
| [[File:pastegrades4.png|thumb|400px]]&lt;br /&gt;
| [[File:pastegrades5.png|thumb|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Paste from a spreadsheet requires similar permissions to a csv file import: (1) general permission to import grades and (2) permission to import grades in a particular format i.e. moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow and gradeimport/direct:view (&amp;quot;Import grades from spreadsheet&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==XML import==&lt;br /&gt;
&lt;br /&gt;
Before importing an XML file you will need to ensure that all of the students that you want to alter grades for have their ID number field filled out. This is located in the &amp;quot;Optional&amp;quot; section of the user edit profile page.&lt;br /&gt;
You will also need to set the ID number of the activity as well. You can find this under &amp;quot;Common module settings&amp;quot; when editing the activity.&lt;br /&gt;
&lt;br /&gt;
The format for the XML should be as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;results&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;activityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;53.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;differentactivityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;73.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;lt;/results&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a working example try exporting the gradebook as an xml file and view the format.&lt;br /&gt;
&lt;br /&gt;
===Remote file URL===&lt;br /&gt;
&lt;br /&gt;
The remote file URL field is for fetching data from a remote server, such as a student information system.&lt;br /&gt;
&lt;br /&gt;
==Grade import capabilities==&lt;br /&gt;
&lt;br /&gt;
* [[Capabilities/gradeimport/csv:view|Import grades from CSV]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:publish|Publish import grades from XML]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:view|Import grades from XML]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=85944 Gradebook confusion]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=92081 Can external software insert data into the gradebook?]&lt;br /&gt;
&lt;br /&gt;
[[ja:評定のインポート]]&lt;br /&gt;
[[de:Bewertungen importieren]]&lt;br /&gt;
[[es:Importar calificaciones]]&lt;br /&gt;
[[fr:Importation des notes]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=119388</id>
		<title>Grade import</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=119388"/>
		<updated>2015-07-27T06:04:23Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Grade Mapping */ notice for overriding feedback&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
==Importing grades==&lt;br /&gt;
Grades may be imported as a CSV or XML file, or by pasting from a spreadsheet. &lt;br /&gt;
&lt;br /&gt;
The import file format is the same as the corresponding export format. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1:&#039;&#039;&#039; Grade import is equivalent to manual grading in the [[Grader report|grader report]]. Thus, if grades for a particular  Moodle activity such as an assignment are imported, they can no longer be edited via the assignment submission page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2:&#039;&#039;&#039;  To import grades above 100% you need to check the  &#039;unlimitedgrades&#039; and &#039;gradepointmax&#039; settings in &#039;&#039;Site administration&amp;gt;Administration&amp;gt;Grades&amp;gt;General settings&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Csv grade import.png|thumb|CSV grade import]]&lt;br /&gt;
To import grades into the gradebook:&lt;br /&gt;
&lt;br /&gt;
# Decide on an import format - CSV or XML file, or paste from spreadsheet (see below) - then [[Grade export|export some grades]] using the corresponding export format.&lt;br /&gt;
# Edit the export file as appropriate and save it.&lt;br /&gt;
# Tip:  If you opened your exported file in Excel, don&#039;t add columns there because Moodle will reject the import if there are new columns that didn&#039;t exist in the exported file. If you need to add columns, do that in Moodle BEFORE you export your gradebook.&lt;br /&gt;
# Select your chosen import format from the gradebook dropdown menu.&lt;br /&gt;
# Browse and upload your previously saved file.&lt;br /&gt;
# Set options as required.&lt;br /&gt;
# Click the &amp;quot;Upload grades&amp;quot; button.&lt;br /&gt;
# CSV import only: Preview the grade import and choose the column mapping then click the &amp;quot;Upload grades&amp;quot; button to complete the grade import.&lt;br /&gt;
## Tip: By default &amp;quot;Map from&amp;quot; is set to First Name, and &amp;quot;Map to&amp;quot; to userid. Change both dropdowns to: &amp;quot;Email Address&amp;quot; to &amp;quot;useremail&amp;quot;, or to &amp;quot;Id Number&amp;quot; to &amp;quot;useridnumber&amp;quot; (assuming that your users have ID number fields filled in in their profiles).&lt;br /&gt;
## Tip: Unlike in most email programs, email addresses are case sensitive in grade import files.  (This should eventually be fixed as per MDL-29315.)&lt;br /&gt;
&lt;br /&gt;
You need two permissions to import grades: (1) general permission to import grades and (2) permission to import grades in a particular format. For example, to import CSV grades you need moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow and gradeimport/csv:view (&amp;quot;Import grades from CSV&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==CSV import==&lt;br /&gt;
&lt;br /&gt;
CSV import is more flexible than XML import, as you may choose the column mapping.&lt;br /&gt;
&lt;br /&gt;
===Grade Mapping===&lt;br /&gt;
&lt;br /&gt;
After selecting your CSV for import you&#039;ll be prompted to map user fields and grade items to the new column headers to ensure that there is a match. More than one item can be mapped to the same grade item in your destination course so be mindful of the mapping to ensure that grade data is imported properly, any collisions (i.e. if two or more fields are mapped to the same but duplicate data exists) will cause an error. User grade data for users not yet enrolled to the destination course will be noted (and once enrolled their grade data will display).&lt;br /&gt;
&lt;br /&gt;
Importing feedback will also overwrite any grades that are linked to that assessment. Please include both feedback and grades for the activity when mapping and importing grades via CSV. If both columns are not included then all grades for that activity will be lost.&lt;br /&gt;
&lt;br /&gt;
===Encoding===&lt;br /&gt;
&lt;br /&gt;
If you are unsure of the encoding of your CSV file, try selecting the second option in the encoding dropdown menu. If you&#039;ve used Excel to produce the CSV file the second option WINDOWS-xxx encoding is probably the correct one. The grade import preview will tell you if you guessed the encoding correctly.&lt;br /&gt;
&lt;br /&gt;
===Verbose scales===&lt;br /&gt;
&lt;br /&gt;
Scales can be either specified as a raw id - eg. 0, 1, 2, 3, etc. or as a string, eg. &amp;quot;good&amp;quot;, &amp;quot;bad&amp;quot;, &amp;quot;not very bad&amp;quot;. The later format is called &amp;quot;verbose&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Force import===&lt;br /&gt;
&lt;br /&gt;
This prevents grade overriding during the grade importing in a scenario where more than one teacher exports the course grades and then re-imports them. If a second teacher exports the grades and tries to import them,  the following error message will be displayed and the grade importing procedure will be aborted:&lt;br /&gt;
&amp;lt;pre&amp;gt;(&#039;&#039;Student name&#039;&#039;) grades have not been imported because the grades in the import file are older than in the grader report. To proceed with the grade import anyway, use the force import option.&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
It will not be possible to  import a file that had been  exported file longer than a year ago,  one with dates in the future. However, in cases where a teacher needs to import the grades regardless, they should use the  &#039;&#039;&#039;Force import&#039;&#039;&#039;. option. This will then import the grades irrespective of the dates.&lt;br /&gt;
&lt;br /&gt;
==Paste from spreadsheet==&lt;br /&gt;
&lt;br /&gt;
Grades may be pasted directly from a spreadsheet such as Excel or Libre Office:&lt;br /&gt;
&lt;br /&gt;
1) Ensure you have the correct column names for your grades (eg the assignment title or manual grade) It might help to  download and edit the relevant students and graded information by using the [[Grade export]] feature.&lt;br /&gt;
&lt;br /&gt;
2) For the students you need either their username, their ID or their email address. Add the grades you need and copy the relevant section:&lt;br /&gt;
[[File:pastegrades1.png|thumb|center|400px]]&lt;br /&gt;
3) In your course, go to &#039;&#039;Grade administration&amp;gt;Import&amp;gt;Paste from spreadsheet&#039;&#039; and paste:&lt;br /&gt;
[[File:pastegrades2.png|thumb|center|400px]]&lt;br /&gt;
4) In the preview, ensure you match up the identifier you used for the students -so if you used &#039;username&#039;, ensure it maps to &#039;username&#039;. Do the same for your graded activities:&lt;br /&gt;
[[File:pastegrades3.png|thumb|400px|center]]&lt;br /&gt;
5) If everything has been correctly mapped (See grade mapping above), you should get a success message and the grades will have been added, displaying in a different colour to show they were imported directly into the gradebook:&lt;br /&gt;
{|&lt;br /&gt;
| [[File:pastegrades4.png|thumb|400px]]&lt;br /&gt;
| [[File:pastegrades5.png|thumb|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Paste from a spreadsheet requires similar permissions to a csv file import: (1) general permission to import grades and (2) permission to import grades in a particular format i.e. moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow and gradeimport/direct:view (&amp;quot;Import grades from spreadsheet&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==XML import==&lt;br /&gt;
&lt;br /&gt;
Before importing an XML file you will need to ensure that all of the students that you want to alter grades for have their ID number field filled out. This is located in the &amp;quot;Optional&amp;quot; section of the user edit profile page.&lt;br /&gt;
You will also need to set the ID number of the activity as well. You can find this under &amp;quot;Common module settings&amp;quot; when editing the activity.&lt;br /&gt;
&lt;br /&gt;
The format for the XML should be as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;results&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;activityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;53.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;differentactivityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;73.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;lt;/results&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a working example try exporting the gradebook as an xml file and view the format.&lt;br /&gt;
&lt;br /&gt;
===Remote file URL===&lt;br /&gt;
&lt;br /&gt;
The remote file URL field is for fetching data from a remote server, such as a student information system.&lt;br /&gt;
&lt;br /&gt;
==Grade import capabilities==&lt;br /&gt;
&lt;br /&gt;
* [[Capabilities/gradeimport/csv:view|Import grades from CSV]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:publish|Publish import grades from XML]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:view|Import grades from XML]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=85944 Gradebook confusion]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=92081 Can external software insert data into the gradebook?]&lt;br /&gt;
&lt;br /&gt;
[[ja:評定のインポート]]&lt;br /&gt;
[[de:Bewertungen importieren]]&lt;br /&gt;
[[es:Importar calificaciones]]&lt;br /&gt;
[[fr:Importation des notes]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/howto_fix_gradebook_issues&amp;diff=119282</id>
		<title>User:Adrian Greeve/howto fix gradebook issues</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=User:Adrian_Greeve/howto_fix_gradebook_issues&amp;diff=119282"/>
		<updated>2015-07-20T02:43:37Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: First edit - main content&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How to fix Grade book issues==&lt;br /&gt;
&lt;br /&gt;
There has been a policy decision that any fixes to the grade book must not result in any changes to grades. Some fixes may result in grades being changed and in these situations we need to freeze the grade book and let the teacher / admin / higher power agree to applying the change.&lt;br /&gt;
&lt;br /&gt;
For future fixes to the grade book we will be putting revision numbers and nested code into the grade book libraries.&lt;br /&gt;
&lt;br /&gt;
===Fixing the issue===&lt;br /&gt;
&lt;br /&gt;
Choose a freeze number that is greater than the current build number but will be less than the next build number (This needs explaining)&lt;br /&gt;
&lt;br /&gt;
When making changes wrap your code in an if statement. &lt;br /&gt;
&lt;br /&gt;
example: &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$gradebookcalculationsfreeze = get_config(&#039;core&#039;, &#039;gradebook_calculations_freeze_&#039; . $courseid);&lt;br /&gt;
// Stick with the original code if the grade book is frozen.&lt;br /&gt;
if ($gradebookcalculationsfreeze &amp;amp;&amp;amp; (int)$gradebookcalculationsfreeze &amp;lt;= {your code freeze number}) {&lt;br /&gt;
    {original code goes here}&lt;br /&gt;
} else {&lt;br /&gt;
    {new fixed code goes here}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Enter in details about your fix at https://docs.moodle.org/310/en/Gradebook_calculation_changes&lt;br /&gt;
&lt;br /&gt;
===Upgrade code===&lt;br /&gt;
&lt;br /&gt;
Code will be required to determine if the site being upgraded is affected. If so then it should be flagged to be frozen.&lt;br /&gt;
&lt;br /&gt;
example (lib/db/upgrade.php):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    if ($oldversion &amp;lt; 2015062500.01) {&lt;br /&gt;
        // MDL-48239. Changed calculated grade items so that the maximum and minimum grade can be set.&lt;br /&gt;
&lt;br /&gt;
        // If the changes are accepted and a regrade is done on the gradebook then some grades may change significantly.&lt;br /&gt;
        // This is here to freeze the gradebook in affected courses.&lt;br /&gt;
&lt;br /&gt;
        // This script is included in each major version upgrade process so make sure we don&#039;t run it twice.&lt;br /&gt;
        if (empty($CFG-&amp;gt;upgrade_calculatedgradeitemsignored)) {&lt;br /&gt;
            upgrade_calculated_grade_items();&lt;br /&gt;
&lt;br /&gt;
            // To skip running the same script on the upgrade to the next major release.&lt;br /&gt;
            set_config(&#039;upgrade_calculatedgradeitemsignored&#039;, 1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Main savepoint reached.&lt;br /&gt;
        upgrade_main_savepoint(true, 2015062500.01);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The code for doing this check should be located in lib/db/upgradelib.php so that it can also be run when a course is being restored.&lt;br /&gt;
&lt;br /&gt;
===New installations===&lt;br /&gt;
&lt;br /&gt;
Make sure to not run the upgrade step with the new installation&lt;br /&gt;
&lt;br /&gt;
example (lib/db/install.php:: xmldb_main_install() line 135): &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &#039;upgrade_calculatedgradeitemsignored&#039; =&amp;gt; 1, // New installs should not run this upgrade step.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restoration code===&lt;br /&gt;
&lt;br /&gt;
Code should be generated so that a regrading of the gradebook will fix the problem. Any solution that requires direct alteration of the grades in the database will result in an extremely complex set of restore code.&lt;br /&gt;
&lt;br /&gt;
example (backup/moodle2/restore_stepslib.php):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Calculated grade items need recalculating for backups made between 2.8 release (20141110) and the fix release (20150627).&lt;br /&gt;
if (!$gradebookcalculationsfreeze &amp;amp;&amp;amp; $backupbuild &amp;gt;= 20141110 &amp;amp;&amp;amp; $backupbuild &amp;lt; 20150627) {&lt;br /&gt;
    require_once($CFG-&amp;gt;libdir . &#039;/db/upgradelib.php&#039;);&lt;br /&gt;
    upgrade_calculated_grade_items($this-&amp;gt;get_courseid());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===Tests===&lt;br /&gt;
&lt;br /&gt;
Create a behat test to make sure that when the gradebook is frozen that grades are not changed.&lt;br /&gt;
Create a behat test to make sure that when the gradebook is not frozen that the issue is solved.&lt;br /&gt;
&lt;br /&gt;
Create unit tests to check functions in the upgradelib.php file.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=119094</id>
		<title>Gradebook calculation changes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=119094"/>
		<updated>2015-06-26T07:12:58Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: update to grade build number&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: The following information only applies if you see a message displayed in the gradebook following a site upgrade, or after restoring a course backup from a different version of Moodle.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occasionally there are error fixes which can affect gradebook calculations in certain courses. As part of the upgrade process, such courses are identified and a message is displayed in the gradebook informing teachers that error fixes may result in some grades being changed. Details of these changes are provided below. The 8-digit version number is the date of the fix.&lt;br /&gt;
&lt;br /&gt;
It is recommended that the errors are fixed by clicking the button &#039;Accept grade changes and fix calculation errors&#039;. Until this is done, the message will continue to be displayed in the gradebook (only for teachers; students can&#039;t see it). The old gradebook calculations will still be used (ensuring grades remain unchanged), however they are likely to result in more errors if grades are updated in the future.&lt;br /&gt;
&lt;br /&gt;
=== 20150619 - Calculation of extra credit item weights when using natural aggregation ===&lt;br /&gt;
&lt;br /&gt;
Two errors were fixed:&lt;br /&gt;
# Overriding the weight of the extra credit item can lead to changes in other items&#039; weights and random final grades&lt;br /&gt;
# The automatic weight of an extra credit item was dependent on the overrides of the normal item&#039;s weights&lt;br /&gt;
&lt;br /&gt;
The second error was especially noticeable for students with excluded grade items (for example, when they are hidden or empty). &lt;br /&gt;
&lt;br /&gt;
For example, a category has two normal grade items and one extra credit item. If the maximum grades for each item are the same, the weights of the three items will be: 50%, 50% and 50%. However if the weights of the normal items are overridden to be 50% and 50%, then the weight of the extra credit item would become 0%. If the teacher overrode the weight of the first item to 80%, the second item would automatically become 20% (correct) and the extra credit would also become 20% (incorrect). &lt;br /&gt;
&lt;br /&gt;
The correct behaviour (after the fix): If the weight of extra credit item is not overridden, it should be itemmaxgrade / totalmaxgrade , where totalmaxgrade does not include the extra credit item. In the example, the weight of the extra credit item should always be 50%.&lt;br /&gt;
&lt;br /&gt;
See MDL-49257 for further details including screenshots.&lt;br /&gt;
&lt;br /&gt;
=== 20150627 - Calculated grade items ===&lt;br /&gt;
&lt;br /&gt;
Three errors were fixed:&lt;br /&gt;
# Changing the maxgrade of a category item with a calculation using &amp;quot;Natural aggregation&amp;quot; is now possible.&lt;br /&gt;
# A change to the minimum or maximum grade value will immediately be displayed without the need for regrading to be triggered regardless of what the setting &amp;quot;Min and max grades used in calculation&amp;quot; is set to.&lt;br /&gt;
# With the setting &amp;quot;Min and max grades used in calculation&amp;quot; set to &amp;quot;initial min and max grades&amp;quot; calculated grade items are correctly displayed out of the max and min grade for that item.&lt;br /&gt;
&lt;br /&gt;
The first two errors should have no impact on existing grades in the gradebook. The last error fix does have the potential to change existing grades. If you have the setting of &amp;quot;Min and max grades used in calculation&amp;quot; set to &amp;quot;initial min and max grades&amp;quot;, calculated grade items with a maximum and minimum grade value that is not 100 and 0 respectively will have it changed to match the current minimum and maximum.&lt;br /&gt;
&lt;br /&gt;
See MDL-48239 for further details.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=119092</id>
		<title>Gradebook calculation changes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Gradebook_calculation_changes&amp;diff=119092"/>
		<updated>2015-06-26T03:46:40Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: 20150620 information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;Note: The following information only applies if you see a message displayed in the gradebook following a site upgrade, or after restoring a course backup from a different version of Moodle.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Occasionally there are error fixes which can affect gradebook calculations in certain courses. As part of the upgrade process, such courses are identified and a message is displayed in the gradebook informing teachers that error fixes may result in some grades being changed. Details of these changes are provided below. The 8-digit version number is the date of the fix.&lt;br /&gt;
&lt;br /&gt;
It is recommended that the errors are fixed by clicking the button &#039;Accept grade changes and fix calculation errors&#039;. Until this is done, the message will continue to be displayed in the gradebook (only for teachers; students can&#039;t see it). The old gradebook calculations will still be used (ensuring grades remain unchanged), however they are likely to result in more errors if grades are updated in the future.&lt;br /&gt;
&lt;br /&gt;
=== 20150619 - Calculation of extra credit item weights when using natural aggregation ===&lt;br /&gt;
&lt;br /&gt;
Two errors were fixed:&lt;br /&gt;
# Overriding the weight of the extra credit item can lead to changes in other items&#039; weights and random final grades&lt;br /&gt;
# The automatic weight of an extra credit item was dependent on the overrides of the normal item&#039;s weights&lt;br /&gt;
&lt;br /&gt;
The second error was especially noticeable for students with excluded grade items (for example, when they are hidden or empty). &lt;br /&gt;
&lt;br /&gt;
For example, a category has two normal grade items and one extra credit item. If the maximum grades for each item are the same, the weights of the three items will be: 50%, 50% and 50%. However if the weights of the normal items are overridden to be 50% and 50%, then the weight of the extra credit item would become 0%. If the teacher overrode the weight of the first item to 80%, the second item would automatically become 20% (correct) and the extra credit would also become 20% (incorrect). &lt;br /&gt;
&lt;br /&gt;
The correct behaviour (after the fix): If the weight of extra credit item is not overridden, it should be itemmaxgrade / totalmaxgrade , where totalmaxgrade does not include the extra credit item. In the example, the weight of the extra credit item should always be 50%.&lt;br /&gt;
&lt;br /&gt;
See MDL-49257 for further details including screenshots.&lt;br /&gt;
&lt;br /&gt;
=== 20150620 - Calculated grade items ===&lt;br /&gt;
&lt;br /&gt;
Three errors were fixed:&lt;br /&gt;
# Changing the maxgrade of a category item with a calculation using &amp;quot;Natural aggregation&amp;quot; is now possible.&lt;br /&gt;
# A change to the minimum or maximum grade value will immediately be displayed without the need for regrading to be triggered regardless of what the setting &amp;quot;Min and max grades used in calculation&amp;quot; is set to.&lt;br /&gt;
# With the setting &amp;quot;Min and max grades used in calculation&amp;quot; set to &amp;quot;initial min and max grades&amp;quot; calculated grade items are correctly displayed out of the max and min grade for that item.&lt;br /&gt;
&lt;br /&gt;
The first two errors should have no impact on existing grades in the gradebook. The last error fix does have the potential to change existing grades. If you have the setting of &amp;quot;Min and max grades used in calculation&amp;quot; set to &amp;quot;initial min and max grades&amp;quot;, calculated grade items with a maximum and minimum grade value that is not 100 and 0 respectively will have it changed to match the current minimum and maximum.&lt;br /&gt;
&lt;br /&gt;
See MDL-48239 for futher details.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=115805</id>
		<title>Grade import</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=115805"/>
		<updated>2014-11-07T02:53:52Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Slight update to paste from spreadsheet section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}Grades may be imported as a CSV or XML file, or (new in 2.8 onwards) by pasting from a spreadsheet.&lt;br /&gt;
&lt;br /&gt;
The import file format is the same as the corresponding export format. &lt;br /&gt;
&lt;br /&gt;
Note: Grade import is equivalent to manual grading in the [[Grader report|grader report]]. Thus, if grades for a particular  Moodle activity such as an assignment are imported, they can no longer be edited via the assignment submission page.&lt;br /&gt;
&lt;br /&gt;
==Importing grades==&lt;br /&gt;
[[Image:Csv grade import.png|thumb|CSV grade import]]&lt;br /&gt;
To import grades into the gradebook:&lt;br /&gt;
&lt;br /&gt;
# Decide on an import format - CSV or XML file, or paste from spreadsheet (see below) - then [[Grade export|export some grades]] using the corresponding export format.&lt;br /&gt;
# Edit the export file as appropriate and save it.&lt;br /&gt;
# Tip:  If you opened your exported file in Excel, don&#039;t add columns there because Moodle will reject the import if there are new columns that didn&#039;t exist in the exported file. If you need to add columns, do that in Moodle BEFORE you export your gradebook.&lt;br /&gt;
# Select your chosen import format from the gradebook dropdown menu.&lt;br /&gt;
# Browse and upload your previously saved file.&lt;br /&gt;
# Set options as required.&lt;br /&gt;
# Click the &amp;quot;Upload grades&amp;quot; button.&lt;br /&gt;
# CSV import only: Preview the grade import and choose the column mapping then click the &amp;quot;Upload grades&amp;quot; button to complete the grade import.&lt;br /&gt;
## Tip: By default &amp;quot;Map from&amp;quot; is set to First Name, and &amp;quot;Map to&amp;quot; to userid. Change both dropdowns to: &amp;quot;Email Address&amp;quot; to &amp;quot;useremail&amp;quot;, or to &amp;quot;Id Number&amp;quot; to &amp;quot;useridnumber&amp;quot; (assuming that your users have ID number fields filled in in their profiles).&lt;br /&gt;
## Tip: Unlike in most email programs, email addresses are case sensitive in grade import files.  (This should eventually be fixed as per MDL-29315.)&lt;br /&gt;
&lt;br /&gt;
You need two permissions to import grades: (1) general permission to import grades and (2) permission to import grades in a particular format. For example, to import CSV grades you need&lt;br /&gt;
&lt;br /&gt;
    moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow&lt;br /&gt;
    gradeimport/csv:view (&amp;quot;Import grades from CSV&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==CSV import==&lt;br /&gt;
&lt;br /&gt;
CSV import is more flexible than XML import, as you may choose the column mapping.&lt;br /&gt;
&lt;br /&gt;
===Grade Mapping===&lt;br /&gt;
&lt;br /&gt;
When Importing to Moodle 2.x or higher, after selecting your CSV for import you&#039;ll be prompted to map user fields and grade items to the new column headers to ensure that there is a match. More than one item can be mapped to the same grade item in your destination course so be mindful of the mapping to ensure that grade data is imported properly, any collisions (i.e. if two or more fields are mapped to the same but duplicate data exists) will cause an error. User grade data for users not yet enrolled to the destination course will be noted (and once enrolled their grade data will display).&lt;br /&gt;
&lt;br /&gt;
===Encoding===&lt;br /&gt;
&lt;br /&gt;
If you are unsure of the encoding of your CSV file, try selecting the second option in the encoding dropdown menu. If you&#039;ve used Excel to produce the CSV file the second option WINDOWS-xxx encoding is probably the correct one. The grade import preview will tell you if you guessed the encoding correctly.&lt;br /&gt;
&lt;br /&gt;
===Verbose scales===&lt;br /&gt;
&lt;br /&gt;
Scales can be either specified as a raw id - eg. 0, 1, 2, 3, etc. or as a string, eg. &amp;quot;good&amp;quot;, &amp;quot;bad&amp;quot;, &amp;quot;not very bad&amp;quot;. The later format is called &amp;quot;verbose&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Paste from spreadsheet==&lt;br /&gt;
&lt;br /&gt;
{{New features}}&lt;br /&gt;
Grades may be pasted directly from a spreadsheet such as Excel or Libre Office:&lt;br /&gt;
&lt;br /&gt;
1) Ensure you have the correct column names for your grades (eg the assignment title or manual grade) It might help to  download and edit the relevant students and graded information by using the [[Grade export]] feature.&lt;br /&gt;
&lt;br /&gt;
2) For the students you need either their username, their ID or their email address. Add the grades you need and copy the relevant section:&lt;br /&gt;
[[File:pastegrades1.png|thumb|center|400px]]&lt;br /&gt;
3) In your course, go to &#039;&#039;Grade administration&amp;gt;Import&amp;gt;Paste from spreadsheet&#039;&#039; and paste:&lt;br /&gt;
[[File:pastegrades2.png|thumb|center|400px]]&lt;br /&gt;
4) In the preview, ensure you match up the identifier you used for the students -so if you used &#039;username&#039;, ensure it maps to &#039;username&#039;. Do the same for your graded activities:&lt;br /&gt;
[[File:pastegrades3.png|thumb|400px|center]]&lt;br /&gt;
5) If everything has been correctly mapped (See grade mapping above), you should get a success message and the grades will have been added, displaying in a different colour to show they were imported directly into the gradebook:&lt;br /&gt;
{|&lt;br /&gt;
| [[File:pastegrades4.png|thumb|400px]]&lt;br /&gt;
| [[File:pastegrades5.png|thumb|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Paste from a spreadsheet requires similar permissions to a csv file import: (1) general permission to import grades and (2) permission to import grades in a particular format.&lt;br /&gt;
&lt;br /&gt;
    moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow&lt;br /&gt;
    gradeimport/direct:view (&amp;quot;Import grades from spreadsheet&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==XML import==&lt;br /&gt;
&lt;br /&gt;
Before importing an XML file you will need to ensure that all of the students that you want to alter grades for have their ID number field filled out. This is located in the &amp;quot;Optional&amp;quot; section of the user edit profile page.&lt;br /&gt;
You will also need to set the ID number of the activity as well. You can find this under &amp;quot;Common module settings&amp;quot; when editing the activity.&lt;br /&gt;
&lt;br /&gt;
The format for the XML should be as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;results&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;activityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;53.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;differentactivityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;73.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;lt;/results&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a working example try exporting the gradebook as an xml file and view the format.&lt;br /&gt;
&lt;br /&gt;
===Remote file URL===&lt;br /&gt;
&lt;br /&gt;
The remote file URL field is for fetching data from a remote server, such as a student information system.&lt;br /&gt;
&lt;br /&gt;
==Grade import capabilities==&lt;br /&gt;
&lt;br /&gt;
* [[Capabilities/gradeimport/csv:view|Import grades from CSV]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:publish|Publish import grades from XML]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:view|Import grades from XML]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=85944 Gradebook confusion]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=92081 Can external software insert data into the gradebook?]&lt;br /&gt;
&lt;br /&gt;
[[ja:評定のインポート]]&lt;br /&gt;
[[de:Bewertungen importieren]]&lt;br /&gt;
[[es:Importar calificaciones]]&lt;br /&gt;
[[fr:Importation des notes]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Event_list_report&amp;diff=111728</id>
		<title>Event list report</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Event_list_report&amp;diff=111728"/>
		<updated>2014-04-11T06:17:17Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Placeholder for Event list report.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Event list report&lt;br /&gt;
I created a plugin for reporting all of the events in a list. It&#039;s awesome. You should totally go and check it out.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=111727</id>
		<title>Grade import</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=111727"/>
		<updated>2014-04-11T02:21:50Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* XML import */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}Grades may be imported as a CSV or XML file.&lt;br /&gt;
&lt;br /&gt;
The import file format is the same as the corresponding export format. &lt;br /&gt;
&lt;br /&gt;
Note: Grade import is equivalent to manual grading in the [[Grader report|grader report]]. Thus, if grades for a particular  Moodle activity such as an assignment are imported, they can no longer be edited via the assignment submission page.&lt;br /&gt;
&lt;br /&gt;
==Importing grades==&lt;br /&gt;
[[Image:Csv grade import.png|thumb|CSV grade import]]&lt;br /&gt;
To import grades into the gradebook:&lt;br /&gt;
&lt;br /&gt;
# Decide on an import format - CSV or XML file (see below) - then [[Grade export|export some grades]] using the corresponding export format.&lt;br /&gt;
# Edit the export file as appropriate and save it.&lt;br /&gt;
# Tip:  If you opened your exported file in Excel, don&#039;t add columns there because Moodle will reject the import if there are new columns that didn&#039;t exist in the exported file. If you need to add columns, do that in Moodle BEFORE you export your gradebook.&lt;br /&gt;
# Select your chosen import format from the gradebook dropdown menu.&lt;br /&gt;
# Browse and upload your previously saved file.&lt;br /&gt;
# Set options as required.&lt;br /&gt;
# Click the &amp;quot;Upload grades&amp;quot; button.&lt;br /&gt;
# CSV import only: Preview the grade import and choose the column mapping then click the &amp;quot;Upload grades&amp;quot; button to complete the grade import.&lt;br /&gt;
## Tip: By default &amp;quot;Map from&amp;quot; is set to First Name, and &amp;quot;Map to&amp;quot; to userid. Change both dropdowns to: &amp;quot;Email Address&amp;quot; to &amp;quot;useremail&amp;quot;, or to &amp;quot;Id Number&amp;quot; to &amp;quot;useridnumber&amp;quot; (assuming that your users have ID number fields filled in in their profiles).&lt;br /&gt;
## Tip: Unlike in most email programs, email addresses are case sensitive in grade import files.  (This should eventually be fixed as per MDL-29315.)&lt;br /&gt;
&lt;br /&gt;
You need two permissions to import grades: (1) general permission to import grades and (2) permission to import grades in a particular format. For example, to import CSV grades you need&lt;br /&gt;
&lt;br /&gt;
    moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow&lt;br /&gt;
    gradeimport/csv:view (&amp;quot;Import grades from CSV&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==XML import==&lt;br /&gt;
&lt;br /&gt;
Before importing an XML file you will need to ensure that all of the students that you want to alter grades for have their ID number field filled out. This is located in the &amp;quot;Optional&amp;quot; section of the user edit profile page.&lt;br /&gt;
You will also need to set the ID number of the activity as well. You can find this under &amp;quot;Common module settings&amp;quot; when editing the activity.&lt;br /&gt;
&lt;br /&gt;
The format for the XML should be as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;results&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;activityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;53.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;differentactivityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;73.00&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;lt;/results&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a working example try exporting the gradebook as an xml file and view the format.&lt;br /&gt;
&lt;br /&gt;
===Remote file URL===&lt;br /&gt;
&lt;br /&gt;
The remote file URL field is for fetching data from a remote server, such as a student information system.&lt;br /&gt;
&lt;br /&gt;
==CSV import==&lt;br /&gt;
&lt;br /&gt;
CSV import is more flexible than XML import, as you may choose the column mapping.&lt;br /&gt;
&lt;br /&gt;
===Grade Mapping===&lt;br /&gt;
&lt;br /&gt;
When Importing to Moodle 2.x or higher, after selecting your CSV for import you&#039;ll be prompted to map user fields and grade items to the new column headers to ensure that there is a match. More than one item can be mapped to the same grade item in your destination course so be mindful of the mapping to ensure that grade data is imported properly, any collisions (i.e. if two or more fields are mapped to the same but duplicate data exists) will cause an error. User grade data for users not yet enrolled to the destination course will be noted (and once enrolled their grade data will display).&lt;br /&gt;
&lt;br /&gt;
===Encoding===&lt;br /&gt;
&lt;br /&gt;
If you are unsure of the encoding of your CSV file, try selecting the second option in the encoding dropdown menu. If you&#039;ve used Excel to produce the CSV file the second option WINDOWS-xxx encoding is probably the correct one. The grade import preview will tell you if you guessed the encoding correctly.&lt;br /&gt;
&lt;br /&gt;
===Verbose scales===&lt;br /&gt;
&lt;br /&gt;
Scales can be either specified as a raw id - eg. 0, 1, 2, 3, etc. or as a string, eg. &amp;quot;good&amp;quot;, &amp;quot;bad&amp;quot;, &amp;quot;not very bad&amp;quot;. The later format is called &amp;quot;verbose&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Grade import capabilities==&lt;br /&gt;
&lt;br /&gt;
* [[Capabilities/gradeimport/csv:view|Import grades from CSV]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:publish|Publish import grades from XML]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:view|Import grades from XML]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=85944 Gradebook confusion]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=92081 Can external software insert data into the gradebook?]&lt;br /&gt;
&lt;br /&gt;
[[ja:評定のインポート]]&lt;br /&gt;
[[de:Bewertungen importieren]]&lt;br /&gt;
[[fr:Importation des notes]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=111726</id>
		<title>Grade import</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Grade_import&amp;diff=111726"/>
		<updated>2014-04-11T02:21:07Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* XML import - expanded detail and example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}Grades may be imported as a CSV or XML file.&lt;br /&gt;
&lt;br /&gt;
The import file format is the same as the corresponding export format. &lt;br /&gt;
&lt;br /&gt;
Note: Grade import is equivalent to manual grading in the [[Grader report|grader report]]. Thus, if grades for a particular  Moodle activity such as an assignment are imported, they can no longer be edited via the assignment submission page.&lt;br /&gt;
&lt;br /&gt;
==Importing grades==&lt;br /&gt;
[[Image:Csv grade import.png|thumb|CSV grade import]]&lt;br /&gt;
To import grades into the gradebook:&lt;br /&gt;
&lt;br /&gt;
# Decide on an import format - CSV or XML file (see below) - then [[Grade export|export some grades]] using the corresponding export format.&lt;br /&gt;
# Edit the export file as appropriate and save it.&lt;br /&gt;
# Tip:  If you opened your exported file in Excel, don&#039;t add columns there because Moodle will reject the import if there are new columns that didn&#039;t exist in the exported file. If you need to add columns, do that in Moodle BEFORE you export your gradebook.&lt;br /&gt;
# Select your chosen import format from the gradebook dropdown menu.&lt;br /&gt;
# Browse and upload your previously saved file.&lt;br /&gt;
# Set options as required.&lt;br /&gt;
# Click the &amp;quot;Upload grades&amp;quot; button.&lt;br /&gt;
# CSV import only: Preview the grade import and choose the column mapping then click the &amp;quot;Upload grades&amp;quot; button to complete the grade import.&lt;br /&gt;
## Tip: By default &amp;quot;Map from&amp;quot; is set to First Name, and &amp;quot;Map to&amp;quot; to userid. Change both dropdowns to: &amp;quot;Email Address&amp;quot; to &amp;quot;useremail&amp;quot;, or to &amp;quot;Id Number&amp;quot; to &amp;quot;useridnumber&amp;quot; (assuming that your users have ID number fields filled in in their profiles).&lt;br /&gt;
## Tip: Unlike in most email programs, email addresses are case sensitive in grade import files.  (This should eventually be fixed as per MDL-29315.)&lt;br /&gt;
&lt;br /&gt;
You need two permissions to import grades: (1) general permission to import grades and (2) permission to import grades in a particular format. For example, to import CSV grades you need&lt;br /&gt;
&lt;br /&gt;
    moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow&lt;br /&gt;
    gradeimport/csv:view (&amp;quot;Import grades from CSV&amp;quot;) = Allow&lt;br /&gt;
&lt;br /&gt;
==XML import==&lt;br /&gt;
&lt;br /&gt;
Before importing an XML file you will need to ensure that all of the students that you want to alter grades for have their ID number field filled out. This is located in the &amp;quot;Optional&amp;quot; section of the user edit profile page.&lt;br /&gt;
You will also need to set the ID number of the activity as well. You can find this under &amp;quot;Common module settings&amp;quot; when editing the activity.&lt;br /&gt;
&lt;br /&gt;
The format for the XML should be as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;results&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;activityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;53.00&amp;lt;/score&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
    &amp;lt;result&amp;gt;&lt;br /&gt;
        &amp;lt;assignment&amp;gt;differentactivityidnumber&amp;lt;/assignment&amp;gt;&lt;br /&gt;
        &amp;lt;student&amp;gt;studentidnumber&amp;lt;/student&amp;gt;&lt;br /&gt;
        &amp;lt;score&amp;gt;73.00&amp;lt;/score&amp;lt;/score&amp;gt;&lt;br /&gt;
    &amp;lt;/result&amp;gt;&lt;br /&gt;
&amp;lt;/results&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a working example try exporting the gradebook as an xml file and view the format.&lt;br /&gt;
&lt;br /&gt;
===Remote file URL===&lt;br /&gt;
&lt;br /&gt;
The remote file URL field is for fetching data from a remote server, such as a student information system.&lt;br /&gt;
&lt;br /&gt;
==CSV import==&lt;br /&gt;
&lt;br /&gt;
CSV import is more flexible than XML import, as you may choose the column mapping.&lt;br /&gt;
&lt;br /&gt;
===Grade Mapping===&lt;br /&gt;
&lt;br /&gt;
When Importing to Moodle 2.x or higher, after selecting your CSV for import you&#039;ll be prompted to map user fields and grade items to the new column headers to ensure that there is a match. More than one item can be mapped to the same grade item in your destination course so be mindful of the mapping to ensure that grade data is imported properly, any collisions (i.e. if two or more fields are mapped to the same but duplicate data exists) will cause an error. User grade data for users not yet enrolled to the destination course will be noted (and once enrolled their grade data will display).&lt;br /&gt;
&lt;br /&gt;
===Encoding===&lt;br /&gt;
&lt;br /&gt;
If you are unsure of the encoding of your CSV file, try selecting the second option in the encoding dropdown menu. If you&#039;ve used Excel to produce the CSV file the second option WINDOWS-xxx encoding is probably the correct one. The grade import preview will tell you if you guessed the encoding correctly.&lt;br /&gt;
&lt;br /&gt;
===Verbose scales===&lt;br /&gt;
&lt;br /&gt;
Scales can be either specified as a raw id - eg. 0, 1, 2, 3, etc. or as a string, eg. &amp;quot;good&amp;quot;, &amp;quot;bad&amp;quot;, &amp;quot;not very bad&amp;quot;. The later format is called &amp;quot;verbose&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Grade import capabilities==&lt;br /&gt;
&lt;br /&gt;
* [[Capabilities/gradeimport/csv:view|Import grades from CSV]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:publish|Publish import grades from XML]]&lt;br /&gt;
* [[Capabilities/gradeimport/xml:view|Import grades from XML]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=85944 Gradebook confusion]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=92081 Can external software insert data into the gradebook?]&lt;br /&gt;
&lt;br /&gt;
[[ja:評定のインポート]]&lt;br /&gt;
[[de:Bewertungen importieren]]&lt;br /&gt;
[[fr:Importation des notes]]&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107477</id>
		<title>Additional name fields</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107477"/>
		<updated>2013-11-06T07:43:00Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Updating the user&amp;#039;s profile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{New features}}&lt;br /&gt;
&lt;br /&gt;
Moodle 2.6 now has four additional name fields. These fields allow for further detail to be displayed about the user. The additional name fields are:&lt;br /&gt;
* First name - phonetic&lt;br /&gt;
* Surname - phonetic&lt;br /&gt;
* Middle name&lt;br /&gt;
* Alternate name&lt;br /&gt;
&lt;br /&gt;
[[File:26names.png]]&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The display of the user&#039;s full name is determined by the capability *Add capability here*&lt;br /&gt;
&lt;br /&gt;
[[File:participants-after.png]]&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
Configuration of the additional name fields is done in the following Administration page [Administration ► Site administration ► Users ► Permissions ► User policies].&lt;br /&gt;
The setting to change is &amp;quot;Full name format&amp;quot; (fullnamedisplay).&lt;br /&gt;
This setting uses the following placeholders:&lt;br /&gt;
* firstname&lt;br /&gt;
* lastname&lt;br /&gt;
* firstnamephonetic&lt;br /&gt;
* lastnamephonetic&lt;br /&gt;
* middlename&lt;br /&gt;
* alternatename&lt;br /&gt;
* language (used on its own to force the use of the language pack)&lt;br /&gt;
By default it has the place-holder &amp;quot;language&amp;quot; and it will use the local language pack to determine how user names are displayed. (location: /lang/en/moodle.php - fullnamedisplay)&lt;br /&gt;
&lt;br /&gt;
To enable the additional name fields, just enter in the placeholders into the text box. The order that you enter in the names will be the order that they are displayed around Moodle.&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!First name &lt;br /&gt;
!Surname&lt;br /&gt;
!Middle name&lt;br /&gt;
!Surname - phonetic&lt;br /&gt;
!First name - phonetic&lt;br /&gt;
|-&lt;br /&gt;
|John&lt;br /&gt;
|Doe&lt;br /&gt;
|James&lt;br /&gt;
|Dough&lt;br /&gt;
|Jon&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;firstname middlename lastname&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;John James Doe&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other characters can be included in the setting such as commas and parenthesis.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;lastname firstname (lastnamephonetic firstnamephonetic)&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Doe John (Dough Jon)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Updating the user&#039;s profile==&lt;br /&gt;
Any additional names that are included in the &amp;quot;Full name format&amp;quot; setting will be displayed directly under the text boxes for first name and surname. All other name fields that are not being used are located under the section &amp;quot;Additional names&amp;quot; further down the page.&lt;br /&gt;
&lt;br /&gt;
==Upgrade from previous versions==&lt;br /&gt;
&lt;br /&gt;
When upgrading to 2.6, the &amp;quot;Full name format&amp;quot; (fullnamedisplay) setting found in [Administration ► Site administration ► Security ► Site policies] will automatically be changed over. All of the additional name fields will be blank.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107476</id>
		<title>Additional name fields</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107476"/>
		<updated>2013-11-06T07:35:47Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: /* Example 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{New features}}&lt;br /&gt;
&lt;br /&gt;
Moodle 2.6 now has four additional name fields. These fields allow for further detail to be displayed about the user. The additional name fields are:&lt;br /&gt;
* First name - phonetic&lt;br /&gt;
* Surname - phonetic&lt;br /&gt;
* Middle name&lt;br /&gt;
* Alternate name&lt;br /&gt;
&lt;br /&gt;
[[File:26names.png]]&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The display of the user&#039;s full name is determined by the capability *Add capability here*&lt;br /&gt;
&lt;br /&gt;
[[File:participants-after.png]]&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
Configuration of the additional name fields is done in the following Administration page [Administration ► Site administration ► Users ► Permissions ► User policies].&lt;br /&gt;
The setting to change is &amp;quot;Full name format&amp;quot; (fullnamedisplay).&lt;br /&gt;
This setting uses the following placeholders:&lt;br /&gt;
* firstname&lt;br /&gt;
* lastname&lt;br /&gt;
* firstnamephonetic&lt;br /&gt;
* lastnamephonetic&lt;br /&gt;
* middlename&lt;br /&gt;
* alternatename&lt;br /&gt;
* language (used on its own to force the use of the language pack)&lt;br /&gt;
By default it has the place-holder &amp;quot;language&amp;quot; and it will use the local language pack to determine how user names are displayed. (location: /lang/en/moodle.php - fullnamedisplay)&lt;br /&gt;
&lt;br /&gt;
To enable the additional name fields, just enter in the placeholders into the text box. The order that you enter in the names will be the order that they are displayed around Moodle.&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!First name &lt;br /&gt;
!Surname&lt;br /&gt;
!Middle name&lt;br /&gt;
!Surname - phonetic&lt;br /&gt;
!First name - phonetic&lt;br /&gt;
|-&lt;br /&gt;
|John&lt;br /&gt;
|Doe&lt;br /&gt;
|James&lt;br /&gt;
|Dough&lt;br /&gt;
|Jon&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;firstname middlename lastname&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;John James Doe&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other characters can be included in the setting such as commas and parenthesis.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;lastname firstname (lastnamephonetic firstnamephonetic)&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Doe John (Dough Jon)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Updating the user&#039;s profile==&lt;br /&gt;
&lt;br /&gt;
==Upgrade from previous versions==&lt;br /&gt;
&lt;br /&gt;
When upgrading to 2.6, the &amp;quot;Full name format&amp;quot; (fullnamedisplay) setting found in [Administration ► Site administration ► Security ► Site policies] will automatically be changed over. All of the additional name fields will be blank.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107475</id>
		<title>Additional name fields</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107475"/>
		<updated>2013-11-06T07:32:00Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: setting mistake&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{New features}}&lt;br /&gt;
&lt;br /&gt;
Moodle 2.6 now has four additional name fields. These fields allow for further detail to be displayed about the user. The additional name fields are:&lt;br /&gt;
* First name - phonetic&lt;br /&gt;
* Surname - phonetic&lt;br /&gt;
* Middle name&lt;br /&gt;
* Alternate name&lt;br /&gt;
&lt;br /&gt;
[[File:26names.png]]&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The display of the user&#039;s full name is determined by the capability *Add capability here*&lt;br /&gt;
&lt;br /&gt;
[[File:participants-after.png]]&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
Configuration of the additional name fields is done in the following Administration page [Administration ► Site administration ► Users ► Permissions ► User policies].&lt;br /&gt;
The setting to change is &amp;quot;Full name format&amp;quot; (fullnamedisplay).&lt;br /&gt;
This setting uses the following placeholders:&lt;br /&gt;
* firstname&lt;br /&gt;
* lastname&lt;br /&gt;
* firstnamephonetic&lt;br /&gt;
* lastnamephonetic&lt;br /&gt;
* middlename&lt;br /&gt;
* alternatename&lt;br /&gt;
* language (used on its own to force the use of the language pack)&lt;br /&gt;
By default it has the place-holder &amp;quot;language&amp;quot; and it will use the local language pack to determine how user names are displayed. (location: /lang/en/moodle.php - fullnamedisplay)&lt;br /&gt;
&lt;br /&gt;
To enable the additional name fields, just enter in the placeholders into the text box. The order that you enter in the names will be the order that they are displayed around Moodle.&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!First name &lt;br /&gt;
!Surname&lt;br /&gt;
!Middle name&lt;br /&gt;
!Surname - phonetic&lt;br /&gt;
!First name - phonetic&lt;br /&gt;
|-&lt;br /&gt;
|John&lt;br /&gt;
|Doe&lt;br /&gt;
|James&lt;br /&gt;
|Jon&lt;br /&gt;
|Dough&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;firstname middlename lastname&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;John James Doe&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other characters can be included in the setting such as commas and parenthesis.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;lastname firstname (lastnamephonetic firstnamephonetic)&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Doe John (Dough Jon)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Updating the user&#039;s profile==&lt;br /&gt;
&lt;br /&gt;
==Upgrade from previous versions==&lt;br /&gt;
&lt;br /&gt;
When upgrading to 2.6, the &amp;quot;Full name format&amp;quot; (fullnamedisplay) setting found in [Administration ► Site administration ► Security ► Site policies] will automatically be changed over. All of the additional name fields will be blank.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107474</id>
		<title>Additional name fields</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107474"/>
		<updated>2013-11-06T03:19:42Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Participants page example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{New features}}&lt;br /&gt;
&lt;br /&gt;
Moodle 2.6 now has four additional name fields. These fields allow for further detail to be displayed about the user. The additional name fields are:&lt;br /&gt;
* First name - phonetic&lt;br /&gt;
* Surname - phonetic&lt;br /&gt;
* Middle name&lt;br /&gt;
* Alternate name&lt;br /&gt;
&lt;br /&gt;
[[File:26names.png]]&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The display of the user&#039;s full name is determined by the capability *Add capability here*&lt;br /&gt;
&lt;br /&gt;
[[File:participants-after.png]]&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
Configuration of the additional name fields is done in the following Administration page [Administration ► Site administration ► Users ► Permissions ► User policies].&lt;br /&gt;
The setting to change is &amp;quot;Full name format&amp;quot; (fullnamedisplay).&lt;br /&gt;
This setting uses the following placeholders:&lt;br /&gt;
* firstname&lt;br /&gt;
* lastname&lt;br /&gt;
* firstnamephonetic&lt;br /&gt;
* lastnamephonetic&lt;br /&gt;
* middlename&lt;br /&gt;
* alternatename&lt;br /&gt;
* language (used on its own to force the use of the language pack)&lt;br /&gt;
By default it has the place-holder &amp;quot;language&amp;quot; and it will use the local language pack to determine how user names are displayed. (location: /lang/en/moodle.php - fullnamedisplay)&lt;br /&gt;
&lt;br /&gt;
To enable the additional name fields, just enter in the placeholders into the text box. The order that you enter in the names will be the order that they are displayed around Moodle.&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!First name &lt;br /&gt;
!Surname&lt;br /&gt;
!Middle name&lt;br /&gt;
!Surname - phonetic&lt;br /&gt;
!First name - phonetic&lt;br /&gt;
|-&lt;br /&gt;
|John&lt;br /&gt;
|Doe&lt;br /&gt;
|James&lt;br /&gt;
|Jon&lt;br /&gt;
|Jay-ms&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;firstname middlename lastname&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;John James Doe&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other characters can be included in the setting such as commas and parenthesis.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;lastname firstname (lastnamephonetic firstnamephonetic)&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;James John (Jay-ms Jon)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Updating the user&#039;s profile==&lt;br /&gt;
&lt;br /&gt;
==Upgrade from previous versions==&lt;br /&gt;
&lt;br /&gt;
When upgrading to 2.6, the &amp;quot;Full name format&amp;quot; (fullnamedisplay) setting found in [Administration ► Site administration ► Security ► Site policies] will automatically be changed over. All of the additional name fields will be blank.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=File:participants-after.png&amp;diff=107473</id>
		<title>File:participants-after.png</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=File:participants-after.png&amp;diff=107473"/>
		<updated>2013-11-06T03:15:27Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107472</id>
		<title>Additional name fields</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/310/en/index.php?title=Additional_name_fields&amp;diff=107472"/>
		<updated>2013-11-06T03:07:20Z</updated>

		<summary type="html">&lt;p&gt;Abgreeve: Addition of a few categories and a bit of detail&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{New features}}&lt;br /&gt;
&lt;br /&gt;
Moodle 2.6 now has four additional name fields. These fields allow for further detail to be displayed about the user. The additional name fields are:&lt;br /&gt;
* First name - phonetic&lt;br /&gt;
* Surname - phonetic&lt;br /&gt;
* Middle name&lt;br /&gt;
* Alternate name&lt;br /&gt;
&lt;br /&gt;
[[File:26names.png]]&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The display of the user&#039;s full name is determined by the capability *Add capability here*&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
Configuration of the additional name fields is done in the following Administration page [Administration ► Site administration ► Users ► Permissions ► User policies].&lt;br /&gt;
The setting to change is &amp;quot;Full name format&amp;quot; (fullnamedisplay).&lt;br /&gt;
This setting uses the following placeholders:&lt;br /&gt;
* firstname&lt;br /&gt;
* lastname&lt;br /&gt;
* firstnamephonetic&lt;br /&gt;
* lastnamephonetic&lt;br /&gt;
* middlename&lt;br /&gt;
* alternatename&lt;br /&gt;
* language (used on its own to force the use of the language pack)&lt;br /&gt;
By default it has the place-holder &amp;quot;language&amp;quot; and it will use the local language pack to determine how user names are displayed. (location: /lang/en/moodle.php - fullnamedisplay)&lt;br /&gt;
&lt;br /&gt;
To enable the additional name fields, just enter in the placeholders into the text box. The order that you enter in the names will be the order that they are displayed around Moodle.&lt;br /&gt;
&lt;br /&gt;
===Example 1===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!First name &lt;br /&gt;
!Surname&lt;br /&gt;
!Middle name&lt;br /&gt;
!Surname - phonetic&lt;br /&gt;
!First name - phonetic&lt;br /&gt;
|-&lt;br /&gt;
|John&lt;br /&gt;
|Doe&lt;br /&gt;
|James&lt;br /&gt;
|Jon&lt;br /&gt;
|Jay-ms&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;firstname middlename lastname&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;John James Doe&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other characters can be included in the setting such as commas and parenthesis.&lt;br /&gt;
&lt;br /&gt;
===Example 2===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Full name format setting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;lastname firstname (lastnamephonetic firstnamephonetic)&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
will display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;James John (Jay-ms Jon)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Updating the user&#039;s profile==&lt;br /&gt;
&lt;br /&gt;
==Upgrade from previous versions==&lt;br /&gt;
&lt;br /&gt;
When upgrading to 2.6, the &amp;quot;Full name format&amp;quot; (fullnamedisplay) setting found in [Administration ► Site administration ► Security ► Site policies] will automatically be changed over. All of the additional name fields will be blank.&lt;/div&gt;</summary>
		<author><name>Abgreeve</name></author>
	</entry>
</feed>