user2548213
user2548213

Reputation: 366

jQuery's .prepend is replacing my content instead of adding it to the beginning

I'm trying to place the text from an input in a list, and allow the user to add multiple items, with the new items being added to the top. I'm using .prepend, which should add the new item to the top, but instead it is replacing the existing element. Any thoughts?

It's on Codepen

function getParameter(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
function postMessage(){
    var currentTime = new Date().getSeconds(),
        thoughts = getParameter("post"),
        message = "<li>" + thoughts + " - " + currentTime + "</li>";
    $("#list").prepend(message);
}
$("form").on( "submit", postMessage());

Upvotes: 0

Views: 131

Answers (3)

myfunkyside
myfunkyside

Reputation: 3950

That happens because when a form is submitted, the page is reloaded. So your content isn't really being replaced, what in fact happens is (1) the page reloads clearing all content, and (2) the input which has been added to the URL as parameter, is now prepended to the list as first and only content.

To prevent this, you can either:

  1. Prevent the forms's default behaviour by changing
    $("form").on("submit", postMessage()); to
    $("form").on("submit", function(e){e.preventDefault(); postMessage();});.

  2. Change the <input type="submit" /> to <input type="button" /> (a regular button), bypassing the whole submit issue altogether. Since the form doesn't need to be submitted, the submit-button really isn't necessary, and even a bit misplaced. You also don't need to prevent any default behaviour, which is a lot cleaner in my opinion.
    This option has my preference, so I'll explain this option in more detail below:


$(window).on("load", function(){
  $(".input").click(function() {
    $(this).select();
  });
  
  $("#search .submit").click(function(){
    var currentTime = new Date().getSeconds(),
        thoughts = $("#search .input").val(),
        message = "<li>" + thoughts + " - " + currentTime + " seconds </li>";
    $("#list").prepend(message);  
  });
});
html{
  height: 100%;
}
body{
  background: #fff;
  font-size: 13px;
  min-width: 800px;
}
br{
  clear: left;
}

#header{
  background:cornflowerblue;
  padding: 10px 5px;
  box-shadow: 0px 1px 5px #fff;
  text-align:center;
}
#search{
  display: inline-block;
}
.input{
  width: 300px;
  padding: 2px 3px;
  border: 2px solid #A2C4DA;
  font-size: 1.2em;
  line-height:2;
}
.submit{
  padding: 6px 12px;
  vertical-align: top;
  font-weight: bold;
  text-shadow: 1px 1px 1px #fff;
  background:#fff;
  border: 1px solid #6FD6F7;
  line-height:2;
}
.submit:hover{cursor:pointer;}

#page{
  width: 800px;
  background: dodgerblue;
  border: 1px solid #ffffff;
  margin: 10px auto 0px;
  padding: 1em 2em;
  font-size:2em;
}
#page li{
  list-style:none;
  text-align:center;
  color: #fff;
  border-top:1px solid #fff;
}
#page li:nth-child(n+1){
  border:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="header">
  <div id="search">
    <form>
      <input type="text" class="input" placeholder="thoughts?" />
      <input type="button" class="submit" value="Post" />
    </form>
  </div>
  <br>
</div>

<div id="page">
  <ul id="list"></ul>
</div>
(codepen: http://codepen.io/anon/pen/yefcw)

  • Because the page doesn't reload anymore, you can't use thoughts = getParameter("post") anymore. Since the page doesn't reload, no parameter is added to the URL.
    To get that working again, I changed that line to thoughts = $("#post").val().

  • I gave the <input type="text"/> and <input type="button"/> both classes, so they can be referenced by JS and CSS. I removed the name from the input-field, because it's not needed in this situation.
    (I could have used ID's instead of classes, but the classes give you more flexibility. For instance, if you want a second input-form on the page just like this one, you can just copy-paste it, except the <div id="search"> needs another ID. Then, in the JS you make another click-handler like $("#search .submit").click( where you also change the #search to the new ID.
    But in the CSS you have to change nothing, because the CSS rules for the classes .input and .submit will also style the new input field and button.)

  • I updated the CSS selectors accordingly to reference the new classes.
  • I removed method="get" from your form, since it's not used or needed anymore.
  • I removed the getParameter() function, since you don't need it anymore.
  • I added the $("#input").click(... function, which selects all the text in the input field when you click on it. This is not necessary, but I thought it might be a little bit more user-friendly.
  • I wrapped your code in window.load. This is just good practice to make sure the code isn't executed before the page is completely loaded.

Upvotes: 2

Chandan Sarma
Chandan Sarma

Reputation: 308

function getParameter(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
function postMessage(){
 var currentTime = new Date().getSeconds(),
  thoughts = $("#post").val(),
  message = "<li>" + thoughts + " - " + currentTime + " seconds </li>";
 $("#page").prepend(message);
  $("#post").val("");
}
$("form").on( "submit", function(e){
  e.preventDefault();
  postMessage();
});

and put a id in inputtext box

<input type="text" name="post" id="post" placeholder="thoughts?"/>

Upvotes: 0

Kolban
Kolban

Reputation: 15266

In your code, the submit button is submitting the form which is causing the whole page to be reloaded/reset. The reload of the page causes the <ul> to be reloaded without content and then you insert content. This is repeated each time. You might want to consider not using <form> processing for getting input data.

Upvotes: 1

Related Questions