Angular JS ui-grid within accordion cannot display data - javascript

Friends, I'm trying to build an accordion dynamically with an ui-grid inside it. The problem i'm having is that i cannot see any data in my grids. I need a second pair of eyes to see what i'm doing wrong.
Here is my HTML:
<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/ng-grid/2.0.11/ng-grid.css" />
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css">
<script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
</head>
<body>
<div ng-controller="AccordionDemoCtrl" id="akkordion"></div>
</body>
</html>
And here is my JS:
//noprotect
var app = angular.module('myApp',['ui.bootstrap','ui.grid', 'ui.grid.cellNav', 'ui.grid.edit'] );
var json = '[{"name":"Service Request","isOpen":"false","groups":[{"name":"Header","isOpen":"false","grids":[{"data":"myData"}]},{"name":"Details 1","isOpen":"false"}]},{"name":"Service Confirmation","isOpen":"false","groups":""}]';
var mydata = '[{"firstName":"Cox","lastName":"Carney","company":"Enormo","employed":true},{"firstName":"Lorraine","lastName":"Wise","company":"Comveyer","employed":false},{"firstName":"Nancy","lastName":"Waters","company":"Fuelton","employed":false}]';
var ary = JSON.parse(json);
var accView = "";
var accLevel = 0;
var accName = "groups";
var gridName = "grid";
var dataName = "{ data: mydata }";
var accBuild = function (obj){
if (typeof(obj)==="object"){
for (var i in obj) {
accView = accView + "<accordion close-others=\"true\">";
accView = accView + "<accordion-group ng-repeat=\""+(accName+accLevel);
if(accLevel>0){
accView = accView + " in "+accName+".groups\" is-open=\"{{"+(accName+accLevel)+".isOpen}}\"><accordion-heading><div ng-click=\"opened("+(accName+accLevel)+".name)\">{{"+(accName+accLevel)+".name}}</div></accordion-heading></div>";
accView = accView + "<div id='" +(gridName+accLevel) + "'";
accView = accView + " ui-grid='" + dataName + "'></div>";
}else{
accView = accView + " in "+accName+"\" is-open=\"{{"+(accName+accLevel)+".isOpen}}\"><accordion-heading><div ng-click=\"opened("+(accName+accLevel)+".name)\">{{"+(accName+accLevel)+".name}}</div></accordion-heading>";
}
accName = accName+accLevel;
accLevel = accLevel + 1;
accBuild(obj[i].groups);
accView = accView + "</accordion-group></accordion>";
}
}
};
accBuild(ary);
//console.log(accView);
document.all.akkordion.innerHTML=accView;
function AccordionDemoCtrl($scope) {
$scope.opened = function (groupname) {
console.log("Opened group: "+ groupname);
};
$scope.groups = ary;
}

Sorry, I cant comment.
You need to add your Controller to your module, like #user2341963 said.
app.controller('AccordionDemoCtrl', AccordionDemoCtrl);
And if you want to access your data like this
ui-grid="{ data: mydata }"
mydata has to be bound to $scope in your Controller for Angular to find/access it. See the Updated JSBin .
app.controller('AccordionDemoCtrl', AccordionDemoCtrl);
function AccordionDemoCtrl($scope) {
$scope.mydata = [
{
test: 'test',
other: 'other'
},
{
test: 'test',
other: 'other'
},
{
test: 'test',
other: 'other'
},
];
$scope.opened = function (groupname) {
console.log("Opened group: "+ groupname);
};
$scope.groups = ary;
}

Related

Read formatted text from form through javascript

