VuetifyのバリデーションをJavaScriptで実行する

html

1
2
3
4
5
<v-form ref="form">
<v-text-field
:rules="[rules.required]"
></v-text-field>
</v-form>

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
// バリデーション
let form = ref(null)
const rules = ref({
required: value => !!value || '',
})

const submit = async () => {
const validResult = await form.value.validate()
if (!validResult.valid) {
return
}
//以下、submitの処理
}

【JavaScript】base64の画像をimgタグにセットする方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
async setImageToInput(base64Image, inputElement) {
// Base64形式の画像を<img>要素にセット
const img = document.createElement('img');
img.src = base64Image;

// 画像の読み込みを待つ
await new Promise((resolve) => img.onload = resolve);

// <img>要素の画像を<canvas>要素に描画
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);

// <canvas>要素の画像をBlobオブジェクトに変換
const blob = await new Promise((resolve) => canvas.toBlob(resolve));

// BlobオブジェクトをFileオブジェクトに変換
const file = new File([blob], 'image.jpg', {type: blob.type});

// FileオブジェクトをDataTransferオブジェクトに追加
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);

// DataTransferオブジェクトをinput要素のfilesプロパティにセット
inputElement.files = dataTransfer.files;

// changeイベントを明示的にトリガーする
inputElement.dispatchEvent(new Event('change'));
},

// input
const base64Image = document.getElementById(imgId).src;
const inputElement = document.getElementById('item_image');
this.setImageToInput(base64Image, inputElement).then(r =>
// セットした後の処理
);

Vue3でユニットテストツールのJestを入れたけど諦めた

ライブラリをインストール

1
2
3
4
5
6
7
8
9
# testライブラリ
npm install --save-dev jest
# for vue
npm install --save-dev babel-jest
npm install --save-dev babel-preset-env
npm install --save-dev babel-core@bridge
# for vue3
npm install --save-dev @vue/test-utils@next
npm install --save-dev vue-jest@next

test準備

プロジェクトルートディレクトリにjest.config.jsを作成する

※作成しない場合、以下のエラーになった。
Consider using the "jsdom" test environment.

1
2
3
module.exports = {
testEnvironment: "jsdom"
};

package.jsonに以下を追加する
npm testでテスト実行できるようにするため

1
2
3
"scripts": {
"test": "jest",
},

testコード作成

プロジェクトルートディレクトリに__tests__/unit/index.jsを作成する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { mount } from "@vue/test-utils";

// The component to test
const MessageComponent = {
template: "<p>{{ msg }}</p>",
props: ["msg"]
};

test("displays message", () => {
const wrapper = mount(MessageComponent, {
props: {
msg: "Hello world"
}
});

// Assert the rendered text of the component
expect(wrapper.text()).toContain("Hello world");
});

ここまで完了すれば、npm testでテスト実行できる。

と、ここまでは良いのだが、Vue.jsのコードに接続するコードを書くと以下のエラーになった
解決できず、諦めた。。

({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<template>

【OAuth2】クライアントアプリのサンプルコード【NodeJS】

はじめに

OAuth2のクライアントアプリを作成したので、手順をメモしておきます。

環境

フロント
 Vue.js:3.0.0
バックエンド
 Express:4.17.1

【JS】json内のデータの位置を並び替える方法

JavaScriptでjson内のデータの位置を並び替える方法です。

例えば

1
2
3
4
5
{
"1":"test1",
"2":"test2",
"3":"test3",
}

これを

1
2
3
4
5
{
"3":"test3",
"1":"test1",
"2":"test2",
}

にしたい時に使う方法です。

以下は”hoge”データを3番目に入れる例です。

1
2
3
let pairs = Object.entries(beforeJson);
pairs.splice(3, 0, ["hoge", beforeJson["hoge"]]);
afterJson = Object.fromEntries(pairs);

上にある通り、一度配列にしてから順番を入れ替え、その後にjsonに戻せばOKです。

以上です。

フォームボタンを連打したら多重送信されてしまうバグを防ぐ方法

フォームボタンを連打したら多重送信されてしまうバグを防ぐ方法です。

1
2
3
$('form').submit(function() {
$('input[name="submit"]').prop('disabled', true);
})

JavaScriptでバーコードを読み取る方法

利用ライブラリ

利用ライブラリ
https://github.com/ericblade/quagga2

※元々はhttps://github.com/serratus/quaggaJS の方ですが保守されていないのでフォークされた上の方が良いです

コード

html

1
2
3
4
5
<button type="button" class="btn btn-fab btn-round btn-info btc_scan" name="btc_scan"></button>
<!-- スキャンエリア -->
<div class="scan_area" style="height: 100vh; display:none">
<div id="photo-area" class="viewport"></div>
</div>

js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// スキャン
function register_btc_scan() {
$('.btc_scan').on('click', (event) => {
$('.scan_area').show()
startScanner()
scrollTo(0, 0)
})
const startScanner = () => {
Quagga.init(
{
inputStream: {
numOfWorkers: 0,
frequency: 1,
name: 'Live',
type: 'LiveStream',
target: document.querySelector('#photo-area'),
constraints: {
decodeBarCodeRate: 3,
successTimeout: 500,
codeRepetition: false,
tryVertical: true,
frameRate: 15,
facingMode: 'environment',
},
},
decoder: {
readers: ['ean_reader'],
},
},
function (err) {
if (err) {
console.log(err)
return
}
console.log('Initialization finished. Ready to start')
Quagga.start()
_scannerIsRunning = true
}
)
Quagga.onProcessed(_onProcessed)
Quagga.onDetected(_onDetected)
}
}
// スキャン中
function _onProcessed(result) {
var drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute('width')), parseInt(drawingCanvas.getAttribute('height')))
result.boxes
.filter(function (box) {
return box !== result.box
})
.forEach(function (box) {
Quagga.ImageDebug.drawPath(
box,
{
x: 0,
y: 1,
},
drawingCtx,
{
color: 'green',
lineWidth: 2,
}
)
})
}
if (result.box) {
Quagga.ImageDebug.drawPath(
result.box,
{
x: 0,
y: 1,
},
drawingCtx,
{
color: '#00F',
lineWidth: 2,
}
)
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(
result.line,
{
x: 'x',
y: 'y',
},
drawingCtx,
{
color: 'red',
lineWidth: 3,
}
)
}
}
}

