I want to reuse the value of a previous field into a form to initialize a new field or better a new section of the form, depending of the reference value
How to proceed ?
Jean-Marie
I want to reuse the value of a previous field into a form to initialize a new field or better a new section of the form, depending of the reference value
How to proceed ?
Jean-Marie
@jms27000 I think that you are asking how to use the value of a field on a form to change the value / options available for another field on that same form? If so: the only ability we offer to do that sort of thing is through writing JavaScript and adding it to form.js
. Other than the file picker, the most advanced custom logic we have written thus far is for OSC’s Ansys Workbench where we conditionally show/hide a field based on the user’s selections, and change the available number of CPU cores based on which compute node type the user wants.
Hi. Morgan
Thanks for your answer. It’s the idea. I will test it when I’ll be back from vacations.
Jean-Marie
Hi, Morgan,
back from vacations but not still at work. as you know, we will use the file_picker function in each form.yml.erb we’ll have to generate. a good idea seems to let the “file_picker” file as you send it and to avoid to modify it.
question : how to create a generic form.js file which realizes the include of all other “js” files located in this app directory ?
may be you prefer that i open a new topic on that subject ?
thanks a lot.
jean-marie
We can answer this question here; it’s fine. In general I think your preference to avoid changing 3rd party code is probably a good idea unless you need to fix something (and even then pull requests on the main repo are welcome!). I suggest the following three options:
$APP_ROOT/local/.js
and put your code there; this takes advantage of our support for the notion of sub-apps (which I do not understand very well). Given that you would be adding code to a ‘hidden’ file this is by far my least favorite solution.bc_js_filepicker
project, modify src/main.js
to include code specific to your project, build it yourself (using NodeJS 10+), and then just include form.js
as usual./etc/ood/config/apps/dashboard/initializers
that alters BatchConnect::App#custom_javascript_files
to return additional app-specific JavaScript files.An example of the last:
require 'batch_connect/app'
module BatchConnect
class App
# Return any custom JS files that exist at root in order
#
# Use numeric prefixes to control load order: 00_file.js, 01_file.js, ...
#
# @return [Pathname] paths to custom javascript files that exist
def custom_javascript_files
(
Pathname.glob(root.join('*js')) +
# Add the JS file for a possible sub_app
[sub_app_root.join("#{sub_app}.js")]
).select(&:file?).sort
end
end
end
Hi, Morgan
i have spent some time to test the dynamic form with the following context :
my test :
the result is OK, but not realized like you done with the Workbench example, because i have introduced a kind of loop
is it the good way to follow ? thanks for your reading
jean-marie
form.yml.erb :
<%-
name = "Fluent"
name_down = name.downcase
name_up = name.upcase
vnc_disp = qdisplay
projects = qprojects
hold_jids = qhold_jid (name)
versions = qversion(name_down)
my_work_dir = qdatadir
max_cores = qnb_cores
free_cores = qnb_free_cores
-%>---
cluster: "verhpc"
form:
- working_dir
- type_node
- test1
- test2
- inputfile
attributes:
working_dir:
label: "Working Directory"
data-filepicker: true
readonly: false
help: "Type the workingdir you want to work in :"
value: "<%= my_work_dir %>"
test1:
widget: "text_field"
label: "test1"
value: ""
help: "Description of the test1"
test2:
widget: "text_field"
label: "test2"
help: "Description of the test2"
inputfile:
data-filepicker: true
readonly: false
value: "<%= my_work_dir %>"
type_node:
widget: select
label: "Type_Node"
help: "You can't leave this blank"
options:
- [ "DELL_16", 16 ]
- [ "DELL_28", 28 ]
- [ "DELL_32", 32 ]
value: "DELL_16"
required: true
dyn_form.js :
'use strict'
/**
* Toggle the visibilty of a form group
*
* @param {string} form_id The form identifier
* @param {boolean} show Whether to show or hide
*/
function toggle_visibilty_of_form_group(form_id, show) {
let form_element = $(form_id);
let parent = form_element.parent();
if(show) {
parent.show();
} else {
form_element.val('');
parent.hide();
}
}
/**
* Toggle the visibilty of the test fields
*
*/
function toggle_tests_field_visibility() {
let type_node = $("#batch_connect_session_context_type_node");
toggle_visibilty_of_form_group(
'#batch_connect_session_context_test1',
type_node.val() === '16'
);
toggle_visibilty_of_form_group(
'#batch_connect_session_context_test2',
type_node.val() !== '16'
);
}
/**
* Sets the change handler for the node_type select.
*/
function set_node_type_change_handler() {
let node_type_input = $('#batch_connect_session_context_node_type');
node_type_input.change(toggle_tests_field_visibility);
}
function set_node_inputfile_change_handler() {
let inputfile_type = $('#batch_connect_session_context_inputfile');
let working_dir_type = $('#batch_connect_session_context_working_dir');
let the_dir = working_dir_type.val();
if (the_dir !== old_dir) {
inputfile_type.attr('value', the_dir);
old_dir = the_dir;
}
}
/**
* Install event handlers
*/
function main() {
$(document).ready(function() {
// Ensure that fields are shown or hidden based on what was set in the last session
toggle_tests_field_visibility();
set_node_type_change_handler();
set_node_inputfile_change_handler();
});
};
/* main */
let old_dir = "none";
setInterval(main, 5000);
A few comments on this:
setInterval
should be setTimeout
if you only intend for the function to execute once: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
.keyup
so that there is no lag between the user finishing typing and the update occurring.$(document.ready(function() {...})
in Batch Connect form.js
files because the contents of those scripts are concatenated into the document itself rather than linked via script tags in the document header; some day I will need to update the Abaqus app and I will update its form to remove the ready
event listenerset_node_inputfile_change_handler
is not actually setting a change handler for anythingHi, Morgan and thanks for these informations. As I’m not specialized as a developper, all your infos are’nt clear in first reading, but with time, it’ll be ok for me. What do i have to do to have a
" set_node_inputfile_change_handler
" function operational ?
Have a good weekend.
jean-marie
The set_*_change_handler
functions are meant to install HTML event listeners to avoid having to write our own event loops like you did with setInterval
. The event listeners which I called handlers, are what actually do the work when the event occurs.
So for the node_inputfile
element I would do something like this:
function set_node_inputfile_change_handler() {
let inputfile_type = $('#batch_connect_session_context_inputfile');
// Handle typing
// Note that the file picker does not generate events at this time.
// I am going to release an updated version that will emit a keyup event.
inputfile_type.keyup(handle_inputfile_changes);
}
function handle_inputfile_changes(event) {
// Wrap the input with jQuery for convenience
let inputfile_type = $(event.target);
// Do something with your input
}
I just updated the file picker to version 0.3.0 which emits a keyup
event whenever a file is picked. That will let you use event listeners that will work even when the file picker is what changes the input element. I also added the ability to set the Favorites menu through another data attribute in form.yml
.
file_picker_input:
data-filepicker: true
data-file_picker_favorites: '[{"title": "Team Project", "href": "/fs/project/PZS0714"}]'
Where data-file_picker_favorites
value is expected to be a string containing JSON in the format:
[
{
"title": "...",
"href": "..."
},
...
]
Hi, everybody,
Morgan, i have tested your file-picker v0.3.0 with the keyup event as proposed.
good job ! thanks a lot.
jean-marie