I am facing small problem here. here it comes all the output. But if I delete those it will delete from database also. I want to close the content only from html page rather deleting it from database.
I am using javascript of that. Any help will be greatly helpful for me.
HTML
<html>
<head>
<meta charset="utf-8">
<title>My Parse App</title>
<meta name="description" content="My Parse App">
<meta name="viewport" content="width=device-width">
<!-- <link rel="stylesheet" href="css/reset.css">-->
<!-- <link rel="stylesheet" href="css/styles.css">-->
<!--
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-latest.js"></script>
<style>
/* my CSS here */
</style>
</head>
<body bgcolor="#45a049">
<div>
<form id=post-form>
<label for="fname">First Name :</label>
<input type="text" id="post-fname" name="firstname"><br>
<label for="lname">Last Name :</label>
<input type="text" id="post-lname" name="lastname"><br>
<label for="image">Select Image :</label>
<input type="file" id="post-image" ><br>
<input type="submit" value="Submit">
</form>
</div>
<list id="list-posts" style="list-style-type:circle; width:50%" border="2" cellspacing="1" cellpadding="100" >
</list>
<script type="text/javascript">
/* my JS here */
</script>
</body>
</html>
CSS
input[type=text],
select {
width: 50%;
/*align-content:center;*/
align-self: center;
padding: 5px 20px;
margin: 30px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type=file],
select {
/*padding: 20px 5px;*/
padding-right: -5px;
padding-left: 50px;
margin: 20px 10px;
}
input[type=submit] {
width: 40%;
/*align-self: center;*/
background-color: #4CAF50;
color: white;
padding: 7px 30px;
/*align:center;*/
margin: 20px 10px;
margin-left: 5px;
margin-right: 5px;
text-align: center;
border: none;
border-radius: 10px;
cursor: pointer;
}
input[type=submit]:hover {
background-color: #45a049;
}
div {
border-radius: 10px;
background-color: #f2f2f2;
background-position: center;
background-size: contain;
/*background-position: 30px 60px;*/
position: absolute;
padding: 10px 10px;
margin: 80px 500px;
text-align: center;
align-self: center;
left=50%;
top=50%;
}
JS
Parse.initialize("", "");
var Post = Parse.Object.extend("UpdateDelete");
$("#post-form").submit(function(event) {
event.preventDefault();
var Firstname = $("#post-fname").val();
var Lastname = $("#post-lname").val();
var Image = $("#post-image").val();
var new_post = new Post;
new_post.set("Firstname", Firstname);
new_post.set("Lastname", Lastname);
var fileElement = $("#post-image")[0];
var filePath = $("#post-image").val();
var fileName = filePath.split("\\").pop();
console.log("sumbit for post clicked");
if (fileElement.files.length > 0) {
var file = fileElement.files[0];
var newFile = new Parse.File(fileName, file);
newFile.save({
success: function() {
console.log("Inserted");
},
error: function(file, error) {
console.log("Error");
}
}).then(function(theFile) {
new_post.set("Image", theFile);
new_post.save({
success: function() {
console.log("Image Saved");
},
error: function(error) {
console.log("Post Save with file error " + error.message);
}
});
});
} else {
new_post.save(Firstname, Lastname, {
success: function(new_post) {
console.log("All posted");
getPosts();
},
error: function(new_post, error) {
console.log("Error" + error.message);
}
});
}
});
// deleting item form list
$("#list-posts").on("click", "#delitem", function() {
close();
var id = $(this).attr("href");
console.log("ID retrieved" + id);
var query = new Parse.Query(Post);
var delobj = id;
query.equalTo("objectId", id);
query.get(delobj, {
success: function(delobj) {
delobj.destroy({});
location.reload();
console.log("Object deleted successfully");
},
error: function(delobj, error) {
console.log("error deleting");
}
});
});
function showDialog() {
$("#list-posts").on("click", "#showDialog()", function(e) {
e.preventDefault();
var x = document.getElementById("myDialog");
function showDialog() {
x.show();
}
})
}
// Retrieving
function getPosts() {
var query = new Parse.Query(Post);
query.find({
success: function(results) {
console.log("Retrieving");
var output = "";
for (var i in results) {
var Firstname = results[i].get("Firstname");
var Lastname = results[i].get("Lastname");
var id = results[i].id;
// console.log(results[i].get("file"));
var img = "";
if (results[i].get("Image")) {
var file = results[i].get("Image");
var url = file.url();
console.log("url:" + url);
img = "<img src='" + url + "' style='width:170px;height:170px; margin:20px 10px'/>";
}
output += "<li style= 'list-style-type:circle' reversed='reversed' >";
output += "<h3 id='Firstname' href='" + id + "'>" + Firstname + "</h3>";
output += "<li style= 'list-style-type:circle' reversed='reversed' >";
output += "<h3 id='Lastname' href='" + id + "' >" + Lastname + "</h3>";
output += img;
output += "<button id='delitem' href='" + id + "' style='display:inline-block; margin:20px 10px'>delete</button>";
output += "<button id='mydialog' style='display:inline-block; margin:20px 10px'>User Info</button>";
output += "<dialog id='myDialog'> This is dialog window</dialog>";
output += "<button id='modals_close' style='display:inline-block; margin:20px 10px'>Close Info</button>";
output += "</li>";
$("#list-posts").html(output);
};
},
error: function(error) {
console.log("Query Error" + error.message);
}
});
}
getPosts();
First of all: you iterate through a list of items and create HTML for every item. This HTML contains DOM elements having ID. So a single ID occurs multiple times in your HTML, which it isn't allowed. Use classes instead.
There aren't the same amount of closing <LI> tags as opening ones.
I created a fiddle from your supplied code: https://jsfiddle.net/1muc0460/
But since accessing api.parse.com is unauthorized (due to initialize fails, because we need an app-key and a js-id), we can't get pretty far with it.
There are a lot errors in it. Selectors containing special character. There are Function definitions inside function definitions with the same name. Those add event handlers, but are never called (initialized).
I started some fixing: https://jsfiddle.net/1muc0460/1/
But I gave up. I don't know what logic you were trying to go after, so it's pretty hard to repair.
I added a test item as your JS would create, but none of your buttons had any effect.
As soon as you provide proper functional code, I can update this answer.
Related
I have a dynamic HTML table created using json data. I want to create an extra column for datapicker plugin. My requirement is that when I click on a particular datapicker cell for the corresponding row, an input field should be created in that cell. When this input is clicked, the datapicker for this particular row should be invoked. I should be able to pick-up the date of my choice from the inline calender(this functionality is provided by the datapicker).In my case this date pick-up is not happening, rather this error is appearing:
Uncaught Missing instance data for this datepicker
This is the jsfiddle link to the code:
https://jsfiddle.net/0akqg9b8/3/
<html>
<head>
<meta content="text/javascript; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="https://code.jquery.com/jquery-1.11.1.min.js" integrity="sha256-VAvG3sHdS5LqTT+5A/aeq/bZGa/Uj04xKxY8KM/w9EE=" crossorigin="anonymous"></script>
<link href="https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-1.11.1.min.js" integrity="sha256-VAvG3sHdS5LqTT+5A/aeq/bZGa/Uj04xKxY8KM/w9EE=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
</head>
<body>
<div id="container">
<p class="message box"></p>
</div>
<style>
#myelement {
width: 80%;
margin: auto;
border: 0.06em solid #999;
border-spacing: 0.3em;
box-shadow: 0.7em 0.7em 0.7em #999;
background: #a1deee;
}
#myelement tr{
color: blue;
}
#myelement td {
width: 10%;
padding: 0.5em;
border: 0.1em solid #000;
font-size: 15px;
text-align: center;
cursor: pointer;
}
button {
width: 10%;
padding: 0.5em;
border: 0.1em solid #000;
font-size: 15px;
text-align: center;
cursor: pointer;
}
button:hover {
background-color: #0F5897;
border: 1px solid #0F5897;
}
</style>
<script>
var keys;
var myValue;
var myVar;
var myTableRows = [];
var html;
var table;
var c;
var myRow;
var myCol;
json = [{
ShipperID: 1,
CompanyName: "Federal Package",
Phone: "(503) 555-9931"
},
{
ShipperID: 2,
CompanyName: "United Package",
Phone: "(503) 655-7865"
},
{
ShipperID: 3,
CompanyName: "My Package",
Phone: "(508) 955-8997"
}
];
getMyData();
function getMyData() {
let myData = json[0];
let myTablehead = [];
myTablehead.push(myData);
html = '';
for (let i = 0; i < json.length; i++) {
myTableRows.push(json[i])
}
myTablehead.forEach(function(val) {
keys = Object.keys(val);
//html table starts here
html += "<table class='myTable' id=\"myelement\">"
html += "<tr>";
keys.forEach(function(key) {
html += "<th>" + key + "</th>";
});
html += "";
html += "</tr>";
});
myTableRows.forEach(function(val) {
mykeys = Object.keys(val);
//Set up the html row
html += "<tbody id=\"myRows\">"
html += "<tr class=\"thisRow\">"
for (var mykeys in val) {
myValue = val[mykeys];
html += "<td class='normalBtn'>"
html += myValue;
html += "</td>";
}
html += "<td class=\"dateBtn\">"
html += "Enter Date:";
html += "<input type = \"text\" class='datepicker-1'>"
html += "</td>";
html += "</tr>";
});
html += "</tbody>"
html += "</table>";
document.getElementsByClassName('message')[0].innerHTML += html;
}
$(".dateBtn").on('click','input',function(){
$("input").remove('.datepicker-1');
})
$.fn.timeline = function() {
return this.click(function(){
var myinput = "<input type = \"text\" class='datepicker-1' val=''></input>";
$(this).append(myinput);
var dataInstance = $( ".datepicker-1" ).datepicker();
$("input:text").val(function(n){
return dataInstance;
});
})
}
$(".dateBtn" ).timeline();
</script>
</body>
</html>
I did some changes in the code, because there was a lot of not really needed part.
var keys;
var myValue;
var myVar;
var myTableRows = [];
var c;
var myRow;
var myCol;
json = [{
ShipperID: 1,
CompanyName: "Federal Package",
Phone: "(503) 555-9931"
},
{
ShipperID: 2,
CompanyName: "United Package",
Phone: "(503) 655-7865"
},
{
ShipperID: 3,
CompanyName: "My Package",
Phone: "(508) 955-8997"
}
];
getMyData();
function generateDateInput() {
let input = $('<input>').attr({'type': 'text', 'class': 'datepicker-1'});
input.datepicker();
input.on('focus', function() {
// The datepopup activates by the focus, not by the click.
// So let's remove every input which is not in focus.
$('.myTable input:not(:focus())').remove();
}).on('click', function(event) {
// This needed to stop bubbling effect down to the tr.
event.stopPropagation();
});
return input;
}
function getMyData() {
let myData = json[0];
let myTablehead = [];
myTablehead.push(myData);
let table = '';
for (let i = 0; i < json.length; i++) {
myTableRows.push(json[i])
}
myTablehead.forEach(function(val) {
keys = Object.keys(val);
//html table starts here
table = $('<table>', document).attr({'class': 'myTable', 'id': 'myelement'});
let tr = $('<tr>');
keys.forEach(function(key) {
tr.append($("<th>").text(key));
});
table.append(tr);
});
let tbody = $('<tbody>').attr('id', 'myRows');
myTableRows.forEach(function(val) {
mykeys = Object.keys(val);
//Set up the html row
let tr = $('<tr>').attr('class', 'thisRow');
for (var mykeys in val) {
tr.append(
$('<td>').attr('class', 'normalBtn').text(val[mykeys])
);
}
tr.append(
$('<td>').attr('class', 'dateBtn').text('Enter Date:').append(generateDateInput())
).on('click', function() {
$('td:eq(3)', this).append(generateDateInput());
// After append we set the focus to the input field from the current row. This
// will only work in the current form until there's only one input field.
$('input', this).focus();
});
tbody.append(tr);
});
table.append(tbody);
$('#container').append(table);
}
#myelement {
width: 80%;
margin: auto;
border: 0.06em solid #999;
border-spacing: 0.3em;
box-shadow: 0.7em 0.7em 0.7em #999;
background: #a1deee;
}
#myelement td {
width: 10%;
padding: 0.5em;
border: 0.1em solid #000;
font-size: 15px;
text-align: center;
cursor: pointer;
}
button {
width: 10%;
padding: 0.5em;
border: 0.1em solid #000;
font-size: 15px;
text-align: center;
cursor: pointer;
}
button:hover {
background-color: #0F5897;
border: 1px solid #0F5897;
}
<html>
<head>
<meta content="text/javascript; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="https://code.jquery.com/jquery-1.11.1.min.js" integrity="sha256-VAvG3sHdS5LqTT+5A/aeq/bZGa/Uj04xKxY8KM/w9EE=" crossorigin="anonymous"></script>
<link href="https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-1.11.1.min.js" integrity="sha256-VAvG3sHdS5LqTT+5A/aeq/bZGa/Uj04xKxY8KM/w9EE=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.min.js"></script>
</head>
<body>
<div id="container">
<p class="message box"></p>
</div>
</body>
</html>
I have text-field and button. When the button is clicked, it should generate the text-field with emoji picker enabled. I can see the button but the emoji picker is not getting enabled.
My code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="js/jquery.emojiFace.js"></script>
</head>
<body>
<form class="col-sm-12">
<div id="textfields">
<div id="entireText0">
<div class="form-row">
<div class="col-sm-10">
<div class="form-group">
<label for="textarea0">Question 1</label>
<!--<textarea class="form-control" id="textarea0" rows="2"></textarea>-->
<div class="containers">
<textarea rows="3" id="textarea0" class="form-control faceText" spellcheck="false"></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
<br><br>
<button type="button" id="button0" class="btn btn-primary" onclick="addTextFields();">Add Questions</button>
</form>
<script>
$(function() {
$('.faceText').emojiInit({
fontSize: 20,
success: function(data) {},
error: function(data, msg) {}
});
});
textareaid = 0;
addButtonid = 0;
function addTextFields() {
textareaid++;
addButtonid++;
var objTo = document.getElementById('textfields');
var divtest = document.createElement("div");
divtest.innerHTML = "<div id='textfields'><div id='entireText" + addButtonid + "'> <div class='form-row'> <div class='col-sm-10'> <div class='form-group'> <label for='textarea" + addButtonid + "'>Question " + (addButtonid + 1) + "</label> <div class='containers'><textarea rows='3' id='textarea" + addButtonid + "' class='form-control faceText' spellcheck='false'></textarea></div></div></div></div></div></div>";
objTo.appendChild(divtest);
$('.faceText').emojiInit();
}
</script>
</body>
</html>
EmojiPicker code(jquery.emojiFace.js):
var option;
(function(c) {
var d = "ƒ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ Φ Χ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς σ τ υ φ χ ψ ω ϑ ϒ ϖ • … ′ ″ ‾ ⁄ ℘ ℑ ℜ ™ ℵ ← → ↓ ↔ ↵ ⇐ ⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ ∈ ∉ ∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ ⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ ⌉ ⌊ ⌋ 〈 〉 ◊ ♠ ♣ ♥ ♦".split(" ");
c.fn.emojiInit = function(b) {
option = c.extend({
targetId: "",
fontSize: 14,
faceList: d,
success: function(a) {},
error: function(a, b) {}
}, b);
option.targetId = c(this).attr("id");
b = c(this);
if (void 0 == b || 0 >= b.length) option.error(null, "target object is undefined");
else {
option.fontSize = 20 < option.fontSize ? 20 : option.fontSize;
option.fontSize = 14 > option.fontSize ? 14 : option.fontSize;
var a = "";
option.faceList.forEach(function(b) {
a += "<div onclick='insertAtCaret(\"" + option.targetId + '","' + b + "\",this)' style='font: normal normal normal 14px/1 FontAwesome;cursor: pointer;padding:3px;font-size:" + option.fontSize + "px;width: 20px;display: inline-block;text-align:center;'>" + b + "</div>";
});
b.css("width", "100%");
b.css("padding", "5px 30px 5px 5px");
b.css("box-sizing", "border-box");
b.css("resize", "vertical");
b.parent().css("position", "relative");
b.after("<div id='faceEnter' onclick='showFaceBlock()' style='padding: 5px;position: absolute;right: 0;top: 0;cursor: pointer;font: normal normal normal 14px/1 FontAwesome;'>+</div>");
b.after("<div id='faceBlock' style='background:rgb(216, 216, 216);border-radius: 12px;display: none;position: absolute;border: 1px solid #e2e2e2;padding: 5px;right: -150px;top: 25px;width: 300px;'>" + a + "</div>");
c(document).click(function() {
c("#faceBlock").hide();
});
c("#faceBlock").click(function(a) {
a.stopPropagation();
});
c("#faceEnter").click(function(a) {
a.stopPropagation();
})
}
}
})(jQuery);
function showFaceBlock() {
$("#faceBlock").show();
}
function insertAtCaret(c, d, b) {
try {
$("#faceBlock").hide();
var a = $("#" + c).get(0);
if (document.all && a.createTextRange && a.caretPos) {
var e = a.caretPos;
e.text = "" == e.text.charAt(e.text.length - 1) ? d + "" : d;
} else if (a.setSelectionRange) {
var f = a.selectionStart,
h = a.selectionEnd,
k = a.value.substring(0, f),
l = a.value.substring(h);
a.value = k + d + l;
a.focus();
var g = d.length;
a.setSelectionRange(f + g, f + g);
a.blur();
} else a.value += d;
option.success(b);
} catch (m) {
option.error(b, m);
}
};
I am using this emoji picker:
https://www.jqueryscript.net/text/Unicode-Emoji-Picker-jQuery-emojiFace.html
I can enable the emojipicker for first text-area. But, cannot do it when the text-area is dynamically generated. For instance, "Question 2" text-area is dynamically generated one.
Now, I can see something like this.
You have to loop through each html element with class faceText. Try this;
$('.faceText').each(function(i,v){
$(this).emojiInit({
fontSize: 20,
success: function(data) {},
error: function(data, msg) {}
});
});
Moved some scripts here and there, I didn't notice that addTextFields is being called when a button is clicked;
<script>
textareaid = 0;
addButtonid = 0;
function addTextFields() {
textareaid++;
addButtonid++;
var objTo = document.getElementById('textfields');
var divtest = document.createElement("div");
divtest.innerHTML = "<div id='textfields'><div id='entireText" + addButtonid + "'> <div class='form-row'> <div class='col-sm-10'> <div class='form-group'> <label for='textarea" + addButtonid + "'>Question " + (addButtonid + 1) + "</label> <div class='containers'><textarea rows='3' id='textarea" + addButtonid + "' class='form-control faceText' spellcheck='false'></textarea></div></div></div></div></div></div>";
objTo.appendChild(divtest);
$('.faceText').each(function(i,v){
if($(this).hasClass('done')){
$(this).emojiInit({
fontSize: 20,
success: function(data) {},
error: function(data, msg) {}
});
$(this).addClass('done');
}
});
}
</script>
Here is your own jquery based emoji picker
<div id="con">
<!-- Component -->
<div class="emojiPicker">
<div class="emojis">
<div class="emojiFrame"><span class="emoji">š</span></div>
<div class="emojiFrame"><span class="emoji">š</span></div>
</div>
</div>
<!-- Sample text input -->
<div id="text">
<textarea id="target"></textarea>
</div>
</div>
Script
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".emojiFrame").click(function(){
// target, where emoji will be placed
var target = $("#target");
//emoji will be placed always at end of textbox
target.text(target.text() + $(this).text());
})
})
</script>
Style
<style>
/* page */
body{
box-sizing: border-box;
min-height: 100vh;
margin: 0;
background-color: rgb(202, 193, 193);
}
#con{
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
textarea {
resize: none;
margin-top: 10px;
box-sizing: content-box;
width: calc(100% - 6px);
border: 1px solid black;
}
/* component */
.emojiPicker{
/* 5 emojis in row */
/* width: 212px; */
/* 6 emojis in row */
/* width: 254px; */
/* 7 emojis in row */
width: 296px;
border: 1px solid #0d8cfc;
background-color: aliceblue;
-webkit-box-shadow: 1px 1px 5px -1px rgba(0,0,0,0.75);
-moz-box-shadow: 1px 1px 5px -1px rgba(0,0,0,0.75);
box-shadow: 1px 1px 5px -1px rgba(0,0,0,0.75);
}.emojis{
width: 100%;
display: flex;
flex-wrap: wrap;
}.emojiFrame{
box-sizing: content-box;
user-select: none;
text-align: center;
cursor: pointer;
width: 30px;
font-size: 21px;
padding: 3px;
margin: 3px;
background-color: transparent;
transform: scale(0.9);
transition: background-color 0.2s, transform 0.1s;
}.emojiFrame:hover{
background-color: #0d8cfc;
}.emojiFrame:active{
background-color: #4babff;
transform: scale(0.95);
}
</style>
I have an input box which you can enter items, submit it, and create a box with it's own delete button to remove it. Problem is, after deleting a number of boxes, and then entering something new in input, all the previous items that were deleted get reloaded, including the new item.
How can I prevent reloading of already removed boxes?
Fiddle (Stacksnippets do not allow submit)
This is my Html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Shopping List Example</title>
<link rel="stylesheet" type="text/css" href="css-list.css">
</head>
<div id="centerPanel">
<form class="my-list-form">
<input type="text" class="input" name="add-input" id="add-input">
<button class="add-button" id="submitBtn">Add</button>
</form>
<ul class="my-list-ul"></ul>
</div>
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<script src="js-list.js"></script>
</html>
JS:
var state = {items:[]};
var addItem = function(state, item)
{
state.items.push(item);
}
var displayItem = function(state, element){
var htmlItems = state.items.map(function(item){
return '<li class="box">' + item + '</br><button class="divBtns" id="deleteBtn">Delete</button>' + '</li>';
});
element.html(htmlItems);
}
//After deleting items, this button again loads all items that have been created since
//the page loaded up, including the new item.
//Needs to be fixed to not reload the deleted items
$('.my-list-form').submit(function(event){
event.preventDefault();
addItem(state, $('.input').val());
displayItem(state, $('.my-list-ul') );
/* alert(state.items[1]); shows that the items array holds everything that is turned into a div*/
})
$(document).ready(function(e){
$('ul').on('click', '#deleteBtn', function(event){
var rmvButton = $(this).closest('li');
rmvButton.remove();
});
})
css:
* {
font-family: sans-serif;
font-weight: normal;
}
#centerPanel {
margin-left: 50px;
margin-top: 50px;
padding-left: 10px;
}
h1 {
font-size: 34px;
}
.font-size {
font-size: 17px;
}
#add-input {
height:25px;
width: 190px;
font-size: 16px;
}
button {
font-size: 17px;
}
#submitBtn {
height: 30px;
width: 85px;
}
.divBtns {
margin-top: 10px;
}
.box {
border: 1px solid black;
border-color: grey;
width: 153px;
height: 65px;
padding: 20px;
font-style: italic;
font-size: 22px;
margin-bottom:10px;
margin-right: 10px;
}
ul {
list-style-type: none;
margin-left:-40px;
color: grey;
}
li {
float: left;
}
It appears you never remove anything from the state object, which is added to every time you run addItem().
You'd need a way to remove a specific item from this array, probably by getting the index of the li to delete and doing
state.items.splice(index, 1);
Store the index as a data attribute on the button:
var displayItem = function(state, element){
var i = 0;
var htmlItems = state.items.map(function(item){
return '<li class="box">' + item + '</br><button class="divBtns" ' +
'id="deleteBtn" data-index="' + (i++) + '">Delete</button>' + '</li>';
});
element.html(htmlItems);
}
Then you can get it in the click callback
var index = $(this).data('index');
You can update state to solve this problem.
It's my code:
...
var deleteItem = function(state, itemId) {
var index = 0;
var isFind = state.items.some(function(item, i) {
if (item.id == itemId) {
index = i;
return true;
} else {
return false;
}
});
if (isFind) {
state.items.splice(index, 1);
}
}
...
$(document).ready(function(e){
$('ul').on('click', '#deleteBtn', function(event){
...
// update state
deleteItem(state, $(this).parent().data('id'));
});
})
https://jsfiddle.net/q483cLp9/
Masonry is not working with my dynamic content, I don't know why. I don't think it's a bug on my side, at least I've looked at the code for a few hours now and I can't find anything that isn't working.
//reads listbox.php and cycles through the array calling createbox
function listboxs() {
$.ajax({
url: '_php/listbox.php',
success: function (output) {
var jsonArray = $.parseJSON(output);
$.each(jsonArray, function (i, box) {
createbox(box.id, box.name, box.link, box.description, box.tags);
});
}
});
}
//create the code for 1 box
function createbox(id, name, link, description, tags) {
var boxHtml = "",
tagsHtml = "",
descriptionHtml = "";
boxHtml = '' + '<div class="box" id="' + id + '">' + '<div class="boxinfo">' + '<label class="boxname">' + name + '</label>';
$.each(tags, function (i, tag) {
tagsHtml += '<label class="boxtag">' + ((!tag.name) ? tags[i] : tag.name) + '</label>';
});
//if(description.trim().length > 0){
descriptionHtml = '<textarea class="boxdescription" readonly rows="1">' + description + '</textarea>';
//}
boxHtml += tagsHtml + '</div>' + descriptionHtml + '</div>';
$content.html($content.html() + boxHtml);
}
Below is the simplified HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="_css/index.css" />
<link href='http://fonts.googleapis.com/css?family=Marck+Script' rel='stylesheet'
type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Rosario' rel='stylesheet'
type='text/css'>
<script src="_resources/jquery-2.0.3.min.js" type="text/javascript" language="javascript"></script>
<script src="_resources/masonry.pkgd.min.js"></script>
<script type="text/javascript" language="javascript">
$('#content').masonry();
</script>
</head>
<body>
<div id="content" class="js-masonry"></div>
</body>
</html>
I know that I don't need the inline javascript calling masonry on content but it's one of my many tests...
Below is part of the CSS:
#content{
padding: 15px;
min-height: 400px;
}
/*
################################
box
*/
.box{
border: 1px solid black;
float: left;
padding: 5px;
background: #F0F0F0;
margin-left: 5px;
margin-bottom: 5px;
}
.boxinfo{
border-bottom: 1px solid black;
}
.boxname{
font-weight: bold;
}
.boxdescription{
border: none;
outline: none;
background: white;
overflow: hidden;
}
.boxtag{
margin-left: 5px;
}
#boxdecoy{
height: 45px;
}
.boxname, .boxtag, .boxdescription{
font-family: 'Rosario', sans-serif;
font-size: 12px;
}
.boxlink{
text-decoration: none;
color: black;
}
.boxlink:hover{
text-decoration: underline;
}
I'm really going crazy with all of it because I tested creating boxes by hand (this means writting in the html) in content, and if i do masonry works fine. If i create them through the function that you see there it doesn't work... i call listboxs right in the begining of the javascript file after I declare all my vars...
Hope I was clear and you can help me.
You should use appended method. From docs:
Add and lay out newly appended item elements.
Look at this jsfiddle
Try to change your code to
boxHtml += tagsHtml +
'</div>' +
descriptionHtml +
'</div>';
var $boxHtml = $(boxHtml);
$content.append($boxHtml).masonry('appended', $boxHtml);
Adding up to Grin's answer:
You should also apply data-masonry-options='{ "columnWidth": 200, "itemSelector": ".item" }' to your #container.
<div id="content" class="js-masonry" data-masonry-options='{ "columnWidth": 200, "itemSelector": ".item" }'></div>
Like so. It might help with your comment response. I don't have the rep to answer as a comment.
I have a problem with a piece of JavaScript code - a snippet is shown below. Basically the code is issuing a getJSON request to a rails controller and then should process the returned data, building an HTML table and then embedding it in a Div. It doesn't work. I have tried stepping through it with alerts, etc - all to no avail. The data is retrieved from the rails controller and I can verify that. I have placed the piece of code that issues and processes the getJSON request in the niddle of the Rails Welcome page - this is not all mine. The code is below:
<!DOCTYPE html>
<html>
<head>
<title>Ruby on Rails: Welcome aboard</title>
<style type="text/css" media="screen">
body {
margin: 0;
margin-bottom: 25px;
padding: 0;
background-color: #f0f0f0;
font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
font-size: 13px;
color: #333;
}
h1 {
font-size: 28px;
color: #000;
}
a {color: #03c}
a:hover {
background-color: #03c;
color: white;
text-decoration: none;
}
#page {
background-color: #f0f0f0;
width: 750px;
margin: 0;
margin-left: auto;
margin-right: auto;
}
#content {
float: left;
background-color: white;
border: 3px solid #aaa;
border-top: none;
padding: 25px;
width: 500px;
}
#sidebar {
float: right;
width: 175px;
}
#footer {
clear: both;
}
#header, #about, #getting-started {
padding-left: 75px;
padding-right: 30px;
}
#header {
background-image: url("images/rails.png");
background-repeat: no-repeat;
background-position: top left;
height: 64px;
}
#header h1, #header h2 {margin: 0}
#header h2 {
color: #888;
font-weight: normal;
font-size: 16px;
}
#about h3 {
margin: 0;
margin-bottom: 10px;
font-size: 14px;
}
#about-content {
background-color: #ffd;
border: 1px solid #fc0;
margin-left: -55px;
margin-right: -10px;
}
#about-content table {
margin-top: 10px;
margin-bottom: 10px;
font-size: 11px;
border-collapse: collapse;
}
#about-content td {
padding: 10px;
padding-top: 3px;
padding-bottom: 3px;
}
#about-content td.name {color: #555}
#about-content td.value {color: #000}
#about-content ul {
padding: 0;
list-style-type: none;
}
#about-content.failure {
background-color: #fcc;
border: 1px solid #f00;
}
#about-content.failure p {
margin: 0;
padding: 10px;
}
#getting-started {
border-top: 1px solid #ccc;
margin-top: 25px;
padding-top: 15px;
}
#getting-started h1 {
margin: 0;
font-size: 20px;
}
#getting-started h2 {
margin: 0;
font-size: 14px;
font-weight: normal;
color: #333;
margin-bottom: 25px;
}
#getting-started ol {
margin-left: 0;
padding-left: 0;
}
#getting-started li {
font-size: 18px;
color: #888;
margin-bottom: 25px;
}
#getting-started li h2 {
margin: 0;
font-weight: normal;
font-size: 18px;
color: #333;
}
#getting-started li p {
color: #555;
font-size: 13px;
}
#sidebar ul {
margin-left: 0;
padding-left: 0;
}
#sidebar ul h3 {
margin-top: 25px;
font-size: 16px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
}
#sidebar li {
list-style-type: none;
}
#sidebar ul.links li {
margin-bottom: 5px;
}
</style>
<script src="/javascripts/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
function about() {
info = document.getElementById('about-content');
if (window.XMLHttpRequest)
{ xhr = new XMLHttpRequest(); }
else
{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
xhr.open("GET","rails/info/properties",false);
xhr.send("");
info.innerHTML = xhr.responseText;
info.style.display = 'block'
}
</script>
<script type="text/javascript">
alert('Start of JSON Routine');
$(document).ready( function() {
alert('Attach a JQuery Live event to the button');
$('#getdata-button').live('click', function() {
alert("Get JSON data");
$.getJSON('http://0.0.0.0:3000/getjson/1', function(data) {
alert('Processing returned JSON data');
var tmp = '<table border=1>';
for (i=0;i<data.length;i++)
{
tmp = tmp +'<tr>';
tmp = tmp + '<td>' + data[i].book.price + '</td>';
tmp = tmp + '<td>' + data[i].book.title + '</td>';
tmp = tmp + '<td>' + data[i].book.author + '</td>';
tmp = tmp + '<td>' + data[i].book.ISBN + '</td>';
tmp = tmp + '<td>' + data[i].book.yearPublished + '</td>';
tmp = tmp + '<td>' + data[i].book.volume + '</td>';
tmp = tmp + '<td>' + data[i].book.publisher + '</td>';
tmp = tmp + '<td>' + data[i].book.edition + '</td>';
tmp = tmp + '<td>View</td>';
tmp = tmp + '</tr>';
}
tmp = tmp + '</table>';
alert('About to insert Table into DOM in content Div');
$('#showdata').html(tmp);
}); //getJSON end
}); //getdata-button end
}); //document.ready end
alert('End of JSON routine');
</script>
</head>
<body>
<div id="page">
<div id="sidebar">
<ul id="sidebar-items">
<li>
<h3>Browse the documentation</h3>
<ul class="links">
<li>Rails API</li>
<li>Ruby standard library</li>
<li>Ruby core</li>
<li>Rails Guides</li>
</ul>
</li>
</ul>
</div>
Get JSON Data
<script>alert("Before the JMC div");</script>
<div id="showdata">JMC</div>
<script>alert("Past the JMC div");</script>
<div id="content">
<h1>Welcome aboard</h1>
<h2>Youāre riding Ruby on Rails!</h2>
</div>
<div id="about">
<h3>About your applicationās environment</h3>
<div id="about-content" style="display: none"></div>
</div>
<div id="getting-started">
<h1>Getting started</h1>
<h2>Hereās how to get rolling:</h2>
<ol>
<li>
<h2>Use <code>rails generate</code> to create your models and controllers</h2>
<p>To see all available options, run it without parameters.</p>
</li>
<li>
<h2>Set up a default route and remove or rename this file</h2>
<p>Routes are set up in config/routes.rb.</p>
</li>
<li>
<h2>Create your database</h2>
<p>Run <code>rake db:migrate</code> to create your database. If you're not using SQLite (the default), edit <code>config/database.yml</code> with your username and password.</p>
</li>
</ol>
</div>
</div>
<div id="footer"> </div>
</div>
</body>
</html>
Here is the JSON data I get back when I just invoked the URL/ Controller action directly from the browser:
[
{
"book":{
"price":"25.52",
"created_at":"2011-10-27T22:35:04Z",
"ISBN":"",
"author":"Obie Fernandez",
"title":"Rails 3 Way, The (2nd Edition)",
"updated_at":"2011-10-27T22:35:04Z",
"yearPublished":"2010",
"id":1,
"publisher":"Addison-Wesley",
"volume":"2",
"edition":"second edition"
}
},
{
"book":{
"price":"23.94",
"created_at":"2011-10-27T22:39:37Z",
"ISBN":"",
"author":"Michael Hartl",
"title":"Ruby on Rails 3 Tutorial: Learn Rails by Example",
"updated_at":"2011-10-27T22:39:37Z",
"yearPublished":"2010",
"id":2,
"publisher":"Addison-Wesley",
"volume":"",
"edition":"first edition"
}
},
{
"book":{
"price":"24.97",
"created_at":"2011-10-27T22:42:42Z",
"ISBN":"",
"author":"Cloves Carneiro Jr. and Rida Al Barazi",
"title":"Beginning Rails 3 ",
"updated_at":"2011-10-27T22:42:42Z",
"yearPublished":"2009",
"id":3,
"publisher":"Apress",
"volume":"",
"edition":"first edition"
}
}
]
Anything else that might be useful. The Rails logs show the request being handled correctly.
When I step through the script, the alerts come up in a starnge sequence:
THe first alert I get is "Here at start of JSON Routine", followed by "Finished document ready routine" and then "Attach a JQuery Live event to the button". I then click the button for getdata and then a # appears at the end of the URL and then nothing.
MOved the script into the head - same outcome.
SWitched #content to #showdata - same outcome.
Final Edit:
The problem is solved thanks to the input of many people.
There were a number of issues, but the final issue was a same origin error in that the URL on the getJSON request was different to the URL making the request. The request had 0.0.0.0:3000/getjson/1 whereas the requesting URL was localhost:3000/getjson/1. Very hard to spot and the lack of return / status info with getJSON made it more difficult. Anyway thanks is due to all contributors, who all made valid contributions. I hope I have the expertise to contribute myself someday.
This is most related to same origin policy (cross domain blocking) and can be resolved by using a JSONP call. Add a ?callback=? to the end of the URL:
$(document).ready( function() {
alert('Attach a JQuery Live event to the button');
$('#getdata-button').live('click', function() {
$.getJSONP('http://0.0.0.0:3000/getjson/1?callback=?, function(data) {
// ... Omiting for brevity
$('#content').html(tmp);
});
});
});
Alright Joe, you need to start with the simplest case possible... clean up all of your HTML and get rid of everything that you do not need. I tested this and verified that it works on my local Rails server.
I mocked up the Rails controller action to return your JSON data using:
def getjson
json_data = '[{ "book": { "price": 18.75, "title": "Moby Dick", "author": "Herman Melville", "ISBN": "0393972836", "yearPublished": 2001, "volume": 1, "publisher": "W. W. Norton & Company", "edition": "2nd Edition" }}]'
render :json => json_data, :status => :ok
end
You shouldn't need to change your Rails controller code since you said it was working. I just wanted to show you how I mocked it up for your future reference.
Now, replace the contents of your HTML file with this:
<!DOCTYPE html>
<html>
<head>
<title>JSON Test example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#getdata-button').live('click', function() {
// clear out the old data:
$('#content').html('');
alert("Getting JSON data");
$.ajax({
dataType: 'json',
type: 'GET',
url: '/getjson/1',
success: function(json) {
console.log(json);
alert('Processing returned JSON data');
var tmp = '<table border=1>';
for (i = 0; i < json.length; i++) {
tmp = tmp + '<tr>';
tmp = tmp + '<td>' + json[i].book.price + '</td>';
tmp = tmp + '<td>' + json[i].book.title + '</td>';
tmp = tmp + '<td>' + json[i].book.author + '</td>';
tmp = tmp + '<td>' + json[i].book.ISBN + '</td>';
tmp = tmp + '<td>' + json[i].book.yearPublished + '</td>';
tmp = tmp + '<td>' + json[i].book.volume + '</td>';
tmp = tmp + '<td>' + json[i].book.publisher + '</td>';
tmp = tmp + '<td>' + json[i].book.edition + '</td>';
tmp = tmp + '<td>View</td>';
tmp = tmp + '</tr>';
}
tmp = tmp + '</table>';
alert('About to insert the following data into DOM: ' + tmp);
// Show the div we are looking for in the browser's console
console.log($('#content'));
$('#content').html(tmp);
},
error: function(response) {
alert('There was an error: ' + response.status);
}
}); // $.ajax end
}); //getdata-button end
}); //document.ready end
</script>
</head>
<body>
Get JSON Data
<br/><br/>
<div id="content">The data will be placed here.</div>
</body>
</html>
Notice that I am using the $.ajax method which allows me to specify an error handler callback. I would recommend using this way of doing things until you become more familiar with jQuery and feel confident that you can start using the other AJAX helpers.
I hope this helps!
Your page is being refreshed and the data is likely getting dropped. Try:
$('#getdata-button').live('click', function(evt) {
evt.preventDefault();
}
$('#content') doesn't seem to exist.
EDIT
After another look, it seems to problem hinges on the button click event not firing. Since this is added via live, and as another user has posted, works on jsfiddle: I wonder what version of jQuery you are using? Looks like it could be very old indeed. Try upgrading to a newer version.