技術者情報 案件登録画面において、集計のために案件商品に対して疑似的に担当社員・担当部署を紐づける
-
必要な情報集計をするために、案件情報登録画面上で商品情報項目に対して、疑似的に担当社員・担当部署を紐づけするJSプラグインを紹介します。
このJSプラグインにより、案件情報登録画面上で、商品情報項目の担当・部署情報がテキスト項目型にセットされます。
データの登録更新処理にはREST APIを利用します。
ここではJSプラグインの実例や、プラグイン上で必要な値の確認方法を紹介します。
機能概要
案件登録画面の商品情報項目で「部署番号」、「部署名」、「部署番号」、「担当者名」が疑似的に紐付され登録できます。
部署用・担当者用の検索ボックスが設置され、検索結果が各テキストボックスに設定されます。
検索結果を選択後、エンターキー押下によってREST APIを利用した登録処理が行われます。
項目対応表
No. 名前 型 1 商品名 テキストボックス 2 部署番号 テキストボックス、ReadOnly 3 部署名 テキストボックス、ReadOnly 4 部署名 テキストボックス 5 検索ボタン(部署名) ボタン 6 部署リスト モーダルウィンドウ 7 担当者番号 テキストボックス、ReadOnly 8 担当者名 テキストボックス、ReadOnly 9 担当者名 テキストボックス 10 検索ボタン(担当者名) ボタン 11 担当者リスト モーダルウィンドウ
事前設定
営業プロセスの案件項目の変更画面上で、「案件商品情報」に制御用データを追加します。
No.4定義データは編集可能としておき、プラグイン側で編集不可とします。
※事前に商品情報項目に対して、部署番号・部署名・担当者番号・担当者名用の項目を、編集不可で用意しておく
マニフェストファイルの作成
JSプラグインの動作に必要なマニフェストファイルを作成します。
詳細はJSプラグインの作成マニュアルをご覧ください。
menu_typeについては、案件の新規登録画面であるため「2_007」です。
manifest.json
{
"plugin_name": {
"ja": "サンプルプラグイン04",
"en": "sample plugin04",
"zh": "插件的例子04",
"ko": "샘플 플러그인04"
},
"menu_type":0,
"target" : ["2_007"],
"note": {
"ja": "案件商品に対して担当社員・担当部署を紐づける",
"en": "Associate the employee in charge and the department in charge with the product",
"zh": "将负责员工和主管部门与产品相关联",
"ko": "안건 상품에 대해 담당 직원 · 부서를 끈 짓는"
},
"version":"ver 1.0",
"author":"softbrain"
}
必要な値の確認
JSプラグインの動作に必要になる内部コードを確認します。
本機能で必要な値は以下です。
・REST API認証情報(APIトークン)
<REST API認証情報(APIトークン)>
REST APIでデータ連携を行うために必要な認証情報です。
Javascriptの作成
詳細についてはAPI連携についてを確認してください。
また認証方法は「ユーザー認証」と「APIトークン認証」に2通りありますが、今回の例では「APIトークン認証」を利用します。
実際に作成するJavascriptファイルです。
APIトークンなどは事前に確認した値を設定します。
js/sample01.js
/*!
* eSM プラグインサンプル04 ver 1.0
* 案件登録画面 商品情報項目制御スクリプト
* https://www.softbrain.co.jp/
* Copyright (c) SOFTBRAIN Co.,Ltd.
*/
// APIトークン
var token = '968dea36-1137-42d3-bb81-cdeb0a806103';
// eSMのコンテキストパスを取得
var contextPath = window.location.protocol + '//' + window.location.host + '/' + document.URL.split('/')[3];
// リクエストRestAPIのパス
var restApiUrl = '/rest/v1/entities/search';
// 商品入力欄のデータ接頭辞
var prefix = 'EXT_8_ANKEN_PRODUCT_VARCHAR_';
// 検索タイプ部署
var typeDep = 'dep';
// 部署ラベル
var labelDep = '部署名';
// 検索タイプ担当者
var typePer = 'per';
// 担当者ラベル
var labelPer = '担当者';
// 検索テキストボックスID
var searchText = 'SearchText';
// 検索ボタンID
var viewResult = 'ViewResult';
// 検索候補リストID
var suggestList = 'SuggestList';
// 検索候補内容ID
var tipList = 'TipList'
// 検索候補ツールチップID
var toolTip = 'ToolTip'
//-----共通関数-----
/**
* テキストコンポーネントを読み取り専用に変更
* @param obj テーブルオブジェクト(td)
* @param type インデックス(商品情報項目のデータ番号)
* @param ankenProduct プロダクト番号
*/
function setReadOnly(obj, index, ankenProduct) {
// コンポーネント名の構築
var name = prefix + index + '_' + ankenProduct;
if($('input:text[name="' + name + '"]').size()) {
$('input:text[name="' + name + '"]').attr('readonly',true);
}
}
/**
* 検索コンポーネントを追加
* @param obj テーブルオブジェクト(td)
* @param type データタイプ
* @param ankenProduct プロダクト番号
*/
function appendSearchUI(obj, type, ankenProduct) {
var spanText = '';
if(type == typeDep) {
spanText = labelDep;
} else {
spanText = labelPer;
}
var searchPrefix = type + ankenProduct;
if(obj != null) {
// 外枠
var html = '<div class="searchArea addEmpSearchBox" style="margin-left: 0px; float: right;">';
// 検索エリア
html += '<div class="search" style="text-align: left; border-radius: 15px; box-shadow: 1px 1px 1 1 rgba(0, 0, 0, 0.4)">';
html += '<span class="proPlaceholder" style="color: rgb(170, 170, 170); display: inline;" onclick="javascript: $(\'#' +searchPrefix + searchText + '\').focus();">' + spanText + '</span>';
html += '<input id="' + searchPrefix + searchText + '" type="text" style="top: 1px;" autocomplete="off">';
if(type == typeDep) {
html += '<input id="' + searchPrefix + viewResult + '" type="button" onclick="viewDepartmentSuggestList($(\'#' + searchPrefix + searchText + '\').val(),\'' + ankenProduct + '\');" style="cursor: pointer;">';
} else {
html += '<input id="' + searchPrefix + viewResult + '" type="button" onclick="viewPersonSuggestList($(\'#' + searchPrefix + searchText + '\').val(),\'' + ankenProduct + '\');" style="cursor: pointer;">';
}
html += '</div>';
// 選択候補
html += '<div id="' + searchPrefix + suggestList + '" style="width: 250px; padding-top: 0px; display: none; -ms-overflow-x: hidden; max-height: none;">';
html += '<ul id="' + searchPrefix + tipList + '" class="tipList"></ul>';
html += '</div>';
html += '</div>';
// 外枠閉じ
$(obj).append(html);
// KeyUpイベントリスナー設定
$('#' + searchPrefix + searchText).keyup(function(e) {
var charCode = (typeof e.which === "number") ? e.which : e.keyCode;
// Enterキー入力
if (charCode==13){
// 検索ワードの取得
var searchWord = $('#' + searchPrefix + searchText).val();
// 候補リストの表示
if(type == typeDep) {
viewDepartmentSuggestList(searchWord, ankenProduct);
} else {
viewPersonSuggestList(searchWord, ankenProduct);
}
}
});
}
}
/**
* 検索候補リスト作成
* @param values 検索候補データ
* @param type データタイプ
* @param ankenProduct プロダクト番号
*/
function createSuggestList(values, type, ankenProduct) {
var searchPrefix = type + ankenProduct;
// 候補リストを空にする
$('#' + searchPrefix + tipList).empty();
// 候補リストにデータを追加する
$(values).each(function(i, o){
var name = o.item_data[0].text;
var num = o.item_data[1].text;
var html = null;
if(type == typeDep) {
html = '<li class="skc-res-item " onclick="setDepartmentSelectValue(\'' + ankenProduct + '\',\'' + name + '\',\'' + num + '\');" selectable="true"><div class="suggestedrow"><a href="javascript:void(0);"><span>' + name + '</span></a></div></li>';
} else {
html = '<li class="skc-res-item " onclick="setPersonSelectValue(\'' + ankenProduct + '\',\'' + name + '\',\'' + num + '\');" selectable="true"><div class="suggestedrow"><a href="javascript:void(0);"><span>' + name + '</span></a></div></li>';
}
$('#' + searchPrefix + tipList).append(html);
});
// ツールチップの表示
eSMQTips2.addTips(event, {'id':searchPrefix + toolTip,'my':'top center','at':'bottom center','scroll':false,'width':'240px','target':'#' + searchPrefix + searchText,'classes':'qtip-content-listview','dispData':'$(\'#' + searchPrefix + suggestList + '\')','events':{'visible':resizeTipFunc}});
}
//-----部署専用関数-----
/**
* 部署の検索候補リスト表示
* @param searchWord 検索ワード
* @param ankenProduct プロダクト番号
*/
function viewDepartmentSuggestList(searchWord, ankenProduct) {
searchDepartment(searchWord, ankenProduct);
}
/**
* 部署の選択設定
* @param ankenProduct プロダクト番号
* @param name 設定する部署名
* @param num 設定する部署番号
*/
function setDepartmentSelectValue(ankenProduct, name, num) {
var searchPrefix = typeDep + ankenProduct;
// 部署番号
$('input:text[name="' + prefix + '1_' + ankenProduct + '"]').val(num);
// 部署名
$('input:text[name="' + prefix + '2_' + ankenProduct + '"]').val(name);
// ツールチップを消す
try{ $("#qtip-" + searchPrefix + toolTip).qtip('destroy', true); }catch(e){};
}
//-----担当者専用関数-----
/**
* 担当者の検索候補リスト表示
* @param searchWord 検索ワード
* @param ankenProduct プロダクト番号
*/
function viewPersonSuggestList(searchWord, ankenProduct) {
searchPerson(searchWord, ankenProduct);
}
/**
* 担当者の選択設定
* @param ankenProduct プロダクト番号
* @param name 設定する部署名
* @param num 設定する部署番号
*/
function setPersonSelectValue(ankenProduct, name, num) {
var searchPrefix = typePer + ankenProduct;
// 担当者番号
$('input:text[name="' + prefix + '3_' + ankenProduct + '"]').val(num);
// 担当者名
$('input:text[name="' + prefix + '4_' + ankenProduct + '"]').val(name);
// ツールチップを消す
try{ $("#qtip-" + searchPrefix + toolTip).qtip('destroy', true); }catch(e){};
}
//-----ロードイベント関数-----
/**
* ページロード時のイベント処理
*
* 案件登録画面表示時に商品情報項目が存在した場合に
* 部署、担当者の制御テーブルを追加する
*/
$(document).ready(function(){
// 商品テーブルを検索
//var tables = $("div").find('iframe').contents().find('.productTable');
var tables = $('.productTable');
if(tables.size()) {
tables.each(function(i, o){
// 商品コードを取得
var productCode = $(o).closest('.commodityDetail').first().attr("data-product-code");
// 部署番号
var depNum = $(o).find('.dd')[10];
setReadOnly(depNum, 1, productCode, "test dep num");
// 部署名
var depName = $(o).find('.dd')[11];
setReadOnly(depName, 2, productCode, "test dep name");
appendSearchUI(depName, typeDep, productCode);
// 担当者番号
var perNum = $(o).find('.dd')[12];
setReadOnly(perNum, 3, productCode, "test per num");
// 担当者名
var perName = $(o).find('.dd')[13];
setReadOnly(perName, 4, productCode, "test per name");
appendSearchUI(perName, typePer, productCode);
});
}
});
//-----Ajax実行関数-----
/**
* 部署検索
* @param searchWord 検索ワード
* @param ankenProduct プロダクト番号
*/
function searchDepartment(searchWord, ankenProduct) {
// 検索ワードが未入力の場合は実行しない
if(searchWord == null || searchWord == '') {
return;
}
// RestAPIのURLの構築
var urlStr = contextPath + restApiUrl;
// 送信データ
var data = {
searchCondition: {
targetObjectName: "depart",
items: [
{
columnCode: 1502,
operator: "partly",
text: searchWord
}
]
},
columnCodes: [1502, 1506],
sortKeys: null,
fromIndex: 1
};
// RestAPIへリクエストを送信
$.ajax({
url:urlStr, // RestAPIのURL
type:'POST', // HTTPメソッド
headers: { // リクエストヘッダー
'X-Auth-API-Token' : token
},
contentType: 'application/json',
data:JSON.stringify(data),
dataType:'json', // 受信データタイプ
cache: false, // キャッシュを無効
timespan:1000 // タイムアウト時間(msec)
}).done(function(data){
if(data.values.length) {
createSuggestList(data.values, typeDep, ankenProduct);
}
}).fail(function(XMLHttpRequest, textStatus, errorThrown){
// 問題が発生した場合は警告ダイアログ表示
alert(errorThrown);
});
}
/**
* 担当者検索
* @param searchWord 検索ワード
* @param ankenProduct プロダクト番号
*/
function searchPerson(searchWord, ankenProduct) {
// 検索ワードが未入力の場合は実行しない
if(searchWord == null || searchWord == '') {
return;
}
// RestAPIのURLの構築
var urlStr = contextPath + restApiUrl;
// 送信データ
var data = {
searchCondition: {
targetObjectName: "employee",
items: [
{
columnCode: 502,
operator: "partly",
text: searchWord
}
]
},
columnCodes: [502, 602],
sortKeys: null,
fromIndex: 1
};
// RestAPIへリクエストを送信
$.ajax({
url:urlStr, // RestAPIのURL
type:'POST', // HTTPメソッド
headers: { // リクエストヘッダー
'X-Auth-API-Token' : token
},
contentType: 'application/json',
data:JSON.stringify(data),
dataType:'json', // 受信データタイプ
cache: false, // キャッシュを無効
timespan:1000 // タイムアウト時間(msec)
}).done(function(data){
if(data.values.length) {
createSuggestList(data.values, typePer, ankenProduct);
}
}).fail(function(XMLHttpRequest, textStatus, errorThrown){
// 問題が発生した場合は警告ダイアログ表示
alert(errorThrown);
});
}
作成が完了したらmanifest.jsonとともにzipファイルに圧縮し、eセールスマネージャーへアップロードを行います。
仕様書
今回のサンプルプログラムの仕様書を公開しています。
以下のリンクよりダウンロードしてください。
- プログラム仕様書_案件登録画面(案件商品に対して疑似的に担当社員・担当部署を紐づける)プラグイン (PDF 形式:1.0 MByte)
管理番号:1447 / 作成日時:
参考になりましたか?