Html form Change focus on enter - javascript

I am trying to change the focus on enter key on my html input form.
I have to trigger saveValue() from input field while pressing enter and focus to next input field. I am trying with the directive from angularjs move focus to next control on enter but dont know how can i modify according to my need.
angular.module('ionicApp', ['ionic'])
.controller('appCtrl', function($scope) {
$scope.inputs = [{
value: ''
}];
var checkedValues = [];
$scope.addField = function(index) {
console.log(index);
var name = {
'value': ''
};
if ($scope.inputs.length <= index + 1 && $scope.inputs.length < 10) {
$scope.inputs.splice(index + 1, 0, name);
}
}
$scope.saveValue = function(ticked, item, index) {
console.log(index);
if (ticked) {
if (index >= 0) {
$scope.showButton = true;
}
//if(index<=9) checkedValues.splice(index,0,item);
checkedValues[index] = item;
console.log(checkedValues);
} else {
var indexs = checkedValues.indexOf(item);
if (indexs > -1) {
checkedValues.splice(indexs, 1);
}
console.log(checkedValues);
}
}
})
.small-input .item-checkbox .checkbox {
position: absolute;
top: 50%;
right: 8px;
left: 5px!important;
z-index: 3;
margin-top: -20px!important;
transform: scale(1);
}
.checkbox-royal input:before,
.checkbox-royal .checkbox-icon:before {
border-color: #000;
background-color: #387ef5;
}
.checkbox-royal input:checked:before,
.checkbox-royal input:checked + .checkbox-icon:before {
background: #099AD1;
border-color: #387ef5;
}
<html>
<head>
<link href="http://code.ionicframework.com/1.3.2/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.3.2/js/ionic.bundle.js"></script>
</head>
<body ng-app="ionicApp" ng-controller="appCtrl">
<form id="valueForm" ng-submit="submitValues()">
<div class="small-input list padding" style="padding-top:4px;">
<div ng-repeat="item in inputs track by $index">
<label class="item item-input">
<input type="text" placeholder="" ng-model="item.value" ng-disabled="item.ticked">
<ion-checkbox ng-click="addField($index)" ng-change="saveValue(item.ticked,item.value,$index)" ng-model="item.ticked" ng-disabled="!item.value" style="border: none;padding-left: 30px;" class="checkbox-royal"></ion-checkbox>
</label>
</div>
<button type="submit" ng-show="showButton" class="button button-dark button-shadow pull-right" style=""><i class="ion-ios-arrow-forward"></i>
</button>
</div>
</form>
</body>
</head>

The problem you will have is that when the directive keydown handler runs the new input will not exist on the page yet. It will get created later on. I suggest you use a $interval to keep checking when the input has been added and then assign the focus:
elem.bind('keydown', function(e) {
var code = e.keyCode || e.which;
if (code === 13) {
e.preventDefault();
scope.addFieldAndSave(index);
// Create interval to check when the new input has been added
scope.interval = $interval(function() {
var e = $('input[type=text]');
if (e.length === scope.inputs.length) {
scope.cancel();
// Set focus to the last element enabled input
$('input[type=text]:not(:disabled):last').focus();
}
}, 10);
}
});
This is quite complex so I've done a plunker. To get this to work I added a new method in the main controller called addFieldAndSave to do the add and save functions
https://plnkr.co/edit/2NXQB7N7bVxUVQk7PLsx?p=preview

Related

Javascript - How to limit character in a contentEditable div?

I am learning english yet. Thank you for you patience.
I created a todo list CRUD. The code is working well but I am improving even more my code.
When I press the button "plus" I create a div with the text, button delete and edit as you can see in the pic.
Task created
But when I pass a certain number of characters, it happens. (See the pic)
When the task is big, it passes to other line
How can I put a limit to it? Thank you!
My HTML code:
<body>
<header>
<h1>Lista de Tarefas</h1>
</header>
<form>
<input type="text" name="task" id="task" maxlength="34">
<button class='btnadd'><i class="fas fa-plus"></i></button>
</form>
<div class="container-tasks">
<ul class="list-task"></ul>
</div>
<script src="/js/app.js"></script>
</body>
My Javascript code:
let input = document.getElementById('task');
let btnAdd = document.querySelector(".btnadd");
let list = document.querySelector(".list-task");
// Events
btnAdd.addEventListener('click', addTask);
// Functions
function addTask(event){
event.preventDefault();
if (input.value === ''){
alert('You must type something');
return false;
} else {
addTask
}
let divTask = document.createElement("div");
divTask.classList.add("task");
let newTask = document.createElement("div");
newTask.innerText = input.value;
newTask.classList.add("new-task");
divTask.appendChild(newTask);
let btnDelete = document.createElement('button');
btnDelete.innerHTML = 'Remover';
btnDelete.classList.add("btn-remover");
divTask.appendChild(btnDelete);
let btnEdit = document.createElement('button');
btnEdit.innerHTML = 'Editar';
btnEdit.classList.add("btn-editar");
divTask.appendChild(btnEdit);
list.appendChild(divTask);
input.value = "";
btn.addEventListener('click', removeTask);
function removeTask(){
divTask.remove();
}
btnEdit.addEventListener('click', editTask);
function editTask(){
const endEdit = document.createElement('button');
endEdit.classList.add('end-edit');
endEdit.innerHTML = 'Finalizar'
divTask.appendChild(endEdit);
newTask.contentEditable = true;
newTask.focus();
btnEdit.style.display = 'none'
endEdit.addEventListener('click', endEdition);
function endEdition(){
newTask.contentEditable = false;
endEdit.remove();
btnEdit.style.display = 'block'
}
}
}
I dont think there is a definite option for that, but you can surely use keydowns count.
jQuery
$('div').on('keydown', function(event) {
$('span').text('Total chars:' + $(this).text().length);
if($(this).text().length === 100 && event.keyCode != 8) {
event.preventDefault();
}
});
div {
height: 100px;
width: 300px;
border: 1px solid grey;
outline: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div contenteditable="true"></div>
<span></span>
Vanilla JS
let maxChars = 10;
let currentChars = 0;
function checkLength(event) {
if(currentChars >= maxChars) {
alert('reached max chars');
event.preventDefault();
} else {
currentChars++;
}
}
div {
height: 100px;
width: 300px;
border: 1px solid grey;
outline: 0;
}
<div contenteditable="true" onkeypress="checkLength(event)"></div>
<span></span>

Why is my text output from next() and prev() toggle incorrect?

When clicking the arrows to change the displayed option, the incorrect options is shown.
The user should be able click on the option menu to toggle it open/cosed and be able to click on a option to select it. Alternatively, the arrows could be used to toggle through the options instead.
This is the problematic code:
<script>
$("#arrow_left_physics").click(function() {
var $selected = $(".left_menu_option_selected").removeClass("left_menu_option_selected");
var divs = $("#left_menu__variant_physics").children();
divs.eq((divs.index($selected) - 1) % divs.length).addClass("left_menu_option_selected");
$("#left_menu_open .button-text").text($($selected).text());
});
$("#arrow_right_physics").click(function() {
var $selected = $(".left_menu_option_selected").removeClass("left_menu_option_selected");
var divs = $selected.parent().children();
divs.eq((divs.index($selected) + 1) % divs.length).addClass("left_menu_option_selected");
$("#left_menu_open .button-text").text($($selected).text());
});
</script>
$("#menu_open").click(function() {
$("#menu").toggle();
});
$(".menu_option").click(function() {
if ($(this).hasClass(".menu_option_selected")) {} else {
$(".menu_option").removeClass("menu_option_selected");
$(this).addClass("menu_option_selected");
$("#menu_open .button_text").text($(this).text());
}
});
$("#arrow_left").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) - 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($($selected).text());
});
$("#arrow_right").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) + 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($($selected).text());
});
.menu_open {
Cursor: pointer;
}
.menu {
display: none;
position: absolute;
border: 1px solid;
}
.menu_option {
Cursor: pointer;
Padding: 5px;
}
.menu_option:hover {
Background-Color: black;
Color: white;
}
.menu_option_selected {
color: green;
Background-color: #00ff0a4d;
}
.menu_option_selected:hover {
color: green;
}
.arrow {
Cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="arrow" type="button" id="arrow_left" value="❮" />
<input class="arrow" type="button" id="arrow_right" value="❯" />
</div>
<div>
<button class="menu_open" id="menu_open">
<span class="button_text">option1</span>
</button>
</div>
<div class="menu" id=menu>
<div class="menu_option menu_option_selected">option1</div>
<div class="menu_option">option2</div>
<div class="menu_option">option3</div>
<div class="menu_option">option4</div>
<div class="menu_option">option5</div>
<div class="menu_option">option6</div>
</div>
-It seems that the first click of the arrows isn't working and that the index function is incorrect somewhere.
The problem is this line:
$("#menu_open .button_text").text($($selected).text());
$($selected) is the option that was previously selected, so you're showing the text of the previous option, not the current option. (BTW, there's no need to wrap $selected in $(), since it's already a jQuery object.)
You should use $(".menu_option_selected").text() instead of $($selected).text() to get the current option.
You should also make the initial text of the button option1, so it matches the selected option.
$("#menu_open").click(function() {
$("#menu").toggle();
});
$(".menu_option").click(function() {
if ($(this).hasClass(".menu_option_selected")) {} else {
$(".menu_option").removeClass("menu_option_selected");
$(this).addClass("menu_option_selected");
$("#menu_open .button_text").text($(this).text());
}
});
$("#arrow_left").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) - 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($(".menu_option_selected").text());
});
$("#arrow_right").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) + 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($(".menu_option_selected").text());
});
.menu_open {
Cursor: pointer;
}
.menu {
display: none;
position: absolute;
border: 1px solid;
}
.menu_option {
Cursor: pointer;
Padding: 5px;
}
.menu_option:hover {
Background-Color: black;
Color: white;
}
.menu_option_selected {
color: green;
Background-color: #00ff0a4d;
}
.menu_option_selected:hover {
color: green;
}
.arrow {
Cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="arrow" type="button" id="arrow_left" value="❮" />
<input class="arrow" type="button" id="arrow_right" value="❯" />
</div>
<div>
<button class="menu_open" id="menu_open">
<span class="button_text">option1</span>
</button>
</div>
<div class="menu" id=menu>
<div class="menu_option menu_option_selected">option1</div>
<div class="menu_option">option2</div>
<div class="menu_option">option3</div>
<div class="menu_option">option4</div>
<div class="menu_option">option5</div>
<div class="menu_option">option6</div>
</div>
Just another version, refactoring your javascript code with some Arrow functions.
const setButtonText = () => {
$("#menu_open .button_text").text(
$(".menu_option_selected").text()
);
}
const moveSelection = direction => {
var selected = $(".menu_option_selected")
var options = $("#menu").children()
var newIndex;
if (direction == 'right') {
newIndex = (options.index(selected) + 1) % options.length
} else {
newIndex = (options.index(selected) - 1) % options.length
}
selected.removeClass("menu_option_selected")
options.eq(newIndex).addClass("menu_option_selected")
setButtonText()
}
// inizilize menu button_text
setButtonText()
$("#arrow_left").click(() => moveSelection('left'));
$("#arrow_right").click( () => moveSelection('right'));
$("#menu_open").click( () => $("#menu").toggle());
$(".menu_option").click( function() {
$(".menu_option_selected").removeClass("menu_option_selected")
$(this).addClass("menu_option_selected")
setButtonText()
});

Display only 5 records in the autocomplete <input> tag bound with the <datalist> tag items and for rest items show the scroll bar [duplicate]

I am having trouble with datalist in HTML5, i have 10000 rows to display in my option values, I am populating from mysql using PHP, for some reason I can't see any scrollbar, i tried overflow:scroll setting height and width but no help. Please help me!
<div class="container">
<form action="NutritionDataBank.php" method="post">
<label>Select NDBNum:</label>
<input list="ndbnum" id="ndb" placeholder="e.g.1001" size="20" multiple>
<datalist id="ndbnum">
<?php
//...
while($row = mysqli_fetch_array($result)){
echo "<option value=$row[ndbNum]></option>";
}
?>
</datalist>
</form>
</div>
Unfortunately, there's not much you can do with the datalist attribute. The datalist does not currently support any CSS styling, and specific visual characteristics are browser-specific. Some browsers may choose to add scrollbars for long lists.
If this isn't acceptable, you may have to forget the datalist and implement a ComboBox via Javascript. I believe JQuery has an autocomplete function that may be appropriate.
Agree with above.However below is the work around.Here is the jsfiddle (http://jsfiddle.net/v30gqws5/9/)
var app = angular.module('myApp', []);
app.controller('TodoCtrl', function($scope, $timeout) {
$scope.CountryList = [{
name: 'india'
},
{
name: 'usa'
},
{
name: 'iran'
},
{
name: 'australia'
},
{
name: 'china'
},
{
name: 'delhi'
},
{
name: 'korea'
},
{
name: 'france'
}
];
const dataList = document.getElementById('dataList');
const input = document.getElementById('autoComplete');
var dataList2;
for (let i = 0; i < $scope.CountryList.length; ++i) {
if (i < 5) {
option = document.createElement('option');
option.setAttribute('value', $scope.CountryList[i].name);
option.innerHTML = $scope.CountryList[i].name;
dataList.appendChild(option);
} else {
if (i == 5) {
dataList.innerHTML += '<datalist id="scrolldatalist"/>'
}
dataList2 = document.getElementById('scrolldatalist');
option = document.createElement('option');
option.setAttribute('value', $scope.CountryList[i].name);
option.innerHTML = $scope.CountryList[i].name;
dataList2.appendChild(option);
}
}
dataList.querySelectorAll('option').forEach((el, idx, arr) => {
el.addEventListener('click', (e) => {
input.value = el.value;
});
});
dataList2.querySelectorAll('option').forEach((el, idx, arr) => {
el.addEventListener('click', (e) => {
input.value = el.value;
});
});
input.addEventListener('focus', showList);
input.addEventListener('blur', () => {
setTimeout(() => {
dataList.classList.remove('show');
dataList2.classList.remove('show');
}, 300);
});
input.addEventListener('keyup', showList);
function showList() {
if (!!input.value) {
input.setAttribute("list", "dataList");
dataList.classList.remove('show');
dataList2.classList.remove('show');
} else {
input.removeAttribute("list");
dataList.classList.add('show');
dataList2.classList.add('show');
}
}
input.addEventListener('change', () => {
if (!dataList.querySelector(`option[value='${input.value}']`)) {
input.value = '';
} else {
input.blur();
}
});
})
#dataList {
display: none;
height: 120px;
overflow: auto;
left: 0;
border: 1px solid black;
}
#scrolldatalist {
display: none;
height: 80px;
overflow: auto;
}
#dataList option,
#scrolldatalist option {
font-family: arial;
font-size: 11.8px;
cursor: pointer;
padding: 5px 10px;
font-weight: bold;
}
#dataList.show,
#scrolldatalist.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.10/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="TodoCtrl">
<div class="container">
<input type="text" id="autoComplete" placeholder="country" autocomplete="off" />
<datalist id="dataList" />
</div>
</div>
</div>

