220 lines
6.1 KiB
HTML
220 lines
6.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>JSDoc: Source: FormDataDeep.mjs</title>
|
|
|
|
<script src="scripts/prettify/prettify.js"> </script>
|
|
<script src="scripts/prettify/lang-css.js"> </script>
|
|
<!--[if lt IE 9]>
|
|
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
<![endif]-->
|
|
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="main">
|
|
|
|
<h1 class="page-title">Source: FormDataDeep.mjs</h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section>
|
|
<article>
|
|
<pre class="prettyprint source linenums"><code>/** @module FormDataDeep */
|
|
|
|
/**
|
|
* Usage: `Array<HTMLElement>.filter(removeChildren)`
|
|
*
|
|
* Removes elements from the array which are children of other elements in the array.
|
|
*/
|
|
export function removeChildren(element,index,array){
|
|
for(const sibling of array){
|
|
if(!sibling.isSameNode(element) && sibling.contains(element)){
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
/**
|
|
* Appends a new value onto an existing key inside an object, or adds the key if it does not already exist.
|
|
* @param {Object} object
|
|
* @param {String} name
|
|
* @param {*} value
|
|
*/
|
|
export function append(object,name,value){
|
|
if(name in object){
|
|
if(object[name] instanceof Array){
|
|
object[name].push(value)
|
|
}else{
|
|
object[name]=[object[name],value]
|
|
}
|
|
}else{
|
|
object[name]=value
|
|
}
|
|
}
|
|
/**
|
|
* Get `form` data as an object, including nested forms.
|
|
* @param {HTMLFormElement} form
|
|
* @param {Boolean} primitives whether to convert string values to primitives. Defaults `false`.
|
|
*/
|
|
export function getFormDataDeep(form,primitives=false){
|
|
const formDataDeep={}
|
|
const formData=new FormData(form)
|
|
for(const name of formData.keys()){
|
|
const value=formData.getAll(name)
|
|
if(value.length==0){
|
|
continue
|
|
}
|
|
if(primitives){
|
|
for(let i=0;i<value.length;i++){
|
|
if(!isNaN(+value[i])){
|
|
value[i]=+value[i]
|
|
}
|
|
if(value[i]=='on'){
|
|
value[i]=true
|
|
}
|
|
}
|
|
}
|
|
if(value.length==1){
|
|
formDataDeep[name]=value[0]
|
|
}else{
|
|
formDataDeep[name]=value
|
|
}
|
|
}
|
|
for(const child of [...form.querySelectorAll('form')].filter(removeChildren)){
|
|
const value=getFormDataDeep(child,primitives)
|
|
if(Object.keys(value)==0){
|
|
continue
|
|
}
|
|
const name=child.name
|
|
append(formDataDeep,name,value)
|
|
}
|
|
return formDataDeep
|
|
}
|
|
/**
|
|
* Convenience class to have a similar interface to FormData
|
|
*/
|
|
export class FormDataDeep extends FormData {
|
|
/**
|
|
* Get `form` data as an object, including nested forms.
|
|
* @param {HTMLFormElement | Object} form the root form element, or a JSON Object containing form data.
|
|
* @param {Boolean} primitives whether to convert string values to primitives. Defaults `false`.
|
|
*/
|
|
constructor(form,primitives=false){
|
|
super()
|
|
if(form instanceof HTMLFormElement){
|
|
Object.assign(this,getFormDataDeep(form,primitives))
|
|
}else{
|
|
Object.assign(this,form)
|
|
}
|
|
}
|
|
append(name,value,filename=undefined){
|
|
if(filename!==undefined){
|
|
value=new File([value],filename)
|
|
}
|
|
append(this,name,value)
|
|
}
|
|
delete(name){
|
|
delete this[name]
|
|
}
|
|
entries(){
|
|
return Object.entries(this).filter((value)=>!value instanceof Function)
|
|
}
|
|
get(name){
|
|
if(this[name] instanceof Array){
|
|
return this[name].at(-1)
|
|
}else{
|
|
return this[name]
|
|
}
|
|
}
|
|
getAll(name){
|
|
if(this[name] instanceof Array){
|
|
return this[name]
|
|
}else{
|
|
return [this[name]]
|
|
}
|
|
}
|
|
has(name){
|
|
return name in this
|
|
}
|
|
keys(){
|
|
return this.entries().keys()
|
|
}
|
|
set(name,value,filename=undefined){
|
|
if(filename!==undefined){
|
|
value=new File([value],filename)
|
|
}
|
|
this[name]=value
|
|
}
|
|
values(){
|
|
return this.entries().values()
|
|
}
|
|
/**
|
|
* Applies the values in this object to the target form.
|
|
* @param {HTMLFormElement} form
|
|
*/
|
|
apply(form){
|
|
for(const element of form.elements){
|
|
const name=element.name
|
|
if(! name in this){
|
|
continue
|
|
}
|
|
let value
|
|
if(this[name] instanceof Array){
|
|
value=this[name].shift()
|
|
}else{
|
|
value=this[name]
|
|
delete this[name]
|
|
}
|
|
switch(element.type){
|
|
case 'radio':
|
|
case 'checkbox':{
|
|
element.checked=true
|
|
break
|
|
}
|
|
default:{
|
|
element.value=value
|
|
break
|
|
}
|
|
}
|
|
}
|
|
for(const child of [...form.querySelectorAll('form')].filter(removeChildren)){
|
|
const name=child.name
|
|
if(! name in this){
|
|
continue
|
|
}
|
|
new FormDataDeep(this[name]).apply(form)
|
|
}
|
|
}
|
|
}
|
|
|
|
export default FormDataDeep</code></pre>
|
|
</article>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<nav>
|
|
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-CSSRandom.html">CSSRandom</a></li><li><a href="module-FileReaderAsync.html">FileReaderAsync</a></li><li><a href="module-FormDataDeep.html">FormDataDeep</a></li><li><a href="module-fontScale.html">fontScale</a></li></ul><h3>Classes</h3><ul><li><a href="module-FileReaderAsync.FileReaderAsync.html">FileReaderAsync</a></li><li><a href="module-FormDataDeep.FormDataDeep.html">FormDataDeep</a></li></ul>
|
|
</nav>
|
|
|
|
<br class="clear">
|
|
|
|
<footer>
|
|
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.0</a> on Wed Dec 07 2022 13:47:25 GMT+0000 (Coordinated Universal Time)
|
|
</footer>
|
|
|
|
<script> prettyPrint(); </script>
|
|
<script src="scripts/linenumber.js"> </script>
|
|
</body>
|
|
</html>
|