mirror of
https://github.com/ansible/awx.git
synced 2026-03-14 07:27:28 -02:30
Use select lists for multiple choice answers
This commit is contained in:
@@ -507,14 +507,14 @@ function($compile, Rest, GetBasePath, TextareaResize,CreateDialog, GenerateForm,
|
||||
url = params.url,
|
||||
callback=params.callback,
|
||||
scope = params.scope,
|
||||
i, j,
|
||||
i,
|
||||
requiredAsterisk,
|
||||
requiredClasses,
|
||||
defaultValue,
|
||||
choices,
|
||||
element,
|
||||
minlength, maxlength,
|
||||
checked, min, max,
|
||||
min, max,
|
||||
survey_url = GetBasePath('job_templates') + id + '/survey_spec/' ;
|
||||
|
||||
//for toggling the input on password inputs
|
||||
@@ -605,41 +605,35 @@ function($compile, Rest, GetBasePath, TextareaResize,CreateDialog, GenerateForm,
|
||||
if(question.type === 'multiplechoice'){
|
||||
choices = question.choices.split(/\n/);
|
||||
element = (question.type==="multiselect") ? "checkbox" : 'radio';
|
||||
question.default = (question.default) ? question.default : (question.default_multiselect) ? question.default_multiselect : "" ;
|
||||
html+='<div class="survey_taker_input" > ';
|
||||
for( j = 0; j<choices.length; j++){
|
||||
checked = (!Empty(question.default) && question.default.indexOf(choices[j])!==-1) ? "checked" : "";
|
||||
choices[j] = $filter('sanitize')(choices[j]);
|
||||
html+= '<input type="'+element+'" class="mc" ng-model="'+question.variable+'" ng-required="'+question.required+'" name="'+question.variable+ ' " id="'+question.variable+'" value=" '+choices[j]+' " '+checked+' >' +
|
||||
'<span>'+choices[j] +'</span><br>' ;
|
||||
|
||||
if (question.default) {
|
||||
scope[question.variable] = question.default;
|
||||
} else {
|
||||
scope[question.variable] = '';
|
||||
}
|
||||
html+= '<div class="error survey_error" ng-show="job_launch_form.'+ question.variable + '.$dirty && ' +
|
||||
'job_launch_form.'+question.variable+'.$error.required\">Please select an answer.</div>'+
|
||||
'<div class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></div>';
|
||||
|
||||
html+='<div class="survey_taker_input" > ';
|
||||
html += '<survey-question type="' + question.type + '" index="' + question.index + '" survey-questions="survey_questions" ng-model="' + question.variable + '" ng-required="' + question.required + '"></survey-question>';
|
||||
// html+= '<div class="error survey_error" ng-show="job_launch_form.'+ question.variable + '.$dirty && ' +
|
||||
// 'job_launch_form.'+question.variable+'.$error.required\">Please select an answer.</div>'+
|
||||
// '<div class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></div>';
|
||||
html+= '</div>'; //end survey_taker_input
|
||||
}
|
||||
|
||||
if(question.type === "multiselect"){
|
||||
//seperate the choices out into an array
|
||||
choices = question.choices.split(/\n/);
|
||||
question.default = (question.default) ? question.default : (question.default_multiselect) ? question.default_multiselect : "" ;
|
||||
//ensure that the default answers are in an array
|
||||
scope[question.variable] = question.default.split(/\n/);
|
||||
//create a new object to be used by the surveyCheckboxes directive
|
||||
scope[question.variable + '_object'] = {
|
||||
name: question.variable,
|
||||
value: (question.default.split(/\n/)[0]==="") ? [] : question.default.split(/\n/) ,
|
||||
required: question.required,
|
||||
options:[]
|
||||
};
|
||||
//load the options into the 'options' key of the new object
|
||||
for(j=0; j<choices.length; j++){
|
||||
scope[question.variable+'_object'].options.push( {value:choices[j]} );
|
||||
if (question.default) {
|
||||
scope[question.variable] = question.default.split(/\n/);
|
||||
} else {
|
||||
scope[question.variable] = '';
|
||||
}
|
||||
//surveyCheckboxes takes a list of checkboxes and connects them to one scope variable
|
||||
html += '<survey-checkboxes name="'+question.variable+'" ng-model=" '+question.variable + '_object " ng-required="'+question.required+'">'+
|
||||
'</survey-checkboxes>{{job_launch_form.'+question.variable+'_object.$error.checkbox}}'+
|
||||
'<div class="error survey_error" ng-show="job_launch_form.'+question.variable+'.$error.checkbox">Please select at least one answer.</div>';
|
||||
//create a new object to be used by the surveyCheckboxes directive
|
||||
html += '<survey-question type="' + question.type + '" index="' + question.index + '" survey-questions="survey_questions" ng-model="' + question.variable + '" ng-required="' + question.required + '"></survey-question>';
|
||||
// html += '<survey-checkboxes name="'+question.variable+'" ng-model=" '+question.variable + '_object " ng-required="'+question.required+'">'+
|
||||
// '</survey-checkboxes>{{job_launch_form.'+question.variable+'_object.$error.checkbox}}'+
|
||||
// '<div class="error survey_error" ng-show="job_launch_form.'+question.variable+'.$error.checkbox">Please select at least one answer.</div>';
|
||||
}
|
||||
|
||||
if(question.type === 'integer'){
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import listGenerator from '../../shared/list-generator/main';
|
||||
import questions from './questions/main';
|
||||
import surveys from './surveys/main';
|
||||
import render from './render/main';
|
||||
import shared from './shared/main';
|
||||
|
||||
export default
|
||||
@@ -8,5 +9,6 @@ export default
|
||||
[ listGenerator.name,
|
||||
questions.name,
|
||||
surveys.name,
|
||||
render.name,
|
||||
shared.name
|
||||
]);
|
||||
|
||||
@@ -18,13 +18,9 @@ export default
|
||||
index = params.index,
|
||||
required,
|
||||
element,
|
||||
choices,
|
||||
i,
|
||||
checked,
|
||||
max,
|
||||
min,
|
||||
defaultValue,
|
||||
answers,
|
||||
html = "";
|
||||
|
||||
question.index = index;
|
||||
@@ -65,18 +61,28 @@ export default
|
||||
'</div></div>';
|
||||
}
|
||||
if(question.type === 'multiplechoice' || question.type === "multiselect"){
|
||||
choices = question.choices.split(/\n/);
|
||||
element = (question.type==="multiselect") ? "checkbox" : 'radio';
|
||||
question.default = (question.default) ? question.default : (question.default_multiselect) ? question.default_multiselect : "" ;
|
||||
answers = question.default.split(/\n/);
|
||||
html += '<div class="input_area">';
|
||||
for( i = 0; i<choices.length; i++){
|
||||
checked = (!Empty(question.default) && $.inArray(choices[i], answers) !== -1) ? "checked" : "";
|
||||
choices[i] = $filter('sanitize')(choices[i]);
|
||||
choices[i] = scope.serialize(choices[i]);
|
||||
html+= '<input type="'+element+'" class="mc" ng-required="!'+question.variable+'" name="'+question.variable+ ' " id="'+question.variable+'" value=" '+choices[i]+' " '+checked+' disabled>' +
|
||||
'<span>'+choices[i] +'</span><br>' ;
|
||||
|
||||
question.default = question.default_multiselect || question.default;
|
||||
|
||||
var defaultScopePropertyName =
|
||||
question.variable + '_default';
|
||||
|
||||
if (question.default) {
|
||||
if (question.type === 'multiselect' && typeof question.default.split === 'function') {
|
||||
scope[defaultScopePropertyName] = question.default.split('\n');
|
||||
} else if (question.type !== 'multiselect') {
|
||||
scope[defaultScopePropertyName] = question.default;
|
||||
}
|
||||
} else {
|
||||
scope[defaultScopePropertyName] = '';
|
||||
}
|
||||
|
||||
html += '<div class="row">';
|
||||
html += '<div class="col-xs-8">';
|
||||
html += '<div class="SurveyControls-selectWrapper">';
|
||||
html += '<survey-question type="' + question.type + '" index="' + question.index + '" survey-questions="survey_questions" ng-required="' + question.required + '" ng-model="' + defaultScopePropertyName + '"></survey-question>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import surveyQuestion from './survey-question.directive';
|
||||
import multipleChoice from './multiple-choice.directive';
|
||||
import multiSelect from './multiselect.directive';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplates.surveyMaker.render', [])
|
||||
.directive('surveyQuestion', surveyQuestion)
|
||||
.directive('multipleChoice', multipleChoice)
|
||||
.directive('multiSelect', multiSelect);
|
||||
@@ -0,0 +1,56 @@
|
||||
/* jshint unused: vars */
|
||||
import {templateUrl} from '../../../shared/template-url/template-url.factory';
|
||||
|
||||
function link($timeout, scope, element, attrs, ngModel) {
|
||||
attrs.width = attrs.width || '100%';
|
||||
|
||||
$timeout(function() {
|
||||
|
||||
$.fn.select2.amd.require(
|
||||
[ 'select2/utils',
|
||||
'select2/dropdown',
|
||||
'select2/dropdown/search',
|
||||
'select2/dropdown/attachContainer',
|
||||
'select2/dropdown/closeOnSelect',
|
||||
'select2/dropdown/minimumResultsForSearch'
|
||||
],
|
||||
function(Utils, Dropdown, Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch) {
|
||||
|
||||
var CustomAdapter =
|
||||
_.reduce([Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch],
|
||||
function(Adapter, Decorator) {
|
||||
return Utils.Decorate(Adapter, Decorator);
|
||||
}, Dropdown);
|
||||
|
||||
element.find('select').select2(
|
||||
{ multiple: scope.isMultipleSelect(),
|
||||
minimumResultsForSearch: Infinity,
|
||||
theme: 'bootstrap',
|
||||
width: attrs.width,
|
||||
dropdownAdapter: CustomAdapter
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export default
|
||||
[ '$timeout',
|
||||
function($timeout) {
|
||||
var directive =
|
||||
{ restrict: 'E',
|
||||
require: 'ngModel',
|
||||
scope: {
|
||||
isMultipleSelect: '&multiSelect',
|
||||
choices: '=',
|
||||
question: '=',
|
||||
isRequired: '=ngRequired',
|
||||
selectedValue: '=ngModel'
|
||||
},
|
||||
templateUrl: templateUrl('job-templates/survey-maker/render/multiple-choice'),
|
||||
link: _.partial(link, $timeout)
|
||||
};
|
||||
return directive;
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,5 @@
|
||||
<div>
|
||||
<select class="form-control" ng-model="selectedValue" multi-select ng-required="isRequired">
|
||||
<option ng-repeat="choice in choices" value="{{choice}}" ng-selected="selectedValue.indexOf(choice) !== -1">{{choice}}</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -0,0 +1,42 @@
|
||||
/* jshint unused: vars */
|
||||
|
||||
/**
|
||||
* @ngdoc
|
||||
*
|
||||
* @name jobTemplates.surveyMaker.render.multiSelect
|
||||
* @description
|
||||
* Angular provides no method of binding to "multiple" for
|
||||
* select lists. This is because under normal circumstances,
|
||||
* the structure of `ng-model` changes based on whether `multiple`
|
||||
* is true or false. We're not needing to "bind" to "multiple",
|
||||
* but we do need to pass in the value dynamically. This allows
|
||||
* us to do that.
|
||||
*/
|
||||
|
||||
var directive =
|
||||
{ require: 'ngModel',
|
||||
compile: function() {
|
||||
return {
|
||||
pre: function(scope, element, attrs, ngModel) {
|
||||
if (_.isUndefined(scope.isMultipleSelect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scope.isMultipleSelect()) {
|
||||
return;
|
||||
}
|
||||
|
||||
element.attr('multiple', true);
|
||||
attrs.multiple = true;
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
},
|
||||
priority: 1000
|
||||
};
|
||||
|
||||
export default
|
||||
function() {
|
||||
return directive;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/* jshint unused: vars */
|
||||
import {templateUrl} from '../../../shared/template-url/template-url.factory';
|
||||
|
||||
/**
|
||||
* @ngdoc
|
||||
* @name jobTemplates.surveyMaker.render.surveyQuestion
|
||||
* @description
|
||||
* Directive that will eventually hold all logic
|
||||
* for rendering different form controls based on
|
||||
* the question type for a survey.
|
||||
*/
|
||||
|
||||
// Since we're generating HTML for the entire survey, and _then_
|
||||
// calling $compile, this directive never actually gets compiled
|
||||
// with the question object we need. Therefore, we give it the index
|
||||
// of the question as an attribute (not scope) and then look it up
|
||||
// in the `survey_questions` by that index when it the directive gets
|
||||
// compiled.
|
||||
//
|
||||
function findQuestionByIndex(questions, index) {
|
||||
return _.find(questions, function(question) {
|
||||
return question.index === index;
|
||||
});
|
||||
}
|
||||
|
||||
function link(scope, element, attrs) {
|
||||
var question = findQuestionByIndex(scope.surveyQuestions, Number(attrs.index));
|
||||
|
||||
scope.question = question;
|
||||
|
||||
if (!_.isUndefined(question.choices)) {
|
||||
scope.choices = question.choices.split('\n');
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
function() {
|
||||
var directive =
|
||||
{ restrict: 'E',
|
||||
scope:
|
||||
{ surveyQuestions: '=',
|
||||
selectedValue: '=ngModel',
|
||||
isRequired: '@ngRequired'
|
||||
},
|
||||
templateUrl: templateUrl('job-templates/survey-maker/render/survey-question'),
|
||||
link: link
|
||||
};
|
||||
|
||||
return directive;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<multiple-choice
|
||||
multi-select="question.type === 'multiselect'"
|
||||
question="question"
|
||||
choices="choices"
|
||||
ng-required="isRequired === 'true'"
|
||||
ng-model="selectedValue">
|
||||
</multiple-choice>
|
||||
@@ -0,0 +1,11 @@
|
||||
/** @define SurveyControls */
|
||||
|
||||
.SurveyControls {
|
||||
&-selectWrapper {
|
||||
margin-left: 15px;
|
||||
}
|
||||
&--dropdown {
|
||||
z-index: 10000;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -136,13 +136,13 @@ export default
|
||||
if(questions.length>0){
|
||||
$('#survey-save-button').removeAttr('disabled');
|
||||
}
|
||||
scope.finalizeQuestion(questions[key], key);
|
||||
scope.finalizeQuestion(questions[key], Number(key));
|
||||
}
|
||||
else if(scope.mode=== 'edit' ){
|
||||
if(scope.survey_questions.length>0 && scope.can_edit === true){
|
||||
$('#survey-save-button').removeAttr('disabled');
|
||||
}
|
||||
scope.finalizeQuestion(scope.survey_questions[key] , key);
|
||||
scope.finalizeQuestion(scope.survey_questions[key] , Number(key));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -464,7 +464,7 @@ export default
|
||||
scope.survey_questions[key] = data;
|
||||
}
|
||||
$('#'+elementID).empty();
|
||||
scope.finalizeQuestion(data , key);
|
||||
scope.finalizeQuestion(data , Number(key));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -70,6 +70,9 @@ export default
|
||||
}
|
||||
|
||||
},
|
||||
_allowInteraction: function(e) {
|
||||
return !!$(e.target).is('.select2-input') || this._super(e);
|
||||
},
|
||||
callback: callback
|
||||
});
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper'])
|
||||
onResizeStop = params.onResizeStop,
|
||||
onClose = params.onClose,
|
||||
onOpen = params.onOpen,
|
||||
_allowInteraction = params._allowInteraction,
|
||||
callback = params.callback,
|
||||
beforeDestroy = params.beforeDestroy,
|
||||
closeOnEscape = (params.closeOnEscape === undefined) ? false : params.closeOnEscape,
|
||||
@@ -177,7 +178,8 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper'])
|
||||
if (onOpen) {
|
||||
onOpen();
|
||||
}
|
||||
}
|
||||
},
|
||||
_allowInteraction: _allowInteraction
|
||||
});
|
||||
};
|
||||
}])
|
||||
|
||||
Reference in New Issue
Block a user