Get the number of dates time later than current datetime

I have a array of objects where i have a property of date_time, and in this array i wish to get the lenght of dates_times objects that are sooner with my current date_time.
Ex:
[data:[{date: "2017-02-24 16:41:51"}, {date: ""2017-02-21 16:41:51"}...],
last_clicked: "2017-02-24 19:41:51"]
I wish to get the length of objecs on "data" array that haves a date_time sooner than "last_clicked".
Maybe you can try something like this:
let length = data.filter(function(d) {
return new Date(d.date) < new Date(last_clicked)
}).length;
You can use Angulars-orderBy-filter. I set up an example for you, just swap out where I have the id key for your data's date key.
function exampleController($scope, exampleFactory, $filter) {
$scope.list = [];
$scope.reverse = false;
$scope.changeSortOrder = function() {
$scope.reverse = !$scope.reverse;
};
function getList() {
exampleFactory
.getList()
.then(function(list) {
// $scope.list = list;
//alternatively you could filter here and change the sort order with the button if needed at all.
$scope.list = $filter('orderBy')(list, '-id'); //where this would be replaced by date(note: the '-' in front of id changes the sort order ASC/DESC)
//$scope.list = $filter('orderBy')(list, 'id', true); //where 3rd argument is wether order should be reversed
});
}
getList();
}
function exampleFactory($http) {
var root = 'http://jsonplaceholder.typicode.com';
function getList() {
return $http.get(root + '/comments')
.then(function(resp) {
return resp.data;
});
}
return {
getList: getList
};
}
angular
.module('app', [])
.controller('exampleController', exampleController)
.factory('exampleFactory', exampleFactory);
.container-fluid {
background-color: #1D1F20;
color: #fff;
font-size: 14px;
font-weight: bold;
button {
margin-top: 20%;
}
}
ul li {
list-style: none;
margin: 10px;
}
.child-padding>div {
padding: 2px;
}
.col-md-2 {
position: fixed;
button {
margin-bottom: 10%;
}
}
.btn-circle {
width: 30px;
height: 30px;
text-align: center;
padding: 6px 0;
font-size: 12px;
line-height: 1.428571429;
border-radius: 50%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div class="container-fluid" ng-app="app">
<div class="container" ng-controller="exampleController">
<div class="row">
<div class="col-md-2 text-center">
<button class="btn btn-primary" type="button" ng-click="changeSortOrder()">Change Sort Order</button>
</div>
<div class="col-md-10 pull-right">
<ul class="ul">
<li ng-repeat="comment in list | orderBy: 'date': reverse track by $index">
<div class="child-padding">
<div>
<span ng-bind="comment.email"></span>
<span class="pull-right btn-info btn-circle" ng-bind="comment.id"></span>
</div>
<div ng-bind="comment.body"></div>
</div>
<div ng-bind="comment.name"></div>
</li>
</ul>
</div>
</div>
</div>
</div>
Use Date.parse to parse your date strings
DEMO JsFiddle
The following code will alert:
Sooner times: 1
var o = {
data:[
{date: "2017-02-24 16:41:51"},
{date: "2017-02-21 16:41:51"}
],
last_clicked: "2017-02-24 12:41:51"
};
function getSoonerLength(data, soonerThan) {
var count = 0;
for (var i = 0 ; i < data.length ; i++) {
var d = Date.parse(data[i].date);
var than = Date.parse(soonerThan);
if (d < than)
count++;
}
return count;
}
alert('Sooner times: ' + getSoonerLength(o.data, o.last_clicked))

Textarea counter / countdown with negative numbers and enforcement

I've been working on adding a character counter to a TEXTAREA field. There are many, many solutions available online for this task.
"Stop-at-Zero" Solution
The problem I'm having is that practically all solutions terminate user input at 0. That's effective, I guess, but it's not optimal in terms of user-friendliness. For example, if a user pastes text into the TEXTAREA, and the text exceeds the field's limitation, this stop-at-zero solution will abruptly truncate the excess text. The user then has to work to find the missing content and then edit their message, submit a second form, or some other burden.
"Negative Character Count" Solution
Other solutions allow the user to enter all they want. The character counter will go from positive to negative. The problem with these counters is lack of enforcement: They allow users to submit the form even with a negative character count.
Twitter Solution
I think Twitter has it right. They let users input all they want and highlight the excess text with a negative character count (and a colored background, which I don't need to have). They disable the submit button while the count is negative.
My (Incomplete) Solution
Working with third-party code I found through Google, I've devised a character counter that works perfectly in terms of the count. But being somewhat new to JS I haven't been able to code the enforcement part.
Here's my question:
How do I get the code to prevent submission of the form when the counter is a negative number?
HTML
<form action="" method="post">
<div>
<textarea name="comments" id="comments" cols="50" rows="10"></textarea>
</div>
<div>
<input type="submit">
</div>
</form>
CSS
form div {
position: relative;
}
form .counter {
position: absolute;
left: 300px;
bottom: -25px;
font-size: 25px;
font-weight: bold;
color: #ccc;
}
form .warning {color: orange;}
form .exceeded {color: red;}
JavaScript
<script src="/js/jquery.js"></script>
<script>
(function($) {
$.fn.charCount = function(options){
// default configuration properties
var defaults = {
allowed: 100,
warning: 25,
css: 'counter',
counterElement: 'span',
cssWarning: 'warning',
cssExceeded: 'exceeded',
counterText: ''
};
var options = $.extend(defaults, options);
function calculate(obj){
var count = $(obj).val().length;
var available = options.allowed - count;
if(available <= options.warning && available >= 0){
$(obj).next().addClass(options.cssWarning);
} else {
$(obj).next().removeClass(options.cssWarning);
}
if(available < 0){
$(obj).next().addClass(options.cssExceeded);
} else {
$(obj).next().removeClass(options.cssExceeded);
}
$(obj).next().html(options.counterText + available);
};
this.each(function() {
$(this).after('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'</'+ options.counterElement +'>');
calculate(this);
$(this).keyup(function(){calculate(this)});
$(this).change(function(){calculate(this)});
});
};
})(jQuery);
</script>
<script>
$(document).ready(function(){
$("#comments").charCount();
});
</script>
https://jsfiddle.net/nyc212/sk5kfopw/
I have modified your plugin to take the submit button as first parameter.
If you want it to be more dynamic:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
form div {
position: relative;
}
form .counter {
position: absolute;
left: 300px;
bottom: -25px;
font-size: 25px;
font-weight: bold;
color: #ccc;
}
form .warning {
color: orange;
}
form .exceeded {
color: red;
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
(function($) {
$.fn.charCount = function(btnsub, options){
this.btnsub = btnsub;
// default configuration properties
var defaults = {
allowed: 100,
warning: 25,
css: 'counter',
counterElement: 'span',
cssWarning: 'warning',
cssExceeded: 'exceeded',
counterText: ''
};
var options = $.extend(defaults, options);
function calculate(obj,btnsub){
btnsub.attr("disabled", "disabled");
var count = $(obj).val().length;
var available = options.allowed - count;
if(available <= options.warning && available >= 0){
$(obj).next().addClass(options.cssWarning);
} else {
$(obj).next().removeClass(options.cssWarning);
}
if(available < 0){
$(obj).next().addClass(options.cssExceeded);
} else {
$(obj).next().removeClass(options.cssExceeded);
btnsub.removeAttr("disabled");
}
$(obj).next().html(options.counterText + available);
};
this.each(function() {
$(this).after('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'</'+ options.counterElement +'>');
calculate(this, btnsub);
$(this).keyup(function(){calculate(this,btnsub)});
$(this).change(function(){calculate(this,btnsub)});
});
};
})(jQuery);
$(document).ready(function(){
$("#comments").charCount($("#btnsub"));
});
</script>
</head>
<body>
<form method="post">
<div>
<textarea name="comments" id="comments" cols="50" rows="10"></textarea>
</div>
<div>
<input type="submit" id="btnsub">
</div>
</form>
</body>
</html>
I would try either by disabling the submit button using the disabled attribute, or preventing the form from submitting using e.preventDefault. I updated your fiddle...just uncomment either of the options
https://jsfiddle.net/sk5kfopw/1/

Categories