class Storedata {
constructor(name, desc, price, qty) {
this.name = name;
this.desc = desc;
this.price = price;
this.qty = qty;
}
}
var arr = [];
var btnform = document.getElementById('clicktoadd');
var btnlist = document.getElementById('clicktoshow');
var rem = document.getElementById('main');
var cancelform;
var submit;
function addData() {
var proname = document.getElementById("inpname");
var prodesc = document.getElementById("inpdesc");
var propric = document.getElementById("inpprice");
var proqty = document.getElementById("inpqty");
arr.push(new Storedata(proname.value, prodesc.value, propric.value, proqty.value));
}
function showlist() {
var data = document.createElement('table');
data.setAttribute("id", "data");
data.innerHTML += "<tr><th>Product Name</th><th>Description</th><th>Price</th><th>Quantity</th><th></th></tr>";
for (let i = 0; i < arr.length; i++) {
data.innerHTML += ("<tr><td>" + arr[i].name + "</td><td>" + arr[i].desc + "</td><td>" + arr[i].price + "</td><td>" + arr[i].qty + "</td><td><button id=\"delete" + i + "\">Delete</button></tr>");
};
document.getElementById('listing').appendChild(data);
document.getElementById('showbutton').removeAttribute("hidden", false);
}
function removelist() {
var data = document.getElementById("data");
data.parentNode.removeChild(data);
}
function addformtopage() {
var form = document.createElement('div');
form.setAttribute("id", "remform");
form.innerHTML += "<div id=\"lblname\">Product Name:</div><input id=\"inpname\" type=\"text\"><div id=\"chkname\" hidden=\"true\">Enter a Product Name</div><div id=\"lbldesc\">Description:</div><textarea id=\"inpdesc\" rows=\"10\" cols=\"35\"></textarea><div id=\"chkdesc\" hidden=\"true\">Enter a Product Desciption</div><div id=\"lblprice\">Price in INR:</div><input id=\"inpprice\" type=\"number\"><div id=\"chkprice\" hidden=\"true\">Enter a Product Price</div><div id=\"lblqty\">Quantity:</div><input id=\"inpqty\" type=\"number\"><div id=\"chkqty\" hidden=\"true\">Enter a Product Quantity</div><br><br><button id=\"submitproduct\">Submit</button><button id=\"cancel\">Cancel</button>";
document.getElementById('panel').appendChild(form);
cancelform = document.getElementById('cancel');
submit = document.getElementById('submitproduct');
}
function validateform() {
var proname = document.getElementById("inpname");
var prodesc = document.getElementById("inpdesc");
var propric = document.getElementById("inpprice");
var proqty = document.getElementById("inpqty");
var errname = document.getElementById("chkname");
var errdesc = document.getElementById("chkdesc");
var errpric = document.getElementById("chkprice");
var errqty = document.getElementById("chkqty");
if ((proname.value) && (prodesc.value) && (propric.value) && (proqty.value)) {
errname.setAttribute("hidden", true);
errdesc.setAttribute("hidden", true);
errpric.setAttribute("hidden", true);
errqty.setAttribute("hidden", true);
return true;
}
if (proname.value) {
errname.setAttribute("hidden", true);
}
if (prodesc.value) {
errdesc.setAttribute("hidden", true);
}
if (propric.value) {
errpric.setAttribute("hidden", true);
}
if (proqty.value) {
errqty.setAttribute("hidden", true);
}
if (!proname.value) {
errname.removeAttribute("hidden", false);
}
if (!prodesc.value) {
errdesc.removeAttribute("hidden", false);
}
if (!propric.value) {
errpric.removeAttribute("hidden", false);
}
if (!proqty.value) {
errqty.removeAttribute("hidden", false);
}
return false;
}
function clearform() {
var proname = document.getElementById("inpname");
var prodesc = document.getElementById("inpdesc");
var propric = document.getElementById("inpprice");
var proqty = document.getElementById("inpqty");
proname.value = null;
prodesc.value = null;
propric.value = null;
proqty.value = null;
}
function removeform() {
var elem = document.getElementById("remform");
elem.parentNode.removeChild(elem);
}
function removebuttons() {
rem.setAttribute("hidden", true);
}
function showbuttons() {
rem.removeAttribute("hidden", false);
}
btnform.addEventListener('click', function() {
addformtopage();
removebuttons();
cancelform.addEventListener('click', function() {
showbuttons();
removeform();
});
submit.addEventListener('click', function() {
if (validateform()) {
alert("Values Added");
addData();
clearform();
}
});
});
btnlist.addEventListener('click', function() {
showlist();
removebuttons();
document.getElementById('showbutton').addEventListener('click', function() {
showbuttons();
removelist();
document.getElementById('showbutton').setAttribute("hidden", "true");
});
});
#chkname,
#chkdesc,
#chkprice,
#chkqty {
color: red;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 70%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<!DOCTYPE HTML>
<html>
<head>
<link href="style.css" rel="stylesheet" />
<title>
JS Form
</title>
</head>
<body>
<div id="main">
<p><button id="clicktoadd">Add Product</button> <button id="clicktoshow">Show List</button></p>
</div>
<div id="panel">
</div>
<div id="listing">
</div>
<button id="showbutton" hidden="true">< Back</button>
<script src="script.js"></script>
</body>
</html>
I want to take input in form for description of the item as formatted text. And then output it in the same format as input, but right now I am getting text separated by space where should be there. Please help..
Steps to perform
1. Run this code snippet.
2. Click on 'Add Product' button.
3. Fill the form (For testing give a description of more than one line) and Submit.
4. Click on 'Cancel' button to return.
5. Click on 'Show List' button.
6. Observe Description column.
This is output I am getting separated by spaces
This is form input I am providing
Well, you have two options. Add a <pre> tag:
for (let i = 0; i < arr.length; i++) {
data.innerHTML += ("<tr><td>" + arr[i].name + "</td><td><pre>" + arr[i].desc + "</pre></td><td>" + arr[i].price + "</td><td>" + arr[i].qty + "</td><td><button id=\"delete" + i + "\">Delete</button></tr>");
};
This way it will display the new lines and you keep your string clean.
Or you can replace the new lines with <br> this way:
for (let i = 0; i < arr.length; i++) {
data.innerHTML += ("<tr><td>" + arr[i].name + "</td><td>" + arr[i].desc.replace(/\n/g, "<br>") + "</td><td>" + arr[i].price + "</td><td>" + arr[i].qty + "</td><td><button id=\"delete" + i + "\">Delete</button></tr>");
};
Remember that the new lines are not shown by default in HTML, if you want a new line put a <br>
Test it online
Hope it helps! :)
Add this into your code:
var text = arr[i].desc;
text = text.replace(/\n/g, '<br />');
JSfiddle
See JavaScript: How to add line breaks to an HTML textarea? too.

