Adding CSS class to form element in Moodle - moodle

I create forms in Moodle by extending the moodle moodleform class and calling the addElement() or createElement() methods. For example, I create a select element this way:
$mform->addElement('select', 'mySelect', 'Select title' , $list);
Where $mform is a reference to the form, and $list is an associative array like:
$list = array('1'=>'one', '2'=>'two', '3'=>'three').
The question is: Is there a way to add a CSS class associated with this or other form elements?
I other words, I would like to programmatically add a class myClass, so that the HTML code looks like this:
<select class="myClass">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

Use the 5th addElement parameter - https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#select
$mform->addElement('select', 'myselect', 'Select title', $list, ['class' => 'myclass']);
(And I assume your real code does this correctly, but make sure you use get_string() for param 3, so it can be translated).

Related

Trying to choose any non-disabled option from a select element

I have a parent record with multiple child records, all shown together on the ViewParentWithChildren and EditParentWithChildren screens. I want to write a cypress test that adds a new child record to an existing parent record. Each child record is in a <tr> of course.
The problem is, the <select> element has many <option disabled> invalid options in it. I need to select a valid, enabled one, and I don't know ahead of time what the names/values in that option are going to be. I don't care what they are, I just need to select any non-disabled option.
I try a standard-ish:
cy.contains('button', /Add Another Child Record/i).click();
cy.get('[name=child_id_name][value=""]') // newly added has nothing in the required field
.parents('tr')
.within(tr => {
cy.get('input[name=child_id_name]').type(randomAlpha());
cy.get('input[name=description]').type(randomAlpha());
cy.get('select[name=type]').select(?????); // TODO
});
Cypress only allows selecting an <option> via name, value, or index. Attempting to .select a valid <option> directly doesn't work, by design.
Here's a couple of other ways you may or may not find easier
Example page for POC
<select>
<option value="1" disabled>three</option>
<option value="2">two</option>
<option value="3" disabled>three</option>
<option value="4">four</option>
</select>
Method 1: Expose the <select> first
cy.get('select')
.should('have.value', '2') // by default the selected value is the first enabled
.then($select => {
cy.wrap($select)
.find('option:enabled:last')
.then($lastEnabledOption => {
cy.wrap($select).select($lastEnabledOption.val())
})
})
.should('have.value', '4') // check new value
Method 2: Set the selected attribute with jQuery
cy.get('select')
.should('have.value', '2') // initial value
.find('option:enabled:last')
.invoke('attr', 'selected', true)
cy.get('select')
.should('have.value', '4') // new value
The solution was kind of inside-out. Get all non-disabled options from that select first, then go within one of them, and "escape hatch" back out again to the select, feeding the .text() to the .select
cy.contains('button', /Add Another Child Record/i).click();
cy.get('[name=child_id_name][value=""]') // newly added has nothing in the required field
.parents('tr')
.within(tr => {
cy.get('input[name=child_id_name]').type(randomAlpha());
cy.get('input[name=description]').type(randomAlpha());
cy.get('select[name=type] option:not([disabled])') // get all its non-disabled options
.last() // the first option is usually blank for un-selecting, so, .last
.within(option => {
cy.root().closest('select').select(option.text());
});
});

TYPO3 - Display system categories and sub categories

I am a new typo3 user and actually I'm creating an extension that will allow me to display a list of categories created with the categories of the system, which will contain subcategories (categories and subcategories can have several subcategories), and finally a pdf file
I'm having a little trouble visualizing how to create this extension
Currently, I manage to retrieve and display the parent categories, but I have no idea how to display the different subcategories after clicking on a parent category
Does anyone have an idea how I could display my different subcategories?
there is some code :
Controller :
public function listAction()
{
$categories = $this->categorieRepository->findByPid(177);
$this->view->assign(
'categories' => $categories
);
}
List.html
<div>
<f:for each="{categories}" as="categorie">
<f:if condition="{categorie.parent} ">
<f:then>
</f:then>
<f:else>
<f:link.action action="list">
{categorie.title}
</f:link.action>
</f:else>
</f:if>
</f:for>
</div>
thanks In advance for your advice
Usually the listAction never get's any parameters and the pid is assigned by the storagePid that is automatically fetched by the repository. The repository also can have the setting to ignore the pid. You never mentioned it but as I see the pid in your code you could also include the option to transfer the pid by the URL as parameter.
Additionally, and that's the answer to your question, you can transfer the parent category, so the listAction would have one or two optional parameters. They have to be optional to display also something if no parameters are given:
public function listAction($parentCategeoryId = null, $pageId = null)
{
// HERE SOME LOGIC
// YOU HAD TO TRANSFER ALSO THE $pageId TO THE REPOSITORY IF USED
$categories = ...
$this->view->assign(
'categories' => $categories
);
}
The viewHelper can transfer the parameters if you add them there:
<f:link.action action="list" arguments="{parentCategeoryId: category.uid, pageId: categorie.pid}" >
{categorie.title}
</f:link.action>
This is no copy-paste answer, so you have still some work, but that's the general approach I'd follow.

Submitting forms containing multiple selects in Play Framework for Scala

