Skip to content

Commit

Permalink
fix #77
Browse files Browse the repository at this point in the history
  • Loading branch information
inc2734 committed Aug 11, 2020
1 parent 42c709f commit 00af62f
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 74 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ module.exports = {
...defaultConfig.globals,
snowmonkeyforms: true,
FormData: true,
XMLHttpRequest: true,
},
};
121 changes: 89 additions & 32 deletions src/js/app.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,100 @@
import $ from 'jquery';
// import $ from 'jquery';
import submit from './module/submit';

$( document ).on( 'change', '.smf-file-control__control', ( event ) => {
const control = $( event.currentTarget );
const filename = control.parent().find( '.smf-file-control__filename' );
const files = control.prop( 'files' );
if ( 0 < files.length && 0 < filename.length ) {
const file = files[ 0 ];
if ( 'undefined' !== typeof file.name ) {
filename.text( file.name );
document.addEventListener(
'change',
( event ) => {
const control = event.target;
if ( control.classList.contains( 'smf-file-control__control' ) ) {
const filename = control.parentNode.querySelector(
'.smf-file-control__filename'
);
const files = control.files;
if ( 0 < files.length && !! filename ) {
const file = files[ 0 ];
if ( 'undefined' !== typeof file.name ) {
filename.textContent = file.name;
}
}
}
},
false
);

const closest = ( el, targetClass ) => {
for ( let item = el; item; item = item.parentElement ) {
if ( item.classList.contains( targetClass ) ) {
return item;
}
}
} );
};

document.addEventListener(
'click',
( event ) => {
const control = event.target;
if ( 'back' === control.getAttribute( 'data-action' ) ) {
const action = closest( control, 'smf-action' );
if ( !! action ) {
const method = action.querySelector(
'[type="hidden"][name="snow-monkey-forms-meta[method]"]'
);
if ( !! method ) {
method.setAttribute( 'value', 'back' );
}
}
}
},
false
);

$( document ).on( 'click', '[data-action="back"]', ( event ) =>
$( event.currentTarget )
.closest( '.smf-action' )
.find( '[type="hidden"][name="snow-monkey-forms-meta[method]"]' )
.attr( 'value', 'back' )
document.addEventListener(
'click',
( event ) => {
const control = event.target;
const submites = [].slice.call(
document.querySelectorAll( '.smf-action [type="submit"]' )
);
if ( -1 !== submites.indexOf( control ) ) {
const sendingMark = control.querySelector( '.smf-sending' );
if ( !! sendingMark ) {
sendingMark.setAttribute( 'aria-hidden', 'false' );
}
}
},
false
);

$( document ).on( 'click', '.smf-action [type="submit"]', ( event ) => {
$( event.currentTarget )
.find( '.smf-sending' )
.attr( 'aria-hidden', 'false' );
const forms = [].slice.call( document.querySelectorAll( '.snow-monkey-form' ) );
forms.forEach( ( form ) => {
form.addEventListener( 'submit', submit, false );
} );

$( '.snow-monkey-form' ).each( ( i, e ) => {
const form = $( e );
form.on( 'submit', submit );
} );
[ 'change', 'keyup' ].forEach( ( eventName ) => {
document.addEventListener(
eventName,
( event ) => {
const control = event.target;
if ( '1' === control.getAttribute( 'data-invalid' ) ) {
control.removeAttribute( 'data-invalid' );

[].slice
.call( control.querySelectorAll( '[data-invalid="1"]' ) )
.forEach( ( element ) =>
element.removeAttribute( 'data-invalid' )
);

$( document ).on( 'change keyup', '[data-invalid="1"]', ( event ) => {
$( event.currentTarget ).removeAttr( 'data-invalid' );
$( event.currentTarget )
.find( '[data-invalid="1"]' )
.removeAttr( 'data-invalid' );
$( event.currentTarget )
.closest( '.smf-placeholder' )
.find( '.smf-error-messages' )
.remove();
const placeholder = closest( control, 'smf-placeholder' );
if ( !! placeholder ) {
const errorMessage = placeholder.querySelector(
'.smf-error-messages'
);
if ( !! errorMessage ) {
errorMessage.parentNode.removeChild( errorMessage );
}
}
}
},
false
);
} );
131 changes: 89 additions & 42 deletions src/js/module/submit.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import $ from 'jquery';
import addCustomEvent from '@inc2734/add-custom-event';

const closest = ( el, targetClass ) => {
for ( let item = el; item; item = item.parentElement ) {
if ( item.classList.contains( targetClass ) ) {
return item;
}
}
};

const maybeHasControls = ( method ) => {
return (
'' === method ||
Expand All @@ -17,66 +24,95 @@ const maybeComplete = ( method ) => {
export default function submit( event ) {
event.preventDefault();

const form = $( event.target );
const contents = form.find( '.smf-form' );
const actionArea = form.find( '.smf-action' );
const formData = new FormData( form.get( 0 ) );
const form = event.target;
const contents = form.querySelector( '.smf-form' );
const actionArea = form.querySelector( '.smf-action' );
const formData = new FormData( form );

const inputs = [].slice
.call(
form.querySelectorAll(
'input[name]:not([disabled]), textarea[name]:not([disabled]), select[name]:not([disabled])'
)
)
.map( ( element ) => {
let value;
if ( 'checkbox' === element.type || 'radio' === element.type ) {
if ( element.checked ) {
value = element.value;
}
} else {
value = element.value;
}

if ( 'undefined' === typeof value ) {
return false;
}

return {
name: element.getAttribute( 'name' ),
value,
};
} )
.filter( ( element ) => element );

const detail = {
status: 'init',
inputs: form.serializeArray(),
inputs,
formData,
};

const replaceContent = ( content ) => {
contents.html( content );
contents.innerHTML = content;
};

const replaceControls = ( controls ) => {
$.each( controls, ( key, control ) => {
const placeholder = form.find(
for ( const key in controls ) {
const control = controls[ key ];
const placeholder = form.querySelector(
`.smf-placeholder[data-name="${ key }"]`
);
placeholder.html( control );
} );
placeholder.innerHTML = control;
}
};

const replaceAction = ( contentType ) => {
actionArea.html( contentType );
actionArea.innerHTML = contentType;
};

const focusToFirstItem = () => {
const firstItem = form.find( '.smf-item' ).eq( 0 );
if ( 0 < firstItem.length ) {
const firstItem = form.querySelector( '.smf-item' );
if ( !! firstItem ) {
firstItem.focus();
}
};

const forcusToFirstErrorControl = ( errorMessages ) => {
if ( 0 < errorMessages.length ) {
const firstErrorMessage = errorMessages.eq( 0 );
const firstErrorControl = firstErrorMessage
.closest( '.smf-placeholder' )
.find( 'input, select, textarea, button' );
if ( 0 < firstErrorControl.length ) {
const firstErrorMessage = errorMessages[ 0 ];
const placeholder = closest( firstErrorMessage, 'smf-placeholder' );
const firstErrorControl =
!! placeholder &&
placeholder.querySelector( 'input, select, textarea, button' );
if ( !! firstErrorControl ) {
firstErrorControl.focus();
}
}
};

const focusToContent = () => {
const content = form.find(
const content = form.querySelector(
'.smf-complete-content, .smf-system-error-content'
);
if ( 0 < content.length ) {
content.eq( 0 ).focus();
if ( !! content ) {
content.focus();
}
};

const icon = form.find( '.smf-sending' );
const icon = form.querySelector( '.smf-sending' );

const doneCallback = ( response ) => {
icon.attr( 'aria-hidden', 'true' );
icon.setAttribute( 'aria-hidden', 'true' );

response = JSON.parse( response );
if ( 'undefined' === typeof response.method ) {
Expand All @@ -86,15 +122,21 @@ export default function submit( event ) {

const method = response.method;

form.attr( 'data-screen', method );
form.setAttribute( 'data-screen', method );

replaceAction( response.action );
form.find( '.smf-placeholder' ).html( '' );
[].slice
.call( form.querySelectorAll( '.smf-placeholder' ) )
.forEach( ( element ) => {
element.innerHTML = '';
} );

if ( maybeHasControls( method ) ) {
replaceControls( response.controls );

const errorMessages = form.find( '.smf-error-messages' );
const errorMessages = [].slice.call(
form.querySelectorAll( '.smf-error-messages' )
);
if ( 0 < errorMessages.length ) {
forcusToFirstErrorControl( errorMessages );
} else {
Expand Down Expand Up @@ -132,15 +174,17 @@ export default function submit( event ) {
};

const failCallback = () => {
form.attr( 'data-screen', 'systemerror' );
form.setAttribute( 'data-screen', 'systemerror' );

const errorMessage = $(
'<div class="smf-system-error-content" tabindex="-1" />'
);
const errorMessageReady = form.find(
const errorMessage = document.createElement( 'div' );
errorMessage.classList.add( 'smf-system-error-content' );
errorMessage.setAttribute( 'tabindex', '-1' );

const errorMessageReady = form.querySelector(
'.smf-system-error-content-ready'
);
errorMessage.text( errorMessageReady.text() );
errorMessage.textContent = errorMessageReady.textContent;

replaceContent( errorMessage );
replaceAction( '' );
focusToContent();
Expand All @@ -151,13 +195,16 @@ export default function submit( event ) {

addCustomEvent( event.target, 'smf.beforesubmit', detail );

$.ajax( {
type: 'POST',
url: snowmonkeyforms.view_json_url,
data: formData,
processData: false,
contentType: false,
} )
.done( doneCallback )
.fail( failCallback );
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if ( 4 === xhr.readyState ) {
if ( 200 === xhr.status ) {
doneCallback( JSON.parse( xhr.response ) );
} else {
failCallback();
}
}
};
xhr.open( 'POST', snowmonkeyforms.view_json_url, true );
xhr.send( formData );
}

0 comments on commit 00af62f

Please sign in to comment.