How on Ajax request genereate once divs for data and then on next ajax request update only the data in the divs?

Hi there I'm trying to populate div with data from ajax request, the idea is to use Ajax to get temperature from multiple sensors and for every sensor temperature data I want a separate div column with the data, So on document.ready I use ajax get once to popualte the main page div with the div columns to get the results, but after that I want to use ajax again every 10 seconds to update the data, but how can I do it not generating the containers for the data again? Because of waht I have right now I can't make it to work when I try to make a filter to show/hide the div for specific location.
$(document).ready(function(){
var menu_list = [];
var tr_str = [];
var temp_int= [];
$.ajax({
url: 'getData.php',
type: 'get',
dataType: 'JSON',
success: function(response){
var len = response.length;
for(var i=0; i<len; i++){
var location = response[i].location;
temp_int[i] = response[i].temp_int;
var temp = response[i].temp;
var hum = response[i].hum;
var dew = response[i].dew;
tr_str[i] = "<div id='locc" + i + "' class='location'>" +
"<span class='title'>" + location + "</span>" +
"<div class='temp" + i + "'><span>Temperatura: </span><span id='check'>" + temp + " &degC</span></div>" +
"<div><span>Względna wilgotność: </span><span>" + hum + " %RH</span></div>" +
"<div><span>Punkt rosy: </span><span>" + dew + " &degC</span></div>" +
"</div>";
menu_list[i] = "<label for='loc" + i + "'>" +
"<input type='checkbox' id='loc" + i + "' checked='checked'/>" +
"<span class='css-checkbox'></span>" +
"<p>" + location + "</p>" +
"</label>";
}
$("#nav").append(menu_list);
$("#data").html(tr_str);
for(var i=0; i<len; i++){
if (temp_int[i] >= 250) {
$(".temp" + i).css("background-color", "#ff0000");
}
else if (temp_int[i] >= 235) {
$('.temp' + i).css("background-color","#f1c40f");
}
else {
$('.temp' +i).css("background-color","#3498db");
}
}
}
});
$("#loc1").change(function () {
if (this.checked){
$("#locc1").show(!this.checked);
}else {
$("#locc1").hide(!this.checked);
}
});
});
setTimeout(fetchdata,5000);
function fetchdata(){
var tr_str = [];
var temp_int= [];
$.ajax({
url: 'getData.php',
type: 'get',
dataType: 'JSON',
cache: false,
success: function(response){
var len = response.length;
for(var i=0; i<len; i++){
var location = response[i].location;
temp_int[i] = response[i].temp_int;
var temp = response[i].temp;
var hum = response[i].hum;
var dew = response[i].dew;
tr_str[i] = "<div id='locc" + i + "' class='location'>" +
"<span class='title'>" + location + "</span>" +
"<div class='temp" + i + "'><span>Temperatura: </span><span id='check'>" + temp + " &degC</span></div>" +
"<div><span>Względna wilgotność: </span><span>" + hum + " %RH</span></div>" +
"<div><span>Punkt rosy: </span><span>" + dew + " &degC</span></div>" +
"</div>";
}
$("#data").html(tr_str);
for(var i=0; i<len; i++){
if (temp_int[i] >= 250) {
$(".temp" + i).css("background-color", "#ff0000");
}
else if (temp_int[i] >= 235) {
$('.temp' + i).css("background-color","#f1c40f");
}
else {
$('.temp' +i).css("background-color","#3498db");
}
}
},
complete:function(){
setTimeout(fetchdata,5000);
}
});
}
function openNav() {
document.getElementById("nav").style.width = "350px";
document.getElementById("data").style.marginLeft = "350px";
}
function closeNav() {
document.getElementById("nav").style.width = "0";
document.getElementById("data").style.marginLeft = "0";
}
<!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="lib/style.css">
</head>
<body>
<div id="nav" class="menu">
×
<button>Uncheck all</button>
</div>
<div class="nav-wrapper">
<span onclick="openNav()">☰</span>
</div>
<div id="data" class="wrapper"></div>
</body>
</html>
You can see that I use almost the same Ajax request again, is there a way to get teh data at first and generate the divs for the data and then just get the data every 10 seconds and update it only withou generating again the divs?
I'm thinking that what I have right now is making tis unable to work
var $checkboxes = $("#nav :checkbox");
var $button = $("#nav button");
function allChecked(){
return $checkboxes.length === $checkboxes.filter(":checked").length;
}
function updateButtonStatus(){
$button.text(allChecked()? "Uncheck all" : "Check all");
}
function handleButtonClick(){
$checkboxes.prop("checked", allChecked()? false : true)
}
$button.on("click", function() {
handleButtonClick();
updateButtonStatus();
checking();
});
$checkboxes.on("change", function(){
updateButtonStatus();
});
function openNav() {
document.getElementById("nav").style.width = "250px";
}
function closeNav() {
document.getElementById("nav").style.width = "0";
}
function checking() {
var temps = <?php echo json_encode($temps); ?>; //I know this is wrong I would change the loop iteration but it is not working even for one static element when I change it.
$.each( temps, function( index, value ){
$('#loc'+index).change(function () {
if( this.checked ) {
$('#locc'+index).show(!this.checked);
} else {
$('#locc'+index).hide(!this.checked);
}
}).change();
});}
Here is the php file code I'm geting using ajax:
<?php
require 'lib/locations.php';
$search = array('STRING: ', '"');
$search2 = array('INTEGER: ', '"');
$replace = array('','');
$return_arr = array();
for ($i = 0; $i < $c; $i++) {
$temp_int = snmpget($ips[$i], $community, ".1.3.6.1.4.1.22626.1.2.3.1.0");
$temp_int = str_replace($search2,$replace,$temp_int);
$temp = snmpget($ips[$i], $community, ".1.3.6.1.4.1.22626.1.2.1.1.0");
$temp = str_replace($search,$replace,$temp);
$hum = snmpget($ips[$i], $community, ".1.3.6.1.4.1.22626.1.2.1.2.0");
$hum = str_replace($search,$replace,$hum);
$dew = snmpget($ips[$i], $community, ".1.3.6.1.4.1.22626.1.2.1.3.0");
$dew = str_replace($search,$replace,$dew);
$loc = $location[$i];
$return_arr[] = array("location" => $loc,
"temp_int" => $temp_int,
"temp" => $temp,
"hum" => $hum,
"dew" => $dew);
}
echo json_encode($return_arr);
?>
The generated data is an array of one integer and strings
something like this:
var response =[{
"location": "location_1"
"temp_int":250,
"temp":"30.5",
"hum":"49.8",
"dew":"8.5"
},
{"location": "location_1"
"temp_int":250,
"temp":"30.5",
"hum":"49.8",
"dew":"8.5"
}, etc.]

