• 목록
  • 아래로
  • 위로

5/24

[기능] 문제 불러오기 기능을 위한 액션, 함수, 쿼리 추가

 

문제 출제 및 수정 시에 exec_json으로 기존의 시험문제를 불러올 수 있는 기능을 고안해봤습니다.
기본적으로는 1-1) 작동 중인 모듈의 모듈번호 기준으로 문제를 가져오고, 1-2) 모듈번호 인자를 전달하지 않으면 모든 시험문제를 리스트로 가져와서, 2) 문제를 선택한 뒤 출제 및 수정 폼 필드들에 덮어쓰는 방식입니다.
다음과 같이 액션, 함수, 쿼리를 추가해봤습니다.

 

1. module.xml 에 액션 추가

<action name="getQuestions" type="model" />

 

 

2. exam.model.php 에 함수 추가

/**
 * 모듈 내의 모든 문제를 구함
 * @param int $module_srl
 * @return object
 */
function getQuestions($module_srl = 0, $status = 'Y')
{
	// get a list of questions
	$args = new stdClass;
	$args->module_srl = $module_srl ? $module_srl : Context::get('module_srl');
	if ( !Context::get('grant')->manager ) $args->status = $status ? $status : Context::get('status');
	$output = executeQueryArray('exam.getQuestions', $args);

	// return if an error occurs in the query results
	if ( !$output->toBool() ) return;

	$this->add('question_list', $output->data);
	return $output->data;
}

 

3. getQuestions 쿼리 xml 추가

<query id="getQuestions" action="select">
    <tables>
        <table name="exam_question" alias="question" />
        <table name="exam" alias="exam" />
    </tables>
    <columns>
        <column name="question.*" />
        <column name="exam.title" alias="document_title" />
		<query id="getCategoryTitle" alias="category_title">
			<tables>
				<table name="document_categories" alias="category" />
			</tables>
			<columns>
				<column name="category.title" />
			</columns>
			<conditions>
				<condition operation="equal" column="category.category_srl" default="exam.category_srl" />
			</conditions>
		</query>
    </columns>
    <conditions>
        <condition operation="equal" column="question.module_srl" var="module_srl" filter="number" pipe="and" />
		<condition operation="equal" column="exam.document_srl" var="question.document_srl" notnull="notnull" pipe="and" />
        <condition operation="equal" column="question.status" var="status" pipe="and" />
    </conditions>
    <navigation>
		<index var="question.list_order" default="question.list_order" order="ASC" />
    </navigation>
</query>

 

4. 스킨의 _paper_q_write.html : 불러오기 버튼

<a href="javascript:void(0);" class="exam_btn btn_close btn_load" data-msrl="{$module_info->module_srl}">{$lang->cmd_load}</a>

 

 

5. exam.js : exec_json으로 문제 목록 가져오기

var question_list = [];
// 문제 불러오기 이벤트
$(document).on('click', 'a.btn_load', function(event) {
	event.preventDefault();
	var container = $(this).parent().next('.question_load_area');
	container.fadeIn();
	if ( !container.is(':empty') ) return false;

	var module_srl = $(this).data('msrl');
	var params = {
		module_srl : module_srl,
		status : 'Y'
	};
	exec_json('exam.getQuestions', params, function(ret_obj) {
		question_list = ret_obj.question_list;
		container.html('<div class="question_load"><h3>문제 불러오기<i class="xi-close"></i></h3>' +
			'<ul class="load_selection"></ul>' +
			'<div class="btn_search">' +
				'<a href="javascript:void(0);" class="exam_btn btn_close" type="button">취소</a>' +
				'<a href="javascript:void(0);" class="exam_btn btn_submit" type="submit">덮어쓰기</a>' +
			'</div>'+
		'</div>');
		$.each(question_list, function(i, v) {
			$('.load_selection').append('<li class="load_target" id="question_'+ i +'" title="'+ v.content +'">' +
				'<h4>' + v.document_title + '</h4>' +
				'<p>' +
					'<strong>' + v.title + '</strong>' +
					'<small>' + v.regdate.substr(0, 8) + '</small>' +
				'</p>' +
			'</li>');
			if ( v.category_title ) $('#question_' + i).children('h4').append('<span> (' + v.category_title +')</span>');
		});
	});
});

 

6. exam.js : 로드한 데이터로 폼 필드에 덮어쓰기

// 불러온 문제 선택
$(document).on('click', '.load_target', function() {
	$(this).parent().children('.load_target').not(this).removeClass('selected');
	$(this).addClass('selected');
});
// 선택된 문제 덮어쓰기
$(document).on('click', '.question_load_area .exam_btn.btn_submit', function(event) {
	event.preventDefault();
	if ( !$('.load_target.selected').length ) alert('문제를 선택해주세요');

	var idx = $('.load_target.selected').attr('id').replace('question_', '');
	var source = question_list[idx];
	
	// 난이도
	$('#q_level' + source.question_level).prop('checked', true);
	// 문제유형
	$('#q_type' + source.question_type).prop('checked', true);
	// 문제
	$('#q_title').val(source.title);
	// 지문 사용?
	if ( source.use_description === 'Y' ) $('#use_description').prop('checked', true);
	// 지문 머리글
	$('#q_description_title').val(source.description_title);
	// 지문 내용 -> CK에디터
	if ( $('.q_editor').find('.cke').length )
	{
		$('.q_editor').find('iframe').contents().find('.xe_content').html(source.description);
	}
	// 지문 내용 -> 프로알라
	else if ( $('.q_editor').children('.fr-box').length )
	{
		$('.fr-placeholder').hide();
		$('.fr-element').html(source.description);
	}
	// 지문 내용 -> textarea
	else
	{
		$('input[name="q_description_content"]').val(source.description);
		$('.q_editor').find('textarea').val(source.description);
	}
	// 정답 : 객관식
	if ( !source.question_type )
	{
		$('#answer_type0').show();
		$('#answer_type1').hide();
		$('input[name="q_answer1"]').val(source.answer1);
		$('input[name="q_answer2"]').val(source.answer2);
		$('input[name="q_answer3"]').val(source.answer3);
		$('input[name="q_answer4"]').val(source.answer4);
		$('input[name="q_answer5"]').val(source.answer5);
		$('.answer_marking').removeClass('on');
		var answers = source.answer.split(',')
		$.each(answers, function(i, v) {
			$('.answer_marking').eq(Number($.trim(v)) - 1).addClass('on');
		});
	}
	// 정답 : 주관식
	else
	{
		$('#answer_type0').hide();
		$('#answer_type1').show();
		$('input[name="q_answer6"]').val(source.answer);
	}
	$('input[name="q_answer"]').val(source.answer);
	// 복수답안 처리
	$('select[name="answer_check_type"]').val(source.answer_check_type);
	// 해설
	$('#q_content').val(source.content);
	// 배점
	$('#q_point').val(source.point);
	
	// 모달 윈도우 닫기
	$('.question_load_area').hide();
});

공유

facebooktwitterpinterestbandkakao story
퍼머링크

댓글 0

에디터