kViewerの新バージョンにて特定の文字列に色を付けて画面表示したい

Javascript初心者ながら、ときどき必要に迫られて、自分で作成している者です。
kViewerのバージョンアップ前より、「特定文字列に色を付ける」ためのjavascriptを
使っておりました。先日のkViewerの大幅なバージョンアップ後に、それが動作しなくなったので、
作り直しに着手しておりますが、上手くいかず、四苦八苦しております。

以下は、前バージョンで動作していたJavascriptです。

var allTags = document.getElementsByTagName(‘*’);
for(var i = 0; i <allTags.length; i ++){
if(allTags [i] .className == “kv-index-td kv-index-td-1234567”){
allTags [i] .innerHTML = allTags [i] .innerHTML.replace(/●/g、‘<font color =“red”>●</ font>’);
}
}

今回、新バージョンkViewer向けに修正してみたJavascriptです。(未だ動作せず)

var allTags = document.getElementsByTagName(‘*’);
for (var i =0;i<allTags.length;i++){
if(allTags[i].className==“kv-text-element”){
allTags[i].innerHTML=allTags[i].innerHTML.replace(/●/g,‘<font color=“red”>●</font>’);
}
console.log(allTags);
}

console.logは、デバッグのために入れています。

Google Chromeのツールでconsoleを確認すると、HTMLCollectionとして大量のタグが出力
されていますので、試しに(‘*’)の部分を(‘div’)に代えてみましたが、改善は
しません。おそらく問題は、DIVタグにて「class=“kv-text-element”」が複数出現するような
構造に変更されているためかな、と想像しています。前のバージョンでは、
「class=“kv-index-td kv-index-td-1234567”」という形で、対象を一意に
できたから意図通り動作した(のかもしれません)。

いろいろググッてみると、「HTML内の特定の文字列をreplaceする」ようなサンプルプログラムでは、
「getElementsByTagName」ではなくて、「getElementById」を使う例がいくつか出ていました。
IDがあるなら一意に定まると思いますが、新kViewerの場合、IDは使われていないので、
そのままでは使えません。新kViewerでは、(おそらく)IDの代わりに「data-v-*****」という形式の
(たぶん)DATA属性が使われていますので、これを使えたらなと思いましたが、
これを「getElementById」で利用するやり方が判らず、挫折しています。

どなたか、打開策をご教示いただけるとたいへんありがたいです。
よろしくお願いいたします。

Tessai さん

getElementsByTagName(‘*’) は、かなり効率が悪い方法です。

querySelectorAllを使って、要素を絞り込みましょう。

現在の kViewer の構造がわかりませんので、いろいろ試してみてください。

 

例 DOM構造が分かりませんので、適当です。

var allTags = document.querySelectorAll(‘div[data-v-*****]’);

rex200様のアドバイスに従い、「querySelectorAll」を使っていろいろ試したところ、
一意でinnerHTMLを取得できることができました。どうもありがとうございます。

「querySelectorAll(‘div’)と」で調べたところ、NodeListが6つヒットしましたが、
そのうちの「div.ui.fluid.container」のinnerHTMLにだけ、kViewerで表示するHTMLの
中身(HTMLタグに括られたデータ群のテキスト)が含まれていることが判ったので、
以下のように絞ってみました。


var allTags = document.querySelectorAll(‘div.ui.fluid.container’);
var allTags2 = allTags.innerHTML;
console.log(allTags);
console.log(allTags2);

ただ、ここまた止まってしまいました。
Google Chromeでみた場合、「console.log(allTags)」だと前述の通り「NodeList(1)」と
表示されますが、「console.log(allTags2)」には「undefined」と表示されてしまいます。
div.ui.fluid.container内のinnerHTMLを取り出すには、どうすればよろしいでしょうか。

querySelectorAll は、対象要素を配列で返しますので、配列の添え字が必要です。

querySelector は、対象要素の先頭のみを返します。

用途によって、使い分けてください。

 

Tessaiさん

 

https://viewer.kintoneapp.com/help/customize

にあるように、JavaScriptで任意の要素を取得するAPIが複数用意されています。

要素を取得するなら getElementsByTagName などを使うよりそちらの方がよいでしょう。

 

またスタイルを変更したいだけであれば、任意のフィールドの style, labelStyle, contentStyle などを直接変更すると良いかと思います。

一覧表示であれば、state.view.mainContent.layout , 詳細表示であれば、state.view.detailView.elements にフィールド一覧がありますので、そちらから任意のフィールドの style, labelStyle, contentStyle などを変更すると良いかと思います。

 