Scope model update

Below demo app is showing three different progressbars.
Now user needs to select which progressbar he/she wants to change value
and then on button click which is provided at same page.
var app = angular.module('myApp',[]);
app.component('listComponent', {
template:'<div ng-repeat="progress in $ctrl.obj.bars track by $index">' +
'<progress value="{{progress}}" max="{{$ctrl.obj.limit}}">{{progress}}</progress><br>'+
'</div>'+
'<br>' +
'<div>' +
'Selected Progressbar : {{$ctrl.selectedProgressbar}}' +
'<span>' +
'<select name="selectedProgressbar" ng-model="$ctrl.selectedProgressbar">' +
'<option ng-repeat="progress in $ctrl.obj.bars track by $index" value="{{$index}}">{{progress}}</option>' +
'</select>' +
'</span>' +
'<span ng-repeat="btn in $ctrl.obj.buttons">' +
'<button class="btn" ng-click="$ctrl.changeProgress(btn, $ctrl.selectedProgressbar)">{{btn}}</button>' +
'</span>' +
'</div>',
controller: function () {
this.obj = {
"buttons": [
10,
38,
-13,
-18
],
"bars": [
62,
45,
62
],
"limit": 230
};
function changeProgressbar(val){
var val = parseInt(val);
var barValue = this.obj.bars[this.selectedProgressbar];
var selectedBar = this.selectedProgressbar;
var bars = this.obj.bars;
// this.obj.bars[0] = parseInt(this.obj.bars[0]) + parseInt(val);
// if we remove comment from above code and comment below one then progresbar value changes at same time
// but with below code its not changing at same time its changing when we click on any button or change progreebar selection
if(val > 0){
var total = parseInt(barValue) + val;
var update = setInterval(function() {
if (parseInt(barValue) > total) {
clearInterval(update);
}
barValue = parseInt(barValue) + 1;
bars[selectedBar] = barValue;
}, 15);
}
}
this.changeProgress = changeProgressbar;
}
});
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="This is just demo application by using Angular 1.6">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Progressbar in Angular 1.6</title>
<style type="text/css" media="screen">
progress:after {
display: block;
content: attr(value);
text-align:center;
}
</style>
</head>
<body ng-app="myApp">
<list-component></list-component>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script>
</script>
</body>
</html>
jsBin is here,
now after selecting any progressbar then click on any first two buttons then no change is found on progreebar
but as soon as you click again or select some other progressbar then value is changing.
After going through your code, I found some issues there.
You should change the changeProgressbar function and remove the interval function.
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="[add your bin description]">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Progressbar in Angular 1.6</title>
<style type="text/css" media="screen">
progress:after {
display: block;
content: attr(value);
text-align:center;
}
</style>
</head>
<body ng-app="myApp">
<list-component></list-component>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script>
var app = angular.module('myApp',[]);
app.component('listComponent', {
// isolated scope binding
template:'{{$ctrl.obj.bars}}<div ng-repeat="progress in $ctrl.obj.bars track by $index">' +
'<progress value="{{progress}}" max="{{$ctrl.obj.limit}}">{{progress}}</progress><br>'+
'</div>'+
'<br>' +
'<div>' +
'Selected Progressbar : {{$ctrl.selectedProgressbar}}' +
'<span>' +
'<select name="selectedProgressbar" ng-model="$ctrl.selectedProgressbar">' +
'<option ng-repeat="progress in $ctrl.obj.bars track by $index" value="{{$index}}">{{progress}}</option>' +
'</select>' +
'</span>' +
'<span ng-repeat="btn in $ctrl.obj.buttons">' +
'<button class="btn" ng-click="$ctrl.changeProgress(btn, $ctrl.selectedProgressbar)">{{btn}}</button>' +
'</span>' +
'</div>',
controller: function () {
this.obj = {
"buttons": [
10,
38,
-13,
-18
],
"bars": [
62,
45,
62
],
"limit": 230
};
function changeProgressbar(val){
var val = parseInt(val);
var barValue = this.obj.bars[this.selectedProgressbar];
var selectedBar = this.selectedProgressbar;
var bars = this.obj.bars;
// this.obj.bars[0] = parseInt(this.obj.bars[0]) + parseInt(val);
// if we remove comment from above code and comment below one then progresbar value changes at same time
// but with below code its not changing at same time its changing when we click on any button or change progreebar selection
if(val > 0){
var total = parseInt(barValue) + val;
if (parseInt(barValue) > total) {
clearInterval(update);
}
else
{
barValue = total;
bars[selectedBar] = barValue;
}
}
}
this.changeProgress = changeProgressbar;
}
});
</script>
</body>
</html>
PLEASE RUN THE ABOVE SNIPPET
Here is a working DEMO

