简体   繁体   中英

Dynamically changing input type date to email from JavaScript is not working in Safari

I am trying to change input type date to email and email to date when user click the button.

Below is my HTML code.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Date Polyfill</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="email-to-date">
        <label>Email to Date:</label>
        <input type="email" name="emailDate" id="emailDate">
        <button id="btn-submit">Click me</button>
    </div>
    
    <script src="script.js"></script>
    <script src="node_modules/date-input-polyfill/date-input-polyfill.dist.js"></script>
</body>
</html> 

Javascript code

document.querySelector("#btn-submit").addEventListener("click", function () {
    var elem_type = document.querySelector("#emailDate").type;
    var email_elem = document.querySelector("#emailDate");
    
    if(elem_type == 'email')
    { 
       email_elem.type = 'date';
    }
    else { 
      email_elem.type = 'email';
    }
});

It is perfectly working in chrome but when i try this in Safari, when ever user clicks the button email field changed to date and vice versa but even though it is email field it shows date picker while clicking input text box.

It is not completely changed to email field.

For supporting date field in safari, I used date-input-polyfill package.

Kindly help me to resolve this.

I think for this to work properly in all browsers, you may have to remove the DOM element and then add a new one with the desired input type.

document.getElementById( "emailDate" ).remove();

and then create a new element and add it to the original parent. Hence, your changed function may look something like this. (It is a little verbose, but I retained it like that so that the logic comes out clearly.)

document.querySelector("#btn-submit").addEventListener("click", function () {
    var email_elem = document.querySelector("#emailDate");
    var elem_type = email_elem.type;
    
    /* Remove the current node, so that we create space for the new one. */
    email_elem.remove();
    
    /* Create the new input DOM node. */
    let newInput = document.createElement( "input" );
    
    /* Create attribute nodes for "id", "name" and "type" (and whatever else you need). We already know the
     * values for "id" and "name"; so we can set them here itself. Only for "type" we need an if..else. */
    let idAttr = document.createAttribute( "id" );
    idAttr.value = "emailDate";
    let nameAttr = document.createAttribute( "name" );
    nameAttr.value = "emailDate";
    let typeAttr = document.createAttribute( "type" );
    
    if( elem_type == 'email' )
    { 
       /* Add date type */
       typeAttr.value = "date";
    }
    else { 
       /* Add email type */
       typeAttr.value = "email";
    }
    
    /* Set the attribute nodes onto the new DOM element. */
    newInput.setAttributeNode( idAttr );
    newInput.setAttributeNode( nameAttr );
    newInput.setAttributeNode( typeAttr );
    
    /* Append the new DOM element as a child of the original parent node. */
    let parent = document.getElementById( "email-to-date" );
    parent.appendChild( newInput );
});

You will face one issue of changed display order, which you will have to control using CSS or using parent.insertBefore() or parent.insertAfter() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM