2018 年販 PyCharm では、コード補完キー操作で、
Pythonスクリプト先頭行に書く、
# -*- coding: utf-8 -*-
がすぐに出てくるのだが、最近のPyCharm はコード補完キー操作では出てこない。
ちゃんとコードテンプレート設定するのが良いようです。
input タグの placeholder の文字色が濃く、うすい色にするのは、
CSS でどのように指定するんだっけ?とよく忘れてしまうので、
書き留めておきます。
placeholder 疑似クラスを使うのです。
input::-webkit-input-placeholder{ color: #cccccc; } input:-ms-input-placeholder{ color: #cccccc; } input::placeholder{ color: #cccccc; }
でも、BootStrap を使うとこれでは効きません!
解決策は、以下のように placeholder 疑似クラスを指定します。
.form-control::placeholder{ color: #cccccc; }
特定の列全てを readOnly にする場合は、columns 定義で、readOnly = true を指定、
動的に任意のセルに対して readOnly = true を指定したければ、
先日のように、セルのメタ情報のreadOnly を true にして、render() 実行すれば良いが、
Handsontable readOnly セルの設定とコンテキストメニュー - Oboe吹きプログラマの黙示録
Renderer で、データの値によって readOnly を指定する場合は、以下のようにする。
var hot = new Handsontable(document.getElementById("table"), { data: Handsontable.helper.createSpreadsheetData(10, 3), rowHeaders: true, colHeaders: true, maxCols: 3, columns: [ { type:'text' }, { type:'text' }, { type:'text', renderer: function(hotInstance, td, row, column, prop, value, cellProperties) { var v = hotInstance.getDataAtCell(row, 0); // 1列目の値が、"A2" or "A4" ならば、readOnly if (v=='A2' || v=='A4'){ cellProperties.readOnly = true; } Handsontable.renderers.TextRenderer.apply(this, arguments); }, }, ], licenseKey: 'non-commercial-and-evaluation' });
上記の指定で興味深いのは、、
readOnly = true にする条件にあてはまらない行の1列目を、
条件に一致するように編集して変更した時、(6行目、1列目 'A6' → 'A2' に変更)
即座に上記 renderer が動いて readOnly になることである。
なお、renderer は、以下の表のとおり、type と renderer が対応していることに留意したい。
type | renderer |
autocomplete | Handsontable.renderers.AutocompleteRenderer |
base | Handsontable.renderers.BaseRenderer |
checkbox | Handsontable.renderers.CheckboxRenderer |
date | Handsontable.renderers.DateRenderer |
dropdown | Handsontable.renderers.DropdownRenderer |
html | Handsontable.renderers.HtmlRenderer |
numeric | Handsontable.renderers.NumericRenderer |
password | Handsontable.renderers.PasswordRenderer |
text | Handsontable.renderers.TextRenderer |
time | Handsontable.renderers.TimeRenderer |
column 定義で、readOnly 属性を true にすれば、読込専用になるのだが、
動的に設定する方法で、コンテキストメニューに、make_read_only が用意されている。
Context menu - Guide - Handsontable Documentation
解除する時は、
このコンテキストメニュー表示を日本語にするだけなら、
セルのメタ情報、readOnly の真偽値をチェックするだけで良いのだが、、
var hot = new Handsontable(document.getElementById("table"), { data: Handsontable.helper.createSpreadsheetData(5, 5), rowHeaders: true, colHeaders: true, maxCols: 5, contextMenu: { items:{ "make_read_only": { name: function(){ var range = this.getSelectedRange(); var flg = false; for(var row=range[0].from.row;row <= range[0].to.row;row++){ for(var col=range[0].from.col;col <= range[0].to.col;col++){ flg = flg | hot.getCellMeta(row, col).readOnly; } } return flg ? '読込専用解除' : '読込専用にする'; }, }, }, }, licenseKey: 'non-commercial-and-evaluation' });
読込専用、解除の設定と同時に何らかの処理を差し込みたい場合、
callback を記述するしかない。
callback で実行する setCellMeta() も注意が必要で、
機械的に getCellMeta() で取得するセルのメタ情報、
readOnly の真偽値の逆を実行するだけでは
選択エリアの readOnly 状態が混ざっている場合が、
単純に反転するだけである。
従って以下のようにする。
var readonlyFlg = false; var hot = new Handsontable(document.getElementById("table"), { data: Handsontable.helper.createSpreadsheetData(5, 5), rowHeaders: true, colHeaders: true, maxCols: 5, contextMenu: { items:{ "make_read_only": { name: function(){ var range = this.getSelectedRange(); for(var row=range[0].from.row;row <= range[0].to.row;row++){ for(var col=range[0].from.col;col <= range[0].to.col;col++){ readonlyFlg = readonlyFlg | hot.getCellMeta(row, col).readOnly; } } return readonlyFlg ? '読込専用解除' : '読込専用にする'; }, callback: function(key, selection, clickEvent){ for(var row=selection[0].start.row; row <= selection[0].end.row; row++){ for(var col=selection[0].start.col; col <= selection[0].end.col; col++){ hot.setCellMeta(row, col, 'readOnly', !readonlyFlg); // TODO readonlyFlg による他の処理を行う } } readonlyFlg = !readonlyFlg; hot.render(); } }, }, }, licenseKey: 'non-commercial-and-evaluation' });
読込専用にした範囲を含んで、混ざっている範囲を選択した時、コンテキストメニューは、、
Handsontable の右クリックコンテキストメニューの callback は、選択領域をメソッドの
引数で認識できますが、
disabled - メニュー表示するが非活性にするなら true
この時、メソッド引数で選択領域を知ることができません。
代用になりますが、最後に選択した領域の取得、
インスタンスメソッドの getSelectedRangeLast() から、
行番号、列番号が取得できます。
偶数行だけ実行可能なコンテキストメニューの例
contextMenu: { items: { "run" : { name : '実行', disabled: function(){ return !(hot.getSelectedRangeLast().from.row % 2); }, callback: function(key, selection, clickEvent){ // TODO }, }, } },
show 実行の引数、JSON で渡す。
例)
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> : 省略
$('#exampleModal').modal('show', { 'dvalue': 'i001' });
shown.bs.modal イベントを捕捉して受け取る。
イベントの relatedTarget が受け取るJSONルートである。
$('#exampleModal').on('shown.bs.modal', function(ev){ var dvalue = ev.relatedTarget.dvalue; });
bootstrap モーダル表示を中央にする時は、、modal-dialog-centered
Handsontable インスタンスの getDataAtRow( row ) は、表示しているグリッドデータの表示範囲しか取得しない。
つまり、4列存在するデータでも、maxCols : 3 と定義していれば、
表示している3列までしか getDataAtRow はデータ取得をしない。
グリッド表示させないデータを持ち何らかの操作で使用したい場合にどうするか?
var data = [ { A:'A1', B:'B1', C:'C1', D:'D1' }, { A:'A2', B:'B2', C:'C2', D:'D2' }, { A:'A3', B:'B3', C:'C3', D:'D3' }, ];
このJSONを3列まで表示して、4列目のキー'D' をコンテキストメニューで選択した時に
使用する場合、、特別なコーディングではないが、以下になる。
var hot = new Handsontable(document.getElementById("table"), { data: data, rowHeaders: true, colHeaders: true, maxCols: 3, columns: [ { data:'A', type:'text', }, { data:'B', type:'text', }, { data:'C', type:'text', }, ], contextMenu: { items:{ "goPage": { name: 'ページ遷移', callback: function(key, selection, clickEvent){ // 非表示データ key='D' の値を使用 var value = data[selection[0].start.row]['D']; location.href = './etcPage?param1='+value; }, }, }, }, licenseKey: 'non-commercial-and-evaluation' });