Why am I getting undefined on this variable assigned with jQuery .val()?

I'm making a basic shopping list app and have run into a wall. The program silently fails, and upon checking with breakpoints and such, I've discovered that on line 75, I'm getting newItem as undefined.
Everything else in the statement is being defined correctly. Any clue what I've done wrong?
Here's the index.js:
'use strict';
var state = {
items: []
};
var listItemTemplate = (
'<li>' +
'<span class="shopping-item js-shopping-item"></span>' +
'<div class="shopping-item-controls">' +
'<button class="js-shopping-item-toggle">' +
'<span class="button-label">check</span>' +
'</button>' +
'<button class="js-shopping-item-delete">' +
'<span class="button-label">delete</span>' +
'</button>' +
'</div>' +
'</li>'
);
// state modification functions
var stateHelper = {
addItem: function(state, item) {
state.items.push({
displayName: item,
checkedOff: false
});
},
getItem: function(state, itemIndex) {
return state.items[itemIndex];
},
deleteItem: function(state, item) {
state.items.splice(itemIndex, 1);
},
updateItem: function(state, item) {
state.items[itemIndex] = newItemState;
}
}
// render functions
var renderHelper = {
renderItem: function(item, itemId, itemTemplate, itemDataAttr) {
var element = $(itemTemplate);
element.find('.js-shopping-item').text(item.displayName);
console.log("item.displayName: " + item.displayName)
console.log("item: " + item)
if (item.checkedOff) {
element.find('.js-shopping-item').addClass('shopping-item__checked');
}
element.find('.js-shopping-item-toggle')
element.attr(itemDataAttr, itemId);
// try `element.find('.js-shopping-item-toggle').attr(itemDataAttr, itemId);` instead and see if it works
console.log("itemDataAttr: " + itemDataAttr)
return element;
},
renderList: function(state, listElement, itemDataAttr) {
var itemsHTML = state.items.map(
function(item, index) {
//what determines the index here?
console.log("index: " + index)
return renderItem(item, index, listItemTemplate, itemDataAttr);
});
listElement.html(itemsHTML);
}
}
// event listeners
var eventHelper = {
handleItemAdds: function(formElement, newItemIdentifier, itemDataAttr, listElement, state) {
formElement.submit(function(event) {
event.preventDefault();
var newItem = formElement.find(newItemIdentifier).val();
console.log(newItem)
stateHelper.addItem(state, newItem);
console.log(newItemIdentifier)
this.reset();
});
},
handleItemDeletes: function(formElement, removeIdentifier, itemDataAttr, listElement, state) {
listElement.on('click', removeIdentifier, function(event) {
var itemIndex = parseInt($(this).closest('li').attr(itemDataAttr));
console.log("this: " + this);
console.log("$(this).closest('li').attr(itemDataAttr " + $(this).closest('li').attr(itemDataAttr));
stateHelper.deleteItem(state, itemIndex);
renderList(state, listElement, itemDataAttr);
console.log("what is itemDataAttr? it is: " + itemDataAttr)
})
},
handleItemToggles: function(listElement, toggleIdentifier, itemDataAttr, state) {
listElement.on('click', toggleIdentifier, function(event) {
var itemId = $(event.currentTarget.closest('li')).attr(itemDataAttr);
var oldItem = stateHelper.getItem(state, itemId);
stateHelper.updateItem(state, itemId, {
displayName: oldItem.displayName,
checkedOff: !oldItem.checkedOff
});
renderHelper.renderList(state, listElement, itemDataAttr)
});
}
}
$(function() {
var formElement = $('#js-shopping-list-form');
var listElement = $('.js-shopping-list');
//id of input containing list items
var newItemIdentifier = "#js-new-item";
//in listItemTemplate above; the delete button has this class
var removeIdentifier = ".js-shopping-item-delete";
//stores id of list item
var itemDataAttr = "data-list-item-id";
var toggleIdentifier = ".js-shopping-list-toggle"
eventHelper.handleItemAdds(formElement, newItemIdentifier, itemDataAttr, listElement, state);
eventHelper.handleItemDeletes(formElement, removeIdentifier, itemDataAttr, listElement, state);
eventHelper.handleItemToggles(listElement, toggleIdentifier, itemDataAttr, state);
});
And here's the index.html for reference:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Shopping List</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<h1>Shopping List</h1>
<form id="js-shopping-list-form">
<label for="shopping-list-entry">Add an item</label>
<input type="text" name="shopping-list-entry" id="shopping-list-entry" placeholder="e.g., broccoli">
<button type="submit">Add item</button>
</form>
<ul class="shopping-list">
</ul>
</div>
<script src="jquery-3.1.1.js"></script>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
Alacritas,
I don't see anywhere in your view that you actually have an element with an id that matches that accessor (#js-new-item).
Your comment says it belongs to the input box, but the input box you have in your html does not have that id.
I think you would need to update the string "#js-new-item" to be "#shopping-list-entry".