function _getMedian(arr) {
arr.sort((a, b) => a - b)
const half = Math.floor(arr.length / 2)
if (arr.length % 2 === 1)
// Odd length
return arr[half]
return (arr[half - 1] + arr[half]) / 2.0
}

let codes = []

// 検知した
function _onDetected(result) {
// 1つでもエラー率0.16以上があれば除外
let is_err = false
$.each(result.codeResult.decodedCodes, function (id, error) {
if (error.error != undefined) {
if (parseFloat(error.error) > 0.16) {
is_err = true
}
}
})
if (is_err) return

// エラー率のmedianが0.05以上なら除外
const errors = result.codeResult.decodedCodes.filter((_) => _.error !== undefined).map((_) => _.error)
const median = _getMedian(errors)
if (median > 0.05) {
return
}

// 3連続同じ数値だった場合のみ採用する
codes.push(result.codeResult.code)
if (codes.length < 3) return
let is_same_all = false
if (codes.every((v) => v === codes[0])) {
is_same_all = true
}
if (!is_same_all) {
codes.shift()
return
}

alert(result.codeResult.code)
$('.scan_area').hide()
Quagga.stop()
Quagga.offProcessed(_onProcessed)
Quagga.offDetected(_onDetected)
}

そのままだと画面いっぱいのサイズにならないので以下を追加して画面いっぱいのサイズになるようにしました
無理やり感ありますが、、

1
2
3
4
5
6
7
8
#photo-area.viewport video {
transform: translateX(-20vw) translateY(-30vw);
width: 120vw;
}

#photo-area.viewport canvas {
transform: translateX(-20vw) translateY(-200vw);
}

JavaScriptでクリップボードにコピーする

html 部分

1
2
<input id="user_id" type="text" style="display: none" value="コピー対象の文言" />
<button class="btn btn-secondary" onclick="copyToClipboard('user_id')">クリップボードにコピー</button>

JavaScript 部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script type="text/javascript">
function copyToClipboard(id) {
var copyTarget = document.getElementById(id)

var textarea = document.createElement('textarea')
textarea.textContent = copyTarget.value
document.body.appendChild(textarea)

var selection = document.getSelection()
var range = document.createRange()
range.selectNode(textarea)
selection.removeAllRanges()
selection.addRange(range)

console.log('copy success', document.execCommand('copy'))
selection.removeAllRanges()

document.body.removeChild(textarea)

alert('コピー完了 : ' + copyTarget.value)
}
</script>

ググると以下のやり方が出てきましたが、これだと Chrome でコピーできないので上のやり方にしました
https://www.w3schools.com/howto/howto_js_copy_clipboard.asp

参考
https://stackoverflow.com/questions/47879184/document-execcommandcopy-not-working-on-chrome?rq=1

【随時更新】個人的にJavaScriptでよく使う記法まとめ

個人的にJavaScriptでよく使う記法をまとめました

JavaScript でクラスを追加・削除する方法

JavaScript でクラスを追加・削除する方法です

1
2
3
const item = document.querySelector('.hoge')
item.classList.remove('hoge')
item.classList.add('fuga')

以上です

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×