以上、参考になりますでしょうか?

落合さん

なるほど、kViewerも各種イベントがサポートされているんですね。

 

Tessaiさん

落合さんのおっしゃるように kViewerの流儀に従って、対応されると今後の仕様変更の影響を受けずに済むと思います。

 

 

rex0220様、落合様、ありがとうございます。
落合様のご紹介いただいたページは、一応見ていたのですが、どうにも意味が判らなくて、
スキップしておりました。イベントという概念自体がよく判っていないのだと思います。
クリックするとか、そういう何か「発生すること」ぐらいの認識です。それが、「kvの指定の
プロパティに定義される」というのは、つまり代入されるということ?? ぐらいの理解度です。
また、state.view.mainContent.layoutというものが、どこにあってどう参照し、
どう引き出すかが、教えていただいにも関わらず、まったく判っていません。
いろいろご教示いただいているのに、私の基礎知識が足りなくて、たいへん申し訳ないです。
ご回答の意味が理解するために、もう少し勉強したいと思います。

横から質問、失礼致します。

私も同様の個所で引っ掛かっているのですが、一覧表示画面にて

特定の項目の値が0かそうでないかで、文字色を変えようとしています。

処理後のstateをconsole.logで確認した所、下図のように値は入っている様なのでが

表示色が変わりません。

指定方法が間違っているのではと思うのですが、正しい方法をご教示頂けませんでしょうか。

よろしくお願い致します。


// ビューのDOMを作成する前処理
kv.events.records.fetched = [function (state) {
   var lm_len = state.records.length;

   for (var i = 0 ; i < lm_len ; i++) {
      state.view.mainContent.layout[7].contentStyle[i] = new Object();
      if((state.records[i][‘項目名’].value) == 0 ){
           state.view.mainContent.layout[7].contentStyle[i].color = ‘#ff0000’;
      }else{
           state.view.mainContent.layout[7].contentStyle[i].color = ‘#000000’;
      };
   };
   console.log(state);
   return state;
}];


Toda様

お世話になっています。

cstapの友利と申します。

特定の項目が0の時に、その特定の項目を含む行(横一列)の色を変えるという認識であっていますでしょうか?

その場合、次のJavaScriptを読み込むことで可能です。

(function() {

"use strict";

kv.events.records.mounted.push(function (state) {
color(state);
return state;
})

kv.events.view.index.mounted.push(function (state) {
if (state.records.length === 0) return;
color(state);
return state;
})

const color = (state) => {
for (const v of state.records) {
if (v['項目名'].value != 0) continue;
kv.index.getRecordElement(v.$id.value).style.color = 'rgba(255, 0, 0)'
}
}

})();

 

cstap 友利様

ご回答、ありがとうございます。

弊社環境に頂いたサンプルをそのまま適用ではうまく表示がかわらず、


if (state.records.length === 0) return;

の前にconsole.log(state)で確認すると行数5と表示されているのに、

console.log(state.records.length)で確認すると0と出力され、

以下処理が通らない?


と言うあたりから引っ掛かっております。

当方初心者のため、頂いたサンプルを元に勉強してみたいと思います。

取り急ぎ、お礼まで。

Toda様

もし Cannot read property ‘value’ of undefined のようなエラーが出ている場合でしたら、

'項目名’の部分が正しく設定されていない可能性があります。

console.log(state.view.detailView.elements)

で出力される配列の任意の要素の’code’の値を使用してください。

 

申し訳ないのですが、直接上のこととは関係ないのですが、

先ほどのコードにバグが合りましたので修正したものを書いておきます。

(function() {

"use strict";

kv.events.records.mounted.push(function (state) {
color(state);
return state;
})

kv.events.view.index.mounted.push(function (state) {
if (state.records.length === 0) return;
color(state);
return state;
})

const color = (state) => {
for (const v of state.records) {
if (v['項目名'].value == 0) {
kv.index.getRecordElement(v.$id.value).style.color = 'rgba(255, 0, 0)'
} else {
kv.index.getRecordElement(v.$id.value).style.color = ''
}
}
}
})();

cstap 友利様

調査個所のご指摘まで、ありがとうございます。

ご指摘頂き、項目値の取得の個所を調べていた所、文字コードがSJISとなっており

漢字項目名がうまく読めておりませんでした。

文字コードをUTF-8にすることで正しく文字色を替える事が出来ました。

 

単純なミスで、申し訳ありませんでした。

今後とも、よろしくお願い致します。

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。