Search code examples
jqueryinputrenderinghtml-sanitizing

Todo List Sanitizing Input jQuery


I am working on a simple to do app. Everything works, except, if the user inputs an html element into the input, then it gets rendered as html. So, for instance if the input is h1 heading /h1 , I get the word "heading" with default h1 styling. I have been googling for 2 hours now, and would really just like to finish this app. this is the code.

var todoList = [];

$("#add").on("click", function() {
  var todoItem = $("#todoInput").val();
  if (!todoItem.trim()) {
    alert("please enter a to do");
  } else {
    todoList.push(todoItem);

    //empty the input field on click
    $("#todoInput").val("");

    //add a mark complete button to every array item
    //publish array
    var addedTodo = todoList[todoList.length - 1];
    console.log(addedTodo);
    $(".todoContainer")
      .append(
        '<li class="eachItem">' +
        '<p class="todoItemStyle">' + addedTodo +
        '</p><button class="sm-btn" id="deleteButton"> delete </button> <button class="sm-btn"  id="completeButton"> complete </button></li>'
      )
      .addClass("todoStyle");
  }
});

//add button to complete all items
$("#completeAll").on("click", function() {
  $(".todoItemStyle").toggleClass("completed");
});

//add button to restart list
$("#newList").on("click", function() {
  todoList = [];
  $(".todoContainer").html("");
});

//button to remove a todo
$("body").on("click", "#deleteButton", function() {
  $(this).parent().remove();
  console.log("delete button pressed");
});

//button to complete a todo
$("body").on("click", "#completeButton", function() {
  $(this).siblings(".todoItemStyle").toggleClass("completed");
  console.log("completed clicked");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main container">
  <div class="all container">
    <h1> My List </h1>
    <div class="buttons">
      <button id="newList" class="global-buttons"> New List </button>
      <button id="completeAll" class="global-buttons"> Complete All</button>
    </div>
    <div class="container list">
      <label> Input your to do </label>
      <input type="text" id="todoInput" placeholder="Input your to do here" name="todo">
      <button id="add" class="global-buttons"> Add to list </button>
      <ul class="todoContainer">
      </ul>
    </div>
  </div>
</div>

Thank you for looking. CodePen


Solution

  • You can strip all html tags on input with a regex pattern:

    $("#todoInput").val().replace(/(<([^>]+)>)/ig,"");
    

    var todoList = [];
    
    $("#add").on("click", function() {
      var todoItem = $("#todoInput").val().replace(/(<([^>]+)>)/ig,"");
      if (!todoItem.trim()) {
        alert("please enter a to do");
      } else {
        todoList.push(todoItem);
    
        //empty the input field on click
        $("#todoInput").val("");
    
        //add a mark complete button to every array item
        //publish array
        var addedTodo = todoList[todoList.length - 1];
        console.log(addedTodo);
        $(".todoContainer")
          .append(
            '<li class="eachItem">' +
            '<p class="todoItemStyle">' + addedTodo +
            '</p><button class="sm-btn" id="deleteButton"> delete </button> <button class="sm-btn"  id="completeButton"> complete </button></li>'
          )
          .addClass("todoStyle");
      }
    });
    
    //add button to complete all items
    $("#completeAll").on("click", function() {
      $(".todoItemStyle").toggleClass("completed");
    });
    
    //add button to restart list
    $("#newList").on("click", function() {
      todoList = [];
      $(".todoContainer").html("");
    });
    
    //button to remove a todo
    $("body").on("click", "#deleteButton", function() {
      $(this).parent().remove();
      console.log("delete button pressed");
    });
    
    //button to complete a todo
    $("body").on("click", "#completeButton", function() {
      $(this).siblings(".todoItemStyle").toggleClass("completed");
      console.log("completed clicked");
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="main container">
      <div class="all container">
        <h1> My List </h1>
        <div class="buttons">
          <button id="newList" class="global-buttons"> New List </button>
          <button id="completeAll" class="global-buttons"> Complete All</button>
        </div>
        <div class="container list">
          <label> Input your to do </label>
          <input type="text" id="todoInput" placeholder="Input your to do here" name="todo">
          <button id="add" class="global-buttons"> Add to list </button>
          <ul class="todoContainer">
          </ul>
        </div>
      </div>
    </div>