I'm using moodle 3.0. While creating user, it displays too many extra fields like SkypeID, AimID etc. So is there any way to edit or delete these fields ?
Also I want to add user profile fields in Grader report.Like, If I created 'Roll_No' field then it should be in the grader report.
Currently, there is no way (that I am aware of) to remove these fields from the user profile form using settings within the front-end of Moodle.
Your two options would be to
1. hack the code that creates the user form to remove these - not recommended!
2. Use some css in your theme to hide these fields in the form. While this does not remove them completely and is dependant on your theme (ie if you enable users to swap themes then that may allow them to reappear), it does mean less potential problems in the case of some other code in another part of Moodle referring to items that you have removed from the profile form.
Example:
Add the examples below to your customcss theme setting (I have used Clean theme to test)
#page-user-edit fieldset#id_moodle_optional {display:none;} // Will hide the entire 'Optional' section
#page-user-edit div#fitem_id_country {display:none;} // Will remove just the 'Country' setting
You can find the appropriate css IDs for the fieldsets or form items using a tool such as firebug or Chrome developer tools to inspect the elements.
For hiding the fields you can use user policy
https://docs.moodle.org/30/en/User_policies#Hide_user_fields
Go to site admin -> users -> permissions -> user policies
Then select the fields you want to hide in hiddenuserfields
For the grader report, there is an option to include custom fields in the export.
Go to site admin -> grades -> general settings - then enter the custom fields in grade_export_customprofilefields
I'm using moodle 3.0
I found a useful way to disable the additional fields,this will edit the form from the code, so simple
go to moodle/user/editlib.php
and comment these lines:
to disable discription:
// $mform->addElement('editor', 'description_editor', get_string('userdescription'), null, $editoroptions);
// $mform->setType('description_editor', PARAM_RAW);
// $mform->addHelpButton('description_editor', 'userdescription');
to disable user pic:
// $mform->addElement('header', 'moodle_picture', get_string('pictureofuser'));
// $mform->setExpanded('moodle_picture', true);
// $mform->addElement('checkbox', 'deletepicture', get_string('deletepicture'));
// $mform->setDefault('deletepicture', 0);
// $mform->addElement('filemanager', 'imagefile', get_string('newpicture'), '', $filemanageroptions);
// $mform->addHelpButton('imagefile', 'newpicture');
// $mform->addElement('text', 'imagealt', get_string('imagealt'), 'maxlength="100" size="30"');
// $mform->setType('imagealt', PARAM_TEXT);
and to disable additional names:
// $mform->addElement('header', 'moodle_additional_names',get_string('additionalnames'));
// $mform->addElement('text', $allname, get_string($allname), 'maxlength="100" size="30"' . $purpose);
// $mform->setType($allname, PARAM_NOTAGS);
to disable interests:
// if (core_tag_tag::is_enabled('core', 'user') and empty($USER->newadminuser)) {
// $mform->addElement('header', 'moodle_interests', get_string('interests'));
// $mform->addElement('tags', 'interests', get_string('interestslist'),
// array('itemtype' => 'user', 'component' => 'core'));
// $mform->addHelpButton('interests', 'interestslist');
// }
to disable optional contact:
// $mform->addElement('header', 'moodle_optional', get_string('optional', 'form'));
// $mform->addElement('text', 'url', get_string('webpage'), 'maxlength="255" size="50"');
// $mform->setType('url', core_user::get_property_type('url'));
// $mform->addElement('text', 'icq', get_string('icqnumber'), 'maxlength="15" size="25"');
// $mform->setType('icq', core_user::get_property_type('icq'));
// $mform->setForceLtr('icq');
// $mform->addElement('text', 'skype', get_string('skypeid'), 'maxlength="50" size="25"');
// $mform->setType('skype', core_user::get_property_type('skype'));
// $mform->setForceLtr('skype');
// $mform->addElement('text', 'aim', get_string('aimid'), 'maxlength="50" size="25"');
// $mform->setType('aim', core_user::get_property_type('aim'));
// $mform->setForceLtr('aim');
// $mform->addElement('text', 'yahoo', get_string('yahooid'), 'maxlength="50" size="25"');
// $mform->setType('yahoo', core_user::get_property_type('yahoo'));
// $mform->setForceLtr('yahoo');
// $mform->addElement('text', 'msn', get_string('msnid'), 'maxlength="50" size="25"');
// $mform->setType('msn', core_user::get_property_type('msn'));
// $mform->setForceLtr('msn');
// $mform->addElement('text', 'idnumber', get_string('idnumber'), 'maxlength="255" size="25"');
// $mform->setType('idnumber', core_user::get_property_type('idnumber'));
// $mform->addElement('text', 'institution', get_string('institution'), 'maxlength="255" size="25"');
// $mform->setType('institution', core_user::get_property_type('institution'));
// $mform->addElement('text', 'department', get_string('department'), 'maxlength="255" size="25"');
// $mform->setType('department', core_user::get_property_type('department'));
// $mform->addElement('text', 'phone1', get_string('phone1'), 'maxlength="20" size="25"');
// $mform->setType('phone1', core_user::get_property_type('phone1'));
// $mform->setForceLtr('phone1');
// $mform->addElement('text', 'phone2', get_string('phone2'), 'maxlength="20" size="25"');
// $mform->setType('phone2', core_user::get_property_type('phone2'));
// $mform->setForceLtr('phone2');
// $mform->addElement('text', 'address', get_string('address'), 'maxlength="255" size="25"');
// $mform->setType('address', core_user::get_property_type('address'));
Related
I want to add more dropdown fields to the appearance tab for editing content elements.
How can I achieve this?
I've tried to add more layouts for the pageTs but that doesn't work. Also couldn't find more on this on the internet.
You can't do this via the backend. You will need to extend the TCA (e.g. in your sitepackage extension).
In your extension:
Add the field in ext_tables.sql
Extend the TCA in Configuration/TCA/Overrides/tt_content.php:
add new fields to the columns
Add the new fields to the visible fields
Add the new fields to the appropriate palette
Tip: You can look at the active TCA configuration for tt_content in the TYPO3 backend Configuration | Globals['TCA']
If you want to place the new field after an existing field, e.g. space_before_class, check which palette this is in ('frames') and place it in that.
Example:
ext_tables.sql:
CREATE TABLE tt_content(
my_new_field TINYINT(1) UNSIGNED DEFAULT '0' NOT NULL
);
Configuration/TCA/Overrides/tt_content.php
$fields = [
// new field
'my_new_field' => [
// title of the field
// alternatively, just use a string, but putting the string in
// language file eases translations
'label' => 'LLL:EXT:myextension/Resources/Private/Language/locallang.xlf:tt_content.my_new_field.title',
'config' => [
// type: select
'type' => 'select',
'renderType' => 'selectSingle',
'default' => 0,
'items' => [
[
// again, better to use language label LLL here
'description',
// value
0
],
[
// another option
'description 2',
// value
1
],
],
],
],
// ...
];
// Add new fields to table:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content', $fields);
// Add new field to palette 'frames'
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette(
'tt_content',
'frames',
'my_new_field',
'before:frame_class'
);
Resources:
extend TCA: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/HowTo/ExtendingTca/Examples/Index.html
TCA: columns field types: https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Index.html
select types: https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Type/Select/Index.html
For the rest of the options, refer to the TCA Reference: https://docs.typo3.org/m/typo3/reference-tca/main/en-us/Index.html
If you could live just with more options to the given fields you can do it in the BE without programming / extending the TCA (Sybille's answer).
Extending the given list of select options for the existing fields is possible with some page/user TSConfig like:
TCEFORM.tt_content.layout.addItems {
20 = additional layout 1|nyt layout 1|neues Layout 1|...
25 = additional layout 2|nyt layout 2|neues Layout 2|...
}
TCEFORM.tt_content.frame_class.addItems {
50 = frame-class-50
55 = frame-class-55
}
Of cause this needs a handling in the rendering of the CEs.
Depending on the TYPO3 version and the active rendering there are different places to handle this.
Without FLUID rendering it needs some edits in the typoscript, with FLUID you need to override the appropriate file (layout/template/partial) where the field (here: layout and frame_class) is handled.
Starting a large application with a handful of developers. Using webpack and bootstrap-vue. How would I default the style for <b-card> (and other components). In other words can I default:
<b-card>
to be the equivalent to:
<b-card style="max-width: 40rem;" header-bg-variant="primary" header-text-variant="white">
to make sure we keep our look consistent throughout the whole application.
You can either use SCSS/CSS overrides to control the b-card layout, or extend/wrap the component to default the props you want:
import { BCard } from 'bootstrap-vue'
export default {
name 'MyCard',
// Create as a functional component wrapper
functional: true,
// define our props (borrow from BCard)
props: {
...BCard.props,
},
render(h, { props, data, children }) {
return h(
BCard,
{
props: {
// Pass all props to BCard
...props,
// Override the following prop defaults (if not provided)
headerBgVariant: props.headerBgVariant || 'primary',
headerTextVariant: props.headerBgVariant || 'white'
},
// Pass any additional (optional) attributes down
attrs: data.attrs,
// Set the style
style: {
// merge in any styles manually applied
...data.style,
// Set the max-width if not explicitly set
maxWidth: data.style.maxWidth || '40rem'
}
}
)
}
}
For more info on functional components and render functions, see https://v2.vuejs.org/v2/guide/render-function.html#Functional-Components
For handling more complex data merges with functional components, check out https://github.com/alexsasharegan/vue-functional-data-merge
I'm trying to modify the TinyMCE 4 "link" plugin to allow users to select content from ListBox elements that are dynamically updated by AJAX requests.
I'm creating the ListBox elements in advance of editor.windowManager.open(), so they are initially rendered properly. I have an onselect handler that performs the AJAX request, and gets a response in JSON format.
What I need to do with the JSON response is to have it update another ListBox element, replacing the existing items with the new results.
I'm baffled, and the documentation is terribly unclear. I don't know if I should replace the entire control, or delete items and then add new ones. I don't know if I need to instantiate a new ListBox control, or render it to HTML, etc.
Basically, I have access to the original rendered ListBox (name: "module"} with
win.find('#module');
I have the new values from the AJAX request:
var data = tinymce.util.JSON.parse(text).data;
And I've tried creating a new Control configuration object, like
newCtrlconfig = {
type: 'listbox',
label: 'Class',
values: data
};
but I wouldn't know how to render it, much less have it replace the existing one.
I tried
var newList = tinymce.ui.Factory.create(newCtrlconfig);
and then
newList.renderHtml()
but even then, the rendered HTML did not contain any markup for the items. And examining these objects is just frustrating: there are "settings", "values", "_values", "items" all of which will happily store my values, but it isn't even clear which of them will work.
Since it's a ListBox and not a simple SELECT menu, I can't even easily use the DOM to manipulate the values.
Has anyone conquered the TinyMCE ListBox in 4.x?
I found this on the TinyMCE forum and I have confirmed that it works:
tinymce.PluginManager.add('myexample', function(editor, url) {
var self = this, button;
function getValues() {
return editor.settings.myKeyValueList;
}
// Add a button that opens a window
editor.addButton('myexample', {
type: 'listbox',
text: 'My Example',
values: getValues(),
onselect: function() {
//insert key
editor.insertContent(this.value());
//reset selected value
this.value(null);
},
onPostRender: function() {
//this is a hack to get button refrence.
//there may be a better way to do this
button = this;
},
});
self.refresh = function() {
//remove existing menu if it is already rendered
if(button.menu){
button.menu.remove();
button.menu = null;
}
button.settings.values = button.settings.menu = getValues();
};
});
Call following code block from ajax success method
//Set new values to myKeyValueList
tinyMCE.activeEditor.settings.myKeyValueList = [{text: 'newtext', value: 'newvalue'}];
//Call plugin method to reload the dropdown
tinyMCE.activeEditor.plugins.myexample.refresh();
The key here is that you need to do the following:
Get the 'button' reference by taking it from 'this' in the onPostRender method
Update the button.settings.values and button.settings.menu with the values you want
To update the existing list, call button.menu.remove() and button.menu = null
I tried the solution from TinyMCE forum, but I found it buggy. For example, when I tried to alter the first ListBox multiple times, only the first time took effect. Also first change to that box right after dialogue popped up didn't take any effect.
But to the solution:
Do not call button.menu.remove();
Also, the "hack" for getting button reference is quite unnecessary. Your job can be done simply using:
var button = win.find("#button")[0];
With these modification, my ListBoxes work just right.
Whole dialogue function:
function ShowDialog() {
var val;
win = editor.windowManager.open({
title: 'title',
body: {type: 'form',
items: [
{type: 'listbox',
name: 'categorybox',
text: 'pick one',
value: 0,
label: 'Section: ',
values: categories,
onselect: setValuebox(this.value())
},
{type: 'listbox',
name: 'valuebox',
text:'pick one',
value: '',
label: 'Page: ',
values: pagelist[0],
onselect: function(e) {
val = this.value();
}
}
]
},
onsubmit: function(e) {
//do whatever
}
});
var valbox = win.find("#valuebox")[0];
function setValuebox(i){
//feel free to call ajax
valbox.value(null);
valbox.menu = null;
valbox.settings.menu = pagelist[i];
// you can also set a value from pagelist[i]["values"][0]
}
}
categories and pagelist are JSONs generated from DB before TinyMCE load. pagelist[category] = data for ListBox for selected category. category=0 means all.
Hope I helped somebody, because I've been struggling this for hours.
It looks like the tinyMCE version that is included in wordpress 4.3 changed some things, and added a state object that caches the initial menu, so changing the menu is not enough anymore.
One will probably have to update the state object as well. Here is an example of updating the menu with data coming from an ajax request:
editor.addButton('shortcodes', {
icon: 'icon_shortcodes',
tooltip: 'Your tooltip',
type: 'menubutton',
onPostRender: function() {
var ctrl = this;
$.getJSON( ajaxurl , function( menu) {
// menu is the array containing your menu items
ctrl.state.data.menu = ctrl.settings.menu = menu;
});
}
});
As far as I can tell, these other approaches are broken in TinyMCE 4.9.
After spending most of the day tinkering to fix my own usage of these approaches, this is the working function I've found:
function updateListbox(win, data) { // win is a tinymce.ui.Window
listbox = win.find('#listbox'); // Substitute your listbox 'name'
formItem = listbox.parent();
listbox.remove();
formItem.append({
label: 'Dynamic Listbox',
type: 'listbox',
name: 'listbox',
values: data
});
}
I have a static html form layout where i add extjs form fields using the "renderTo" config. In order to have form validation and simple submit methods i want to add the fields to a form panel. As the layout is managed by the html frame i don't want the form to be rendered by the panel (panel has html frame as contentEl and this should be used as is).
In extjs3 i could achieve this by adding the field not to the panel but to the BasicForm (formpanel.getForm().add(...)) but in extjs4 this method seems to be gone.
How can i do this using extjs4?
Thanks in advance.
Since you already have a Panel that uses the contentEl to render HTML into its body, I recommend to stick with this approach:
Replace the panel with an Ext.form.Panel instance - the configuration, particularly the contentEl config - can remain unchanged.
The code provided here will override a standard Ext class (Ext.layout.Layout) and introduce support for a 'renderItemTo' config property on child items of any Ext container or panel instance (including Ext.form.Panel).
The value of the config property should be the ID of an already rendered DOM node, e.g. a DIV element that is part of the HTML fragment used in as the contentEl of the parent container's body.
Ext.require(['Ext.layout.Layout'], function() {
Ext.override(Ext.layout.Layout, {
renderItem: function (item, target, position) {
if(item.renderItemTo) {
// render 'renderItemTo' components into the specified DOM element
item.render(item.renderItemTo, 1);
// don't allow container layout to seize the component
item.layoutManagedHeight = 2;
item.layoutManagedWidth = 2;
} else {
// just use standard Ext code for non-renderItemTo components
this.callOverridden(arguments);
}
},
isValidParent: function(item, target, position) {
// signal Ext that we are OK with were our 'renderItemTo' component is right now
// otherwise it would get moved during the layout process
return item.renderItemTo ? true : this.callOverridden(arguments);
}
});
});
Usage:
var panel = Ext.create('Ext.form.Panel', {
contentEl: 'form', // the DOM element ID that holds the HTML fragment for the body
title: 'My FormPanel with special FX',
items: [
{
xtype: 'textfield',
renderItemTo: 'text1', // the ID of a DOM element inside the HTML fragment
fieldLabel: 'Label 1',
},
{
xtype: 'textfield',
renderItemTo: 'text2', // the ID of a DOM element inside the HTML fragment
fieldLabel: 'Label 2'
}
]
});
I uploaded a working example to JSFiddle (note: resize the window if you experience a render problem - this is related to JSFiddle, not my override).
After digging through the layout system of ExtJS 4.1 i implemented a custom layout which moves the items after rendering to the desired position in the fixed markup. The result is the same as for the ExtJS 4.0.7 version from this thread. It seams to work for the ExtJS standard fields. I have some problems with my custom fields though.
Ext.define('Ext.ux.layout.Fixed', {
extend: 'Ext.layout.container.Auto',
alias: 'layout.uxfixed',
afterRenderItem: function(item) {
// move items with renderToFixedMarkup to desired position
if (item.renderToFixedMarkup) {
var target = Ext.getDom(item.renderToFixedMarkup);
this.moveItem(item, target);
}
},
isValidParent: function(item, target, position) {
// items with renderToFixedMarkup property are always positioned correctly
return (item.renderToFixedMarkup) ? true : this.callOverridden(arguments);
}
});
It can be used by setting "layout: 'uxfixed'" on the panel and the "renderToFixedMarkup" config on the items.
Let's say I have a grid with multiselect option on, when user selects 4 lists and wants to get the values ( alerted on screen) how would I do that? And how would I disable buttons untill at least one list is selected?
All questions you've asked are answered many times already. Also there are good ExtJS examples on sencha.com. For example list view grid shows multiple select and editable grid with writable store shows button enable on click. But THE MOST important is documentation! Let me explain functionality on following code. Most of it is from list view example.
This grid gets JSON from list.php which has following structure
{"authors":[{"surname":"Autho1"},{"surname":"Autho2"}]}
And the grid:
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.panel.*'
]);
Ext.onReady(function(){
// Here i've definned simple model with just one field
Ext.define('ImageModel', {
extend: 'Ext.data.Model',
fields: ['surname']
});
var store = Ext.create('Ext.data.JsonStore', {
model: 'ImageModel',
proxy: {
type: 'ajax',
url: 'list.php',
reader: {
type: 'json',
root: 'authors'
}
}
});
store.load();
var listView = Ext.create('Ext.grid.Panel', {
id: 'myPanel', // Notice unique ID of panel
width:425,
height:250,
collapsible:true,
renderTo: Ext.getBody(),
store: store,
multiSelect: true,
viewConfig: {
emptyText: 'No authors to display'
},
columns: [{
text: 'File',
flex: 50,
// dataIndex means which field from model to load in column
dataIndex: 'surname'
}],
dockedItems: [{
xtype: 'toolbar',
items: [{
// This button will log to console authors surname who are selected
// (show via firebug or in chrome js console for example)
text: 'Show selected',
handler: function() {
// Notice that i'm using getCmp(unique Id of my panel)
// to get panel regerence. I could also use
// this.up('toolbar').up('myPanel')
// see documentation for up() meaning
var selection = Ext.getCmp('myPanel').getSelectionModel().getSelection();
for (var i=0; i < selection.length; i++) {
console.log(selection[i].data.surname);
}
}
},{
text: 'Disabled btn',
id: 'myHiddenBtn', // Notice unique ID of my button
disabled: true // disabled by default
}]
}]
});
// Here i'm waiting for event which is fired
// by grid panel automatically when you click on
// any item of grid panel. Then I lookup
// my button via unique ID and set 'disabled' property to false
listView.on('itemclick', function(view, nodes){
Ext.getCmp('myHiddenBtn').setDisabled(false);
});
});
I didn't knew how to do this from top of my head, but I used documentation and the result works ;-). See Grid panel docs for more information.