I have a multiple select item in a Form. According to Play Framework's documentation, I need 'repeated values' to make all the selected options fit into a List[String] property of my data structure.
case class MyFormData (
fq_cset: Option[List[String]]
)
val myForm: Form[MyFormData] = Form(
mapping(
"fq_cset" -> optional(list(text))
)
)(MyFormData.apply _)(MyFormData.unapply _)
I quote Play's documentation:
When you are using repeated data like this, the form values sent by the browser must be named emails[0], emails[1], emails[2], etc.
I cannot figure out how to name the values like mentioned above. I tried to create a select element like this one
<select name="fq_cset">
<option name="fq_cset[0]" value="A" selected="selected">Value A</option>
<option name="fq_cset[1]" value="B" >Value B</option>
<option name="fq_cset[2]" value="C" selected="selected">Value C</option>
<option name="fq_cset[3]" value="D" >Value D</option>
</select>
but after submitting the form I see in the URL
/path?fq_cset=A&fq_cset=C
instead of
/path?fq_cset[0]=A&fq_cset[2]=C
The absence of the indexes enclosed in square brackets, prevents the correct binding of the parameters in the List[String] property named fq_cset in MyFormData class.
How can I get this to work properly? Is this the right approach to get what I need or I misunderstood the documentation?

Filtering a scope with multiple select in AngularJS

Here is my fiddle: http://jsfiddle.net/mwrLc/12/
<div ng-controller="MyCtrl">
<select ng-model="searchCountries" ng-options="cc.country for cc in countriesList | orderBy:'country'">
<option value="">Country...</option>
</select>
<select ng-model="searchCities" ng-options="ci.city for ci in citiesList | filter:searchCountries | orderBy:'city'">
<option value="">City...</option>
</select>
<ul>
<li ng-repeat="item in list | filter:searchCountries | filter:searchCities">
<p>{{item.country}}</p>
<p>{{item.city}}</p>
<p>{{item.pop}}</p>
<br>
</li>
</ul>
The first select filters the second one but also the result list.
The second select filters only the result list.
It works great until a country and a city are chosen. Then, when you choose another country, second select got reseted but the scope seems to be stuck with the old value.
i cant find a way to have it works properly... Please help!
The best solution is to reset the city model when a change to country model is detected via $scope.$watch():
function MyCtrl($scope) {
// ...
$scope.$watch('searchCountry', function() {
$scope.searchCity = null;
});
}
Note that I changed your model names to singular form ("searchCountry" and "searchCity") which is more appropriate considering the value of those models is set to a single country or city.
Here is the full working example: http://jsfiddle.net/evictor/mwrLc/13/
Ezekiel Victors solution is excellent. However, I ran into a bit of a dependency injection issue while trying to get this to work when referencing the controller from an ng-include. Thanks to the help from Ben Tesser I was able to resolve the issue. Ive attached a jsfiddle that details the fix:
http://jsfiddle.net/uxtx/AXvaM/
the main difference is that you need to wrap the searchCountry/searchCity as an object and set the default value to null. Ditto for the watch.
$scope.test = {
searchCountry: null,
searchCity: null
};
/// And your watch statement ///
$scope.$watch('test.searchCountry', function () {
$scope.test.searchCity = null;
});
In your template you'll change all references from searchCountry/searchCity to test.searchCountry.
I hope this saves someone some time. It's trixy.

$_post in Kohana controller

i was wondering if i can get a variable with $_post, in a kohana controller if the controller doesn't 'control' a form.
So, if i insert in a view something like:
<form name="ordering" id="ordering" method="post" action="">
<input type="hidden" id="ordering" value="0">
<select id="ordering" name="ordering">
....
in the controller i put :
$ordering = $_POST['ordering'];
but gives me an error
or
if ($this->request->method == 'POST') {
$ordering = $_POST['ordering'];
}
but in this case it never gets there(at this bunch of code).
so my question is: how can i retrieve in a controller a $_post variable if the controller doesn't handle only a form? thank you!
Kohana 3.0 :
if ($_POST)
{
$ordering = arr::get($_POST, 'ordering');
...
Kohana 3.1 :
if ($ordering = $this->request->post('ordering')) // or just $this->request->post()
{
...
PHP will issue a notice if you attempt to access an undefined array element.
So if the "ordering" form was never submitted, attempting to access $_POST['ordering'] will result in
PHP Notice: Undefined index: ordering in ...
Kohana's Arr class provides a nice helper method to get around this.
If you call
$ordering = Arr::get($_POST, 'ordering', 0);
It will retrieve the ordering value from the post variable. If $_POST['ordering'] is not set, it will return the third parameter instead. You can then try if ($ordering) ...
This is useful for $_POST/$_GET arrays, or any function that accepts arrays – it allows you to concisely specify a fallback behavior rather than having to test with isset.
One of the advantages of Kohana is that the source code tends to be very clean and easy to understand (which is nice because documentation is sparse.) I'd suggest you take a check out the Kohana_Arr class and look at the methods available!
ID's are unique! Use class insted or different IDs.
Your form and the select both have got ordering, change one to something else, like:
<form name="ordering_form" id="ordering_form" method="post" action="">
<input type="hidden" id="ordering_input" value="0">
<select id="ordering" name="ordering">
...
</select>
</form>
and in your Kohana Controller:
if( isset( $_POST['ordering'] ) )
{
$ordering = $_POST['ordering'];
}
this should work, because i cant find any other error