I'm making a simple to-do list with WebSockets. The simple-todo is created but I only managed to create it with a click instead of the draggable option it should have. I changed the click to draggable but it didn't work. here is the code I used.
<!doctype html>
<html>
<head>
<title>Simple Todo</title>
</head>
<body>
TODO <input type="text" id="newTodoItem">
<ul id="itemsTodo">
</ul>
PROGRESS
<ul id="itemsProgress">
</ul>
DONE
<ul id="itemsDone">
</ul>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
/* statusses
0: todo
1: progress
2: done
*/
window.addEventListener('DOMContentLoaded', function () {
socket.emit("submitNewTodoItemMessage", {});
}, false);
// Checks if a new toto item is submitted
document.onkeyup = function (e) {
if (e.which === 13) {
var newTodoItem = {};
newTodoItem.id = parseFloat(new Date().getTime() + Math.random());
newTodoItem.status = 0;
newTodoItem.action = document.getElementById("newTodoItem").value;
if (newTodoItem !== '') {
socket.emit("submitNewTodoItemMessage", newTodoItem);
}
document.getElementById("newTodoItem").value = "";
}
};
socket.on("listOfAllTodoItemsMessage", function (listOfAllTodoItems) {
var itemsTodo = [], itemsProgress = [], itemsDone = [];
for (var i = 0; i < listOfAllTodoItems.length; i++) {
var item = listOfAllTodoItems[i];
var dragItem = "<li>" + item.action + " <span class='changeStatus' id='p_" + item.id + "'>^</span> <span class='changeStatus' id='n_" + item.id + "'>v</span></li>";
if (listOfAllTodoItems[i].status === 0) {
itemsTodo.push(dragItem);
} else if (listOfAllTodoItems[i].status === 1) {
itemsProgress.push(dragItem);
} else if (listOfAllTodoItems[i].status === 2) {
itemsDone.push(dragItem);
}
document.getElementById('itemsTodo').innerHTML = itemsTodo.join("");
document.getElementById('itemsProgress').innerHTML = itemsProgress.join("");
document.getElementById('itemsDone').innerHTML = itemsDone.join("");
}
$(".changeStatus").draggable(function (e) {
socket.emit("submitStatusUpdateTodoItemMessage", e.target.id);
});
$(".changeStatus").css('cursor', 'pointer');
});
</script>
</body>
</html>
the code snippet is now on the draggable state but it isn't working. I'm using jquery so the draggable function should work I guess.
The array shows up when I console.log it, but when i try anything else (alert with array and key, or just appending it) only undefined shows up. In this case, what actually shows up on my screen is: checkbox undefined button
<body>
<input id="text-field-input" type="text" placeholder="what do you have to do?"/>
<button id="submit">submit</button>
<ul id="list-section">
</ul>
var toDoList = [];
function addInputToList(todoinput, checkchecked) {
toDoList.push({todo : todoinput, checked : checkchecked});
};
function renderToDos() {
$('#list-section').append('<input type="checkbox">' + toDoList.todo + ' ' + '<button>x</button>');
};
$('#submit').on('click', function() {
var textFieldInput = $('#text-field-input').val().toLowerCase();
addInputToList(textFieldInput, false);
renderToDos();
});
Your toDoList is an Array, you need to loop through its elements in order to render your to do list:
function renderToDos() {
for(var i = 0; i < toDoList.length; i++) {
$('#list-section').append('<input type="checkbox">' + toDoList[i].todo + ' ' + '<button>x</button>');
}
};
I hope this will help you.
In your code you are trying access an object property on array which does not have such properties( i.e todo). That's why you are getting undefined.
Perhaps you want to achieve this -
var toDoList = [];
function addInputToList(todoinput, checkchecked) {
toDoList.push({todo : todoinput, checked : checkchecked});
};
function renderToDos() {
var count = toDoList.length;
if(count > 0){
var addedTodo = toDoList[count-1]
$('#list-section').append('<input type="checkbox">' + addedTodo.todo + ' ' + '<button>x</button>');
}
};
$('#submit').on('click', function() {
var textFieldInput = $('#text-field-input').val().toLowerCase();
addInputToList(textFieldInput, false);
renderToDos();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<input id="text-field-input" type="text" placeholder="what do you have to do?"/>
<button id="submit">submit</button>
<ul id="list-section">
</ul>
Below code appends text in a box how to avoid entering duplicate values..?
$('#plan td.n').click(function(){
$(this).html('B').css("background-color","red");
$("input:text").val(this.id);
var toAdd = $("input[name=checkListItem]").val();
$(".list").append("<div class = 'item'>" + toAdd + "</div>")//add the seat number to box
});
I'd probably do something like this below. Hope it helps
var lookupObj = {};
var toAdd = $("input[name=checkListItem]").val();
if(!lookupObj[toAdd]) {
$(".list").append("<div class = 'item'>" + toAdd + "</div>")
lookupObj[toAdd] = true;
}
Assuming your markup looks like this:
<input name="checkListItem" value=""/>
<input type="submit" class="addItem" value="Add/Remove"/>
<div class="list">
</div>
You can add an event which filters items which match the text (exactly) of the current .val() of the checkListItem input, which lets you delete the item in the list if it is a duplicate.
$('.addItem').on('click', function() {
var toAdd = $("input[name=checkListItem]").val(),
exists = $('.item').filter(function() {
return $(this).text() == toAdd;
});
if (exists.length > 0) {
exists.remove();
} else {
$(".list").append("<div class = 'item'>" + toAdd + "</div>");
}
});
https://jsfiddle.net/milesrobinson/563h1fq6/
// if you don't care the performance, this is the easy way
var finded = false;
$(".list > .item").each(function(idx){
if (toAdd === $(this).html()) {
finded = true;
return false;
}
});
if (!finded) {
$(".list").append("<div class = 'item'>" + toAdd + "</div>")
}
i want to perform keyup event via textbox id, and all textbox are dynamically created with onclick button event. for this i have to make 20 keyup function. if i use 20 keyup function then my code will become too lengthy and complex. instead of this i want to use a common function for all textbox. can anybody suggest me how to do it..thanks
here is what i am doing to solve it:
<div class="input_fields_wrap">
<button class="add_field_button">Add Booking</button></div>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
var counter = 2;
$(".add_field_button").click(function() {
if (counter > 10) {
alert("Only 10 textboxes allow");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<div id="target"><label>Textbox #' + counter + ' : </label>' +
'<input type="text" name="textbox' + counter +
'" id="firsttextbox' + counter + '" value="" > <input type="text" name="textbox' + counter +
'" id="secondtextbox' + counter + '" value="" > Remove<input type="text" id="box' + counter + '" value="">sum</div>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
function check(a, b) {
var first = a;
var second = b;
var temp = temp;
var novalue = "";
result = parseInt(first) + parseInt(second);
if (!isNaN(result)) {
return result;
} else {
return novalue;
}
}
$(this).on("keyup", "#firsttextbox2", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox2').value;
var b = document.getElementById('secondtextbox2').value;
var number = 2;
result = check(a, b);
document.getElementById('box2').value = result;
});
$(this).on("keyup", "#firsttextbox3", function(e) {
var number = 3;
e.preventDefault();
var a = document.getElementById('firsttextbox3').value;
var b = document.getElementById('secondtextbox3').value;
result = check(a, b);
document.getElementById('box3').value = result;
});
$(this).on("keyup", "#firsttextbox4", function(e) {
var number = 4;
e.preventDefault();
var a = document.getElementById('firsttextbox4').value;
var b = document.getElementById('secondtextbox4').value;
result = check(a, b);
final = document.getElementById('box4').value = result;
});
$(this).on("keyup", "#secondtextbox2", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox2').value;
var b = document.getElementById('secondtextbox2').value;
result = check(a, b);
document.getElementById('box2').value = result;
});
$(this).on("keyup", "#secondtextbox3", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox3').value;
var b = document.getElementById('secondtextbox3').value;
result = check(a, b);
document.getElementById('box3').value = result;
});
$(this).on("keyup", "#secondtextbox4", function(e) {
e.preventDefault();
var a = document.getElementById('firsttextbox4').value;
var b = document.getElementById('secondtextbox4').value;
result = check(a, b);
document.getElementById('box4').value = result;
});
$(this).on("click", "#remove_field", function(e) { //user click on remove text
e.preventDefault();
$(this).parent('#target').remove();
counter--;
});
});
</script>
See the snippet below to see how you can make this implementation more modular and useable. The trick is to think: what do I want to do? I want to be able to add multiple inputs and add their value, printing the result in another input.
It comes down to using classes - since we are going to use the same kind of thing for every row. Then apply something that works for all classes. No IDs whatsoever! You can even use the name property of the input that contains the value you want to save. Using the [] in that property will even pass you back a nice array when POSTING!
I know this looks like a daunting lot, but remove my comments and the number of lines reduces dramatically and this kind of code is almost infinitely extendable and reusable.
But have a look, this works and its simple and - most of all - it's DRY (don't repeat yourself 0 once you do, re-evaluate as there should be a better way!)!
Update
You could also use a <ol>as a wrapper and then add an <li> to this every time, so you get automatic counting of boxes in the front end without any effort from your end! Actually, thats so nice for this that I have changed my implementation.
var add = $('#add_boxes');
var all = $('#boxes');
var amountOfInputs = 2;
var maximumBoxes = 10;
add.click(function(event){
// create a limit
if($(".box").length >= maximumBoxes){
alert("You cannot have more than 10 boxes!");
return;
}
var listItem = $('<li class="box"></li>');
// we will add 2 boxes here, but we can modify this in the amountOfBoxes value
for(var i = 0; i < amountOfInputs; i++){
listItem.append('<input type="text" class="input" />');
}
listItem.append('<input type="text" class="output" name="value" />');
// Lets add a link to remove this group as well, with a removeGroup class
listItem.append('<input type="button" value="Remove" class="removeGroup" />')
listItem.appendTo(all);
});
// This will tie in ANY input you add to the page. I have added them with the class `input`, but you can use any class you want, as long as you target it correctly.
$(document).on("keyup", "input.input", function(event){
// Get the group
var group = $(this).parent();
// Get the children (all that arent the .output input)
var children = group.children("input:not(.output)");
// Get the input where you want to print the output
var output = group.children(".output");
// Set a value
var value = 0;
// Here we will run through every input and add its value
children.each(function(){
// Add the value of every box. If parseInt fails, add 0.
value += parseInt(this.value) || 0;
});
// Print the output value
output.val(value);
});
// Lets implement your remove field option by removing the groups parent div on click
$(document).on("click", ".removeGroup", function(event){
event.preventDefault();
$(this).parent(".box").remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<ol id="boxes">
</ol>
<input type="button" value="Add a row" id="add_boxes" />
You can target all your textboxes, present or future, whatever their number, with a simple function like this :
$(document).on("keyup", "input[type=text]", function(){
var $textbox = $(this);
console.log($textbox.val());
})
$("button").click(function(){
$("#container").append('<input type="text" /><br>');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<input type="text" /><br>
<input type="text" /><br>
<input type="text" /><br>
</div>
<button>Create one more</button>
You don't need complicated generated IDs, not necessarily a class (except if you have other input[type=text] you don't want to conflict with). And you don't need to duplicate your code and write 20 times the same function. Ever. If you're duplicating code, you're doing wrong.
Add classes "a" and "b" to the textboxes and "box" to the box. Then add data-idx attribute with the index (unused!?). Finally register the event handlers:
$('.a').on('keyup', function(e){
e.preventDefault();
var $this = $(this)
var $p = $this.parent()
var a= this.value;
var b= $p.find('.b').val()
var number =$this.data('idx') //unused!?
var result = check(a,b)
$p.find('.box').val(result)
})
$('.b').on('keyup', function(e){
e.preventDefault();
var $this = $(this)
var $p = $this.parent()
var a= $p.find('.a').val()
var b= this.value
var result = check(a,b)
$p.find('.box').val(result)
})
Or a general one:
$('.a,.b').on('keyup', function(e){
e.preventDefault();
var $p = $(this).parent()
var a= $p.find('.a').val()
var b= $p.find('.b').val()
var result = check(a,b)
$p.find('.box').val(result)
})
You can assign a class to all textboxes on which you want to perform keyup event and than using this class you can attach the event on elements which have that class. Here is an example
var html="";
for (var i = 0; i < 20; i++)
{
html += "<input type='text' id='txt" + i + "' class='someClass' />";
}
$("#testDiv").html(html);
Attach keyup event on elements which have class someClass.
$(".someClass").keyup(function () {
alert($(this).attr("id"));
});
A little helper to combine with your favorite answer:
var uid = function () {
var id = 0;
return function () {
return ++id;
};
}();
Usage:
uid(); // 1
uid(); // 2
uid(); // 3
Providing a code-snippet which may give you some hint:
$(".add_field_button").click(function ()
{
if (counter > 10)
{
alert("Only 10 textboxes allow");
return false;
}
var txtBoxDiv = $("<div id='TextBoxDiv"+counter+"' style='float:left;width:10%; position:relative; margin-left:5px;' align='center'></div>");
//creating the risk weight
var txtBox1 = $('<input />',
{
'id' : 'fst_textbox_' + counter,
'name' : 'textbox'+counter,
'type' : 'text',
'class' : 'input_field',
'onClick' : 'txtBoxFun(this,'+counter+')'
});
var txtBox2 = $('<input />',
{
'id' : 'sec_textbox_' + counter,
'name' : 'textbox'+counter,
'type' : 'text',
'class' : 'input_field',
'onClick' : 'txtBoxFun(this,'+counter+')'
});
var txtBox3 = $('<input />',
{
'id' : 'sum_textbox_' + counter,
'name' : 'textbox'+counter,
'type' : 'text',
'class' : 'input_field',
});
$(txtBoxDiv).append(txtBox1).append(txtBox2);
$(txtBoxDiv).append(txtBox3);
});
function txtBoxFun(obj, count)
{
var idGet = $(obj).attr('id');
var idArr = new Array();
idArr = idGet.split("_");
if(idArr[0] == "fst")
{
var sumTxt = parseInt(parseInt($(obj).val()) + parseInt($("#sec_textbox_"+count).val()));
}
else if(idArr[0] == "sec")
{
var sumTxt = parseInt(parseInt($(obj).val()) + parseInt($("#fst_textbox_"+count).val()));
}
$("#sum_textbox_"+count).val(sumTxt);
}
I have these functions:
$(".Read-Showing-Comment-Cancel").live('click', function (e) {
var guid = $(this).data("guid");
e.preventDefault();
var f = $('#comments-form-' + guid).slideUp();
$('comments-text-' + guid).empty();
$('comments-text-' + guid).value = "";
$(this).find('.comments-form-' + guid).hide();
$('comments-sendlink-' + guid).show();
});
$('.showComments').unbind('click').click(function (event) {
$('.ListingDisplayOptions').hide();
$(this).find('.comments-form-' + showGuid).show();
var showGuid = $(this).attr('rel');
loadShowingsComments(showGuid);
$(this).attr('id', 'comments-sendlink-' + showGuid);
event.preventDefault();
});
function loadShowingsComments(guid) {
var commentTextArea = "#comments-form-" + guid;
var commentDisplay = ".spanComments" + guid;
var curComment = $(commentDisplay).text();
var element = "#comments-form-" + guid;
$(element).slideDown();
}
<script>
function showComments() {
var comments = document.querySelectorAll(".spanComments");
for (var i = 0; i < comments.length; i++) {
comments[i].innerHTML = "This is comment #" + i;
}
}
</script>
View Comments
Those functions should grab the information from my controller (it's hooked up correctly. I've stepped through that and it has populated the right information) and place them in my span:
<tr class="p_la" id="comments-form-#currentShowing.ShowingGUID" style="display:none;">
<td colspan="4" style="border-right:5px solid #DDDDDD;">
<form action="" method="post">
<span class="spanComments" cols="100" rows="5">#string.Format("{0} / {1}", #currentShowing.Comments.DateAdded, #currentShowing.Comments.CommentsValue)</span>
<br />
Close
</form>
</td>
</tr>
Unfortunately, when I click on my hyperlink, it only populates the first span with the first span's information. Works great for the first span but when you click on the hyperlink in the second, third, fourth, etc item, they will only open up the first span with the first span's information.
The code should populate each successive span with its own information.
My JQuery was off. It needed this to be changed:
$(".Read-Showing-Comment-Cancel").live('click', function (e) {
var guid = $(this).data("guid");
e.preventDefault();
var f = $('#comments-form-' + guid).slideUp();
$('comments-text-' + guid).empty();
$('comments-text-' + guid).value = "";
$(this).parent("form").parent("td").parent("tr").hide();
$('comments-sendlink-' + guid).show();
});
$('.showComments').unbind('click').click(function (event) {
$('.ListingDisplayOptions').hide();
var showGuid = $(this).attr('rel');
$(this).parent("td").parent("tr").next('#comments-form-' + showGuid).show();
$(this).attr('id', 'comments-sendlink-' + showGuid);
event.preventDefault();
});