0

I am trying to make an existing php web application CSP compliant by doing away with 'unsafe-inline' in the 'script-src' directive

The code currently ( working but only due to unsafe-inline ):

// Currently - button in a php form

 <button type="submit" class="btn-dark" name="button_clearUser" 
        onclick="return singleConfirm('Proceed ?')"  >Clear Penalty</button> 


// js function in an external javascript file

function singleConfirm( msg1 ) {  
  if (confirm(msg1)) {    
        return true;
   } else {
        return false;
   }
 }

To make the above fully CSP compliant, I attempted the following ...


// Amended - button in a php form - added class confirm

 <button type="submit" class="btn-dark confirm" name="button_clearUser" 
         >Clear Penalty</button> 

// Amended - added a eventListener in the external js file
// for class confirm 

document.addEventListener('DOMContentReady', function () {

  document.getElementsByClassName('confirm')
          .addEventListener('click', return singleConfirm(msg1));
});

The above amendments are not working. And I dont see any error in the browser console. I suspect it a JS issue.

Pls advise.

................................ Updates Below ..............................

Update 3 ( the only issue left is that even when i click cancel, the form still submits. With onclick method, the 'return' keyword is used. Not sure how to implement 'return' concept here ) :::

Fixed ReferenceError: msg1 is not defined

function singleConfirm(msg1) {  
  if (confirm(msg1)) {   
      return true;     
  } else {
      return false;  
  }  
}


document.addEventListener('DOMContentLoaded', function () {

    const elems = document.getElementsByClassName('confirm');
    Array.prototype.forEach.call(elems, (elem) => {
        elem.addEventListener('click', () => singleConfirm('Proceed ?'));
    });

});

Update 2 :::

Used array for getElementsByClassName. With the this update, I now have a modal window popping but only if i remove msg1 ( gives ReferenceError: msg1 is not defined )


document.addEventListener('DOMContentLoaded', function () {

    const elems = document.getElementsByClassName('confirm');
    Array.prototype.forEach.call(elems, (elem) => {
        elem.addEventListener('click', () => singleConfirm(msg1));
    });

});

Update 1 :::

Replaced DOMContentReady -> DOMContentLoaded

 document.addEventListener('DOMContentLoaded', function () {

 });

MarcoZen
  • 1,140
  • 14
  • 25
  • Does this answer your question? [Why does jQuery or a DOM method such as getElementById not find the element?](https://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element) – Taplar May 27 '20 at 23:12
  • 1
    `getElementsByClassName` returns an array like result, not a single result. So you have to loop over them to attach event listeners to each of them. – Taplar May 27 '20 at 23:13
  • `.addEventListener('click', return singleConfirm(msg1));` <= also this is not the correct way to attach an event listener. The second argument is expected to be a function declaration/reference, not an expression. If you need an example of how it would be done, just look at how you did the `DOMContentReady` event listener call – Taplar May 27 '20 at 23:13
  • Thank u @Taplar - Amended my code for getElementsByClassName. Also i just realised that there is no DOMContentReady , just DOMContentLoaded. Amended my code ... – MarcoZen May 28 '20 at 00:45
  • With the amandments made (updates 1-2) , I now have a modal window popping but only if i remove msg1 ( gives ReferenceError: msg1 is not defined ). However even if i click cancel ... the form is still submitted... plus i cant seem to pass msg1 to the function from the page. – MarcoZen May 28 '20 at 00:58
  • @Taplar - Update 3. the only issue left is that even when i click cancel, the form still submits. With onclick method, the 'return' keyword is used. Not sure how to implement 'return' concept here – MarcoZen May 28 '20 at 02:10
  • If you want to conditionally prevent the click event, you have to accept the event in on the event handler and `e.preventDefault()` it. – Taplar May 28 '20 at 13:57
  • @Taplar -> I have tried elem.addEventListener('click', (event) => { event.preventDefault(); singleConfirm('Proceed ?'); }); // this however stops both Cancel and OK – MarcoZen May 28 '20 at 15:13

1 Answers1

0

Finally got it to work as below...

function singleConfirm(msg1) {

  if (confirm(msg1)) { 
      return true;
  } else {    
      return false;    
  }

}

// Use class confirmProceed on the php/html form

document.addEventListener('DOMContentLoaded', function () { 

    const elems = document.getElementsByClassName('confirmProceed');

    Array.prototype.forEach.call(elems, (elem) => {    

        elem.addEventListener('click', (event) => {

           if ( !singleConfirm('Proceed with Action?') ){
                event.preventDefault();
           } 


        });

    });  


}); 



MarcoZen
  • 1,140
  • 14
  • 25