JQuery Mobile collapsible does not apply to div

I'm very new to both JQuery and Javascript. I have an feed, I would like to display these feed inside a collapsible div AS a collapsible div. I have the following Javascript file:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("feeds", "1");
google.setOnLoadCallback(showFeed);
function showFeed() {
var feed = new google.feeds.Feed("http://www.varzesh3.com/rss");
feed.setNumEntries(10);
feed.load(function(result) {
if (!result.error) {
var container = document.getElementById("headlines");
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var di = document.createElement("div").setAttributeNode("data-role", "collapsible");
di.innerHTML = '<h3>' + entry.title + '</h3>';
di.innerHTML += '<p>' + entry.contentSnippet + '</p>';
container.appendChild(di);
}
} else {
var container = document.getElementById("headlines");
container.innerHTML = '<li>Get your geek news fix at site</li>';
}
});
}
</script>
<body>
<div data-role="collapsible-set" id="headlines"></div>
</body>
This should fetch all my feed names and put them in a collapsible div, it does exactly that but it shows the names as plain HTML text instead of a JQuery Mobile collapsible div.
#AML, that is more a comment than an answer because a don't analyse your entire code, but I will put here for formatting purposes.
In the line:
var di = document.createElement("div").setAttributeNode("data-role", "collapsible");
You don't take a pointer(di) to the new created element, you take a result of the setAttributeNode(...), You need to split the code in two lines like that:
var di = document.createElement("div");
di.setAttribute("data-role", "collapsible");
There are a problem with setAttributeNode actually is setAttribute.
Now is working, see at http://pannonicaquartet.com/test/feeds.html
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
.collapsible{
display : none;
}
h3{
background-color : lightgray;
}
</style>
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("feeds", "1");
function showFeed() {
var feed = new google.feeds.Feed("http://www.varzesh3.com/rss");
feed.load(function(result) {
if (!result.error) {
var container = document.getElementById("headlines");
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
div.onclick = function(evt){
var elP = this.children[1];
if(elP.style.display == 'inline'){
elP.style.display = 'none';
}else{
elP.style.display = 'inline';
}
};
div.innerHTML = '<h3>' + entry.title + '</h3>';
div.innerHTML += '<p class="collapsible">' + entry.contentSnippet + '</p>';
container.appendChild(div);
}
}
});
}
google.setOnLoadCallback(showFeed);
</script>

Categories

Resources